diff --git a/.github/workflows/README.md b/.github/workflows/README.md
new file mode 100644
index 0000000..704e5bc
--- /dev/null
+++ b/.github/workflows/README.md
@@ -0,0 +1,74 @@
+# GitHub Actions Workflows
+
+Tento adresář obsahuje CI/CD workflow pro automatické buildu aplikací pro všechny platformy.
+
+## Build Windows
+
+Workflow `build-windows.yml` automaticky kompiluje všechny aplikace pro Windows při:
+- Push do `main` nebo `master` branch
+- Pull request do `main` nebo `master` branch
+- Manuálním spuštění přes GitHub Actions tab
+
+## Build macOS
+
+Workflow `build-macos.yml` automaticky kompiluje všechny aplikace pro macOS (ARM64 i x86_64) při:
+- Push do `main` nebo `master` branch
+- Pull request do `main` nebo `master` branch
+- Manuálním spuštění přes GitHub Actions tab
+
+**Poznámka**: macOS buildy běží na dvou runnerech:
+- `macos-latest` - Apple Silicon (ARM64)
+- `macos-13` - Intel (x86_64)
+
+## Build Linux
+
+Workflow `build-linux.yml` automaticky kompiluje všechny aplikace pro Linux při:
+- Push do `main` nebo `master` branch
+- Pull request do `main` nebo `master` branch
+- Manuálním spuštění přes GitHub Actions tab
+
+### Jak to funguje:
+
+1. **Automatické spuštění**: Když pushneš změny do GitHubu, workflow se automaticky spustí
+2. **Windows runner**: GitHub poskytne virtuální Windows počítač
+3. **Instalace nástrojů**: Automaticky se nainstaluje Free Pascal Compiler a Lazarus IDE
+4. **Kompilace**: Všechny aplikace se zkompilují (client, launcher, server, extractor)
+5. **Artefakty**: Zkompilované `.exe` soubory jsou k dispozici ke stažení
+
+### Jak použít:
+
+1. **Pushni změny do GitHubu**:
+ ```bash
+ git add .
+ git commit -m "Update code"
+ git push
+ ```
+
+2. **Zkontroluj stav buildu**:
+ - Jdi na GitHub → tvůj repozitář
+ - Klikni na záložku "Actions"
+ - Uvidíš běžící nebo dokončené buildu
+
+3. **Stáhni artefakty**:
+ - Po dokončení buildu klikni na workflow run
+ - V sekci "Artifacts" klikni na příslušný artifact:
+ - `windows-binaries` - Windows `.exe` soubory
+ - `macos-arm64-binaries` - macOS ARM64 binárky
+ - `macos-x86_64-binaries` - macOS Intel binárky
+ - `linux-binaries` - Linux binárky
+ - Stáhneš ZIP soubor se všemi zkompilovanými soubory
+
+### Manuální spuštění:
+
+1. Jdi na GitHub → tvůj repozitář → záložka "Actions"
+2. Vyber workflow "Build Windows"
+3. Klikni na "Run workflow"
+4. Vyber branch a klikni "Run workflow"
+
+### Poznámky:
+
+- Build trvá obvykle 5-15 minut (závisí na platformě)
+- Artefakty jsou dostupné 30 dní
+- Pokud build selže, zkontroluj logy v sekci "Actions"
+- Všechny tři workflow (Windows, macOS, Linux) běží paralelně, takže dostaneš buildy pro všechny platformy najednou
+
diff --git a/.github/workflows/build-flyio.yml b/.github/workflows/build-flyio.yml
new file mode 100644
index 0000000..2184f08
--- /dev/null
+++ b/.github/workflows/build-flyio.yml
@@ -0,0 +1,157 @@
+name: Build and Release Fly.io Server
+
+# This workflow builds Docker image for Fly.io server and creates a release
+# Responds only to tags starting with "server-v" (e.g., server-v1.0.0)
+on:
+ workflow_dispatch: # Manual trigger
+ push:
+ tags:
+ - 'server-v*' # Triggers on tags starting with 'server-v' (e.g., server-v1.0.0)
+
+jobs:
+ build-and-release:
+ name: Build Docker Image and Create Release
+ runs-on: ubuntu-latest
+
+ steps:
+ # 1. Checkout code
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ # 2. Prepare data directory for Docker build
+ - name: Prepare data directory
+ run: |
+ # If flyio_server/data doesn't exist, use data from project root
+ if [ ! -d "flyio_server/data" ]; then
+ echo "flyio_server/data not found, using data from project root"
+ if [ -d "data" ]; then
+ mkdir -p flyio_server
+ cp -r data flyio_server/data
+ echo "✓ Copied data from project root to flyio_server/data"
+ echo "⚠️ WARNING: This image will be built with placeholder/empty data"
+ echo "⚠️ WARNING: Server deployed from this image will NOT work properly (no game maps)"
+ echo "⚠️ WARNING: Users must add game data using deploy_prebuilt.sh with actual game data"
+ else
+ echo "WARNING: Neither flyio_server/data nor data directory found"
+ echo "Creating empty data directory (server will NOT work properly)"
+ mkdir -p flyio_server/data
+ fi
+ else
+ echo "✓ flyio_server/data exists, using it"
+ # Check if it contains actual game data (has maps directory)
+ if [ -d "flyio_server/data/maps" ] && [ "$(ls -A flyio_server/data/maps 2>/dev/null)" ]; then
+ echo "✓ flyio_server/data contains game maps - image will be fully functional"
+ else
+ echo "⚠️ WARNING: flyio_server/data exists but appears to be empty/placeholder"
+ echo "⚠️ WARNING: Server deployed from this image will NOT work properly"
+ fi
+ fi
+
+ # 3. Setup Docker Buildx
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ # 4. Login to GitHub Container Registry
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ # 5. Extract version from tag or use commit SHA
+ - name: Extract version
+ id: version
+ run: |
+ if [[ "${{ github.ref }}" == refs/tags/server-v* ]]; then
+ # Remove "server-" prefix from tag (server-v1.0.0 -> v1.0.0)
+ VERSION=${GITHUB_REF#refs/tags/server-}
+ else
+ VERSION="dev-${GITHUB_SHA::8}"
+ fi
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ echo "tag=ghcr.io/${{ github.repository_owner }}/fpc-atomic-server:$VERSION" >> $GITHUB_OUTPUT
+ echo "tag_latest=ghcr.io/${{ github.repository_owner }}/fpc-atomic-server:latest" >> $GITHUB_OUTPUT
+ echo "Version: $VERSION"
+
+ # 6. Build Docker image
+ - name: Build Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: ./flyio_server/Dockerfile
+ push: true
+ tags: |
+ ${{ steps.version.outputs.tag }}
+ ${{ steps.version.outputs.tag_latest }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ # 7. Create GitHub Release (only for server tags)
+ - name: Create Release
+ if: startsWith(github.ref, 'refs/tags/server-v')
+ uses: softprops/action-gh-release@v1
+ with:
+ name: Fly.io Server ${{ steps.version.outputs.version }}
+ body: |
+
+ ☁️ Cloud Server Release
+ This release contains files for build and deploy game server to [fly.io](https://fly.io)
+ ## FPC Atomic Server for Fly.io
+
+ ### 🚀 How to deploy to Fly.io (without Pascal compiler!)
+
+ **Easiest way - use the pre-built Docker image:**
+
+ 1. **Install Fly.io CLI:**
+ ```bash
+ curl -L https://fly.io/install.sh | sh
+ ```
+
+ 2. **Login:**
+ ```bash
+ flyctl auth login
+ ```
+
+ 3. **Create a new directory and download configuration:**
+ ```bash
+ mkdir fpc-atomic-server && cd fpc-atomic-server
+ curl -L https://github.com/${{ github.repository }}/releases/latest/download/fly.toml.example -o fly.toml
+ ```
+
+ 4. **Edit `fly.toml` - change the image path to your GitHub username (if you have a fork):**
+ ```toml
+ [build]
+ image = "ghcr.io/${{ github.repository_owner }}/fpc-atomic-server:latest"
+ ```
+
+ 5. **Deploy to Fly.io:**
+ ```bash
+ flyctl launch
+ ```
+
+ **Alternative - build from source code:**
+
+ If you want to build from source code, clone the repository and use `fly.toml` from the `flyio_server/` directory.
+
+ ### 📦 Docker Image
+
+ Image is available on GitHub Container Registry:
+ - `ghcr.io/${{ github.repository_owner }}/fpc-atomic-server:${{ steps.version.outputs.version }}`
+ - `ghcr.io/${{ github.repository_owner }}/fpc-atomic-server:latest`
+
+ ### 🔧 Configuration
+
+ - **Port:** 5521
+ - **Region:** Frankfurt (fra) - can be changed in `fly.toml`
+ - **Auto-shutdown:** 30 seconds of inactivity
+
+ ### 📝 Documentation
+
+ For more information, see [README.md](flyio_server/README.md)
+ draft: false
+ prerelease: false
+ files: |
+ flyio_server/README.md
+ flyio_server/fly.toml.example
+ flyio_server/Dockerfile
diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml
new file mode 100644
index 0000000..b01c733
--- /dev/null
+++ b/.github/workflows/build-linux.yml
@@ -0,0 +1,369 @@
+name: Build Linux
+
+# Tento workflow se spustí při:
+# - Push do main/master branch
+# - Pull request do main/master branch
+# - Manuálně přes GitHub Actions tab
+on:
+ #push:
+ # branches: [ main, master ]
+ #pull_request:
+ # branches: [ main, master ]
+ workflow_dispatch: # Umožňuje manuální spuštění
+
+jobs:
+ build-linux:
+ name: Build for Linux
+ runs-on: ubuntu-latest # Použije Linux runner (Ubuntu)
+
+ steps:
+ # 1. Checkout kódu z repozitáře
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ # 2. Setup Free Pascal Compiler
+ - name: Setup Free Pascal Compiler
+ run: |
+ set -e # Exit on any error
+ sudo apt-get update
+ sudo apt-get install -y fpc fp-compiler
+
+ # Ověřit instalaci - použij -iV pro verzi bez potřeby source souboru
+ fpc -iV
+ echo "FPC version check completed"
+
+ # 3. Setup Lazarus IDE
+ - name: Setup Lazarus IDE
+ run: |
+ set -e # Exit on any error
+ sudo apt-get install -y lazarus lazarus-ide-gtk2
+
+ # Ověřit instalaci
+ lazbuild --version
+ echo "Lazarus version check completed"
+
+ # 4. Install system dependencies
+ - name: Install system dependencies
+ run: |
+ set -e # Exit on any error
+ # Install SDL2 development libraries
+ sudo apt-get install -y libsdl2-dev
+
+ # Install OpenSSL development libraries (for fphttpclient)
+ sudo apt-get install -y libssl-dev
+
+ # Install other build dependencies
+ sudo apt-get install -y build-essential
+
+ # 5. Download and install BASS library
+ - name: Download and install BASS library
+ run: |
+ set -e # Exit on any error
+ echo "Downloading BASS library for Linux..."
+ # BASS library needs to be downloaded from https://www.un4seen.com/
+ # For CI/CD, we'll try to download it or use a placeholder
+ # Note: The actual libbass.so needs to be provided by the user
+ # For now, we'll create a note that it needs to be installed
+
+ # Check for libbass.so in various locations
+ if [ -f "bin/libbass.so" ]; then
+ echo "Found libbass.so in bin/"
+ sudo cp bin/libbass.so /usr/lib/
+ sudo chmod 644 /usr/lib/libbass.so
+ elif [ -f "libbass.so" ]; then
+ echo "Found libbass.so in repository root"
+ sudo cp libbass.so /usr/lib/
+ sudo chmod 644 /usr/lib/libbass.so
+ elif [ -f "macos/bin/arm64/libbass.so" ]; then
+ echo "Found libbass.so in macos/bin/arm64/"
+ sudo cp macos/bin/arm64/libbass.so /usr/lib/
+ sudo chmod 644 /usr/lib/libbass.so
+ else
+ echo "ERROR: libbass.so not found in repository"
+ echo "BASS library needs to be in bin/libbass.so"
+ exit 1
+ fi
+
+ # Verify installation
+ if [ -f "/usr/lib/libbass.so" ]; then
+ echo "✓ libbass.so installed successfully"
+ ls -lh /usr/lib/libbass.so
+ # Verify it's a valid shared library
+ file /usr/lib/libbass.so
+ else
+ echo "ERROR: libbass.so not installed - build will fail"
+ exit 1
+ fi
+
+ # 6. Download and build LNet package
+ - name: Download and build LNet package
+ run: |
+ set -e # Exit on any error
+ echo "Downloading LNet from GitHub..."
+ # Use master branch (not main) - see https://github.com/PascalCorpsman/lnet
+ lnetUrl="https://github.com/PascalCorpsman/lnet/archive/refs/heads/master.zip"
+ lnetZip="/tmp/lnet.zip"
+ lnetDir="/tmp/lnet"
+
+ # Download LNet
+ echo "Downloading from: $lnetUrl"
+ curl -L -f -o "$lnetZip" "$lnetUrl" || {
+ echo "ERROR: Failed to download LNet (curl exit code: $?)"
+ echo "Trying alternative URL..."
+ # Try alternative URL format
+ lnetUrlAlt="https://github.com/PascalCorpsman/lnet/archive/master.zip"
+ curl -L -f -o "$lnetZip" "$lnetUrlAlt" || {
+ echo "ERROR: All download attempts failed"
+ exit 1
+ }
+ }
+ echo "LNet downloaded successfully"
+
+ # Extract LNet
+ echo "Extracting LNet..."
+ unzip -q "$lnetZip" -d "$lnetDir" || {
+ echo "ERROR: Failed to extract LNet"
+ exit 1
+ }
+
+ # Find the package files
+ lnetPackagePath=$(find "$lnetDir" -name "lnetvisual.lpk" | head -1)
+ if [ -z "$lnetPackagePath" ]; then
+ echo "ERROR: lnetvisual.lpk not found in downloaded archive"
+ exit 1
+ fi
+
+ lnetBasePath=$(find "$lnetDir" -name "lnetbase.lpk" | head -1)
+ if [ -z "$lnetBasePath" ]; then
+ echo "ERROR: lnetbase.lpk not found in downloaded archive"
+ exit 1
+ fi
+
+ echo "Found LNet packages:"
+ echo " Base: $lnetBasePath"
+ echo " Visual: $lnetPackagePath"
+
+ # Build base package first
+ echo "Building lnetbase.lpk..."
+ lazbuild --build "$lnetBasePath" || {
+ echo "WARNING: lnetbase.lpk build failed, but continuing..."
+ }
+
+ # Build visual package
+ echo "Building lnetvisual.lpk..."
+ lazbuild --build "$lnetPackagePath" || {
+ echo "WARNING: LNet package build failed"
+ }
+
+ # Copy LNet source files to expected location for search paths
+ echo "Copying LNet source files to macos/third_party..."
+ lnetSourceDir=$(find "$lnetDir" -type d -name "lnet-*" | head -1)
+ if [ -z "$lnetSourceDir" ]; then
+ echo "ERROR: LNet source directory not found"
+ exit 1
+ fi
+
+ targetLnetBaseDir="macos/third_party/lnet"
+ targetLnetSrcDir="macos/third_party/lnet_src"
+
+ # Create base directory structure
+ mkdir -p "$targetLnetBaseDir"
+ mkdir -p "$targetLnetSrcDir"
+
+ # Copy lib directory as subdirectory (search path expects macos/third_party/lnet/lib/)
+ if [ -d "$lnetSourceDir/lib" ]; then
+ targetLibDir="$targetLnetBaseDir/lib"
+ cp -r "$lnetSourceDir/lib" "$targetLibDir"
+ echo "Copied LNet lib directory to $targetLibDir"
+ # Verify lnet.pp exists at correct path
+ if [ -f "$targetLibDir/lnet.pp" ]; then
+ echo "✓ lnet.pp found at: $targetLibDir/lnet.pp"
+ else
+ echo "WARNING: lnet.pp not found at expected location"
+ echo "Contents of $targetLibDir:"
+ ls -la "$targetLibDir" | head -5
+ exit 1
+ fi
+ else
+ echo "ERROR: LNet lib directory not found at $lnetSourceDir/lib"
+ exit 1
+ fi
+
+ # Copy lazaruspackage directory (contains lclnet.pas and lnetcomponents.pas)
+ if [ -d "$lnetSourceDir/lazaruspackage" ]; then
+ cp -r "$lnetSourceDir/lazaruspackage" "$targetLnetSrcDir/"
+ echo "Copied LNet lazaruspackage to $targetLnetSrcDir"
+ else
+ echo "ERROR: LNet lazaruspackage directory not found at $lnetSourceDir/lazaruspackage"
+ exit 1
+ fi
+
+ # Verify key files are available at correct paths
+ lnetComponentsPath="$targetLnetSrcDir/lazaruspackage/lnetcomponents.pas"
+ lclnetPath="$targetLnetSrcDir/lazaruspackage/lclnet.pas"
+ lnetPath="$targetLnetBaseDir/lib/lnet.pp"
+
+ if [ -f "$lnetComponentsPath" ]; then
+ echo "✓ lnetcomponents.pas available at: $lnetComponentsPath"
+ else
+ echo "ERROR: lnetcomponents.pas not found at: $lnetComponentsPath"
+ exit 1
+ fi
+
+ if [ -f "$lclnetPath" ]; then
+ echo "✓ lclnet.pas available at: $lclnetPath"
+ else
+ echo "ERROR: lclnet.pas not found at: $lclnetPath"
+ exit 1
+ fi
+
+ if [ -f "$lnetPath" ]; then
+ echo "✓ lnet.pp available at: $lnetPath"
+ else
+ echo "ERROR: lnet.pp not found at: $lnetPath"
+ exit 1
+ fi
+
+ echo "All LNet files copied and verified successfully!"
+
+ # 7. Verify dependencies
+ - name: Verify dependencies
+ run: |
+ set -e # Exit on any error
+ echo "Verifying all required dependencies..."
+
+ # Check dglopengl.pas
+ if [ -f "units/dglOpenGL.pas" ]; then
+ echo "✓ dglOpenGL.pas found"
+ else
+ echo "ERROR: dglOpenGL.pas not found"
+ exit 1
+ fi
+
+ # Check bass.pas
+ if [ -f "units/bass.pas" ]; then
+ echo "✓ bass.pas found"
+ else
+ echo "ERROR: bass.pas not found"
+ exit 1
+ fi
+
+ # Check SDL2-for-Pascal
+ if [ -d "units/sdl2_for_pascal" ]; then
+ echo "✓ SDL2-for-Pascal found"
+ else
+ echo "ERROR: SDL2-for-Pascal not found"
+ exit 1
+ fi
+
+ # Check LNet source files
+ lnetComponentsFound=false
+ possibleLnetPaths=(
+ "macos/third_party/lnet_src/lazaruspackage/lnetcomponents.pas"
+ "/tmp/lnet/lnet-*/lazaruspackage/lnetcomponents.pas"
+ )
+
+ for path in "${possibleLnetPaths[@]}"; do
+ if [ -f "$path" ]; then
+ echo "✓ LNet source files found at: $path"
+ lnetComponentsFound=true
+ break
+ fi
+ done
+
+ if [ "$lnetComponentsFound" = false ]; then
+ echo "WARNING: LNet source files not found in expected locations"
+ echo "LNet was downloaded and built, should be available via compiled packages"
+ echo "Continuing anyway..."
+ fi
+
+ # Check LazOpenGLContext (should be in Lazarus IDE)
+ echo "✓ LazOpenGLContext should be part of Lazarus IDE (checked in RequiredPackages)"
+
+ # Note: synapse is not needed anymore (replaced with fphttpclient)
+ echo "Note: synapse is not required (replaced with fphttpclient)"
+
+ echo "All dependencies verified!"
+
+ # 8. Build Client
+ - name: Build Client
+ run: |
+ set -e # Exit on any error
+ cd client
+ lazbuild --build-mode=default fpc_atomic.lpi
+
+ # 9. Build Launcher
+ - name: Build Launcher
+ run: |
+ set -e # Exit on any error
+ cd launcher
+ lazbuild --build-mode=default atomic_launcher.lpi
+
+ # 10. Build Server
+ - name: Build Server
+ run: |
+ set -e # Exit on any error
+ cd server
+ lazbuild --build-mode=default atomic_server.lpi
+
+ # 11. Build CD Data Extractor
+ - name: Build CD Data Extractor
+ run: |
+ set -e # Exit on any error
+ cd cd_data_extractor_src
+ lazbuild --build-mode=default cd_data_extractor.lpi
+
+ # 12. Prepare artifacts
+ - name: Prepare artifacts
+ run: |
+ set -e # Exit on any error
+ mkdir -p linux/bin
+ echo "Looking for compiled binaries..."
+
+ # Binaries are compiled to the root directory (one level up from project folders)
+ binaries=(
+ "fpc_atomic"
+ "atomic_launcher"
+ "atomic_server"
+ "cd_data_extractor"
+ )
+
+ for bin in "${binaries[@]}"; do
+ if [ -f "$bin" ]; then
+ echo "Found: $bin"
+ mv "$bin" linux/bin/
+ else
+ echo "WARNING: $bin not found"
+ fi
+ done
+
+ # Copy Linux libraries if they exist
+ if [ -f "bin/libbass.so" ]; then
+ echo "Copying libbass.so to artifacts"
+ cp bin/libbass.so linux/bin/
+ fi
+
+ if [ -f "bin/libai.so" ]; then
+ echo "Copying libai.so to artifacts"
+ cp bin/libai.so linux/bin/
+ fi
+
+ # Copy data directory to artifacts
+ echo "Copying data directory..."
+ if [ -d "data" ]; then
+ cp -r data linux/bin/
+ echo "✓ data directory copied to linux/bin/data"
+ else
+ echo "WARNING: data directory not found"
+ fi
+
+ echo "Artifacts prepared. Contents of linux/bin:"
+ ls -lh linux/bin/
+
+ # 13. Upload artifacts (soubory ke stažení)
+ - name: Upload Linux binaries
+ uses: actions/upload-artifact@v4
+ with:
+ name: FPCAtomic-Linux
+ path: linux/bin/*
+ retention-days: 30 # Uchovat 30 dní
diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml
new file mode 100644
index 0000000..ceea4a2
--- /dev/null
+++ b/.github/workflows/build-macos.yml
@@ -0,0 +1,154 @@
+name: Build macOS
+
+# Tento workflow se spustí pouze:
+# - Manuálně přes GitHub Actions tab
+# Automatické spuštění je zakomentováno
+on:
+ # push:
+ # branches: [ main, master ]
+ # pull_request:
+ # branches: [ main, master ]
+ workflow_dispatch: # Umožňuje manuální spuštění
+
+jobs:
+ build-macos-arm64:
+ name: Build for macOS (ARM64)
+ runs-on: macos-latest # Použije macOS runner (Apple Silicon)
+
+ steps:
+ # 1. Checkout kódu z repozitáře
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ # 2. Setup Free Pascal Compiler
+ - name: Setup Free Pascal Compiler
+ run: |
+ # Nainstalovat FPC přes Homebrew
+ brew install fpc
+
+ # Ověřit instalaci
+ fpc -v
+
+ # 3. Setup Lazarus IDE
+ - name: Setup Lazarus IDE
+ run: |
+ # Nainstalovat Lazarus přes Homebrew
+ brew install --cask lazarus
+
+ # Ověřit instalaci
+ lazbuild --version
+
+ # 4. Build Client
+ - name: Build Client (ARM64)
+ run: |
+ cd client
+ lazbuild --build-mode=macos_arm64 fpc_atomic.lpi
+
+ # 5. Build Launcher
+ - name: Build Launcher (ARM64)
+ run: |
+ cd launcher
+ lazbuild --build-mode=macos_arm64 atomic_launcher.lpi
+
+ # 6. Build Server
+ - name: Build Server (ARM64)
+ run: |
+ cd server
+ lazbuild --build-mode=macos_arm64 atomic_server.lpi
+
+ # 7. Build CD Data Extractor
+ - name: Build CD Data Extractor (ARM64)
+ run: |
+ cd cd_data_extractor_src
+ lazbuild --build-mode=macos_arm64 cd_data_extractor.lpi
+
+ # 8. Prepare artifacts
+ - name: Prepare artifacts
+ run: |
+ mkdir -p macos/bin/arm64
+ if [ -f "macos/bin/arm64/fpc_atomic" ]; then
+ echo "Client built successfully"
+ fi
+ if [ -f "macos/bin/arm64/atomic_launcher" ]; then
+ echo "Launcher built successfully"
+ fi
+ if [ -f "macos/bin/arm64/atomic_server" ]; then
+ echo "Server built successfully"
+ fi
+ if [ -f "macos/bin/arm64/cd_data_extractor" ]; then
+ echo "CD Data Extractor built successfully"
+ fi
+
+ # 9. Upload artifacts
+ - name: Upload macOS ARM64 binaries
+ uses: actions/upload-artifact@v4
+ with:
+ name: macos-arm64-binaries
+ path: macos/bin/arm64/*
+ retention-days: 30
+
+ build-macos-x86_64:
+ name: Build for macOS (x86_64)
+ runs-on: macos-13 # Použije macOS runner (Intel - starší verze, ale stále dostupná)
+
+ steps:
+ # 1. Checkout kódu z repozitáře
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ # 2. Setup Free Pascal Compiler
+ - name: Setup Free Pascal Compiler
+ run: |
+ brew install fpc
+
+ # Ověřit instalaci
+ fpc -v
+
+ # 3. Setup Lazarus IDE
+ - name: Setup Lazarus IDE
+ run: |
+ brew install --cask lazarus
+
+ # Ověřit instalaci
+ lazbuild --version
+
+ # 4. Build Client
+ - name: Build Client (x86_64)
+ run: |
+ cd client
+ lazbuild --build-mode=macos_x86_64 fpc_atomic.lpi
+
+ # 5. Build Launcher
+ - name: Build Launcher (x86_64)
+ run: |
+ cd launcher
+ lazbuild --build-mode=macos_x86_64 atomic_launcher.lpi
+
+ # 6. Build Server
+ - name: Build Server (x86_64)
+ run: |
+ cd server
+ lazbuild --build-mode=macos_x86_64 atomic_server.lpi
+
+ # 7. Build CD Data Extractor
+ - name: Build CD Data Extractor (x86_64)
+ run: |
+ cd cd_data_extractor_src
+ lazbuild --build-mode=macos_x86_64 cd_data_extractor.lpi
+
+ # 8. Prepare artifacts
+ - name: Prepare artifacts
+ run: |
+ mkdir -p macos/bin/x86_64
+ if [ -f "macos/bin/x86_64/fpc_atomic" ]; then
+ echo "Client built successfully"
+ fi
+
+ # 9. Upload artifacts
+ - name: Upload macOS x86_64 binaries
+ uses: actions/upload-artifact@v4
+ with:
+ name: macos-x86_64-binaries
+ path: macos/bin/x86_64/*
+ retention-days: 30
+
diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 0000000..8c45c7c
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,599 @@
+name: Build Windows
+
+# Tento workflow se spustí při:
+# - Push do main/master branch
+# - Pull request do main/master branch
+# - Manuálně přes GitHub Actions tab
+on:
+ #push:
+ # branches: [ main, master ]
+ #pull_request:
+ # branches: [ main, master ]
+ workflow_dispatch: # Umožňuje manuální spuštění
+
+jobs:
+ build-windows:
+ name: Build for Windows
+ runs-on: windows-latest # Použije Windows runner (virtuální Windows počítač)
+
+ steps:
+ # 1. Checkout kódu z repozitáře
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ # 2. Setup Free Pascal Compiler
+ - name: Setup Free Pascal Compiler
+ run: |
+ $fpcVersion = "3.2.2"
+ $fpcInstaller = "$env:TEMP\fpc-installer.exe"
+
+ # Download FPC from SourceForge
+ # Chocolatey installs 32-bit only, but we need 64-bit for lazbuild
+ # Use the combined installer which includes both 32-bit and 64-bit
+ Write-Host "Downloading FPC 64-bit from SourceForge..."
+ $fpcUrl = "https://sourceforge.net/projects/freepascal/files/Win32/$fpcVersion/fpc-$fpcVersion.win32.and.win64.exe/download"
+
+ # Use curl with proper redirect handling
+ Write-Host "Downloading FPC installer from: $fpcUrl"
+ $ProgressPreference = 'SilentlyContinue'
+
+ # Try curl first
+ curl.exe -L --location-trusted -f -o $fpcInstaller $fpcUrl 2>&1 | Out-Null
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $fpcInstaller)) {
+ Write-Host "curl failed, trying Invoke-WebRequest..."
+ try {
+ Invoke-WebRequest -Uri $fpcUrl -OutFile $fpcInstaller -UseBasicParsing -MaximumRedirection 10 -ErrorAction Stop
+ } catch {
+ Write-Host "ERROR: Download failed - $_"
+ Write-Host "Trying alternative URL..."
+ # Alternative: try the x86_64 specific installer
+ $fpcUrlAlt = "https://sourceforge.net/projects/freepascal/files/Win32/$fpcVersion/fpc-$fpcVersion.x86_64-win64.exe/download"
+ curl.exe -L --location-trusted -f -o $fpcInstaller $fpcUrlAlt 2>&1 | Out-Null
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $fpcInstaller)) {
+ Write-Host "ERROR: All download attempts failed"
+ exit 1
+ }
+ }
+ }
+
+ # Verify file size (should be > 10MB)
+ $fileInfo = Get-Item $fpcInstaller
+ Write-Host "Downloaded file size: $($fileInfo.Length) bytes"
+ if ($fileInfo.Length -lt 10MB) {
+ Write-Host "ERROR: File too small, may be HTML error page"
+ Get-Content $fpcInstaller -TotalCount 10
+ exit 1
+ }
+
+ # Verify EXE header (MZ)
+ $fileBytes = [System.IO.File]::ReadAllBytes($fpcInstaller)
+ if ($fileBytes.Length -lt 2 -or $fileBytes[0] -ne 0x4D -or $fileBytes[1] -ne 0x5A) {
+ Write-Host "ERROR: Not a valid EXE file (missing MZ header)"
+ exit 1
+ }
+ Write-Host "File verified as valid EXE"
+
+ # Install FPC
+ Write-Host "Installing FPC..."
+ $fullInstallerPath = (Resolve-Path $fpcInstaller).Path
+
+ # Create setup.inf to ensure 64-bit is installed
+ $setupInfPath = "$env:TEMP\fpc_setup.inf"
+ $setupInfLines = @(
+ "[Setup]",
+ "Lang=default",
+ "Dir=C:\FPC",
+ "Group=Free Pascal",
+ "NoIcons=1",
+ "SetupType=full",
+ "Components=base,binutils,docs,ide,utils,make,demo,gdb,units,examples",
+ "Tasks="
+ )
+ $setupInfLines | Out-File -FilePath $setupInfPath -Encoding ASCII
+
+ # Install with setup.inf to ensure all components are installed
+ $installProcess = Start-Process -FilePath $fullInstallerPath -ArgumentList "/VERYSILENT /NORESTART /LOADINF=`"$setupInfPath`"" -Wait -PassThru -NoNewWindow
+ if ($installProcess.ExitCode -ne 0) {
+ Write-Host "ERROR: Installer exited with code $($installProcess.ExitCode)"
+ exit 1
+ }
+ Write-Host "FPC installer completed successfully"
+
+ # Wait a moment for installation to complete
+ Start-Sleep -Seconds 3
+
+ # Debug: List what was installed
+ Write-Host "Checking installation directory..."
+ if (Test-Path "C:\FPC") {
+ Write-Host "Contents of C:\FPC:"
+ Get-ChildItem "C:\FPC" -Recurse -Directory -Depth 2 | Select-Object -First 20 FullName
+ }
+
+ # Find FPC installation path - prioritize 64-bit for lazbuild
+ Write-Host "Searching for FPC installation (preferring 64-bit)..."
+
+ # First, try to find 64-bit version (needed for lazbuild)
+ $fpcPath64 = $null
+ $possiblePaths64 = @(
+ "C:\FPC\bin\x86_64-win64",
+ "C:\FPC\bin\win64",
+ "C:\FPC\$fpcVersion\bin\x86_64-win64",
+ "C:\FPC\$fpcVersion\bin\win64"
+ )
+
+ foreach ($path in $possiblePaths64) {
+ if (Test-Path $path) {
+ $ppcExe = Join-Path $path "ppcx64.exe"
+ if (Test-Path $ppcExe) {
+ Write-Host "Found FPC 64-bit at: $path"
+ $fpcPath64 = $path
+ break
+ }
+ }
+ }
+
+ # If 64-bit not found, search recursively
+ if (-not $fpcPath64) {
+ Write-Host "Searching for ppcx64.exe in C:\FPC..."
+ $ppc64Exe = Get-ChildItem -Path "C:\FPC" -Recurse -Filter "ppcx64.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
+ if ($ppc64Exe) {
+ $fpcPath64 = $ppc64Exe.DirectoryName
+ Write-Host "Found FPC 64-bit compiler at: $fpcPath64"
+ }
+ }
+
+ # Fallback to 32-bit if 64-bit not available
+ $fpcPath = $fpcPath64
+ if (-not $fpcPath) {
+ Write-Host "64-bit FPC not found, trying 32-bit..."
+ $possiblePaths32 = @(
+ "C:\FPC\bin\i386-win32",
+ "C:\FPC\bin\win32",
+ "C:\FPC\$fpcVersion\bin\i386-win32",
+ "C:\FPC\$fpcVersion\bin\win32"
+ )
+
+ foreach ($path in $possiblePaths32) {
+ if (Test-Path $path) {
+ $ppcExe = Join-Path $path "ppc386.exe"
+ if (Test-Path $ppcExe) {
+ Write-Host "Found FPC 32-bit at: $path"
+ $fpcPath = $path
+ break
+ }
+ }
+ }
+
+ # Last resort: search for any fpc.exe or ppc*.exe
+ if (-not $fpcPath) {
+ $fpcExe = Get-ChildItem -Path "C:\FPC" -Recurse -Filter "fpc.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
+ if ($fpcExe) {
+ $fpcPath = $fpcExe.DirectoryName
+ Write-Host "Found FPC executable at: $fpcPath"
+ }
+ }
+ }
+
+ if (-not $fpcPath) {
+ Write-Host "ERROR: Could not locate FPC installation"
+ Write-Host "Contents of C:\FPC\bin:"
+ if (Test-Path "C:\FPC\bin") {
+ Get-ChildItem "C:\FPC\bin" -Directory | Select-Object FullName
+ }
+ exit 1
+ }
+
+ # Add FPC to PATH
+ $env:PATH = "$fpcPath;$env:PATH"
+ echo "$fpcPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ Write-Host "Added to PATH: $fpcPath"
+
+ # Verify installation - use -iV to get version without requiring source file
+ Write-Host "Verifying FPC installation..."
+ $fpcExePath = Join-Path $fpcPath "fpc.exe"
+ if (Test-Path $fpcExePath) {
+ & $fpcExePath -iV
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "FPC verified successfully"
+ } else {
+ Write-Host "WARNING: fpc -iV failed, but continuing..."
+ }
+ } else {
+ Write-Host "WARNING: fpc.exe not found, but compiler found at: $fpcPath"
+ }
+
+ # 3. Setup Lazarus IDE
+ - name: Setup Lazarus IDE
+ run: |
+ $lazarusVersion = "3.0"
+ $lazarusInstaller = "$env:TEMP\lazarus-installer.exe"
+
+ # Try Chocolatey first (if available)
+ Write-Host "Trying Chocolatey for Lazarus..."
+ choco install lazarus --version=$lazarusVersion -y --no-progress
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "Lazarus installed via Chocolatey"
+ # Refresh PATH to pick up Chocolatey installation
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
+
+ # Wait a moment for PATH to update
+ Start-Sleep -Seconds 2
+
+ # Try to find lazbuild in common locations
+ $lazbuildPath = $null
+ $possibleLazbuildPaths = @(
+ "C:\lazarus",
+ "C:\Program Files\Lazarus",
+ "C:\Program Files (x86)\Lazarus",
+ "$env:ProgramFiles\Lazarus",
+ "$env:ProgramFiles(x86)\Lazarus"
+ )
+
+ foreach ($path in $possibleLazbuildPaths) {
+ $lazbuildExe = Join-Path $path "lazbuild.exe"
+ if (Test-Path $lazbuildExe) {
+ Write-Host "Found lazbuild at: $lazbuildExe"
+ $lazbuildPath = $path
+ $env:PATH = "$path;$env:PATH"
+ echo "$path" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ break
+ }
+ }
+
+ # If not found, search recursively
+ if (-not $lazbuildPath) {
+ Write-Host "Searching for lazbuild.exe recursively..."
+ $lazbuildExe = Get-ChildItem -Path "C:\" -Recurse -Filter "lazbuild.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
+ if ($lazbuildExe) {
+ $lazbuildPath = $lazbuildExe.DirectoryName
+ Write-Host "Found lazbuild at: $lazbuildPath"
+ $env:PATH = "$lazbuildPath;$env:PATH"
+ echo "$lazbuildPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ }
+ }
+
+ # Verify installation
+ if ($lazbuildPath) {
+ lazbuild --version
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "Lazarus verified successfully"
+ exit 0
+ }
+ } else {
+ Write-Host "WARNING: lazbuild not found after Chocolatey installation, will try SourceForge..."
+ }
+ }
+
+ # Fallback: Download from SourceForge
+ Write-Host "Chocolatey failed or Lazarus not found, downloading from SourceForge..."
+ $lazarusUrl = "https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/Lazarus%20$lazarusVersion/lazarus-$lazarusVersion-fpc-3.2.2-win64.exe/download"
+
+ # Use curl with proper redirect handling
+ Write-Host "Downloading Lazarus installer..."
+ $ProgressPreference = 'SilentlyContinue'
+ curl.exe -L --location-trusted -f -o $lazarusInstaller $lazarusUrl
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $lazarusInstaller)) {
+ Write-Host "ERROR: Download failed"
+ exit 1
+ }
+
+ # Verify file size (should be > 50MB)
+ $fileInfo = Get-Item $lazarusInstaller
+ Write-Host "Downloaded file size: $($fileInfo.Length) bytes"
+ if ($fileInfo.Length -lt 50MB) {
+ Write-Host "ERROR: File too small, may be HTML error page"
+ Get-Content $lazarusInstaller -TotalCount 10
+ exit 1
+ }
+
+ # Verify EXE header (MZ)
+ $fileBytes = [System.IO.File]::ReadAllBytes($lazarusInstaller)
+ if ($fileBytes.Length -lt 2 -or $fileBytes[0] -ne 0x4D -or $fileBytes[1] -ne 0x5A) {
+ Write-Host "ERROR: Not a valid EXE file (missing MZ header)"
+ exit 1
+ }
+ Write-Host "File verified as valid EXE"
+
+ # Install Lazarus
+ Write-Host "Installing Lazarus IDE..."
+ $fullInstallerPath = (Resolve-Path $lazarusInstaller).Path
+ $installProcess = Start-Process -FilePath $fullInstallerPath -ArgumentList "/VERYSILENT /NORESTART /DIR=C:\lazarus" -Wait -PassThru -NoNewWindow
+ if ($installProcess.ExitCode -ne 0) {
+ Write-Host "ERROR: Installer exited with code $($installProcess.ExitCode)"
+ exit 1
+ }
+
+ # Add Lazarus to PATH
+ $lazarusPath = "C:\lazarus"
+ if (-not (Test-Path $lazarusPath)) {
+ Write-Host "ERROR: Lazarus installation path not found: $lazarusPath"
+ exit 1
+ }
+ $env:PATH = "$lazarusPath;$env:PATH"
+ echo "$lazarusPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
+ # Verify installation
+ Write-Host "Verifying Lazarus installation..."
+ lazbuild --version
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "ERROR: Lazarus verification failed"
+ exit 1
+ }
+
+ # 4. Download and build LNet package
+ - name: Download and build LNet package
+ run: |
+ Write-Host "Downloading LNet from GitHub..."
+ # Use master branch (not main) - see https://github.com/PascalCorpsman/lnet
+ $lnetUrl = "https://github.com/PascalCorpsman/lnet/archive/refs/heads/master.zip"
+ $lnetZip = "$env:TEMP\lnet.zip"
+ $lnetDir = "$env:TEMP\lnet"
+
+ # Download LNet
+ Write-Host "Downloading from: $lnetUrl"
+ $ProgressPreference = 'SilentlyContinue'
+ curl.exe -L --location-trusted -f -o $lnetZip $lnetUrl
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $lnetZip)) {
+ Write-Host "ERROR: Failed to download LNet (curl exit code: $LASTEXITCODE)"
+ Write-Host "Trying alternative URL..."
+ # Try alternative URL format
+ $lnetUrlAlt = "https://github.com/PascalCorpsman/lnet/archive/master.zip"
+ curl.exe -L --location-trusted -f -o $lnetZip $lnetUrlAlt
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $lnetZip)) {
+ Write-Host "ERROR: All download attempts failed"
+ exit 1
+ }
+ }
+ Write-Host "LNet downloaded successfully"
+
+ # Extract LNet
+ Write-Host "Extracting LNet..."
+ Expand-Archive -Path $lnetZip -DestinationPath $lnetDir -Force
+
+ # Find the package files
+ $lnetPackagePath = Get-ChildItem -Path $lnetDir -Recurse -Filter "lnetvisual.lpk" | Select-Object -First 1
+ if (-not $lnetPackagePath) {
+ Write-Host "ERROR: lnetvisual.lpk not found in downloaded archive"
+ exit 1
+ }
+
+ $lnetBasePath = Get-ChildItem -Path $lnetDir -Recurse -Filter "lnetbase.lpk" | Select-Object -First 1
+ if (-not $lnetBasePath) {
+ Write-Host "ERROR: lnetbase.lpk not found in downloaded archive"
+ exit 1
+ }
+
+ Write-Host "Found LNet packages:"
+ Write-Host " Base: $($lnetBasePath.FullName)"
+ Write-Host " Visual: $($lnetPackagePath.FullName)"
+
+ # Build base package first
+ Write-Host "Building lnetbase.lpk..."
+ lazbuild --build $lnetBasePath.FullName
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "WARNING: lnetbase.lpk build failed, but continuing..."
+ } else {
+ Write-Host "lnetbase.lpk built successfully"
+ }
+
+ # Build visual package
+ Write-Host "Building lnetvisual.lpk..."
+ lazbuild --build $lnetPackagePath.FullName
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "LNet package built successfully"
+ } else {
+ Write-Host "WARNING: LNet package build failed"
+ }
+
+ # Copy LNet source files to expected location for search paths
+ Write-Host "Copying LNet source files to macos/third_party..."
+ $lnetSourceDir = "$lnetDir\lnet-master"
+ $targetLnetBaseDir = "macos\third_party\lnet"
+ $targetLnetSrcDir = "macos\third_party\lnet_src"
+
+ # Create base directory structure
+ New-Item -ItemType Directory -Force -Path $targetLnetBaseDir | Out-Null
+ New-Item -ItemType Directory -Force -Path $targetLnetSrcDir | Out-Null
+
+ # Copy lib directory as subdirectory (search path expects macos/third_party/lnet/lib/)
+ if (Test-Path "$lnetSourceDir\lib") {
+ $targetLibDir = "$targetLnetBaseDir\lib"
+ Copy-Item -Path "$lnetSourceDir\lib" -Destination $targetLibDir -Recurse -Force
+ Write-Host "Copied LNet lib directory to $targetLibDir"
+ # Verify lnet.pp exists at correct path
+ if (Test-Path "$targetLibDir\lnet.pp") {
+ Write-Host "✓ lnet.pp found at: $targetLibDir\lnet.pp"
+ } else {
+ Write-Host "WARNING: lnet.pp not found at expected location"
+ Write-Host "Contents of ${targetLibDir}:"
+ Get-ChildItem -Path $targetLibDir -Filter "*.pp" | Select-Object -First 5 Name
+ exit 1
+ }
+ } else {
+ Write-Host "ERROR: LNet lib directory not found at $lnetSourceDir\lib"
+ exit 1
+ }
+
+ # Copy lazaruspackage directory (contains lclnet.pas and lnetcomponents.pas)
+ if (Test-Path "$lnetSourceDir\lazaruspackage") {
+ Copy-Item -Path "$lnetSourceDir\lazaruspackage" -Destination $targetLnetSrcDir -Recurse -Force
+ Write-Host "Copied LNet lazaruspackage to $targetLnetSrcDir"
+ } else {
+ Write-Host "ERROR: LNet lazaruspackage directory not found at $lnetSourceDir\lazaruspackage"
+ exit 1
+ }
+
+ # Verify key files are available at correct paths
+ $lnetComponentsPath = "$targetLnetSrcDir\lazaruspackage\lnetcomponents.pas"
+ $lclnetPath = "$targetLnetSrcDir\lazaruspackage\lclnet.pas"
+ $lnetPath = "$targetLnetBaseDir\lib\lnet.pp"
+
+ if (Test-Path $lnetComponentsPath) {
+ Write-Host "✓ lnetcomponents.pas available at: $lnetComponentsPath"
+ } else {
+ Write-Host "ERROR: lnetcomponents.pas not found at: $lnetComponentsPath"
+ exit 1
+ }
+
+ if (Test-Path $lclnetPath) {
+ Write-Host "✓ lclnet.pas available at: $lclnetPath"
+ } else {
+ Write-Host "ERROR: lclnet.pas not found at: $lclnetPath"
+ exit 1
+ }
+
+ if (Test-Path $lnetPath) {
+ Write-Host "✓ lnet.pp available at: $lnetPath"
+ } else {
+ Write-Host "ERROR: lnet.pp not found at: $lnetPath"
+ exit 1
+ }
+
+ Write-Host "All LNet files copied and verified successfully!"
+
+ # 5. Verify dependencies
+ - name: Verify dependencies
+ run: |
+ Write-Host "Verifying all required dependencies..."
+
+ # Check dglopengl.pas
+ if (Test-Path "units\dglOpenGL.pas") {
+ Write-Host "✓ dglOpenGL.pas found"
+ } else {
+ Write-Host "ERROR: dglOpenGL.pas not found"
+ exit 1
+ }
+
+ # Check bass.pas
+ if (Test-Path "units\bass.pas") {
+ Write-Host "✓ bass.pas found"
+ } else {
+ Write-Host "ERROR: bass.pas not found"
+ exit 1
+ }
+
+ # Check SDL2-for-Pascal
+ if (Test-Path "units\sdl2_for_pascal") {
+ Write-Host "✓ SDL2-for-Pascal found"
+ } else {
+ Write-Host "ERROR: SDL2-for-Pascal not found"
+ exit 1
+ }
+
+ # Check LNet source files (may be in downloaded archive or in repo)
+ $lnetComponentsFound = $false
+ $possibleLnetPaths = @(
+ "macos\third_party\lnet_src\lazaruspackage\lnetcomponents.pas",
+ "macos/third_party/lnet_src/lazaruspackage/lnetcomponents.pas",
+ "$env:TEMP\lnet\lnet-master\lazaruspackage\lnetcomponents.pas"
+ )
+
+ foreach ($path in $possibleLnetPaths) {
+ if (Test-Path $path) {
+ Write-Host "✓ LNet source files found at: $path"
+ $lnetComponentsFound = $true
+ break
+ }
+ }
+
+ if (-not $lnetComponentsFound) {
+ Write-Host "WARNING: LNet source files not found in expected locations"
+ Write-Host "LNet was downloaded and built, should be available via compiled packages"
+ Write-Host "Continuing anyway..."
+ }
+
+ # Check LazOpenGLContext (should be in Lazarus IDE)
+ Write-Host "✓ LazOpenGLContext should be part of Lazarus IDE (checked in RequiredPackages)"
+
+ # Note: synapse is not needed anymore (replaced with fphttpclient)
+ Write-Host "Note: synapse is not required (replaced with fphttpclient)"
+
+ Write-Host "All dependencies verified!"
+
+ # 6. Build Client
+ - name: Build Client
+ run: |
+ cd client
+ lazbuild --build-mode=default fpc_atomic.lpi
+ if ($LASTEXITCODE -ne 0) { exit 1 }
+
+ # 7. Build Launcher
+ - name: Build Launcher
+ run: |
+ cd launcher
+ lazbuild --build-mode=default atomic_launcher.lpi
+ if ($LASTEXITCODE -ne 0) { exit 1 }
+
+ # 8. Build Server
+ - name: Build Server
+ run: |
+ cd server
+ lazbuild --build-mode=default atomic_server.lpi
+ if ($LASTEXITCODE -ne 0) { exit 1 }
+
+ # 9. Build CD Data Extractor
+ - name: Build CD Data Extractor
+ run: |
+ cd cd_data_extractor_src
+ lazbuild --build-mode=default cd_data_extractor.lpi
+ if ($LASTEXITCODE -ne 0) { exit 1 }
+
+ # 10. Create artifacts directory
+ - name: Prepare artifacts
+ run: |
+ New-Item -ItemType Directory -Force -Path windows\bin
+ Write-Host "Looking for compiled binaries..."
+
+ # Binaries are compiled to the root directory (one level up from project folders)
+ $binaries = @(
+ "fpc_atomic.exe",
+ "atomic_launcher.exe",
+ "atomic_server.exe",
+ "cd_data_extractor.exe"
+ )
+
+ foreach ($bin in $binaries) {
+ if (Test-Path $bin) {
+ Write-Host "Found: $bin"
+ Move-Item $bin "windows\bin\" -Force
+ } else {
+ Write-Host "WARNING: $bin not found"
+ }
+ }
+
+ # Copy DLL files (ai.dll, bass.dll, SDL2.dll) to artifacts
+ Write-Host "Copying DLL files..."
+ $dllFiles = @(
+ "bin\ai.dll",
+ "bin\bass.dll",
+ "bin\SDL2.dll"
+ )
+
+ foreach ($dll in $dllFiles) {
+ if (Test-Path $dll) {
+ Write-Host "Found: $dll"
+ Copy-Item $dll "windows\bin\" -Force
+ } else {
+ Write-Host "WARNING: $dll not found"
+ }
+ }
+
+ # Copy data directory to artifacts
+ Write-Host "Copying data directory..."
+ if (Test-Path "data") {
+ Copy-Item -Path "data" -Destination "windows\bin\data" -Recurse -Force
+ Write-Host "✓ data directory copied to windows\bin\data"
+ } else {
+ Write-Host "WARNING: data directory not found"
+ }
+
+ Write-Host "Artifacts prepared. Contents of windows\bin:"
+ Get-ChildItem windows\bin\ | Format-Table
+
+ # 11. Upload artifacts (soubory ke stažení)
+ - name: Upload Windows binaries
+ uses: actions/upload-artifact@v4
+ with:
+ name: FPCAtomic-Windows
+ path: windows/bin/*
+ retention-days: 30 # Uchovat 30 dní
diff --git a/.github/workflows/create-game-release.yml b/.github/workflows/create-game-release.yml
new file mode 100644
index 0000000..55aa618
--- /dev/null
+++ b/.github/workflows/create-game-release.yml
@@ -0,0 +1,130 @@
+name: Create Game Release
+
+# This workflow creates a release with game builds for Windows and Linux
+# macOS builds are created locally, not via GitHub Actions
+# Responds only to tags starting with "v" (e.g., v1.0.0), but NOT "server-v*"
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Version tag (e.g., v1.0.0)'
+ required: true
+ push:
+ tags:
+ - 'v*' # Triggers on tags starting with 'v' (e.g., v1.0.0)
+
+jobs:
+ create-release:
+ name: Create Game Release
+ runs-on: ubuntu-latest
+ # Don't run for server tags - they have their own workflow
+ if: ${{ !startsWith(github.ref, 'refs/tags/server-v') }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Extract version
+ id: version
+ run: |
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
+ VERSION="${{ github.event.inputs.version }}"
+ elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
+ VERSION=${GITHUB_REF#refs/tags/}
+ else
+ VERSION="dev-${GITHUB_SHA::8}"
+ fi
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ echo "Version: $VERSION"
+
+ - name: Download Windows artifacts
+ uses: dawidd6/action-download-artifact@v3
+ continue-on-error: true
+ with:
+ workflow: build-windows.yml
+ name: FPCAtomic-Windows
+ path: release-assets/windows
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Download Linux artifacts
+ uses: dawidd6/action-download-artifact@v3
+ continue-on-error: true
+ with:
+ workflow: build-linux.yml
+ name: FPCAtomic-Linux
+ path: release-assets/linux
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Prepare release assets
+ run: |
+ mkdir -p release-assets
+ echo "Preparing release assets for ${{ steps.version.outputs.version }}"
+
+ # Check which platforms are available
+ if [ -d "release-assets/windows" ] && [ "$(ls -A release-assets/windows 2>/dev/null)" ]; then
+ echo "✓ Windows binaries found"
+ # Create ZIP for Windows
+ cd release-assets/windows
+ zip -r ../FPCAtomic-Windows-${{ steps.version.outputs.version }}.zip .
+ cd ../..
+ fi
+
+ if [ -d "release-assets/linux" ] && [ "$(ls -A release-assets/linux 2>/dev/null)" ]; then
+ echo "✓ Linux binaries found"
+ # Create tar.gz for Linux
+ cd release-assets/linux
+ tar -czf ../FPCAtomic-Linux-${{ steps.version.outputs.version }}.tar.gz .
+ cd ../..
+ fi
+
+ # List all prepared files
+ echo "Release assets prepared:"
+ ls -lh release-assets/*.{zip,tar.gz} 2>/dev/null || echo "⚠️ No archives found - make sure build workflows have run for this tag"
+
+ # If no artifacts found, create at least a placeholder
+ if [ ! -f "release-assets/FPCAtomic-Windows-${{ steps.version.outputs.version }}.zip" ] && \
+ [ ! -f "release-assets/FPCAtomic-Linux-${{ steps.version.outputs.version }}.tar.gz" ]; then
+ echo "⚠️ WARNING: No build artifacts found. Release will be created but without binaries."
+ echo "⚠️ WARNING: Make sure to run build workflows (build-windows.yml, build-linux.yml) first."
+ fi
+
+ - name: Create Release
+ if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
+ uses: softprops/action-gh-release@v1
+ with:
+ name: FPC Atomic ${{ steps.version.outputs.version }}
+ tag_name: ${{ steps.version.outputs.version }}
+ body: |
+ ## FPC Atomic ${{ steps.version.outputs.version }}
+
+ ### 🎮 Game Release
+
+ This release contains game binaries for Windows and Linux and macOS.
+ To play the game, you need to extract the original graphics from the game disc and provide them as requested by the game.
+
+ ### 📦 Available Downloads
+
+ - **Windows**: Download `FPCAtomic-Windows-${{ steps.version.outputs.version }}.zip` and extract to play
+ - **Linux**: Download `FPCAtomic-Linux-${{ steps.version.outputs.version }}.tar.gz` and extract to play
+ - **macOS**: macOS builds are created locally. See [macos/README_mac.md](../macos/README_mac.md) for build instructions.
+
+ ### 🚀 Installation
+
+ See the main [README.md](README.md) for installation instructions.
+
+ ### 📝 Notes
+
+ - For macOS, you may need to remove quarantine attributes running: `remove_quarantine.command`
+ - Linux users may need to install dependencies: `sudo apt-get install libssl-dev`
+ - Windows Defender may flag unsigned executables - this is normal for unsigned builds
+
+ ### 🔗 Related Releases
+
+ - **Fly.io Server**: See [server releases](https://github.com/${{ github.repository }}/releases) tagged with `server-v*` for cloud server deployment
+ draft: false
+ prerelease: false
+ files: |
+ release-assets/*.zip
+ release-assets/*.tar.gz
+ token: ${{ secrets.GITHUB_TOKEN }}
+
diff --git a/.gitignore b/.gitignore
index e1043a1..9f64561 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,16 @@
# Source: https://github.com/github/gitignore/blob/main/Global/Lazarus.gitignore
+# Exception: Required libraries in bin/ directory for CI/CD builds
+# These are downloaded from GitHub releases and needed for linking
+# Must be before the global *.dll, *.so rules
+!bin/libbass.so
+!bin/libai.so
+!bin/bass.dll
+!bin/ai.dll
+!bin/SDL2.dll
+!bin/Linux_sound_install_script.sh
+!bin/fpc_atomic.version
+
# Lazarus compiler-generated binaries (safe to delete)
*.exe
*.dll
@@ -27,12 +38,32 @@
backup/
*.bak
lib/
-release/
# Application bundle for Mac OS
*.app/
+# Full game data - for flyio server
+flyio_server/data/
+
# Atomic files
server/stats.txt
stats.txt
+.env
+macos/app_arm64/data
+macos/app_x86_64/data
+macos/app_universal/data
+bin/macos/
+data
+
+# DMG files for distribution
+releases/
+releases/*.dmg
+releases/*.temp.dmg
+
+# Notarization temporary files
+*.zip
+!*.lpi
+
+# Fly.io secrets (keep your own secrets private)
+# Note: fly.toml is now committed with placeholder, actual app name comes from .env
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..dde5607
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,13 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build with FPC",
+ "type": "shell",
+ "command": "fpc",
+ "args": ["-MObjFPC", "-Sh", "launcher/atomic_launcher.lpr"],
+ "group": "build",
+ "problemMatcher": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 9fcd885..a74236e 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,27 @@
# FPC Atomic
-Author : Uwe Schächterle (Corpsman)
-Homepage : https://www.Corpsman.de
-Source : https://github.com/PascalCorpsman/fpc_atomic
-Wiki : https://en.wikipedia.org/wiki/Atomic_Bomberman
+Author : Uwe Schächterle (Corpsman)
+Homepage : https://www.Corpsman.de
+Source : https://github.com/PascalCorpsman/fpc_atomic
+Wiki : https://en.wikipedia.org/wiki/Atomic_Bomberman
+
+MacOS version : Pavel Zvěřina
## Description
FPC Atomic is a complete reimplementation of the original Atomic Bomberman game (from 1997). This repository hosts only the source code, as the graphics and sounds are copyrighted by Interplay Productions. To play the game, you need to extract the original graphics from the game disc and provide them as requested by the game.
+## Differences from the original fork
+
+This version is a fork of the original FPC Atomic implementation by Uwe Schächterle (Corpsman). While maintaining compatibility with the original game mechanics, this fork focuses on:
+- Native build macOS (Apple Silicon and Intel)
+- Cross-platform game compatibility and native builds for all major platforms
+- Build and deploy game server on [fly.io](https://fly.io)
+- Modern deployment options (automated builds)
+- Enhanced user experience (better controller support, network optimizations)
+- Support of Game Controllers ()
+- Support for up to 4 players on a single computer (2 Keyboards, 2 Game Controllers)
+- Bug fixes and animation corrections
+
## Preview:
@@ -15,15 +29,13 @@ FPC Atomic is a complete reimplementation of the original Atomic Bomberman game
## What needs to be done to play the game?
-The steps shown here are only needed to be done once (for installation).
-
-
1. get the Atomic Bomberman CD-content (buy the game it is worth it!) and store it on your harddrive
1.1 if you want all animations download and merge the expansion pack from [here](https://www.oocities.org/timessquare/tower/4056/ani.html) or use this [direct download link](https://www.oocities.org/timessquare/tower/4056/download/ani.zip) link is broken use [new link](https://www.geocities.ws/mheid.geo/download/ani.zip)
1.2 extract the content of ani.zip into the CD-Content "/DATA/ANI" subfolder
-2. download the atomic_launcher from the latest release [here](https://github.com/PascalCorpsman/fpc_atomic/releases/latest) and store it on your harddisc
-
+
+2. download the files from the latest release [here](https://github.com/zverinapavel/fpc_atomic_macos/releases/latest) and store it on your harddisc
+
2.1 Linux users will need to
>
> chmod +x atomic_launcher
@@ -38,10 +50,11 @@ The steps shown here are only needed to be done once (for installation).
4.2 Click "start extraction"
5. read the [manual](MANUAL.md)
5.5 if you are a Linux user run the "Linux_sound_install_script.sh"
-6. start the game by executing "atomic_launcher" and enjoy
+6. start the game by executing "atomic_launcher" or "FPCAtomic" application and enjoy
## How do i get updates ?
-By using the launcher you can click the "check for update" feature to check wether there are updates available. If so, the launcher automatically asks you to download the updates.
+By using the launcher you can click the "check for update" feature to check wether there are updates available. If so, the launcher automatically asks you to download the updates.
+NOTE: This feature is not supported on MacOS
## Differences to the original
@@ -62,17 +75,50 @@ See the license.md file located at [license.md](license.md) for details about th
## What needs to be done to compile the code ?
+### General Requirements
+
1. Install Lazarus IDE from https://www.lazarus-ide.org/
2. Download dglopengl.pas from https://github.com/saschawillems/dglopengl and store it in the "units" folder
3. Download bass.pas from https://www.un4seen.com/ and store it in the "units" folder
- - Linux users: copy libbass.so to "/usr/lib/" or run "Linux_sound_install_script.sh"
- - Windows users: copy bass.dll from the bin folder into the repository root folder
-4. Download synapse from http://www.ararat.cz/synapse/doku.php/download and store it in a new subfolder "synapse"
-5. Install the following packages into the Lazarus IDE:
+4. Install the following packages into the Lazarus IDE:
- 'Lnet' from https://github.com/almindor/L-Net or the fixed version from https://github.com/PascalCorpsman/lnet
- 'LazOpenGLContext' (from the list of available packages inside the IDE)
-6. Download SDL2-Header from https://github.com/PascalCorpsman/SDL2-for-Pascal and store the content its "units" folder in a new subfolder "sdl2_for_pascal"
-7. Add the paths from 4. and 6. as searchpaths for all .lpi files (at least client, launcher and server) (in the IDE project -> settings -> compilersettings -> paths). Ignore the not resolvable searchpaths.
+5. Download SDL2-Header from https://github.com/PascalCorpsman/SDL2-for-Pascal and store the content its "units" folder in a new subfolder "sdl2_for_pascal"
+6. Add the paths from 5. as searchpaths for all .lpi files (at least client, launcher and server) (in the IDE project -> settings -> compilersettings -> paths). Ignore the not resolvable searchpaths.
+
+### Platform-Specific Instructions
+
+#### Linux
+- Copy libbass.so to "/usr/lib/" or run "Linux_sound_install_script.sh"
+
+#### Windows
+- Copy bass.dll from the bin folder into the repository root folder
+
+#### macOS
+
+**Installation (for end users):**
+
+1. Download the latest release from the [releases page](https://github.com/PascalCorpsman/fpc_atomic/releases/latest)
+2. Drag the FPCAtomic folder to your Applications folder
+3. Open the FPCAtomic folder and double-click `FPCAtomicLauncher.app` to start the launcher
+4. If the data directory is included, the game is ready to play!
+ - If not, click "Run CD data extractor", set the path to your Atomic Bomberman CD data, and click "Start extraction"
+5. If you copied the apps via AirDrop or downloaded them, you may need to:
+ - Double-click `remove_quarantine.command` to remove macOS quarantine
+ - This allows the apps to run without security warnings
+6. After extraction, you can launch the game from the launcher
+
+**System Requirements:**
+- macOS 11.0 (Big Sur) or later
+- For arm64 version: Apple Silicon Mac (M1/M2/M3 or later)
+- For x86_64 version: Intel Mac
+- For universal version: Any Mac (automatically uses the correct architecture)
+
+**Building from source:**
+- **See [macos/README_mac.md](macos/README_mac.md) for detailed macOS build instructions**
+- **Quick start:** `./macos/tools/build_all_arm64.command` (ARM64) or `./macos/tools/build_all_x86_64.command` (x86_64)
+- Copy libbass.dylib from the bass24-osx into macos/lib/arm64 and macos/lib/x86_64
+- For x86_64 builds, Rosetta Homebrew is required (installed automatically via `install_rosetta_homebrew.command`)
!! Attention !!
@@ -87,13 +133,31 @@ The AI that is delivered with this repository is more a try than a real AI, and
Read the manual section [Console commands](MANUAL.md#console-commands) to load and unload your ai without the need to restart the application.
+### Enhancements and bug fixies
+
+This fork includes significant improvements and new features:
+
+- **Multi-platform builds**: Added native builds for macOS (Apple Silicon and Intel)
+- **Resizable main window**: Main window of the game can be resized now
+- **Improved networking**: Network connection runs on a separate thread for better performance
+- **Cross-platform multiplayer**: Cross-play support between Windows, macOS, and Linux
+- **Cloud server support**: Server deployment on Fly.io for online multiplayer
+- **Enhanced controller support**: Improved joystick support with fine-tuned controls for both joystick and D-Pad
+- **Local multiplayer**: Support for up to 4 players on a single computer
+
+- **Network optimization**: Player movement prediction and extrapolation for smoother gameplay on low-quality networks
+- **Animation fixes**: Corrected "locked in" animations and fixed cornered animation bug (when bomberman is locked and cannot move)
+- **CI/CD automation**: GitHub Actions for automated builds (Windows, Linux, and Fly.io Docker server)
+
+
## External known sites which link to this repository
- https://osgameclones.com/atomic-bomberman/
- https://www.myabandonware.com/game/atomic-bomberman-bat
## Contributors
Idea : Interplay Productions
-Implementation : Uwe Schächterle
+Original Implementation : Uwe Schächterle (Corpsman)
+Enhanced Implementation & Cross-platform Support : Pavel Zverina
Graphics : Interplay Productions
Leveldesign : Interplay Productions
-Testing : Uwe Schächterle
+Testing : Uwe Schächterle, Pavel Zverina
diff --git a/ai/ai.lpi b/ai/ai.lpi
index 834203a..b2ac7c9 100644
--- a/ai/ai.lpi
+++ b/ai/ai.lpi
@@ -13,8 +13,48 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ai_c/ai_types.h b/ai_c/ai_types.h
index da854c1..c7cc292 100644
--- a/ai_c/ai_types.h
+++ b/ai_c/ai_types.h
@@ -83,7 +83,7 @@ typedef struct
int AvailableBombs; // The number of bombs the AI is allowed to place at the moment. This will decrease when a bomb is placed and increase if the bomb explodes. It is 0 if the player has the "no bomb" disease.
float Speed; // The actual speed of the player in fields per second.
uint32_t Abilities; // A bitfield of abilities. If the bit is 1, then the ability is available.
- IsIll: Boolean; // If true the Player has a Disease (Unknown which)
+ bool IsIll; // If true the Player has a Disease (Unknown which)
} TAiPlayerInfo_t;
typedef enum
diff --git a/bin/Linux_sound_install_script.sh b/bin/Linux_sound_install_script.sh
new file mode 100755
index 0000000..3c1c124
--- /dev/null
+++ b/bin/Linux_sound_install_script.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+echo
+echo This is the fpc_atomic sound installation script for Linux
+echo you only have to run this script on the very first time
+echo you want to use the game.
+echo
+echo You need root rights to install bass.so
+echo
+echo Press Return to continue
+echo
+read cmd
+sudo cp libbass.so /usr/lib
+sudo chmod o+r /usr/lib/libbass.so
+echo
+echo Finished, have a nice day
+echo
diff --git a/bin/SDL2.dll b/bin/SDL2.dll
new file mode 100644
index 0000000..3131862
Binary files /dev/null and b/bin/SDL2.dll differ
diff --git a/bin/ai.dll b/bin/ai.dll
new file mode 100644
index 0000000..5f57e8e
Binary files /dev/null and b/bin/ai.dll differ
diff --git a/bin/bass.dll b/bin/bass.dll
new file mode 100644
index 0000000..825b68e
Binary files /dev/null and b/bin/bass.dll differ
diff --git a/bin/libai.so b/bin/libai.so
new file mode 100755
index 0000000..626d70e
Binary files /dev/null and b/bin/libai.so differ
diff --git a/bin/libbass.so b/bin/libbass.so
new file mode 100644
index 0000000..a5c6809
Binary files /dev/null and b/bin/libbass.so differ
diff --git a/cd_data_extractor_src/cd_data_extractor.lpi b/cd_data_extractor_src/cd_data_extractor.lpi
index 935408b..95a126f 100644
--- a/cd_data_extractor_src/cd_data_extractor.lpi
+++ b/cd_data_extractor_src/cd_data_extractor.lpi
@@ -12,8 +12,48 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -45,7 +85,7 @@
-
+
diff --git a/cd_data_extractor_src/cd_data_extractor.lpr b/cd_data_extractor_src/cd_data_extractor.lpr
index 20cec1b..5876151 100644
--- a/cd_data_extractor_src/cd_data_extractor.lpr
+++ b/cd_data_extractor_src/cd_data_extractor.lpr
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Program cd_data_extractor;
{$MODE objfpc}{$H+}
@@ -24,7 +29,7 @@
athreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, Unit1, Unit2, upcx, uopengl_animation, uopengl_spriteengine,
+ Forms, Unit1, Unit2, uopengl_animation, uopengl_spriteengine,
uopengl_graphikengine;
{$R *.res}
diff --git a/cd_data_extractor_src/cd_data_extractor_nogui.lpi b/cd_data_extractor_src/cd_data_extractor_nogui.lpi
index c510a2e..ca0e106 100644
--- a/cd_data_extractor_src/cd_data_extractor_nogui.lpi
+++ b/cd_data_extractor_src/cd_data_extractor_nogui.lpi
@@ -1,99 +1,99 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
diff --git a/cd_data_extractor_src/ucdextractor.pas b/cd_data_extractor_src/ucdextractor.pas
index a089de0..fca0a2b 100644
--- a/cd_data_extractor_src/ucdextractor.pas
+++ b/cd_data_extractor_src/ucdextractor.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit ucdextractor;
{$MODE ObjFPC}{$H+}
@@ -478,11 +483,17 @@
Var
s: String;
Begin
+{$IFDEF Darwin}
+ // On macOS, check for FPCAtomic.app bundle
+ s := 'FPCAtomic.app';
+ result := DirectoryExists(IncludeTrailingPathDelimiter(aFolder) + s);
+{$ELSE}
s := 'fpc_atomic';
{$IFDEF Windows}
s := s + '.exe';
{$ENDIF}
result := FileExists(IncludeTrailingPathDelimiter(aFolder) + s);
+{$ENDIF}
End;
(*
@@ -512,6 +523,58 @@
* if match is not found result will be ''
*)
+(*
+ * Fixes ANI files that have leading whitespace by removing it and creating a corrected version
+ * Returns the path to the corrected file (or original if no fix was needed)
+ *)
+Function FixAniFileIfNeeded(Const AniFilename: String): String;
+Var
+ fs: TFileStream;
+ firstByte: Byte;
+ correctedFilename: String;
+ correctedStream: TFileStream;
+ buffer: Array[0..1023] Of Byte;
+ bytesRead: Integer;
+Begin
+ result := AniFilename;
+ If Not FileExists(AniFilename) Then Begin
+ exit;
+ End;
+ // Check if file starts with whitespace (0x20 = space)
+ fs := TFileStream.Create(AniFilename, fmOpenRead);
+ Try
+ If fs.Size < 11 Then Begin
+ exit; // File too small
+ End;
+ fs.Read(firstByte, 1);
+ If firstByte <> $20 Then Begin
+ exit; // No leading space, file is OK
+ End;
+ // File has leading space, create corrected version
+ correctedFilename := ChangeFileExt(AniFilename, '') + '-corrected' + ExtractFileExt(AniFilename);
+ If FileExists(correctedFilename) Then Begin
+ // Corrected file already exists, use it
+ result := correctedFilename;
+ exit;
+ End;
+ // Create corrected file (skip first byte)
+ fs.Position := 1; // Skip the leading space
+ correctedStream := TFileStream.Create(correctedFilename, fmCreate);
+ Try
+ While fs.Position < fs.Size Do Begin
+ bytesRead := fs.Read(buffer[0], SizeOf(buffer));
+ correctedStream.Write(buffer[0], bytesRead);
+ End;
+ AddLog(' Fixed ANI file (removed leading space): ' + ExtractFileName(AniFilename) + ' -> ' + ExtractFileName(correctedFilename));
+ result := correctedFilename;
+ Finally
+ correctedStream.Free;
+ End;
+ Finally
+ fs.Free;
+ End;
+End;
+
Function GetFileByMatch(Folder, Match: String): String;
Var
sl: TStringList;
@@ -573,6 +636,8 @@
AddLog(' Error: could not find: ' + Job.SourceAni);
exit;
End;
+ // Fix ANI file if it has leading whitespace
+ AniFilename := FixAniFileIfNeeded(AniFilename);
ani := TAniFile.Create();
If Not ani.LoadFromFile(AniFilename) Then Begin
ani.free;
diff --git a/cd_data_extractor_src/unit1.pas b/cd_data_extractor_src/unit1.pas
index 608ef1b..e4e6f9d 100644
--- a/cd_data_extractor_src/unit1.pas
+++ b/cd_data_extractor_src/unit1.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit Unit1;
{$MODE objfpc}{$H+}
@@ -67,6 +72,8 @@
{ TForm1 }
Procedure TForm1.FormCreate(Sender: TObject);
+Var
+ defaultAtomicFolder: String;
Begin
IniPropStorage1.IniFileName := 'settings.ini';
(*
@@ -74,7 +81,30 @@
*)
caption := DefCaption;
label1.caption := ConcatRelativePath(ExtractFilePath(ParamStr(0)), IniPropStorage1.ReadString('CD-Root', ''));
- label2.caption := ConcatRelativePath(ExtractFilePath(ParamStr(0)), IniPropStorage1.ReadString('FPC-Atomic', ''));
+
+ // Set default FPC Atomic folder
+{$IFDEF Darwin}
+ // On macOS, set default to relative path ../../../ (three levels up from Contents/MacOS/)
+ // From: .../FPCAtomicLauncher.app/Contents/MacOS/
+ // To: .../app_arm64/
+ defaultAtomicFolder := IniPropStorage1.ReadString('FPC-Atomic', '');
+ If defaultAtomicFolder = '' Then Begin
+ // Use relative path ../../../ from the executable location
+ defaultAtomicFolder := '..' + PathDelim + '..' + PathDelim + '..' + PathDelim;
+ defaultAtomicFolder := ExcludeTrailingPathDelimiter(defaultAtomicFolder);
+ End;
+ label2.caption := ConcatRelativePath(ExtractFilePath(ParamStr(0)), defaultAtomicFolder);
+{$ELSE}
+ // On Windows/Linux, set default to the directory where the executable is located
+ defaultAtomicFolder := IniPropStorage1.ReadString('FPC-Atomic', '');
+ If defaultAtomicFolder = '' Then Begin
+ // Use the directory where the executable is located
+ defaultAtomicFolder := ExtractFilePath(ParamStr(0));
+ defaultAtomicFolder := ExcludeTrailingPathDelimiter(defaultAtomicFolder);
+ End;
+ label2.caption := ConcatRelativePath(ExtractFilePath(ParamStr(0)), defaultAtomicFolder);
+{$ENDIF}
+
memo1.clear;
Constraints.MinWidth := Width;
Constraints.MinHeight := Height;
@@ -109,9 +139,29 @@
End;
Procedure TForm1.Button4Click(Sender: TObject);
+Var
+ defaultDir: String;
Begin
// Set FPC Atomic Folder
SelectDirectoryDialog1.Title := button4.caption;
+{$IFDEF Darwin}
+ // On macOS, always set initial directory to two levels up (../../)
+ defaultDir := ExpandFileName(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + '..' + PathDelim + '..' + PathDelim);
+ defaultDir := ExcludeTrailingPathDelimiter(defaultDir);
+ If DirectoryExists(defaultDir) Then Begin
+ SelectDirectoryDialog1.InitialDir := defaultDir;
+ End
+ Else Begin
+ // Fallback to label2.caption if ../../ doesn't exist
+ If label2.caption <> '' Then Begin
+ SelectDirectoryDialog1.InitialDir := label2.caption;
+ End;
+ End;
+{$ELSE}
+ If label2.caption <> '' Then Begin
+ SelectDirectoryDialog1.InitialDir := label2.caption;
+ End;
+{$ENDIF}
If SelectDirectoryDialog1.Execute Then Begin
If CheckFPCAtomicFolder(SelectDirectoryDialog1.FileName) Then Begin
label2.Caption := SelectDirectoryDialog1.FileName;
@@ -121,7 +171,11 @@
End;
End
Else Begin
+{$IFDEF Darwin}
+ showmessage('Error, the folder should at least contain FPCAtomic.app');
+{$ELSE}
showmessage('Error, the folder should at least contain the executable for fpc_atomic');
+{$ENDIF}
End;
End;
End;
diff --git a/client/fpc_atomic.lpi b/client/fpc_atomic.lpi
index 104e26e..cd55e97 100644
--- a/client/fpc_atomic.lpi
+++ b/client/fpc_atomic.lpi
@@ -14,8 +14,56 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -33,19 +81,16 @@
-
+
-
+
-
+
-
-
-
-
+
@@ -199,7 +244,7 @@
-
+
@@ -210,7 +255,7 @@
-
+
diff --git a/client/fpc_atomic.lpr b/client/fpc_atomic.lpr
index f4a7b46..6ee344c 100644
--- a/client/fpc_atomic.lpr
+++ b/client/fpc_atomic.lpr
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Program fpc_atomic;
{$MODE objfpc}{$H+}
@@ -21,7 +26,9 @@
cthreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, Unit1, Unit18, uatomic, ukeyboarddialog, ukeygrabber;
+ Forms, Unit1, Unit18,
+ SysUtils
+ ;
Begin
// Do not Report if there is no error, that only confuses player..
diff --git a/client/uatomic.pas b/client/uatomic.pas
index 4a3c3d7..5160be3 100644
--- a/client/uatomic.pas
+++ b/client/uatomic.pas
@@ -1,476 +1,499 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uatomic;
-
-{$MODE ObjFPC}{$H+}
-
-{$I globaldefines.inc}
-
-Interface
-
-Uses
- Classes, SysUtils, uvectormath, uatomic_common
- , Graphics
- , uGraphics
- , uopengl_animation
- , uopengl_graphikengine
- ;
-
-Type
-
- TGameState = (
- gs_MainMenu, // Der Spieler ist im Hauptmenü
- gs_Gaming // Das Spiel läuft
- );
-
- tAtomicAnimation = (
- aaStandStill,
- aaWalk,
- aaKick, // Kicken
- aaPunch, // Weg schlagen (Roter Handschu)
- aaPup // Die Pupserkrankheit
- );
-
- TAnimation = Record
- Ani: TOpenGL_Animation;
- OffsetX, OffsetY: integer;
- End;
-
- TAnimations = Array Of TAnimation;
-
- { TAtomic }
-
- TAtomic = Class
- private
- fDieAnimations: TAnimations;
- fLockedInAnimations: TAnimations;
- fZenAnimations: TAnimations;
- fAnimations: Array[tAtomicAnimation] Of TAnimation;
- fShadowTex: TGraphikItem;
-
- public
- FlameEnd, FlameCross, FlameMiddle: TOpenGL_Animation;
- Bomb: TAnimation;
- Bomb_dud: TAnimation;
- Bomb_trigger: TAnimation;
- Bomb_Wobble: TAnimation;
-
- Constructor Create(); virtual;
- Destructor Destroy(); override;
- Function GetAnimTimeInMs(Anim: TRenderAnimation; Value: uint16): Integer;
- Function InitAsColor(path: String; aTargetColor: TRGB): Boolean;
-
- Procedure Render(Const Info: TAtomicInfo; Edge: Boolean);
- End;
-
- TAtomics = Array[0..length(PlayerColors) - 1] Of TAtomic;
-
-Implementation
-
-Uses
- math
- , dglOpenGL
- , IntfGraphics
- , fpImage
- ;
-
-Function LoadColorTabledImage(PNGImage: String; PlayerColor: TRGB): TBitmap;
-Var
- png: TPortableNetworkGraphic;
- bi: TBitmap;
- IntfImgi, IntfImgo: TLazIntfImage;
- i, j, k: Integer;
- ci, co: TFPColor;
- m, r, g, b: Integer;
- n: integer;
-Begin
- If Not FileExists(PNGImage) Then Begin
- result := Nil;
- exit;
- End;
- png := TPortableNetworkGraphic.Create;
- png.LoadFromFile(PNGImage);
- bi := TBitmap.create;
- bi.Assign(png);
- png.free;
- IntfImgi := TLazIntfImage.create(0, 0);
- IntfImgi.LoadFromBitmap(bi.Handle, Bi.MaskHandle);
- intfimgo := TLazIntfImage.create(0, 0);
- IntfImgo.LoadFromBitmap(bi.Handle, Bi.MaskHandle);
- For i := 0 To bi.width - 1 Do
- For j := 0 To bi.height - 1 Do Begin
- ci := IntfImgi.Colors[i, j];
- r := ci.red Shr 8;
- g := ci.green Shr 8;
- b := ci.blue Shr 8;
- If (g > r) And (g > b) Then Begin
- n := (r + b) Div 2;
- k := (g - n);
- r := n + (k * (PlayerColor.r)) Div 100;
- g := n + (k * (PlayerColor.g)) Div 100;
- b := n + (k * (PlayerColor.b)) Div 100;
- (*
- Tritt nur auf wenn die PlayerColor Werte > 100 haben
- *)
- m := max(r, max(g, b));
- If m > 255 Then Begin
- r := round(r * 255 / m);
- g := round(g * 255 / m);
- b := round(b * 255 / m);
- End;
- r := min(255, r);
- g := min(255, g);
- b := min(255, b);
- co.red := r Shl 8;
- co.green := g Shl 8;
- co.blue := b Shl 8;
- co.Alpha := 255 Shl 8;
- IntfImgo.Colors[i, j] := co;
- End
- Else Begin
- IntfImgo.Colors[i, j] := ci;
- End;
- End;
- result := TBitmap.create;
- result.LoadFromIntfImage(intfimgo);
- IntfImgi.free;
- IntfImgo.free;
- bi.free;
-End;
-
-{ TAtomic }
-
-Constructor TAtomic.Create;
-Begin
- Inherited Create();
-End;
-
-Destructor TAtomic.Destroy;
-Var
- ta: tAtomicAnimation;
- i: integer;
-Begin
- For i := 0 To high(fZenAnimations) Do Begin
- fZenAnimations[i].ani.Free;
- End;
- For i := 0 To high(fLockedInAnimations) Do Begin
- fLockedInAnimations[i].ani.Free;
- End;
- For i := 0 To high(fDieAnimations) Do Begin
- fDieAnimations[i].ani.Free;
- End;
-
- For ta In tAtomicAnimation Do Begin
- fAnimations[ta].ani.free;
- End;
- Bomb.ani.free;
- Bomb_dud.ani.free;
- Bomb_trigger.ani.free;
- Bomb_Wobble.ani.free;
- FlameCross.free;
- FlameMiddle.free;
- FlameEnd.free;
-End;
-
-Function TAtomic.GetAnimTimeInMs(Anim: TRenderAnimation; Value: uint16
- ): Integer;
-
-Var
- Ani: TOpenGL_Animation;
-Begin
- result := 0;
- ani := Nil;
- Case Anim Of
- raStandStill: ani := Nil;
- raWalk: ani := Nil;
- raKick: ani := fAnimations[aaKick].ani;
- raPunch: ani := fAnimations[aaPunch].ani;
- raPup: ani := fAnimations[aaPup].ani;
- raDie: Begin
- //ani := fDieAnimations[Value Mod length(fDieAnimations)].Ani;
- // Die Todesanimation ist ein Sonderfall, die darf nicht ablaufen, da nach der Animation der Atomic nicht mehr gerendert werden darf !
- result := AtomicDieTimeout * 2;
- End;
- raZen: ani := fZenAnimations[Value Mod length(fZenAnimations)].Ani;
- raLockedIn: ani := fLockedInAnimations[Value Mod length(fLockedInAnimations)].Ani;
- Else Begin
- Raise exception.Create('Error, missing implementation: TAtomic.GetAnimTimeInMs');
- End;
- End;
- If assigned(ani) Then Begin
- result := ani.Sprite[0].FrameCount * ani.Sprite[0].TimePerFrame;
- End;
-End;
-
-(*
- * Zumindest auf dem Windows Rechner ist das Langsammer als es durch den RAM zu schleifen ...
- *)
-{.$DEFINE useCaching}
-
-Function TAtomic.InitAsColor(path: String; aTargetColor: TRGB): Boolean;
-
- Function CreateAnimation(Filename: String; AngleOffset: Single; TimePerFrame, w, h, fpr, fpc, c: integer; Const RangeData: Array Of Integer): TOpenGL_Animation;
- Var
- B: TBitmap;
- s: TAniSprite;
- i: Integer;
- fn: String;
- Begin
- result := Nil;
- If Not FileExists(Filename) Then exit;
- fn := ExtractFileName(Filename) + ColorToString(RGBToColor(aTargetColor));
- (*
- * Alle Farbtabellen laden wir gepuffert, das ist beim 1. mal zwar langsamer, aber ab dann deutlisch schneller ;)
- *)
-{$IFDEF useCaching}
- fn := IncludeTrailingPathDelimiter(GetAppConfigDir(false)) + fn;
- If FileExists(fn) Then Begin
- b := TBitmap.Create;
- b.LoadFromFile(fn);
- End
- Else Begin
-{$ENDIF}
- b := LoadColorTabledImage(Filename, aTargetColor);
-{$IFDEF useCaching}
- If assigned(b) Then Begin
- If Not ForceDirectories(GetAppConfigDir(false)) Then exit;
- b.SaveToFile(fn);
- End
- Else Begin
- exit;
- End;
- End;
-{$ENDIF}
- result := TOpenGL_Animation.Create;
- result.AngleOffset := AngleOffset;
- For i := 0 To high(RangeData) Do Begin
- If i <> 0 Then result.AddRange(true); // Die Animation wird bereits mit einem Range erzeugt, also darf der 1. nicht generiert werden ;)
- s := Result.Sprite[i];
- If i = 0 Then Begin
- s.Bitmap := b;
- s.Derived := false;
- End
- Else Begin
- s.Bitmap := Nil;
- s.Derived := true;
- End;
- s.AlphaImage := true;
- s.AlphaMask := Nil;
- s.TimePerFrame := TimePerFrame;
- s.rect := rect(0, 0, b.Width, b.Height);
- s.Name := fn;
- s.Width := w;
- s.Height := h;
- s.FramesPerRow := fpr;
- s.FramesPerCol := fpc;
- s.FrameOffset := RangeData[i];
- s.FrameCount := c;
- Result.Sprite[i] := s;
- End;
- // Die OpenGL Daten dürfen erst erstellt werden, wenn alle Daten gültig drin sind
- For i := 0 To high(RangeData) Do Begin
- Result.CreateOpenGLData(i);
- End;
- //b.free; -- Wird vom Sprite gemacht !
- End;
-
- Function LoadDir(Dir: String; Var Animations: TAnimations): Boolean;
- Var
- sl: TStringList;
- w, h, tpf, fpc, fpr, i, c, rox, roy: integer;
- sa: TStringArray;
- Begin
- result := true;
- sl := TStringList.Create;
- sl.LoadFromFile(dir + 'files.txt');
- For i := 0 To sl.Count - 1 Do Begin
- If trim(sl[i]) = '' Then Continue;
- If pos('#', trim(sl[i])) = 1 Then Continue;
- sa := sl[i].Split(';');
- If length(sa) <> 9 Then exit(false);
- If Not FileExists(dir + sa[0]) Then Begin
- Log(format('Warning, can not load animation, file: %s does not exist', [dir + sa[0]]), llWarning);
- Continue; // Gibt es die eine Animation nicht, dann wird sie ignoriert
- End;
- tpf := strtointdef(sa[1], -1);
- If tpf = -1 Then exit(false);
- fpr := strtointdef(sa[2], -1);
- If fpr = -1 Then exit(false);
- fpc := strtointdef(sa[3], -1);
- If fpc = -1 Then exit(false);
- w := StrToIntDef(sa[4], -1);
- If w = -1 Then exit(false);
- h := StrToIntDef(sa[5], -1);
- If h = -1 Then exit(false);
- c := strtointdef(sa[6], -1);
- If c = -1 Then exit(false);
- rox := strtointdef(sa[7], 0);
- roy := strtointdef(sa[8], 0);
-
- setlength(Animations, high(Animations) + 2);
- Animations[high(Animations)].Ani := CreateAnimation(dir + sa[0], 0, tpf, w, h, fpr, fpc, c, [0]);
- Animations[high(Animations)].OffsetX := rox;
- Animations[high(Animations)].Offsety := roy;
-{$IFDEF Only1Directory}
- // Immer nur den ersten Eintrag laden, der Rest wird eingespart ;
- break;
-{$ENDIF}
- End;
- sl.free;
- If Length(Animations) = 0 Then result := false;
- End;
-
-Begin
- result := false;
- (*
- * Laden aller Texturen die ein Einzelner Spieler so haben kann
- *)
- fShadowTex := OpenGL_GraphikEngine.LoadAlphaGraphikItem(path + 'shadow.png', smClamp);
- fAnimations[aaWalk].Ani := CreateAnimation(path + 'walk.png', 45, 50, 110, 110, 15, 4, 15, [0, 15, 45, 30]);
- fAnimations[aaWalk].OffsetX := 55;
- fAnimations[aaWalk].OffsetY := 90;
- If Not assigned(fAnimations[aaWalk].Ani) Then exit;
-
- fAnimations[aaStandStill].ani := CreateAnimation(path + 'stand.png', 45, 100, 110, 110, 2, 2, 1, [0, 1, 3, 2]);
- fAnimations[aaStandStill].OffsetX := 55;
- fAnimations[aaStandStill].OffsetY := 90;
- If Not assigned(fAnimations[aaStandStill].ani) Then exit;
-
- fAnimations[aaKick].ani := CreateAnimation(path + 'kick.png', 45, 50, 50, 69, 10, 4, 10, [10, 0, 30, 20]);
- fAnimations[aaKick].OffsetX := 25;
- fAnimations[aaKick].OffsetY := 60;
- If Not assigned(fAnimations[aaKick].ani) Then exit;
-
- fAnimations[aaPunch].ani := CreateAnimation(path + 'punbomb.png', 45, 50, 110, 110, 10, 4, 10, [30, 10, 20, 0]);
- fAnimations[aaPunch].OffsetX := 55;
- fAnimations[aaPunch].OffsetY := 90;
- If Not assigned(fAnimations[aaPunch].ani) Then exit;
-
- fAnimations[aaPup].ani := CreateAnimation(path + 'pupbomb.png', 45, 50, 110, 110, 11, 4, 11, [11, 33, 0, 22]);
- fAnimations[aaPup].OffsetX := 55;
- fAnimations[aaPup].OffsetY := 90;
- If Not assigned(fAnimations[aaPup].ani) Then exit;
-
-
- Bomb.ani := CreateAnimation(path + 'bomb.png', 0, 50, 40, 37, 5, 4, 18, [0]);
- Bomb.OffsetX := -20;
- Bomb.OffsetY := -37 Div 2;
- If Not assigned(Bomb.ani) Then exit;
- Bomb_dud.ani := CreateAnimation(path + 'bomb_dud.png', 0, 750, 40, 40, 1, 2, 2, [0]);
- Bomb_dud.OffsetX := -20;
- Bomb_dud.OffsetY := -20;
- If Not assigned(Bomb_dud.ani) Then exit;
- Bomb_trigger.ani := CreateAnimation(path + 'bomb_trigger.png', 0, 50, 40, 40, 5, 4, 18, [0]);
- Bomb_trigger.OffsetX := -20;
- Bomb_trigger.OffsetY := -20;
- If Not assigned(Bomb_trigger.ani) Then exit;
- Bomb_Wobble.ani := CreateAnimation(path + 'bomb_wobble.png', 0, 75, 40, 37, 4, 3, 12, [0]);
- Bomb_Wobble.OffsetX := -20;
- Bomb_Wobble.OffsetY := -37 Div 2;
- If Not assigned(Bomb_Wobble.ani) Then exit;
- FlameCross := CreateAnimation(path + 'flame.png', 0, 50, 41, 37, 5, 9, 5, [0]);
- If Not assigned(FlameCross) Then exit;
- FlameMiddle := CreateAnimation(path + 'flame.png', 45, 50, 41, 37, 5, 9, 5, [40, 25, 35, 30]);
- If Not assigned(FlameMiddle) Then exit;
- FlameEnd := CreateAnimation(path + 'flame.png', 45, 50, 41, 37, 5, 9, 5, [20, 5, 10, 15]);
- If Not assigned(FlameEnd) Then exit;
- If Not LoadDir(Path + 'idle' + PathDelim, fZenAnimations) Then exit;
- If Not LoadDir(Path + 'locked_in' + PathDelim, fLockedInAnimations) Then exit;
- If Not LoadDir(Path + 'die' + PathDelim, fDieAnimations) Then exit;
-
- result := true;
-End;
-
-Procedure TAtomic.Render(Const Info: TAtomicInfo; Edge: Boolean);
-Const // TODO: Redundant zu uatomic_field !
- xOff = 20;
- yOff = 66;
-Var
- fAnimation: TAnimation;
- aDirection: Single;
-Begin
- aDirection := Info.Direction;
- glColor4f(1, 1, 1, 1);
- glPushMatrix;
- glAlphaFunc(GL_LESS, 0.5);
- glEnable(GL_ALPHA_TEST);
- // Anfahren der Spielerposition
- glTranslatef(info.Position.x * FieldBlockWidth + xOff, (info.Position.y + 0.25) * FieldBlockHeight + yOff, atomic_Layer);
-
- glPushMatrix;
-
- // Die Notwendige Animation
- If Info.Dying Then Begin
- // Das hier Triggert hoffentlich nur bei der ersten Steigenden Flanke
- fAnimation := fDieAnimations[Info.Value Mod length(fDieAnimations)];
- (*
- * Wenn die Animation abgelaufen ist -> Abschalten und warten bis das Spiel beendet ist.
- *)
- If info.Counter >= fAnimation.Ani.Sprite[0].TimePerFrame * fAnimation.Ani.Sprite[0].FrameCount Then Begin
- fAnimation.Ani := Nil;
- End;
- End
- Else Begin
- // Der Schatten
- RenderAlphaQuad(-fShadowTex.OrigHeight / 2, -fShadowTex.OrigWidth / 2, fShadowTex);
- // anhand der Info die Passende Animation wählen !
- Case Info.Animation Of
- raStandStill: fAnimation := fAnimations[aaStandStill];
- raWalk: fAnimation := fAnimations[aaWalk];
- raKick: fAnimation := fAnimations[aaKick];
- raPunch: fAnimation := fAnimations[aaPunch];
- raPup: fAnimation := fAnimations[aaPup];
- raDie: fAnimation := fDieAnimations[Info.Value Mod length(fDieAnimations)]; // Eigentlich müsste es diesen Fall gar nicht geben da info.Dieing ja gesetzt ist dabei ..
- raZen: fAnimation := fZenAnimations[Info.Value Mod length(fZenAnimations)];
- raLockedIn: fAnimation := fLockedInAnimations[Info.Value Mod length(fLockedInAnimations)];
- raTeleport: Begin
- // Die Idee, dass die Animation alle 50 ms um 90 Grad weiter dreht, denn dem Atomic soll schwindelig werden !
- fAnimation := fAnimations[aaWalk];
- aDirection := ((Info.Counter Mod 200) Div 50) * 90;
- Edge := True; // Der User soll immer das 1. Frame sehen, denn der Atomic steht ja wenn er sich dreht
- End;
- End;
- End;
- If assigned(fAnimation.Ani) Then Begin
- If Edge And (info.Animation <> raWalk) Then Begin
- fAnimation.Ani.ResetAnimation();
- End;
- glTranslatef(-fAnimation.OffsetX, -fAnimation.OffsetY, atomic_EPSILON);
- fAnimation.ani.Render(aDirection);
- End;
- glPopMatrix;
-
- gldisable(GL_ALPHA_TEST);
- glPopMatrix;
-
- (*
- * Zum Debuggen ein Punkt exakt da wo finfo.Position ist !
- * )
- glPushMatrix;
- glDisable(GL_DEPTH_TEST);
- glTranslatef(finfo.Position.x * FieldBlockWidth + xOff, finfo.Position.y * FieldBlockHeight + yOff, atomic_Layer);
- glPointSize(3);
- glBegin(GL_POINTS);
- glColor3f(1, 0, 0);
- glVertex2f(0, 0);
- glend();
- glPointSize(1);
- glEnable(GL_DEPTH_TEST);
- glPopMatrix;
- // Ende Debuggen *)
-End;
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uatomic;
+
+{$MODE ObjFPC}{$H+}
+
+{$I globaldefines.inc}
+
+Interface
+
+Uses
+ Classes, SysUtils, uvectormath, uatomic_common
+ , Graphics
+ , uGraphics
+ , uopengl_animation
+ , uopengl_graphikengine
+ ;
+
+Type
+
+ TGameState = (
+ gs_MainMenu, // Der Spieler ist im Hauptmenü
+ gs_Gaming // Das Spiel läuft
+ );
+
+ tAtomicAnimation = (
+ aaStandStill,
+ aaWalk,
+ aaKick, // Kicken
+ aaPunch, // Weg schlagen (Roter Handschu)
+ aaPup // Die Pupserkrankheit
+ );
+
+ TAnimation = Record
+ Ani: TOpenGL_Animation;
+ OffsetX, OffsetY: integer;
+ End;
+
+ TAnimations = Array Of TAnimation;
+
+ { TAtomic }
+
+ TAtomic = Class
+ private
+ fDieAnimations: TAnimations;
+ fLockedInAnimations: TAnimations;
+ fZenAnimations: TAnimations;
+ fAnimations: Array[tAtomicAnimation] Of TAnimation;
+ fShadowTex: TGraphikItem;
+
+ public
+ FlameEnd, FlameCross, FlameMiddle: TOpenGL_Animation;
+ Bomb: TAnimation;
+ Bomb_dud: TAnimation;
+ Bomb_trigger: TAnimation;
+ Bomb_Wobble: TAnimation;
+
+ Constructor Create(); virtual;
+ Destructor Destroy(); override;
+ Function GetAnimTimeInMs(Anim: TRenderAnimation; Value: uint16): Integer;
+ Function InitAsColor(path: String; aTargetColor: TRGB): Boolean;
+
+ Procedure Render(Const Info: TAtomicInfo; Edge: Boolean);
+ End;
+
+ TAtomics = Array[0..length(PlayerColors) - 1] Of TAtomic;
+
+Implementation
+
+Uses
+ math
+ , dglOpenGL
+ , IntfGraphics
+ , fpImage
+ ;
+
+Function LoadColorTabledImage(PNGImage: String; PlayerColor: TRGB): TBitmap;
+Var
+ png: TPortableNetworkGraphic;
+ bi: TBitmap;
+ IntfImgi, IntfImgo: TLazIntfImage;
+ i, j, k: Integer;
+ ci, co: TFPColor;
+ m, r, g, b: Integer;
+ n: integer;
+Begin
+ If Not FileExists(PNGImage) Then Begin
+ result := Nil;
+ exit;
+ End;
+ png := TPortableNetworkGraphic.Create;
+ png.LoadFromFile(PNGImage);
+ bi := TBitmap.create;
+ bi.Assign(png);
+ png.free;
+ IntfImgi := TLazIntfImage.create(0, 0);
+ IntfImgi.LoadFromBitmap(bi.Handle, Bi.MaskHandle);
+ intfimgo := TLazIntfImage.create(0, 0);
+ IntfImgo.LoadFromBitmap(bi.Handle, Bi.MaskHandle);
+ For i := 0 To bi.width - 1 Do
+ For j := 0 To bi.height - 1 Do Begin
+ ci := IntfImgi.Colors[i, j];
+ r := ci.red Shr 8;
+ g := ci.green Shr 8;
+ b := ci.blue Shr 8;
+ If (g > r) And (g > b) Then Begin
+ n := (r + b) Div 2;
+ k := (g - n);
+ r := n + (k * (PlayerColor.r)) Div 100;
+ g := n + (k * (PlayerColor.g)) Div 100;
+ b := n + (k * (PlayerColor.b)) Div 100;
+ (*
+ Tritt nur auf wenn die PlayerColor Werte > 100 haben
+ *)
+ m := max(r, max(g, b));
+ If m > 255 Then Begin
+ r := round(r * 255 / m);
+ g := round(g * 255 / m);
+ b := round(b * 255 / m);
+ End;
+ r := min(255, r);
+ g := min(255, g);
+ b := min(255, b);
+ co.red := r Shl 8;
+ co.green := g Shl 8;
+ co.blue := b Shl 8;
+ co.Alpha := 255 Shl 8;
+ IntfImgo.Colors[i, j] := co;
+ End
+ Else Begin
+ IntfImgo.Colors[i, j] := ci;
+ End;
+ End;
+ result := TBitmap.create;
+ result.LoadFromIntfImage(intfimgo);
+ IntfImgi.free;
+ IntfImgo.free;
+ bi.free;
+End;
+
+{ TAtomic }
+
+Constructor TAtomic.Create;
+Begin
+ Inherited Create();
+End;
+
+Destructor TAtomic.Destroy;
+Var
+ ta: tAtomicAnimation;
+ i: integer;
+Begin
+ For i := 0 To high(fZenAnimations) Do Begin
+ fZenAnimations[i].ani.Free;
+ End;
+ For i := 0 To high(fLockedInAnimations) Do Begin
+ fLockedInAnimations[i].ani.Free;
+ End;
+ For i := 0 To high(fDieAnimations) Do Begin
+ fDieAnimations[i].ani.Free;
+ End;
+
+ For ta In tAtomicAnimation Do Begin
+ fAnimations[ta].ani.free;
+ End;
+ Bomb.ani.free;
+ Bomb_dud.ani.free;
+ Bomb_trigger.ani.free;
+ Bomb_Wobble.ani.free;
+ FlameCross.free;
+ FlameMiddle.free;
+ FlameEnd.free;
+End;
+
+Function TAtomic.GetAnimTimeInMs(Anim: TRenderAnimation; Value: uint16
+ ): Integer;
+
+Var
+ Ani: TOpenGL_Animation;
+Begin
+ result := 0;
+ ani := Nil;
+ Case Anim Of
+ raStandStill: ani := Nil;
+ raWalk: ani := Nil;
+ raKick: ani := fAnimations[aaKick].ani;
+ raPunch: ani := fAnimations[aaPunch].ani;
+ raPup: ani := fAnimations[aaPup].ani;
+ raDie: Begin
+ //ani := fDieAnimations[Value Mod length(fDieAnimations)].Ani;
+ // Die Todesanimation ist ein Sonderfall, die darf nicht ablaufen, da nach der Animation der Atomic nicht mehr gerendert werden darf !
+ result := AtomicDieTimeout * 2;
+ End;
+ raZen: ani := fZenAnimations[Value Mod length(fZenAnimations)].Ani;
+ raLockedIn: ani := fLockedInAnimations[Value Mod length(fLockedInAnimations)].Ani;
+ Else Begin
+ Raise exception.Create('Error, missing implementation: TAtomic.GetAnimTimeInMs');
+ End;
+ End;
+ If assigned(ani) Then Begin
+ result := ani.Sprite[0].FrameCount * ani.Sprite[0].TimePerFrame;
+ End;
+End;
+
+(*
+ * Zumindest auf dem Windows Rechner ist das Langsammer als es durch den RAM zu schleifen ...
+ *)
+{.$DEFINE useCaching}
+
+Function TAtomic.InitAsColor(path: String; aTargetColor: TRGB): Boolean;
+
+ Function CreateAnimation(Filename: String; AngleOffset: Single; TimePerFrame, w, h, fpr, fpc, c: integer; Const RangeData: Array Of Integer): TOpenGL_Animation;
+ Var
+ B: TBitmap;
+ s: TAniSprite;
+ i: Integer;
+ fn: String;
+ Begin
+ result := Nil;
+ If Not FileExists(Filename) Then exit;
+ fn := ExtractFileName(Filename) + ColorToString(RGBToColor(aTargetColor));
+ (*
+ * Alle Farbtabellen laden wir gepuffert, das ist beim 1. mal zwar langsamer, aber ab dann deutlisch schneller ;)
+ *)
+{$IFDEF useCaching}
+ fn := IncludeTrailingPathDelimiter(GetAppConfigDir(false)) + fn;
+ If FileExists(fn) Then Begin
+ b := TBitmap.Create;
+ b.LoadFromFile(fn);
+ End
+ Else Begin
+{$ENDIF}
+ b := LoadColorTabledImage(Filename, aTargetColor);
+{$IFDEF useCaching}
+ If assigned(b) Then Begin
+ If Not ForceDirectories(GetAppConfigDir(false)) Then exit;
+ b.SaveToFile(fn);
+ End
+ Else Begin
+ exit;
+ End;
+ End;
+{$ENDIF}
+ result := TOpenGL_Animation.Create;
+ result.AngleOffset := AngleOffset;
+ For i := 0 To high(RangeData) Do Begin
+ If i <> 0 Then result.AddRange(true); // Die Animation wird bereits mit einem Range erzeugt, also darf der 1. nicht generiert werden ;)
+ s := Result.Sprite[i];
+ If i = 0 Then Begin
+ s.Bitmap := b;
+ s.Derived := false;
+ End
+ Else Begin
+ s.Bitmap := Nil;
+ s.Derived := true;
+ End;
+ s.AlphaImage := true;
+ s.AlphaMask := Nil;
+ s.TimePerFrame := TimePerFrame;
+ s.rect := rect(0, 0, b.Width, b.Height);
+ s.Name := fn;
+ s.Width := w;
+ s.Height := h;
+ s.FramesPerRow := fpr;
+ s.FramesPerCol := fpc;
+ s.FrameOffset := RangeData[i];
+ s.FrameCount := c;
+ Result.Sprite[i] := s;
+ End;
+ // Die OpenGL Daten dürfen erst erstellt werden, wenn alle Daten gültig drin sind
+ For i := 0 To high(RangeData) Do Begin
+ Result.CreateOpenGLData(i);
+ End;
+ //b.free; -- Wird vom Sprite gemacht !
+ End;
+
+ Function LoadDir(Dir: String; Var Animations: TAnimations): Boolean;
+ Var
+ sl: TStringList;
+ w, h, tpf, fpc, fpr, i, c, rox, roy: integer;
+ sa: TStringArray;
+ Begin
+ result := true;
+ sl := TStringList.Create;
+ sl.LoadFromFile(dir + 'files.txt');
+ For i := 0 To sl.Count - 1 Do Begin
+ If trim(sl[i]) = '' Then Continue;
+ If pos('#', trim(sl[i])) = 1 Then Continue;
+ sa := sl[i].Split(';');
+ If length(sa) <> 9 Then exit(false);
+ If Not FileExists(dir + sa[0]) Then Begin
+ Log(format('Warning, can not load animation, file: %s does not exist', [dir + sa[0]]), llWarning);
+ Continue; // Gibt es die eine Animation nicht, dann wird sie ignoriert
+ End;
+ tpf := strtointdef(sa[1], -1);
+ If tpf = -1 Then exit(false);
+ fpr := strtointdef(sa[2], -1);
+ If fpr = -1 Then exit(false);
+ fpc := strtointdef(sa[3], -1);
+ If fpc = -1 Then exit(false);
+ w := StrToIntDef(sa[4], -1);
+ If w = -1 Then exit(false);
+ h := StrToIntDef(sa[5], -1);
+ If h = -1 Then exit(false);
+ c := strtointdef(sa[6], -1);
+ If c = -1 Then exit(false);
+ rox := strtointdef(sa[7], 0);
+ roy := strtointdef(sa[8], 0);
+
+ setlength(Animations, high(Animations) + 2);
+ Animations[high(Animations)].Ani := CreateAnimation(dir + sa[0], 0, tpf, w, h, fpr, fpc, c, [0]);
+ Animations[high(Animations)].OffsetX := rox;
+ Animations[high(Animations)].Offsety := roy;
+{$IFDEF Only1Directory}
+ // Immer nur den ersten Eintrag laden, der Rest wird eingespart ;
+ break;
+{$ENDIF}
+ End;
+ sl.free;
+ If Length(Animations) = 0 Then result := false;
+ End;
+
+Begin
+ result := false;
+ (*
+ * Laden aller Texturen die ein Einzelner Spieler so haben kann
+ *)
+ fShadowTex := OpenGL_GraphikEngine.LoadAlphaGraphikItem(path + 'shadow.png', smClamp);
+ fAnimations[aaWalk].Ani := CreateAnimation(path + 'walk.png', 45, 50, 110, 110, 15, 4, 15, [0, 15, 45, 30]);
+ fAnimations[aaWalk].OffsetX := 55;
+ fAnimations[aaWalk].OffsetY := 90;
+ If Not assigned(fAnimations[aaWalk].Ani) Then exit;
+
+ fAnimations[aaStandStill].ani := CreateAnimation(path + 'stand.png', 45, 100, 110, 110, 2, 2, 1, [0, 1, 3, 2]);
+ fAnimations[aaStandStill].OffsetX := 55;
+ fAnimations[aaStandStill].OffsetY := 90;
+ If Not assigned(fAnimations[aaStandStill].ani) Then exit;
+
+ fAnimations[aaKick].ani := CreateAnimation(path + 'kick.png', 45, 50, 50, 69, 10, 4, 10, [10, 0, 30, 20]);
+ fAnimations[aaKick].OffsetX := 25;
+ fAnimations[aaKick].OffsetY := 60;
+ If Not assigned(fAnimations[aaKick].ani) Then exit;
+
+ fAnimations[aaPunch].ani := CreateAnimation(path + 'punbomb.png', 45, 50, 110, 110, 10, 4, 10, [30, 10, 20, 0]);
+ fAnimations[aaPunch].OffsetX := 55;
+ fAnimations[aaPunch].OffsetY := 90;
+ If Not assigned(fAnimations[aaPunch].ani) Then exit;
+
+ fAnimations[aaPup].ani := CreateAnimation(path + 'pupbomb.png', 45, 50, 110, 110, 11, 4, 11, [11, 33, 0, 22]);
+ fAnimations[aaPup].OffsetX := 55;
+ fAnimations[aaPup].OffsetY := 90;
+ If Not assigned(fAnimations[aaPup].ani) Then exit;
+
+
+ Bomb.ani := CreateAnimation(path + 'bomb.png', 0, 50, 40, 37, 5, 4, 18, [0]);
+ Bomb.OffsetX := -20;
+ Bomb.OffsetY := -37 Div 2;
+ If Not assigned(Bomb.ani) Then exit;
+ Bomb_dud.ani := CreateAnimation(path + 'bomb_dud.png', 0, 750, 40, 40, 1, 2, 2, [0]);
+ Bomb_dud.OffsetX := -20;
+ Bomb_dud.OffsetY := -20;
+ If Not assigned(Bomb_dud.ani) Then exit;
+ Bomb_trigger.ani := CreateAnimation(path + 'bomb_trigger.png', 0, 50, 40, 40, 5, 4, 18, [0]);
+ Bomb_trigger.OffsetX := -20;
+ Bomb_trigger.OffsetY := -20;
+ If Not assigned(Bomb_trigger.ani) Then exit;
+ Bomb_Wobble.ani := CreateAnimation(path + 'bomb_wobble.png', 0, 75, 40, 37, 4, 3, 12, [0]);
+ Bomb_Wobble.OffsetX := -20;
+ Bomb_Wobble.OffsetY := -37 Div 2;
+ If Not assigned(Bomb_Wobble.ani) Then exit;
+ // Grid is 5 columns x 9 rows, each frame is 41x37 pixels
+ // Each row is a 5-frame animation of one flame element:
+ // Row 0 (frames 0-4): FlameCross - 5-frame animation of cross pattern
+ // Row 1 (frames 5-9): FlameEnd up (vertical top end) - 5-frame animation
+ // Row 2 (frames 10-14): FlameEnd left (horizontal left end) - 5-frame animation
+ // Row 3 (frames 15-19): FlameEnd down (vertical bottom end) - 5-frame animation
+ // Row 4 (frames 20-24): FlameEnd right (horizontal right end) - 5-frame animation
+ // Row 5 (frames 25-29): FlameMiddle up (vertical middle going up) - 5-frame animation
+ // Row 6 (frames 30-34): FlameMiddle down (vertical middle going down) - 5-frame animation
+ // Row 7 (frames 35-39): FlameMiddle right (horizontal middle going right) - 5-frame animation
+ // Row 8 (frames 40-44): FlameMiddle left (horizontal middle going left) - 5-frame animation
+ // Each range corresponds to a direction: 0°=right, 90°=up, 180°=left, 270°=down
+ FlameCross := CreateAnimation(path + 'flame.png', 0, 50, 41, 37, 5, 9, 5, [0]); // Row 0: cross animation (5 frames)
+ If Not assigned(FlameCross) Then exit;
+ // FlameEnd: 4 ranges for 4 directions, each with 5-frame animation
+ // EqualizeRanges divides 360° into 4 equal parts: Range 0=0-89°, Range 1=90-179°, Range 2=180-269°, Range 3=270-359°
+ // When FlameAngle is set: 0°=right, 90°=up, 180°=left, 270°=down
+ // Frame offsets: 20=right(0°), 5=up(90°), 10=left(180°), 15=down(270°)
+ FlameEnd := CreateAnimation(path + 'flame.png', 0, 50, 41, 37, 5, 9, 5, [20, 5, 10, 15]); // right, up, left, down
+ If Not assigned(FlameEnd) Then exit;
+ // FlameMiddle: 4 ranges for 4 directions, each with 5-frame animation
+ // Frame offsets: 40=right(0°), 30=up(90°), 35=left(180°), 25=down(270°) - swapped right/left and up/down
+ FlameMiddle := CreateAnimation(path + 'flame.png', 0, 50, 41, 37, 5, 9, 5, [40, 30, 35, 25]);
+ If Not assigned(FlameEnd) Then exit;
+ If Not LoadDir(Path + 'idle' + PathDelim, fZenAnimations) Then exit;
+ If Not LoadDir(Path + 'locked_in' + PathDelim, fLockedInAnimations) Then exit;
+ If Not LoadDir(Path + 'die' + PathDelim, fDieAnimations) Then exit;
+
+ result := true;
+End;
+
+Procedure TAtomic.Render(Const Info: TAtomicInfo; Edge: Boolean);
+Const // TODO: Redundant zu uatomic_field !
+ xOff = 20;
+ yOff = 66;
+Var
+ fAnimation: TAnimation;
+ aDirection: Single;
+Begin
+ aDirection := Info.Direction;
+ glColor4f(1, 1, 1, 1);
+ glPushMatrix;
+ glAlphaFunc(GL_LESS, 0.5);
+ glEnable(GL_ALPHA_TEST);
+ // Anfahren der Spielerposition
+ glTranslatef(info.Position.x * FieldBlockWidth + xOff, (info.Position.y + 0.25) * FieldBlockHeight + yOff, atomic_Layer);
+
+ glPushMatrix;
+
+ // Die Notwendige Animation
+ If Info.Dying Then Begin
+ // Das hier Triggert hoffentlich nur bei der ersten Steigenden Flanke
+ fAnimation := fDieAnimations[Info.Value Mod length(fDieAnimations)];
+ (*
+ * Wenn die Animation abgelaufen ist -> Abschalten und warten bis das Spiel beendet ist.
+ *)
+ If info.Counter >= fAnimation.Ani.Sprite[0].TimePerFrame * fAnimation.Ani.Sprite[0].FrameCount Then Begin
+ fAnimation.Ani := Nil;
+ End;
+ End
+ Else Begin
+ // Der Schatten
+ RenderAlphaQuad(-fShadowTex.OrigHeight / 2, -fShadowTex.OrigWidth / 2, fShadowTex);
+ // anhand der Info die Passende Animation wählen !
+ Case Info.Animation Of
+ raStandStill: fAnimation := fAnimations[aaStandStill];
+ raWalk: fAnimation := fAnimations[aaWalk];
+ raKick: fAnimation := fAnimations[aaKick];
+ raPunch: fAnimation := fAnimations[aaPunch];
+ raPup: fAnimation := fAnimations[aaPup];
+ raDie: fAnimation := fDieAnimations[Info.Value Mod length(fDieAnimations)]; // Eigentlich müsste es diesen Fall gar nicht geben da info.Dieing ja gesetzt ist dabei ..
+ raZen: fAnimation := fZenAnimations[Info.Value Mod length(fZenAnimations)];
+ raLockedIn: fAnimation := fLockedInAnimations[Info.Value Mod length(fLockedInAnimations)];
+ raTeleport: Begin
+ // Die Idee, dass die Animation alle 50 ms um 90 Grad weiter dreht, denn dem Atomic soll schwindelig werden !
+ fAnimation := fAnimations[aaWalk];
+ aDirection := ((Info.Counter Mod 200) Div 50) * 90;
+ Edge := True; // Der User soll immer das 1. Frame sehen, denn der Atomic steht ja wenn er sich dreht
+ End;
+ End;
+ End;
+ If assigned(fAnimation.Ani) Then Begin
+ If Edge And (info.Animation <> raWalk) Then Begin
+ fAnimation.Ani.ResetAnimation();
+ End;
+ glTranslatef(-fAnimation.OffsetX, -fAnimation.OffsetY, atomic_EPSILON);
+ fAnimation.ani.Render(aDirection);
+ End;
+ glPopMatrix;
+
+ gldisable(GL_ALPHA_TEST);
+ glPopMatrix;
+
+ (*
+ * Zum Debuggen ein Punkt exakt da wo finfo.Position ist !
+ * )
+ glPushMatrix;
+ glDisable(GL_DEPTH_TEST);
+ glTranslatef(finfo.Position.x * FieldBlockWidth + xOff, finfo.Position.y * FieldBlockHeight + yOff, atomic_Layer);
+ glPointSize(3);
+ glBegin(GL_POINTS);
+ glColor3f(1, 0, 0);
+ glVertex2f(0, 0);
+ glend();
+ glPointSize(1);
+ glEnable(GL_DEPTH_TEST);
+ glPopMatrix;
+ // Ende Debuggen *)
+End;
+
+End.
+
diff --git a/client/uearlylog.pas b/client/uearlylog.pas
new file mode 100644
index 0000000..ff7902a
--- /dev/null
+++ b/client/uearlylog.pas
@@ -0,0 +1,66 @@
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uearlylog;
+
+{$MODE objfpc}{$H+}
+
+{$I globaldefines.inc}
+
+Interface
+
+Procedure EarlyLog(Const Msg: String);
+
+Implementation
+
+Uses SysUtils
+{$IFDEF DARWIN}
+ , LazFileUtils
+{$ENDIF}
+ ;
+
+Procedure EarlyLog(Const Msg: String);
+Var
+ LogFile: TextFile;
+ LogPath: String;
+Begin
+ Try
+{$IFDEF DARWIN}
+ LogPath := IncludeTrailingPathDelimiter(GetUserDir) + 'Library/Application Support/fpc_atomic/early_debug.log';
+ If Not DirectoryExistsUTF8(ExtractFilePath(LogPath)) Then
+ ForceDirectoriesUTF8(ExtractFilePath(LogPath));
+{$ELSE}
+ // On Windows and Linux, create log file next to executable
+ LogPath := ChangeFileExt(ParamStr(0), '_debug.log');
+{$ENDIF}
+ AssignFile(LogFile, LogPath);
+ If FileExists(LogPath) Then
+ Append(LogFile)
+ Else
+ Rewrite(LogFile);
+ WriteLn(LogFile, FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' [EARLY] ' + Msg);
+ Flush(LogFile);
+ CloseFile(LogFile);
+ Except
+ // Ignore errors in early logging
+ End;
+End;
+
+End.
+
diff --git a/client/ugame.pas b/client/ugame.pas
index 7486d40..1247663 100644
--- a/client/ugame.pas
+++ b/client/ugame.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit ugame;
{$MODE ObjFPC}{$H+}
@@ -22,7 +27,8 @@
Uses
Classes, SysUtils, controls, OpenGLContext, lNetComponents, lnet,
- uatomic_common, uopengl_animation, uscreens, uChunkmanager, uatomic_field, uatomic, uopengl_graphikengine, usounds, usdl_joystick;
+ uatomic_common, uopengl_animation, uscreens, uChunkmanager, uatomic_field, uatomic, uopengl_graphikengine, usounds, usdl_joystick, usdl_gamecontroller,
+ uloaderdialog;
Type
TUDPPingData = Record
@@ -60,11 +66,19 @@
private
fsdl_Loaded: Boolean;
fsdlJoysticks: Array[TKeySet] Of TSDL_Joystick;
+ fsdlControllers: Array[TKeySet] Of TSDL_GameControllerEx;
+ fControllerLogged: Array[TKeySet] Of Boolean; // Track if we've logged controller usage
+ fMenuDpadState: record
+ up, down, left, right, buttonA, buttonB: Boolean;
+ end; // Track previous D-pad state for menu navigation
+ fBlockGameInputUntilRelease: Boolean; // Block game input until all buttons released
+ fBlockMenuInputUntilRelease: Boolean; // Block menu input until all buttons released
fTramp, fConveyors, fArrows: TOpenGL_Animation; // Wird den Karten zur Verfügung gestellt
fHurry: THurry;
fSoundManager: TSoundManager;
fSoundInfo: TSoundInfo;
fLastIdleTick: QWord;
+ fLastUpdateTimestamp: QWord; // For network performance monitoring
fLastKeyDown: Array[akFirstAction..akSecondAction] Of QWORD;
fPlayerdeadTex: TGraphikItem;
fPowerUpsTex: TPowerTexArray;
@@ -72,6 +86,9 @@
fBombs: Array[0..15 * 11 - 1] Of TBombInfo;
fParamJoinIP: String;
fParamJoinPort: integer;
+ fWaitingForLocalServer: Boolean; // True when waiting for local server to start
+ fLastConnectionAttempt: QWord; // Timestamp of last connection attempt
+ fConnectionRetryInterval: QWord; // Interval between retry attempts (ms)
fPlayingTime_s: integer;
fPause: Boolean;
fNeedDisconnect: Boolean; // Wenn True, dann wird ein Disconnect via Idle Handler durchgeführt (das darf nach LNet nicht im Socket Event gemacht werden da es sonst eine AV-Gibt)
@@ -80,6 +97,7 @@
fAtomics: TAtomics;
fBackupSettings: TAtomicSettings; // Sind wir nicht der Master Spieler, dann müssen wir unsere Settings Sichern
fInitialized: Boolean; // True, wenn Initialize erfolgreich durchgelaufen wurde
+ fLoaderDialog: TLoaderDialog; // Reference to loading dialog during initialization
fFields: Array Of TAtomicField;
fScheme: TScheme;
{$IFNDEF DebuggMode}
@@ -99,6 +117,36 @@
fChunkManager: TChunkManager;
fUDPPingData: TUDPPingData;
+ FViewportOffsetX: Integer;
+ FViewportOffsetY: Integer;
+ FViewportWidth: Integer;
+ FViewportHeight: Integer;
+ FControlWidth: Integer;
+ FControlHeight: Integer;
+ FViewportScale: Double;
+ fDataPath: String; // Base path to data directory
+ fServerPID: Integer; // PID of locally started server process (0 if no server started)
+
+ // === CLIENT-SIDE INTERPOLATION ===
+ // Snapshots of server state
+ fServerSnapshots: Array[0..1] Of Record
+ Timestamp: QWord; // GetTickCount64 when received
+ ServerTime_ms: Integer; // fPlayingTime_s * 1000
+ PlayerInfos: Array[0..9] Of TAtomicInfo;
+ Valid: Boolean; // Is this snapshot valid?
+ End;
+ fCurrentSnapshot: Integer; // Index of current snapshot (0 or 1)
+
+ // Interpolated state (calculated each frame)
+ fInterpolatedState: Record
+ PlayingTime_ms: Integer;
+ PlayerInfos: Array[0..9] Of TAtomicInfo;
+ End;
+
+ // Interpolation parameters
+ fExtrapolationLimit: Integer; // Max extrapolation time (default 100ms)
+
+ // Note: fInterpolationDelay and fDebugStats are now in public section for debug overlay access
Procedure FOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Procedure FOnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
@@ -108,16 +156,27 @@
Procedure FOnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
Procedure FOnKeyUp(Sender: TObject; Var Key: Word; Shift: TShiftState);
- Procedure CheckKeyDown(Key: Word; Keys: TKeySet);
+ Function CheckKeyDown(Key: Word; Keys: TKeySet): Boolean;
Procedure CheckKeyUp(Key: Word; Keys: TKeySet);
Procedure CheckSDLKeys();
+ Procedure ReadCurrentButtonState(var up, down, left, right, buttonA, buttonB: Boolean);
+ Function AreAllGamepadButtonsReleased(): Boolean;
+ Procedure CheckSDLKeysForMenu();
+ Procedure ReinitControllersWithLogs();
Function LoadSchemeFromFile(Const SchemeFileName: String): Boolean;
Procedure OnQuitGameSoundFinished(Sender: TObject);
+ Function ResolveResourceBase(BasePath: String): String;
Procedure RenderPlayerbyInfo(Const Info: TAtomicInfo; Edge: Boolean);
Procedure RenderFieldHeader();
Procedure RenderBombs();
+ Function PointInsideViewport(ScreenX, ScreenY: Integer): Boolean;
+ Function ScreenToGameX(ScreenX: Integer): Integer;
+ Function ScreenToGameY(ScreenY: Integer): Integer;
+
+ // Client-side interpolation
+ Procedure InterpolateGameState();
Procedure Connection_Connect(aSocket: TLSocket);
Procedure Connection_Disconnect(aSocket: TLSocket);
@@ -149,6 +208,7 @@
* Routinen die der Master Spieler Aufruft um den Rest zu Aktualisieren
*)
Function StartHost: Boolean;
+ Function GetServerIPAddress(): String; // Get local network IP address for server display
Procedure SendSettings();
Procedure UpdateFieldSetup(FieldName: String; FieldHash: Uint64; NeededWins: integer);
Procedure SwitchToPlayerSetup;
@@ -168,9 +228,27 @@
fPlayer: TPlayers;
{$ENDIF}
Settings: TAtomicSettings; // für uscreens
+
+ // Expose interpolation fields for debug overlay (must be before properties!)
+ fDebugStats: Record
+ LastRTT: Integer;
+ AvgRTT: Single;
+ MaxRTT: Integer; // Worst RTT since game start
+ InterpolationFactor: Single;
+ MaxInterpFactor: Single; // Worst interpolation factor
+ IsExtrapolating: Boolean;
+ SnapshotAge: Integer;
+ MaxSnapAge: Integer; // Worst snapshot age
+ End;
+ fInterpolationDelay: Integer;
OnNeedHideCursor: TNotifyEvent;
OnNeedShowCursor: TNotifyEvent;
+
+ Property PlayingTime_s: Integer Read fPlayingTime_s;
+ Property ChunkManager: TChunkManager Read fChunkManager; // For network thread access
+ Property LoaderDialog: TLoaderDialog Read fLoaderDialog; // For OnPaint to render loading dialog during initialization
+ Property IsInitialized: Boolean Read fInitialized; // Check if game is initialized
Constructor Create();
Destructor Destroy; override;
@@ -187,6 +265,8 @@
Procedure OnIdle; // Wird von Application.OnIdle aufgerufen
Procedure JoinViaParams(ip: String; Port: integer); // Nur 1 mal direkt nach dem Start erlaubt (siehe TForm1.OnIdle)
+ Function GetControllerCount: Integer;
+
(*
* Werden und dürfen nur aus uScreens heraus aufgerufen werden
*)
@@ -196,10 +276,14 @@
Procedure StartGame();
Procedure StartPlayingSong(Filename: String);
Procedure PlaySoundEffect(Filename: String; EndCallback: TNotifyEvent = Nil);
+ Procedure SetViewportMetrics(ControlWidth, ControlHeight, OffsetX, OffsetY,
+ ViewportWidth, ViewportHeight: Integer);
+ Function GetKeySetDisplayName(Keys: TKeySet): String;
End;
Var
Game: TGame; // Die SpielEngine
+ NeedFormClose: Boolean = false; // Set to true when user confirms exit, triggers form close after quit sound
Implementation
@@ -214,7 +298,6 @@
, sdl2
, uip
, uOpenGL_ASCII_Font
- , uloaderdialog
, uvectormath
, LCLType
, process
@@ -223,11 +306,9 @@
, uatomicfont
, uopengl_spriteengine
, ugraphics
+ , uearlylog
;
-Var
- NeedFormClose: Boolean = false;
-
(*
* Gibt den Index von Value in aArray zurück, -1 wenn nicht enthalten.
*)
@@ -309,39 +390,19 @@
Procedure TGame.SwitchToScreen(TargetScreen: TScreenEnum);
Var
- index: integer;
+ index, index2: integer;
Begin
If Not fInitialized Then exit; // So Lange wir nicht Initialisiert sind, machen wir gar nix !
log('TGame.SwitchToScreen', llTrace);
+
+ // Blocking is now done immediately when button is pressed in CheckSDLKeysForMenu
+ // Don't reset fMenuDpadState here - let the blocking mechanism handle it
// Sobald wir versuchen uns in ein Spiel ein zu loggen muss ggf. SDL initialisiert werden
- If (TargetScreen = sHost) Or (TargetScreen = sJoinNetwork) Then Begin
+ // Also initialize for main menu and options to enable gamepad navigation
+ If (TargetScreen = sHost) Or (TargetScreen = sJoinNetwork) Or
+ (TargetScreen = sMainScreen) Or (TargetScreen = sOptions) Then Begin
If assigned(OnNeedHideCursor) Then OnNeedHideCursor(Nil);
- If (Settings.Keys[ks0].UseSDL2 Or Settings.Keys[ks1].UseSDL2) Then Begin
- If (Not fsdl_Loaded) Then Begin
- fsdl_Loaded := SDL_LoadLib('');
- If fsdl_Loaded Then Begin
- fsdl_Loaded := SDL_Init(SDL_INIT_JOYSTICK) = 0;
- End;
- End;
- If assigned(fsdlJoysticks[ks0]) Then fsdlJoysticks[ks0].Free;
- If assigned(fsdlJoysticks[ks1]) Then fsdlJoysticks[ks1].Free;
- fsdlJoysticks[ks0] := Nil;
- fsdlJoysticks[ks1] := Nil;
- If fsdl_Loaded Then Begin
- If Settings.Keys[ks0].UseSDL2 Then Begin
- index := ResolveJoystickNameToIndex(Settings.Keys[ks0].Name, Settings.Keys[ks0].NameIndex);
- If index <> -1 Then Begin
- fsdlJoysticks[ks0] := TSDL_Joystick.Create(index);
- End;
- End;
- If Settings.Keys[ks1].UseSDL2 Then Begin
- index := ResolveJoystickNameToIndex(Settings.Keys[ks1].Name, Settings.Keys[ks1].NameIndex);
- If index <> -1 Then Begin
- fsdlJoysticks[ks1] := TSDL_Joystick.Create(index);
- End;
- End;
- End;
- End;
+ ReinitControllersWithLogs();
End;
(*
* Wenn es "individuell" noch was zu tun gibt ...
@@ -353,6 +414,7 @@
sMainScreen: Begin
fgameState := gs_MainMenu;
StopPingingForGames;
+ fWaitingForLocalServer := false; // Stop waiting for local server when returning to main menu
Disconnect();
HandleSetPause(false); // Sonst bleibt die Hauptmenü Animation ggf stehen, das will natürlich keiner ;)
If assigned(OnNeedShowCursor) Then OnNeedShowCursor(Nil);
@@ -360,7 +422,10 @@
sExitBomberman: Begin
NeedFormClose := true;
StartPlayingSong(''); // Disable the Background musik if playing, that speeds up the shutdown process or at least stop making noises
- PlaySoundEffect('data' + pathdelim + 'res' + PathDelim + 'quitgame.wav', @OnQuitGameSoundFinished);
+ If fDataPath = '' Then Begin
+ fDataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ End;
+ PlaySoundEffect(fDataPath + 'res' + PathDelim + 'quitgame.wav', @OnQuitGameSoundFinished);
End;
sHost: Begin
fParamJoinIP := '';
@@ -368,10 +433,19 @@
LogLeave;
exit;
End;
+ // After starting server, automatically connect to localhost
+ // This is faster and more reliable than UDP broadcast
+ fParamJoinIP := '127.0.0.1';
+ fParamJoinPort := Settings.Port;
+ log('Server started, will connect to localhost:' + inttostr(fParamJoinPort), llInfo);
+
+ // Get and display server IP address for other players to connect
+ If Assigned(fScreens[sJoinNetwork]) Then Begin
+ TJoinMenu(fScreens[sJoinNetwork]).SetServerIP(GetServerIPAddress());
+ End;
+
TargetScreen := sJoinNetwork;
- //Als nächstes muss es einen Server zum Drauf verbinden geben
- // -> Der Server Startet und macht den UDP Auf
- // Sobald der Client den finden verbindet er direkt, PW gibt es keins !
+ // The client will automatically connect via JoinViaParams in sJoinNetwork handler
End;
sPlayerSetupRequest: Begin
SwitchToPlayerSetup;
@@ -381,6 +455,7 @@
End;
sPlayerSetup: Begin
// Den Screen mit den Aktuellsten Daten versorgen
+ ReinitControllersWithLogs(); // ensure detection fresh in setup
TPlayerSetupMenu(fScreens[sPlayerSetup]).TeamPlay := Settings.TeamPlay;
TPlayerSetupMenu(fScreens[sPlayerSetup]).LoadPlayerdata(fPlayer, fUserID);
End;
@@ -412,7 +487,7 @@
exit;
End
Else Begin
- If FileExists('data' + PathDelim + 'schemes' + PathDelim + Settings.SchemeFile) Then Begin
+ If (fDataPath <> '') And FileExistsUTF8(fDataPath + 'schemes' + PathDelim + Settings.SchemeFile) Then Begin
StartPingingForGames;
End
Else Begin
@@ -436,8 +511,42 @@
Procedure TGame.ChangePlayerKey(PlayerIndex, Direction: Integer);
Var
m: TMemoryStream;
+ numJoy: Integer;
+ currentKeySet: TKeySet;
+ skipJoy1, skipJoy2: Boolean;
+ nextKeySet: TKeySet;
Begin
log('TGame.ChangePlayerKey', llTrace);
+
+ // Check which joysticks are available
+ numJoy := 0;
+ skipJoy1 := false;
+ skipJoy2 := false;
+ try
+ If fsdl_Loaded And Assigned(SDL_NumJoysticks) Then Begin
+ numJoy := SDL_NumJoysticks();
+ // Joy 1 is available only if at least 1 joystick is detected
+ skipJoy1 := (numJoy < 1);
+ // Joy 2 is available only if at least 2 joysticks are detected
+ skipJoy2 := (numJoy < 2);
+ End
+ Else Begin
+ // SDL not loaded, skip both joysticks
+ skipJoy1 := true;
+ skipJoy2 := true;
+ End;
+ except
+ // On error, skip both joysticks
+ skipJoy1 := true;
+ skipJoy2 := true;
+ end;
+
+ // If joysticks need to be skipped, we need to send multiple change requests
+ // to skip unavailable joysticks. But this is complex and could cause issues.
+ // Instead, we'll let the server cycle through all options, and the client
+ // will handle skipping unavailable joysticks in HandleRefreshPlayerStats.
+ // This is simpler and more reliable.
+
m := TMemoryStream.Create;
m.Write(PlayerIndex, SizeOf(PlayerIndex));
m.Write(Direction, SizeOf(Direction));
@@ -469,9 +578,13 @@
Var
xx, yy: Integer;
Begin
- // Umrechnen der Echten Koords in die Screencoords
- xx := round(ConvertDimension(0, fOwner.ClientWidth, x, 0, GameWidth));
- yy := round(ConvertDimension(0, fOwner.ClientHeight, y, 0, GameHeight));
+ If Not PointInsideViewport(X, Y) Then Begin
+ If Assigned(FOnMouseDownCapture) Then
+ FOnMouseDownCapture(Sender, Button, Shift, X, Y);
+ exit;
+ End;
+ xx := ScreenToGameX(X);
+ yy := ScreenToGameY(Y);
Case fgameState Of
gs_MainMenu: Begin
If assigned(fActualScreen) Then Begin
@@ -513,6 +626,7 @@
Procedure TGame.FOnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
Var
aVolume: Dword;
+ KeyProcessed: Boolean;
Begin
(*
* Der Hack zum Beenden von Atomic Bomberman im Fehlerfall ;)
@@ -522,18 +636,21 @@
SwitchToScreen(sExitBomberman);
exit;
End;
+ KeyProcessed := false;
If Not ((ssalt In Shift) And (key = VK_RETURN)) Then Begin // Sonst wird das VK_Return ggf unsinnig ausgewertet
If key = VK_ADD Then Begin
aVolume := fSoundManager.IncVolume;
settings.VolumeValue := aVolume;
fBackupSettings.VolumeValue := aVolume;
fSoundInfo.Volume := aVolume;
+ KeyProcessed := true;
End;
If key = VK_SUBTRACT Then Begin
aVolume := fSoundManager.DecVolume();
settings.VolumeValue := aVolume;
fBackupSettings.VolumeValue := aVolume;
fSoundInfo.Volume := aVolume;
+ KeyProcessed := true;
End;
If key = VK_M Then Begin // Toggle Musik an aus
Settings.PlaySounds := Not Settings.PlaySounds;
@@ -549,38 +666,70 @@
StartPlayingSong(fActualField.Sound);
End;
End;
+ KeyProcessed := true;
End;
Case fgameState Of
gs_MainMenu: Begin
If assigned(fActualScreen) Then Begin
+ // Save original key value before menu processes it
+ // Check if this is a key that menu typically processes
+ KeyProcessed := (key In [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_RETURN, VK_BACK, VK_ESCAPE]) Or
+ ((fPlayerIndex[ks0] <> -1) And (key In [Settings.Keys[ks0].KeyPrimary, Settings.Keys[ks0].KeySecondary])) Or
+ ((fPlayerIndex[ks1] <> -1) And (key In [Settings.Keys[ks1].KeyPrimary, Settings.Keys[ks1].KeySecondary]));
+ // Let menu process the key first - menu will play sounds and handle the key
+ // Menu needs Key to remain unchanged during OnKeyDown to properly process it
fActualScreen.OnKeyDown(Sender, Key, Shift);
+ // If menu set key to 0, it was definitely processed and consumed
+ If (key = 0) Then KeyProcessed := true;
+ // After menu processed the key, we need to mark it as handled to prevent system beep
+ // but we do this at the end, after menu had chance to play sounds
End;
End;
gs_Gaming: Begin
If key = VK_ESCAPE Then Begin
- SwitchToScreen(sMainScreen);
+{$IFNDEF Only3Player}
+ If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then
+{$ENDIF}
+ SwitchToScreen(sMainScreen);
+ KeyProcessed := true;
End;
If key = VK_P Then Begin
SendChunk(miTogglePause, Nil);
+ KeyProcessed := true;
+ End;
+ If fPlayerIndex[ks0] <> -1 Then Begin
+ If CheckKeyDown(key, ks0) Then KeyProcessed := true;
+ End;
+ If fPlayerIndex[ks1] <> -1 Then Begin
+ If CheckKeyDown(key, ks1) Then KeyProcessed := true;
End;
- If fPlayerIndex[ks0] <> -1 Then CheckKeyDown(key, ks0);
- If fPlayerIndex[ks1] <> -1 Then CheckKeyDown(key, ks1);
End;
End;
End;
If assigned(FOnKeyDownCapture) Then Begin
FOnKeyDownCapture(sender, key, shift);
End;
+ // Mark key as handled to prevent system beep on macOS
+ // For gaming state, always set Key := 0 if processed
+ If KeyProcessed And (fgameState = gs_Gaming) Then Begin
+ Key := 0;
+ End;
+ // For menu: don't set Key := 0 to allow menu sounds to play properly
+ // Menu needs Key unchanged to process it and play sounds
+ // The menu OnKeyDown handlers should process keys and prevent system beep naturally
+ // by consuming the key events they handle
End;
-Procedure TGame.CheckKeyDown(Key: Word; Keys: TKeySet);
+Function TGame.CheckKeyDown(Key: Word; Keys: TKeySet): Boolean;
Var
m: TMemoryStream;
db, b: Boolean;
ak: TAtomicKey;
n: QWORD;
Begin
+ result := false;
If key In [Settings.Keys[Keys].KeyLeft, Settings.Keys[Keys].KeyRight, Settings.Keys[Keys].KeyUp, Settings.Keys[Keys].KeyDown, Settings.Keys[Keys].KeyPrimary, Settings.Keys[Keys].KeySecondary] Then Begin
+ result := true;
m := TMemoryStream.Create;
b := true;
db := false;
@@ -651,6 +800,8 @@
If fgameState = gs_Gaming Then Begin
If fPlayerIndex[ks0] <> -1 Then CheckKeyUp(Key, ks0);
If fPlayerIndex[ks1] <> -1 Then CheckKeyUp(key, ks1);
+ If fPlayerIndex[ksJoy1] <> -1 Then CheckKeyUp(key, ksJoy1);
+ If fPlayerIndex[ksJoy2] <> -1 Then CheckKeyUp(key, ksJoy2);
End;
If assigned(FOnKeyUpCapture) Then Begin
FOnKeyUpCapture(sender, key, shift);
@@ -661,29 +812,230 @@
Procedure CheckKeys(Keys: TKeySet);
Var
- d: Integer;
+ d, d0, d1: Integer;
up, down, left, right, first, second: Boolean;
+ wasUp, wasDown, wasLeft, wasRight: Boolean; // Previous state for hysteresis
+ diagonalThreshold: Integer; // Lower threshold when in diagonal mode
+ wasDiagonal: Boolean; // Was in diagonal mode in previous frame
+ isDiagonal: Boolean;
+ verticalStrength, horizontalStrength: Integer;
+ dominantDirection: TAtomicKey;
+ sendDominant: Boolean;
+ dpadUp, dpadDown, dpadLeft, dpadRight: Boolean; // D-Pad state
+ wasDpadUp, wasDpadDown, wasDpadLeft, wasDpadRight: Boolean; // Previous D-Pad state
+ isDpadDiagonal: Boolean; // D-Pad diagonal state
+ dpadActive: Boolean; // Whether D-Pad is currently active
Begin
+ If fPlayerIndex[keys] = AIPlayer Then exit;
+ If fPlayerIndex[keys] = -1 Then exit;
+ // Use legacy joystick mapping if configured
If Not Settings.Keys[keys].UseSDL2 Then exit;
If Not assigned(fsdlJoysticks[keys]) Then exit;
- If fPlayerIndex[keys] = AIPlayer Then exit;
+
+ // Remember previous state for hysteresis
+ wasUp := fPlayer[fPlayerIndex[keys]].KeysPressed[akUp];
+ wasDown := fPlayer[fPlayerIndex[keys]].KeysPressed[akDown];
+ wasLeft := fPlayer[fPlayerIndex[keys]].KeysPressed[akLeft];
+ wasRight := fPlayer[fPlayerIndex[keys]].KeysPressed[akRight];
+
+ // 1. Check D-Pad first (digital input, should be sent immediately like keyboard)
+ // D-Pad is processed separately from analog stick to ensure smooth diagonal movement
+ dpadUp := false;
+ dpadDown := false;
+ dpadLeft := false;
+ dpadRight := false;
+ dpadActive := false;
+
+ // Universal approach: Check both HAT and button-based D-Pad
+ // Some controllers use HAT (classic), others use buttons 11-14 (modern controllers like DualSense)
+ try
+ // First check HAT-based D-pad (classic joysticks)
+ if fsdlJoysticks[keys].HatCount > 0 then begin
+ d := fsdlJoysticks[keys].Hat[0];
+ if (d and SDL_HAT_UP) <> 0 then begin
+ dpadUp := true;
+ dpadActive := true;
+ end;
+ if (d and SDL_HAT_DOWN) <> 0 then begin
+ dpadDown := true;
+ dpadActive := true;
+ end;
+ if (d and SDL_HAT_LEFT) <> 0 then begin
+ dpadLeft := true;
+ dpadActive := true;
+ end;
+ if (d and SDL_HAT_RIGHT) <> 0 then begin
+ dpadRight := true;
+ dpadActive := true;
+ end;
+ end;
+
+ // Also check button-based D-pad (modern controllers like DualSense, some Xbox controllers)
+ // Check if controller has enough buttons and try buttons 11-14
+ // Note: We check both HAT and buttons, so if controller has both, HAT takes priority
+ if (not dpadActive) and (fsdlJoysticks[keys].ButtonCount > 14) then begin
+ // Modern controllers: D-pad as buttons 11-14
+ // Button 11 = Up, 12 = Down, 13 = Left, 14 = Right
+ if fsdlJoysticks[keys].Button[11] then begin
+ dpadUp := true;
+ dpadActive := true;
+ end;
+ if fsdlJoysticks[keys].Button[12] then begin
+ dpadDown := true;
+ dpadActive := true;
+ end;
+ if fsdlJoysticks[keys].Button[13] then begin
+ dpadLeft := true;
+ dpadActive := true;
+ end;
+ if fsdlJoysticks[keys].Button[14] then begin
+ dpadRight := true;
+ dpadActive := true;
+ end;
+ end;
+ except
+ // Ignore D-pad errors, analog stick still works
+ end;
+
+ // If D-Pad is active, send events immediately (like keyboard) and skip analog stick processing
+ // This ensures D-Pad behaves like keyboard input with smooth diagonal movement
+ if dpadActive then begin
+ // Remember previous D-Pad state
+ wasDpadUp := fPlayer[fPlayerIndex[keys]].KeysPressed[akUp];
+ wasDpadDown := fPlayer[fPlayerIndex[keys]].KeysPressed[akDown];
+ wasDpadLeft := fPlayer[fPlayerIndex[keys]].KeysPressed[akLeft];
+ wasDpadRight := fPlayer[fPlayerIndex[keys]].KeysPressed[akRight];
+
+ // Send all direction changes (like keyboard - each key is independent)
+ // This allows server to process diagonal movement when multiple directions are active
+ If wasDpadUp <> dpadUp Then Begin
+ If dpadUp Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyUp, keys);
+ End
+ Else Begin
+ CheckKeyUp(Settings.Keys[keys].KeyUp, keys);
+ End;
+ End;
+ If wasDpadDown <> dpadDown Then Begin
+ If dpadDown Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyDown, keys);
+ End
+ Else Begin
+ CheckKeyUp(Settings.Keys[keys].KeyDown, keys);
+ End;
+ End;
+ If wasDpadLeft <> dpadLeft Then Begin
+ If dpadLeft Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyLeft, keys);
+ End
+ Else Begin
+ CheckKeyUp(Settings.Keys[keys].KeyLeft, keys);
+ End;
+ End;
+ If wasDpadRight <> dpadRight Then Begin
+ If dpadRight Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyRight, keys);
+ End
+ Else Begin
+ CheckKeyUp(Settings.Keys[keys].KeyRight, keys);
+ End;
+ End;
+
+ // Enhanced: When in diagonal mode, send all active directions every frame
+ // This matches keyboard behavior where all pressed keys are sent continuously
+ // Server processes diagonal movement when multiple directions are active
+ isDpadDiagonal := ((dpadUp Or dpadDown) And (dpadLeft Or dpadRight));
+ If isDpadDiagonal Then Begin
+ // Send all active directions every frame (like keyboard - keys are held down)
+ // This ensures smooth diagonal movement like keyboard
+ If dpadUp Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyUp, keys);
+ End;
+ If dpadDown Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyDown, keys);
+ End;
+ If dpadLeft Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyLeft, keys);
+ End;
+ If dpadRight Then Begin
+ // Send right last so server processes it (matching keyboard behavior)
+ CheckKeyDown(Settings.Keys[keys].KeyRight, keys);
+ End;
+ End;
+
+ // D-Pad is active, skip analog stick processing
+ // Process buttons and exit early
+ first := Settings.Keys[keys].ButtonsIdle[0] = fsdlJoysticks[keys].Button[Settings.Keys[keys].ButtonIndex[0]];
+ second := Settings.Keys[keys].ButtonsIdle[1] = fsdlJoysticks[keys].Button[Settings.Keys[keys].ButtonIndex[1]];
+
+ // Das Key Up wird bei Action nicht geprüft..
+ If (fPlayer[fPlayerIndex[keys]].KeysPressed[akFirstAction] <> first) And first Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeyPrimary, keys);
+ End;
+ // Das Key Up wird bei Action nicht geprüft..
+ If (fPlayer[fPlayerIndex[keys]].KeysPressed[akSecondAction] <> second) And Second Then Begin
+ CheckKeyDown(Settings.Keys[keys].KeySecondary, keys);
+ End;
+ // 3. Speichern für die nächste Runde ;)
+ fPlayer[fPlayerIndex[keys]].KeysPressed[akFirstAction] := first;
+ fPlayer[fPlayerIndex[keys]].KeysPressed[akSecondAction] := second;
+
+ // Exit early - D-Pad processing is complete, analog stick is skipped
+ exit;
+ end;
+
+ // D-Pad is not active, process analog stick normally (original logic unchanged)
// 1. Ermitteln des Aktuellen "Gedrückt" stati
up := false;
down := false;
left := false;
right := false;
- d := Settings.Keys[keys].AchsisIdle[0] - fsdlJoysticks[keys].Axis[Settings.Keys[keys].AchsisIndex[0]];
- If abs(d) > achsistrigger Then Begin
- If sign(d) = Settings.Keys[keys].AchsisDirection[0] Then Begin
+
+ // Calculate axis differences
+ d0 := Settings.Keys[keys].AchsisIdle[0] - fsdlJoysticks[keys].Axis[Settings.Keys[keys].AchsisIndex[0]];
+ d1 := Settings.Keys[keys].AchsisIdle[1] - fsdlJoysticks[keys].Axis[Settings.Keys[keys].AchsisIndex[1]];
+
+ // Use hysteresis for diagonal directions: if we were in diagonal mode (both axes active),
+ // use lower threshold to turn off. This prevents flickering when one axis slightly drops below threshold.
+ // Check if we were in diagonal mode in previous frame
+ diagonalThreshold := achsistrigger Div 2; // 50% of normal threshold when in diagonal
+ wasDiagonal := ((wasUp Or wasDown) And (wasLeft Or wasRight));
+
+ // Check up/down axis with hysteresis
+ If abs(d0) > achsistrigger Then Begin
+ // Normal threshold for activation
+ If sign(d0) = Settings.Keys[keys].AchsisDirection[0] Then Begin
+ up := true;
+ End
+ Else Begin
+ down := true;
+ End;
+ End
+ Else If wasDiagonal And (abs(d1) > achsistrigger) And (abs(d0) > diagonalThreshold) Then Begin
+ // If we were in diagonal mode and horizontal axis is still active,
+ // use lower threshold to keep vertical direction active
+ If sign(d0) = Settings.Keys[keys].AchsisDirection[0] Then Begin
up := true;
End
Else Begin
down := true;
End;
End;
- d := Settings.Keys[keys].AchsisIdle[1] - fsdlJoysticks[keys].Axis[Settings.Keys[keys].AchsisIndex[1]];
- If abs(d) > achsistrigger Then Begin
- If sign(d) = Settings.Keys[keys].AchsisDirection[1] Then Begin
+
+ // Check left/right axis with hysteresis
+ If abs(d1) > achsistrigger Then Begin
+ // Normal threshold for activation
+ If sign(d1) = Settings.Keys[keys].AchsisDirection[1] Then Begin
+ left := true;
+ End
+ Else Begin
+ right := true;
+ End;
+ End
+ Else If wasDiagonal And (abs(d0) > achsistrigger) And (abs(d1) > diagonalThreshold) Then Begin
+ // If we were in diagonal mode and vertical axis is still active,
+ // use lower threshold to keep horizontal direction active
+ If sign(d1) = Settings.Keys[keys].AchsisDirection[1] Then Begin
left := true;
End
Else Begin
@@ -692,7 +1044,124 @@
End;
first := Settings.Keys[keys].ButtonsIdle[0] = fsdlJoysticks[keys].Button[Settings.Keys[keys].ButtonIndex[0]];
second := Settings.Keys[keys].ButtonsIdle[1] = fsdlJoysticks[keys].Button[Settings.Keys[keys].ButtonIndex[1]];
+
// 2. Rauskriegen ob ein Event abgeleitet werden muss
+ // For diagonal directions, determine which direction should win based on axis strength
+ // This matches keyboard behavior where the last key pressed determines direction
+ // When in diagonal mode, send the stronger direction last so server processes it correctly
+
+ // Determine if we're in diagonal mode and which direction should win
+ Begin
+ isDiagonal := ((up Or down) And (left Or right));
+ verticalStrength := 0;
+ horizontalStrength := 0;
+ dominantDirection := akUp; // Default
+ sendDominant := false;
+
+ // Calculate axis strengths for diagonal mode
+ If isDiagonal Then Begin
+ If up Or down Then verticalStrength := abs(d0);
+ If left Or right Then horizontalStrength := abs(d1);
+
+ // Determine dominant direction based on axis strength
+ // If vertical is stronger, prioritize up/down; if horizontal is stronger, prioritize left/right
+ If (verticalStrength > horizontalStrength) Then Begin
+ If up Then dominantDirection := akUp
+ Else If down Then dominantDirection := akDown;
+ sendDominant := true;
+ End
+ Else If (horizontalStrength > verticalStrength) Then Begin
+ If left Then dominantDirection := akLeft
+ Else If right Then dominantDirection := akRight;
+ sendDominant := true;
+ End
+ Else Begin
+ // Equal strength - use priority order: Up > Down > Left > Right
+ If up Then dominantDirection := akUp
+ Else If down Then dominantDirection := akDown
+ Else If left Then dominantDirection := akLeft
+ Else If right Then dominantDirection := akRight;
+ sendDominant := true;
+ End;
+ End;
+
+ // Send direction changes, handling diagonal mode specially
+ If isDiagonal And sendDominant Then Begin
+ // In diagonal mode, send all active directions, but send the dominant one last
+ // This ensures server processes the correct direction
+
+ // Send non-dominant directions first (if they changed)
+ If (dominantDirection <> akUp) Then Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akUp] <> up Then Begin
+ If up Then CheckKeyDown(Settings.Keys[keys].KeyUp, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyUp, keys);
+ End;
+ End;
+ If (dominantDirection <> akDown) Then Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akDown] <> down Then Begin
+ If down Then CheckKeyDown(Settings.Keys[keys].KeyDown, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyDown, keys);
+ End;
+ End;
+ If (dominantDirection <> akLeft) Then Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akLeft] <> left Then Begin
+ If left Then CheckKeyDown(Settings.Keys[keys].KeyLeft, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyLeft, keys);
+ End;
+ End;
+ If (dominantDirection <> akRight) Then Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akRight] <> right Then Begin
+ If right Then CheckKeyDown(Settings.Keys[keys].KeyRight, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyRight, keys);
+ End;
+ End;
+
+ // Send dominant direction last so server processes it
+ Case dominantDirection Of
+ akUp: Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akUp] <> up Then Begin
+ If up Then CheckKeyDown(Settings.Keys[keys].KeyUp, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyUp, keys);
+ End
+ Else If up Then Begin
+ // Re-send to ensure server processes it (in case other direction was sent first)
+ CheckKeyDown(Settings.Keys[keys].KeyUp, keys);
+ End;
+ End;
+ akDown: Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akDown] <> down Then Begin
+ If down Then CheckKeyDown(Settings.Keys[keys].KeyDown, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyDown, keys);
+ End
+ Else If down Then Begin
+ // Re-send to ensure server processes it (in case other direction was sent first)
+ CheckKeyDown(Settings.Keys[keys].KeyDown, keys);
+ End;
+ End;
+ akLeft: Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akLeft] <> left Then Begin
+ If left Then CheckKeyDown(Settings.Keys[keys].KeyLeft, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyLeft, keys);
+ End
+ Else If left Then Begin
+ // Re-send to ensure server processes it (in case other direction was sent first)
+ CheckKeyDown(Settings.Keys[keys].KeyLeft, keys);
+ End;
+ End;
+ akRight: Begin
+ If fPlayer[fPlayerIndex[keys]].KeysPressed[akRight] <> right Then Begin
+ If right Then CheckKeyDown(Settings.Keys[keys].KeyRight, keys)
+ Else CheckKeyUp(Settings.Keys[keys].KeyRight, keys);
+ End
+ Else If right Then Begin
+ // Re-send to ensure server processes it (in case other direction was sent first)
+ CheckKeyDown(Settings.Keys[keys].KeyRight, keys);
+ End;
+ End;
+ End;
+ End
+ Else Begin
+ // Normal single-direction mode - send changes as before
If fPlayer[fPlayerIndex[keys]].KeysPressed[akUp] <> up Then Begin
If up Then Begin
CheckKeyDown(Settings.Keys[keys].KeyUp, keys);
@@ -723,6 +1192,8 @@
End
Else Begin
CheckKeyUp(Settings.Keys[keys].KeyRight, keys);
+ End;
+ End;
End;
End;
// Das Key Up wird bei Action nicht geprüft..
@@ -738,44 +1209,591 @@
fPlayer[fPlayerIndex[keys]].KeysPressed[akSecondAction] := second;
End;
-Var
- event: TSDL_Event;
Begin
If Not fsdl_Loaded Then exit;
- If Not (Settings.Keys[ks0].UseSDL2 Or Settings.Keys[ks1].UseSDL2) Then exit;
- SDL_PumpEvents();
- While SDL_PollEvent(@event) <> 0 Do Begin // TODO: Braucht man das wirklich ?
+ // If neither joystick is present and UseSDL2 not configured, nothing to do
+ // Check all possible keysets that might use SDL
+ If Not (Settings.Keys[ks0].UseSDL2 Or Settings.Keys[ks1].UseSDL2 Or
+ Settings.Keys[ksJoy1].UseSDL2 Or Settings.Keys[ksJoy2].UseSDL2) Then exit;
+
+ // If we're blocking input until buttons are released, skip input processing
+ If fBlockGameInputUntilRelease Then Begin
+ exit;
End;
+
+ // SDL_PumpEvents is now called in OnIdle before this function
CheckKeys(ks0);
CheckKeys(ks1);
+ CheckKeys(ksJoy1);
+ CheckKeys(ksJoy2);
+End;
+
+Procedure TGame.ReadCurrentButtonState(var up, down, left, right, buttonA, buttonB: Boolean);
+
+ Procedure CheckJoystick(Keys: TKeySet);
+Var
+ d: Integer;
+Begin
+ If Not Assigned(fsdlJoysticks[Keys]) Then exit;
+ try
+ // Check analog stick
+ d := fsdlJoysticks[Keys].Axis[1]; // Y axis
+ if d < -12000 then up := true;
+ if d > 12000 then down := true;
+ d := fsdlJoysticks[Keys].Axis[0]; // X axis
+ if d < -12000 then left := true;
+ if d > 12000 then right := true;
+
+ // Check D-pad buttons (DualSense style)
+ if fsdlJoysticks[Keys].ButtonCount > 14 then begin
+ if fsdlJoysticks[Keys].Button[11] then up := true;
+ if fsdlJoysticks[Keys].Button[12] then down := true;
+ if fsdlJoysticks[Keys].Button[13] then left := true;
+ if fsdlJoysticks[Keys].Button[14] then right := true;
+ end;
+ // Check HAT (classic joysticks)
+ if fsdlJoysticks[Keys].HatCount > 0 then begin
+ d := fsdlJoysticks[Keys].Hat[0];
+ if (d and SDL_HAT_UP) <> 0 then up := true;
+ if (d and SDL_HAT_DOWN) <> 0 then down := true;
+ if (d and SDL_HAT_LEFT) <> 0 then left := true;
+ if (d and SDL_HAT_RIGHT) <> 0 then right := true;
+ end;
+
+ // Buttons: X = button 0 (Enter), Circle = button 1 (Esc)
+ if fsdlJoysticks[Keys].ButtonCount > 0 then buttonA := fsdlJoysticks[Keys].Button[0];
+ if fsdlJoysticks[Keys].ButtonCount > 1 then buttonB := fsdlJoysticks[Keys].Button[1];
+ except
+ // Ignore errors
+ end;
+ End;
+
+Begin
+ up := false;
+ down := false;
+ left := false;
+ right := false;
+ buttonA := false;
+ buttonB := false;
+
+ // Check all possible joysticks - first available one wins
+ CheckJoystick(ks0);
+ CheckJoystick(ks1);
+ CheckJoystick(ksJoy1);
+ CheckJoystick(ksJoy2);
+End;
+
+Function TGame.AreAllGamepadButtonsReleased(): Boolean;
+Var
+ up, down, left, right, buttonA, buttonB: Boolean;
+Begin
+ // Read current button state
+ ReadCurrentButtonState(up, down, left, right, buttonA, buttonB);
+
+ // Return true only if ALL buttons are released
+ result := not (up or down or left or right or buttonA or buttonB);
+End;
+
+Procedure TGame.CheckSDLKeysForMenu();
+Var
+ up, down, left, right, buttonA, buttonB: Boolean;
+ d, i: Integer;
+ key: Word;
+ shift: TShiftState;
+Begin
+ // Only process in menu, not during gameplay
+ If fgameState = gs_Gaming Then exit;
+ If Not fsdl_Loaded Then exit;
+ If Not assigned(fActualScreen) Then exit;
+
+ // If we're blocking menu input until buttons are released, skip input processing
+ If fBlockMenuInputUntilRelease Then Begin
+ exit;
+ End;
+
+ // Check if any joystick is available (check all possible keysets)
+ If Not (Assigned(fsdlJoysticks[ks0]) Or Assigned(fsdlJoysticks[ks1]) Or
+ Assigned(fsdlJoysticks[ksJoy1]) Or Assigned(fsdlJoysticks[ksJoy2])) Then exit;
+
+ // Read D-pad and button state from first available controller
+ ReadCurrentButtonState(up, down, left, right, buttonA, buttonB);
+
+ shift := [];
+
+ // Generate key events on state change (press only)
+ if up and not fMenuDpadState.up then begin
+ key := VK_UP;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+ if down and not fMenuDpadState.down then begin
+ key := VK_DOWN;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+ if left and not fMenuDpadState.left then begin
+ key := VK_LEFT;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+ if right and not fMenuDpadState.right then begin
+ key := VK_RIGHT;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+ if buttonA and not fMenuDpadState.buttonA then begin
+ key := VK_RETURN;
+ // Mark button as pressed AND block menu input BEFORE calling OnKeyDown to prevent double-trigger
+ fMenuDpadState.buttonA := true;
+ fBlockMenuInputUntilRelease := true;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+ if buttonB and not fMenuDpadState.buttonB then begin
+ key := VK_ESCAPE;
+ // Mark button as pressed AND block menu input BEFORE calling OnKeyDown to prevent double-trigger
+ fMenuDpadState.buttonB := true;
+ fBlockMenuInputUntilRelease := true;
+ fActualScreen.OnKeyDown(nil, key, shift);
+ end;
+
+ // Save state for next frame
+ fMenuDpadState.up := up;
+ fMenuDpadState.down := down;
+ fMenuDpadState.left := left;
+ fMenuDpadState.right := right;
+ // buttonA and buttonB are already set above if they were just pressed,
+ // otherwise update them normally
+ if not buttonA then fMenuDpadState.buttonA := false;
+ if not buttonB then fMenuDpadState.buttonB := false;
+End;
+
+Function TGame.GetControllerCount: Integer;
+begin
+ result := 0;
+ if Assigned(fsdlJoysticks[ks0]) then inc(result);
+ if Assigned(fsdlJoysticks[ks1]) then inc(result);
+ if Assigned(fsdlJoysticks[ksJoy1]) then inc(result);
+ if Assigned(fsdlJoysticks[ksJoy2]) then inc(result);
+end;
+
+Procedure TGame.ReinitControllersWithLogs();
+Var
+ index, index2: integer;
+ numJoy: Integer;
+ i: Integer;
+Begin
+ // If menu or game input is blocked, skip reinit to avoid resetting button states
+ If (fBlockMenuInputUntilRelease Or fBlockGameInputUntilRelease) And Assigned(fsdlJoysticks[ks0]) Then Begin
+ exit;
+ End;
+
+ // Always try to init SDL and detect controllers
+ If (Not fsdl_Loaded) Then Begin
+ fsdl_Loaded := SDL_LoadLib('');
+ If fsdl_Loaded Then Begin
+ // Initialize with GAMECONTROLLER (implies JOYSTICK)
+ fsdl_Loaded := SDL_Init(SDL_INIT_GAMECONTROLLER) = 0;
+ End;
+ End;
+
+ // Clean up old instances
+ If assigned(fsdlJoysticks[ks0]) Then Begin
+ fsdlJoysticks[ks0].Free;
+ fsdlJoysticks[ks0] := Nil;
+ End;
+ If assigned(fsdlJoysticks[ks1]) Then Begin
+ fsdlJoysticks[ks1].Free;
+ fsdlJoysticks[ks1] := Nil;
+ End;
+ If assigned(fsdlJoysticks[ksJoy1]) Then Begin
+ fsdlJoysticks[ksJoy1].Free;
+ fsdlJoysticks[ksJoy1] := Nil;
+ End;
+ If assigned(fsdlJoysticks[ksJoy2]) Then Begin
+ fsdlJoysticks[ksJoy2].Free;
+ fsdlJoysticks[ksJoy2] := Nil;
+ End;
+ If assigned(fsdlControllers[ks0]) Then Begin
+ fsdlControllers[ks0].Free;
+ fsdlControllers[ks0] := Nil;
+ End;
+ If assigned(fsdlControllers[ks1]) Then Begin
+ fsdlControllers[ks1].Free;
+ fsdlControllers[ks1] := Nil;
+ End;
+ If assigned(fsdlControllers[ksJoy1]) Then Begin
+ fsdlControllers[ksJoy1].Free;
+ fsdlControllers[ksJoy1] := Nil;
+ End;
+ If assigned(fsdlControllers[ksJoy2]) Then Begin
+ fsdlControllers[ksJoy2].Free;
+ fsdlControllers[ksJoy2] := Nil;
+ End;
+ // Reset logging flags
+ fControllerLogged[ks0] := false;
+ fControllerLogged[ks1] := false;
+ fControllerLogged[ksJoy1] := false;
+ fControllerLogged[ksJoy2] := false;
+
+ If fsdl_Loaded Then Begin
+ // Try to detect and configure joystick-based controls (SDL_Joystick + existing mapping)
+ try
+ numJoy := SDL_NumJoysticks();
+ except
+ numJoy := 0;
+ end;
+
+ // Auto-configure ksJoy1/ksJoy2 to use first/second joystick
+ // Note: We do NOT auto-configure ks0/ks1 anymore - they remain as keyboard inputs
+ // Users can manually select Joy 1 or Joy 2 in the player setup menu
+ // Always configure ksJoy1 and ksJoy2 so they're available for selection
+ if numJoy > 0 then begin
+ // Configure Joy 1 (ksJoy1) to use joystick 0
+ // Only set UseSDL2 if not already configured (preserve user settings)
+ if not Settings.Keys[ksJoy1].UseSDL2 then begin
+ Settings.Keys[ksJoy1].UseSDL2 := true;
+ try
+ if SDL_JoystickNameForIndex(0) <> nil then
+ Settings.Keys[ksJoy1].Name := SDL_JoystickNameForIndex(0)
+ else
+ Settings.Keys[ksJoy1].Name := '';
+ except
+ Settings.Keys[ksJoy1].Name := '';
+ end;
+ Settings.Keys[ksJoy1].NameIndex := 0;
+ Settings.Keys[ksJoy1].AchsisIndex[0] := 1;
+ Settings.Keys[ksJoy1].AchsisIdle[0] := 0;
+ Settings.Keys[ksJoy1].AchsisDirection[0] := 1;
+ Settings.Keys[ksJoy1].AchsisIndex[1] := 0;
+ Settings.Keys[ksJoy1].AchsisIdle[1] := 0;
+ Settings.Keys[ksJoy1].AchsisDirection[1] := 1;
+ Settings.Keys[ksJoy1].ButtonIndex[0] := 0;
+ Settings.Keys[ksJoy1].ButtonsIdle[0] := false;
+ Settings.Keys[ksJoy1].ButtonIndex[1] := 2;
+ Settings.Keys[ksJoy1].ButtonsIdle[1] := false;
+ end;
+ end;
+ if numJoy > 1 then begin
+ // Configure Joy 2 (ksJoy2) to use joystick 1
+ // Only set UseSDL2 if not already configured (preserve user settings)
+ if not Settings.Keys[ksJoy2].UseSDL2 then begin
+ Settings.Keys[ksJoy2].UseSDL2 := true;
+ try
+ if SDL_JoystickNameForIndex(1) <> nil then
+ Settings.Keys[ksJoy2].Name := SDL_JoystickNameForIndex(1)
+ else
+ Settings.Keys[ksJoy2].Name := '';
+ except
+ Settings.Keys[ksJoy2].Name := '';
+ end;
+ Settings.Keys[ksJoy2].NameIndex := 0;
+ Settings.Keys[ksJoy2].AchsisIndex[0] := 1;
+ Settings.Keys[ksJoy2].AchsisIdle[0] := 0;
+ Settings.Keys[ksJoy2].AchsisDirection[0] := 1;
+ Settings.Keys[ksJoy2].AchsisIndex[1] := 0;
+ Settings.Keys[ksJoy2].AchsisIdle[1] := 0;
+ Settings.Keys[ksJoy2].AchsisDirection[1] := 1;
+ Settings.Keys[ksJoy2].ButtonIndex[0] := 0;
+ Settings.Keys[ksJoy2].ButtonsIdle[0] := false;
+ Settings.Keys[ksJoy2].ButtonIndex[1] := 2;
+ Settings.Keys[ksJoy2].ButtonsIdle[1] := false;
+ end;
+ end;
+
+ // Open legacy joystick instances according to configured names
+ If Settings.Keys[ks0].UseSDL2 Then Begin
+ index := ResolveJoystickNameToIndex(Settings.Keys[ks0].Name, Settings.Keys[ks0].NameIndex);
+ If index <> -1 Then Begin
+ fsdlJoysticks[ks0] := TSDL_Joystick.Create(index);
+ End;
+ End;
+ If Settings.Keys[ks1].UseSDL2 Then Begin
+ index := ResolveJoystickNameToIndex(Settings.Keys[ks1].Name, Settings.Keys[ks1].NameIndex);
+ If index <> -1 Then Begin
+ fsdlJoysticks[ks1] := TSDL_Joystick.Create(index);
+ End;
+ End;
+ // Universal approach: Always map ksJoy1 and ksJoy2 by physical index, not by name
+ // This ensures any controller works regardless of its name
+ // ksJoy1 always maps to physical joystick index 0, ksJoy2 to index 1
+ If Settings.Keys[ksJoy1].UseSDL2 And (numJoy > 0) Then Begin
+ // Always use physical index 0 for ksJoy1, regardless of saved name
+ // This ensures universal compatibility - any controller at index 0 will work
+ try
+ fsdlJoysticks[ksJoy1] := TSDL_Joystick.Create(0);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[ksJoy1] := Nil;
+ End;
+ end;
+ End;
+ If Settings.Keys[ksJoy2].UseSDL2 And (numJoy > 1) Then Begin
+ // Always use physical index 1 for ksJoy2, regardless of saved name
+ // This ensures universal compatibility - any controller at index 1 will work
+ try
+ fsdlJoysticks[ksJoy2] := TSDL_Joystick.Create(1);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[ksJoy2] := Nil;
+ End;
+ end;
+ End;
+ End;
+End;
+
+Function TGame.GetKeySetDisplayName(Keys: TKeySet): String;
+begin
+ // Handle joystick-specific keysets - show just "Joy 1" or "Joy 2" without controller name
+ if keys = ksJoy1 then begin
+ exit('Joy 1');
+ end;
+ if keys = ksJoy2 then begin
+ exit('Joy 2');
+ end;
+
+ // Keyboard labels - shortened to "Key 0" and "Key 1" for consistency with "Joy 1" and "Joy 2"
+ if keys = ks0 then exit('Key 0') else exit('Key 1');
+end;
+
+Function TGame.GetServerIPAddress(): String;
+Var
+ adapters: TNetworkAdapterList;
+ i: Integer;
+Begin
+ Result := '127.0.0.1'; // Default to localhost
+ Try
+ adapters := GetLocalIPs();
+ // Find first non-localhost IP address (prefer network IP over localhost)
+ For i := 0 To High(adapters) Do Begin
+ If (adapters[i].IpAddress <> '127.0.0.1') And (adapters[i].IpAddress <> '') Then Begin
+ Result := adapters[i].IpAddress;
+ log('Server IP address: ' + Result, llInfo);
+ exit;
+ End;
+ End;
+ // If no network IP found, use localhost
+ log('No network IP found, using localhost: ' + Result, llInfo);
+ Except
+ On E: Exception Do Begin
+ log('Error getting server IP address: ' + E.Message + ', using localhost', llWarning);
+ Result := '127.0.0.1';
+ End;
+ End;
End;
Function TGame.StartHost: Boolean;
Var
serv: String;
p: TProcessUTF8;
+ basePath, clientPath: String;
+{$IFDEF DARWIN}
+ serverAppPath: String;
+ portCheck: TProcessUTF8;
+ portCheckOutput: String;
+ portCheckCount: Integer;
+ portListening: Boolean;
+{$ENDIF}
+{$IFDEF UNIX}
+{$IFNDEF DARWIN}
+ serverCmd: String;
+ terminalFound: Boolean;
+ terminalExe: String;
+{$ENDIF}
+{$ENDIF}
Begin
//Begin
log('TGame.StartHost', llTrace);
result := false;
// Starten des Atomic_servers, dann als Client verbinden
- serv := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'atomic_server';
+ clientPath := ExtractFilePath(ParamStrUTF8(0));
+ basePath := IncludeTrailingPathDelimiter(clientPath);
+{$IFDEF DARWIN}
+ // On macOS, check if we're in an .app bundle
+ // If so, look for FPCAtomicServer.app in the same directory as FPCAtomic.app
+ If Pos('.app/Contents/MacOS/', clientPath) > 0 Then Begin
+ // We're in an .app bundle (e.g., FPCAtomic.app/Contents/MacOS/)
+ // Go up to the app bundle directory (../../ from MacOS)
+ serverAppPath := ExpandFileName(IncludeTrailingPathDelimiter(clientPath) + '../../');
+ // Replace FPCAtomic.app with FPCAtomicServer.app
+ If Pos('FPCAtomic.app', serverAppPath) > 0 Then Begin
+ serverAppPath := StringReplace(serverAppPath, 'FPCAtomic.app', 'FPCAtomicServer.app', []);
+ End
+ Else Begin
+ // Fallback: try relative to MacOS directory
+ serverAppPath := ExpandFileName(IncludeTrailingPathDelimiter(clientPath) + '../../../FPCAtomicServer.app');
+ End;
+ log('Looking for server app at: ' + serverAppPath, llInfo);
+ If DirectoryExistsUTF8(serverAppPath) Then Begin
+ // Launch server directly with atomic_server binary (like run_server script does)
+ // This ensures DYLD_LIBRARY_PATH is set correctly and parameters are passed
+ serv := IncludeTrailingPathDelimiter(serverAppPath) + 'Contents/MacOS/atomic_server';
+ If FileExistsUTF8(serv) Then Begin
+ log('Launching server in terminal: ' + serv, llInfo);
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poDetached];
+ // Use osascript to open Terminal and run server command
+ p.Executable := '/usr/bin/osascript';
+ p.Parameters.Add('-e');
+ p.Parameters.Add('tell application "Terminal" to do script "cd ''' +
+ IncludeTrailingPathDelimiter(serverAppPath) + 'Contents/MacOS''' +
+ ' && export DYLD_LIBRARY_PATH=''' + IncludeTrailingPathDelimiter(serverAppPath) + 'Contents/lib:$DYLD_LIBRARY_PATH''' +
+ ' && ''' + serv + ''' -p ' + inttostr(settings.Port) +
+ ' -t 0 -l ' + IntToStr(GetLoggerLoglevel()) + '; echo \"\nServer terminated. Press any key to close this window...\"; read"');
+ p.Execute;
+ p.free;
+ result := true;
+ fServerPID := 0; // Server runs in terminal, no PID tracking needed
+ // Wait for server to start
+ Sleep(2000);
+ LogLeave;
+ exit;
+ End
+ Else Begin
+ log('Server binary not found at: ' + serv, llWarning);
+ End;
+ End
+ Else Begin
+ log('Server app not found at: ' + serverAppPath, llWarning);
+ End;
+ End;
+{$ENDIF}
+ // Fallback: look for atomic_server binary in the same directory
+ serv := basePath + 'atomic_server';
{$IFDEF Windows}
serv := serv + '.exe';
{$ENDIF}
If FileExistsUTF8(serv) Then Begin
+ log('Launching server in terminal: ' + serv, llInfo);
+{$IFDEF Windows}
+ // On Windows, use start command to open new console window
p := TProcessUTF8.Create(Nil);
- p.Options := [poNewConsole];
+ p.Options := [poDetached];
+ p.Executable := 'cmd.exe';
+ p.Parameters.Add('/c');
+ p.Parameters.Add('start');
+ p.Parameters.Add('"FPC Atomic Server"');
+ p.Parameters.Add('cmd.exe');
+ p.Parameters.Add('/k');
+ // Build the command to run server
+ p.Parameters.Add(serv + ' -p ' + inttostr(settings.Port) +
+ ' -t 0 -l ' + IntToStr(GetLoggerLoglevel()) +
+ ' -f ' + IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'logs' + PathDelim + 'server.log');
+ p.Execute;
+ p.free;
+ fServerPID := 0; // Server runs in terminal, no PID tracking needed
+ Sleep(2000); // Wait for server to start
+{$ELSE}
+{$IFDEF UNIX}
+{$IFNDEF DARWIN}
+ // On Linux/Unix (not macOS), try to find a terminal emulator
+ serverCmd := 'cd ''' + basePath + ''' && ''' + serv + ''' -p ' + inttostr(settings.Port) +
+ ' -t 0 -l ' + IntToStr(GetLoggerLoglevel()) +
+ ' -f ' + IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'logs' + PathDelim + 'server.log' +
+ '; echo ""; echo "Server terminated. Press Enter to close..."; read';
+ terminalFound := false;
+
+ // Try x-terminal-emulator first (works on most Linux systems)
+ terminalExe := FindDefaultExecutablePath('x-terminal-emulator');
+ If (terminalExe <> '') Or FileExistsUTF8('/usr/bin/x-terminal-emulator') Then Begin
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poDetached];
+ If terminalExe <> '' Then p.Executable := terminalExe Else p.Executable := '/usr/bin/x-terminal-emulator';
+ p.Parameters.Add('-e');
+ p.Parameters.Add('bash');
+ p.Parameters.Add('-c');
+ p.Parameters.Add(serverCmd);
+ p.Execute;
+ p.free;
+ terminalFound := true;
+ End
+ // Try gnome-terminal
+ Else Begin
+ terminalExe := FindDefaultExecutablePath('gnome-terminal');
+ If (terminalExe <> '') Or FileExistsUTF8('/usr/bin/gnome-terminal') Then Begin
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poDetached];
+ If terminalExe <> '' Then p.Executable := terminalExe Else p.Executable := '/usr/bin/gnome-terminal';
+ p.Parameters.Add('--');
+ p.Parameters.Add('bash');
+ p.Parameters.Add('-c');
+ p.Parameters.Add(serverCmd);
+ p.Execute;
+ p.free;
+ terminalFound := true;
+ End
+ // Try konsole (KDE)
+ Else Begin
+ terminalExe := FindDefaultExecutablePath('konsole');
+ If (terminalExe <> '') Or FileExistsUTF8('/usr/bin/konsole') Then Begin
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poDetached];
+ If terminalExe <> '' Then p.Executable := terminalExe Else p.Executable := '/usr/bin/konsole';
+ p.Parameters.Add('-e');
+ p.Parameters.Add('bash');
+ p.Parameters.Add('-c');
+ p.Parameters.Add(serverCmd);
+ p.Execute;
+ p.free;
+ terminalFound := true;
+ End
+ // Try xterm as fallback
+ Else Begin
+ terminalExe := FindDefaultExecutablePath('xterm');
+ If (terminalExe <> '') Or FileExistsUTF8('/usr/bin/xterm') Then Begin
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poDetached];
+ If terminalExe <> '' Then p.Executable := terminalExe Else p.Executable := '/usr/bin/xterm';
+ p.Parameters.Add('-e');
+ p.Parameters.Add('bash');
+ p.Parameters.Add('-c');
+ p.Parameters.Add(serverCmd);
+ p.Execute;
+ p.free;
+ terminalFound := true;
+ End;
+ End;
+ End;
+ End;
+
+ If Not terminalFound Then Begin
+ log('Warning: No terminal emulator found, starting server in background', llWarning);
+ // Fallback: start server without terminal
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poNewConsole, poNewProcessGroup];
+ p.Executable := serv;
+ p.Parameters.Add('-p');
+ p.Parameters.Add(inttostr(settings.Port));
+ p.Parameters.Add('-t');
+ p.Parameters.Add('0');
+ p.Parameters.Add('-l');
+ p.Parameters.Add(IntToStr(GetLoggerLoglevel()));
+ p.Parameters.Add('-f');
+ p.Parameters.Add(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'logs' + PathDelim + 'server.log');
+ p.Execute;
+ fServerPID := p.ProcessID;
+ p.free;
+ End
+ Else Begin
+ fServerPID := 0; // Server runs in terminal, no PID tracking needed
+ End;
+ Sleep(2000); // Wait for server to start
+{$ENDIF} // IFNDEF DARWIN
+{$ELSE} // UNIX
+ // Other platforms - fallback to background start
+ p := TProcessUTF8.Create(Nil);
+ p.Options := [poNewConsole, poNewProcessGroup];
p.Executable := serv;
p.Parameters.Add('-p');
p.Parameters.Add(inttostr(settings.Port));
+ p.Parameters.Add('-t');
+ p.Parameters.Add('0');
p.Parameters.Add('-l');
p.Parameters.Add(IntToStr(GetLoggerLoglevel()));
p.Parameters.Add('-f');
p.Parameters.Add(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'logs' + PathDelim + 'server.log');
p.Execute;
+ fServerPID := p.ProcessID;
p.free;
+ Sleep(2000);
+{$ENDIF} // UNIX
+{$ENDIF} // Windows
End
Else Begin
LogShow('Error: could not find server application, abort now', llError);
@@ -783,10 +1801,46 @@
exit;
End;
// Bis der Server Steht dauerts ein bischen, also warten wir
+ // On macOS, .app bundles take longer to start, especially with network thread initialization
+ // Also need time for the server to initialize and start listening on the port
{$IFDEF Windows}
- sleep(1500); // Unter Windows scheint es deutlich "länger" zu dauern, wie lange genau wäre gut zu wissen ..
+ sleep(3000); // Unter Windows scheint es deutlich "länger" zu dauern
+{$ELSE}
+{$IFDEF DARWIN}
+ // Wait for server to start and check if port is listening
+ sleep(3000); // Initial wait for .app bundle to start (increased from 2000ms)
+ // Check if server is actually listening on the port (up to 10 seconds)
+ portListening := false;
+ portCheckCount := 0;
+ While (portCheckCount < 20) And (Not portListening) Do Begin
+ sleep(500); // Check every 500ms
+ Inc(portCheckCount);
+
+ // Use lsof to check if port is listening
+ portCheck := TProcessUTF8.Create(Nil);
+ portCheck.Options := [poUsePipes, poWaitOnExit];
+ portCheck.Executable := '/usr/sbin/lsof';
+ portCheck.Parameters.Add('-i');
+ portCheck.Parameters.Add(':' + inttostr(settings.Port));
+ portCheck.Execute;
+
+ SetLength(portCheckOutput, 1024);
+ SetLength(portCheckOutput, portCheck.Output.Read(portCheckOutput[1], Length(portCheckOutput)));
+ portCheck.Free;
+
+ // If lsof found something, port is listening
+ If Length(portCheckOutput) > 0 Then Begin
+ portListening := true;
+ log('Server is listening on port ' + inttostr(settings.Port), llInfo);
+ End;
+ End;
+
+ If Not portListening Then Begin
+ log('Warning: Server port not detected after ' + inttostr(portCheckCount * 500) + 'ms, will try to connect anyway', llWarning);
+ End;
{$ELSE}
- sleep(500);
+ sleep(3000); // For other Unix-like systems
+{$ENDIF}
{$ENDIF}
// StartClientGame; --> Das Verbinden macht der SwitchToScreen schon ;)
Application.Restore;
@@ -874,6 +1928,10 @@
Begin
// Der Client ist beim Server Registriert, nun gilt es um die Mitspielerlaubniss zu fragen.
log('TGame.Connection_Connect', llTrace);
+
+ // Stop waiting for local server - we're connected now
+ fWaitingForLocalServer := false;
+
fChunkManager.SetNoDelay(true);
m := TMemoryStream.Create;
m.Write(ProtocollVersion, sizeof(ProtocollVersion));
@@ -911,6 +1969,16 @@
Procedure TGame.Connection_Error(Const msg: String; aSocket: TLSocket);
Begin
log('TGame.Connection_Error', llTrace);
+
+ // If we're waiting for local server, don't show error and don't switch to main menu
+ // OnIdle will retry the connection periodically
+ If fWaitingForLocalServer Then Begin
+ log('Connection error while waiting for local server: ' + msg + ' - will retry', llInfo);
+ LogLeave;
+ exit;
+ End;
+
+ // For remote servers or if we're not waiting, show error and go back to main menu
LogShow(msg, llError);
SwitchToScreen(sMainScreen); // Wir Fliegen raus auf die Top ebene
LogLeave;
@@ -987,12 +2055,6 @@
m: TMemoryStream;
b: Boolean;
Begin
-{$IFDEF DoNotLog_CyclicMessages}
- If ((Chunk.UserDefinedID And $FFFF) <> miUpdateGameData) And
- ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
- ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
-{$ENDIF}
- log('TGame.OnReceivedChunk : ' + MessageIdentifierToString(Chunk.UserDefinedID), llTrace);
Case (Chunk.UserDefinedID And $FFFF) Of
miUpdateMasterID: Begin
HandleUpdateMasterId(Chunk.Data);
@@ -1105,12 +2167,6 @@
log('Unknown user defined id : ' + inttostr((Chunk.UserDefinedID And $FFFF)), llError);
End;
End;
-{$IFDEF DoNotLog_CyclicMessages}
- If ((Chunk.UserDefinedID And $FFFF) <> miUpdateGameData) And
- ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
- ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
-{$ENDIF}
- LogLeave;
End;
Procedure TGame.SendChunk(UserDefinedID: Integer; Const Data: TStream);
@@ -1130,7 +2186,7 @@
Procedure TGame.HandleRefreshPlayerStats(Const Stream: TMemoryStream);
Var
- cnt, i, uid, j: integer;
+ cnt, i, uid, j, index, numJoy: integer;
found: Boolean;
k: TKeySet;
Begin
@@ -1153,6 +2209,119 @@
fPlayer[i].UID := uid;
k := ks0;
stream.Read(k, sizeof(k));
+
+ // Check if selected joystick is available, if not, skip to next available option
+ numJoy := 0;
+ try
+ If fsdl_Loaded And Assigned(SDL_NumJoysticks) Then Begin
+ numJoy := SDL_NumJoysticks();
+ End;
+ except
+ numJoy := 0;
+ end;
+
+ // If server set Joy 1 but no joysticks are available, skip to next option
+ If (k = ksJoy1) And (numJoy < 1) Then Begin
+ // Skip to next option by sending another change request
+ If (uid = fUserID) And (fPlayer[i].UID = uid) Then Begin
+ // This is our player, send change request to skip unavailable joystick
+ ChangePlayerKey(i, 1);
+ // Don't process this update, wait for next refresh
+ LogLeave;
+ exit;
+ End
+ Else Begin
+ // Not our player, just set to Keyboard 1 as fallback
+ k := ks1;
+ End;
+ End
+ // If server set Joy 2 but only 0-1 joysticks are available, skip to next option
+ Else If (k = ksJoy2) And (numJoy < 2) Then Begin
+ // Skip to next option by sending another change request
+ If (uid = fUserID) And (fPlayer[i].UID = uid) Then Begin
+ // This is our player, send change request to skip unavailable joystick
+ ChangePlayerKey(i, 1);
+ // Don't process this update, wait for next refresh
+ LogLeave;
+ exit;
+ End
+ Else Begin
+ // Not our player, just set to Keyboard 1 as fallback
+ k := ks1;
+ End;
+ End;
+
+ // Reset UseSDL2 based on selected input type
+ // If player selected keyboard (ks0 or ks1), disable SDL2 and close joystick
+ // If player selected joystick (ksJoy1 or ksJoy2), enable SDL2
+ If (k = ks0) Or (k = ks1) Then Begin
+ // Keyboard input selected - disable SDL2 and close joystick
+ If Settings.Keys[k].UseSDL2 Then Begin
+ Settings.Keys[k].UseSDL2 := false;
+ // Close joystick if open
+ If assigned(fsdlJoysticks[k]) Then Begin
+ fsdlJoysticks[k].Free;
+ fsdlJoysticks[k] := Nil;
+ End;
+ If assigned(fsdlControllers[k]) Then Begin
+ fsdlControllers[k].Free;
+ fsdlControllers[k] := Nil;
+ End;
+ End;
+ End Else If (k = ksJoy1) Or (k = ksJoy2) Then Begin
+ // Joystick input selected - ensure SDL2 is enabled
+ If Not Settings.Keys[k].UseSDL2 Then Begin
+ Settings.Keys[k].UseSDL2 := true;
+ // Open joystick if not already open
+ // Universal approach: Always map by physical index, not by name
+ // ksJoy1 always maps to physical joystick index 0, ksJoy2 to index 1
+ If Not assigned(fsdlJoysticks[k]) And fsdl_Loaded Then Begin
+ If (k = ksJoy1) And (numJoy > 0) Then Begin
+ // Always use physical index 0 for ksJoy1
+ try
+ fsdlJoysticks[k] := TSDL_Joystick.Create(0);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[k] := Nil;
+ End;
+ end;
+ End Else If (k = ksJoy2) And (numJoy > 1) Then Begin
+ // Always use physical index 1 for ksJoy2
+ try
+ fsdlJoysticks[k] := TSDL_Joystick.Create(1);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[k] := Nil;
+ End;
+ end;
+ End;
+ End;
+ End Else Begin
+ // SDL2 already enabled, but make sure joystick is open
+ // Universal approach: Always map by physical index, not by name
+ If Not assigned(fsdlJoysticks[k]) And fsdl_Loaded Then Begin
+ If (k = ksJoy1) And (numJoy > 0) Then Begin
+ // Always use physical index 0 for ksJoy1
+ try
+ fsdlJoysticks[k] := TSDL_Joystick.Create(0);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[k] := Nil;
+ End;
+ end;
+ End Else If (k = ksJoy2) And (numJoy > 1) Then Begin
+ // Always use physical index 1 for ksJoy2
+ try
+ fsdlJoysticks[k] := TSDL_Joystick.Create(1);
+ except
+ On E: Exception Do Begin
+ fsdlJoysticks[k] := Nil;
+ End;
+ end;
+ End;
+ End;
+ End;
+ End;
fPlayer[i].Keyboard := k;
j := -1;
stream.Read(j, SizeOf(j));
@@ -1221,6 +2390,7 @@
i: Integer;
ahash: uint64;
s: String;
+ found: Boolean;
Begin
log('TGame.HandleUpdateAvailableFieldList', llTrace);
For i := 0 To high(fFields) Do Begin
@@ -1231,13 +2401,29 @@
s := stream.ReadAnsiString;
ahash := 0;
stream.Read(ahash, sizeof(ahash));
+ found := false;
+ // First try exact match (name and hash)
For i := 0 To high(fFields) Do Begin
- If (fFields[i].Name = s) And
+ If (CompareText(fFields[i].Name, s) = 0) And
(fFields[i].Hash = ahash) Then Begin
fFields[i].Available := true;
+ found := true;
break;
End;
End;
+ // If exact match not found, try name-only match (for cross-platform compatibility)
+ If Not found Then Begin
+ For i := 0 To high(fFields) Do Begin
+ If CompareText(fFields[i].Name, s) = 0 Then Begin
+ // Name matches but hash differs - accept for cross-platform compatibility
+ // Log warning for debugging (commented out - too noisy in production)
+ // log(format('Field "%s": accepting despite hash mismatch (Server hash: %d, Local hash: %d)',
+ // [s, ahash, fFields[i].Hash]), llWarning);
+ fFields[i].Available := true;
+ break;
+ End;
+ End;
+ End;
End;
// Prüfen ob wir wenigstens noch eine Verfügbare Karte haben
For i := 0 To high(fFields) - 1 Do Begin // Das Letzte Field ist das Random Field, das zählt nicht
@@ -1264,8 +2450,9 @@
fActualField := Nil;
stream.Read(FieldHash, SizeOf(FieldHash));
stream.Read(Wins, SizeOf(Wins));
+ // First try exact match (name and hash)
For i := 0 To high(fFields) Do Begin
- If (fFields[i].Name = FieldName)
+ If (CompareText(fFields[i].Name, FieldName) = 0)
And (fFields[i].Hash = FieldHash) Then Begin
fActualField := fFields[i];
TFieldSetupMenu(fScreens[sEditFieldSetup]).ActualField := fActualField;
@@ -1275,6 +2462,21 @@
exit;
End;
End;
+ // If exact match not found, try name-only match (for cross-platform compatibility)
+ // This handles cases where Windows and Mac have different file versions but same field name
+ For i := 0 To high(fFields) Do Begin
+ If CompareText(fFields[i].Name, FieldName) = 0 Then Begin
+ // Name matches but hash differs - accept for cross-platform compatibility
+ log(format('Field name match but hash mismatch (using local field): Server "%s" (hash: %d) vs Local "%s" (hash: %d)',
+ [FieldName, FieldHash, fFields[i].Name, fFields[i].Hash]), llWarning);
+ fActualField := fFields[i];
+ TFieldSetupMenu(fScreens[sEditFieldSetup]).ActualField := fActualField;
+ TFieldSetupMenu(fScreens[sEditFieldSetup]).LastWinsToWinMatch := wins;
+ Settings.LastWinsToWinMatch := wins;
+ LogLeave;
+ exit;
+ End;
+ End;
// Der Spieler fliegt raus, er kann offensichtlich nicht mit spielen
// Eigentlich darf dieser Code hier aber nie kommen, weil der Master
// Nicht weiterschalten kann wenn nicht alle Spieler die Karten haben ..
@@ -1320,6 +2522,8 @@
fHurry.Enabled := false;
fPlayerIndex[ks0] := -1;
fPlayerIndex[ks1] := -1;
+ fPlayerIndex[ksJoy1] := -1;
+ fPlayerIndex[ksJoy2] := -1;
For i := 0 To high(fPlayer) Do Begin
(*
* Löschen der ggf. vorherigen Die Animation, sonst beginnt der Spieler das Spiel erst mal sterbend...
@@ -1336,11 +2540,35 @@
End;
fLastKeyDown[akFirstAction] := 0;
fLastKeyDown[akSecondAction] := 0;
+ // Transfer menu blocking to game blocking if menu input was blocked (button still pressed)
+ // Otherwise set game blocking anyway to be safe
+ If fBlockMenuInputUntilRelease Then Begin
+ // Button was pressed in menu and is still blocked - transfer to game blocking
+ fBlockGameInputUntilRelease := true;
+ fBlockMenuInputUntilRelease := false;
+ End Else Begin
+ // Set game blocking anyway to prevent any stray presses
+ fBlockGameInputUntilRelease := true;
+ End;
fActualField.Reset;
// TODO: What ever da noch alles so fehlt
StartPlayingSong(fActualField.Sound);
HandleSetPause(false); // Pause auf jeden Fall, aus
fPlayingTime_s := 0;
+
+ // Reset interpolation snapshots when game starts
+ fServerSnapshots[0].Valid := False;
+ fServerSnapshots[0].Timestamp := 0;
+ fServerSnapshots[1].Valid := False;
+ fServerSnapshots[1].Timestamp := 0;
+ fCurrentSnapshot := 0;
+ fInterpolatedState.PlayingTime_ms := 0;
+
+ // Reset MAX stats for new game
+ fDebugStats.MaxRTT := 0;
+ fDebugStats.MaxSnapAge := 0;
+ fDebugStats.MaxInterpFactor := 0;
+
fgameState := gs_Gaming;
End;
@@ -1354,33 +2582,80 @@
i: Integer;
OldValue: UInt16; // Bei Die, Zen, Locked in braucht es ebenfalls den Index
OldAnim: TRenderAnimation;
+ CurrentTime, TimeSinceLastUpdate: QWord;
+ PacketSize: Int64;
Begin
- stream.Read(fPlayingTime_s, sizeof(fPlayingTime_s));
+ CurrentTime := GetTickCount64;
+ PacketSize := Stream.Size;
+
+ // Measure time since last update (for debug stats only, no logging)
+ If fLastUpdateTimestamp > 0 Then Begin
+ TimeSinceLastUpdate := CurrentTime - fLastUpdateTimestamp;
+ // Removed logging - was slowing down client on older machines
+ End;
+ // Calculate RTT for debug stats
+ If fLastUpdateTimestamp > 0 Then Begin
+ fDebugStats.LastRTT := CurrentTime - fLastUpdateTimestamp;
+ If fDebugStats.AvgRTT = 0 Then
+ fDebugStats.AvgRTT := fDebugStats.LastRTT
+ Else
+ fDebugStats.AvgRTT := fDebugStats.AvgRTT * 0.9 + fDebugStats.LastRTT * 0.1; // Running average
+ // Track MAX RTT
+ If fDebugStats.LastRTT > fDebugStats.MaxRTT Then
+ fDebugStats.MaxRTT := fDebugStats.LastRTT;
+ End;
+ fLastUpdateTimestamp := CurrentTime;
+
+ // === NEW: Store data in snapshot instead of directly in fPlayingTime_s ===
+ // Switch to next snapshot buffer
+ fCurrentSnapshot := 1 - fCurrentSnapshot;
+
+ // Read server data into NEW snapshot
+ stream.Read(fPlayingTime_s, sizeof(fPlayingTime_s)); // Read temporarily
+ fServerSnapshots[fCurrentSnapshot].ServerTime_ms := fPlayingTime_s * 1000; // Convert to ms
+ fServerSnapshots[fCurrentSnapshot].Timestamp := CurrentTime;
+ fServerSnapshots[fCurrentSnapshot].Valid := True;
+
+ // Read player positions into snapshot
For i := 0 To high(fPlayer) Do Begin
OldValue := fPlayer[i].Info.Value;
OldAnim := fPlayer[i].Info.Animation;
- Stream.Read(fPlayer[i].Info, sizeof(fPlayer[i].Info));
+ Stream.Read(fServerSnapshots[fCurrentSnapshot].PlayerInfos[i], sizeof(TAtomicInfo));
+
+ // === IMPORTANT: Only copy NON-POSITION data to fPlayer for Edge detection ===
+ // DO NOT copy Position - that's handled by interpolation!
+ fPlayer[i].Info.Animation := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Animation;
+ fPlayer[i].Info.Alive := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Alive;
+ fPlayer[i].Info.Dying := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Dying;
+ fPlayer[i].Info.Direction := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Direction;
+ fPlayer[i].Info.Counter := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Counter;
+ fPlayer[i].Info.Value := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Value;
+ fPlayer[i].Info.ColorIndex := fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].ColorIndex;
+ // Position is NOT copied here - it's interpolated in InterpolateGameState()!
+
(*
* Der Server sendet die OneTimeAnimations genau 1 mal
* Wenn der Server aber schneller neu Sendet als der CLient Rendert
* dann würde der Client diese Flanke beim Rendern gar nicht berücksichtigen
* -> Hier ein Or und im Rendern dann das False !
*)
- fPlayer[i].Edge := (fPlayer[i].Info.Animation In OneTimeAnimations) And (OldAnim <> fPlayer[i].Info.Animation);
+ fPlayer[i].Edge := (fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Animation In OneTimeAnimations) And
+ (OldAnim <> fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Animation);
(*
* Wenn eine neue Animation kommt, stellen wir hier Sicher, dass die neue die alte
* überschreiben kann z.B. "Zen" -> Die
* Die Zen Animation, kann zusätzlich aber auch vom Laufen unterbrochen werden, da
* diese ja nur kommt wenn der Spieler AtomicZenTime lang keine Eingaben gemacht hat.
*)
- If (fPlayer[i].Edge) Or (((OldAnim = raZen) Or (oldAnim = raLockedIn)) And (fPlayer[i].Info.Animation = raWalk)) Then Begin
+ If (fPlayer[i].Edge) Or (((OldAnim = raZen) Or (oldAnim = raLockedIn)) And
+ (fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Animation = raWalk)) Then Begin
OldAnim := raStandStill; // -- Egal es soll ja nur die OldAnim In OneTimeAnimations verhindert werden
End;
(*
* Wenn die Alte Animation eine einmal ablaufen Animation ist.
*)
If OldAnim In OneTimeAnimations Then Begin
- If fPlayer[i].Info.Counter < fAtomics[0].GetAnimTimeInMs(OldAnim, OldValue) Then Begin
+ If fServerSnapshots[fCurrentSnapshot].PlayerInfos[i].Counter < fAtomics[0].GetAnimTimeInMs(OldAnim, OldValue) Then Begin
fPlayer[i].Info.Animation := OldAnim;
fPlayer[i].Info.Value := OldValue;
End;
@@ -1414,6 +2689,8 @@
For ak In TAtomicKey Do Begin
If fPlayerIndex[ks0] <> -1 Then fPlayer[fPlayerIndex[ks0]].KeysPressed[ak] := false;
If fPlayerIndex[ks1] <> -1 Then fPlayer[fPlayerIndex[ks1]].KeysPressed[ak] := false;
+ If fPlayerIndex[ksJoy1] <> -1 Then fPlayer[fPlayerIndex[ksJoy1]].KeysPressed[ak] := false;
+ If fPlayerIndex[ksJoy2] <> -1 Then fPlayer[fPlayerIndex[ksJoy2]].KeysPressed[ak] := false;
End;
End;
End;
@@ -1443,35 +2720,51 @@
Procedure TGame.HandlePlaySoundEffekt(Const Stream: TMemoryStream);
Var
se: TSoundEffect;
- s: String;
+ s, soundFile: String;
Begin
se := seNone;
stream.Read(se, SizeOf(TSoundEffect));
- s := '';
+ soundFile := '';
Case se Of
seNone: Begin // Nix
End;
- seBombDrop: s := SelectRandomSound(BombDrops);
- seBombKick: s := SelectRandomSound(BombKick);
- seBombStop: s := SelectRandomSound(BombStop);
- seBombJelly: s := SelectRandomSound(BombJelly);
- seBombBounce: s := SelectRandomSound(BombBounce);
- seBombGrab: s := SelectRandomSound(BombGrab);
- seBombPunch: s := SelectRandomSound(BombPunch);
- seBombExplode: s := SelectRandomSound(BombExplode);
- seAtomicDie: s := SelectRandomSound(AtomicDie);
- seWinner: s := SelectRandomSound(Winner);
- seGetGoodPowerUp: s := SelectRandomSound(GetGoodPowerUp);
- seGetBadPowerUp: s := SelectRandomSound(GetBadPowerUp);
- seZen: s := SelectRandomSound(AtomicZen);
- seOtherPlayerDied: s := SelectRandomSound(OtherPlayerDie);
- seHurryBrick: s := SelectRandomSound(HurryBrick);
- seHurry: s := SelectRandomSound(Hurry);
- seWrapHohle: s := SelectRandomSound(AtomicWrapHole);
- seTrampoline: s := SelectRandomSound(AtomicJump);
- End;
- If s <> '' Then s := 'data' + PathDelim + 'sounds' + PathDelim + s;
- PlaySoundEffect(s);
+ seBombDrop: soundFile := SelectRandomSound(BombDrops);
+ seBombKick: soundFile := SelectRandomSound(BombKick);
+ seBombStop: soundFile := SelectRandomSound(BombStop);
+ seBombJelly: soundFile := SelectRandomSound(BombJelly);
+ seBombBounce: soundFile := SelectRandomSound(BombBounce);
+ seBombGrab: soundFile := SelectRandomSound(BombGrab);
+ seBombPunch: soundFile := SelectRandomSound(BombPunch);
+ seBombExplode: soundFile := SelectRandomSound(BombExplode);
+ seAtomicDie: soundFile := SelectRandomSound(AtomicDie);
+ seWinner: soundFile := SelectRandomSound(Winner);
+ seGetGoodPowerUp: soundFile := SelectRandomSound(GetGoodPowerUp);
+ seGetBadPowerUp: soundFile := SelectRandomSound(GetBadPowerUp);
+ seZen: soundFile := SelectRandomSound(AtomicZen);
+ seOtherPlayerDied: soundFile := SelectRandomSound(OtherPlayerDie);
+ seHurryBrick: soundFile := SelectRandomSound(HurryBrick);
+ seHurry: soundFile := SelectRandomSound(Hurry);
+ seWrapHohle: soundFile := SelectRandomSound(AtomicWrapHole);
+ seTrampoline: soundFile := SelectRandomSound(AtomicJump);
+ End;
+ If soundFile <> '' Then Begin
+ If fDataPath = '' Then Begin
+ fDataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ log('fDataPath was empty, resolved to: ' + fDataPath, llInfo);
+ End;
+ s := fDataPath + 'sounds' + PathDelim + soundFile;
+ If Not FileExistsUTF8(s) Then Begin
+ log('Sound effect file not found: ' + s + ', trying to re-resolve data path', llWarning);
+ // Try to re-resolve data path
+ fDataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ s := fDataPath + 'sounds' + PathDelim + soundFile;
+ log('Retrying with resolved path: ' + s, llInfo);
+ If Not FileExistsUTF8(s) Then Begin
+ log('Sound effect file still not found: ' + s, llError);
+ End;
+ End;
+ PlaySoundEffect(s);
+ End;
End;
Procedure TGame.HandleUpdateMasterId(Const Stream: TMemoryStream);
@@ -1663,7 +2956,10 @@
Begin
log('TGame.LoadScheme: ' + SchemeFileName, llTrace);
result := false;
- fn := 'data' + PathDelim + 'schemes' + PathDelim + SchemeFileName;
+ If fDataPath = '' Then Begin
+ fDataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ End;
+ fn := fDataPath + 'schemes' + PathDelim + SchemeFileName;
If Not FileExistsUTF8(fn) Then Begin
logshow('Error, could not find scheme file:' + SchemeFileName, llCritical);
LogLeave;
@@ -1752,9 +3048,10 @@
AtomicFont.BackColor := clBlack; // Auf Jeden Fall die BackColor wieder Resetten
(*
* Die Verbleibende Spielzeit
+ * === CHANGED: Use interpolated time instead of raw server time ===
*)
glColor3f(1, 1, 1);
- AtomicBigFont.Textout(500, 10, fPlayingTime_s);
+ AtomicBigFont.Textout(500, 10, fInterpolatedState.PlayingTime_ms div 1000);
glPopMatrix;
End;
@@ -1865,18 +3162,49 @@
End;
Procedure TGame.Join(IP: String; Port: Integer);
+Var
+ isLocalhost: Boolean;
Begin
log('TGame.Join', lltrace);
log(format('Joining to %s on port %d as %s', [ip, port, Settings.NodeName]));
- (*
- * Sollte aus welchem Grund auch immer der Chunkmanager nicht verbinden können (ggf weil er schon verbunden ist),
- * fliegt er hier über den Wechsel in den MainScreen raus und wird dann automatisch disconnected
- * -> Spätestens wenn der User es nun erneut versucht kommt er wieder rein.
- *)
+
+ // Store connection parameters for retry logic
+ fParamJoinIP := ip;
+ fParamJoinPort := port;
+
+ // Check if connecting to localhost
+ isLocalhost := (ip = '127.0.0.1') Or (ip = 'localhost');
+
+ If isLocalhost Then Begin
+ // For localhost, enable waiting mode - will retry periodically in OnIdle
+ // This is needed because localhost "connection refused" comes back immediately
+ // while remote servers may take time to respond (allowing time for server to start)
+ fWaitingForLocalServer := true;
+ fLastConnectionAttempt := 0; // Will trigger immediate attempt in OnIdle
+ fConnectionRetryInterval := 2000; // Retry every 2 seconds
+ log('Localhost connection - will retry periodically until server is available', llInfo);
+ End
+ Else Begin
+ // For remote servers, connection attempt is async - if it fails, Connection_Error will handle it
+ fWaitingForLocalServer := false;
+ End;
+
+ // Initiate async connection attempt
+ // Note: Connect() returning True only means the async connection was initiated,
+ // not that we're actually connected. Real connection status comes via callbacks.
If Not fChunkManager.Connect(ip, port) Then Begin
- LogShow('Error could not connect to server', llError);
- SwitchToScreen(sMainScreen);
+ // Immediate failure - connection couldn't even be initiated
+ log('Could not initiate connection', llWarning);
+ If Not isLocalhost Then Begin
+ LogShow('Error: Could not initiate connection to server', llError);
+ SwitchToScreen(sMainScreen);
+ End;
+ // For localhost, OnIdle will retry
+ End
+ Else Begin
+ log('Connection initiated (async), waiting for result...', llInfo);
End;
+
logleave;
End;
@@ -1886,13 +3214,47 @@
fsdl_Loaded := false;
fsdlJoysticks[ks0] := Nil;
fsdlJoysticks[ks1] := Nil;
+ fControllerLogged[ks0] := false;
+ fControllerLogged[ks1] := false;
+ fLastUpdateTimestamp := 0; // Initialize network performance monitoring
+
+ // Initialize interpolation
+ fServerSnapshots[0].Valid := False;
+ fServerSnapshots[0].Timestamp := 0;
+ fServerSnapshots[1].Valid := False;
+ fServerSnapshots[1].Timestamp := 0;
+ fCurrentSnapshot := 0;
+ fInterpolationDelay := 0; // 0ms delay - interpolate between last 2 snapshots immediately
+ fExtrapolationLimit := 50; // Max 50ms extrapolation (reduced from 100ms)
+ fDebugStats.LastRTT := 0;
+ fDebugStats.AvgRTT := 0;
+ fDebugStats.MaxRTT := 0;
+ fDebugStats.InterpolationFactor := 0;
+ fDebugStats.MaxInterpFactor := 0;
+ fDebugStats.IsExtrapolating := False;
+ fDebugStats.SnapshotAge := 0;
+ fDebugStats.MaxSnapAge := 0;
+
+ fMenuDpadState.up := false;
+ fMenuDpadState.down := false;
+ fMenuDpadState.left := false;
+ fMenuDpadState.right := false;
+ fMenuDpadState.buttonA := false;
+ fMenuDpadState.buttonB := false;
+ fBlockGameInputUntilRelease := false;
+ fBlockMenuInputUntilRelease := false;
fSoundManager := TSoundManager.Create();
fSoundInfo := TSoundInfo.Create();
fParamJoinIP := '';
+ fWaitingForLocalServer := false;
+ fLastConnectionAttempt := 0;
+ fConnectionRetryInterval := 2000; // Retry every 2 seconds
fPause := false;
fNeedDisconnect := false;
fPlayerIndex[ks0] := -1;
fPlayerIndex[ks1] := -1;
+ fPlayerIndex[ksJoy1] := -1;
+ fPlayerIndex[ksJoy2] := -1;
fInitialized := false;
fActualScreen := Nil;
fChunkManager := TChunkManager.create;
@@ -1901,6 +3263,15 @@
fLastIdleTick := GetTickCount64;
OnNeedHideCursor := Nil;
OnNeedShowCursor := Nil;
+ FViewportOffsetX := 0;
+ FViewportOffsetY := 0;
+ FViewportWidth := GameWidth;
+ FViewportHeight := GameHeight;
+ FControlWidth := GameWidth;
+ FControlHeight := GameHeight;
+ FViewportScale := 1;
+ fDataPath := ''; // Will be set in Initialize
+ fServerPID := 0; // No server started initially
End;
Destructor TGame.Destroy;
@@ -1908,10 +3279,18 @@
i: TScreenEnum;
j: Integer;
Begin
+ // Server is running in terminal window - user can terminate it manually
+ // No automatic termination to avoid Access violation errors
+ fServerPID := 0;
+
If assigned(fsdlJoysticks[ks0]) Then fsdlJoysticks[ks0].free;
If assigned(fsdlJoysticks[ks1]) Then fsdlJoysticks[ks1].free;
+ If assigned(fsdlJoysticks[ksJoy1]) Then fsdlJoysticks[ksJoy1].free;
+ If assigned(fsdlJoysticks[ksJoy2]) Then fsdlJoysticks[ksJoy2].free;
fsdlJoysticks[ks0] := Nil;
fsdlJoysticks[ks1] := Nil;
+ fsdlJoysticks[ksJoy1] := Nil;
+ fsdlJoysticks[ksJoy2] := Nil;
fSoundManager.free;
fSoundManager := Nil;
fArrows.free;
@@ -1944,6 +3323,9 @@
Connection.OnError := @Connection_Error;
fChunkManager.OnReceivedChunk := @OnReceivedChunk;
fChunkManager.RegisterConnection(Connection);
+ // Start network thread for non-blocking network processing
+ fChunkManager.StartNetworkThread();
+ log('Network thread started for client', llInfo);
LogLeave;
End;
@@ -1990,9 +3372,37 @@
{$IFDEF ShowInitTime}
t := GetTickCount64;
{$ENDIF}
+ uearlylog.EarlyLog('TGame.Initialize: Starting');
+ uearlylog.EarlyLog('TGame.Initialize: Owner assigned: ' + BoolToStr(Assigned(Owner), true));
log('TGame.Initialize', lltrace);
+ log('TGame.Initialize: Owner assigned: ' + BoolToStr(Assigned(Owner), true), llInfo);
fOwner := Owner;
- Loader := TLoaderDialog.create(Owner);
+
+ // Resolve data path BEFORE creating Loader dialog (Loader needs it)
+ p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
+ uearlylog.EarlyLog('TGame.Initialize: Assets root: ' + p);
+ // Resolve data directory path - check multiple locations for .app bundle compatibility
+ fDataPath := ResolveResourceBase(p);
+ uearlylog.EarlyLog('TGame.Initialize: Data path: ' + fDataPath);
+ uearlylog.EarlyLog('TGame.Initialize: Data path exists: ' + BoolToStr(DirectoryExists(fDataPath), true));
+ log('Assets root: ' + p, llInfo);
+ log('Data path: ' + fDataPath, llInfo);
+ log('Data path exists: ' + BoolToStr(DirectoryExists(fDataPath), true), llInfo);
+ Try
+ uearlylog.EarlyLog('TGame.Initialize: Creating TLoaderDialog...');
+ Loader := TLoaderDialog.create(Owner, fDataPath);
+ fLoaderDialog := Loader; // Store reference for OnPaint
+ uearlylog.EarlyLog('TGame.Initialize: TLoaderDialog created successfully');
+ log('TLoaderDialog created successfully', llInfo);
+ Except
+ On E: Exception Do Begin
+ uearlylog.EarlyLog('ERROR creating TLoaderDialog: ' + E.Message);
+ uearlylog.EarlyLog('Exception class: ' + E.ClassName);
+ log('ERROR creating TLoaderDialog: ' + E.Message, llError);
+ log('Exception class: ' + E.ClassName, llError);
+ Raise;
+ End;
+ End;
(*
* Lade Prozente
* 0..10 : Screens
@@ -2024,8 +3434,7 @@
FOnKeyUpCapture := Owner.OnKeyUp;
Owner.OnKeyUp := @FOnKeyUp;
- p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
- AtomicBigFont.CreateFont(p + 'data' + PathDelim + 'res' + PathDelim);
+ AtomicBigFont.CreateFont(fDataPath + 'res' + PathDelim);
// Laden aller Screens
fScreens[sMainScreen] := TMainMenu.Create(self);
@@ -2043,9 +3452,10 @@
fScreens[sOptions] := TOptionsMenu.Create(self);
fScreens[sExitBomberman] := Nil;
+ log('Loading UI screens from ' + fDataPath + 'res', llInfo);
For i In TScreenEnum Do Begin
If Not assigned(fScreens[i]) Then Continue;
- fScreens[i].LoadFromDisk(p + 'data' + PathDelim + 'res' + PathDelim);
+ fScreens[i].LoadFromDisk(fDataPath + 'res' + PathDelim);
End;
Loader.Percent := 10;
Loader.Render();
@@ -2054,59 +3464,133 @@
{$ENDIF}
fPowerUpsTex[puNone] := 0; // Das Gibts ja net -> Weg
- fPowerUpsTex[puExtraBomb] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powbomb.png', smStretchHard);
- If fPowerUpsTex[puExtraBomb] = 0 Then exit;
- fPowerUpsTex[puLongerFlameLength] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powflame.png', smStretchHard);
- If fPowerUpsTex[puLongerFlameLength] = 0 Then exit;
- fPowerUpsTex[puDisease] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powdisea.png', smStretchHard);
- If fPowerUpsTex[puDisease] = 0 Then exit;
- fPowerUpsTex[puCanCick] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powkick.png', smStretchHard);
- If fPowerUpsTex[puCanCick] = 0 Then exit;
- fPowerUpsTex[puExtraSpeed] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powskate.png', smStretchHard);
- If fPowerUpsTex[puExtraSpeed] = 0 Then exit;
- fPowerUpsTex[puCanPunch] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powpunch.png', smStretchHard);
- If fPowerUpsTex[puCanPunch] = 0 Then exit;
- fPowerUpsTex[puCanGrab] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powgrab.png', smStretchHard);
- If fPowerUpsTex[puCanGrab] = 0 Then exit;
- fPowerUpsTex[puCanSpooger] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powspoog.png', smStretchHard);
- If fPowerUpsTex[puCanSpooger] = 0 Then exit;
- fPowerUpsTex[puGoldFlame] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powgold.png', smStretchHard);
- If fPowerUpsTex[puGoldFlame] = 0 Then exit;
- fPowerUpsTex[puTrigger] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powtrig.png', smStretchHard);
- If fPowerUpsTex[puTrigger] = 0 Then exit;
- fPowerUpsTex[puCanJelly] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powjelly.png', smStretchHard);
- If fPowerUpsTex[puCanJelly] = 0 Then exit;
- fPowerUpsTex[puSuperBadDisease] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powebola.png', smStretchHard);
- If fPowerUpsTex[puSuperBadDisease] = 0 Then exit;
- fPowerUpsTex[puSlow] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powslow.png', smStretchHard);
- If fPowerUpsTex[puSlow] = 0 Then exit;
- fPowerUpsTex[purandom] := OpenGL_GraphikEngine.LoadGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'powrand.png', smStretchHard);
- If fPowerUpsTex[purandom] = 0 Then exit;
+ fPowerUpsTex[puExtraBomb] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powbomb.png', smStretchHard);
+ If fPowerUpsTex[puExtraBomb] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powbomb.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puLongerFlameLength] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powflame.png', smStretchHard);
+ If fPowerUpsTex[puLongerFlameLength] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powflame.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puDisease] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powdisea.png', smStretchHard);
+ If fPowerUpsTex[puDisease] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powdisea.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puCanCick] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powkick.png', smStretchHard);
+ If fPowerUpsTex[puCanCick] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powkick.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puExtraSpeed] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powskate.png', smStretchHard);
+ If fPowerUpsTex[puExtraSpeed] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powskate.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puCanPunch] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powpunch.png', smStretchHard);
+ If fPowerUpsTex[puCanPunch] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powpunch.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puCanGrab] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powgrab.png', smStretchHard);
+ If fPowerUpsTex[puCanGrab] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powgrab.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puCanSpooger] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powspoog.png', smStretchHard);
+ If fPowerUpsTex[puCanSpooger] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powspoog.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puGoldFlame] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powgold.png', smStretchHard);
+ If fPowerUpsTex[puGoldFlame] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powgold.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puTrigger] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powtrig.png', smStretchHard);
+ If fPowerUpsTex[puTrigger] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powtrig.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puCanJelly] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powjelly.png', smStretchHard);
+ If fPowerUpsTex[puCanJelly] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powjelly.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puSuperBadDisease] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powebola.png', smStretchHard);
+ If fPowerUpsTex[puSuperBadDisease] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powebola.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[puSlow] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powslow.png', smStretchHard);
+ If fPowerUpsTex[puSlow] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powslow.png', llError);
+ logleave;
+ exit;
+ End;
+ fPowerUpsTex[purandom] := OpenGL_GraphikEngine.LoadGraphik(fDataPath + 'res' + PathDelim + 'powrand.png', smStretchHard);
+ If fPowerUpsTex[purandom] = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'powrand.png', llError);
+ logleave;
+ exit;
+ End;
// Load PlayerDead Tex correct.
- fPlayerdeadTex.Image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'playerdead.png', ugraphics.ColorToRGB(clfuchsia), smClamp);
- fPlayerdeadTex := OpenGL_GraphikEngine.FindItem(p + 'data' + PathDelim + 'res' + PathDelim + 'playerdead.png');
- If fPlayerdeadTex.Image = 0 Then exit;
- fhurry.Texture.Image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'hurry.png', ugraphics.ColorToRGB(clfuchsia), smClamp);
- If fhurry.Texture.Image = 0 Then exit;
- fhurry.Texture := OpenGL_GraphikEngine.FindItem(p + 'data' + PathDelim + 'res' + PathDelim + 'hurry.png');
- hohletex.image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(p + 'data' + PathDelim + 'res' + PathDelim + 'hole.png', ugraphics.ColorToRGB(clfuchsia), smStretchHard);
- If hohletex.Image = 0 Then exit;
- hohletex := OpenGL_GraphikEngine.FindItem(p + 'data' + PathDelim + 'res' + PathDelim + 'hole.png');
+ fPlayerdeadTex.Image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(fDataPath + 'res' + PathDelim + 'playerdead.png', ugraphics.ColorToRGB(clfuchsia), smClamp);
+ fPlayerdeadTex := OpenGL_GraphikEngine.FindItem(fDataPath + 'res' + PathDelim + 'playerdead.png');
+ If fPlayerdeadTex.Image = 0 Then Begin
+ log('Failed to locate texture handle for playerdead.png', llError);
+ logleave;
+ exit;
+ End;
+ fhurry.Texture.Image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(fDataPath + 'res' + PathDelim + 'hurry.png', ugraphics.ColorToRGB(clfuchsia), smClamp);
+ If fhurry.Texture.Image = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'hurry.png', llError);
+ logleave;
+ exit;
+ End;
+ fhurry.Texture := OpenGL_GraphikEngine.FindItem(fDataPath + 'res' + PathDelim + 'hurry.png');
+ hohletex.image := OpenGL_GraphikEngine.LoadAlphaColorGraphik(fDataPath + 'res' + PathDelim + 'hole.png', ugraphics.ColorToRGB(clfuchsia), smStretchHard);
+ If hohletex.Image = 0 Then Begin
+ log('Failed to load texture ' + fDataPath + 'res' + PathDelim + 'hole.png', llError);
+ logleave;
+ exit;
+ End;
+ hohletex := OpenGL_GraphikEngine.FindItem(fDataPath + 'res' + PathDelim + 'hole.png');
{$IFDEF ShowInitTime}
TimePoint(3);
{$ENDIF}
// Laden der Felder
fArrows := TOpenGL_Animation.Create;
- If Not fArrows.LoadFromFile(p + 'data' + PathDelim + 'res' + PathDelim + 'arrows.ani', true) Then Begin
+ If Not fArrows.LoadFromFile(fDataPath + 'res' + PathDelim + 'arrows.ani', true) Then Begin
+ log('Failed to load animation ' + fDataPath + 'res' + PathDelim + 'arrows.ani', llError);
+ logleave;
Exit;
End;
fConveyors := TOpenGL_Animation.Create;
- If Not fConveyors.LoadFromFile(p + 'data' + PathDelim + 'res' + PathDelim + 'conveyor.ani', true) Then Begin
+ If Not fConveyors.LoadFromFile(fDataPath + 'res' + PathDelim + 'conveyor.ani', true) Then Begin
+ log('Failed to load animation ' + fDataPath + 'res' + PathDelim + 'conveyor.ani', llError);
+ logleave;
Exit;
End;
fTramp := TOpenGL_Animation.Create;
- If Not fTramp.LoadFromFile(p + 'data' + PathDelim + 'res' + PathDelim + 'tramp.ani', true) Then Begin
+ If Not fTramp.LoadFromFile(fDataPath + 'res' + PathDelim + 'tramp.ani', true) Then Begin
+ log('Failed to load animation ' + fDataPath + 'res' + PathDelim + 'tramp.ani', llError);
+ logleave;
Exit;
End;
{$IFDEF ShowInitTime}
@@ -2135,7 +3619,8 @@
{$IFDEF ShowInitTime}
TimePoint(5);
{$ENDIF}
- sl := FindAllDirectories(p + 'data' + PathDelim + 'maps', false);
+ log('Scanning map directories in ' + fDataPath + 'maps', llInfo);
+ sl := FindAllDirectories(fDataPath + 'maps', false);
sl.Sorted := true;
sl.Sort;
{$IFDEF Only1Map}
@@ -2145,17 +3630,18 @@
{$ENDIF}
setlength(fFields, sl.Count);
If sl.count = 0 Then Begin
- LogShow('Error, no fields to load found', llFatal);
+ LogShow('Error, no fields to load found in ' + fDataPath + 'maps', llFatal);
LogLeave;
exit;
End;
+ log('Found ' + inttostr(sl.Count) + ' map directories', llInfo);
{$IFDEF ShowInitTime}
TimePoint(6);
{$ENDIF}
For j := 0 To sl.count - 1 Do Begin
fFields[j] := TAtomicField.Create();
If Not fFields[j].loadFromDirectory(sl[j], fArrows, fConveyors, fTramp, hohletex.Image, fTrampStatic) Then Begin
- LogShow('Error, unable to load field:' + sl[j], llFatal);
+ LogShow('Error, unable to load field: ' + sl[j], llFatal);
LogLeave;
exit;
End;
@@ -2180,8 +3666,8 @@
Loader.Percent := 50 + round(50 * j / length(fAtomics));
Loader.Render();
fAtomics[j] := TAtomic.Create;
- If Not fAtomics[j].InitAsColor(p + 'data' + PathDelim + 'atomic' + PathDelim, PlayerColors[j]) Then Begin
- LogShow('Error, unable to load atomic.', llFatal);
+ If Not fAtomics[j].InitAsColor(fDataPath + 'atomic' + PathDelim, PlayerColors[j]) Then Begin
+ LogShow('Error, unable to load atomic from ' + fDataPath + 'atomic' + PathDelim, llFatal);
LogLeave;
exit;
End;
@@ -2192,6 +3678,7 @@
Loader.Percent := 100;
Loader.Render(); // Als letztes kriegt der User zu sehen, dass wir fertig sind :-)
Loader.free;
+ fLoaderDialog := Nil; // Clear reference after initialization
fInitialized := true;
SwitchToScreen(sMainScreen);
{$IFDEF ShowInitTime}
@@ -2242,11 +3729,157 @@
logleave;
End;
+// Client-side interpolation implementation
+Procedure TGame.InterpolateGameState();
+Var
+ CurrentTime, RenderTime: QWord;
+ OldSnapIndex, NewSnapIndex: Integer;
+ T, Extrapolation: Single;
+ i: Integer;
+ TimeDiff, SnapAge: Int64;
+ VelX, VelY: Single;
+ PlayerSpeed: Single;
+
+ // Linear interpolation
+ Function Lerp(A, B, T: Single): Single;
+ Begin
+ Result := A + (B - A) * T;
+ End;
+
+ // Interpolate 2D vector
+ Function LerpVector2(Const A, B: TVector2; T: Single): TVector2;
+ Begin
+ Result.x := Lerp(A.x, B.x, T);
+ Result.y := Lerp(A.y, B.y, T);
+ End;
+
+Begin
+ CurrentTime := GetTickCount64;
+
+ // Get the snapshot indices
+ OldSnapIndex := 1 - fCurrentSnapshot; // Older
+ NewSnapIndex := fCurrentSnapshot; // Newer
+
+ // If we don't have 2 valid snapshots yet, use the latest one
+ If (Not fServerSnapshots[OldSnapIndex].Valid) Or (Not fServerSnapshots[NewSnapIndex].Valid) Then Begin
+ If fServerSnapshots[NewSnapIndex].Valid Then Begin
+ fInterpolatedState.PlayingTime_ms := fServerSnapshots[NewSnapIndex].ServerTime_ms;
+ fInterpolatedState.PlayerInfos := fServerSnapshots[NewSnapIndex].PlayerInfos;
+ fDebugStats.InterpolationFactor := 1.0;
+ fDebugStats.IsExtrapolating := False;
+ fDebugStats.SnapshotAge := CurrentTime - fServerSnapshots[NewSnapIndex].Timestamp;
+ End;
+ Exit;
+ End;
+
+ // Calculate snapshot age
+ SnapAge := CurrentTime - fServerSnapshots[NewSnapIndex].Timestamp;
+ fDebugStats.SnapshotAge := SnapAge;
+ // Track MAX snapshot age
+ If SnapAge > fDebugStats.MaxSnapAge Then
+ fDebugStats.MaxSnapAge := SnapAge;
+
+ // Calculate time since last snapshot (for interpolation/extrapolation)
+ TimeDiff := fServerSnapshots[NewSnapIndex].Timestamp - fServerSnapshots[OldSnapIndex].Timestamp;
+
+ // If snapshots are too far apart (> 150ms), don't interpolate - just use newest
+ If TimeDiff > 150 Then Begin
+ fInterpolatedState.PlayingTime_ms := fServerSnapshots[NewSnapIndex].ServerTime_ms;
+ fInterpolatedState.PlayerInfos := fServerSnapshots[NewSnapIndex].PlayerInfos;
+ fDebugStats.InterpolationFactor := 1.0;
+ fDebugStats.IsExtrapolating := False;
+ Exit;
+ End;
+
+ // Calculate interpolation factor based on time between snapshots
+ // We want to render at the "latest safe time" which is the newest snapshot + elapsed time
+ If TimeDiff > 0 Then Begin
+ T := (CurrentTime - fServerSnapshots[OldSnapIndex].Timestamp) / TimeDiff;
+ End Else Begin
+ T := 1.0; // Use newest if timestamps are same
+ End;
+
+ // === INTERPOLATION (T between 0 and 1) ===
+ If (T >= 0.0) And (T <= 1.0) Then Begin
+ fDebugStats.InterpolationFactor := T;
+ fDebugStats.IsExtrapolating := False;
+ // Track MAX interpolation factor
+ If T > fDebugStats.MaxInterpFactor Then
+ fDebugStats.MaxInterpFactor := T;
+
+ // Interpolate playing time
+ fInterpolatedState.PlayingTime_ms := Round(
+ Lerp(fServerSnapshots[OldSnapIndex].ServerTime_ms, fServerSnapshots[NewSnapIndex].ServerTime_ms, T)
+ );
+
+ // Interpolate player positions
+ For i := 0 To 9 Do Begin
+ fInterpolatedState.PlayerInfos[i].Position := LerpVector2(
+ fServerSnapshots[OldSnapIndex].PlayerInfos[i].Position,
+ fServerSnapshots[NewSnapIndex].PlayerInfos[i].Position,
+ T
+ );
+
+ // Don't interpolate these - use newest values
+ fInterpolatedState.PlayerInfos[i].Direction := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Direction;
+ fInterpolatedState.PlayerInfos[i].Animation := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Animation;
+ fInterpolatedState.PlayerInfos[i].Alive := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Alive;
+ fInterpolatedState.PlayerInfos[i].Dying := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Dying;
+ fInterpolatedState.PlayerInfos[i].Counter := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Counter;
+ fInterpolatedState.PlayerInfos[i].Value := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Value;
+ fInterpolatedState.PlayerInfos[i].ColorIndex := fServerSnapshots[NewSnapIndex].PlayerInfos[i].ColorIndex;
+ End;
+ End
+ // === EXTRAPOLATION (T > 1.0 - we're ahead of last snapshot) ===
+ Else If T > 1.0 Then Begin
+ // Calculate how much time has elapsed since last snapshot
+ Extrapolation := (CurrentTime - fServerSnapshots[NewSnapIndex].Timestamp) / 1000.0; // in seconds
+
+ // Limit extrapolation aggressively to prevent jitter
+ If Extrapolation > (fExtrapolationLimit / 1000.0) Then Begin
+ Extrapolation := fExtrapolationLimit / 1000.0;
+ End;
+
+ fDebugStats.InterpolationFactor := T;
+ fDebugStats.IsExtrapolating := True;
+ // Track MAX interpolation factor (extrapolation)
+ If T > fDebugStats.MaxInterpFactor Then
+ fDebugStats.MaxInterpFactor := T;
+
+ // Extrapolate playing time smoothly
+ fInterpolatedState.PlayingTime_ms := fServerSnapshots[NewSnapIndex].ServerTime_ms + Round(Extrapolation * 1000);
+
+ // For positions: DON'T extrapolate - just use latest snapshot to avoid jitter!
+ // Extrapolation causes "jittery" movement when predictions are wrong
+ For i := 0 To 9 Do Begin
+ // Just use the latest snapshot position (no prediction)
+ fInterpolatedState.PlayerInfos[i].Position := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Position;
+
+ // Copy other fields
+ fInterpolatedState.PlayerInfos[i].Direction := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Direction;
+ fInterpolatedState.PlayerInfos[i].Animation := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Animation;
+ fInterpolatedState.PlayerInfos[i].Alive := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Alive;
+ fInterpolatedState.PlayerInfos[i].Dying := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Dying;
+ fInterpolatedState.PlayerInfos[i].Counter := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Counter;
+ fInterpolatedState.PlayerInfos[i].Value := fServerSnapshots[NewSnapIndex].PlayerInfos[i].Value;
+ fInterpolatedState.PlayerInfos[i].ColorIndex := fServerSnapshots[NewSnapIndex].PlayerInfos[i].ColorIndex;
+ End;
+ End
+ // === FALLBACK (T < 0 - should not happen, but handle it) ===
+ Else Begin
+ fDebugStats.InterpolationFactor := 0.0;
+ fDebugStats.IsExtrapolating := False;
+ fInterpolatedState.PlayingTime_ms := fServerSnapshots[OldSnapIndex].ServerTime_ms;
+ fInterpolatedState.PlayerInfos := fServerSnapshots[OldSnapIndex].PlayerInfos;
+ End;
+End;
+
Procedure TGame.Render;
Var
i: Integer;
n: QWORD;
Begin
+ // Viewport is set in OpenGLControl1Resize, don't override it here
Go2d(GameWidth, GameHeight);
If Not fInitialized Then Begin
glBindTexture(GL_TEXTURE_2D, 0);
@@ -2264,12 +3897,16 @@
If assigned(fActualScreen) Then fActualScreen.Render;
End;
gs_Gaming: Begin
+ // === NEW: Interpolate game state before rendering ===
+ InterpolateGameState();
+
CheckSDLKeys;
fActualField.render(fAtomics, fPowerUpsTex);
RenderBombs;
For i := 0 To high(fPlayer) Do Begin
- If fPlayer[i].Info.Alive Then Begin
- RenderPlayerbyInfo(fPlayer[i].Info, fPlayer[i].edge);
+ // Use interpolated positions instead of raw server data
+ If fInterpolatedState.PlayerInfos[i].Alive Then Begin
+ RenderPlayerbyInfo(fInterpolatedState.PlayerInfos[i], fPlayer[i].edge);
fPlayer[i].edge := false;
End;
End;
@@ -2305,6 +3942,65 @@
Exit2d();
End;
+Function TGame.PointInsideViewport(ScreenX, ScreenY: Integer): Boolean;
+Begin
+ If (FViewportWidth <= 0) Or (FViewportHeight <= 0) Then
+ exit(true);
+ Result :=
+ (ScreenX >= FViewportOffsetX) And
+ (ScreenX <= FViewportOffsetX + FViewportWidth) And
+ (ScreenY >= FViewportOffsetY) And
+ (ScreenY <= FViewportOffsetY + FViewportHeight);
+End;
+
+Function TGame.ScreenToGameX(ScreenX: Integer): Integer;
+Var
+ Local: Double;
+Begin
+ If (FViewportWidth <= 0) Or (FViewportScale <= 0) Then
+ exit(ScreenX);
+ Local := (ScreenX - FViewportOffsetX) / FViewportScale;
+ If Local < 0 Then
+ Local := 0
+ Else If Local > GameWidth Then
+ Local := GameWidth;
+ Result := round(Local);
+End;
+
+Function TGame.ScreenToGameY(ScreenY: Integer): Integer;
+Var
+ Local: Double;
+Begin
+ If (FViewportHeight <= 0) Or (FViewportScale <= 0) Then
+ exit(ScreenY);
+ Local := (ScreenY - FViewportOffsetY) / FViewportScale;
+ If Local < 0 Then
+ Local := 0
+ Else If Local > GameHeight Then
+ Local := GameHeight;
+ Result := round(Local);
+End;
+
+Procedure TGame.SetViewportMetrics(ControlWidth, ControlHeight, OffsetX,
+ OffsetY, ViewportWidth, ViewportHeight: Integer);
+Begin
+ FControlWidth := ControlWidth;
+ FControlHeight := ControlHeight;
+ FViewportOffsetX := OffsetX;
+ FViewportOffsetY := OffsetY;
+ FViewportWidth := ViewportWidth;
+ FViewportHeight := ViewportHeight;
+ If (ViewportWidth > 0) Then
+ FViewportScale := ViewportWidth / GameWidth
+ Else
+ FViewportScale := 1;
+ If FViewportScale <= 0 Then
+ FViewportScale := 1;
+ log(Format('Viewport metrics: control=%dx%d viewport=%dx%d scale=%.4f offset=(%d,%d)',
+ [FControlWidth, FControlHeight, FViewportWidth, FViewportHeight, FViewportScale,
+ FViewportOffsetX, FViewportOffsetY]), llInfo);
+End;
+
Procedure TGame.OnIdle;
Begin
PingForOpenGames;
@@ -2315,6 +4011,101 @@
If fNeedDisconnect Then Begin
DoDisconnect();
End;
+
+ // Periodically retry connection if we're waiting for local server to start
+ // On localhost, "connection refused" comes back immediately, so we need to retry periodically
+ If fWaitingForLocalServer And (fParamJoinIP <> '') Then Begin
+ If (fLastConnectionAttempt = 0) Or (GetTickCount64 - fLastConnectionAttempt >= fConnectionRetryInterval) Then Begin
+ fLastConnectionAttempt := GetTickCount64;
+ log(format('Retrying connection to %s:%d...', [fParamJoinIP, fParamJoinPort]), llInfo);
+ // Initiate new async connection attempt
+ If Not fChunkManager.Connect(fParamJoinIP, fParamJoinPort) Then Begin
+ log('Could not initiate connection, will retry later', llInfo);
+ End;
+ // If Connect returned True, we wait for Connection_Connect or Connection_Error callback
+ End;
+ End;
+
+ // Always pump SDL events first to update button states
+ // Check all possible keysets that might use SDL
+ If fsdl_Loaded And (Settings.Keys[ks0].UseSDL2 Or Settings.Keys[ks1].UseSDL2 Or
+ Settings.Keys[ksJoy1].UseSDL2 Or Settings.Keys[ksJoy2].UseSDL2) Then Begin
+ SDL_PumpEvents();
+ End;
+
+ // Check if we need to unblock game input (waiting for all buttons to be released)
+ If fBlockGameInputUntilRelease Then Begin
+ If AreAllGamepadButtonsReleased() Then Begin
+ fBlockGameInputUntilRelease := false;
+ End;
+ End;
+
+ // Check if we need to unblock menu input (waiting for all buttons to be released)
+ If fBlockMenuInputUntilRelease Then Begin
+ If AreAllGamepadButtonsReleased() Then Begin
+ fBlockMenuInputUntilRelease := false;
+ End;
+ End;
+
+ // Poll controllers/joysticks each idle tick for input (both menu and game)
+ CheckSDLKeys();
+ // Also poll for menu navigation via gamepad
+ CheckSDLKeysForMenu();
+End;
+
+Function TGame.ResolveResourceBase(BasePath: String): String;
+Var
+ testPath: String;
+ appBundlePath: String;
+Begin
+ // Normalize base path to absolute path
+ BasePath := ExpandFileName(IncludeTrailingPathDelimiter(BasePath));
+ log('ResolveResourceBase: BasePath=' + BasePath, llInfo);
+
+ // Try multiple locations for data directory
+ // 1. Direct relative to executable (works with symlinks)
+ testPath := BasePath + 'data';
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ log('ResolveResourceBase: Found data at ' + Result, llInfo);
+ exit;
+ End;
+ // 2. Relative path from MacOS directory in .app bundle
+ testPath := ExpandFileName(BasePath + '../Resources/data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ log('ResolveResourceBase: Found data at ' + Result, llInfo);
+ exit;
+ End;
+ // 3. Try symlink path (../../data from MacOS) - for shared data directory
+ testPath := ExpandFileName(BasePath + '../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ log('ResolveResourceBase: Found data at ' + Result, llInfo);
+ exit;
+ End;
+ // 4. Try symlink path (../../../data from MacOS) - alternative symlink location
+ testPath := ExpandFileName(BasePath + '../../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ log('ResolveResourceBase: Found data at ' + Result, llInfo);
+ exit;
+ End;
+ // 5. Try path next to .app bundle (for cases where data is outside the bundle)
+ // If BasePath contains ".app/Contents/MacOS/", try going up to the .app bundle's parent directory
+ If Pos('.app/Contents/MacOS/', BasePath) > 0 Then Begin
+ appBundlePath := Copy(BasePath, 1, Pos('.app/Contents/MacOS/', BasePath) + 4); // Get path up to ".app"
+ appBundlePath := ExtractFilePath(ExcludeTrailingPathDelimiter(appBundlePath)); // Get parent directory of .app
+ testPath := ExpandFileName(appBundlePath + 'data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ log('ResolveResourceBase: Found data at ' + Result, llInfo);
+ exit;
+ End;
+ End;
+ // Fallback: use base path (may not exist, but at least we tried)
+ Result := BasePath + 'data' + PathDelim;
+ log('Warning: Could not resolve data directory, using fallback: ' + Result, llWarning);
End;
End.
diff --git a/client/uloaderdialog.pas b/client/uloaderdialog.pas
index c4a98c7..9dccd32 100644
--- a/client/uloaderdialog.pas
+++ b/client/uloaderdialog.pas
@@ -1,209 +1,334 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uloaderdialog;
-
-{$MODE ObjFPC}{$H+}
-
-Interface
-
-Uses
- Classes, SysUtils, OpenGLContext;
-
-Type
-
- { TLoaderDialog }
-
- TLoaderDialog = Class
- private
- fWidth: integer;
- fHeight: integer;
- fOwner: TOpenGLControl;
- fTextures: Array[0..8] Of Integer; // Die 9 Einzeltextruren des Hintergrunds
- public
- Percent: integer;
- Constructor Create(Const Owner: TOpenGLControl);
- Destructor Destroy(); override;
- (*
- * !Achtung!
- * das ist Asynchron und macht ein Vollständiges Render !
- * -> Sollte also nur in Blockierenden Aufgaben aufgerufen werden !
- *)
- Procedure Render();
- End;
-
-Implementation
-
-Uses
- Graphics
- , dglOpenGL
- , Forms
- , LazUTF8
- , uatomic_common
- , uopengl_graphikengine
- , uOpenGL_ASCII_Font
- ;
-
-Procedure RenderImg(w, h, ImageIndex: integer); // TODO: das ggf noch mal irgendwohin auslagern ??
-Begin
- glBindTexture(gl_texture_2d, ImageIndex);
- glbegin(gl_quads);
- glTexCoord2f(0, 1);
- glvertex3f(0, h, 0);
-
- glTexCoord2f(1, 1);
- glvertex3f(w, h, 0);
-
- glTexCoord2f(1, 0);
- glvertex3f(w, 0, 0);
-
- glTexCoord2f(0, 0);
- glvertex3f(0, 0, 0);
- glend;
-End;
-
-{ TLoaderDialog }
-
-Constructor TLoaderDialog.Create(Const Owner: TOpenGLControl);
-Var
- p: String;
- png: TPortableNetworkGraphic;
- b, b2: TBitmap;
- i: Integer;
-Begin
- fWidth := 15 * 24;
- fHeight := 5 * 24;
- fOwner := Owner;
- Percent := 0;
- p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'data' + PathDelim + 'res' + PathDelim + 'loaddialog.png';
- png := TPortableNetworkGraphic.Create;
- png.LoadFromFile(p);
- b := TBitmap.create;
- b.Assign(png);
- b.Transparent := false;
- png.free;
- b2 := TBitmap.Create;
- b2.Height := 24;
- b2.Width := 24;
- b2.Transparent := false;
- For i := 0 To 8 Do Begin
- b2.Canvas.Draw(-(i Mod 3) * 24, -(i Div 3) * 24, b);
- fTextures[i] := OpenGL_GraphikEngine.LoadGraphik(b2, 'TLoaderDialog_img' + inttostr(i), smStretch);
- End;
- b2.free;
- b.free;
-End;
-
-Destructor TLoaderDialog.Destroy;
-Var
- i: Integer;
-Begin
- For i := 0 To 8 Do Begin
- OpenGL_GraphikEngine.RemoveGraphik(fTextures[i]);
- End;
- Inherited Create;
-End;
-
-Procedure TLoaderDialog.Render;
-Var
- x, i, j: Integer;
- s: String;
-Begin
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- glcolor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, 0);
- Go2d(GameWidth, GameHeight);
- glPushMatrix;
- glTranslatef((GameWidth - fWidth) Div 2, (GameHeight - fHeight) Div 2, atomic_dialog_Layer);
- glPushMatrix;
- // Die "Dialogbox"
- // 1. Zeile
- RenderImg(24, 24, fTextures[0]); // Ecke Oben Links
- glPushMatrix;
- For i := 1 To (fWidth Div 24) - 2 Do Begin
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[1]); // Obere Mittlere Kante
- End;
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[2]); // Ecke Oben Rechts
- glPopMatrix;
- // Zeile 2 bis N -1
- For j := 1 To (fHeight Div 24) - 2 Do Begin
- glTranslatef(0, 24, 0);
- glPushMatrix;
- RenderImg(24, 24, fTextures[3]); // Linke Kante
- For i := 1 To (fWidth Div 24) - 2 Do Begin
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[4]); // Die Mittelstücke
- End;
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[5]); // Rechte Kante
- glPopMatrix;
- End;
- // Letzte Zeile
- glTranslatef(0, 24, 0);
- RenderImg(24, 24, fTextures[6]); // Ecke unten Links
- For i := 1 To (fWidth Div 24) - 2 Do Begin
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[7]); // untere Mittlere Kante
- End;
- glTranslatef(24, 0, 0);
- RenderImg(24, 24, fTextures[8]); // Ecke Unten Rechts
- glPopMatrix;
- // Rendern der Elemente auf dem Dialog
- glTranslatef(0, 0, atomic_EPSILON);
- glBindTexture(GL_TEXTURE_2D, 0);
- // Der Schriftzug "Loading data..."
- s := 'Loading data...';
- OpenGL_ASCII_Font.Color := clWhite;
- OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, 24, s);
- // Die Prozentzahl
- s := inttostr(Percent) + '%';
- OpenGL_ASCII_Font.Color := clYellow;
- OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, (fHeight - round(OpenGL_ASCII_Font.TextHeight(s))) Div 2, s);
- // Der Fortschrittsbalken
- glTranslatef(0, 0, -atomic_EPSILON); // Der Weise Rahmen, mittels LineLoop sieht das scheiße aus, also muss der so in den Hintergrund der anderen beiden.
- glBegin(GL_QUADS);
- glColor3f(1, 1, 1);
- glVertex3f(24, 82, 0);
- glVertex3f(24, 82 + 14, 0);
- glVertex3f(fWidth - 24, 82 + 14, 0);
- glVertex3f(fWidth - 24, 82, 0);
- glend;
- glTranslatef(0, 0, atomic_EPSILON);
- x := round((fWidth - 48 - 2) * Percent / 100);
- glBegin(GL_QUADS);
- glColor3f(168 / 255, 168 / 255, 168 / 255);
- glVertex3f(24 + 1, 82 + 1, 0);
- glVertex3f(24 + 1, 82 + 14 - 1, 0);
- glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
- glVertex3f(24 + 1 + x, 82 + 1, 0);
- glend;
- glBegin(GL_QUADS);
- glColor3f(0, 0, 0);
- glVertex3f(24 + 1 + x, 82 + 1, 0);
- glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
- glVertex3f(fWidth - 24 - 1, 82 + 14 - 1, 0);
- glVertex3f(fWidth - 24 - 1, 82 + 1, 0);
- glend;
- glPopMatrix;
- Exit2d();
- fOwner.SwapBuffers;
- Application.ProcessMessages;
-End;
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uloaderdialog;
+
+{$MODE ObjFPC}{$H+}
+
+Interface
+
+Uses
+ Classes, SysUtils, OpenGLContext;
+
+Type
+
+ { TLoaderDialog }
+
+ TLoaderDialog = Class
+ private
+ fWidth: integer;
+ fHeight: integer;
+ fOwner: TOpenGLControl;
+ fTextures: Array[0..8] Of Integer; // Die 9 Einzeltextruren des Hintergrunds
+ public
+ Percent: integer;
+ Constructor Create(Const Owner: TOpenGLControl; Const DataPath: String = '');
+ Destructor Destroy(); override;
+ (*
+ * !Achtung!
+ * das ist Asynchron und macht ein Vollständiges Render !
+ * -> Sollte also nur in Blockierenden Aufgaben aufgerufen werden !
+ *)
+ Procedure Render();
+ Procedure RenderDirect(); // Render without SwapBuffers and ProcessMessages - for use in OnPaint
+ End;
+
+Implementation
+
+Uses
+ Graphics
+ , dglOpenGL
+ , Forms
+ , LazUTF8
+ , LazFileUtils
+ , uatomic_common
+ , uopengl_graphikengine
+ , uOpenGL_ASCII_Font
+ ;
+
+Procedure RenderImg(w, h, ImageIndex: integer); // TODO: das ggf noch mal irgendwohin auslagern ??
+Begin
+ If ImageIndex = 0 Then Begin
+ exit;
+ End;
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(gl_texture_2d, ImageIndex);
+ glbegin(gl_quads);
+ glTexCoord2f(0, 1);
+ glvertex3f(0, h, 0);
+
+ glTexCoord2f(1, 1);
+ glvertex3f(w, h, 0);
+
+ glTexCoord2f(1, 0);
+ glvertex3f(w, 0, 0);
+
+ glTexCoord2f(0, 0);
+ glvertex3f(0, 0, 0);
+ glend;
+End;
+
+{ TLoaderDialog }
+
+Constructor TLoaderDialog.Create(Const Owner: TOpenGLControl; Const DataPath: String = '');
+Var
+ p: String;
+ png: TPortableNetworkGraphic;
+ b, b2: TBitmap;
+ i: Integer;
+Begin
+ fWidth := 15 * 24;
+ fHeight := 5 * 24;
+ fOwner := Owner;
+ Percent := 0;
+ // CRITICAL: Ensure OpenGL context is active before loading textures
+ // This is required because LoadGraphik uses glGenTextures and glTexImage2D
+ If Not Owner.MakeCurrent Then Begin
+ Raise Exception.Create('TLoaderDialog.Create: OpenGL context is not active');
+ End;
+ // Use provided DataPath if available, otherwise fall back to old method
+ If DataPath <> '' Then Begin
+ p := IncludeTrailingPathDelimiter(DataPath) + 'res' + PathDelim + 'loaddialog.png';
+ End Else Begin
+ p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStrUTF8(0))) + 'data' + PathDelim + 'res' + PathDelim + 'loaddialog.png';
+ End;
+ png := TPortableNetworkGraphic.Create;
+ If Not FileExistsUTF8(p) Then Begin
+ png.Free;
+ Raise Exception.Create('The data directory is incomplete.' + LineEnding + LineEnding +
+ 'Please run FPC Atomic Launcher and use the "Run CD data extractor" button to extract the required game data.' + LineEnding + LineEnding +
+ 'Missing file: ' + ExtractFileName(p));
+ End;
+ png.LoadFromFile(p);
+ b := TBitmap.create;
+ b.Assign(png);
+ b.Transparent := false;
+ png.free;
+ b2 := TBitmap.Create;
+ b2.Height := 24;
+ b2.Width := 24;
+ b2.Transparent := false;
+ For i := 0 To 8 Do Begin
+ b2.Canvas.Draw(-(i Mod 3) * 24, -(i Div 3) * 24, b);
+ fTextures[i] := OpenGL_GraphikEngine.LoadGraphik(b2, 'TLoaderDialog_img' + inttostr(i), smStretch);
+ End;
+ b2.free;
+ b.free;
+End;
+
+Destructor TLoaderDialog.Destroy;
+Var
+ i: Integer;
+Begin
+ For i := 0 To 8 Do Begin
+ OpenGL_GraphikEngine.RemoveGraphik(fTextures[i]);
+ End;
+ Inherited Create;
+End;
+
+Procedure TLoaderDialog.Render;
+Var
+ x, i, j: Integer;
+ s: String;
+Begin
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ glcolor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ Go2d(GameWidth, GameHeight);
+ glPushMatrix;
+ glTranslatef((GameWidth - fWidth) Div 2, (GameHeight - fHeight) Div 2, atomic_dialog_Layer);
+ glPushMatrix;
+ // Die "Dialogbox"
+ // 1. Zeile
+ RenderImg(24, 24, fTextures[0]); // Ecke Oben Links
+ glPushMatrix;
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[1]); // Obere Mittlere Kante
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[2]); // Ecke Oben Rechts
+ glPopMatrix;
+ // Zeile 2 bis N -1
+ For j := 1 To (fHeight Div 24) - 2 Do Begin
+ glTranslatef(0, 24, 0);
+ glPushMatrix;
+ RenderImg(24, 24, fTextures[3]); // Linke Kante
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[4]); // Die Mittelstücke
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[5]); // Rechte Kante
+ glPopMatrix;
+ End;
+ // Letzte Zeile
+ glTranslatef(0, 24, 0);
+ RenderImg(24, 24, fTextures[6]); // Ecke unten Links
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[7]); // untere Mittlere Kante
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[8]); // Ecke Unten Rechts
+ glPopMatrix;
+ // Rendern der Elemente auf dem Dialog
+ glTranslatef(0, 0, atomic_EPSILON);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Der Schriftzug "Loading data..."
+ s := 'Loading data...';
+ OpenGL_ASCII_Font.Color := clWhite;
+ OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, 24, s);
+ // Die Prozentzahl
+ s := inttostr(Percent) + '%';
+ OpenGL_ASCII_Font.Color := clYellow;
+ OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, (fHeight - round(OpenGL_ASCII_Font.TextHeight(s))) Div 2, s);
+ // Der Fortschrittsbalken
+ glTranslatef(0, 0, -atomic_EPSILON); // Der Weise Rahmen, mittels LineLoop sieht das scheiße aus, also muss der so in den Hintergrund der anderen beiden.
+ glBegin(GL_QUADS);
+ glColor3f(1, 1, 1);
+ glVertex3f(24, 82, 0);
+ glVertex3f(24, 82 + 14, 0);
+ glVertex3f(fWidth - 24, 82 + 14, 0);
+ glVertex3f(fWidth - 24, 82, 0);
+ glend;
+ glTranslatef(0, 0, atomic_EPSILON);
+ x := round((fWidth - 48 - 2) * Percent / 100);
+ glBegin(GL_QUADS);
+ glColor3f(168 / 255, 168 / 255, 168 / 255);
+ glVertex3f(24 + 1, 82 + 1, 0);
+ glVertex3f(24 + 1, 82 + 14 - 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 1, 0);
+ glend;
+ glBegin(GL_QUADS);
+ glColor3f(0, 0, 0);
+ glVertex3f(24 + 1 + x, 82 + 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
+ glVertex3f(fWidth - 24 - 1, 82 + 14 - 1, 0);
+ glVertex3f(fWidth - 24 - 1, 82 + 1, 0);
+ glend;
+ glPopMatrix;
+ Exit2d();
+ fOwner.SwapBuffers;
+ Application.ProcessMessages;
+End;
+
+Procedure TLoaderDialog.RenderDirect();
+Var
+ x, i, j: Integer;
+ s: String;
+Begin
+ // Same as Render(), but without SwapBuffers and ProcessMessages
+ // This is for use in OnPaint, which already handles these
+
+ // CRITICAL: Ensure OpenGL context is active
+ If Not fOwner.MakeCurrent Then Begin
+ exit;
+ End;
+
+ // Enable texturing
+ glEnable(GL_TEXTURE_2D);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ glcolor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ Go2d(GameWidth, GameHeight);
+ glPushMatrix;
+ glTranslatef((GameWidth - fWidth) Div 2, (GameHeight - fHeight) Div 2, atomic_dialog_Layer);
+ glPushMatrix;
+ // Die "Dialogbox"
+ // 1. Zeile
+ RenderImg(24, 24, fTextures[0]); // Ecke Oben Links
+ glPushMatrix;
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[1]); // Obere Mittlere Kante
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[2]); // Ecke Oben Rechts
+ glPopMatrix;
+ // Zeile 2 bis N -1
+ For j := 1 To (fHeight Div 24) - 2 Do Begin
+ glTranslatef(0, 24, 0);
+ glPushMatrix;
+ RenderImg(24, 24, fTextures[3]); // Linke Kante
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[4]); // Die Mittelstücke
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[5]); // Rechte Kante
+ glPopMatrix;
+ End;
+ // Letzte Zeile
+ glTranslatef(0, 24, 0);
+ RenderImg(24, 24, fTextures[6]); // Ecke unten Links
+ For i := 1 To (fWidth Div 24) - 2 Do Begin
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[7]); // untere Mittlere Kante
+ End;
+ glTranslatef(24, 0, 0);
+ RenderImg(24, 24, fTextures[8]); // Ecke Unten Rechts
+ glPopMatrix;
+ // Rendern der Elemente auf dem Dialog
+ glTranslatef(0, 0, atomic_EPSILON);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Der Schriftzug "Loading data..."
+ s := 'Loading data...';
+ OpenGL_ASCII_Font.Color := clWhite;
+ OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, 24, s);
+ // Die Prozentzahl
+ s := inttostr(Percent) + '%';
+ OpenGL_ASCII_Font.Color := clYellow;
+ OpenGL_ASCII_Font.Textout((fWidth - round(OpenGL_ASCII_Font.TextWidth(s))) Div 2, (fHeight - round(OpenGL_ASCII_Font.TextHeight(s))) Div 2, s);
+ // Der Fortschrittsbalken
+ glTranslatef(0, 0, -atomic_EPSILON); // Der Weise Rahmen, mittels LineLoop sieht das scheiße aus, also muss der so in den Hintergrund der anderen beiden.
+ glBegin(GL_QUADS);
+ glColor3f(1, 1, 1);
+ glVertex3f(24, 82, 0);
+ glVertex3f(24, 82 + 14, 0);
+ glVertex3f(fWidth - 24, 82 + 14, 0);
+ glVertex3f(fWidth - 24, 82, 0);
+ glend;
+ glTranslatef(0, 0, atomic_EPSILON);
+ x := round((fWidth - 48 - 2) * Percent / 100);
+ glBegin(GL_QUADS);
+ glColor3f(168 / 255, 168 / 255, 168 / 255);
+ glVertex3f(24 + 1, 82 + 1, 0);
+ glVertex3f(24 + 1, 82 + 14 - 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 1, 0);
+ glend;
+ glBegin(GL_QUADS);
+ glColor3f(0, 0, 0);
+ glVertex3f(24 + 1 + x, 82 + 1, 0);
+ glVertex3f(24 + 1 + x, 82 + 14 - 1, 0);
+ glVertex3f(fWidth - 24 - 1, 82 + 14 - 1, 0);
+ glVertex3f(fWidth - 24 - 1, 82 + 1, 0);
+ glend;
+ glPopMatrix;
+ Exit2d();
+End;
+
+End.
+
diff --git a/client/unit1.lfm b/client/unit1.lfm
index df8df2a..86b80e3 100644
--- a/client/unit1.lfm
+++ b/client/unit1.lfm
@@ -7,7 +7,7 @@ object Form1: TForm1
Caption = 'Form1'
ClientHeight = 479
ClientWidth = 692
- FormStyle = fsStayOnTop
+ KeyPreview = True
Position = poScreenCenter
LCLVersion = '4.99.0.0'
OnCloseQuery = FormCloseQuery
diff --git a/client/unit1.pas b/client/unit1.pas
index bccef4a..a119b80 100644
--- a/client/unit1.pas
+++ b/client/unit1.pas
@@ -34,6 +34,11 @@
* Sicht auf Optionen Dialog: https://www.youtube.com/watch?v=fO9HhzhEloE
* Network Spiel aus Server Sicht: https://www.youtube.com/watch?v=cuZ2GOkse5k
*)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit Unit1;
{$MODE objfpc}{$H+}
@@ -44,7 +49,7 @@
Uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
- ExtCtrls, IniPropStorage,
+ Math, ExtCtrls, IniPropStorage,
OpenGlcontext, lNetComponents, lNet,
(*
* Kommt ein Linkerfehler wegen OpenGL dann: sudo apt-get install freeglut3-dev
@@ -53,7 +58,8 @@
, uopengl_graphikengine // Die OpenGLGraphikengine ist eine Eigenproduktion von www.Corpsman.de, und kann getrennt geladen werden.
, uOpenGL_ASCII_Font
, ugame
- , uatomic_common;
+ , uatomic_common
+ , uscreens; // For TScreenEnum (sExitBomberman)
{$IFDEF AUTOMODE}
Const
@@ -107,7 +113,12 @@
Form1ShowOnce: Boolean;
FPS_Counter, LastFPS_Counter: integer;
LastFPSTime: int64;
+ fLastControlWidth, fLastControlHeight: Integer; // Track last control size to detect resize
+ fLevelStartTime: int64; // Time when current level started (for elapsed time tracking)
+ fLastPlayingTime_s: integer; // Last known playing time to detect level start
+ fGameInitialized: Boolean; // Flag to track if Game.Initialize has been called
FWishFullscreen: Boolean;
+ FAdjustingSize: Boolean;
{$IFDEF AUTOMODE}
AutomodeData: TAutomodeData;
{$ENDIF}
@@ -117,6 +128,7 @@
Function GetWorkDir(Out Directory: String): Boolean;
Procedure HideCursor(Sender: TObject);
Procedure ShowCursor(Sender: TObject);
+ Function InitializeBASS(): Boolean;
public
{ public declarations }
Procedure OnConnectToServer(Sender: TObject);
@@ -141,9 +153,8 @@
, bass
// , unit18 // Der Fortschrittsbalken während des Updates
, uatomicfont
-{$IFDEF AUTOMODE}
- , uscreens
-{$ENDIF}
+ // uscreens is now imported in main uses section (line 57) for TScreenEnum access
+ , uearlylog
;
Var
@@ -161,6 +172,8 @@
Procedure TForm1.OpenGLControl1MakeCurrent(Sender: TObject; Var Allow: boolean);
Begin
+ // Changed to llTrace to reduce log spam
+ // log('OpenGLControl1MakeCurrent allowcnt=' + inttostr(allowcnt), llTrace);
If allowcnt > 2 Then Begin
exit;
End;
@@ -171,10 +184,34 @@
ReadExtensions; // Anstatt der Extentions kann auch nur der Core geladen werden. ReadOpenGLCore;
ReadImplementationProperties;
End;
+{$IFDEF Windows}
+ // On Windows: allowcnt = 2 (exactly 2) and call Game.Initialize directly here
If allowcnt = 2 Then Begin // Dieses If Sorgt mit dem obigen dafür, dass der Code nur 1 mal ausgeführt wird.
+ log('Initializing OpenGL resources (allowcnt=' + inttostr(allowcnt) + ')', llInfo);
OpenGL_GraphikEngine.clear;
- Create_ASCII_Font;
- AtomicFont.CreateFont;
+ // EarlyLog('OpenGLControl1MakeCurrent: Creating ASCII font...');
+ Try
+ Create_ASCII_Font;
+ // If Assigned(OpenGL_ASCII_Font) Then
+ // EarlyLog('OpenGLControl1MakeCurrent: ASCII font created successfully')
+ // Else
+ // EarlyLog('OpenGLControl1MakeCurrent: WARNING - ASCII font is Nil after creation');
+ Except
+ On E: Exception Do Begin
+ // EarlyLog('OpenGLControl1MakeCurrent: ERROR creating ASCII font: ' + E.Message);
+ // log('ERROR creating ASCII font: ' + E.Message, llError);
+ End;
+ End;
+ // EarlyLog('OpenGLControl1MakeCurrent: Creating AtomicFont...');
+ Try
+ AtomicFont.CreateFont;
+ // EarlyLog('OpenGLControl1MakeCurrent: AtomicFont.CreateFont completed without exception');
+ Except
+ On E: Exception Do Begin
+ // EarlyLog('OpenGLControl1MakeCurrent: ERROR creating AtomicFont: ' + E.Message);
+ // log('ERROR creating AtomicFont: ' + E.Message, llError);
+ End;
+ End;
glenable(GL_TEXTURE_2D); // Texturen
glEnable(GL_DEPTH_TEST); // Tiefentest
glDepthFunc(gl_less);
@@ -186,73 +223,371 @@
Game.initialize(OpenGLControl1);
Timer1.Enabled := true;
End;
+{$ELSE}
+ // On macOS: allowcnt >= 1 and Game.Initialize will be called from OnIdle
+ If (allowcnt >= 1) And (Not Initialized) Then Begin // Ensure initialization runs once when the context becomes available.
+ // log('Initializing OpenGL resources (allowcnt=' + inttostr(allowcnt) + ')', llInfo);
+ OpenGL_GraphikEngine.clear;
+ // EarlyLog('OpenGLControl1MakeCurrent: Creating ASCII font...');
+ Try
+ Create_ASCII_Font;
+ // If Assigned(OpenGL_ASCII_Font) Then
+ // EarlyLog('OpenGLControl1MakeCurrent: ASCII font created successfully')
+ // Else
+ // EarlyLog('OpenGLControl1MakeCurrent: WARNING - ASCII font is Nil after creation');
+ Except
+ On E: Exception Do Begin
+ // EarlyLog('OpenGLControl1MakeCurrent: ERROR creating ASCII font: ' + E.Message);
+ // log('ERROR creating ASCII font: ' + E.Message, llError);
+ End;
+ End;
+ // EarlyLog('OpenGLControl1MakeCurrent: Creating AtomicFont...');
+ Try
+ AtomicFont.CreateFont;
+ // EarlyLog('OpenGLControl1MakeCurrent: AtomicFont.CreateFont completed without exception');
+ Except
+ On E: Exception Do Begin
+ // EarlyLog('OpenGLControl1MakeCurrent: ERROR creating AtomicFont: ' + E.Message);
+ // log('ERROR creating AtomicFont: ' + E.Message, llError);
+ End;
+ End;
+ glenable(GL_TEXTURE_2D); // Texturen
+ glEnable(GL_DEPTH_TEST); // Tiefentest
+ glDepthFunc(gl_less);
+ glBlendFunc(gl_one, GL_ONE_MINUS_SRC_ALPHA); // Sorgt dafür, dass Voll Transparente Pixel nicht in den Tiefenpuffer Schreiben.
+
+ // Der Anwendung erlauben zu Rendern.
+ Initialized := True;
+ OpenGLControl1Resize(Nil);
+ Timer1.Enabled := true;
+ // NOTE: On macOS, Game.Initialize is called from Application.OnIdle
+ // This ensures Application.Run is active, so OnPaint can be called during initialization
+ fGameInitialized := false; // Will be set to true in OnIdle after Game.Initialize completes
+ End;
+{$ENDIF}
Form1.Invalidate;
End;
Procedure TForm1.OpenGLControl1Paint(Sender: TObject);
Var
s: String;
+ CurrentPlayingTime: Integer;
+ // ElapsedMs, ElapsedSeconds, Minutes, Seconds: Integer;
Begin
(*
* Unter Windows kann es vorkommen, dass dieses OnPaint ausgelöst wird obwohl wir noch am Laden in OpenGLControl1MakeCurrent sind
* Wenn das Passiert, bekommt der User eine Fehlermeldung die nicht stimmt.
*
* Zum Glück kann man das Abfangen in dem man hier den Timer1 abprüft und das so verhindert ;)
+ *
+ * NOTE: Allow rendering during initialization to show loading dialog (critical on macOS and Windows)
*)
If Not Timer1.Enabled Then exit;
- If Not Initialized Then Exit;
+ // Allow rendering loading dialog even if Initialized is false (during Game.Initialize on macOS)
+ // On macOS, Initialized may be false but Game.Initialize is in progress
+ If Not Initialized And (Not Assigned(Game) Or Not Assigned(Game.LoaderDialog) Or Game.IsInitialized) Then Exit;
+ // On Windows, Game.Initialize is called from OpenGLControl1MakeCurrent, so if Initialized is true
+ // but Game is not initialized yet, we should wait (though this should not happen)
+{$IFDEF Windows}
+ If Initialized And (Not Assigned(Game) Or (Assigned(Game) And Not Game.IsInitialized And Not Assigned(Game.LoaderDialog))) Then Exit;
+{$ENDIF}
+
+ // Check if window size changed and update viewport if needed
+ If (OpenGLControl1.ClientWidth <> fLastControlWidth) Or
+ (OpenGLControl1.ClientHeight <> fLastControlHeight) Then Begin
+ OpenGLControl1Resize(Nil);
+ End;
+
// Render Szene
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glcolor4f(1, 1, 1, 1);
glBindTexture(GL_TEXTURE_2D, 0);
- Game.Render();
- If Game.Settings.ShowFPS Then Begin
+ // Render loading dialog during initialization, otherwise render game
+ If Assigned(Game) And Assigned(Game.LoaderDialog) And Not Game.IsInitialized Then Begin
+ // Render loading dialog directly during initialization (critical for macOS visibility)
+ // EarlyLog('OpenGLControl1Paint: Rendering LoaderDialog');
+ Game.LoaderDialog.RenderDirect();
+ // EarlyLog('OpenGLControl1Paint: LoaderDialog rendered');
+ End Else If Assigned(Game) And Game.IsInitialized Then Begin
+ Game.Render();
+ End Else Begin
+ // EarlyLog('OpenGLControl1Paint: Not rendering - Game=' + BoolToStr(Assigned(Game), true) +
+ // ', LoaderDialog=' + BoolToStr(Assigned(Game) And Assigned(Game.LoaderDialog), true) +
+ // ', IsInitialized=' + BoolToStr(Assigned(Game) And Game.IsInitialized, true));
+ End;
+ If Assigned(Game) And Game.IsInitialized And Game.Settings.ShowFPS Then Begin
+ // Track level start time - detect when level begins (playing time resets to 0 or jumps up)
+ If Assigned(Game) Then Begin
+ CurrentPlayingTime := Game.PlayingTime_s;
+ // Detect level start: playing time reset to 0 (or -1 for infinity) when level begins
+ // or when playing time suddenly increases (new round starts)
+ If (CurrentPlayingTime >= 0) And ((fLastPlayingTime_s < 0) Or
+ (fLastPlayingTime_s > CurrentPlayingTime + 5)) Then Begin
+ // Level started (reset detected or time jumped backwards significantly)
+ fLevelStartTime := GetTickCount64();
+ End;
+ fLastPlayingTime_s := CurrentPlayingTime;
+ End;
+
Go2d(OpenGLControl1.Width, OpenGLControl1.Height);
glBindTexture(GL_TEXTURE_2D, 0);
- OpenGL_ASCII_Font.Color := clwhite;
glTranslatef(0, 0, atomic_dialog_Layer + atomic_EPSILON);
- s := 'FPS : ' + inttostr(LastFPS_Counter);
-{$IFDEF DebuggMode}
- If game.fPlayer[1].UID = -1 Then Begin // Wenn der Spieler 1 eine AI ist ..
- s := s + format(' AI: %0.4f %0.4f', [game.fPlayer[1].Info.Position.x, game.fPlayer[1].Info.Position.y]);
+
+ // === ENHANCED DEBUG OVERLAY - BOTTOM OF SCREEN ===
+ // Use AtomicFont for larger, more readable text
+ AtomicFont.Color := clWhite;
+
+ // First line: FPS and Network stats with MAX values
+ s := 'FPS: ' + inttostr(LastFPS_Counter);
+ If Assigned(Game) Then Begin
+ s := s + format(' | RTT: %dms (max %dms)', [Game.fDebugStats.LastRTT, Game.fDebugStats.MaxRTT]);
+ s := s + format(' | Snap: %dms (max %dms)', [Game.fDebugStats.SnapshotAge, Game.fDebugStats.MaxSnapAge]);
End;
-{$ENDIF}
- OpenGL_ASCII_Font.Textout(5, 5, s);
+ AtomicFont.Textout(10, OpenGLControl1.Height - 60, s);
+
+ // Second line: Interpolation stats with MAX
+ If Assigned(Game) Then Begin
+ s := format('Interp: %.2f (max %.2f)', [Game.fDebugStats.InterpolationFactor, Game.fDebugStats.MaxInterpFactor]);
+ If Game.fDebugStats.IsExtrapolating Then
+ s := s + ' [EXTRAPOLATING]'
+ Else
+ s := s + ' [interpolating]';
+ AtomicFont.Textout(10, OpenGLControl1.Height - 40, s);
+ End;
+
+ // Third line: Viewport info (if in debug mode)
+ {$IFDEF DebuggMode}
+ If Assigned(Game) Then Begin
+ s := 'Viewport: ' + inttostr(OpenGLControl1.ClientWidth) + 'x' + inttostr(OpenGLControl1.ClientHeight);
+ s := s + ' | Game: ' + inttostr(Game.DebugViewportWidth) + 'x' + inttostr(Game.DebugViewportHeight);
+ s := s + format(' Scale: %.2f', [Game.DebugViewportScale]);
+ AtomicFont.Textout(10, OpenGLControl1.Height - 20, s);
+
+ // AI position debug
+ If game.fPlayer[1].UID = -1 Then Begin
+ s := format('AI: %.2f, %.2f', [game.fPlayer[1].Info.Position.x, game.fPlayer[1].Info.Position.y]);
+ OpenGL_ASCII_Font.Textout(10, OpenGLControl1.Height - 5, s);
+ End;
+ End;
+ {$ENDIF}
Exit2d();
End;
OpenGLControl1.SwapBuffers;
End;
Procedure TForm1.OpenGLControl1Resize(Sender: TObject);
+Var
+ ControlW, ControlH: Integer;
+ ScaleX, ScaleY, UniformScale: Double;
+ ViewportWidth, ViewportHeight: Integer;
+ OffsetX, OffsetY: Integer;
Begin
- If Initialized Then Begin
+ ControlW := OpenGLControl1.ClientWidth;
+ ControlH := OpenGLControl1.ClientHeight;
+ If ControlW <= 0 Then ControlW := GameWidth;
+ If ControlH <= 0 Then ControlH := GameHeight;
+
+ ScaleX := ControlW / GameWidth;
+ ScaleY := ControlH / GameHeight;
+ If ScaleX < ScaleY Then
+ UniformScale := ScaleX
+ Else
+ UniformScale := ScaleY;
+ If UniformScale <= 0 Then
+ UniformScale := 1;
+
+ ViewportWidth := Round(GameWidth * UniformScale);
+ ViewportHeight := Round(GameHeight * UniformScale);
+ If ViewportWidth < 1 Then ViewportWidth := 1;
+ If ViewportHeight < 1 Then ViewportHeight := 1;
+ If ViewportWidth > ControlW Then ViewportWidth := ControlW;
+ If ViewportHeight > ControlH Then ViewportHeight := ControlH;
+
+ OffsetX := (ControlW - ViewportWidth) div 2;
+ OffsetY := (ControlH - ViewportHeight) div 2;
+
+ // Always set viewport if OpenGL context is available
+ // CRITICAL: Set projection matrix to fixed logical dimensions (GameWidth x GameHeight)
+ // This ensures game coordinates are always the same regardless of viewport size
+ // Without this, changing viewport size changes the logical coordinate system,
+ // which affects animation timing and game speed
+ If Initialized And OpenGLControl1.MakeCurrent Then Begin
+ glViewport(OffsetX, OffsetY, ViewportWidth, ViewportHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glViewport(0, 0, OpenGLControl1.Width, OpenGLControl1.Height);
- gluPerspective(45.0, OpenGLControl1.Width / OpenGLControl1.Height, 0.1, 100.0);
+ // Set orthographic projection with fixed logical dimensions (GameWidth x GameHeight)
+ // This ensures that game coordinates are always the same, regardless of viewport size
+ glOrtho(0, GameWidth, GameHeight, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
End;
+
+ // Update game viewport metrics even before initialization
+ If Assigned(Game) Then
+ Game.SetViewportMetrics(ControlW, ControlH, OffsetX, OffsetY,
+ ViewportWidth, ViewportHeight);
+
+ // Track current control size to detect resize changes
+ fLastControlWidth := ControlW;
+ fLastControlHeight := ControlH;
+End;
+
+Function TForm1.InitializeBASS(): Boolean;
+Var
+ DeviceIndex: Integer;
+ DeviceInfo: BASS_DEVICEINFO;
+ ErrorCode: Integer;
+ ErrorMsg: String;
+ TriedDevices: String;
+Begin
+ Result := False;
+ TriedDevices := '';
+
+ (*
+ * BASS_DEVICE_DMIX = Allows multiple applications to write to the sound card.
+ * Without this flag, no other sound applications can run.
+ *)
+
+ // First try: Default device (-1) with DMIX flag
+ log('Trying to initialize BASS with default device (-1) and DMIX flag...', llInfo);
+{$IFDEF Windows}
+ If BASS_Init(-1, 44100, BASS_DEVICE_DMIX, 0, Nil) Then Begin
+{$ELSE}
+ If BASS_Init(-1, 44100, BASS_DEVICE_DMIX, Nil, Nil) Then Begin
+{$ENDIF}
+ log('BASS initialized successfully with default device and DMIX', llInfo);
+ Result := True;
+ Exit;
+ End;
+
+ ErrorCode := BASS_ErrorGetCode;
+ TriedDevices := 'Default device (-1)';
+ log('Failed to initialize with default device, error code: ' + IntToStr(ErrorCode), llWarning);
+
+ // Second try: Enumerate available devices and try each one with DMIX
+ log('Enumerating available audio devices...', llInfo);
+ DeviceIndex := 0;
+ While BASS_GetDeviceInfo(DeviceIndex, DeviceInfo) Do Begin
+ If (DeviceInfo.flags And BASS_DEVICE_ENABLED) <> 0 Then Begin
+ If TriedDevices <> '' Then TriedDevices := TriedDevices + ', ';
+ If Assigned(DeviceInfo.name) Then
+ TriedDevices := TriedDevices + 'Device ' + IntToStr(DeviceIndex) + ' (' + String(DeviceInfo.name) + ')'
+ Else
+ TriedDevices := TriedDevices + 'Device ' + IntToStr(DeviceIndex);
+
+ log('Trying device ' + IntToStr(DeviceIndex) + ' with DMIX...', llInfo);
+{$IFDEF Windows}
+ If BASS_Init(DeviceIndex, 44100, BASS_DEVICE_DMIX, 0, Nil) Then Begin
+{$ELSE}
+ If BASS_Init(DeviceIndex, 44100, BASS_DEVICE_DMIX, Nil, Nil) Then Begin
+{$ENDIF}
+ log('BASS initialized successfully with device ' + IntToStr(DeviceIndex) + ' and DMIX', llInfo);
+ Result := True;
+ Exit;
+ End;
+ ErrorCode := BASS_ErrorGetCode;
+ log('Failed to initialize device ' + IntToStr(DeviceIndex) + ', error code: ' + IntToStr(ErrorCode), llWarning);
+ End;
+ Inc(DeviceIndex);
+ End;
+
+ // Third try: Default device without DMIX flag (fallback)
+ log('Trying default device without DMIX flag (fallback)...', llInfo);
+{$IFDEF Windows}
+ If BASS_Init(-1, 44100, 0, 0, Nil) Then Begin
+{$ELSE}
+ If BASS_Init(-1, 44100, 0, Nil, Nil) Then Begin
+{$ENDIF}
+ log('BASS initialized successfully with default device without DMIX (note: other sound apps may not work)', llWarning);
+ Result := True;
+ Exit;
+ End;
+
+ ErrorCode := BASS_ErrorGetCode;
+
+ // Fourth try: Enumerate devices without DMIX
+ log('Trying available devices without DMIX flag...', llInfo);
+ DeviceIndex := 0;
+ While BASS_GetDeviceInfo(DeviceIndex, DeviceInfo) Do Begin
+ If (DeviceInfo.flags And BASS_DEVICE_ENABLED) <> 0 Then Begin
+ log('Trying device ' + IntToStr(DeviceIndex) + ' without DMIX...', llInfo);
+{$IFDEF Windows}
+ If BASS_Init(DeviceIndex, 44100, 0, 0, Nil) Then Begin
+{$ELSE}
+ If BASS_Init(DeviceIndex, 44100, 0, Nil, Nil) Then Begin
+{$ENDIF}
+ log('BASS initialized successfully with device ' + IntToStr(DeviceIndex) + ' without DMIX', llWarning);
+ Result := True;
+ Exit;
+ End;
+ ErrorCode := BASS_ErrorGetCode;
+ End;
+ Inc(DeviceIndex);
+ End;
+
+ // All attempts failed - show detailed error message
+ ErrorMsg := 'Unable to initialize audio device.' + LineEnding + LineEnding;
+ ErrorMsg := ErrorMsg + 'Error code: ' + IntToStr(ErrorCode);
+ Case ErrorCode Of
+ 23: ErrorMsg := ErrorMsg + ' (BASS_ERROR_DEVICE - illegal device number)';
+ 3: ErrorMsg := ErrorMsg + ' (BASS_ERROR_DRIVER - cannot find a free sound driver)';
+ 8: ErrorMsg := ErrorMsg + ' (BASS_ERROR_INIT - BASS_Init has not been successfully called)';
+ 11: ErrorMsg := ErrorMsg + ' (BASS_ERROR_REINIT - device needs to be reinitialized)';
+ 46: ErrorMsg := ErrorMsg + ' (BASS_ERROR_BUSY - the device is busy)';
+ 49: ErrorMsg := ErrorMsg + ' (BASS_ERROR_DENIED - access denied)';
+ Else ErrorMsg := ErrorMsg + ' (unknown error)';
+ End;
+ ErrorMsg := ErrorMsg + LineEnding + LineEnding;
+ ErrorMsg := ErrorMsg + 'Tried devices: ' + TriedDevices;
+ ErrorMsg := ErrorMsg + LineEnding + LineEnding;
+ ErrorMsg := ErrorMsg + 'Possible solutions:' + LineEnding;
+ ErrorMsg := ErrorMsg + '1. Check if audio device is available and not used by another application' + LineEnding;
+ ErrorMsg := ErrorMsg + '2. Restart the application' + LineEnding;
+ ErrorMsg := ErrorMsg + '3. Check audio driver installation' + LineEnding;
+ ErrorMsg := ErrorMsg + '4. On Linux: ensure ALSA/PulseAudio is properly configured';
+
+ log(ErrorMsg, llError);
+ showmessage(ErrorMsg);
End;
Procedure TForm1.FormCreate(Sender: TObject);
Var
FileloggingDir: String;
i: integer;
+ AutoLogFile: String;
+ ConfigDirUsed: String;
+{$IFDEF DARWIN}
+ ConfigDir: String;
+{$ENDIF}
Begin
Randomize;
ConnectParamsHandled := false;
Initialized := false; // Wenn True dann ist OpenGL initialisiert
Form1ShowOnce := true;
- IniPropStorage1.IniFileName := 'fpc_atomic.ini';
+ FAdjustingSize := false;
+ fGameInitialized := false; // Game.Initialize will be called from OnIdle
+ FileloggingDir := '';
+ AutoLogFile := '';
+ ConfigDirUsed := '';
+{$IFDEF DARWIN}
+ ConfigDir := IncludeTrailingPathDelimiter(GetUserDir) + 'Library/Application Support/fpc_atomic/';
+ If Not ForceDirectoriesUTF8(ConfigDir) Then
+ ConfigDir := IncludeTrailingPathDelimiter(GetAppConfigDirUTF8(False));
+ If (ConfigDir <> '') And ForceDirectoriesUTF8(ConfigDir) Then Begin
+ IniPropStorage1.IniFileName := ConfigDir + 'fpc_atomic.ini';
+ ConfigDirUsed := ConfigDir;
+ AutoLogFile := ConfigDir + 'debug.log';
+ End
+ Else
+{$ENDIF}
+ IniPropStorage1.IniFileName := 'fpc_atomic.ini';
DefFormat := DefaultFormatSettings;
DefFormat.DecimalSeparator := '.';
LogShowHandler := @ShowUserMessage;
fUserMessages := Nil;
DefaultFormatSettings.DecimalSeparator := '.';
InitLogger();
- FileloggingDir := '';
For i := 1 To Paramcount Do Begin
{$IFDEF Windows}
If lowercase(ParamStrUTF8(i)) = '-c' Then Begin
@@ -283,10 +618,19 @@
End;
End;
End;
+ If (FileloggingDir = '') And (AutoLogFile <> '') Then Begin
+ FileloggingDir := AutoLogFile;
+ SetLoggerLogFile(FileloggingDir);
+ End;
+ If ConfigDirUsed <> '' Then
+ log('Using config dir: ' + ConfigDirUsed, llInfo);
log('TForm1.FormCreate', llInfo);
log('TForm1.FormCreate', lltrace);
If FileloggingDir = '' Then Begin
log('Disabled, file logging.', llWarning);
+ End
+ Else Begin
+ log('Writing log to: ' + FileloggingDir, llInfo);
End;
caption := defCaption;
@@ -295,17 +639,8 @@
halt;
End;
- (*
- BASS_DEVICE_DMIX = Erlaubt das Mehrfache Beschreiben auf die Soundkarte.
- Ohne dieses Flag, können keine anderen Sound anwendungen mehr laufen.
- *)
-{$IFDEF Windows}
- If Not Bass_init(-1, 44100, BASS_DEVICE_DMIX, 0, Nil) Then Begin
-{$ELSE}
- // Steht der Compiler auf Object Pascal mus diese Zeile genommen werden.
- If Not Bass_init(-1, 44100, BASS_DEVICE_DMIX, Nil, Nil) Then Begin
-{$ENDIF}
- showmessage('Unable to init the device, Error code :' + inttostr(BASS_ErrorGetCode));
+ // Try to initialize BASS with better error handling and fallback options
+ If Not InitializeBASS() Then Begin
halt;
End;
@@ -313,6 +648,11 @@
ClientHeight := 480;
Tform(self).Constraints.MinHeight := 480;
Tform(self).Constraints.Minwidth := 640;
+{$IFDEF Darwin}
+ // Prevent fullscreen mode by limiting window size (prevents "Game Mode" activation)
+ Tform(self).Constraints.MaxWidth := Screen.Width - 1;
+ Tform(self).Constraints.MaxHeight := Screen.Height - 1;
+{$ENDIF}
// Init dglOpenGL.pas , Teil 1
If Not InitOpenGl Then Begin
LogShow('Error, could not init dglOpenGL.pas', llfatal);
@@ -327,6 +667,10 @@
*)
Timer1.Interval := 17;
OpenGLControl1.Align := alClient;
+ fLastControlWidth := 0;
+ fLastControlHeight := 0;
+ fLevelStartTime := 0;
+ fLastPlayingTime_s := -1;
Game := TGame.Create();
game.OnNeedHideCursor := @HideCursor;
game.OnNeedShowCursor := @ShowCursor;
@@ -377,20 +721,42 @@
Procedure TForm1.FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
Begin
log('TForm1.FormCloseQuery', llTrace);
- // Todo: Speichern der Map, oder wenigstens Nachfragen ob gespeichert werden soll
- log('Shuting down.', llInfo);
- IniPropStorage1.WriteInteger('ProtocollVersion', ProtocollVersion);
- IniPropStorage1.WriteString('Version', Version);
- //setValue('MainForm', 'Left', inttostr(Form1.left));
- //setValue('MainForm', 'Top', inttostr(Form1.top));
- //setValue('MainForm', 'Width', inttostr(Form1.Width));
- //setValue('MainForm', 'Height', inttostr(Form1.Height));
-
- timer1.Enabled := false;
- Initialized := false;
- // Eine Evtl bestehende Verbindung Kappen, so lange die LCL und alles andere noch Lebt.
- Game.Disconnect;
- Game.OnIdle;
+
+ // If NeedFormClose is already true, user has confirmed exit via menu/ESC
+ // Allow the close to proceed normally
+ If NeedFormClose Then Begin
+ log('Shuting down (user confirmed exit).', llInfo);
+ IniPropStorage1.WriteInteger('ProtocollVersion', ProtocollVersion);
+ IniPropStorage1.WriteString('Version', Version);
+ //setValue('MainForm', 'Left', inttostr(Form1.left));
+ //setValue('MainForm', 'Top', inttostr(Form1.top));
+ //setValue('MainForm', 'Width', inttostr(Form1.Width));
+ //setValue('MainForm', 'Height', inttostr(Form1.Height));
+
+ timer1.Enabled := false;
+ Initialized := false;
+ // Eine Evtl bestehende Verbindung Kappen, so lange die LCL und alles andere noch Lebt.
+ Game.Disconnect;
+ Game.OnIdle;
+ LogLeave;
+ Exit; // Allow close to proceed
+ End;
+
+ // User clicked window close button - show confirmation dialog
+ log('Window close button clicked, showing confirmation dialog', llInfo);
+ CanClose := false; // Prevent immediate close
+
+ // Show the same dialog as when user presses ESC or selects Exit from menu
+ If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then Begin
+ // User confirmed - switch to Exit Bomberman screen
+ // This will set NeedFormClose := true, play quit sound, and then close the form
+ // TScreenEnum is available through ugame.pas which uses uscreens.pas
+ If Assigned(Game) Then Begin
+ Game.SwitchToScreen(sExitBomberman);
+ End;
+ End;
+ // If user clicked No, CanClose remains false, so window stays open
+
LogLeave;
End;
@@ -401,7 +767,26 @@
p: Pchar;
{$ENDIF}
t: int64;
+{$IFDEF Darwin}
+ MaxWidth, MaxHeight: Integer;
+{$ENDIF}
Begin
+{$IFDEF Darwin}
+ // Convert fullscreen attempt (green button click) to large windowed mode
+ If WindowState = wsFullScreen Then Begin
+ WindowState := wsNormal;
+ MaxWidth := Screen.Width - 1;
+ MaxHeight := Screen.Height - 1;
+ Tform(self).Constraints.MaxWidth := MaxWidth;
+ Tform(self).Constraints.MaxHeight := MaxHeight;
+ Left := (Screen.Width - MaxWidth) div 2;
+ Top := (Screen.Height - MaxHeight) div 2;
+ Width := MaxWidth;
+ Height := MaxHeight;
+ fWishFullscreen := True;
+ Game.Settings.Fullscreen := True;
+ End;
+{$ENDIF}
If Initialized Then Begin
inc(FPS_Counter);
t := GetTickCount64();
@@ -430,6 +815,32 @@
i, port: Integer;
msg, ip: String;
Begin
+ // CRITICAL: On macOS, Game.Initialize must be called from OnIdle (after Application.Run starts)
+ // This ensures OnPaint can be called during initialization to show the loading dialog
+ // On Windows, Game.Initialize is called directly from OpenGLControl1MakeCurrent
+{$IFNDEF Windows}
+ If Not fGameInitialized And Initialized And Assigned(Game) Then Begin
+ // Ensure OpenGL context is active before initializing (required for texture loading)
+ // On macOS, context might not be ready immediately after Application.Run starts
+ If Not OpenGLControl1.MakeCurrent Then Begin
+ // Context not ready yet, try again next time
+ exit;
+ End;
+ fGameInitialized := true; // Set flag first to prevent re-entry
+ // Initialize game - this will load textures and create loading dialog
+ // All texture loading happens here, so context must be active
+ Game.initialize(OpenGLControl1);
+ // Process messages to allow OnPaint to render loading dialog
+ // This is critical on macOS to show loading progress
+ Application.ProcessMessages;
+ End;
+{$ENDIF}
+
+ // Process incoming network chunks from network thread
+ If Assigned(Game) Then Begin
+ Game.ChunkManager.ProcessIncomingChunks();
+ End;
+
{$IFDEF AUTOMODE}
Case AutomodeData.State Of
AM_Idle: Begin
@@ -557,6 +968,40 @@
Game.Settings.Keys[ks1].AchsisIdle[1] := IniPropStorage1.readInteger('SDL_LeftRightIdle2', Game.Settings.Keys[ks1].AchsisIdle[1]);
Game.Settings.Keys[ks1].AchsisDirection[1] := IniPropStorage1.readInteger('SDL_LeftRightDirection2', Game.Settings.Keys[ks1].AchsisDirection[1]);
End;
+ // Load joystick mappings for ksJoy1
+ Game.Settings.Keys[ksJoy1] := AtomicDefaultKeys(ksJoy1);
+ Game.Settings.Keys[ksJoy1].UseSDL2 := IniPropStorage1.ReadBoolean('UseSDLJoy1', Game.Settings.Keys[ksJoy1].UseSDL2);
+ If Game.Settings.Keys[ksJoy1].UseSDL2 Then Begin
+ Game.Settings.Keys[ksJoy1].Name := IniPropStorage1.ReadString('SDL_NameJoy1', Game.Settings.Keys[ksJoy1].Name);
+ Game.Settings.Keys[ksJoy1].NameIndex := IniPropStorage1.readInteger('SDL_NameIndexJoy1', Game.Settings.Keys[ksJoy1].NameIndex);
+ Game.Settings.Keys[ksJoy1].ButtonIndex[0] := IniPropStorage1.readInteger('SDL_FirstJoy1', Game.Settings.Keys[ksJoy1].ButtonIndex[0]);
+ Game.Settings.Keys[ksJoy1].ButtonsIdle[0] := IniPropStorage1.ReadBoolean('SDL_FirstIdleJoy1', Game.Settings.Keys[ksJoy1].ButtonsIdle[0]);
+ Game.Settings.Keys[ksJoy1].ButtonIndex[1] := IniPropStorage1.readInteger('SDL_SecondJoy1', Game.Settings.Keys[ksJoy1].ButtonIndex[1]);
+ Game.Settings.Keys[ksJoy1].ButtonsIdle[1] := IniPropStorage1.ReadBoolean('SDL_SecondIdleJoy1', Game.Settings.Keys[ksJoy1].ButtonsIdle[1]);
+ Game.Settings.Keys[ksJoy1].AchsisIndex[0] := IniPropStorage1.readInteger('SDL_UpDownJoy1', Game.Settings.Keys[ksJoy1].AchsisIndex[0]);
+ Game.Settings.Keys[ksJoy1].AchsisIdle[0] := IniPropStorage1.readInteger('SDL_UpDownIdleJoy1', Game.Settings.Keys[ksJoy1].AchsisIdle[0]);
+ Game.Settings.Keys[ksJoy1].AchsisDirection[0] := IniPropStorage1.readInteger('SDL_UpDownDirectionJoy1', Game.Settings.Keys[ksJoy1].AchsisDirection[0]);
+ Game.Settings.Keys[ksJoy1].AchsisIndex[1] := IniPropStorage1.readInteger('SDL_LeftRightJoy1', Game.Settings.Keys[ksJoy1].AchsisIndex[1]);
+ Game.Settings.Keys[ksJoy1].AchsisIdle[1] := IniPropStorage1.readInteger('SDL_LeftRightIdleJoy1', Game.Settings.Keys[ksJoy1].AchsisIdle[1]);
+ Game.Settings.Keys[ksJoy1].AchsisDirection[1] := IniPropStorage1.readInteger('SDL_LeftRightDirectionJoy1', Game.Settings.Keys[ksJoy1].AchsisDirection[1]);
+ End;
+ // Load joystick mappings for ksJoy2
+ Game.Settings.Keys[ksJoy2] := AtomicDefaultKeys(ksJoy2);
+ Game.Settings.Keys[ksJoy2].UseSDL2 := IniPropStorage1.ReadBoolean('UseSDLJoy2', Game.Settings.Keys[ksJoy2].UseSDL2);
+ If Game.Settings.Keys[ksJoy2].UseSDL2 Then Begin
+ Game.Settings.Keys[ksJoy2].Name := IniPropStorage1.ReadString('SDL_NameJoy2', Game.Settings.Keys[ksJoy2].Name);
+ Game.Settings.Keys[ksJoy2].NameIndex := IniPropStorage1.readInteger('SDL_NameIndexJoy2', Game.Settings.Keys[ksJoy2].NameIndex);
+ Game.Settings.Keys[ksJoy2].ButtonIndex[0] := IniPropStorage1.readInteger('SDL_FirstJoy2', Game.Settings.Keys[ksJoy2].ButtonIndex[0]);
+ Game.Settings.Keys[ksJoy2].ButtonsIdle[0] := IniPropStorage1.ReadBoolean('SDL_FirstIdleJoy2', Game.Settings.Keys[ksJoy2].ButtonsIdle[0]);
+ Game.Settings.Keys[ksJoy2].ButtonIndex[1] := IniPropStorage1.readInteger('SDL_SecondJoy2', Game.Settings.Keys[ksJoy2].ButtonIndex[1]);
+ Game.Settings.Keys[ksJoy2].ButtonsIdle[1] := IniPropStorage1.ReadBoolean('SDL_SecondIdleJoy2', Game.Settings.Keys[ksJoy2].ButtonsIdle[1]);
+ Game.Settings.Keys[ksJoy2].AchsisIndex[0] := IniPropStorage1.readInteger('SDL_UpDownJoy2', Game.Settings.Keys[ksJoy2].AchsisIndex[0]);
+ Game.Settings.Keys[ksJoy2].AchsisIdle[0] := IniPropStorage1.readInteger('SDL_UpDownIdleJoy2', Game.Settings.Keys[ksJoy2].AchsisIdle[0]);
+ Game.Settings.Keys[ksJoy2].AchsisDirection[0] := IniPropStorage1.readInteger('SDL_UpDownDirectionJoy2', Game.Settings.Keys[ksJoy2].AchsisDirection[0]);
+ Game.Settings.Keys[ksJoy2].AchsisIndex[1] := IniPropStorage1.readInteger('SDL_LeftRightJoy2', Game.Settings.Keys[ksJoy2].AchsisIndex[1]);
+ Game.Settings.Keys[ksJoy2].AchsisIdle[1] := IniPropStorage1.readInteger('SDL_LeftRightIdleJoy2', Game.Settings.Keys[ksJoy2].AchsisIdle[1]);
+ Game.Settings.Keys[ksJoy2].AchsisDirection[1] := IniPropStorage1.readInteger('SDL_LeftRightDirectionJoy2', Game.Settings.Keys[ksJoy2].AchsisDirection[1]);
+ End;
Game.Settings.ShowFPS := IniPropStorage1.ReadBoolean('ShowFPS', false);
Game.Settings.CheckForUpdates := IniPropStorage1.ReadBoolean('CheckForUpdates', true);
Game.Settings.LastPlayedField := IniPropStorage1.ReadString('LastPlayedField', '');
@@ -638,6 +1083,38 @@
IniPropStorage1.WriteInteger('SDL_LeftRight2', Game.Settings.Keys[ks1].AchsisIndex[1]);
IniPropStorage1.WriteInteger('SDL_LeftRightIdle2', Game.Settings.Keys[ks1].AchsisIdle[1]);
IniPropStorage1.WriteInteger('SDL_LeftRightDirection2', Game.Settings.Keys[ks1].AchsisDirection[1]);
+ // Save joystick mappings for ksJoy1
+ IniPropStorage1.WriteBoolean('UseSDLJoy1', Game.Settings.Keys[ksJoy1].UseSDL2);
+ If Game.Settings.Keys[ksJoy1].UseSDL2 Then Begin
+ IniPropStorage1.WriteString('SDL_NameJoy1', Game.Settings.Keys[ksJoy1].Name);
+ IniPropStorage1.WriteInteger('SDL_NameIndexJoy1', Game.Settings.Keys[ksJoy1].NameIndex);
+ IniPropStorage1.WriteInteger('SDL_FirstJoy1', Game.Settings.Keys[ksJoy1].ButtonIndex[0]);
+ IniPropStorage1.WriteBoolean('SDL_FirstIdleJoy1', Game.Settings.Keys[ksJoy1].ButtonsIdle[0]);
+ IniPropStorage1.WriteInteger('SDL_SecondJoy1', Game.Settings.Keys[ksJoy1].ButtonIndex[1]);
+ IniPropStorage1.WriteBoolean('SDL_SecondIdleJoy1', Game.Settings.Keys[ksJoy1].ButtonsIdle[1]);
+ IniPropStorage1.WriteInteger('SDL_UpDownJoy1', Game.Settings.Keys[ksJoy1].AchsisIndex[0]);
+ IniPropStorage1.WriteInteger('SDL_UpDownIdleJoy1', Game.Settings.Keys[ksJoy1].AchsisIdle[0]);
+ IniPropStorage1.WriteInteger('SDL_UpDownDirectionJoy1', Game.Settings.Keys[ksJoy1].AchsisDirection[0]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightJoy1', Game.Settings.Keys[ksJoy1].AchsisIndex[1]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightIdleJoy1', Game.Settings.Keys[ksJoy1].AchsisIdle[1]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightDirectionJoy1', Game.Settings.Keys[ksJoy1].AchsisDirection[1]);
+ End;
+ // Save joystick mappings for ksJoy2
+ IniPropStorage1.WriteBoolean('UseSDLJoy2', Game.Settings.Keys[ksJoy2].UseSDL2);
+ If Game.Settings.Keys[ksJoy2].UseSDL2 Then Begin
+ IniPropStorage1.WriteString('SDL_NameJoy2', Game.Settings.Keys[ksJoy2].Name);
+ IniPropStorage1.WriteInteger('SDL_NameIndexJoy2', Game.Settings.Keys[ksJoy2].NameIndex);
+ IniPropStorage1.WriteInteger('SDL_FirstJoy2', Game.Settings.Keys[ksJoy2].ButtonIndex[0]);
+ IniPropStorage1.WriteBoolean('SDL_FirstIdleJoy2', Game.Settings.Keys[ksJoy2].ButtonsIdle[0]);
+ IniPropStorage1.WriteInteger('SDL_SecondJoy2', Game.Settings.Keys[ksJoy2].ButtonIndex[1]);
+ IniPropStorage1.WriteBoolean('SDL_SecondIdleJoy2', Game.Settings.Keys[ksJoy2].ButtonsIdle[1]);
+ IniPropStorage1.WriteInteger('SDL_UpDownJoy2', Game.Settings.Keys[ksJoy2].AchsisIndex[0]);
+ IniPropStorage1.WriteInteger('SDL_UpDownIdleJoy2', Game.Settings.Keys[ksJoy2].AchsisIdle[0]);
+ IniPropStorage1.WriteInteger('SDL_UpDownDirectionJoy2', Game.Settings.Keys[ksJoy2].AchsisDirection[0]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightJoy2', Game.Settings.Keys[ksJoy2].AchsisIndex[1]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightIdleJoy2', Game.Settings.Keys[ksJoy2].AchsisIdle[1]);
+ IniPropStorage1.WriteInteger('SDL_LeftRightDirectionJoy2', Game.Settings.Keys[ksJoy2].AchsisDirection[1]);
+ End;
IniPropStorage1.WriteBoolean('ShowFPS', Game.Settings.ShowFPS);
IniPropStorage1.WriteBoolean('CheckForUpdates', Game.Settings.CheckForUpdates);
@@ -650,17 +1127,33 @@
End;
Procedure TForm1.SetFullScreen(Value: Boolean);
+Var
+ MaxWidth, MaxHeight: Integer;
Begin
If value Then Begin
- // TODO: Klären ob man unter Windows wirklich die Differenzierung braucht
-{$IFDEF Windows}
- WindowState := wsMaximized;
-{$ELSE}
- WindowState := wsFullScreen;
+ // On macOS: use large windowed mode instead of true fullscreen to avoid "Game Mode"
+ MaxWidth := Screen.Width - 1;
+ MaxHeight := Screen.Height - 1;
+{$IFDEF Darwin}
+ Tform(self).Constraints.MaxWidth := MaxWidth;
+ Tform(self).Constraints.MaxHeight := MaxHeight;
{$ENDIF}
+ Left := (Screen.Width - MaxWidth) div 2;
+ Top := (Screen.Height - MaxHeight) div 2;
+ Width := MaxWidth;
+ Height := MaxHeight;
+ WindowState := wsNormal;
End
Else Begin
+{$IFDEF Darwin}
+ Tform(self).Constraints.MaxWidth := Screen.Width - 1;
+ Tform(self).Constraints.MaxHeight := Screen.Height - 1;
+{$ENDIF}
WindowState := wsNormal;
+ Left := (Screen.Width - 640) div 2;
+ Top := (Screen.Height - 480) div 2;
+ Width := 640;
+ Height := 480;
End;
Game.Settings.Fullscreen := value;
fWishFullscreen := value;
@@ -682,10 +1175,55 @@
End;
Procedure TForm1.FormResize(Sender: TObject);
+Const
+ DesiredWidth = GameWidth;
+ DesiredHeight = GameHeight;
+Var
+ TargetHeight, TargetWidth: Integer;
+{$IFDEF Darwin}
+ MaxWidth, MaxHeight: Integer;
+{$ENDIF}
Begin
+{$IFDEF Darwin}
+ // Convert fullscreen attempt (green button click) to large windowed mode
+ If WindowState = wsFullScreen Then Begin
+ WindowState := wsNormal;
+ MaxWidth := Screen.Width - 1;
+ MaxHeight := Screen.Height - 1;
+ Tform(self).Constraints.MaxWidth := MaxWidth;
+ Tform(self).Constraints.MaxHeight := MaxHeight;
+ Left := (Screen.Width - MaxWidth) div 2;
+ Top := (Screen.Height - MaxHeight) div 2;
+ Width := MaxWidth;
+ Height := MaxHeight;
+ fWishFullscreen := True;
+ Game.Settings.Fullscreen := True;
+ Exit;
+ End;
+{$ENDIF}
+{$IFDEF Windows}
If fWishFullscreen Then Begin
WindowState := wsFullScreen;
End;
+{$ENDIF}
+ If FAdjustingSize Then
+ Exit;
+ If WindowState <> wsNormal Then
+ Exit;
+ FAdjustingSize := true;
+ Try
+ TargetHeight := Round(ClientWidth * DesiredHeight / DesiredWidth);
+ If Abs(TargetHeight - ClientHeight) > 1 Then Begin
+ ClientHeight := TargetHeight;
+ End
+ Else Begin
+ TargetWidth := Round(ClientHeight * DesiredWidth / DesiredHeight);
+ If Abs(TargetWidth - ClientWidth) > 1 Then
+ ClientWidth := TargetWidth;
+ End;
+ Finally
+ FAdjustingSize := false;
+ End;
End;
Function TForm1.GetWorkDir(Out Directory: String): Boolean;
diff --git a/client/uscreens.pas b/client/uscreens.pas
index 494b4cc..76c77c6 100644
--- a/client/uscreens.pas
+++ b/client/uscreens.pas
@@ -1,1250 +1,1351 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uscreens;
-
-{$MODE ObjFPC}{$H+}
-
-Interface
-
-{$I globaldefines.inc}
-
-Uses
- Classes, SysUtils, controls, uatomic_common, uopengl_animation, uatomic_field;
-
-Type
-
- (*
- * Im MainMenu die diversen Screens
- *)
- TScreenEnum = (
- sMainScreen // Hauptscreen
- //, sSinglePlayer -- ??
- , sHost // Den Gibt es gar nicht, der wird direkt auf den sJoinNetwork umgeleitet
- , sJoinNetwork // Alle Spieler gehen zusammen in das Spiel rein
- , sPlayerSetupRequest // Anfrage zum Wechsel in sPlayerSetup
- , sPlayerSetup // Die Spieler dürfen sich ihre Farben "aussuchen"
- , sEditFieldSetupRequest // Anfrage zum Einstellen der Field einstellungen
- , sEditFieldSetup // Der Master stellt die eigenschaften des fields ein
- , sDrawGame // Der Screen der Angezeigt wird wenn ein Unentschieden gespielt wurde
- , sMatchStatistik // Der Screen der die Match Statistik anzeigt
- , sVictory // Der Screen der das Wer hat gewonnen bild anzeigt
- , sOptions // Der Optionen Dialog
- //, sOnlineManual -- ??
- , sExitBomberman // byby
- );
-
- { TScreen }
-
- TScreen = Class
- private
- fOwner: TObject;
- fBackFile: String;
- fBackTex: Integer; // OpenGL Pointer der fBackFile
- fSoundFile: String;
- fSoundExitScreen: String;
- fCursorFile: String;
- public
-
- PlayerIsFirst: Boolean; // Global Verfügbar, True, wenn der Spieler "Spieler 1" ist !
-
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); virtual;
- Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-
- Constructor Create(Owner: TObject); virtual;
- Destructor Destroy(); override;
-
- Procedure Render; virtual;
- Procedure LoadFromDisk(ResPath: String); virtual;
-
- Procedure Reset; virtual; // Abstract
- Procedure StartPLaySong(); virtual;
- End;
-
- { TMainMenu }
-
- TMainMenu = Class(TScreen)
- private
- fCursor: TOpenGL_Animation;
- fCursorPos: integer; // Position der "Bombe" in Menüpunkten
- public
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
- Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
-
- Constructor Create(Owner: TObject); override;
- Destructor Destroy(); override;
-
- Procedure LoadFromDisk(ResPath: String); override;
- Procedure Render; override;
- Procedure Reset; override;
- End;
-
- { TJoinMenu }
-
- TJoinMenu = Class(TScreen)
- private
- fPlayerInfoString: String; // Die Spieler die Gerade auch eingewählt sind.
-
- public
- Connected: Boolean;
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
-
- Constructor Create(Owner: TObject); override;
- Procedure LoadPlayerdata(Const PlayerData: Array Of TPlayer);
- Procedure Render; override;
- Procedure Reset; override;
- End;
-
- { TPlayerSetupMenu }
-
- TPlayerSetupMenu = Class(TScreen)
- private
- fSchemeFile: String;
- fcursorTex: integer;
- fCursorPos: integer; // Position des "Kopfes" in Menüpunkten
- fPlayerDetails: Array[0..length(PlayerColors) - 1] Of Record
- Team: Integer;
- PlayerData: String;
- End;
- public
- TeamPlay: Boolean; // True = Anzeigen der Spielerfarben als Team wird via "miSwitchToPlayerSetup" gesetzt
-
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
- // TODO: Maus Support
-
- Constructor Create(Owner: TObject); override;
-
- Procedure LoadScheme(Const Scheme: TScheme); // Wird via miUpdateScheme gesetzt
- Procedure LoadPlayerdata(Const PlayerData: TPlayers; Uid: Integer); // wird via TAtomic.SwitchToScreen gesetzt
-
- Procedure LoadFromDisk(ResPath: String); override;
-
- Procedure Render; override;
- Procedure Reset; override;
- End;
-
- { TFieldSetupMenu }
-
- TFieldSetupMenu = Class(TScreen)
- private
- fCursorPos: integer;
- fcursorTex: Integer;
- public
- MasterPlayerName: String;
- ActualField: TAtomicField;
- LastWinsToWinMatch: Integer;
- SchemeFile: String;
-
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
-
- Constructor Create(Owner: TObject); override;
-
- Procedure LoadFromDisk(ResPath: String); override;
- Procedure Render; override;
- Procedure Reset; override;
- End;
-
- { TDrawGameMenu }
-
- TDrawGameMenu = Class(TScreen)
- private
- public
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
-
- Constructor Create(Owner: TObject); override;
-
- Procedure Reset; override;
- End;
-
- { TMatchStatistikMenu }
-
- TMatchStatistikMenu = Class(TScreen)
- private
- fPlayers: TPlayers;
- public
- Victor: TVictor;
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
-
- Procedure LoadPlayerdata(Const PlayerData: TPlayers);
-
- Constructor Create(Owner: TObject); override;
-
- Procedure Render; override;
-
- End;
-
- { TVictoryMenu }
-
- TVictoryMenu = Class(TScreen)
- private
- fbackGrounds: Array[TVictor] Of Integer;
- public
- Victor: TVictor;
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
-
- Procedure LoadFromDisk(ResPath: String); override;
-
- Procedure Render; override;
- Constructor Create(Owner: TObject); override;
- End;
-
- { TOptionsMenu }
-
- TOptionsMenu = Class(TScreen)
- private
- fcursorTex: integer;
- fCursorPos: integer; // Position des "Kopfes" in Menüpunkten
- public
- Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
- Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
-
- Constructor Create(Owner: TObject); override;
-
- Procedure LoadFromDisk(ResPath: String); override;
- Procedure Render; override;
- Procedure Reset; override;
- End;
-
-Implementation
-
-Uses LCLType, Math, Graphics, Dialogs, forms, StdCtrls, fileutil, StrUtils
- , dglOpenGL
- , Unit1 // WTF, why is this unit in here ?
- , uopengl_graphikengine
- , uatomicfont
- , uvectormath
- , ugraphics
- , ugame
- , ukeyboarddialog
- ;
-
-Type
-
- { TSchemQuestionForm }
-
- TSchemQuestionForm = Class(TForm)
- Procedure FormButton1Click(Sender: TObject);
- Procedure FormShow(Sender: Tobject);
- Procedure ListboxKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
- private
- Listbox1: TListbox;
- Button1: TButton;
- public
- Procedure LoadSchemes(SelectedScheme: String);
- // Weil die Form keine Ressource hat, muss sie mittels CreateNew erzeugt werden, was auch immer das für einen unterschied macht ...
- Constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
- End;
-
- { TJoinQuestionForm }
-
- TJoinQuestionForm = Class(TForm)
- private
- Edit1: TEdit;
- Edit2: TEdit;
- Label1: TLabel;
- Label2: TLabel;
- Button1: TButton;
- Button2: TButton;
- public
- Constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
- End;
-
- { TJoinQuestionForm }
-
-Constructor TJoinQuestionForm.CreateNew(AOwner: TComponent; Num: Integer);
-Begin
- Inherited CreateNew(AOwner, Num);
- caption := 'Enter IP-Settings';
- width := 312;
- height := 163;
- Position := poScreenCenter;
- Constraints.MaxWidth := Width;
- Constraints.MinWidth := Width;
- Constraints.MaxHeight := Height;
- Constraints.MinHeight := Height;
-
- Edit1 := TEdit.Create(self);
- edit1.name := 'Edit1';
- edit1.Parent := self;
- edit1.Top := 32;
- edit1.Left := 16;
- edit1.Width := 288;
- edit1.Text := '127.0.0.1';
-
- Edit2 := TEdit.Create(self);
- edit2.name := 'Edit2';
- edit2.Parent := self;
- edit2.Top := 88;
- edit2.Left := 16;
- edit2.Width := 288;
- edit2.Text := '9876';
-
- label1 := TLabel.Create(self);
- label1.Name := 'Label1';
- label1.Parent := self;
- label1.caption := 'IP';
- label1.top := 8;
- label1.Left := 8;
-
- label2 := TLabel.Create(self);
- label2.Name := 'Label2';
- label2.Parent := self;
- label2.caption := 'Port';
- label2.top := 64;
- label2.Left := 8;
-
- Button1 := TButton.Create(self);
- Button1.Name := 'Button1';
- Button1.Parent := self;
- Button1.caption := 'OK';
- Button1.ModalResult := mrOK;
- Button1.Top := 128;
- Button1.Left := 229;
-
- Button2 := TButton.Create(self);
- Button2.Name := 'Button2';
- Button2.Parent := self;
- Button2.caption := 'Cancel';
- Button2.ModalResult := mrCancel;
- Button2.Top := 128;
- Button2.Left := 16;
-End;
-
-{ TVictoryMenu }
-
-Procedure TVictoryMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If (key = VK_RETURN) Or (key = VK_ESCAPE) Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- TGame(fOwner).SwitchToScreen(sMainScreen);
- End;
-End;
-
-Procedure TVictoryMenu.LoadFromDisk(ResPath: String);
-Begin
- Inherited LoadFromDisk(ResPath);
- fbackGrounds[vWhiteTeam] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'team0.png', smStretch);
- fbackGrounds[vRedTeam] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'team1.png', smStretch);
- fbackGrounds[vCol0] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory0.png', smStretch);
- fbackGrounds[vCol1] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory1.png', smStretch);
- fbackGrounds[vCol2] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory2.png', smStretch);
- fbackGrounds[vCol3] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory3.png', smStretch);
- fbackGrounds[vCol4] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory4.png', smStretch);
- fbackGrounds[vCol5] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory5.png', smStretch);
- fbackGrounds[vCol6] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory6.png', smStretch);
- fbackGrounds[vCol7] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory7.png', smStretch);
- fbackGrounds[vCol8] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory8.png', smStretch);
- fbackGrounds[vCol9] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory9.png', smStretch);
-End;
-
-Procedure TVictoryMenu.Render;
-Begin
- fBackTex := fbackGrounds[Victor];
- Inherited Render;
-End;
-
-Constructor TVictoryMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fSoundFile := 'draw.wav';
-End;
-
-{ TMatchStatistikMenu }
-
-Procedure TMatchStatistikMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If key = VK_ESCAPE Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- TGame(fOwner).SwitchToScreen(sMainScreen);
- End;
- If PlayerIsFirst Then Begin
- If key = VK_RETURN Then Begin
- TGame(fOwner).StartGame();
- End;
- End;
-End;
-
-Procedure TMatchStatistikMenu.LoadPlayerdata(Const PlayerData: TPlayers);
-Begin
- fPlayers := PlayerData;
-End;
-
-Constructor TMatchStatistikMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'results.png';
- fSoundFile := 'draw.wav';
-End;
-
-Procedure TMatchStatistikMenu.Render;
-
- Function VictorToString(Value: TVictor): String;
- Var
- index: integer;
- Begin
- Case Value Of
- vRedTeam: result := 'Red Team';
- vWhiteTeam: result := 'White Team';
- Else Begin
- index := integer(value) - integer(vCol0);
- result := fPlayers[index].UserName;
- If result = '' Then
- result := 'Ai';
- End;
- End;
- End;
-
-Var
- s, un: String;
- i: Integer;
-Begin
- Inherited Render;
- glpushmatrix();
- glTranslatef(0, 0, atomic_Map_Layer + 0.5);
- glBindTexture(GL_TEXTURE_2D, 0);
- glColor4f(1, 1, 1, 1);
- AtomicFont.BackColor := clBlack;
- AtomicFont.Color := $00A8ADAB;
- AtomicFont.Textout(150, 100, '(Match winner must score ' + inttostr(TGame(fOwner).Settings.LastWinsToWinMatch) + ' victories)');
- s := 'Game Winner was ' + VictorToString(Victor) + ' !';
- AtomicFont.BackColor := clBlack;
- AtomicFont.Color := clwhite;
- AtomicFont.Textout(150, 150, s);
- glPushMatrix;
- glTranslatef(130, 200, 0);
- For i := 0 To high(fPlayers) Do Begin
- If fPlayers[i].UID <> NoPlayer Then Begin
- If i = 1 Then Begin
- AtomicFont.BackColor := clWhite;
- End
- Else Begin
- AtomicFont.BackColor := clBlack;
- End;
- AtomicFont.Color := AtomicPlayerColorToColor(PlayerColors[i]);
- un := fPlayers[i].UserName;
- If un = '' Then un := 'Ai';
- un := PadRight(un, 20);
- s := format('%s: score: %d (kills: %d)', [un, fPlayers[i].Score, fPlayers[i].Kills]);
- AtomicFont.Textout(0, 0, s);
- glTranslatef(0, 20, 0);
- End;
- End;
- glPopMatrix;
- AtomicFont.BackColor := clBlack; // Reset nach außen
- glPopMatrix;
-End;
-
-{ TDrawGameMenu }
-
-Procedure TDrawGameMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If key = VK_ESCAPE Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sMainScreen);
- End;
- If PlayerIsFirst Then Begin
- If key = VK_RETURN Then Begin
- TGame(fOwner).StartGame;
- End;
- End;
-End;
-
-Constructor TDrawGameMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'draw.png'; // WTF, warum geht das net als PNG ?
- fSoundFile := 'draw.wav';
- fCursorFile := '';
-End;
-
-Procedure TDrawGameMenu.Reset;
-Begin
- Inherited Reset;
-End;
-
-{ TSchemQuestionForm }
-
-Constructor TSchemQuestionForm.CreateNew(AOwner: TComponent; Num: Integer);
-Begin
- Inherited CreateNew(AOwner, Num);
- caption := 'Please select a scheme';
- Width := 350;
- height := 350;
- FormStyle := fsSystemStayOnTop;
- Constraints.MinHeight := height;
- Constraints.MaxHeight := height;
- Constraints.MinWidth := Width;
- Constraints.MaxWidth := Width;
- BorderIcons := [biSystemMenu];
- position := poScreenCenter;
- Button1 := TButton.Create(self);
- button1.name := 'Button1';
- Button1.Parent := self;
- Button1.Align := alBottom;
- button1.caption := 'OK';
- button1.OnClick := @FormButton1Click;
- Listbox1 := TListBox.Create(self);
- Listbox1.Name := 'Listbox1';
- Listbox1.Parent := self;
- Listbox1.Align := alClient;
- Listbox1.OnKeyDown := @ListboxKeyDown;
-
- OnShow := @FormShow;
-End;
-
-Procedure TSchemQuestionForm.FormButton1Click(Sender: TObject);
-Begin
- If Listbox1.ItemIndex <> -1 Then Begin
- ModalResult := mrOK;
- End
- Else Begin
- ModalResult := mrCancel; // Anscheinend haben wir keine Scheme files, dann versuchen wir auch nicht sie zu speichern
- End;
-End;
-
-Procedure TSchemQuestionForm.FormShow(Sender: Tobject);
-Begin
- Listbox1.SetFocus;
- (*
- * Die TopRow Eigenschaft darf erst gesetzt werden, wenn die Listbox dabei ist sich zu zeichnen
- * im LoadSchemes geht das nicht ..
- *)
- If Listbox1.ItemIndex <> -1 Then Begin
- Listbox1.TopIndex := Listbox1.ItemIndex;
- End;
-End;
-
-Procedure TSchemQuestionForm.ListboxKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If key = VK_RETURN Then Begin
- key := 0; // Den Key Löschen, da der Button1.Click das Formular Platt macht und der Key sonst in TScreen nochmal ausgewertet wird.
- button1.Click;
- End;
- If key = VK_ESCAPE Then ModalResult := mrCancel;
-End;
-
-Procedure TSchemQuestionForm.LoadSchemes(SelectedScheme: String);
-Var
- p: String;
- sl: TStringList;
- i: Integer;
-Begin
- p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'data' + PathDelim + 'schemes';
- sl := FindAllfiles(p, '*.sch', false);
- Listbox1.Clear;
- Listbox1.Sorted := true;
- For i := 0 To sl.Count - 1 Do Begin
- Listbox1.Items.Add(ExtractFileName(sl[i]));
- End;
- For i := 0 To Listbox1.Items.Count - 1 Do Begin
- If lowercase(SelectedScheme) = lowercase(Listbox1.Items[i]) Then Begin
- Listbox1.ItemIndex := i;
- break;
- End;
- End;
- sl.free;
-End;
-
-{ TFieldSetupMenu }
-
-Procedure TFieldSetupMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If key = VK_ESCAPE Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- TGame(fOwner).SwitchToScreen(sMainScreen);
- End;
- If PlayerIsFirst Then Begin
- If key = VK_RETURN Then Begin
- TGame(fOwner).StartGame;
- End;
- If key = VK_DOWN Then Begin
- fCursorPos := min(fCursorPos + 1, 1);
- End;
- If key = VK_UP Then Begin
- fCursorPos := max(fCursorPos - 1, 0);
- End;
- If key = VK_LEFT Then Begin
- Case fCursorPos Of
- 0: TGame(fOwner).UpdateSelectedField(-1);
- 1: TGame(fOwner).UpdateWinsToWin(-1);
- End;
- End;
- If key = VK_Right Then Begin
- Case fCursorPos Of
- 0: TGame(fOwner).UpdateSelectedField(1);
- 1: TGame(fOwner).UpdateWinsToWin(1);
- End;
- End;
- End;
-End;
-
-Constructor TFieldSetupMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- ActualField := Nil;
- fBackFile := 'fieldsetup.png'; // WTF, warum geht das net als PNG ?
- fSoundFile := 'player_setup_sound.wav';
- fCursorFile := 'options_cursor.png';
-End;
-
-Procedure TFieldSetupMenu.LoadFromDisk(ResPath: String);
-Begin
- Inherited LoadFromDisk(ResPath);
- (*
- * Neu Laden der Hintergrundgraphik mit Transparenz
- *)
- OpenGL_GraphikEngine.RemoveGraphik(fBackTex);
- fBackTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fBackFile, ColorToRGB(clfuchsia), smStretchHard);
- fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
-End;
-
-Procedure TFieldSetupMenu.Render;
-Begin
- // Das Vorschaubild
- glColor4f(1, 1, 1, 1);
- // Der Eigentliche Hintergrund
- glpushmatrix();
- glAlphaFunc(GL_LESS, 0.5);
- // Das ist ja eine Textur mit "Fenster" -> Also Alphatest mit an
- glEnable(GL_ALPHA_TEST);
- glTranslatef(0, 0, atomic_Map_Layer + 0.5);
- RenderAlphaQuad(v2(320, 240), GameWidth, -GameHeight, 0, fBackTex);
- gldisable(GL_ALPHA_TEST);
- glBindTexture(GL_TEXTURE_2D, 0);
- glpopmatrix();
- If assigned(ActualField) Then Begin
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- If ActualField.Name = '' Then Begin
- AtomicFont.Textout(55, 176, 'Random Each Game');
- End
- Else Begin
- AtomicFont.Textout(55, 176, ActualField.Name);
- End;
- End
- Else Begin
- AtomicFont.Color := clRed;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(55, 176, 'No Field informations...');
- End;
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(55, 176 + 28, inttostr(LastWinsToWinMatch) + ' Wins to win match');
- If PlayerIsFirst Then Begin
- glPushMatrix();
- glTranslatef(20, 176 - 14 + 28 * fCursorPos, atomic_Map_Layer + 0.5 + atomic_EPSILON);
- RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
- glPopMatrix();
- End
- Else Begin
- AtomicFont.Color := clYellow;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(45, 176 - 28 - 28, 'Wait until ' + MasterPlayerName + LineEnding + 'finished setup.');
- End;
- glBindTexture(GL_TEXTURE_2D, 0);
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(60, 400, 'Scheme: ' + SchemeFile);
- (*
- * Das Eigentliche Kartenvorschau Fenster
- *)
- glpushmatrix();
- glTranslatef(379, 33, 0); // Das Offset zum Vorschaufenster ;)
- If assigned(ActualField) Then Begin
- ActualField.RenderPreview;
- End;
- glpopmatrix();
-End;
-
-Procedure TFieldSetupMenu.Reset;
-Begin
- Inherited Reset;
- MasterPlayerName := '';
- fCursorPos := 0;
-End;
-
-{ TPlayerSetupMenu }
-
-Procedure TPlayerSetupMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Begin
- If key = VK_RETURN Then Begin
- If PlayerIsFirst Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sEditFieldSetupRequest);
- End;
- End;
- If key = VK_ESCAPE Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sMainScreen);
- End;
- If key = VK_DOWN Then Begin
- fCursorPos := min(fCursorPos + 1, length(PlayerColors) - 1);
- End;
- If key = VK_UP Then Begin
- fCursorPos := max(fCursorPos - 1, 0);
- End;
- If key = VK_LEFT Then Begin
- Tgame(fOwner).ChangePLayerKey(fCursorPos, -1);
- End;
- If key = VK_RIGHT Then Begin
- Tgame(fOwner).ChangePLayerKey(fCursorPos, 1);
- End;
-End;
-
-Constructor TPlayerSetupMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'join.png';
- fSoundFile := 'player_setup_sound.wav';
- fCursorFile := 'options_cursor.png';
-End;
-
-Procedure TPlayerSetupMenu.LoadScheme(Const Scheme: TScheme);
-Var
- i: Integer;
-Begin
- fSchemeFile := Scheme.Filename;
- (*
- * Für das Playersetup ist nur die "TEAM" Verteilung relevant / interessant
- *)
- For i := 0 To high(fPlayerDetails) Do Begin
- fPlayerDetails[i].Team := Scheme.PlayerStartPositions[i].Team;
- End;
-End;
-
-Procedure TPlayerSetupMenu.LoadPlayerdata(Const PlayerData: TPlayers;
- Uid: Integer);
-Var
- i: Integer;
-Begin
- (*
- * Siehe TPlayer.UID
- *)
- For i := 0 To high(fPlayerDetails) Do Begin
- If PlayerData[i].UID = Uid Then Begin
- If PlayerData[i].Keyboard = ks0 Then Begin
- fPlayerDetails[i].PlayerData := 'key 0';
- End
- Else Begin
- fPlayerDetails[i].PlayerData := 'key 1';
- End;
- //fCursorPos := i; // Das geht leider nicht, da sonst der Cursor merkwürdig Springt wenn der Spieler 2 mal eingestellt ist..
- End
- Else Begin
- If PlayerData[i].UID > 0 Then Begin
- fPlayerDetails[i].PlayerData := PlayerData[i].UserName; // 'NET'; -- The Orig Game shows at this place only a "NET" entry
- End
- Else Begin
- If PlayerData[i].UID = NoPlayer Then Begin
- fPlayerDetails[i].PlayerData := 'OFF';
- End
- Else Begin
- If PlayerData[i].UID = AIPlayer Then Begin
- fPlayerDetails[i].PlayerData := 'AI';
- End;
- End;
- End;
- End;
- End;
-End;
-
-Procedure TPlayerSetupMenu.LoadFromDisk(ResPath: String);
-Begin
- Inherited LoadFromDisk(ResPath);
- fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
-End;
-
-Procedure TPlayerSetupMenu.Render;
-Var
- i: Integer;
- s: String;
-Begin
- Inherited Render;
- glBindTexture(GL_TEXTURE_2D, 0);
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(60, 37 + 40, 'Available players:');
- For i := 0 To high(fPlayerDetails) Do Begin
- If i = 1 Then Begin
- AtomicFont.BackColor := clWhite;
- End
- Else Begin
- AtomicFont.BackColor := clBlack;
- End;
- AtomicFont.Color := AtomicPlayerColorToColor(PlayerColors[i]);
- s := format('Player %0.2d: ', [i + 1]);
- AtomicFont.Textout(60 + 20, 37 + (i + 1) * 28 + 50, s);
- If TeamPlay Then Begin
- (*
- * Im Teamplay Färben wir den Detail Text in der teamfarbe ein
- *)
- If fPlayerDetails[i].Team = TeamIndexWhite Then Begin
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- End
- Else Begin
- AtomicFont.Color := clRed;
- AtomicFont.BackColor := clBlack;
- End;
- End;
- s := format(' %s', [fPlayerDetails[i].PlayerData]);
- AtomicFont.Textout(60 + 20, 37 + (i + 1) * 28 + 50, s);
- End;
- // Reset am ende
- AtomicFont.Color := clwhite;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(60, 400, 'Scheme: ' + fSchemeFile);
- glPushMatrix();
- glTranslatef(60 - 32 + 10, 37 + 14 + 28 * fCursorPos + 50, atomic_Map_Layer + atomic_EPSILON);
- RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
- glPopMatrix();
-End;
-
-Procedure TPlayerSetupMenu.Reset;
-Begin
- Inherited Reset;
- fCursorPos := 0;
-End;
-
-{ TJoinMenu }
-
-Procedure TJoinMenu.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState
- );
-Begin
- If (key = VK_ESCAPE) Or (key = VK_BACK) Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sMainScreen);
- End;
- If key = VK_RETURN Then Begin // Alle Clients sind da -> Ab in den Spieler Config Dialog..
- If PlayerIsFirst Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sPlayerSetupRequest);
- End;
- End;
-End;
-
-Constructor TJoinMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'join.png';
- fSoundFile := 'join_sound.wav';
- fCursorFile := '';
-End;
-
-Procedure TJoinMenu.LoadPlayerdata(Const PlayerData: Array Of TPlayer);
-Var
- i: Integer;
-Begin
- fPlayerInfoString := 'Connected network players:' + LineEnding + LineEnding;
- For i := 0 To high(PlayerData) Do Begin
- If PlayerData[i].UID <> NoPlayer Then Begin
- fPlayerInfoString := fPlayerInfoString + ' ' + PlayerData[i].UserName + LineEnding;
- End;
- End;
-End;
-
-Procedure TJoinMenu.Render;
-Begin
- Inherited Render;
- glPushMatrix;
- glColor3f(1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, 0);
- AtomicFont.color := $00EAE556;
- AtomicFont.BackColor := clBlack;
- AtomicFont.Textout(100, 50, 'Our Nodename is: ''' + Tgame(fOwner).Settings.NodeName + '''');
- If Connected Then Begin
- // Der Server hat unseren Login Versuch Grundsätzlich aktzeptiert
- // Wir zeigen nun die Infos der Spieler an, bis der 1. Spieler in den Nächsten Screen umschaltet
- AtomicFont.color := clWhite;
- AtomicFont.Textout(120, 100, fPlayerInfoString);
- End
- Else Begin
- AtomicFont.color := clYellow;
- AtomicFont.Textout(120, 100, 'Waiting for server to host a game..');
- End;
- glPopMatrix;
-End;
-
-Procedure TJoinMenu.Reset;
-Begin
- Inherited Reset;
- Connected := false;
- fPlayerInfoString := 'waiting for playerlist from server..';
-End;
-
-{ TOptionsMenu }
-
-Procedure TOptionsMenu.OnKeyDown(Sender: TObject; Var Key: Word;
- Shift: TShiftState);
-Var
- kd: TKeyboardDialog;
- qf: TSchemQuestionForm;
- nn: String;
-Begin
- // Zurück ins Hauptmenü
- If (key = VK_ESCAPE) Or (key = VK_BACK) Then Begin
- Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
- Tgame(fOwner).SwitchToScreen(sMainScreen);
- Form1.IniPropStorage1SavingProperties(Nil);
- End;
- If key = VK_DOWN Then Begin
- fCursorPos := min(fCursorPos + 1, 11);
- End;
- If key = VK_UP Then Begin
- fCursorPos := max(fCursorPos - 1, 0);
- End;
- If (key = VK_RETURN) Or (Key = VK_ADD) Or (key = VK_SUBTRACT)
- Or (Key = VK_LEFT) Or (Key = VK_RIGHT) Then Begin
- Case fCursorPos Of
- 0: Tgame(fOwner).Settings.TeamPlay := Not Tgame(fOwner).Settings.TeamPlay;
- 1: Tgame(fOwner).Settings.RandomStart := Not Tgame(fOwner).Settings.RandomStart;
- 2: Begin
- key := 0;
- nn := InputBox('Edit', 'Enter Nodename', Tgame(fOwner).Settings.NodeName);
- If trim(nn) <> '' Then Begin
- Tgame(fOwner).Settings.NodeName := nn;
- End
- Else Begin
- LogShow('Empty username not allowed', llWarning);
- End;
- End;
- 3: Begin
- If key In [VK_RETURN, VK_ADD, VK_RIGHT] Then Begin
- Case Tgame(fOwner).Settings.ConveyorSpeed Of
- csSlow: Tgame(fOwner).Settings.ConveyorSpeed := csMiddle;
- csMiddle: Tgame(fOwner).Settings.ConveyorSpeed := csFast;
- csFast: Tgame(fOwner).Settings.ConveyorSpeed := csSlow;
- End;
- End
- Else Begin
- Case Tgame(fOwner).Settings.ConveyorSpeed Of
- csSlow: Tgame(fOwner).Settings.ConveyorSpeed := csFast;
- csMiddle: Tgame(fOwner).Settings.ConveyorSpeed := csSlow;
- csFast: Tgame(fOwner).Settings.ConveyorSpeed := csMiddle;
- End;
- End;
- End;
- 4: Begin // Scheme File
- key := 0;
- qf := TSchemQuestionForm.CreateNew(Nil);
- qf.LoadSchemes(Tgame(fOwner).Settings.SchemeFile);
- qf.ShowModal;
- If qf.ModalResult = mrOK Then Begin
- Tgame(fOwner).Settings.SchemeFile := qf.Listbox1.Items[qf.Listbox1.ItemIndex];
- End;
- qf.free;
- End;
- 5: Begin // Play Time
- If key In [VK_LEFT, VK_SUBTRACT] Then Begin
- Tgame(fOwner).Settings.PlayTime := max(0, Tgame(fOwner).Settings.PlayTime - 15);
- If Tgame(fOwner).Settings.PlayTime < 80 Then Tgame(fOwner).Settings.PlayTime := 0;
- End
- Else Begin
- If Tgame(fOwner).Settings.PlayTime = 0 Then Begin
- Tgame(fOwner).Settings.PlayTime := 90;
- End
- Else Begin
- Tgame(fOwner).Settings.PlayTime := Tgame(fOwner).Settings.PlayTime + 15;
- End;
- End;
- End;
- 6: Tgame(fOwner).Settings.LostPlayersRevertToAI := Not Tgame(fOwner).Settings.LostPlayersRevertToAI;
- 7: Tgame(fOwner).Settings.PlaySounds := Not Tgame(fOwner).Settings.PlaySounds;
- 8: Begin
- key := 0;
- kd := TKeyboardDialog.CreateNew(Nil);
- kd.LoadKeys(Tgame(fOwner).Settings.Keys[ks0], Tgame(fOwner).Settings.Keys[ks1]);
- If kd.Execute() Then Begin
- Tgame(fOwner).Settings.Keys[ks0] := kd.GetKeys(ks0);
- Tgame(fOwner).Settings.Keys[ks1] := kd.GetKeys(ks1);
- End;
- kd.Free;
- End;
- 9: Tgame(fOwner).Settings.Port := strtointdef(InputBox('Edit', 'Enter port', inttostr(Tgame(fOwner).Settings.Port)), 1234);
- 10: Tgame(fOwner).Settings.ShowFPS := Not Tgame(fOwner).Settings.ShowFPS;
- 11: Begin
- Tgame(fOwner).Settings.Fullscreen := Not Tgame(fOwner).Settings.Fullscreen;
- Form1.SetFullScreen(Tgame(fOwner).Settings.Fullscreen);
-{$IFDEF Windows}
- If Tgame(fOwner).Settings.Fullscreen Then Begin
- LogShow('To switch to Fullscreen mode, you need to restart the game.');
- End;
-{$ENDIF}
- End;
- End;
- End;
-End;
-
-Procedure TOptionsMenu.OnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
-Var
- key: Word;
-Begin
- // Der Klick auf die Buttons ;)
- If (x > 60) And (x < 320) And
- (y > 36) And
- (y < 36 + 12 * 28)
- Then Begin
- fCursorPos := (y - 36) Div 28;
- key := VK_RETURN;
- OnKeyDown(Nil, key, []);
- End;
-End;
-
-Constructor TOptionsMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'options.png';
- fSoundFile := ''; // Die Optionen haben keinen Extra "Sound"
- fCursorFile := 'options_cursor.png';
-End;
-
-Procedure TOptionsMenu.LoadFromDisk(ResPath: String);
-Begin
- Inherited LoadFromDisk(ResPath);
- fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
-End;
-
-Procedure TOptionsMenu.Render;
- Function PrettyTime(Value_s: integer): String;
- Begin
- If Value_s = 0 Then Begin
- result := 'infinity';
- End
- Else Begin
- result := format('%0.2d:%0.2d', [Value_s Div 60, Value_s Mod 60]);
- End;
- End;
-
- Function ConveyerSpeedToString(aSpeed: TConveyorSpeed): String;
- Begin
- result := '';
- Case aSpeed Of
- csSlow: result := 'Slow';
- csMiddle: result := 'Middle';
- csFast: result := 'Fast';
- End;
- End;
-
-Begin
- Inherited Render;
- glBindTexture(GL_TEXTURE_2D, 0);
- AtomicFont.BackColor := clblack;
- AtomicFont.Color := clwhite;
- AtomicFont.Textout(60, 37,
- 'Team Play: ' + BoolToStr(TGame(fOwner).Settings.TeamPlay, 'Yes', 'No') + LineEnding + LineEnding +
- 'Random Start: ' + BoolToStr(TGame(fOwner).Settings.RandomStart, 'Yes', 'No') + LineEnding + LineEnding +
- 'Node Name: ''' + TGame(fOwner).Settings.NodeName + '''' + LineEnding + LineEnding +
- 'Conveyor Speed: ' + ConveyerSpeedToString(TGame(fOwner).Settings.ConveyorSpeed) + LineEnding + LineEnding +
- 'Scheme File: ' + TGame(fOwner).Settings.SchemeFile + LineEnding + LineEnding +
- 'Play Time: ' + PrettyTime(TGame(fOwner).Settings.PlayTime) + LineEnding + LineEnding +
- 'Lost net players revert to AIs: ' + BoolToStr(TGame(fOwner).Settings.LostPlayersRevertToAI, 'Yes', 'No') + LineEnding + LineEnding +
- 'Disable music during gameplay: ' + BoolToStr(TGame(fOwner).Settings.PlaySounds, 'No', 'Yes') + LineEnding + LineEnding +
- 'Define keyboard layouts' + LineEnding + LineEnding +
- 'Network port: ' + inttostr(TGame(fOwner).Settings.Port) + LineEnding + LineEnding +
- 'Show FPS: ' + BoolToStr(TGame(fOwner).Settings.ShowFPS, 'Yes', 'No') + LineEnding + LineEnding +
- 'Fullscreen: ' + BoolToStr(TGame(fOwner).Settings.Fullscreen, 'Yes', 'No')
- );
-
- glPushMatrix();
- glTranslatef(20, 25 + 28 * fCursorPos, atomic_Map_Layer + atomic_EPSILON);
- RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
- glPopMatrix();
-End;
-
-Procedure TOptionsMenu.Reset;
-Begin
- fCursorPos := 0;
-End;
-
-{ TMainMenu }
-
-Procedure TMainMenu.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState
- );
-Var
- f: TJoinQuestionForm;
-Begin
- If key = VK_J Then Begin
- // Frage IP und Port zum Game.JoinViaParams(ip, port); ab !
- f := TJoinQuestionForm.CreateNew(Nil, 0);
- f.Edit1.Text := TGame(fOwner).Settings.Router_IP;
- f.Edit2.Text := TGame(fOwner).Settings.Router_Port;
- If f.ShowModal = mrOK Then Begin
- TGame(fOwner).JoinViaParams(f.Edit1.Text, strtointdef(f.Edit2.Text, 9876));
- End;
- f.free;
- End;
- If key = VK_DOWN Then Begin
- // fCursorPos := min(fCursorPos + 1, 6);
- fCursorPos := (fCursorPos + 1) Mod 7; // Feature Request by Community, rotating navigation
- End;
- If key = VK_UP Then Begin
- // fCursorPos := max(fCursorPos - 1, 0);
- fCursorPos := (fCursorPos + 6) Mod 7; // Feature Request by Community, rotating navigation
- End;
- If (key >= VK_1) And (key <= VK_7) Then Begin
- fCursorPos := key - VK_1;
- key := VK_RETURN;
- End;
- If key = VK_RETURN Then Begin
- Case fCursorPos Of
- 0: logshow('Not yet implemented.', llinfo); // TAtomic(fOwner).SwitchToScreen(); -- Single Player
- 1: TGame(fOwner).SwitchToScreen(sHost);
- 2: TGame(fOwner).SwitchToScreen(sJoinNetwork);
- 3: TGame(fOwner).SwitchToScreen(sOptions);
- 4: logshow('Not yet implemented.', llinfo); //TGame(fOwner).SwitchToScreen(); -- About Bomberman
- 5: logshow('Not yet implemented.', llinfo); //TGame(fOwner).SwitchToScreen(); -- Online Manual
- 6: Begin
-{$IFNDEF Only3Player}
- If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then
-{$ENDIF}
- TGame(fOwner).SwitchToScreen(sExitBomberman);
- End;
- End;
- End;
- If key = VK_ESCAPE Then Begin
-{$IFNDEF Only3Player}
- If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then
-{$ENDIF}
- TGame(fOwner).SwitchToScreen(sExitBomberman);
- End;
-End;
-
-Procedure TMainMenu.OnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
-Var
- key: Word;
-Begin
- // Der Klick auf die Buttons ;)
- If (x > 350) And (x < 610) And
- (y > 100) And (y < 100 + 7 * 37) Then Begin
- fCursorPos := (y - 100) Div 37;
- key := VK_RETURN;
- OnKeyDown(Nil, key, []);
- End;
-End;
-
-Constructor TMainMenu.Create(Owner: TObject);
-Begin
- Inherited Create(Owner);
- fBackFile := 'mainmenu.png';
- fSoundFile := 'mainmenu_sound.wav';
- fCursorFile := 'mainmenu_cursor.ani';
- fCursor := TOpenGL_Animation.Create;
-End;
-
-Destructor TMainMenu.Destroy;
-Begin
- fCursor.Free;
- Inherited Destroy;
-End;
-
-Procedure TMainMenu.LoadFromDisk(ResPath: String);
-Begin
- Inherited LoadFromDisk(ResPath);
- fCursor.LoadFromFile(ResPath + fCursorFile);
-End;
-
-Procedure TMainMenu.Render;
-Begin
- Inherited Render;
- glPushMatrix();
- glTranslatef(310, 100 + fCursorPos * 37, atomic_Map_Layer + atomic_EPSILON);
- fCursor.Render(0);
- glPopMatrix();
-End;
-
-Procedure TMainMenu.Reset;
-Begin
- Inherited Reset;
- fCursorPos := 0;
-End;
-
-{ TScreen }
-
-Procedure TScreen.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
-Begin
- // Nichts nur zum Überscheiben da..
-End;
-
-Procedure TScreen.OnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
-Begin
- // Nichts nur zum Überscheiben da..
-End;
-
-Constructor TScreen.Create(Owner: TObject);
-Begin
- fOwner := Owner;
- If Not (fOwner Is TGame) Then Begin
- Raise exception.Create('Error, Owner has to be TAtomic!');
- End;
- fBackFile := '';
- fSoundFile := '';
- fBackTex := 0;
-End;
-
-Destructor TScreen.Destroy;
-Begin
- // Nix
-End;
-
-Procedure TScreen.Render;
-Begin
- (*
- * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
- *)
- glpushmatrix();
- glTranslatef(0, 0, atomic_Map_Layer);
- glColor3f(1, 1, 1);
- RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fBackTex);
- glpopmatrix();
-End;
-
-Procedure TScreen.LoadFromDisk(ResPath: String);
-Begin
- fSoundExitScreen := ResPath + 'menuexit.wav';
- If fSoundFile <> '' Then Begin
- fSoundFile := ResPath + fSoundFile;
- End;
- If fBackFile <> '' Then Begin
- fBackTex := OpenGL_GraphikEngine.LoadGraphik(ResPath + fBackFile, smStretch);
- End
- Else Begin
- fBackTex := 0;
- End;
-End;
-
-Procedure TScreen.Reset;
-Begin
- PlayerIsFirst := false;
- StartPLaySong();
-End;
-
-Procedure TScreen.StartPLaySong();
-Begin
- // Auf Jeden Fall soll mal die Passende Screen Musik abgespielt werden.
- If trim(fSoundFile) <> '' Then Begin
- TGame(fOwner).StartPlayingSong(fSoundFile);
- End;
-End;
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uscreens;
+
+{$MODE ObjFPC}{$H+}
+
+Interface
+
+{$I globaldefines.inc}
+
+Uses
+ Classes, SysUtils, controls, uatomic_common, uopengl_animation, uatomic_field;
+
+Type
+
+ (*
+ * Im MainMenu die diversen Screens
+ *)
+ TScreenEnum = (
+ sMainScreen // Hauptscreen
+ //, sSinglePlayer -- ??
+ , sHost // Den Gibt es gar nicht, der wird direkt auf den sJoinNetwork umgeleitet
+ , sJoinNetwork // Alle Spieler gehen zusammen in das Spiel rein
+ , sPlayerSetupRequest // Anfrage zum Wechsel in sPlayerSetup
+ , sPlayerSetup // Die Spieler dürfen sich ihre Farben "aussuchen"
+ , sEditFieldSetupRequest // Anfrage zum Einstellen der Field einstellungen
+ , sEditFieldSetup // Der Master stellt die eigenschaften des fields ein
+ , sDrawGame // Der Screen der Angezeigt wird wenn ein Unentschieden gespielt wurde
+ , sMatchStatistik // Der Screen der die Match Statistik anzeigt
+ , sVictory // Der Screen der das Wer hat gewonnen bild anzeigt
+ , sOptions // Der Optionen Dialog
+ //, sOnlineManual -- ??
+ , sExitBomberman // byby
+ );
+
+ { TScreen }
+
+ TScreen = Class
+ private
+ fOwner: TObject;
+ fBackFile: String;
+ fBackTex: Integer; // OpenGL Pointer der fBackFile
+ fSoundFile: String;
+ fSoundExitScreen: String;
+ fCursorFile: String;
+ public
+
+ PlayerIsFirst: Boolean; // Global Verfügbar, True, wenn der Spieler "Spieler 1" ist !
+
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); virtual;
+ Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
+
+ Constructor Create(Owner: TObject); virtual;
+ Destructor Destroy(); override;
+
+ Procedure Render; virtual;
+ Procedure LoadFromDisk(ResPath: String); virtual;
+
+ Procedure Reset; virtual; // Abstract
+ Procedure StartPLaySong(); virtual;
+ End;
+
+ { TMainMenu }
+
+ TMainMenu = Class(TScreen)
+ private
+ fCursor: TOpenGL_Animation;
+ fCursorPos: integer; // Position der "Bombe" in Menüpunkten
+ public
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+ Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+
+ Constructor Create(Owner: TObject); override;
+ Destructor Destroy(); override;
+
+ Procedure LoadFromDisk(ResPath: String); override;
+ Procedure Render; override;
+ Procedure Reset; override;
+ End;
+
+ { TJoinMenu }
+
+ TJoinMenu = Class(TScreen)
+ private
+ fPlayerInfoString: String; // Die Spieler die Gerade auch eingewählt sind.
+ fServerIP: String; // Server IP address (for display when hosting)
+
+ public
+ Connected: Boolean;
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+
+ Constructor Create(Owner: TObject); override;
+ Procedure LoadPlayerdata(Const PlayerData: Array Of TPlayer);
+ Procedure SetServerIP(Const IP: String); // Set server IP address for display
+ Procedure Render; override;
+ Procedure Reset; override;
+ End;
+
+ { TPlayerSetupMenu }
+
+ TPlayerSetupMenu = Class(TScreen)
+ private
+ fSchemeFile: String;
+ fcursorTex: integer;
+ fCursorPos: integer; // Position des "Kopfes" in Menüpunkten
+ fPlayerDetails: Array[0..length(PlayerColors) - 1] Of Record
+ Team: Integer;
+ PlayerData: String;
+ End;
+ public
+ TeamPlay: Boolean; // True = Anzeigen der Spielerfarben als Team wird via "miSwitchToPlayerSetup" gesetzt
+
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+ // TODO: Maus Support
+
+ Constructor Create(Owner: TObject); override;
+
+ Procedure LoadScheme(Const Scheme: TScheme); // Wird via miUpdateScheme gesetzt
+ Procedure LoadPlayerdata(Const PlayerData: TPlayers; Uid: Integer); // wird via TAtomic.SwitchToScreen gesetzt
+
+ Procedure LoadFromDisk(ResPath: String); override;
+
+ Procedure Render; override;
+ Procedure Reset; override;
+ End;
+
+ { TFieldSetupMenu }
+
+ TFieldSetupMenu = Class(TScreen)
+ private
+ fCursorPos: integer;
+ fcursorTex: Integer;
+ public
+ MasterPlayerName: String;
+ ActualField: TAtomicField;
+ LastWinsToWinMatch: Integer;
+ SchemeFile: String;
+
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+
+ Constructor Create(Owner: TObject); override;
+
+ Procedure LoadFromDisk(ResPath: String); override;
+ Procedure Render; override;
+ Procedure Reset; override;
+ End;
+
+ { TDrawGameMenu }
+
+ TDrawGameMenu = Class(TScreen)
+ private
+ public
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+
+ Constructor Create(Owner: TObject); override;
+
+ Procedure Reset; override;
+ End;
+
+ { TMatchStatistikMenu }
+
+ TMatchStatistikMenu = Class(TScreen)
+ private
+ fPlayers: TPlayers;
+ public
+ Victor: TVictor;
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+
+ Procedure LoadPlayerdata(Const PlayerData: TPlayers);
+
+ Constructor Create(Owner: TObject); override;
+
+ Procedure Render; override;
+
+ End;
+
+ { TVictoryMenu }
+
+ TVictoryMenu = Class(TScreen)
+ private
+ fbackGrounds: Array[TVictor] Of Integer;
+ public
+ Victor: TVictor;
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+
+ Procedure LoadFromDisk(ResPath: String); override;
+
+ Procedure Render; override;
+ Constructor Create(Owner: TObject); override;
+ End;
+
+ { TOptionsMenu }
+
+ TOptionsMenu = Class(TScreen)
+ private
+ fcursorTex: integer;
+ fCursorPos: integer; // Position des "Kopfes" in Menüpunkten
+ public
+ Procedure OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState); override;
+ Procedure OnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+
+ Constructor Create(Owner: TObject); override;
+
+ Procedure LoadFromDisk(ResPath: String); override;
+ Procedure Render; override;
+ Procedure Reset; override;
+ End;
+
+Implementation
+
+Uses LCLType, Math, Graphics, Dialogs, forms, StdCtrls, fileutil, StrUtils
+ , dglOpenGL
+ , Unit1 // WTF, why is this unit in here ?
+ , uopengl_graphikengine
+ , uatomicfont
+ , uvectormath
+ , ugraphics
+ , ugame
+ , ukeyboarddialog
+ , uip // For GetLocalIPs() to get server IP address
+ , sdl2 // For SDL joystick functions
+ ;
+
+Type
+
+ { TSchemQuestionForm }
+
+ TSchemQuestionForm = Class(TForm)
+ Procedure FormButton1Click(Sender: TObject);
+ Procedure FormShow(Sender: Tobject);
+ Procedure ListboxKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+ private
+ Listbox1: TListbox;
+ Button1: TButton;
+ public
+ Procedure LoadSchemes(SelectedScheme: String);
+ // Weil die Form keine Ressource hat, muss sie mittels CreateNew erzeugt werden, was auch immer das für einen unterschied macht ...
+ Constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+ End;
+
+ { TJoinQuestionForm }
+
+ TJoinQuestionForm = Class(TForm)
+ private
+ Edit1: TEdit;
+ Edit2: TEdit;
+ Label1: TLabel;
+ Label2: TLabel;
+ Button1: TButton;
+ Button2: TButton;
+ Procedure EditKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+ Procedure FormKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+ public
+ Constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+ End;
+
+ { TJoinQuestionForm }
+
+Constructor TJoinQuestionForm.CreateNew(AOwner: TComponent; Num: Integer);
+Begin
+ Inherited CreateNew(AOwner, Num);
+ caption := 'Enter IP-Settings';
+ width := 312;
+ height := 163;
+ Position := poScreenCenter;
+ Constraints.MaxWidth := Width;
+ Constraints.MinWidth := Width;
+ Constraints.MaxHeight := Height;
+ Constraints.MinHeight := Height;
+
+ Edit1 := TEdit.Create(self);
+ edit1.name := 'Edit1';
+ edit1.Parent := self;
+ edit1.Top := 32;
+ edit1.Left := 16;
+ edit1.Width := 288;
+ edit1.Text := '127.0.0.1';
+
+ Edit2 := TEdit.Create(self);
+ edit2.name := 'Edit2';
+ edit2.Parent := self;
+ edit2.Top := 88;
+ edit2.Left := 16;
+ edit2.Width := 288;
+ edit2.Text := '9876';
+
+ label1 := TLabel.Create(self);
+ label1.Name := 'Label1';
+ label1.Parent := self;
+ label1.caption := 'IP';
+ label1.top := 8;
+ label1.Left := 8;
+
+ label2 := TLabel.Create(self);
+ label2.Name := 'Label2';
+ label2.Parent := self;
+ label2.caption := 'Port';
+ label2.top := 64;
+ label2.Left := 8;
+
+ Button1 := TButton.Create(self);
+ Button1.Name := 'Button1';
+ Button1.Parent := self;
+ Button1.caption := 'OK';
+ Button1.ModalResult := mrOK;
+ Button1.Default := True; // Make Enter key trigger this button (when focus is on button)
+ Button1.Top := 128;
+ Button1.Left := 229;
+
+ Button2 := TButton.Create(self);
+ Button2.Name := 'Button2';
+ Button2.Parent := self;
+ Button2.caption := 'Cancel';
+ Button2.ModalResult := mrCancel;
+ Button2.Cancel := True; // Make Esc key trigger this button
+ Button2.Top := 128;
+ Button2.Left := 16;
+
+ // Add keyboard support: Enter = OK everywhere
+ // Set handlers on Edit fields to catch Enter when focus is in Edit
+ Edit1.OnKeyDown := @EditKeyDown;
+ Edit2.OnKeyDown := @EditKeyDown;
+ // Set handler on form to catch Enter when focus is on form (not on Edit or Button)
+ OnKeyDown := @FormKeyDown;
+ KeyPreview := True; // Enable form-level key handling
+End;
+
+Procedure TJoinQuestionForm.EditKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+Begin
+ If key = VK_RETURN Then Begin
+ // Enter in Edit field = OK button
+ // Strategy: Set focus to OK button, then trigger it programmatically
+ Key := 0; // Prevent default behavior (newline in Edit)
+ Button1.SetFocus; // Focus the OK button first
+ // Now trigger the button click programmatically
+ Button1.Click; // This will set ModalResult := mrOK and close the form
+ End;
+ // Esc is handled automatically by Button2.Cancel := True
+End;
+
+Procedure TJoinQuestionForm.FormKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+Begin
+ If key = VK_RETURN Then Begin
+ // Enter on form (when focus is NOT on Button1) = OK button
+ // Strategy: Set focus to OK button, then trigger it programmatically
+ If ActiveControl <> Button1 Then Begin
+ Key := 0; // Prevent default behavior
+ Button1.SetFocus; // Focus the OK button first
+ // Now trigger the button click programmatically
+ Button1.Click; // This will set ModalResult := mrOK and close the form
+ End;
+ // If focus is on Button1, let default behavior (Default := True) handle it
+ End;
+ // Esc is handled automatically by Button2.Cancel := True
+End;
+
+{ TVictoryMenu }
+
+Procedure TVictoryMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If (key = VK_RETURN) Or (key = VK_ESCAPE) Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ TGame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+End;
+
+Procedure TVictoryMenu.LoadFromDisk(ResPath: String);
+Begin
+ Inherited LoadFromDisk(ResPath);
+ fbackGrounds[vWhiteTeam] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'team0.png', smStretch);
+ fbackGrounds[vRedTeam] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'team1.png', smStretch);
+ fbackGrounds[vCol0] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory0.png', smStretch);
+ fbackGrounds[vCol1] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory1.png', smStretch);
+ fbackGrounds[vCol2] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory2.png', smStretch);
+ fbackGrounds[vCol3] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory3.png', smStretch);
+ fbackGrounds[vCol4] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory4.png', smStretch);
+ fbackGrounds[vCol5] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory5.png', smStretch);
+ fbackGrounds[vCol6] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory6.png', smStretch);
+ fbackGrounds[vCol7] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory7.png', smStretch);
+ fbackGrounds[vCol8] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory8.png', smStretch);
+ fbackGrounds[vCol9] := OpenGL_GraphikEngine.LoadGraphik(ResPath + 'victory9.png', smStretch);
+End;
+
+Procedure TVictoryMenu.Render;
+Begin
+ fBackTex := fbackGrounds[Victor];
+ Inherited Render;
+End;
+
+Constructor TVictoryMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fSoundFile := 'draw.wav';
+End;
+
+{ TMatchStatistikMenu }
+
+Procedure TMatchStatistikMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If key = VK_ESCAPE Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ TGame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+ If PlayerIsFirst Then Begin
+ If key = VK_RETURN Then Begin
+ TGame(fOwner).StartGame();
+ End;
+ End;
+End;
+
+Procedure TMatchStatistikMenu.LoadPlayerdata(Const PlayerData: TPlayers);
+Begin
+ fPlayers := PlayerData;
+End;
+
+Constructor TMatchStatistikMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'results.png';
+ fSoundFile := 'draw.wav';
+End;
+
+Procedure TMatchStatistikMenu.Render;
+
+ Function VictorToString(Value: TVictor): String;
+ Var
+ index: integer;
+ Begin
+ Case Value Of
+ vRedTeam: result := 'Red Team';
+ vWhiteTeam: result := 'White Team';
+ Else Begin
+ index := integer(value) - integer(vCol0);
+ result := fPlayers[index].UserName;
+ If result = '' Then
+ result := 'Ai';
+ End;
+ End;
+ End;
+
+Var
+ s, un: String;
+ i: Integer;
+Begin
+ Inherited Render;
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_Map_Layer + 0.5);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glColor4f(1, 1, 1, 1);
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Color := $00A8ADAB;
+ AtomicFont.Textout(150, 100, '(Match winner must score ' + inttostr(TGame(fOwner).Settings.LastWinsToWinMatch) + ' victories)');
+ s := 'Game Winner was ' + VictorToString(Victor) + ' !';
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Color := clwhite;
+ AtomicFont.Textout(150, 150, s);
+ glPushMatrix;
+ glTranslatef(130, 200, 0);
+ For i := 0 To high(fPlayers) Do Begin
+ If fPlayers[i].UID <> NoPlayer Then Begin
+ If i = 1 Then Begin
+ AtomicFont.BackColor := clWhite;
+ End
+ Else Begin
+ AtomicFont.BackColor := clBlack;
+ End;
+ AtomicFont.Color := AtomicPlayerColorToColor(PlayerColors[i]);
+ un := fPlayers[i].UserName;
+ If un = '' Then un := 'Ai';
+ un := PadRight(un, 20);
+ s := format('%s: score: %d (kills: %d)', [un, fPlayers[i].Score, fPlayers[i].Kills]);
+ AtomicFont.Textout(0, 0, s);
+ glTranslatef(0, 20, 0);
+ End;
+ End;
+ glPopMatrix;
+ AtomicFont.BackColor := clBlack; // Reset nach außen
+ glPopMatrix;
+End;
+
+{ TDrawGameMenu }
+
+Procedure TDrawGameMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If key = VK_ESCAPE Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+ If PlayerIsFirst Then Begin
+ If key = VK_RETURN Then Begin
+ TGame(fOwner).StartGame;
+ End;
+ End;
+End;
+
+Constructor TDrawGameMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'draw.png'; // WTF, warum geht das net als PNG ?
+ fSoundFile := 'draw.wav';
+ fCursorFile := '';
+End;
+
+Procedure TDrawGameMenu.Reset;
+Begin
+ Inherited Reset;
+End;
+
+{ TSchemQuestionForm }
+
+Constructor TSchemQuestionForm.CreateNew(AOwner: TComponent; Num: Integer);
+Begin
+ Inherited CreateNew(AOwner, Num);
+ caption := 'Please select a scheme';
+ Width := 350;
+ height := 350;
+ FormStyle := fsSystemStayOnTop;
+ Constraints.MinHeight := height;
+ Constraints.MaxHeight := height;
+ Constraints.MinWidth := Width;
+ Constraints.MaxWidth := Width;
+ BorderIcons := [biSystemMenu];
+ position := poScreenCenter;
+ Button1 := TButton.Create(self);
+ button1.name := 'Button1';
+ Button1.Parent := self;
+ Button1.Align := alBottom;
+ button1.caption := 'OK';
+ button1.OnClick := @FormButton1Click;
+ Listbox1 := TListBox.Create(self);
+ Listbox1.Name := 'Listbox1';
+ Listbox1.Parent := self;
+ Listbox1.Align := alClient;
+ Listbox1.OnKeyDown := @ListboxKeyDown;
+
+ OnShow := @FormShow;
+End;
+
+Procedure TSchemQuestionForm.FormButton1Click(Sender: TObject);
+Begin
+ If Listbox1.ItemIndex <> -1 Then Begin
+ ModalResult := mrOK;
+ End
+ Else Begin
+ ModalResult := mrCancel; // Anscheinend haben wir keine Scheme files, dann versuchen wir auch nicht sie zu speichern
+ End;
+End;
+
+Procedure TSchemQuestionForm.FormShow(Sender: Tobject);
+Begin
+ Listbox1.SetFocus;
+ (*
+ * Die TopRow Eigenschaft darf erst gesetzt werden, wenn die Listbox dabei ist sich zu zeichnen
+ * im LoadSchemes geht das nicht ..
+ *)
+ If Listbox1.ItemIndex <> -1 Then Begin
+ Listbox1.TopIndex := Listbox1.ItemIndex;
+ End;
+End;
+
+Procedure TSchemQuestionForm.ListboxKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If key = VK_RETURN Then Begin
+ key := 0; // Den Key Löschen, da der Button1.Click das Formular Platt macht und der Key sonst in TScreen nochmal ausgewertet wird.
+ button1.Click;
+ End;
+ If key = VK_ESCAPE Then ModalResult := mrCancel;
+End;
+
+Procedure TSchemQuestionForm.LoadSchemes(SelectedScheme: String);
+Var
+ p: String;
+ sl: TStringList;
+ i: Integer;
+Begin
+ p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'data' + PathDelim + 'schemes';
+ sl := FindAllfiles(p, '*.sch', false);
+ Listbox1.Clear;
+ Listbox1.Sorted := true;
+ For i := 0 To sl.Count - 1 Do Begin
+ Listbox1.Items.Add(ExtractFileName(sl[i]));
+ End;
+ For i := 0 To Listbox1.Items.Count - 1 Do Begin
+ If lowercase(SelectedScheme) = lowercase(Listbox1.Items[i]) Then Begin
+ Listbox1.ItemIndex := i;
+ break;
+ End;
+ End;
+ sl.free;
+End;
+
+{ TFieldSetupMenu }
+
+Procedure TFieldSetupMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If key = VK_ESCAPE Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ TGame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+ If PlayerIsFirst Then Begin
+ If key = VK_RETURN Then Begin
+ TGame(fOwner).StartGame;
+ End;
+ If key = VK_DOWN Then Begin
+ fCursorPos := min(fCursorPos + 1, 1);
+ End;
+ If key = VK_UP Then Begin
+ fCursorPos := max(fCursorPos - 1, 0);
+ End;
+ If key = VK_LEFT Then Begin
+ Case fCursorPos Of
+ 0: TGame(fOwner).UpdateSelectedField(-1);
+ 1: TGame(fOwner).UpdateWinsToWin(-1);
+ End;
+ End;
+ If key = VK_Right Then Begin
+ Case fCursorPos Of
+ 0: TGame(fOwner).UpdateSelectedField(1);
+ 1: TGame(fOwner).UpdateWinsToWin(1);
+ End;
+ End;
+ End;
+End;
+
+Constructor TFieldSetupMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ ActualField := Nil;
+ fBackFile := 'fieldsetup.png'; // WTF, warum geht das net als PNG ?
+ fSoundFile := 'player_setup_sound.wav';
+ fCursorFile := 'options_cursor.png';
+End;
+
+Procedure TFieldSetupMenu.LoadFromDisk(ResPath: String);
+Begin
+ Inherited LoadFromDisk(ResPath);
+ (*
+ * Neu Laden der Hintergrundgraphik mit Transparenz
+ *)
+ OpenGL_GraphikEngine.RemoveGraphik(fBackTex);
+ fBackTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fBackFile, ColorToRGB(clfuchsia), smStretchHard);
+ fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
+End;
+
+Procedure TFieldSetupMenu.Render;
+Begin
+ // Das Vorschaubild
+ glColor4f(1, 1, 1, 1);
+ // Der Eigentliche Hintergrund
+ glpushmatrix();
+ glAlphaFunc(GL_LESS, 0.5);
+ // Das ist ja eine Textur mit "Fenster" -> Also Alphatest mit an
+ glEnable(GL_ALPHA_TEST);
+ glTranslatef(0, 0, atomic_Map_Layer + 0.5);
+ RenderAlphaQuad(v2(320, 240), GameWidth, -GameHeight, 0, fBackTex);
+ gldisable(GL_ALPHA_TEST);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glpopmatrix();
+ If assigned(ActualField) Then Begin
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ If ActualField.Name = '' Then Begin
+ AtomicFont.Textout(55, 176, 'Random Each Game');
+ End
+ Else Begin
+ AtomicFont.Textout(55, 176, ActualField.Name);
+ End;
+ End
+ Else Begin
+ AtomicFont.Color := clRed;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(55, 176, 'No Field informations...');
+ End;
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(55, 176 + 28, inttostr(LastWinsToWinMatch) + ' Wins to win match');
+ If PlayerIsFirst Then Begin
+ glPushMatrix();
+ glTranslatef(20, 176 - 14 + 28 * fCursorPos, atomic_Map_Layer + 0.5 + atomic_EPSILON);
+ RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
+ glPopMatrix();
+ End
+ Else Begin
+ AtomicFont.Color := clYellow;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(45, 176 - 28 - 28, 'Wait until ' + MasterPlayerName + LineEnding + 'finished setup.');
+ End;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(60, 400, 'Scheme: ' + SchemeFile);
+ (*
+ * Das Eigentliche Kartenvorschau Fenster
+ *)
+ glpushmatrix();
+ glTranslatef(379, 33, 0); // Das Offset zum Vorschaufenster ;)
+ If assigned(ActualField) Then Begin
+ ActualField.RenderPreview;
+ End;
+ glpopmatrix();
+End;
+
+Procedure TFieldSetupMenu.Reset;
+Begin
+ Inherited Reset;
+ MasterPlayerName := '';
+ fCursorPos := 0;
+End;
+
+{ TPlayerSetupMenu }
+
+Procedure TPlayerSetupMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Begin
+ If key = VK_RETURN Then Begin
+ If PlayerIsFirst Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sEditFieldSetupRequest);
+ End;
+ End;
+ If key = VK_ESCAPE Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+ If key = VK_DOWN Then Begin
+ fCursorPos := min(fCursorPos + 1, length(PlayerColors) - 1);
+ End;
+ If key = VK_UP Then Begin
+ fCursorPos := max(fCursorPos - 1, 0);
+ End;
+ If key = VK_LEFT Then Begin
+ Tgame(fOwner).ChangePLayerKey(fCursorPos, -1);
+ End;
+ If key = VK_RIGHT Then Begin
+ Tgame(fOwner).ChangePLayerKey(fCursorPos, 1);
+ End;
+End;
+
+Constructor TPlayerSetupMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'join.png';
+ fSoundFile := 'player_setup_sound.wav';
+ fCursorFile := 'options_cursor.png';
+End;
+
+Procedure TPlayerSetupMenu.LoadScheme(Const Scheme: TScheme);
+Var
+ i: Integer;
+Begin
+ fSchemeFile := Scheme.Filename;
+ (*
+ * Für das Playersetup ist nur die "TEAM" Verteilung relevant / interessant
+ *)
+ For i := 0 To high(fPlayerDetails) Do Begin
+ fPlayerDetails[i].Team := Scheme.PlayerStartPositions[i].Team;
+ End;
+End;
+
+Procedure TPlayerSetupMenu.LoadPlayerdata(Const PlayerData: TPlayers;
+ Uid: Integer);
+Var
+ i: Integer;
+Begin
+ (*
+ * Siehe TPlayer.UID
+ *)
+ For i := 0 To high(fPlayerDetails) Do Begin
+ // Always show the input method label for ks0/ks1/ksJoy1/ksJoy2; OFF/AI for special states
+ If PlayerData[i].UID = NoPlayer Then Begin
+ fPlayerDetails[i].PlayerData := 'OFF';
+ End
+ Else If PlayerData[i].UID = AIPlayer Then Begin
+ fPlayerDetails[i].PlayerData := 'AI';
+ End
+ Else Begin
+ // Player assigned; display the control mapping label (keyboard, game controller, or joystick)
+ fPlayerDetails[i].PlayerData := TGame(fOwner).GetKeySetDisplayName(PlayerData[i].Keyboard);
+ End;
+ End;
+End;
+
+Procedure TPlayerSetupMenu.LoadFromDisk(ResPath: String);
+Begin
+ Inherited LoadFromDisk(ResPath);
+ fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
+End;
+
+Procedure TPlayerSetupMenu.Render;
+Var
+ i, numJoy, joyIndex: Integer;
+ s: String;
+ joyName: PAnsiChar;
+Begin
+ Inherited Render;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(60, 37 + 40, 'Available players:');
+ For i := 0 To high(fPlayerDetails) Do Begin
+ If i = 1 Then Begin
+ AtomicFont.BackColor := clWhite;
+ End
+ Else Begin
+ AtomicFont.BackColor := clBlack;
+ End;
+ AtomicFont.Color := AtomicPlayerColorToColor(PlayerColors[i]);
+ s := format('Player %0.2d: ', [i + 1]);
+ AtomicFont.Textout(60 + 20, 37 + (i + 1) * 28 + 50, s);
+ If TeamPlay Then Begin
+ (*
+ * Im Teamplay Färben wir den Detail Text in der teamfarbe ein
+ *)
+ If fPlayerDetails[i].Team = TeamIndexWhite Then Begin
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ End
+ Else Begin
+ AtomicFont.Color := clRed;
+ AtomicFont.BackColor := clBlack;
+ End;
+ End;
+ s := format(' %s', [fPlayerDetails[i].PlayerData]);
+ AtomicFont.Textout(60 + 20, 37 + (i + 1) * 28 + 50, s);
+ End;
+
+ // Display available joysticks on the right side (moved left, formatted on multiple lines)
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(300, 37 + 40, 'Available Joysticks:');
+ try
+ If Assigned(SDL_NumJoysticks) Then Begin
+ numJoy := SDL_NumJoysticks();
+ For joyIndex := 0 To numJoy - 1 Do Begin
+ try
+ // Display "Joy X" on one line
+ s := format('Joy %d', [joyIndex + 1]);
+ AtomicFont.Textout(300 + 20, 37 + (joyIndex * 2 + 2) * 28 + 50, s);
+ // Display controller name on next line
+ If Assigned(SDL_JoystickNameForIndex) Then Begin
+ joyName := SDL_JoystickNameForIndex(joyIndex);
+ If Assigned(joyName) Then Begin
+ s := String(joyName);
+ End
+ Else Begin
+ s := 'Unknown';
+ End;
+ End
+ Else Begin
+ s := 'Unknown';
+ End;
+ AtomicFont.Textout(300 + 20, 37 + (joyIndex * 2 + 3) * 28 + 50, s);
+ except
+ // On error, still show "Joy X"
+ s := format('Joy %d', [joyIndex + 1]);
+ AtomicFont.Textout(300 + 20, 37 + (joyIndex * 2 + 2) * 28 + 50, s);
+ end;
+ End;
+ End;
+ except
+ // SDL not loaded or error, don't display joysticks
+ end;
+
+ // Reset am ende
+ AtomicFont.Color := clwhite;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(60, 400, 'Scheme: ' + fSchemeFile);
+ glPushMatrix();
+ glTranslatef(60 - 32 + 10, 37 + 14 + 28 * fCursorPos + 50, atomic_Map_Layer + atomic_EPSILON);
+ RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
+ glPopMatrix();
+End;
+
+Procedure TPlayerSetupMenu.Reset;
+Begin
+ Inherited Reset;
+ fCursorPos := 0;
+End;
+
+{ TJoinMenu }
+
+Procedure TJoinMenu.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState
+ );
+Begin
+ If (key = VK_ESCAPE) Or (key = VK_BACK) Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sMainScreen);
+ End;
+ If key = VK_RETURN Then Begin // Alle Clients sind da -> Ab in den Spieler Config Dialog..
+ If PlayerIsFirst Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sPlayerSetupRequest);
+ End;
+ End;
+End;
+
+Constructor TJoinMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'join.png';
+ fSoundFile := 'join_sound.wav';
+ fCursorFile := '';
+ fServerIP := '';
+End;
+
+Procedure TJoinMenu.LoadPlayerdata(Const PlayerData: Array Of TPlayer);
+Var
+ i: Integer;
+Begin
+ fPlayerInfoString := 'Connected network players:' + LineEnding + LineEnding;
+ For i := 0 To high(PlayerData) Do Begin
+ If PlayerData[i].UID <> NoPlayer Then Begin
+ fPlayerInfoString := fPlayerInfoString + ' ' + PlayerData[i].UserName + LineEnding;
+ End;
+ End;
+End;
+
+Procedure TJoinMenu.SetServerIP(Const IP: String);
+Begin
+ fServerIP := IP;
+End;
+
+Procedure TJoinMenu.Render;
+Var
+ serverInfo: String;
+Begin
+ Inherited Render;
+ glPushMatrix;
+ glColor3f(1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ AtomicFont.color := $00EAE556;
+ AtomicFont.BackColor := clBlack;
+ AtomicFont.Textout(100, 50, 'Our Nodename is: ''' + Tgame(fOwner).Settings.NodeName + '''');
+
+ // Display server IP address if available (when hosting)
+ If fServerIP <> '' Then Begin
+ serverInfo := 'Server IP: ' + fServerIP + ':' + Tgame(fOwner).Settings.Router_Port;
+ AtomicFont.color := clLime; // Green color for server IP
+ AtomicFont.Textout(100, 75, serverInfo);
+ End;
+
+ If Connected Then Begin
+ // Der Server hat unseren Login Versuch Grundsätzlich aktzeptiert
+ // Wir zeigen nun die Infos der Spieler an, bis der 1. Spieler in den Nächsten Screen umschaltet
+ AtomicFont.color := clWhite;
+ AtomicFont.Textout(120, 100, fPlayerInfoString);
+ End
+ Else Begin
+ AtomicFont.color := clYellow;
+ AtomicFont.Textout(120, 100, 'Waiting for server to host a game..');
+ End;
+ glPopMatrix;
+End;
+
+Procedure TJoinMenu.Reset;
+Begin
+ Inherited Reset;
+ Connected := false;
+ fPlayerInfoString := 'waiting for playerlist from server..';
+End;
+
+{ TOptionsMenu }
+
+Procedure TOptionsMenu.OnKeyDown(Sender: TObject; Var Key: Word;
+ Shift: TShiftState);
+Var
+ kd: TKeyboardDialog;
+ qf: TSchemQuestionForm;
+ nn: String;
+Begin
+ // Zurück ins Hauptmenü
+ If (key = VK_ESCAPE) Or (key = VK_BACK) Then Begin
+ Tgame(fOwner).PlaySoundEffect(fSoundExitScreen);
+ Tgame(fOwner).SwitchToScreen(sMainScreen);
+ Form1.IniPropStorage1SavingProperties(Nil);
+ End;
+ If key = VK_DOWN Then Begin
+ fCursorPos := min(fCursorPos + 1, 11);
+ End;
+ If key = VK_UP Then Begin
+ fCursorPos := max(fCursorPos - 1, 0);
+ End;
+ If (key = VK_RETURN) Or (Key = VK_ADD) Or (key = VK_SUBTRACT)
+ Or (Key = VK_LEFT) Or (Key = VK_RIGHT) Then Begin
+ Case fCursorPos Of
+ 0: Tgame(fOwner).Settings.TeamPlay := Not Tgame(fOwner).Settings.TeamPlay;
+ 1: Tgame(fOwner).Settings.RandomStart := Not Tgame(fOwner).Settings.RandomStart;
+ 2: Begin
+ key := 0;
+ nn := InputBox('Edit', 'Enter Nodename', Tgame(fOwner).Settings.NodeName);
+ If trim(nn) <> '' Then Begin
+ Tgame(fOwner).Settings.NodeName := nn;
+ End
+ Else Begin
+ LogShow('Empty username not allowed', llWarning);
+ End;
+ End;
+ 3: Begin
+ If key In [VK_RETURN, VK_ADD, VK_RIGHT] Then Begin
+ Case Tgame(fOwner).Settings.ConveyorSpeed Of
+ csSlow: Tgame(fOwner).Settings.ConveyorSpeed := csMiddle;
+ csMiddle: Tgame(fOwner).Settings.ConveyorSpeed := csFast;
+ csFast: Tgame(fOwner).Settings.ConveyorSpeed := csSlow;
+ End;
+ End
+ Else Begin
+ Case Tgame(fOwner).Settings.ConveyorSpeed Of
+ csSlow: Tgame(fOwner).Settings.ConveyorSpeed := csFast;
+ csMiddle: Tgame(fOwner).Settings.ConveyorSpeed := csSlow;
+ csFast: Tgame(fOwner).Settings.ConveyorSpeed := csMiddle;
+ End;
+ End;
+ End;
+ 4: Begin // Scheme File
+ key := 0;
+ qf := TSchemQuestionForm.CreateNew(Nil);
+ qf.LoadSchemes(Tgame(fOwner).Settings.SchemeFile);
+ qf.ShowModal;
+ If qf.ModalResult = mrOK Then Begin
+ Tgame(fOwner).Settings.SchemeFile := qf.Listbox1.Items[qf.Listbox1.ItemIndex];
+ End;
+ qf.free;
+ End;
+ 5: Begin // Play Time
+ If key In [VK_LEFT, VK_SUBTRACT] Then Begin
+ Tgame(fOwner).Settings.PlayTime := max(0, Tgame(fOwner).Settings.PlayTime - 15);
+ If Tgame(fOwner).Settings.PlayTime < 80 Then Tgame(fOwner).Settings.PlayTime := 0;
+ End
+ Else Begin
+ If Tgame(fOwner).Settings.PlayTime = 0 Then Begin
+ Tgame(fOwner).Settings.PlayTime := 90;
+ End
+ Else Begin
+ Tgame(fOwner).Settings.PlayTime := Tgame(fOwner).Settings.PlayTime + 15;
+ End;
+ End;
+ End;
+ 6: Tgame(fOwner).Settings.LostPlayersRevertToAI := Not Tgame(fOwner).Settings.LostPlayersRevertToAI;
+ 7: Tgame(fOwner).Settings.PlaySounds := Not Tgame(fOwner).Settings.PlaySounds;
+ 8: Begin
+ key := 0;
+ kd := TKeyboardDialog.CreateNew(Nil);
+ kd.LoadKeys(Tgame(fOwner).Settings.Keys[ks0], Tgame(fOwner).Settings.Keys[ks1]);
+ If kd.Execute() Then Begin
+ Tgame(fOwner).Settings.Keys[ks0] := kd.GetKeys(ks0);
+ Tgame(fOwner).Settings.Keys[ks1] := kd.GetKeys(ks1);
+ End;
+ kd.Free;
+ End;
+ 9: Tgame(fOwner).Settings.Port := strtointdef(InputBox('Edit', 'Enter port', inttostr(Tgame(fOwner).Settings.Port)), 1234);
+ 10: Tgame(fOwner).Settings.ShowFPS := Not Tgame(fOwner).Settings.ShowFPS;
+ 11: Begin
+ Tgame(fOwner).Settings.Fullscreen := Not Tgame(fOwner).Settings.Fullscreen;
+ Form1.SetFullScreen(Tgame(fOwner).Settings.Fullscreen);
+{$IFDEF Windows}
+ If Tgame(fOwner).Settings.Fullscreen Then Begin
+ LogShow('To switch to Fullscreen mode, you need to restart the game.');
+ End;
+{$ENDIF}
+ End;
+ End;
+ End;
+End;
+
+Procedure TOptionsMenu.OnMouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+Var
+ key: Word;
+Begin
+ // Der Klick auf die Buttons ;)
+ If (x > 60) And (x < 320) And
+ (y > 36) And
+ (y < 36 + 12 * 28)
+ Then Begin
+ fCursorPos := (y - 36) Div 28;
+ key := VK_RETURN;
+ OnKeyDown(Nil, key, []);
+ End;
+End;
+
+Constructor TOptionsMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'options.png';
+ fSoundFile := ''; // Die Optionen haben keinen Extra "Sound"
+ fCursorFile := 'options_cursor.png';
+End;
+
+Procedure TOptionsMenu.LoadFromDisk(ResPath: String);
+Begin
+ Inherited LoadFromDisk(ResPath);
+ fcursorTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(ResPath + fCursorFile, ColorToRGB(clfuchsia), smStretch);
+End;
+
+Procedure TOptionsMenu.Render;
+ Function PrettyTime(Value_s: integer): String;
+ Begin
+ If Value_s = 0 Then Begin
+ result := 'infinity';
+ End
+ Else Begin
+ result := format('%0.2d:%0.2d', [Value_s Div 60, Value_s Mod 60]);
+ End;
+ End;
+
+ Function ConveyerSpeedToString(aSpeed: TConveyorSpeed): String;
+ Begin
+ result := '';
+ Case aSpeed Of
+ csSlow: result := 'Slow';
+ csMiddle: result := 'Middle';
+ csFast: result := 'Fast';
+ End;
+ End;
+
+Begin
+ Inherited Render;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ AtomicFont.BackColor := clblack;
+ AtomicFont.Color := clwhite;
+ AtomicFont.Textout(60, 37,
+ 'Team Play: ' + BoolToStr(TGame(fOwner).Settings.TeamPlay, 'Yes', 'No') + LineEnding + LineEnding +
+ 'Random Start: ' + BoolToStr(TGame(fOwner).Settings.RandomStart, 'Yes', 'No') + LineEnding + LineEnding +
+ 'Node Name: ''' + TGame(fOwner).Settings.NodeName + '''' + LineEnding + LineEnding +
+ 'Conveyor Speed: ' + ConveyerSpeedToString(TGame(fOwner).Settings.ConveyorSpeed) + LineEnding + LineEnding +
+ 'Scheme File: ' + TGame(fOwner).Settings.SchemeFile + LineEnding + LineEnding +
+ 'Play Time: ' + PrettyTime(TGame(fOwner).Settings.PlayTime) + LineEnding + LineEnding +
+ 'Lost net players revert to AIs: ' + BoolToStr(TGame(fOwner).Settings.LostPlayersRevertToAI, 'Yes', 'No') + LineEnding + LineEnding +
+ 'Disable music during gameplay: ' + BoolToStr(TGame(fOwner).Settings.PlaySounds, 'No', 'Yes') + LineEnding + LineEnding +
+ 'Define keyboard layouts' + LineEnding + LineEnding +
+ 'Network port: ' + inttostr(TGame(fOwner).Settings.Port) + LineEnding + LineEnding +
+ 'Show FPS: ' + BoolToStr(TGame(fOwner).Settings.ShowFPS, 'Yes', 'No') + LineEnding + LineEnding +
+ 'Fullscreen: ' + BoolToStr(TGame(fOwner).Settings.Fullscreen, 'Yes', 'No')
+ );
+
+ glPushMatrix();
+ glTranslatef(20, 25 + 28 * fCursorPos, atomic_Map_Layer + atomic_EPSILON);
+ RenderAlphaQuad(point(16, 16), 32, -32, 0, fcursorTex);
+ glPopMatrix();
+End;
+
+Procedure TOptionsMenu.Reset;
+Begin
+ fCursorPos := 0;
+End;
+
+{ TMainMenu }
+
+Procedure TMainMenu.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState
+ );
+Var
+ f: TJoinQuestionForm;
+Begin
+ If key = VK_J Then Begin
+ // Frage IP und Port zum Game.JoinViaParams(ip, port); ab !
+ f := TJoinQuestionForm.CreateNew(Nil, 0);
+ f.Edit1.Text := TGame(fOwner).Settings.Router_IP;
+ f.Edit2.Text := TGame(fOwner).Settings.Router_Port;
+ If f.ShowModal = mrOK Then Begin
+ TGame(fOwner).JoinViaParams(f.Edit1.Text, strtointdef(f.Edit2.Text, 9876));
+ End;
+ f.free;
+ End;
+ If key = VK_DOWN Then Begin
+ // fCursorPos := min(fCursorPos + 1, 6);
+ fCursorPos := (fCursorPos + 1) Mod 7; // Feature Request by Community, rotating navigation
+ End;
+ If key = VK_UP Then Begin
+ // fCursorPos := max(fCursorPos - 1, 0);
+ fCursorPos := (fCursorPos + 6) Mod 7; // Feature Request by Community, rotating navigation
+ End;
+ If (key >= VK_1) And (key <= VK_7) Then Begin
+ fCursorPos := key - VK_1;
+ key := VK_RETURN;
+ End;
+ If key = VK_RETURN Then Begin
+ Case fCursorPos Of
+ 0: logshow('Not yet implemented.', llinfo); // TAtomic(fOwner).SwitchToScreen(); -- Single Player
+ 1: TGame(fOwner).SwitchToScreen(sHost);
+ 2: Begin
+ // Join Network Game - open IP/Port dialog (same as pressing J)
+ f := TJoinQuestionForm.CreateNew(Nil, 0);
+ f.Edit1.Text := TGame(fOwner).Settings.Router_IP;
+ f.Edit2.Text := TGame(fOwner).Settings.Router_Port;
+ If f.ShowModal = mrOK Then Begin
+ TGame(fOwner).JoinViaParams(f.Edit1.Text, strtointdef(f.Edit2.Text, 9876));
+ End;
+ f.free;
+ End;
+ 3: TGame(fOwner).SwitchToScreen(sOptions);
+ 4: logshow('Not yet implemented.', llinfo); //TGame(fOwner).SwitchToScreen(); -- About Bomberman
+ 5: logshow('Not yet implemented.', llinfo); //TGame(fOwner).SwitchToScreen(); -- Online Manual
+ 6: Begin
+{$IFNDEF Only3Player}
+ If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then
+{$ENDIF}
+ TGame(fOwner).SwitchToScreen(sExitBomberman);
+ End;
+ End;
+ End;
+ If key = VK_ESCAPE Then Begin
+{$IFNDEF Only3Player}
+ If ID_YES = Application.MessageBox('Do you really want to quit?', 'Question', MB_ICONQUESTION Or MB_YESNO) Then
+{$ENDIF}
+ TGame(fOwner).SwitchToScreen(sExitBomberman);
+ End;
+End;
+
+Procedure TMainMenu.OnMouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+Var
+ key: Word;
+Begin
+ // Der Klick auf die Buttons ;)
+ If (x > 350) And (x < 610) And
+ (y > 100) And (y < 100 + 7 * 37) Then Begin
+ fCursorPos := (y - 100) Div 37;
+ key := VK_RETURN;
+ OnKeyDown(Nil, key, []);
+ End;
+End;
+
+Constructor TMainMenu.Create(Owner: TObject);
+Begin
+ Inherited Create(Owner);
+ fBackFile := 'mainmenu.png';
+ fSoundFile := 'mainmenu_sound.wav';
+ fCursorFile := 'mainmenu_cursor.ani';
+ fCursor := TOpenGL_Animation.Create;
+End;
+
+Destructor TMainMenu.Destroy;
+Begin
+ fCursor.Free;
+ Inherited Destroy;
+End;
+
+Procedure TMainMenu.LoadFromDisk(ResPath: String);
+Begin
+ Inherited LoadFromDisk(ResPath);
+ fCursor.LoadFromFile(ResPath + fCursorFile);
+End;
+
+Procedure TMainMenu.Render;
+Begin
+ Inherited Render;
+ glPushMatrix();
+ glTranslatef(310, 100 + fCursorPos * 37, atomic_Map_Layer + atomic_EPSILON);
+ fCursor.Render(0);
+ glPopMatrix();
+End;
+
+Procedure TMainMenu.Reset;
+Begin
+ Inherited Reset;
+ fCursorPos := 0;
+End;
+
+{ TScreen }
+
+Procedure TScreen.OnKeyDown(Sender: TObject; Var Key: Word; Shift: TShiftState);
+Begin
+ // Nichts nur zum Überscheiben da..
+End;
+
+Procedure TScreen.OnMouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+Begin
+ // Nichts nur zum Überscheiben da..
+End;
+
+Constructor TScreen.Create(Owner: TObject);
+Begin
+ fOwner := Owner;
+ If Not (fOwner Is TGame) Then Begin
+ Raise exception.Create('Error, Owner has to be TAtomic!');
+ End;
+ fBackFile := '';
+ fSoundFile := '';
+ fBackTex := 0;
+End;
+
+Destructor TScreen.Destroy;
+Begin
+ // Nix
+End;
+
+Procedure TScreen.Render;
+Begin
+ (*
+ * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
+ *)
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_Map_Layer);
+ glColor3f(1, 1, 1);
+ RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fBackTex);
+ glpopmatrix();
+End;
+
+Procedure TScreen.LoadFromDisk(ResPath: String);
+Begin
+ fSoundExitScreen := ResPath + 'menuexit.wav';
+ If fSoundFile <> '' Then Begin
+ fSoundFile := ResPath + fSoundFile;
+ End;
+ If fBackFile <> '' Then Begin
+ fBackTex := OpenGL_GraphikEngine.LoadGraphik(ResPath + fBackFile, smStretch);
+ End
+ Else Begin
+ fBackTex := 0;
+ End;
+End;
+
+Procedure TScreen.Reset;
+Begin
+ PlayerIsFirst := false;
+ StartPLaySong();
+End;
+
+Procedure TScreen.StartPLaySong();
+Begin
+ // Auf Jeden Fall soll mal die Passende Screen Musik abgespielt werden.
+ If trim(fSoundFile) <> '' Then Begin
+ TGame(fOwner).StartPlayingSong(fSoundFile);
+ End;
+End;
+
+End.
+
diff --git a/client/usounds.pas b/client/usounds.pas
index 61efc9d..f063180 100644
--- a/client/usounds.pas
+++ b/client/usounds.pas
@@ -171,7 +171,7 @@
// ggf. neu starten des Songs
If game.Settings.PlaySounds And (FileExists(Filename)) And (Filename <> '') Then Begin
// Start des Liedes in Endlosschleife
- fBassSong := BASS_StreamCreateFile(false, Pchar(filename), 0, 0, BASS_MUSIC_LOOP);
+ fBassSong := BASS_StreamCreateFile(0, Pchar(filename), 0, 0, BASS_MUSIC_LOOP);
If fBassSong = 0 Then Begin
LogShow('Error unable to load :' + LineEnding + filename + LineEnding + 'Error code :' + inttostr(BASS_ErrorGetCode), llCritical);
exit;
@@ -206,7 +206,7 @@
End;
End;
// Wir kennen den Sound noch nicht -> Aufnehmen und starten
- song := BASS_StreamCreateFile(false, Pchar(filename), 0, 0, 0);
+ song := BASS_StreamCreateFile(0, Pchar(filename), 0, 0, 0);
If Song = 0 Then Begin
LogShow('Error unable to load :' + LineEnding + filename + LineEnding + 'Error code :' + inttostr(BASS_ErrorGetCode), llCritical);
exit;
diff --git a/documentation/asset_download_preview.png b/documentation/asset_download_preview.png
index 4ac5a7b..82bfde6 100644
Binary files a/documentation/asset_download_preview.png and b/documentation/asset_download_preview.png differ
diff --git a/flyio_server/.dockerignore b/flyio_server/.dockerignore
new file mode 100644
index 0000000..155269e
--- /dev/null
+++ b/flyio_server/.dockerignore
@@ -0,0 +1,41 @@
+# .dockerignore for FPC Atomic TCP Server
+
+# macOS specific
+.DS_Store
+*.app
+app_*
+bin/
+
+# Build artifacts
+*.o
+*.ppu
+*.a
+lib/
+*.compiled
+*.or
+
+# Development
+.git/
+.gitignore
+*.log
+*.bak
+*~
+
+# IDE
+.vscode/
+.idea/
+*.lps
+
+# Test files
+test_*
+tools/packet_*
+tools/udp_*
+
+# Enet (not used for TCP)
+enet_src/
+flyio/echo_test/
+
+# Documentation
+*.md
+README*
+
diff --git a/flyio_server/Dockerfile b/flyio_server/Dockerfile
new file mode 100644
index 0000000..bbf2e72
--- /dev/null
+++ b/flyio_server/Dockerfile
@@ -0,0 +1,107 @@
+# Dockerfile for FPC Atomic TCP Server on Fly.io
+# Multi-stage build for smaller final image
+
+FROM ubuntu:22.04 AS builder
+
+WORKDIR /build
+
+# Install Lazarus and dependencies (including gcc for AI library)
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
+ fpc \
+ fp-compiler \
+ lazarus \
+ lazarus-ide-gtk2 \
+ libgtk2.0-dev \
+ build-essential \
+ gcc \
+ make \
+ && rm -rf /var/lib/apt/lists/*
+
+# Copy source code
+# Build context should be project root, not flyio_server/
+COPY server /build/server
+COPY units /build/units
+COPY client /build/client
+COPY ai /build/ai
+
+# Copy data directory
+# Note: Workflow ensures flyio_server/data exists (copies from data/ if needed)
+# If flyio_server/data doesn't exist, this will fail - but workflow should handle it
+COPY flyio_server/data /build/data
+
+# Download and setup LNet library (needed for server networking)
+# LNet is not in the repository, so we download it during build
+RUN echo "=== Downloading LNet library ===" && \
+ apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y curl unzip && \
+ lnetUrl="https://github.com/PascalCorpsman/lnet/archive/refs/heads/master.zip" && \
+ lnetZip="/tmp/lnet.zip" && \
+ lnetDir="/tmp/lnet" && \
+ curl -L -f -o "$lnetZip" "$lnetUrl" || \
+ curl -L -f -o "$lnetZip" "https://github.com/PascalCorpsman/lnet/archive/master.zip" && \
+ unzip -q "$lnetZip" -d "$lnetDir" && \
+ lnetSourceDir=$(find "$lnetDir" -type d -name "lnet-*" | head -1) && \
+ mkdir -p /build/lnet_src && \
+ if [ -d "$lnetSourceDir/lazaruspackage" ]; then \
+ cp -r "$lnetSourceDir/lazaruspackage" /build/lnet_src/; \
+ fi && \
+ if [ -d "$lnetSourceDir/lib" ]; then \
+ mkdir -p /build/lnet_src/lib && \
+ cp -r "$lnetSourceDir/lib"/* /build/lnet_src/lib/; \
+ fi && \
+ rm -rf "$lnetZip" "$lnetDir" && \
+ apt-get purge -y curl unzip && \
+ apt-get autoremove -y && \
+ echo "=== LNet library downloaded and set up ===" && \
+ ls -la /build/lnet_src/
+
+# Build AI library (Pascal version - fully functional!)
+WORKDIR /build/ai
+RUN echo "=== Building Pascal AI library ===" && \
+ cp /build/server/uai_types.pas . && \
+ cp /build/units/ufifo.pas . && \
+ fpc -Tlinux -Px86_64 -O3 -CX -XX -Xs -vw ai.lpr && \
+ mv libai.so ../libai.so && \
+ echo "=== AI library built, checking..." && \
+ ls -la ../libai.so && \
+ file ../libai.so && \
+ nm -D ../libai.so | grep -E "(AiInit|AiHandlePlayer|AiVersion)" && \
+ echo "=== Pascal AI library OK ==="
+
+# Modify .lpi to use correct search paths for Docker build and compile
+WORKDIR /build/server
+RUN sed -i 's|../../Sample/TCP_IP;../../Sample/DatenSteuerung;../units;../../Sample/Graphik;../macos/third_party/lnet/lib;../macos/third_party/lnet_src/lazaruspackage|../units;../lnet_src/lib;../lnet_src/lazaruspackage|g' atomic_server.lpi && \
+ echo "=== Building TCP server with Lazarus ===" && \
+ lazbuild --lazarusdir=/usr/lib/lazarus/default --build-mode="Default" atomic_server.lpi && \
+ mkdir -p /app && \
+ mv /build/atomic_server /app/atomic_server && \
+ mv /build/libai.so /app/libai.so && \
+ ls -la /app/atomic_server /app/libai.so && \
+ file /app/atomic_server /app/libai.so
+
+# Runtime stage
+FROM debian:bookworm-slim
+
+WORKDIR /app
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ libc6 \
+ && rm -rf /var/lib/apt/lists/*
+
+# Copy compiled server, AI library, and data directory
+COPY --from=builder /app/atomic_server /app/atomic_server
+COPY --from=builder /app/libai.so /app/libai.so
+COPY --from=builder /build/data /app/data
+
+# Make executable
+RUN chmod +x /app/atomic_server
+
+# Expose TCP port
+EXPOSE 5521/tcp
+
+# Run server
+# -p 5521 = port
+# -t 30000 = auto-shutdown after 30s with no players (for clean restart)
+# -l 2 = log level Info
+CMD ["/app/atomic_server", "-p", "5521", "-t", "30000", "-l", "2"]
+
diff --git a/flyio_server/README.cs.md b/flyio_server/README.cs.md
new file mode 100644
index 0000000..7d4bac5
--- /dev/null
+++ b/flyio_server/README.cs.md
@@ -0,0 +1,326 @@
+# Deployment FPC Atomic Server na Fly.io
+
+## 🌐 Co je Fly.io?
+
+**Fly.io** je cloudová platforma, která umožňuje spouštět aplikace na edge serverech po celém světě. Pro FPC Atomic server to znamená:
+
+- **Server mimo lokální síť** - Server běží v cloudu, takže nemusíte mít otevřený port ve vaší lokální síti
+- **Menší zátěž pro lokální síť** - Veškerý herní provoz jde přes Fly.io, ne přes vaši domácí síť
+- **Větší bezpečnost** - Nemusíte otevírat porty ve firewallu nebo routeru
+- **Každý si může vytvořit svůj server** - Každý hráč si může jednoduše vytvořit vlastní server pro sebe a své kamarády
+- **Automatické spouštění** - Server se nemusí spouštět ručně - spouští se automaticky, když se někdo připojí, a vypíná se po 30 sekundách nečinnosti
+
+## 📋 Požadavky
+
+1. **Fly.io Účet** - Vytvořte si bezplatný účet na [fly.io](https://fly.io)
+ - Přejděte na https://fly.io a zaregistrujte se (dostupný bezplatný tarif)
+ - K vytvoření účtu budete potřebovat emailovou adresu
+ - Bezplatný tarif zahrnuje 3 sdílené CPU VM a 3GB trvalého úložiště
+
+2. **Fly.io CLI** - Command Line Interface - nainstalovaný a přihlášený
+ ```bash
+ # Instalace (macOS)
+ curl -L https://fly.io/install.sh | sh
+
+ # Instalace (Linux)
+ curl -L https://fly.io/install.sh | sh
+
+ # Instalace (Windows - PowerShell)
+ powershell -Command "iwr https://fly.io/install.ps1 -useb | iex"
+
+ # Přihlášení (vyžaduje Fly.io účet)
+ flyctl auth login
+ ```
+
+2. **Git** - pro klonování repozitáře (volitelné, pokud používáte předpřipravený image)
+
+## 📋 Který deploy script použít?
+
+V repozitáři jsou dva deploy scripty:
+
+- **`deploy_prebuilt.sh`** (doporučeno) - Rychlejší varianta
+ - Používá předpřipravený Docker image z GitHub Container Registry
+ - Rychlejší (nekompiluje z source)
+ - Vyžaduje herní data (bez nich selže)
+ - Použij, pokud máš herní data a chceš rychlý deploy
+
+- **`build_and_deploy.sh`** - Pomalejší varianta
+ - Builduje server z Pascal source kódu
+ - Pomalejší (kompiluje během build procesu)
+ - Může pracovat bez herních dat (varuje, ale pokračuje)
+ - Použij, pokud chceš buildnout z aktuálního source kódu nebo nemáš herní data
+
+## 🚀 Rychlý postup
+
+### Varianta A: Deploy z předpřipraveného Docker image (doporučeno) - `deploy_prebuilt.sh`
+
+**Rychlejší varianta** - používá předpřipravený Docker image z GitHub Container Registry. Nemusíte mít nainstalovaný Pascal compiler ani Lazarus. Musíte ale přidat herní data extrahovaná z originálního CD.
+
+**⚠️ DŮLEŽITÉ: Herní data jsou vyžadována**
+
+Předpřipravený Docker image neobsahuje herní data kvůli licenčním důvodům. Musíte extrahovat data z originálního CD Atomic Bomberman a přidat je k deploymentu.
+
+1. **Extrahujte herní data:**
+ - Použijte CD Data Extractor (součást repozitáře) k extrakci dat z originálního CD
+ - Tím se vytvoří adresář `data` s mapami, zdroji a zvuky
+
+2. **Vytvořte adresář pro deployment:**
+ ```bash
+ mkdir fpc-atomic-server
+ cd fpc-atomic-server
+ ```
+
+3. **Zkopírujte herní data:**
+ ```bash
+ # Zkopírujte extrahovaný adresář data
+ cp -r /cesta/k/extrahovanym/datam .
+ ```
+
+ Adresář `data` by měl obsahovat:
+ - `maps/` - herní mapy
+ - `res/` - zdroje, textury, atd.
+ - `sounds/` - zvukové efekty
+
+4. **Naklonujte repozitář (pro získání deploy scriptu):**
+ ```bash
+ git clone https://github.com/PavelZverina/fpc_atomic_macos.git
+ cd fpc_atomic/flyio_server
+ ```
+
+5. **Zkopírujte svůj adresář data:**
+ ```bash
+ # Zkopírujte extrahovaná data do flyio_server/
+ cp -r /cesta/k/extrahovanym/datam .
+ ```
+
+6. **Deploy na Fly.io:**
+ ```bash
+ # Použijte deploy script, který přidá data k předpřipravenému image
+ ./deploy_prebuilt.sh
+ ```
+
+ **Alternativa - Ruční deployment:**
+
+ Pokud preferujete ruční deployment, můžete vytvořit vlastní Dockerfile:
+ ```dockerfile
+ FROM ghcr.io/PavelZverina/fpc-atomic-server:latest
+ COPY data /app/data
+ ```
+
+ Pak vytvořte `fly.toml`:
+ ```toml
+ app = "your-app-name-here" # Změňte to na váš unikátní název aplikace
+ primary_region = "fra"
+
+ [build]
+ dockerfile = "Dockerfile"
+
+ [env]
+ PORT = "5521"
+
+ [[services]]
+ protocol = "tcp"
+ internal_port = 5521
+ processes = ["app"]
+ auto_stop_machines = true
+ auto_start_machines = true
+ min_machines_running = 0
+
+ [[services.ports]]
+ port = 5521
+ ```
+
+ Pak deployujte:
+ ```bash
+ flyctl deploy
+ ```
+
+### Varianta B: Build z source kódu a deploy - `build_and_deploy.sh`
+
+**Pomalejší varianta** - builduje server z Pascal source kódu a pak ho deployuje. Vyžaduje Pascal compiler (ale ten je už v Dockerfile, takže nemusíte mít nic lokálně nainstalované). Může pracovat i bez herních dat (server poběží, ale bez map).
+
+**⚠️ DŮLEŽITÉ: Herní data jsou vyžadována**
+
+Před deployem musíte extrahovat herní data z originálního CD Atomic Bomberman a zkopírovat je do adresáře `flyio_server/data`.
+
+1. **Extrahujte herní data:**
+ - Použijte CD Data Extractor (součást repozitáře) k extrakci dat z originálního CD
+ - Tím se vytvoří adresář `data` s mapami, zdroji a zvuky
+
+2. **Zkopírujte data do flyio_server:**
+ ```bash
+ # Zkopírujte extrahovaný adresář data do flyio_server/
+ cp -r /cesta/k/extrahovanym/datam flyio_server/data
+ ```
+
+ Adresář `flyio_server/data` by měl obsahovat:
+ - `maps/` - herní mapy
+ - `res/` - zdroje, textury, atd.
+ - `sounds/` - zvukové efekty
+
+3. **Naklonujte repozitář:**
+ ```bash
+ git clone https://github.com/PavelZverina/fpc_atomic_macos.git
+ cd fpc_atomic
+ ```
+
+4. **Nastavte název aplikace v .env souboru:**
+
+ Vytvořte nebo upravte `.env` soubor v rootu projektu:
+ ```bash
+ # V rootu projektu (ne v flyio_server/)
+ echo "FLY_APP_NAME=fpc-atomic-tcp-server-moje-jmeno" >> .env
+ ```
+
+ **Důležité:** Název aplikace je uložen v `.env` souboru (který je v `.gitignore`), takže můžeš commitovat `fly.toml` do gitu bez odhalení svého názvu aplikace.
+
+5. **Deploy na Fly.io:**
+
+ **Nejjednodušší způsob - použijte build and deploy script:**
+ ```bash
+ cd flyio_server
+ ./build_and_deploy.sh
+ ```
+
+ **Co tento script dělá:**
+ - Builduje server z Pascal source kódu (kompilace probíhá v Docker image)
+ - Deployuje buildu na Fly.io
+ - Může pracovat bez herních dat (varuje, ale pokračuje)
+
+ **Nebo ručně:**
+ ```bash
+ # Ujistěte se, že jste v rootu projektu
+ cd /cesta/k/fpc_atomic
+
+ # První deploy (vytvoří novou aplikaci)
+ flyctl deploy --config flyio_server/fly.toml
+
+ # Nebo pokud už máte aplikaci
+ flyctl deploy --config flyio_server/fly.toml
+ ```
+
+ **Poznámka:** Build context musí být root projektu (ne `flyio_server/`), takže vždy spouštějte `flyctl deploy` z rootu projektu s `--config flyio_server/fly.toml`.
+
+ **Poznámka:** Pokud nezahrnete herní data, server se zbuildí a poběží, ale bez herních map. Budou dostupné pouze náhodné mapy.
+
+### 3. Zobrazení informací
+
+```bash
+# Zobrazit status a IP adresu
+flyctl status
+
+# Zobrazit logy
+flyctl logs
+
+# SSH do kontejneru (pro debugging)
+flyctl ssh console
+```
+
+## 📝 Co se děje při deployi?
+
+1. **Build**: Dockerfile automaticky:
+ - Zkompiluje AI knihovnu (`libai.so`) pro Linux
+ - Zkompiluje server (`atomic_server`) pro Linux
+ - Zkopíruje data adresář (obsahuje mapy a další herní data)
+
+2. **Deploy**: Fly.io:
+ - Vytvoří Docker image
+ - Spustí server na portu 5521
+ - Server se automaticky vypne po 30 sekundách nečinnosti (auto_stop_machines)
+ - Server se automaticky zapne při novém připojení (auto_start_machines)
+
+## ⚙️ Konfigurace
+
+### Port
+Server naslouchá na portu **5521** (nastaveno v `fly.toml` a `Dockerfile`).
+
+### Timeout
+Server se automaticky vypne po **30 sekundách** nečinnosti (nastaveno v `Dockerfile` jako `-t 30000`).
+
+### Region
+Defaultní region je **Frankfurt (fra)** - můžete změnit v `fly.toml`.
+
+## 🔧 Troubleshooting
+
+### Build selže
+
+1. Zkontrolujte, že všechny potřebné soubory jsou v projektu:
+ - `server/` - zdrojové kódy serveru
+ - `units/` - jednotky
+ - `macos/third_party/lnet_src/` - LNet knihovna
+ - `macos/data/` - game data
+ - `ai/` - AI knihovna
+
+2. Zkuste lokální build:
+ ```bash
+ docker build -t fpc-atomic-test .
+ ```
+
+### Server se nespustí
+
+1. Zkontrolujte logy:
+ ```bash
+ flyctl logs
+ ```
+
+2. Ověřte, že data adresář existuje a obsahuje potřebné soubory (mapy v `data/maps/`)
+
+### Připojení klientů
+
+**⚠️ DŮLEŽITÉ: Každý server má svou vlastní adresu**
+
+Každý, kdo nasadí server na fly.io, má svou vlastní unikátní adresu. Pokud více lidí použije stejný název aplikace, budou se snažit deploynout do stejné aplikace, což nebude fungovat - každý musí mít svůj vlastní účet a aplikaci.
+
+**DŮLEŽITÉ:** Před deployem změňte název aplikace v `fly.toml` na něco unikátního, například:
+```toml
+app = "fpc-atomic-tcp-server-moje-jmeno"
+```
+
+**Jak zjistit adresu serveru:**
+
+1. **DNS adresa (doporučeno):** `.fly.dev`
+ - Například: `your-app-name-here.fly.dev`
+ - Tato adresa se nemění a je spolehlivější než IP adresa
+ - Zjistíte ji z názvu aplikace v `fly.toml` nebo z:
+ ```bash
+ flyctl status
+ ```
+
+2. **IP adresa (alternativa):**
+ ```bash
+ flyctl status
+ ```
+ - IP adresa se může měnit, proto je lepší použít DNS jméno
+
+**Připojení v klientovi:**
+
+1. Stiskněte **"j"** v hlavním menu
+2. Zadejte adresu serveru:
+ - **DNS adresa:** `.fly.dev` (např. `your-app-name-here.fly.dev`)
+ - **Nebo IP adresa:** z `flyctl status`
+3. Zadejte port: **5521**
+4. Stiskněte **OK**
+
+**Alternativa - Command line parametry:**
+```bash
+./fpc_atomic -ip your-app-name-here.fly.dev -port 5521
+```
+
+## 📊 Monitoring
+
+```bash
+# Reálné logy
+flyctl logs
+
+# Status aplikace
+flyctl status
+
+# Metriky
+flyctl metrics
+```
+
+## 🔗 Užitečné odkazy
+
+- [Fly.io dokumentace](https://fly.io/docs/)
+- [Fly.io CLI reference](https://fly.io/docs/flyctl/)
+
diff --git a/flyio_server/README.md b/flyio_server/README.md
new file mode 100644
index 0000000..d7a35d2
--- /dev/null
+++ b/flyio_server/README.md
@@ -0,0 +1,324 @@
+# Deploying FPC Atomic Server to Fly.io
+
+## 🌐 What is Fly.io?
+
+**Fly.io** is a cloud platform that allows you to run applications on edge servers around the world. For FPC Atomic server, this means:
+
+- **Server outside local network** - Server runs in the cloud, so you don't need to open ports in your local network
+- **Less load on local network** - All game traffic goes through Fly.io, not through your home network
+- **Better security** - You don't need to open ports in your firewall or router
+- **Everyone can create their own server** - Each player can easily create their own server for themselves and their friends
+- **Automatic startup** - Server doesn't need to be started manually - it starts automatically when someone connects, and shuts down after 30 seconds of inactivity
+
+## 📋 Requirements
+
+1. **Fly.io Account** - Create a free account at [fly.io](https://fly.io)
+ - Go to https://fly.io and register (free tier available)
+ - You'll need an email address to create an account
+ - Free tier includes 3 shared CPU VMs and 3GB persistent storage
+
+2. **Fly.io CLI** - Command Line Interface - installed and logged in
+ ```bash
+ # Installation (macOS)
+ curl -L https://fly.io/install.sh | sh
+
+ # Installation (Linux)
+ curl -L https://fly.io/install.sh | sh
+
+ # Installation (Windows - PowerShell)
+ powershell -Command "iwr https://fly.io/install.ps1 -useb | iex"
+
+ # Login (requires Fly.io account)
+ flyctl auth login
+ ```
+
+3. **Git** - for cloning the repository (optional, if using pre-built image)
+
+## 📋 Which deploy script to use?
+
+There are two deploy scripts in the repository:
+
+- **`deploy_prebuilt.sh`** (recommended) - Faster option
+ - Uses pre-built Docker image from GitHub Container Registry
+ - Faster (doesn't compile from source)
+ - Requires game data (will fail without it)
+ - Use if you have game data and want a quick deploy
+
+- **`build_and_deploy.sh`** - Slower option
+ - Builds server from Pascal source code
+ - Slower (compiles during build process)
+ - Can work without game data (warns but continues)
+ - Use if you want to build from current source code or don't have game data
+
+## 🚀 Quick Start
+
+### Option A: Deploy from pre-built Docker image (recommended) - `deploy_prebuilt.sh`
+
+**Faster option** - uses pre-built Docker image from GitHub Container Registry. You don't need to have Pascal compiler or Lazarus installed. However, you must add game data extracted from the original CD.
+
+**⚠️ IMPORTANT: Game data is required**
+
+The pre-built Docker image doesn't contain game data due to licensing reasons. You must extract data from the original Atomic Bomberman CD and add it to the deployment.
+
+1. **Extract game data:**
+ - Use CD Data Extractor (part of the repository) to extract data from the original CD
+ - This will create a `data` directory with maps, resources, and sounds
+
+2. **Create deployment directory:**
+ ```bash
+ mkdir fpc-atomic-server
+ cd fpc-atomic-server
+ ```
+
+3. **Copy game data:**
+ ```bash
+ # Copy the extracted data directory
+ cp -r /path/to/extracted/data .
+ ```
+
+ The `data` directory should contain:
+ - `maps/` - game maps
+ - `res/` - resources, textures, etc.
+ - `sounds/` - sound effects
+
+4. **Clone the repository (to get the deploy script):**
+ ```bash
+ git clone https://github.com/your-username/fpc_atomic.git
+ cd fpc_atomic/flyio_server
+ ```
+
+5. **Copy your data directory:**
+ ```bash
+ # Copy extracted data to flyio_server/
+ cp -r /path/to/extracted/data .
+ ```
+
+6. **Deploy to Fly.io:**
+ ```bash
+ # Use the deploy script, which will add data to the pre-built image
+ ./deploy_prebuilt.sh
+ ```
+
+ **Alternative - Manual deployment:**
+
+ If you prefer manual deployment, you can create your own Dockerfile:
+ ```dockerfile
+ FROM ghcr.io/your-username/fpc-atomic-server:latest
+ COPY data /app/data
+ ```
+
+ Then create `fly.toml`:
+ ```toml
+ app = "your-app-name-here" # Change this to your unique application name
+ primary_region = "fra"
+
+ [build]
+ dockerfile = "Dockerfile"
+
+ [env]
+ PORT = "5521"
+
+ [[services]]
+ protocol = "tcp"
+ internal_port = 5521
+ processes = ["app"]
+ auto_stop_machines = true
+ auto_start_machines = true
+ min_machines_running = 0
+
+ [[services.ports]]
+ port = 5521
+ ```
+
+ Then deploy:
+ ```bash
+ flyctl deploy
+ ```
+
+### Option B: Build from source code and deploy - `build_and_deploy.sh`
+
+**Slower option** - builds server from Pascal source code and then deploys it. Requires Pascal compiler (but it's already in Dockerfile, so you don't need anything installed locally). Can work even without game data (server will run, but without maps).
+
+**⚠️ IMPORTANT: Game data is required**
+
+Before deploying, you must extract game data from the original Atomic Bomberman CD and copy it to the `flyio_server/data` directory.
+
+1. **Extract game data:**
+ - Use CD Data Extractor (part of the repository) to extract data from the original CD
+ - This will create a `data` directory with maps, resources, and sounds
+
+2. **Copy data to flyio_server:**
+ ```bash
+ # Copy extracted data directory to flyio_server/
+ cp -r /path/to/extracted/data flyio_server/data
+ ```
+
+ The `flyio_server/data` directory should contain:
+ - `maps/` - game maps
+ - `res/` - resources, textures, etc.
+ - `sounds/` - sound effects
+
+3. **Clone the repository:**
+ ```bash
+ git clone https://github.com/your-username/fpc_atomic.git
+ cd fpc_atomic
+ ```
+
+4. **Set application name in .env file:**
+
+ Create or edit `.env` file in the project root:
+ ```bash
+ # In project root (not in flyio_server/)
+ echo "FLY_APP_NAME=fpc-atomic-tcp-server-my-name" >> .env
+ ```
+
+ **Important:** The application name is stored in the `.env` file (which is in `.gitignore`), so you can commit `fly.toml` to git without revealing your application name.
+
+5. **Deploy to Fly.io:**
+
+ **Easiest way - use the build and deploy script:**
+ ```bash
+ cd flyio_server
+ ./build_and_deploy.sh
+ ```
+
+ **What this script does:**
+ - Builds server from Pascal source code (compilation happens in Docker image)
+ - Deploys the build to Fly.io
+ - Can work without game data (warns but continues)
+
+ **Or manually:**
+ ```bash
+ # Make sure you're in the project root
+ cd /path/to/fpc_atomic
+
+ # First deploy (creates new application)
+ flyctl deploy --config flyio_server/fly.toml
+
+ # Or if you already have an application
+ flyctl deploy --config flyio_server/fly.toml
+ ```
+
+ **Note:** Build context must be the project root (not `flyio_server/`), so always run `flyctl deploy` from the project root with `--config flyio_server/fly.toml`.
+
+ **Note:** If you don't include game data, the server will build and run, but without game maps. Only random maps will be available.
+
+### 3. View information
+
+```bash
+# Show status and IP address
+flyctl status
+
+# Show logs
+flyctl logs
+
+# SSH into container (for debugging)
+flyctl ssh console
+```
+
+## 📝 What happens during deployment?
+
+1. **Build**: Dockerfile automatically:
+ - Compiles AI library (`libai.so`) for Linux
+ - Compiles server (`atomic_server`) for Linux
+ - Copies data directory (contains maps and other game data)
+
+2. **Deploy**: Fly.io:
+ - Creates Docker image
+ - Starts server on port 5521
+ - Server automatically shuts down after 30 seconds of inactivity (auto_stop_machines)
+ - Server automatically starts on new connection (auto_start_machines)
+
+## ⚙️ Configuration
+
+### Port
+Server listens on port **5521** (set in `fly.toml` and `Dockerfile`).
+
+### Timeout
+Server automatically shuts down after **30 seconds** of inactivity (set in `Dockerfile` as `-t 30000`).
+
+### Region
+Default region is **Frankfurt (fra)** - you can change it in `fly.toml`.
+
+## 🔧 Troubleshooting
+
+### Build fails
+
+1. Check that all required files are in the project:
+ - `server/` - server source code
+ - `units/` - units
+ - `ai/` - AI library
+ - `data/` - game data
+
+2. Try local build:
+ ```bash
+ docker build -t fpc-atomic-test -f flyio_server/Dockerfile .
+ ```
+
+### Server doesn't start
+
+1. Check logs:
+ ```bash
+ flyctl logs
+ ```
+
+2. Verify that data directory exists and contains required files (maps in `data/maps/`)
+
+### Client connections
+
+**⚠️ IMPORTANT: Each server has its own address**
+
+Everyone who deploys a server on fly.io has their own unique address. If multiple people use the same application name, they will try to deploy to the same application, which won't work - everyone must have their own account and application.
+
+**IMPORTANT:** Before deploying, change the application name in `fly.toml` to something unique, for example:
+```toml
+app = "fpc-atomic-tcp-server-my-name"
+```
+
+**How to find server address:**
+
+1. **DNS address (recommended):** `.fly.dev`
+ - For example: `your-app-name-here.fly.dev`
+ - This address doesn't change and is more reliable than IP address
+ - You can find it from the application name in `fly.toml` or from:
+ ```bash
+ flyctl status
+ ```
+
+2. **IP address (alternative):**
+ ```bash
+ flyctl status
+ ```
+ - IP address may change, so it's better to use DNS name
+
+**Connecting in client:**
+
+1. Press **"j"** in the main menu
+2. Enter server address:
+ - **DNS address:** `.fly.dev` (e.g., `your-app-name-here.fly.dev`)
+ - **Or IP address:** from `flyctl status`
+3. Enter port: **5521**
+4. Press **OK**
+
+**Alternative - Command line parameters:**
+```bash
+./fpc_atomic -ip your-app-name-here.fly.dev -port 5521
+```
+
+## 📊 Monitoring
+
+```bash
+# Real-time logs
+flyctl logs
+
+# Application status
+flyctl status
+
+# Metrics
+flyctl metrics
+```
+
+## 🔗 Useful links
+
+- [Fly.io documentation](https://fly.io/docs/)
+- [Fly.io CLI reference](https://fly.io/docs/flyctl/)
diff --git a/flyio_server/build_and_deploy.sh b/flyio_server/build_and_deploy.sh
new file mode 100755
index 0000000..06cff7f
--- /dev/null
+++ b/flyio_server/build_and_deploy.sh
@@ -0,0 +1,160 @@
+#!/bin/bash
+# Build and deploy FPC Atomic Server to Fly.io from source code
+# This script builds the server from Pascal source code and deploys it to Fly.io
+# Works on macOS, Linux, and Windows (with Git Bash or WSL)
+# This script ensures the correct build context (project root) is used
+
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+FLYIO_DIR="${SCRIPT_DIR}"
+
+echo "========================================="
+echo "Deploying FPC Atomic Server to Fly.io"
+echo "========================================="
+echo ""
+
+# Check if flyctl is installed
+if ! command -v flyctl &> /dev/null; then
+ echo "Error: flyctl is not installed" >&2
+ echo "Please install it using:" >&2
+ echo " curl -L https://fly.io/install.sh | sh" >&2
+ echo "Or visit: https://fly.io/docs/getting-started/installing-flyctl/" >&2
+ exit 1
+fi
+
+# Check if fly.toml exists
+if [[ ! -f "${FLYIO_DIR}/fly.toml" ]]; then
+ echo "Error: fly.toml not found at ${FLYIO_DIR}/fly.toml" >&2
+ exit 1
+fi
+
+# Load app name from .env file (if exists)
+FLY_APP_NAME=""
+if [[ -f "${PROJECT_ROOT}/.env" ]]; then
+ # Extract FLY_APP_NAME from .env file
+ # Handles: FLY_APP_NAME=value, export FLY_APP_NAME=value, FLY_APP_NAME="value", FLY_APP_NAME='value', and comments
+ FLY_APP_NAME=$(grep -E '^[[:space:]]*(export[[:space:]]+)?FLY_APP_NAME[[:space:]]*=' "${PROJECT_ROOT}/.env" 2>/dev/null | head -1 | sed -E 's/^[[:space:]]*(export[[:space:]]+)?FLY_APP_NAME[[:space:]]*=[[:space:]]*//' | sed -E 's/^["'\''](.*)["'\'']$/\1/' | sed -E 's/[[:space:]]*#.*$//' | tr -d '[:space:]')
+ if [[ -n "${FLY_APP_NAME:-}" ]]; then
+ echo "✓ Using app name from .env: ${FLY_APP_NAME}"
+ fi
+fi
+
+# If FLY_APP_NAME is not set, try to extract from fly.toml placeholder
+if [[ -z "${FLY_APP_NAME:-}" ]]; then
+ # Check if fly.toml contains placeholder
+ if grep -q '\${FLY_APP_NAME}' "${FLYIO_DIR}/fly.toml" 2>/dev/null; then
+ echo "⚠️ Error: FLY_APP_NAME not found in .env file" >&2
+ echo "Please add FLY_APP_NAME=your-app-name to ${PROJECT_ROOT}/.env" >&2
+ exit 1
+ fi
+ # If no placeholder, extract actual app name from fly.toml
+ FLY_APP_NAME=$(grep -E '^app\s*=' "${FLYIO_DIR}/fly.toml" | head -1 | sed -E 's/^app\s*=\s*["'\'']?([^"'\'']+)["'\'']?.*/\1/' | tr -d ' ')
+ if [[ -n "${FLY_APP_NAME}" ]]; then
+ echo "✓ Using app name from fly.toml: ${FLY_APP_NAME}"
+ fi
+fi
+
+# Create temporary fly.toml with replaced app name
+TEMP_FLY_TOML="${FLYIO_DIR}/fly.toml.tmp"
+if [[ -n "${FLY_APP_NAME:-}" ]]; then
+ # Replace ${FLY_APP_NAME} placeholder in fly.toml
+ sed "s|\${FLY_APP_NAME}|${FLY_APP_NAME}|g" "${FLYIO_DIR}/fly.toml" > "${TEMP_FLY_TOML}"
+ echo "✓ Created temporary fly.toml with app name: ${FLY_APP_NAME}"
+else
+ echo "⚠️ Warning: No app name found, using fly.toml as-is" >&2
+ cp "${FLYIO_DIR}/fly.toml" "${TEMP_FLY_TOML}"
+fi
+
+# Check if Dockerfile exists
+if [[ ! -f "${FLYIO_DIR}/Dockerfile" ]]; then
+ echo "Error: Dockerfile not found at ${FLYIO_DIR}/Dockerfile" >&2
+ exit 1
+fi
+
+# Check if data directory exists in flyio_server/
+if [[ ! -d "${FLYIO_DIR}/data" ]]; then
+ echo "========================================="
+ echo "⚠️ WARNING: Game data directory not found!"
+ echo "========================================="
+ echo ""
+ echo "The server will work but WITHOUT game maps (only random maps available)."
+ echo ""
+ echo "To add game data before deployment:"
+ echo " 1. Extract data from the original Atomic Bomberman CD"
+ echo " using the CD Data Extractor tool (included in the repository)"
+ echo " 2. Copy the extracted 'data' directory to:"
+ echo " ${FLYIO_DIR}/data"
+ echo ""
+ echo "The data directory should contain:"
+ echo " - maps/ (game maps)"
+ echo " - res/ (resources, textures, etc.)"
+ echo " - sounds/ (sound effects)"
+ echo ""
+
+ # Check if data exists in project root as alternative
+ if [[ -d "${PROJECT_ROOT}/data" ]]; then
+ echo "Found data directory in project root: ${PROJECT_ROOT}/data"
+ read -p "Copy it to flyio_server/data? (y/N) " -n 1 -r
+ echo ""
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo "Copying data directory..."
+ cp -r "${PROJECT_ROOT}/data" "${FLYIO_DIR}/data"
+ echo "✓ Data directory copied"
+ else
+ read -p "Continue deployment without game data? (y/N) " -n 1 -r
+ echo ""
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ echo "Deployment cancelled."
+ exit 0
+ fi
+ fi
+ else
+ read -p "Continue deployment without game data? (y/N) " -n 1 -r
+ echo ""
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ echo "Deployment cancelled."
+ exit 0
+ fi
+ fi
+else
+ echo "✓ Game data directory found at ${FLYIO_DIR}/data"
+fi
+
+# Change to project root (build context must be project root)
+cd "${PROJECT_ROOT}"
+
+echo ""
+echo "Build context: ${PROJECT_ROOT}"
+echo "Fly.io config: ${FLYIO_DIR}/fly.toml"
+echo "Dockerfile: ${FLYIO_DIR}/Dockerfile"
+echo ""
+
+# Deploy to Fly.io
+# Build context is project root, so we use --config to point to temporary fly.toml
+echo "Starting deployment..."
+flyctl deploy --config "${TEMP_FLY_TOML}" "$@"
+
+# Cleanup temporary file
+rm -f "${TEMP_FLY_TOML}"
+
+echo ""
+echo "========================================="
+echo "Deployment complete!"
+echo "========================================="
+echo ""
+echo "To check server status:"
+if [[ -n "${FLY_APP_NAME:-}" ]]; then
+ echo " flyctl status --app ${FLY_APP_NAME}"
+else
+ echo " flyctl status --config ${FLYIO_DIR}/fly.toml"
+fi
+echo ""
+echo "To view logs:"
+if [[ -n "${FLY_APP_NAME:-}" ]]; then
+ echo " flyctl logs --app ${FLY_APP_NAME}"
+else
+ echo " flyctl logs --config ${FLYIO_DIR}/fly.toml"
+fi
+echo ""
diff --git a/flyio_server/deploy_prebuilt.sh b/flyio_server/deploy_prebuilt.sh
new file mode 100755
index 0000000..5c8e93a
--- /dev/null
+++ b/flyio_server/deploy_prebuilt.sh
@@ -0,0 +1,228 @@
+#!/bin/bash
+# Deploy FPC Atomic Server to Fly.io using pre-built Docker image from GitHub
+# This script uses a pre-built Docker image from GitHub Container Registry and adds game data
+# Faster than building from source - no compilation needed
+# Works on macOS, Linux, and Windows (with Git Bash or WSL)
+
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+FLYIO_DIR="${SCRIPT_DIR}"
+
+# Default base image
+BASE_IMAGE="${BASE_IMAGE:-ghcr.io/PavelZverina/fpc-atomic-server:latest}"
+
+echo "========================================="
+echo "Deploying FPC Atomic Server to Fly.io"
+echo "Using pre-built image + game data"
+echo "========================================="
+echo ""
+
+# Check if flyctl is installed
+if ! command -v flyctl &> /dev/null; then
+ echo "Error: flyctl is not installed" >&2
+ echo "Please install it using:" >&2
+ echo " curl -L https://fly.io/install.sh | sh" >&2
+ exit 1
+fi
+
+# Check if Docker is installed (needed for local build)
+if ! command -v docker &> /dev/null; then
+ echo "Error: Docker is not installed" >&2
+ echo "This script requires Docker to build a custom image with game data." >&2
+ echo "Please install Docker Desktop or Docker Engine." >&2
+ exit 1
+fi
+
+# Check if data directory exists
+if [[ ! -d "${FLYIO_DIR}/data" ]]; then
+ echo "========================================="
+ echo "⚠️ ERROR: Game data directory not found!"
+ echo "========================================="
+ echo ""
+ echo "This script requires game data to be present."
+ echo ""
+ echo "To add game data:"
+ echo " 1. Extract data from the original Atomic Bomberman CD"
+ echo " using the CD Data Extractor tool"
+ echo " 2. Copy the extracted 'data' directory to:"
+ echo " ${FLYIO_DIR}/data"
+ echo ""
+ echo "The data directory should contain:"
+ echo " - maps/ (game maps)"
+ echo " - res/ (resources, textures, etc.)"
+ echo " - sounds/ (sound effects)"
+ echo ""
+
+ # Check if data exists in project root as alternative
+ if [[ -d "${PROJECT_ROOT}/data" ]]; then
+ echo "Found data directory in project root: ${PROJECT_ROOT}/data"
+ read -p "Copy it to flyio_server/data? (y/N) " -n 1 -r
+ echo ""
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo "Copying data directory..."
+ cp -r "${PROJECT_ROOT}/data" "${FLYIO_DIR}/data"
+ echo "✓ Data directory copied"
+ else
+ echo "Deployment cancelled."
+ exit 1
+ fi
+ else
+ echo "Deployment cancelled. Please add game data first."
+ exit 1
+ fi
+else
+ echo "✓ Game data directory found at ${FLYIO_DIR}/data"
+fi
+
+# Verify data directory has required content
+if [[ ! -d "${FLYIO_DIR}/data/maps" ]]; then
+ echo "Warning: data/maps directory not found. Server will work but without game maps." >&2
+fi
+
+# Create temporary Dockerfile that uses base image + adds data
+TEMP_DOCKERFILE="${FLYIO_DIR}/Dockerfile.with_data"
+cat > "${TEMP_DOCKERFILE}" << EOF
+# Temporary Dockerfile for deployment with game data
+# This file is auto-generated by deploy_prebuilt.sh
+# It uses the pre-built base image and adds game data
+
+FROM ${BASE_IMAGE}
+
+# Copy game data into the image
+COPY data /app/data
+
+# The base image already has the server binary and all dependencies
+# We just need to add the game data
+EOF
+
+echo ""
+echo "Created temporary Dockerfile: ${TEMP_DOCKERFILE}"
+echo "Base image: ${BASE_IMAGE}"
+echo ""
+
+# Load app name from .env file (if exists)
+APP_NAME=""
+if [[ -f "${PROJECT_ROOT}/.env" ]]; then
+ # Extract FLY_APP_NAME from .env file
+ # Handles: FLY_APP_NAME=value, export FLY_APP_NAME=value, FLY_APP_NAME="value", FLY_APP_NAME='value', and comments
+ FLY_APP_NAME=$(grep -E '^[[:space:]]*(export[[:space:]]+)?FLY_APP_NAME[[:space:]]*=' "${PROJECT_ROOT}/.env" 2>/dev/null | head -1 | sed -E 's/^[[:space:]]*(export[[:space:]]+)?FLY_APP_NAME[[:space:]]*=[[:space:]]*//' | sed -E 's/^["'\''](.*)["'\'']$/\1/' | sed -E 's/[[:space:]]*#.*$//' | tr -d '[:space:]')
+ if [[ -n "${FLY_APP_NAME:-}" ]]; then
+ APP_NAME="${FLY_APP_NAME}"
+ echo "✓ Using app name from .env: ${APP_NAME}"
+ fi
+fi
+
+# If FLY_APP_NAME is not set, try to extract from fly.toml
+if [[ -z "${APP_NAME:-}" ]]; then
+ if [[ -f "${FLYIO_DIR}/fly.toml" ]]; then
+ # Check if fly.toml contains placeholder
+ if grep -q '\${FLY_APP_NAME}' "${FLYIO_DIR}/fly.toml" 2>/dev/null; then
+ echo "⚠️ Error: FLY_APP_NAME not found in .env file" >&2
+ echo "Please add FLY_APP_NAME=your-app-name to ${PROJECT_ROOT}/.env" >&2
+ exit 1
+ fi
+ # Try to extract app name from existing fly.toml
+ EXTRACTED_APP=$(grep -E '^app\s*=' "${FLYIO_DIR}/fly.toml" | head -1 | sed -E 's/^app\s*=\s*["'\'']?([^"'\'']+)["'\'']?.*/\1/' | tr -d ' ')
+ if [[ -n "${EXTRACTED_APP}" && "${EXTRACTED_APP}" != "your-app-name-here" && "${EXTRACTED_APP}" != "\${FLY_APP_NAME}" ]]; then
+ APP_NAME="${EXTRACTED_APP}"
+ echo "✓ Using app name from fly.toml: ${APP_NAME}"
+ fi
+ fi
+fi
+
+# If still no app name, use placeholder
+if [[ -z "${APP_NAME:-}" ]]; then
+ APP_NAME="your-app-name-here"
+ echo "⚠️ Warning: Using placeholder app name 'your-app-name-here'"
+ echo " Please add FLY_APP_NAME=your-app-name to ${PROJECT_ROOT}/.env"
+ echo ""
+fi
+
+# Extract primary_region from existing fly.toml or fly.toml.example
+PRIMARY_REGION="fra"
+if [[ -f "${FLYIO_DIR}/fly.toml" ]]; then
+ EXTRACTED_REGION=$(grep -E '^primary_region\s*=' "${FLYIO_DIR}/fly.toml" | head -1 | sed -E 's/^primary_region\s*=\s*["'\'']?([^"'\'']+).*/\1/' | tr -d ' ')
+ if [[ -n "${EXTRACTED_REGION}" ]]; then
+ PRIMARY_REGION="${EXTRACTED_REGION}"
+ fi
+elif [[ -f "${FLYIO_DIR}/fly.toml.example" ]]; then
+ EXTRACTED_REGION=$(grep -E '^primary_region\s*=' "${FLYIO_DIR}/fly.toml.example" | head -1 | sed -E 's/^primary_region\s*=\s*["'\'']?([^"'\'']+).*/\1/' | tr -d ' ')
+ if [[ -n "${EXTRACTED_REGION}" ]]; then
+ PRIMARY_REGION="${EXTRACTED_REGION}"
+ fi
+fi
+
+# Create temporary fly.toml that uses the Dockerfile
+TEMP_FLY_TOML="${FLYIO_DIR}/fly.toml.with_data"
+cat > "${TEMP_FLY_TOML}" << EOF
+# Temporary fly.toml for deployment with game data
+# This file is auto-generated by deploy_prebuilt.sh
+
+app = "${APP_NAME}"
+primary_region = "${PRIMARY_REGION}"
+
+[build]
+ dockerfile = "Dockerfile.with_data"
+ build_args = {}
+
+[deploy]
+ strategy = "immediate"
+
+[env]
+ PORT = "5521"
+
+[[services]]
+ protocol = "tcp"
+ internal_port = 5521
+ processes = ["app"]
+ auto_stop_machines = true
+ auto_start_machines = true
+ min_machines_running = 0
+
+ [[services.ports]]
+ port = 5521
+
+ [services.concurrency]
+ type = "connections"
+ hard_limit = 100
+ soft_limit = 50
+
+ [[services.tcp_checks]]
+ interval = "15s"
+ timeout = "10s"
+ grace_period = "45s"
+ restart_limit = 6
+EOF
+
+echo "Created temporary fly.toml: ${TEMP_FLY_TOML}"
+echo ""
+
+# Change to flyio_server directory (build context will be this directory)
+cd "${FLYIO_DIR}"
+
+echo "Build context: ${FLYIO_DIR}"
+echo "Dockerfile: ${TEMP_DOCKERFILE}"
+echo ""
+
+# Deploy to Fly.io
+echo "Starting deployment with game data..."
+flyctl deploy --config "${TEMP_FLY_TOML}" "$@"
+
+# Cleanup temporary files
+echo ""
+echo "Cleaning up temporary files..."
+rm -f "${TEMP_DOCKERFILE}" "${TEMP_FLY_TOML}"
+
+echo ""
+echo "========================================="
+echo "Deployment complete!"
+echo "========================================="
+echo ""
+echo "To check server status:"
+echo " flyctl status --config ${FLYIO_DIR}/fly.toml"
+echo ""
+echo "To view logs:"
+echo " flyctl logs --config ${FLYIO_DIR}/fly.toml"
+echo ""
diff --git a/flyio_server/fly.toml b/flyio_server/fly.toml
new file mode 100644
index 0000000..c34ab44
--- /dev/null
+++ b/flyio_server/fly.toml
@@ -0,0 +1,40 @@
+# Fly.io configuration for FPC Atomic TCP Server
+
+app = "${FLY_APP_NAME}" # App name is loaded from .env file (FLY_APP_NAME variable) via deploy script
+primary_region = "fra" # Frankfurt (closest to Czech Republic)
+
+[build]
+ dockerfile = "Dockerfile"
+ build_args = {}
+
+[deploy]
+ strategy = "immediate"
+
+[env]
+ PORT = "5521"
+
+# TCP service configuration
+[[services]]
+ protocol = "tcp"
+ internal_port = 5521
+ processes = ["app"]
+ auto_stop_machines = true # Stop machine when server exits (after 30s timeout)
+ auto_start_machines = true # Auto-start when new connection arrives
+ min_machines_running = 0 # No machine running when no players connected
+
+ [[services.ports]]
+ port = 5521
+ # No handlers = plain TCP passthrough (no TLS termination)
+
+ [services.concurrency]
+ type = "connections"
+ hard_limit = 100
+ soft_limit = 50
+
+ # TCP health check
+ [[services.tcp_checks]]
+ interval = "15s"
+ timeout = "10s"
+ grace_period = "45s" # Wait for server auto-shutdown (30s) + buffer
+ restart_limit = 6
+
diff --git a/flyio_server/fly.toml.example b/flyio_server/fly.toml.example
new file mode 100644
index 0000000..040d0eb
--- /dev/null
+++ b/flyio_server/fly.toml.example
@@ -0,0 +1,52 @@
+# Fly.io configuration for FPC Atomic TCP Server
+#
+# This is a template file. Copy this to fly.toml.
+#
+# Usage:
+# 1. Copy this file: cp fly.toml.example fly.toml
+# 2. Add FLY_APP_NAME=your-app-name to your .env file (in project root)
+# 3. Deploy using: ./build_and_deploy.sh (build from source) or ./deploy_prebuilt.sh (use pre-built image)
+#
+# The app name is loaded from .env file (FLY_APP_NAME variable) to keep your
+# app name private while still being able to commit fly.toml to git.
+
+app = "${FLY_APP_NAME}" # App name is loaded from .env file (FLY_APP_NAME variable) via deploy script
+primary_region = "fra" # Frankfurt (closest to Czech Republic)
+
+[build]
+ # Použití předpřipraveného Docker image (bez nutnosti Pascal compiler)
+ image = "ghcr.io/PavelZverina/fpc-atomic-server:latest"
+
+ # Pokud chcete buildnout z source kódu, použijte místo toho:
+ # dockerfile = "flyio_server/Dockerfile"
+
+[deploy]
+ strategy = "immediate"
+
+[env]
+ PORT = "5521"
+
+# TCP service configuration
+[[services]]
+ protocol = "tcp"
+ internal_port = 5521
+ processes = ["app"]
+ auto_stop_machines = true # Stop machine when server exits (after 30s timeout)
+ auto_start_machines = true # Auto-start when new connection arrives
+ min_machines_running = 0 # No machine running when no players connected
+
+ [[services.ports]]
+ port = 5521
+ # No handlers = plain TCP passthrough (no TLS termination)
+
+ [services.concurrency]
+ type = "connections"
+ hard_limit = 100
+ soft_limit = 50
+
+ # TCP health check
+ [[services.tcp_checks]]
+ interval = "15s"
+ timeout = "10s"
+ grace_period = "45s" # Wait for server auto-shutdown (30s) + buffer
+ restart_limit = 6
diff --git a/launcher/atomic_launcher.lpi b/launcher/atomic_launcher.lpi
index b1a3b81..8c1feed 100644
--- a/launcher/atomic_launcher.lpi
+++ b/launcher/atomic_launcher.lpi
@@ -12,8 +12,50 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -109,7 +151,7 @@
-
+
diff --git a/launcher/atomic_launcher.lpr b/launcher/atomic_launcher.lpr
index c2fb7cd..3825b88 100644
--- a/launcher/atomic_launcher.lpr
+++ b/launcher/atomic_launcher.lpr
@@ -10,10 +10,14 @@
athreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, unit1, ulauncher, unit2, unit3, ucdextractor, ukeyboarddialog,
- uJSON, uwave, uopengl_animation, usdl_joystick, usynapsedownloader,
+ Forms, unit1, unit2, unit3, ucdextractor, uopengl_animation,
usdlwizzard;
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
{$R *.res}
begin
diff --git a/launcher/ulauncher.pas b/launcher/ulauncher.pas
index 05cc503..0b4833a 100644
--- a/launcher/ulauncher.pas
+++ b/launcher/ulauncher.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit ulauncher;
{$MODE ObjFPC}{$H+}
@@ -108,7 +113,7 @@
Implementation
-Uses unit1, unit2, ssl_openssl, httpsend, synautil, uJSON, LazFileUtils, ucdextractor;
+Uses unit1, unit2, uJSON, LazFileUtils, ucdextractor;
Procedure ClearLog();
Begin
diff --git a/launcher/unit1.lfm b/launcher/unit1.lfm
index 1055ac4..33597f2 100644
--- a/launcher/unit1.lfm
+++ b/launcher/unit1.lfm
@@ -8,8 +8,10 @@ object Form1: TForm1
ClientWidth = 467
Position = poScreenCenter
LCLVersion = '4.99.0.0'
+ OnActivate = FormActivate
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
+ OnShow = FormShow
object Image1: TImage
Left = 8
Height = 288
@@ -18,6 +20,12 @@ object Form1: TForm1
Center = True
Stretch = True
end
+ object Timer1: TTimer
+ Enabled = True
+ OnTimer = Timer1Timer
+ Left = 184
+ Top = 368
+ end
object Button1: TButton
Left = 208
Height = 25
diff --git a/launcher/unit1.pas b/launcher/unit1.pas
index 825f0d5..7ea08d5 100644
--- a/launcher/unit1.pas
+++ b/launcher/unit1.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit Unit1;
{$MODE objfpc}{$H+}
@@ -45,6 +50,7 @@
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
+ Timer1: TTimer;
Procedure Button1Click(Sender: TObject);
Procedure Button2Click(Sender: TObject);
Procedure Button3Click(Sender: TObject);
@@ -52,11 +58,15 @@
Procedure Button5Click(Sender: TObject);
Procedure FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
Procedure FormCreate(Sender: TObject);
+ Procedure FormActivate(Sender: TObject);
+ Procedure FormShow(Sender: TObject);
+ Procedure Timer1Timer(Sender: TObject);
private
ini: TIniFile;
Atomic_Version: TVersion;
ProtocollVersion: integer;
Version: Single;
+ fImageLoaded: Boolean; // Track if image was loaded last time we checked
Procedure LoadSettings();
Procedure StoreSettings();
@@ -74,11 +84,10 @@
{$R *.lfm}
-Uses UTF8Process, process, Unit2, Unit3, LCLType
+Uses UTF8Process, process, Unit2, Unit3, LCLType, LazFileUtils, LazUTF8
, ukeyboarddialog, uatomic_common, usynapsedownloader
{$IFDEF Windows}
, LResources
- , ssl_openssl_lib, ssl_openssl, blcksock
{$ENDIF}
;
@@ -120,8 +129,12 @@
Constraints.MaxWidth := Width;
SetCurrentDir(ExtractFilePath(ParamStr(0)));
Atomic_Version := TVersion.Create();
+ fImageLoaded := false;
LoadSideImage();
LoadSettings();
+ // Set up timer to periodically check if image file appears (after data extraction)
+ Timer1.Interval := 1000; // Check every second
+ Timer1.Enabled := true;
caption := format('FPC Atomic, launcher ver. %0.2f', [LauncherVersion / 100]);
// Handle Launcher Parameters
For i := 1 To ParamCount Do Begin
@@ -139,22 +152,37 @@
Procedure TForm1.Button4Click(Sender: TObject);
Var
P: TProcessUTF8;
+ extractorPath: String;
Begin
// run cd data extractor
StoreSettings();
ini.UpdateFile;
+ // Find cd_data_extractor in the same directory as the launcher (for macOS app bundle)
+ // On macOS, this will be in Contents/MacOS/ of the app bundle
+ extractorPath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'cd_data_extractor'{$IFDEF Windows} + '.exe'{$ENDIF};
// Short Prechecks
- If (Not FileExists('cd_data_extractor'{$IFDEF Windows} + '.exe'{$ENDIF})) Or
- (Not FileExists('cd_data_extractor'{$IFDEF Windows} + '.exe'{$ENDIF})) Then Begin
- showmessage('Error, installation not complete, please run "Check for updates"');
+ If Not FileExists(extractorPath) Then Begin
+ showmessage('Error, installation not complete, please run "Check for updates"' + LineEnding +
+ 'Missing: ' + extractorPath);
exit;
End;
// Run the App ;)
+ // On macOS, GUI applications need to be run detached to show GUI properly
p := TProcessUTF8.Create(Nil);
- p.Executable := 'cd_data_extractor'{$IFDEF Windows} + '.exe'{$ENDIF};
+ p.Executable := extractorPath;
+{$IFDEF Darwin}
+ // On macOS, run GUI application detached so it can show its window
+ p.Options := p.Options + [poDetached];
+{$ELSE}
+ // On other platforms, wait for exit
p.Options := p.Options + [poWaitOnExit];
+{$ENDIF}
p.Execute;
p.free;
+ // Refresh image after extractor might have created data files
+ LoadSideImage();
+ Image1.Invalidate;
+ Application.ProcessMessages;
End;
Procedure TForm1.Button5Click(Sender: TObject);
@@ -262,10 +290,25 @@
ini := Nil;
End;
+Procedure TForm1.FormActivate(Sender: TObject);
+Begin
+ // Refresh side image when form gets focus (in case data was extracted)
+ LoadSideImage();
+ Image1.Invalidate;
+End;
+
+Procedure TForm1.FormShow(Sender: TObject);
+Begin
+ // Refresh side image when form is shown (in case data was extracted)
+ LoadSideImage();
+ Image1.Invalidate;
+End;
+
Procedure TForm1.Button2Click(Sender: TObject);
Var
P: TProcessUTF8;
sl: TStringList;
+ exePath, serverPath, workDir: String;
Begin
// Launch
StoreSettings();
@@ -280,14 +323,21 @@
End;
sl.free;
// Short Prechecks
- If (Not FileExists('fpc_atomic'{$IFDEF Windows} + '.exe'{$ENDIF})) Or
- (Not FileExists('atomic_server'{$IFDEF Windows} + '.exe'{$ENDIF})) Then Begin
+ workDir := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
+ exePath := workDir + 'fpc_atomic';
+ serverPath := workDir + 'atomic_server';
+{$IFDEF Windows}
+ exePath := exePath + '.exe';
+ serverPath := serverPath + '.exe';
+{$ENDIF}
+ If (Not FileExists(exePath)) Or (Not FileExists(serverPath)) Then Begin
showmessage('Error, installation not complete, please run "Check for updates"');
exit;
End;
// Run the App ;)
p := TProcessUTF8.Create(Nil);
- p.Executable := 'fpc_atomic'{$IFDEF Windows} + '.exe'{$ENDIF};
+ p.Executable := exePath;
+ p.CurrentDirectory := ExcludeTrailingPathDelimiter(workDir);
If CheckBox3.Checked Then Begin
p.Parameters.Add('-ip');
p.Parameters.Add(Edit2.Text);
@@ -304,6 +354,12 @@
tmpFolder: String;
dl: TSynapesDownloader;
Begin
+{$IFDEF Darwin}
+ // Updates are not implemented on macOS yet
+ showmessage('Updates are not yet available on macOS.' + LineEnding + LineEnding +
+ 'Please check the project repository for manual updates.');
+ exit;
+{$ENDIF}
{$IFDEF Linux}
If DirectoryExists('cd_data_extractor') Then Begin
If id_yes = Application.MessageBox('In the launcher location there is a folder named "cd_data_extractor", this will crash the update process' + LineEnding +
@@ -360,16 +416,100 @@
form2.Hide;
End;
+Function ResolveResourceBase(BasePath: String): String;
+Var
+ testPath: String;
+ appBundlePath: String;
+Begin
+ // Normalize base path to absolute path
+ BasePath := ExpandFileName(IncludeTrailingPathDelimiter(BasePath));
+
+ // Try multiple locations for data directory
+ // 1. Direct relative to executable (works with symlinks)
+ testPath := BasePath + 'data';
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 2. Relative path from MacOS directory in .app bundle
+ testPath := ExpandFileName(BasePath + '../Resources/data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 3. Try symlink path (../../data from MacOS) - for shared data directory
+ testPath := ExpandFileName(BasePath + '../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 4. Try symlink path (../../../data from MacOS) - alternative symlink location
+ testPath := ExpandFileName(BasePath + '../../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 5. Try path next to .app bundle (for cases where data is outside the bundle)
+ // If BasePath contains ".app/Contents/MacOS/", try going up to the .app bundle's parent directory
+ If Pos('.app/Contents/MacOS/', BasePath) > 0 Then Begin
+ appBundlePath := Copy(BasePath, 1, Pos('.app/Contents/MacOS/', BasePath) + 4); // Get path up to ".app"
+ appBundlePath := ExtractFilePath(ExcludeTrailingPathDelimiter(appBundlePath)); // Get parent directory of .app
+ testPath := ExpandFileName(appBundlePath + 'data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ End;
+ // Fallback: use base path (may not exist, but at least we tried)
+ Result := BasePath + 'data' + PathDelim;
+End;
+
+Procedure TForm1.Timer1Timer(Sender: TObject);
+Var
+ dataPath, imagePath: String;
+ imageExists: Boolean;
+Begin
+ // Check if image file exists now (if data was extracted)
+ dataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ imagePath := dataPath + 'res' + PathDelim + 'mainmenu.png';
+ imageExists := FileExistsUTF8(imagePath);
+
+ // If image file status changed (appeared or disappeared), reload
+ If imageExists <> fImageLoaded Then Begin
+ LoadSideImage(); // This will update fImageLoaded internally
+ // Once image is loaded, we can slow down the timer or disable it
+ If imageExists Then Begin
+ Timer1.Interval := 5000; // Check less frequently once image is loaded
+ End;
+ End;
+End;
+
Procedure TForm1.LoadSideImage;
Var
p: TPortableNetworkGraphic;
+ dataPath: String;
+ imagePath: String;
Begin
- If FileExists('data' + PathDelim + 'res' + PathDelim + 'mainmenu.png') Then Begin
+ // Resolve data directory path
+ dataPath := ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))));
+ imagePath := dataPath + 'res' + PathDelim + 'mainmenu.png';
+ If FileExistsUTF8(imagePath) Then Begin
p := TPortableNetworkGraphic.Create;
- p.LoadFromFile('data' + PathDelim + 'res' + PathDelim + 'mainmenu.png');
- p.Width := p.Width Div 2;
- Image1.Picture.Assign(p);
- p.free;
+ Try
+ p.LoadFromFile(imagePath);
+ p.Width := p.Width Div 2;
+ Image1.Picture.Assign(p);
+ Image1.Invalidate; // Force redraw
+ fImageLoaded := true;
+ Finally
+ p.free;
+ End;
+ End
+ Else Begin
+ // Clear image if file doesn't exist
+ Image1.Picture.Clear;
+ Image1.Invalidate;
+ fImageLoaded := false;
End;
End;
@@ -420,14 +560,15 @@
// TODO: Hier fehlt noch ein Hinweis wie man die .lrs Datei erzeugt ;)
{$I atomic_launcher.lrs}
- // 1. ggf. die Crypto libs entpacken und dann einrichten
- If Not CheckAndMaybeExtract('ssleay32') Then exit;
- If Not CheckAndMaybeExtract('libeay32') Then exit;
-
- If SSLImplementation = TSSLNone Then Begin
- If InitSSLInterface Then
- SSLImplementation := TSSLOpenSSL;
- End;
+ // SSL initialization removed - using fphttpclient instead of Synapse
+ // fphttpclient handles SSL automatically via system libraries
+ // Old Synapse SSL code:
+ // If Not CheckAndMaybeExtract('ssleay32') Then exit;
+ // If Not CheckAndMaybeExtract('libeay32') Then exit;
+ // If SSLImplementation = TSSLNone Then Begin
+ // If InitSSLInterface Then
+ // SSLImplementation := TSSLOpenSSL;
+ // End;
{$ENDIF}
End.
diff --git a/macos/README_mac.md b/macos/README_mac.md
new file mode 100644
index 0000000..79c79ac
--- /dev/null
+++ b/macos/README_mac.md
@@ -0,0 +1,135 @@
+# FPC Atomic – macOS Overview
+
+Tento dokument obsahuje přehled macOS build systému. Pro detailní návod na kompilaci viz **[BUILD_GUIDE.md](tools/BUILD_GUIDE.md)**.
+
+## Rychlý start
+
+```bash
+# ARM64 (Apple Silicon)
+./macos/tools/build_all_arm64.command
+
+# x86_64 (Intel Macs)
+./macos/tools/build_all_x86_64.command
+```
+
+## Požadované nástroje
+- Xcode Command Line Tools (`xcode-select --install`)
+- Free Pascal Compiler 3.2.2 (balíček pro Intel+ARM)
+- Lazarus IDE 3.9 (nebo novější) – zkompilovaný s podporou `lazbuild`
+- SDL2 runtime (např. `brew install sdl2` nebo `SDL2.framework` z oficiálního DMG)
+- BASS knihovna (`libbass.dylib` z https://www.un4seen.com/)
+- **Pro x86_64 build:** Rosetta Homebrew (instaluje se automaticky přes `install_rosetta_homebrew.command`)
+- Další Pascal jednotky umístěné do `units/`:
+ - `dglOpenGL.pas`
+ - `bass.pas`
+ - `sdl2_for_pascal/` (hlavičky SDL2 od autora projektu)
+
+## Struktura adresáře `macos/`
+```
+macos/
+ bin/
+ arm64/
+ x86_64/
+ lib/
+ arm64/
+ x86_64/
+ data/
+ atomic/
+ maps/
+ game_assets/ # sem patří proprietární data z originální hry (není versionováno)
+ tools/
+ run_launcher.command
+ run_client.command
+ run_server.command
+ development/
+ Documents/
+ MacOS implementationplan.md
+```
+
+## Build módy v `.lpi`
+- Každý projekt (klient, launcher, server, AI) má módy `macos_arm64` a `macos_x86_64`.
+- Výstupy se generují do `macos/bin/` a `macos/lib/`.
+- Jednotky se stále kompilují do `lib/-` v rámci projektu.
+
+### Automatická kompilace (doporučeno)
+
+```bash
+# ARM64 (Apple Silicon)
+./macos/tools/build_all_arm64.command
+
+# x86_64 (Intel Macs) - automaticky připraví knihovny
+./macos/tools/build_all_x86_64.command
+```
+
+### Ruční kompilace
+
+Viz detailní návod v [BUILD_GUIDE.md](tools/BUILD_GUIDE.md).
+
+## Runtime knihovny
+
+### ARM64
+- `libbass.dylib` → `macos/lib/arm64/`
+- `libSDL2.dylib` → `macos/lib/arm64/` (nebo použij framework)
+- OpenSSL knihovny → automaticky z Homebrew
+
+### x86_64
+- **Automatická příprava:** Skript `prepare_x86_64_libs.command` automaticky:
+ - Ověří architektury všech knihoven
+ - Zkopíruje x86_64 OpenSSL z Rosetta Homebrew
+ - Vytvoří `libSDL2.dylib` z frameworku
+- **Ruční příprava:** Viz [BUILD_GUIDE.md](tools/BUILD_GUIDE.md)
+
+### Poznámky
+- SDL2 se načítá runtime (`SDL_RUNTIME_LOADING`), není potřeba explicitní linkování
+- lNet knihovna: po stažení `https://github.com/PascalCorpsman/lnet` spusť `make lib` a obsah `lib/` synchronizuj do `macos/third_party/lnet/`
+- SDL2 Pascal headers: `git clone https://github.com/PascalCorpsman/SDL2-for-Pascal.git macos/third_party/sdl2_for_pascal`, poté zkopíruj `macos/third_party/sdl2_for_pascal/units/*` do `units/sdl2_for_pascal/`
+
+## Spouštěcí skripty
+- `macos/tools/run_launcher.command`
+- `macos/tools/run_client.command`
+- `macos/tools/run_server.command`
+
+Skript zjistí architekturu (`uname -m`), nastaví `DYLD_LIBRARY_PATH` na odpovídající podsložku a spustí binárku. V případě Apple Silicon můžeš použít Rosettu pro x86_64 build: `arch -x86_64 macos/tools/run_client.command`.
+
+## Vytvoření `.app` balíčků
+
+App bundly se vytvoří automaticky při použití `build_all_*.command` skriptů.
+
+### Výstup
+- `macos/app_arm64/` - App bundly pro Apple Silicon
+- `macos/app_x86_64/` - App bundly pro Intel Macs
+
+Každý obsahuje:
+- `FPCAtomic.app` (klient)
+- `FPCAtomicLauncher.app` (launcher + klient + server)
+- `FPCAtomicServer.app` (samostatný server)
+
+### Code signing
+- App bundly jsou automaticky podepsané ad-hoc podpisem
+- Pro distribuci je potřeba Developer ID podpis a notarizace
+- Viz [BUILD_GUIDE.md](tools/BUILD_GUIDE.md) pro detailní informace
+
+Tipy k použití:
+- Launcher spuštěný z `.app` používá interní kopii klienta/serveru a nastavený pracovní adresář.
+- Server `.app` při dvojkliku otevře Terminal a spustí `atomic_server`; parametry můžeš přidat přes `open macos/app/FPCAtomicServer.app --args -p 1234`.
+- `macos/tools/run_server.command` i `.app` varianta serveru automaticky doplní `-p 5521` a `-t 0`, pokud nejsou předané – server tak zůstane běžet neomezeně dlouho. Vlastní port nebo timeout nastavíš přidáním `-p`/`-t` argumentů.
+
+## Integrace originálních dat
+1. Zkopíruj obsah CD a (volitelně) expansion pack do `macos/game_assets/`.
+2. Spusť `macos/tools/run_launcher.command` nebo samostatný nástroj `bin//cd_data_extractor` (po dořešení buildů) a nasměruj výstup do `macos/data/`.
+3. `macos/data/` zůstává verzovací čisté (ignorováno v `.gitignore`).
+
+## Testování
+- Spusť server: `macos/tools/run_server.command -p 9876`.
+- Spusť klienta: `macos/tools/run_client.command --some-option` (parametry dle `MANUAL.md`).
+- Launcher ověří dostupnost dat a aktualizací.
+
+## Dokumentace
+
+- **[BUILD_GUIDE.md](tools/BUILD_GUIDE.md)** - Kompletní návod na kompilaci
+- **[BUILD_README.md](tools/BUILD_README.md)** - Rychlý přehled build skriptů
+- **[MacOS implementationplan.md](development/Documents/MacOS%20implementationplan.md)** - Technický plán implementace
+
+## Další kroky
+- Zvážit vytvoření `.dmg` nebo `.pkg` pro distribuci
+- Udržovat dokumentaci aktuální
diff --git a/macos/app_arm64/remove_quarantine.command b/macos/app_arm64/remove_quarantine.command
new file mode 100755
index 0000000..5f78588
--- /dev/null
+++ b/macos/app_arm64/remove_quarantine.command
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Remove quarantine attribute from all app bundles in this directory
+# Run this after copying the apps to a new Mac
+
+cd "$(dirname "$0")"
+
+echo "Removing quarantine attribute from app bundles..."
+echo "(You may be prompted for your password)"
+
+for app in *.app; do
+ if [[ -d "$app" ]]; then
+ echo " → $app"
+ sudo xattr -cr "$app"
+ fi
+done
+
+echo "Done. You can now run the applications."
+
+# If this does not work, try the following:
+# 1. Open the Terminal app
+# Method 1: sudo xattr -d com.apple.quarantine (odstraní jen karanténu)
+# Method 2: sudo xattr -cr (odstraní všechny extended attributes recursively)
+# Method 3: bez sudo (pro soubory vlastněné uživatelem)
+# Method 4: xattr -c bez sudo
\ No newline at end of file
diff --git a/macos/app_templates/Game/Contents/Info.plist b/macos/app_templates/Game/Contents/Info.plist
new file mode 100644
index 0000000..53381a8
--- /dev/null
+++ b/macos/app_templates/Game/Contents/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ fpc_atomic
+ CFBundleIdentifier
+ cz.fpcatomic.client
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ FPC Atomic
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ 11.0
+ LSApplicationCategoryType
+ public.app-category.games
+ NSHighResolutionCapable
+
+ CFBundleIconFile
+ AppIcon
+ LSUIElement
+
+
+
diff --git a/macos/app_templates/Game/Contents/MacOS/.keep b/macos/app_templates/Game/Contents/MacOS/.keep
new file mode 100644
index 0000000..9e5f5f8
--- /dev/null
+++ b/macos/app_templates/Game/Contents/MacOS/.keep
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/macos/app_templates/Game/Contents/PkgInfo b/macos/app_templates/Game/Contents/PkgInfo
new file mode 100644
index 0000000..cae6d0a
--- /dev/null
+++ b/macos/app_templates/Game/Contents/PkgInfo
@@ -0,0 +1,2 @@
+APPL????
+
diff --git a/macos/app_templates/Game/Contents/entitlements.plist b/macos/app_templates/Game/Contents/entitlements.plist
new file mode 100644
index 0000000..9ce849e
--- /dev/null
+++ b/macos/app_templates/Game/Contents/entitlements.plist
@@ -0,0 +1,13 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-library-validation
+
+
+
+
diff --git a/macos/app_templates/Launcher/Contents/Info.plist b/macos/app_templates/Launcher/Contents/Info.plist
new file mode 100644
index 0000000..043e4a7
--- /dev/null
+++ b/macos/app_templates/Launcher/Contents/Info.plist
@@ -0,0 +1,29 @@
+
+
+
+
+ CFBundleName
+ FPC Atomic Launcher
+ CFBundleDisplayName
+ FPC Atomic Launcher
+ CFBundleIdentifier
+ cz.pavelzverina.fpcatomic.launcher
+ CFBundleVersion
+ 0.12009
+ CFBundleShortVersionString
+ 0.12009
+ CFBundleExecutable
+ atomic_launcher
+ CFBundlePackageType
+ APPL
+ LSMinimumSystemVersion
+ 11.0
+ NSHighResolutionCapable
+
+ CFBundleIconFile
+ AppIcon
+
+
+
+
+
diff --git a/macos/app_templates/Launcher/Contents/MacOS/.gitkeep b/macos/app_templates/Launcher/Contents/MacOS/.gitkeep
new file mode 100644
index 0000000..fd40910
--- /dev/null
+++ b/macos/app_templates/Launcher/Contents/MacOS/.gitkeep
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/macos/app_templates/Launcher/Contents/PkgInfo b/macos/app_templates/Launcher/Contents/PkgInfo
new file mode 100644
index 0000000..cae6d0a
--- /dev/null
+++ b/macos/app_templates/Launcher/Contents/PkgInfo
@@ -0,0 +1,2 @@
+APPL????
+
diff --git a/macos/app_templates/Launcher/Contents/entitlements.plist b/macos/app_templates/Launcher/Contents/entitlements.plist
new file mode 100644
index 0000000..9ce849e
--- /dev/null
+++ b/macos/app_templates/Launcher/Contents/entitlements.plist
@@ -0,0 +1,13 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-library-validation
+
+
+
+
diff --git a/macos/app_templates/Server/Contents/Info.plist b/macos/app_templates/Server/Contents/Info.plist
new file mode 100644
index 0000000..701e6d3
--- /dev/null
+++ b/macos/app_templates/Server/Contents/Info.plist
@@ -0,0 +1,29 @@
+
+
+
+
+ CFBundleName
+ FPC Atomic Server
+ CFBundleDisplayName
+ FPC Atomic Server
+ CFBundleIdentifier
+ cz.pavelzverina.fpcatomic.server
+ CFBundleVersion
+ 0.12009
+ CFBundleShortVersionString
+ 0.12009
+ CFBundleExecutable
+ run_server
+ CFBundlePackageType
+ APPL
+ LSMinimumSystemVersion
+ 11.0
+ NSHighResolutionCapable
+
+ CFBundleIconFile
+ AppIcon
+
+
+
+
+
diff --git a/macos/app_templates/Server/Contents/MacOS/.gitkeep b/macos/app_templates/Server/Contents/MacOS/.gitkeep
new file mode 100644
index 0000000..fd40910
--- /dev/null
+++ b/macos/app_templates/Server/Contents/MacOS/.gitkeep
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/macos/app_templates/Server/Contents/MacOS/run_server b/macos/app_templates/Server/Contents/MacOS/run_server
new file mode 100644
index 0000000..c47742c
--- /dev/null
+++ b/macos/app_templates/Server/Contents/MacOS/run_server
@@ -0,0 +1,67 @@
+#!/bin/zsh
+set -euo pipefail
+
+APP_DIR="$(cd "$(dirname "$0")" && pwd)"
+SERVER_BIN="${APP_DIR}/atomic_server"
+
+if [[ ! -x "${SERVER_BIN}" ]]; then
+ /usr/bin/osascript <
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-library-validation
+
+
+
+
diff --git a/macos/app_universal/remove_quarantine.command b/macos/app_universal/remove_quarantine.command
new file mode 100755
index 0000000..5f78588
--- /dev/null
+++ b/macos/app_universal/remove_quarantine.command
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Remove quarantine attribute from all app bundles in this directory
+# Run this after copying the apps to a new Mac
+
+cd "$(dirname "$0")"
+
+echo "Removing quarantine attribute from app bundles..."
+echo "(You may be prompted for your password)"
+
+for app in *.app; do
+ if [[ -d "$app" ]]; then
+ echo " → $app"
+ sudo xattr -cr "$app"
+ fi
+done
+
+echo "Done. You can now run the applications."
+
+# If this does not work, try the following:
+# 1. Open the Terminal app
+# Method 1: sudo xattr -d com.apple.quarantine (odstraní jen karanténu)
+# Method 2: sudo xattr -cr (odstraní všechny extended attributes recursively)
+# Method 3: bez sudo (pro soubory vlastněné uživatelem)
+# Method 4: xattr -c bez sudo
\ No newline at end of file
diff --git a/macos/app_x86_64/remove_quarantine.command b/macos/app_x86_64/remove_quarantine.command
new file mode 100755
index 0000000..5f78588
--- /dev/null
+++ b/macos/app_x86_64/remove_quarantine.command
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Remove quarantine attribute from all app bundles in this directory
+# Run this after copying the apps to a new Mac
+
+cd "$(dirname "$0")"
+
+echo "Removing quarantine attribute from app bundles..."
+echo "(You may be prompted for your password)"
+
+for app in *.app; do
+ if [[ -d "$app" ]]; then
+ echo " → $app"
+ sudo xattr -cr "$app"
+ fi
+done
+
+echo "Done. You can now run the applications."
+
+# If this does not work, try the following:
+# 1. Open the Terminal app
+# Method 1: sudo xattr -d com.apple.quarantine (odstraní jen karanténu)
+# Method 2: sudo xattr -cr (odstraní všechny extended attributes recursively)
+# Method 3: bez sudo (pro soubory vlastněné uživatelem)
+# Method 4: xattr -c bez sudo
\ No newline at end of file
diff --git a/macos/assets/AtomicBomberIcon.icns b/macos/assets/AtomicBomberIcon.icns
new file mode 100644
index 0000000..750ddbc
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.icns differ
diff --git a/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-2.png b/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-2.png
new file mode 100644
index 0000000..48fe671
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-2.png differ
diff --git a/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-gradient.jpg b/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-gradient.jpg
new file mode 100644
index 0000000..56ff45d
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.icon/Assets/bomberman-ikona-gradient.jpg differ
diff --git a/macos/assets/AtomicBomberIcon.icon/icon.json b/macos/assets/AtomicBomberIcon.icon/icon.json
new file mode 100644
index 0000000..8ca0cb1
--- /dev/null
+++ b/macos/assets/AtomicBomberIcon.icon/icon.json
@@ -0,0 +1,66 @@
+{
+ "fill" : {
+ "automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000"
+ },
+ "groups" : [
+ {
+ "layers" : [
+ {
+ "glass" : false,
+ "image-name" : "bomberman-ikona-2.png",
+ "name" : "bomberman-ikona-2",
+ "position-specializations" : [
+ {
+ "idiom" : "square",
+ "value" : {
+ "scale" : 0.35,
+ "translation-in-points" : [
+ 41.04207201411085,
+ -100.55361209199803
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "blend-mode" : "normal",
+ "glass" : false,
+ "hidden-specializations" : [
+ {
+ "idiom" : "square",
+ "value" : false
+ }
+ ],
+ "image-name" : "bomberman-ikona-gradient.jpg",
+ "name" : "bomberman-ikona-gradient",
+ "position-specializations" : [
+ {
+ "idiom" : "square",
+ "value" : {
+ "scale" : 0.3,
+ "translation-in-points" : [
+ 0,
+ 0
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "shadow" : {
+ "kind" : "neutral",
+ "opacity" : 0.5
+ },
+ "translucency" : {
+ "enabled" : true,
+ "value" : 0.5
+ }
+ }
+ ],
+ "supported-platforms" : {
+ "circles" : [
+ "watchOS"
+ ],
+ "squares" : "shared"
+ }
+}
\ No newline at end of file
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_128x128.png b/macos/assets/AtomicBomberIcon.iconset/icon_128x128.png
new file mode 100644
index 0000000..0cc4379
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_128x128.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_128x128@2x.png b/macos/assets/AtomicBomberIcon.iconset/icon_128x128@2x.png
new file mode 100644
index 0000000..f50b75b
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_128x128@2x.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_16x16.png b/macos/assets/AtomicBomberIcon.iconset/icon_16x16.png
new file mode 100644
index 0000000..7a7339b
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_16x16.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_16x16@2x.png b/macos/assets/AtomicBomberIcon.iconset/icon_16x16@2x.png
new file mode 100644
index 0000000..ee6ca50
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_16x16@2x.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_256x256.png b/macos/assets/AtomicBomberIcon.iconset/icon_256x256.png
new file mode 100644
index 0000000..f50b75b
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_256x256.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_256x256@2x.png b/macos/assets/AtomicBomberIcon.iconset/icon_256x256@2x.png
new file mode 100644
index 0000000..9addf0b
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_256x256@2x.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_32x32.png b/macos/assets/AtomicBomberIcon.iconset/icon_32x32.png
new file mode 100644
index 0000000..ee6ca50
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_32x32.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_32x32@2x.png b/macos/assets/AtomicBomberIcon.iconset/icon_32x32@2x.png
new file mode 100644
index 0000000..a2dcf11
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_32x32@2x.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_512x512.png b/macos/assets/AtomicBomberIcon.iconset/icon_512x512.png
new file mode 100644
index 0000000..9addf0b
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_512x512.png differ
diff --git a/macos/assets/AtomicBomberIcon.iconset/icon_512x512@2x.png b/macos/assets/AtomicBomberIcon.iconset/icon_512x512@2x.png
new file mode 100644
index 0000000..63685ae
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.iconset/icon_512x512@2x.png differ
diff --git a/macos/assets/AtomicBomberIcon.png b/macos/assets/AtomicBomberIcon.png
new file mode 100644
index 0000000..63685ae
Binary files /dev/null and b/macos/assets/AtomicBomberIcon.png differ
diff --git a/macos/assets/README.md b/macos/assets/README.md
new file mode 100644
index 0000000..59d0d6a
--- /dev/null
+++ b/macos/assets/README.md
@@ -0,0 +1,50 @@
+# Assets Directory
+
+This directory contains application assets that are not committed to the Git repository, typically due to licensing restrictions.
+
+## Application Icon
+
+### Option 1: Direct .icns file (Recommended)
+
+Place your application icon file directly here:
+
+- **Icon file**: `AtomicBomberIcon.icns`
+- **Location**: Copy `AtomicBomberIcon.icns` to this directory (`macos/assets/AtomicBomberIcon.icns`)
+- **Usage**: The build script (`../tools/build_app_bundles.command`) will automatically copy this icon to all `.app` bundles during the build process
+
+### Option 2: Create .icns from PNG/JPG
+
+If you only have a PNG or JPG image (like `AtomicBomberIcon.icon/Assets/bomberman-ikona-gradient.jpg`), you can create a `.icns` file:
+
+1. **Using online tools**: Upload your PNG to an online converter like:
+ - https://cloudconvert.com/png-to-icns
+ - https://iconverticons.com/online/
+
+2. **Using macOS tools** (requires creating an icon set):
+ ```bash
+ # Create iconset directory structure
+ mkdir -p AtomicBomberIcon.iconset
+
+ # Copy image to various sizes (macOS requires specific sizes)
+ sips -z 16 16 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_16x16.png
+ sips -z 32 32 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_16x16@2x.png
+ sips -z 32 32 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_32x32.png
+ sips -z 64 64 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_32x32@2x.png
+ sips -z 128 128 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_128x128.png
+ sips -z 256 256 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_128x128@2x.png
+ sips -z 256 256 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_256x256.png
+ sips -z 512 512 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_256x256@2x.png
+ sips -z 512 512 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_512x512.png
+ sips -z 1024 1024 bomberman-ikona-gradient.jpg --out AtomicBomberIcon.iconset/icon_512x512@2x.png
+
+ # Convert iconset to .icns
+ iconutil -c icns AtomicBomberIcon.iconset -o AtomicBomberIcon.icns
+
+ # Move to assets directory
+ mv AtomicBomberIcon.icns ../AtomicBomberIcon.icns
+ ```
+
+The icon will be placed in `Contents/Resources/AppIcon.icns` within each application bundle.
+
+### Note
+The icon file is excluded from Git (see `.gitignore`). You need to place it here manually on each machine where you build the application bundles.
diff --git a/macos/assets/dmg_background.afdesign b/macos/assets/dmg_background.afdesign
new file mode 100644
index 0000000..c5f2914
Binary files /dev/null and b/macos/assets/dmg_background.afdesign differ
diff --git a/macos/assets/dmg_background.png b/macos/assets/dmg_background.png
new file mode 100644
index 0000000..5d73e4a
Binary files /dev/null and b/macos/assets/dmg_background.png differ
diff --git a/macos/development/Documents/MacOS b/macos/development/Documents/MacOS
new file mode 100644
index 0000000..e69de29
diff --git a/macos/development/Documents/MacOS implementationplan.md b/macos/development/Documents/MacOS implementationplan.md
new file mode 100644
index 0000000..33a8411
--- /dev/null
+++ b/macos/development/Documents/MacOS implementationplan.md
@@ -0,0 +1,57 @@
+# Plán implementace macOS buildů pro FPC Atomic
+
+## 1. Příprava prostředí
+- Nainstalovat FPC ≥ 3.2.2 a Lazarus IDE (Apple Silicon/Intel balíček).
+- Přidat externí jednotky do `units/`: `dglOpenGL.pas`, `bass.pas`, `sdl2_for_pascal`.
+- Nainstalovat do systému runtime knihovny (`SDL2`, `libbass.dylib`, příp. `libSDL2_mixer.dylib`) a ověřit je přes `otool -L`.
+
+## 2. Konfigurace projektů
+- V `.lpi` souborech (`client`, `server`, `launcher`, `ai`) nastavit cestu k externím jednotkám.
+- Přidat build mód `macos` s výstupem do `macos/bin/`.
+// - Zajistit, že `sdl2_cfg.inc` používá dynamické linkování (`SDL_RUNTIME_LOADING`).
+
+## 3. Kompilace
+- Pro arm64 používat `lazbuild --build-mode=macos_arm64 --lazarusdir=/Applications/Lazarus_3.9 .lpi`.
+- Linker musí běžet přes `ld-classic`, takže jsou v `.lpi` nastaveny parametr `-k-ld_classic`.
+- SDL2 se načítá runtime (`SDL_RUNTIME_LOADING`), proto není potřeba linkovat `libSDL2.dylib`; BASS se linkuje explicitně (`-k /libbass.dylib`).
+- Po kompilaci zkontrolovat binárky (`file`, `otool -L`), zda jsou `Mach-O 64-bit` a mají správné závislosti.
+
+## 4. Knihovny a bundlování
+- Zkopírovat `libbass.dylib` (a případně `libSDL2.dylib`) do `macos/lib//`.
+- RPATH je přidán v `.lpi` (`-k-rpath -k@executable_path/../lib`).
+- Pro `$(TargetCPU)=aarch64` je v `macos/lib` vytvořen symlink `aarch64 -> arm64`.
+
+## 5. Struktura balíčku
+```
+macos/
+ bin/
+ atomic_launcher
+ fpc_atomic
+ atomic_server
+ lib/
+ libSDL2.dylib
+ libbass.dylib
+ data/
+ atomic/
+ maps/
+ tools/
+ run_launcher.command
+ run_server.command
+```
+
+## 6. Integrace originálních dat
+- Vytvořit `macos/game_assets/` pro soukromé soubory a přidat cestu do `.gitignore`.
+- Spustit `cd_data_extractor` tak, aby výstup směřoval do `macos/data/`.
+
+## 7. Testování
+- Spustit `./macos/bin/atomic_launcher` a dokončit instalaci dat.
+- Ověřit běh klienta, serveru i AI modulů na macOS.
+
+## 8. Dokumentace a distribuce
+- Připravit `README_mac.md` se stručným návodem.
+- Rozmyslet signování binárek a případný `.dmg` balíček.
+- Udržovat `macos/development/Documents/MacOS implementationplan.md` aktuální.
+
+## 9. Cross-build pro x86_64
+- Lazarus balík obsahuje `ppcx64`, ale je potřeba dodělat LCL jednotky pro `x86_64-darwin` (`Tools → Build Lazarus with Profile` nebo `lazbuild --cpu=x86_64 --os=darwin --build-ide=`).
+- Po zprovoznění cross jednotek lze použít `lazbuild --build-mode=macos_x86_64`.
diff --git a/macos/tools/BUILD_GUIDE.md b/macos/tools/BUILD_GUIDE.md
new file mode 100644
index 0000000..c4792b4
--- /dev/null
+++ b/macos/tools/BUILD_GUIDE.md
@@ -0,0 +1,404 @@
+# FPC Atomic - macOS Build Guide
+
+Kompletní návod pro kompilaci FPC Atomic na macOS pro obě architektury (ARM64 a x86_64).
+
+## Obsah
+
+1. [Požadavky](#požadavky)
+2. [Příprava prostředí](#příprava-prostředí)
+3. [Příprava knihoven](#příprava-knihoven)
+4. [Kompilace](#kompilace)
+5. [Vytvoření app bundlů](#vytvoření-app-bundlů)
+6. [Řešení problémů](#řešení-problémů)
+
+---
+
+## Požadavky
+
+### Základní nástroje
+
+- **macOS** 10.15 (Catalina) nebo novější
+- **Xcode Command Line Tools**: `xcode-select --install`
+- **Free Pascal Compiler** 3.2.2 nebo novější (balíček pro Intel+ARM)
+- **Lazarus IDE** 3.9 nebo novější (s podporou `lazbuild`)
+- **Homebrew** (pro instalaci knihoven)
+
+### Pascal jednotky
+
+Tyto jednotky musí být umístěny v `units/`:
+
+- `dglOpenGL.pas` - stáhnout z https://github.com/saschawillems/dglopengl
+- `bass.pas` - stáhnout z https://www.un4seen.com/
+- `sdl2_for_pascal/` - hlavičky SDL2 z https://github.com/PascalCorpsman/SDL2-for-Pascal
+
+### Lazarus balíčky
+
+V Lazarus IDE nainstaluj:
+- **Lnet** z https://github.com/PascalCorpsman/lnet
+- **LazOpenGLContext** (z dostupných balíčků v IDE)
+
+---
+
+## Příprava prostředí
+
+### 1. Instalace Xcode Command Line Tools
+
+```bash
+xcode-select --install
+```
+
+### 2. Instalace Free Pascal a Lazarus
+
+Stáhni a nainstaluj z https://www.lazarus-ide.org/:
+- Balíček obsahující FPC i Lazarus
+- Verze podporující jak ARM64, tak x86_64
+
+### 3. Ověření instalace
+
+```bash
+# Zkontroluj FPC
+fpc -i
+
+# Zkontroluj lazbuild
+lazbuild --version
+
+# Zkontroluj x86_64 kompilátor (pro cross-compilation)
+ppcx64 -i
+```
+
+---
+
+## Příprava knihoven
+
+### ARM64 (Apple Silicon)
+
+#### SDL2
+
+SDL2 se načítá runtime, takže není potřeba explicitní linkování. Framework nebo dylib musí být k dispozici:
+
+```bash
+# Možnost 1: Homebrew (doporučeno)
+brew install sdl2
+
+# Možnost 2: Stáhnout framework z https://www.libsdl.org/download-2.0.php
+# a zkopírovat do macos/lib/arm64/frameworks/
+```
+
+#### BASS
+
+```bash
+# Stáhni libbass.dylib z https://www.un4seen.com/
+# Zkopíruj do:
+cp libbass.dylib macos/lib/arm64/
+```
+
+#### OpenSSL
+
+OpenSSL knihovny jsou obvykle k dispozici přes Homebrew:
+
+```bash
+brew install openssl@3
+
+# Zkopíruj knihovny (pokud jsou potřeba v projektu)
+cp /opt/homebrew/lib/libssl.3.dylib macos/lib/arm64/ 2>/dev/null || true
+cp /opt/homebrew/lib/libcrypto.3.dylib macos/lib/arm64/ 2>/dev/null || true
+```
+
+### x86_64 (Intel Macs / Cross-compilation)
+
+Pro kompilaci x86_64 verze na Apple Silicon Macu je potřeba:
+
+#### 1. Rosetta Homebrew (pro x86_64 knihovny)
+
+```bash
+# Instalace Rosetta Homebrew
+arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+# Instalace OpenSSL@3 přes Rosetta Homebrew
+arch -x86_64 /usr/local/bin/brew install openssl@3
+```
+
+**Poznámka:** Rosetta Homebrew se instaluje do `/usr/local` a neovlivní tvůj ARM64 Homebrew v `/opt/homebrew`.
+
+#### 2. Automatická příprava knihoven
+
+Skript `prepare_x86_64_libs.command` automaticky:
+- Ověří architektury všech knihoven
+- Zkopíruje x86_64 OpenSSL z Rosetta Homebrew
+- Vytvoří `libSDL2.dylib` z frameworku
+- Zobrazí varování, pokud něco chybí
+
+```bash
+# Spusť ručně (nebo se spustí automaticky při buildu)
+./macos/tools/prepare_x86_64_libs.command
+```
+
+#### 3. SDL2 Framework
+
+SDL2 framework pro x86_64 musí být v:
+```
+macos/lib/x86_64/frameworks/SDL2.framework/
+```
+
+Stáhni z https://www.libsdl.org/download-2.0.php a zkopíruj správnou architekturu.
+
+#### 4. BASS
+
+```bash
+# Zkopíruj x86_64 verzi libbass.dylib
+cp libbass.dylib macos/lib/x86_64/
+```
+
+---
+
+## Kompilace
+
+### Rychlý build (doporučeno)
+
+Pro automatický build všech aplikací a vytvoření app bundlů:
+
+```bash
+# ARM64 (Apple Silicon)
+./macos/tools/build_all_arm64.command
+
+# x86_64 (Intel Macs)
+./macos/tools/build_all_x86_64.command
+```
+
+### Ruční build
+
+#### ARM64
+
+```bash
+lazbuild --build-mode=macos_arm64 --lazarusdir=/Applications/Lazarus_3.9 client/fpc_atomic.lpi
+lazbuild --build-mode=macos_arm64 --lazarusdir=/Applications/Lazarus_3.9 launcher/atomic_launcher.lpi
+lazbuild --build-mode=macos_arm64 --lazarusdir=/Applications/Lazarus_3.9 server/atomic_server.lpi
+lazbuild --build-mode=macos_arm64 --lazarusdir=/Applications/Lazarus_3.9 ai/ai.lpi
+```
+
+#### x86_64
+
+```bash
+# Ujisti se, že máš x86_64 kompilátor
+export PP=/usr/local/bin/ppcx64 # nebo cesta k tvému ppcx64
+
+lazbuild --build-mode=macos_x86_64 --lazarusdir=/Applications/Lazarus_3.9 --compiler=/usr/local/bin/ppcx64 client/fpc_atomic.lpi
+lazbuild --build-mode=macos_x86_64 --lazarusdir=/Applications/Lazarus_3.9 --compiler=/usr/local/bin/ppcx64 launcher/atomic_launcher.lpi
+lazbuild --build-mode=macos_x86_64 --lazarusdir=/Applications/Lazarus_3.9 --compiler=/usr/local/bin/ppcx64 server/atomic_server.lpi
+lazbuild --build-mode=macos_x86_64 --lazarusdir=/Applications/Lazarus_3.9 --compiler=/usr/local/bin/ppcx64 ai/ai.lpi
+```
+
+### Výstup
+
+Zkompilované binárky jsou v:
+- `macos/bin/arm64/` (pro Apple Silicon)
+- `macos/bin/x86_64/` (pro Intel Macs)
+
+---
+
+## Vytvoření app bundlů
+
+### Automatické vytvoření
+
+App bundly se vytvoří automaticky při použití `build_all_*.command` skriptů.
+
+### Ruční vytvoření
+
+```bash
+# ARM64
+./macos/tools/build_app_bundles.command arm64
+
+# x86_64
+./macos/tools/build_app_bundles.command x86_64
+```
+
+### Výstup
+
+App bundly jsou v:
+- `macos/app_arm64/`:
+ - `FPCAtomic.app` (klient)
+ - `FPCAtomicLauncher.app` (launcher + klient + server)
+ - `FPCAtomicServer.app` (server)
+
+- `macos/app_x86_64/`:
+ - `FPCAtomic.app` (klient)
+ - `FPCAtomicLauncher.app` (launcher + klient + server)
+ - `FPCAtomicServer.app` (server)
+
+### Struktura app bundle
+
+```
+FPCAtomic.app/
+ Contents/
+ MacOS/
+ fpc_atomic # Hlavní executable
+ data -> ../../../data # Symlink na sdílená data
+ lib/
+ libSDL2.dylib
+ libbass.dylib
+ libai.dylib
+ libssl.3.dylib
+ libcrypto.3.dylib
+ Resources/
+ AppIcon.icns
+ Info.plist
+```
+
+### Code signing
+
+App bundly jsou automaticky podepsané ad-hoc podpisem (`codesign --force --deep --sign -`), což je dostačující pro lokální testování.
+
+**Pro distribuci** je potřeba Developer ID podpis a notarizace (viz sekce Řešení problémů).
+
+---
+
+## Řešení problémů
+
+### Problém: Chybějící x86_64 knihovny
+
+**Příznaky:**
+```
+Library not loaded: @rpath/libssl.3.dylib
+```
+
+**Řešení:**
+1. Nainstaluj Rosetta Homebrew (viz sekce Příprava knihoven)
+2. Spusť `./macos/tools/prepare_x86_64_libs.command`
+3. Ověř architektury: `file macos/lib/x86_64/*.dylib`
+
+### Problém: SDL2 knihovna nenalezena
+
+**Příznaky:**
+```
+Library not loaded: @rpath/libSDL2.dylib
+```
+
+**Řešení:**
+1. Ověř, že `libSDL2.dylib` existuje v `macos/lib//`
+2. Pokud chybí, skript `prepare_x86_64_libs.command` ho vytvoří z frameworku
+3. Zkontroluj RPATH: `otool -l | grep LC_RPATH`
+
+### Problém: Neplatný code signature
+
+**Příznaky:**
+```
+code signature invalid
+```
+
+**Řešení:**
+```bash
+# Znovu podepiš všechny knihovny
+for lib in macos/app_*/FPCAtomic.app/Contents/lib/*.dylib; do
+ codesign --force --sign - "$lib"
+done
+
+# Znovu podepiš app bundly
+for app in macos/app_*/FPCAtomic.app; do
+ codesign --force --deep --sign - "$app"
+done
+```
+
+### Problém: Gatekeeper blokuje aplikaci
+
+**Příznaky:**
+```
+"Aplikace je poškozena a nelze ji otevřít"
+```
+
+**Řešení pro lokální testování:**
+```bash
+# Odstranění quarantine atributu
+xattr -cr macos/app_*/FPCAtomic.app
+```
+
+**Pro distribuci:**
+- Použij Developer ID Application certifikát
+- Podepiš všechny komponenty
+- Notarizuj aplikaci přes Apple
+
+### Problém: Cross-compilation selhává
+
+**Příznaky:**
+```
+ld: library not found for -lSDL2
+```
+
+**Řešení:**
+1. Ověř, že máš x86_64 kompilátor: `ppcx64 -i`
+2. Zkontroluj, že SDL2 není linkován staticky (používá se runtime loading)
+3. Ověř nastavení v `client/fpc_atomic.lpi` - mělo by být `SDL_RUNTIME_LOADING`
+
+### Problém: Chybějící data
+
+**Příznaky:**
+Aplikace se spustí, ale chybí grafika/zvuky
+
+**Řešení:**
+1. Zkopíruj obsah originálního CD do `macos/game_assets/`
+2. Spusť launcher a nech ho extrahovat data do `macos/data/`
+3. Ověř, že symlink `Contents/MacOS/data` existuje v app bundle
+
+---
+
+## Testování
+
+### Spuštění aplikací
+
+```bash
+# Launcher
+open macos/app_arm64/FPCAtomicLauncher.app
+
+# Klient (přímo)
+macos/app_arm64/FPCAtomic.app/Contents/MacOS/fpc_atomic
+
+# Server
+open macos/app_arm64/FPCAtomicServer.app
+```
+
+### Ověření architektur
+
+```bash
+# Binárky
+file macos/bin/arm64/fpc_atomic
+file macos/bin/x86_64/fpc_atomic
+
+# Knihovny
+file macos/lib/arm64/*.dylib
+file macos/lib/x86_64/*.dylib
+
+# App bundly
+file macos/app_arm64/FPCAtomic.app/Contents/MacOS/fpc_atomic
+file macos/app_x86_64/FPCAtomic.app/Contents/MacOS/fpc_atomic
+```
+
+### Ověření podpisů
+
+```bash
+# App bundle
+codesign -dv macos/app_arm64/FPCAtomic.app
+
+# Knihovny
+codesign -dv macos/app_arm64/FPCAtomic.app/Contents/lib/*.dylib
+
+# Ověření integrity
+codesign --verify --verbose macos/app_arm64/FPCAtomic.app
+```
+
+---
+
+## Další kroky
+
+- **Distribuce:** Pro distribuci mimo App Store je potřeba Developer ID podpis a notarizace
+- **DMG balíček:** Vytvoř `.dmg` pro snadnou distribuci
+- **Aktualizace:** Udržuj tento dokument aktuální s novými změnami
+
+---
+
+## Užitečné odkazy
+
+- [Lazarus IDE](https://www.lazarus-ide.org/)
+- [Free Pascal Compiler](https://www.freepascal.org/)
+- [SDL2](https://www.libsdl.org/)
+- [BASS Audio Library](https://www.un4seen.com/)
+- [Homebrew](https://brew.sh/)
+
diff --git a/macos/tools/BUILD_README.md b/macos/tools/BUILD_README.md
new file mode 100644
index 0000000..d7588c7
--- /dev/null
+++ b/macos/tools/BUILD_README.md
@@ -0,0 +1,93 @@
+# Build Instructions - Quick Reference
+
+> **Pro kompletní návod viz [BUILD_GUIDE.md](BUILD_GUIDE.md)**
+
+## Quick Build
+
+Pro rychlý build všech aplikací a vytvoření app bundlů máte dvě možnosti:
+
+### 1. Použít specializované build commandy (doporučeno)
+
+```bash
+# Build pro Apple Silicon (ARM64)
+./macos/tools/build_all_arm64.command
+
+# Build pro Intel Macs (x86_64)
+./macos/tools/build_all_x86_64.command
+```
+
+### 2. Použít hlavní build command s parametrem
+
+```bash
+./macos/tools/build_all.command [architektura]
+```
+
+Nebo z kořenového adresáře projektu:
+
+```bash
+cd /Users/pavelzverina/AiProjects/fpc_atomic
+./macos/tools/build_all.command [architektura]
+```
+
+### Volba architektury (pro build_all.command)
+
+- `arm64` nebo `aarch64` - Build pro Apple Silicon (ARM64)
+- `x86_64` nebo `intel` - Build pro Intel Macs (x86_64)
+- Bez argumentu - Automatická detekce podle systému
+
+### Příklady
+
+```bash
+# Build pro Apple Silicon (doporučeno)
+./macos/tools/build_all_arm64.command
+
+# Build pro Intel Macs (doporučeno)
+./macos/tools/build_all_x86_64.command
+
+# Nebo pomocí hlavního commandu
+./macos/tools/build_all.command arm64
+./macos/tools/build_all.command x86_64
+./macos/tools/build_all.command # auto-detekce
+```
+
+## Co script dělá
+
+1. **Zkompiluje všechny aplikace** pro zadanou architekturu:
+ - `fpc_atomic` (klient)
+ - `atomic_launcher` (launcher)
+ - `atomic_server` (server)
+ - `ai` (AI knihovna)
+2. **Vytvoří app bundly** - spustí `build_app_bundles.command`
+
+## Výstup
+
+Zkompilované aplikace jsou v:
+- `macos/bin/arm64/` (pro Apple Silicon)
+- `macos/bin/x86_64/` (pro Intel Macs)
+
+App bundly jsou v samostatných adresářích podle architektury:
+- `macos/app_arm64/FPCAtomic.app`
+- `macos/app_arm64/FPCAtomicLauncher.app`
+- `macos/app_arm64/FPCAtomicServer.app`
+
+a pro x86_64:
+- `macos/app_x86_64/FPCAtomic.app`
+- `macos/app_x86_64/FPCAtomicLauncher.app`
+- `macos/app_x86_64/FPCAtomicServer.app`
+
+## Požadavky
+
+- Lazarus IDE s `lazbuild` v PATH
+- macOS development tools
+- Ikona v `macos/assets/AtomicBomberIcon.icns` (nebo PNG pro generování)
+- **Pro x86_64:** Rosetta Homebrew (instaluje se automaticky)
+
+## Detailní dokumentace
+
+Viz **[BUILD_GUIDE.md](BUILD_GUIDE.md)** pro:
+- Kompletní seznam požadavků
+- Přípravu knihoven (SDL2, BASS, OpenSSL)
+- Instalaci Rosetta Homebrew
+- Řešení problémů
+- Code signing a distribuci
+
diff --git a/macos/tools/RELEASE_GUIDE.md b/macos/tools/RELEASE_GUIDE.md
new file mode 100644
index 0000000..9a39795
--- /dev/null
+++ b/macos/tools/RELEASE_GUIDE.md
@@ -0,0 +1,230 @@
+# Release Guide for macOS
+
+This guide explains how to create signed, notarized, and distributable DMG files for FPC Atomic on macOS.
+
+## Prerequisites
+
+1. **Apple Developer Account**
+ - You need an active Apple Developer account ($99/year)
+ - Enroll at: https://developer.apple.com/programs/
+
+2. **Developer ID Certificate**
+ - Log in to https://developer.apple.com/account/
+ - Go to Certificates, Identifiers & Profiles
+ - Create a "Developer ID Application" certificate
+ - Download and install it in your Keychain
+
+3. **Notarization Credentials**
+ - You need your Apple ID email
+ - Create an app-specific password at: https://appleid.apple.com/
+ - Go to "Sign-In and Security" → "App-Specific Passwords"
+ - Create a password for "Xcode" or "Command Line Tools"
+ - Your Team ID (10 characters) - found in your Apple Developer account
+ - **Create a `.env` file** in the project root with these credentials (see Configuration section below)
+
+4. **Command Line Tools**
+ - Xcode Command Line Tools: `xcode-select --install`
+ - `notarytool` (included with Xcode 13+)
+
+## Quick Start
+
+### Option 1: Full Automated Release (Recommended)
+
+```bash
+cd macos/tools
+./create_release.command arm64 # For Apple Silicon
+./create_release.command x86_64 # For Intel Macs
+./create_release.command universal # Universal binary
+```
+
+This will:
+1. Build all binaries and app bundles
+2. Sign them with your Developer ID
+3. Notarize them with Apple
+4. Create a DMG file ready for distribution
+
+### Option 2: Step by Step
+
+```bash
+# 1. Build
+./build_all.command arm64
+
+# 2. Sign and notarize
+# (Credentials are loaded from .env file automatically)
+./sign_and_notarize.command arm64
+
+# 3. Create DMG
+./create_dmg.command arm64
+```
+
+**Note:** If you haven't created a `.env` file, the script will prompt you for credentials or try to find them automatically.
+
+## Configuration
+
+### Using .env File (Recommended)
+
+Create a `.env` file in the project root with your signing credentials:
+
+```bash
+# .env file in project root
+DEVELOPER_ID="Developer ID Application: Your Name (TEAM_ID)"
+APPLE_ID="your@email.com"
+APPLE_ID_PASSWORD="your-app-specific-password"
+TEAM_ID="YOUR10CHARTEAMID"
+NOTARIZE=true
+```
+
+**Note:** The `.env` file is already in `.gitignore`, so your credentials won't be committed to git.
+
+The scripts will automatically load variables from `.env` if it exists.
+
+### Using Environment Variables
+
+Alternatively, you can set these environment variables directly:
+
+```bash
+export DEVELOPER_ID="Developer ID Application: Your Name (TEAM_ID)"
+export APPLE_ID="your@email.com"
+export APPLE_ID_PASSWORD="your-app-specific-password"
+export TEAM_ID="YOUR10CHARTEAMID"
+export NOTARIZE=true # Set to false to skip notarization
+```
+
+## Scripts Overview
+
+### `create_release.command`
+Master script that runs the entire release process:
+- Builds binaries and app bundles
+- Signs with Developer ID
+- Notarizes with Apple
+- Creates DMG file
+
+**Usage:**
+```bash
+./create_release.command [arm64|x86_64|universal] [--skip-notarize]
+```
+
+### `sign_and_notarize.command`
+Signs app bundles with Developer ID and optionally notarizes them.
+
+**Usage:**
+```bash
+./sign_and_notarize.command [arm64|x86_64|universal]
+```
+
+**Features:**
+- Automatically finds Developer ID certificate
+- Signs all libraries, executables, and bundles
+- Submits to Apple for notarization
+- Waits for notarization to complete
+- Staples the notarization ticket
+
+### `create_dmg.command`
+Creates a DMG file with:
+- All three app bundles (FPCAtomic.app, FPCAtomicLauncher.app, FPCAtomicServer.app)
+- Applications folder symlink
+- README.txt with installation instructions
+- Properly configured window layout
+
+**Usage:**
+```bash
+./create_dmg.command [arm64|x86_64|universal]
+```
+
+**Output:**
+- DMG files are created in `releases/` directory
+- Filename format: `FPCAtomic-{VERSION}-{ARCH}.dmg` (if version available)
+- Filename format: `FPCAtomic-{ARCH}.dmg` (if version not available)
+
+## Troubleshooting
+
+### "No Developer ID Application certificate found"
+- Make sure you've created and installed the certificate in Keychain
+- Check with: `security find-identity -v -p codesigning`
+- The certificate name should contain "Developer ID Application"
+- Or set `DEVELOPER_ID` in your `.env` file with the exact certificate name
+
+### "APPLE_ID not set" or "APPLE_ID_PASSWORD not set"
+- Make sure you've created a `.env` file in the project root
+- Check that `APPLE_ID` and `APPLE_ID_PASSWORD` are set in the `.env` file
+- Verify the `.env` file format: `KEY=value` (no spaces around `=`)
+- Make sure you're using an app-specific password, not your regular Apple ID password
+
+### "Notarization failed"
+- Check your Apple ID credentials in `.env` file
+- Make sure you're using an app-specific password, not your regular password
+- Verify your Team ID is correct in `.env` file
+- Check Apple Developer account status
+
+### "Stapling failed"
+- Notarization must complete successfully before stapling
+- Wait a few minutes and try again if notarization just completed
+- Check with: `xcrun notarytool history --apple-id YOUR_EMAIL --password PASSWORD --team-id TEAM_ID`
+
+### "DMG creation failed"
+- Make sure app bundles exist in `macos/app_{ARCH}/`
+- Check disk space (DMG needs ~100-200MB free)
+- Make sure `releases/` directory exists or can be created
+- Try running with `sudo` if permission issues occur
+
+## Testing the Release
+
+### Verify Signing
+```bash
+codesign -dv --verbose=4 macos/app_arm64/FPCAtomic.app
+codesign --verify --verbose macos/app_arm64/FPCAtomic.app
+```
+
+### Verify Notarization
+```bash
+spctl -a -vv -t install macos/app_arm64/FPCAtomic.app
+xcrun stapler validate macos/app_arm64/FPCAtomic.app
+```
+
+### Test DMG
+1. Double-click the DMG file
+2. Verify it opens and shows the apps
+3. Try dragging an app to Applications
+4. Launch the app and verify it runs without security warnings
+
+## GitHub Release
+
+To create a GitHub release:
+
+1. Create the DMG files for all architectures:
+ ```bash
+ ./create_release.command arm64
+ ./create_release.command x86_64
+ ./create_release.command universal
+ ```
+
+2. Go to GitHub Releases: https://github.com/YOUR_REPO/releases
+
+3. Create a new release:
+ - Tag: `v1.0.0` (or your version)
+ - Title: `FPC Atomic v1.0.0 - macOS`
+ - Description: Include installation instructions
+
+4. Upload the DMG files from `releases/` directory:
+ - `releases/FPCAtomic-1.0.0-arm64.dmg`
+ - `releases/FPCAtomic-1.0.0-x86_64.dmg`
+ - `releases/FPCAtomic-1.0.0-universal.dmg`
+
+5. Users can download and install:
+ - Open the DMG
+ - Drag apps to Applications
+ - Launch FPCAtomicLauncher.app
+
+## Security Notes
+
+- **Never commit** your Apple ID password or app-specific password to git
+- Use environment variables or keychain for credentials
+- App-specific passwords are safer than your main Apple ID password
+- Developer ID certificates should be kept secure
+
+## Additional Resources
+
+- [Apple Code Signing Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/)
+- [Notarization Guide](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution)
+- [DMG Creation Guide](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html)
+
diff --git a/macos/tools/SYNC_UPSTREAM.md b/macos/tools/SYNC_UPSTREAM.md
new file mode 100644
index 0000000..dc56018
--- /dev/null
+++ b/macos/tools/SYNC_UPSTREAM.md
@@ -0,0 +1,184 @@
+# Jak synchronizovat změny z upstream repozitáře
+
+Tento dokument popisuje, jak integrovat nové commity z upstream repozitáře (`PascalCorpsman/fpc_atomic`) do vašeho projektu.
+
+## Automatický způsob (doporučeno)
+
+Použijte připravený script:
+
+```bash
+./macos/tools/sync_upstream.command
+```
+
+Script vás provede celým procesem a zeptá se na potřeby.
+
+## Manuální způsob
+
+### 1. Zkontrolujte aktuální stav
+
+```bash
+git status
+```
+
+**Důležité**: Před synchronizací commitněte nebo uložte všechny lokální změny!
+
+### 2. Uložte lokální změny (pokud jsou)
+
+Pokud máte necommitnuté změny, které chcete dočasně uložit:
+
+```bash
+git stash
+```
+
+Nebo je commitněte:
+
+```bash
+git add .
+git commit -m "Popis změn"
+```
+
+### 3. Stáhněte změny z upstream
+
+```bash
+git fetch upstream
+```
+
+Tento příkaz stáhne všechny nové změny z upstream, ale ještě je neintegruje.
+
+### 4. Zobrazte nové commity (volitelné)
+
+```bash
+git log HEAD..upstream/main --oneline
+```
+
+Toto zobrazí seznam nových commitů, které ještě nemáte.
+
+### 5. Integrujte změny
+
+Máte dvě možnosti:
+
+#### A) Merge (doporučeno pro začátečníky)
+
+```bash
+git merge upstream/main
+```
+
+- Vytvoří merge commit
+- Zachová historii
+- Snadnější řešení konfliktů
+
+#### B) Rebase (pro pokročilé)
+
+```bash
+git rebase upstream/main
+```
+
+- Přepíše historii
+- Čistší historie (bez merge commitů)
+- Složitější řešení konfliktů
+
+### 6. Vyřešte konflikty (pokud nastanou)
+
+Pokud dojde ke konfliktům:
+
+1. **Otevřete soubory s konflikty** (Git je označí)
+2. **Vyřešte konflikty** - najdete značky `<<<<<<<`, `=======`, `>>>>>>>`
+3. **Odeberte značky** a nechte správný kód
+4. **Označte soubory jako vyřešené**:
+ ```bash
+ git add
+ ```
+5. **Dokončete merge/rebase**:
+ - Pro merge: `git commit`
+ - Pro rebase: `git rebase --continue`
+
+### 7. Pushněte změny
+
+```bash
+git push origin
+```
+
+Pokud jste použili rebase, možná budete muset použít force push:
+
+```bash
+git push origin --force-with-lease
+```
+
+⚠️ **Pozor**: Force push přepíše historii na remote. Používejte opatrně!
+
+## Tipy
+
+### Zobrazit rozdíly před merge
+
+```bash
+git diff HEAD upstream/main
+```
+
+### Zrušit merge/rebase
+
+Pokud se něco pokazí:
+
+```bash
+# Pro merge
+git merge --abort
+
+# Pro rebase
+git rebase --abort
+```
+
+### Obnovit změny ze stash
+
+Pokud jste použili `git stash`:
+
+```bash
+git stash pop
+```
+
+## Příklad kompletního workflow
+
+```bash
+# 1. Uložit lokální změny
+git stash
+
+# 2. Stáhnout změny
+git fetch upstream
+
+# 3. Zobrazit nové commity
+git log HEAD..upstream/main --oneline
+
+# 4. Merge
+git merge upstream/main
+
+# 5. Obnovit lokální změny
+git stash pop
+
+# 6. Push
+git push origin macos-port
+```
+
+## Řešení problémů
+
+### "upstream remote není nastaven"
+
+```bash
+git remote add upstream https://github.com/PascalCorpsman/fpc_atomic.git
+```
+
+### "Your branch is ahead of 'origin/macos-port'"
+
+To je v pořádku - znamená to, že máte lokální commity, které ještě nejsou na remote. Pushněte je:
+
+```bash
+git push origin macos-port
+```
+
+### "Cannot rebase: You have unstaged changes"
+
+Commitněte nebo stashněte změny před rebase:
+
+```bash
+git stash
+# nebo
+git add . && git commit -m "WIP"
+```
+
diff --git a/macos/tools/build_all.command b/macos/tools/build_all.command
new file mode 100755
index 0000000..49bed26
--- /dev/null
+++ b/macos/tools/build_all.command
@@ -0,0 +1,177 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Build script for FPC Atomic macOS
+# This script compiles all applications and creates app bundles
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+# Allow architecture to be specified as first argument
+if [[ $# -gt 0 ]]; then
+ REQUESTED_ARCH="$1"
+ case "${REQUESTED_ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ BUILD_MODE="macos_arm64"
+ ;;
+ x86_64|intel)
+ TARGET_ARCH="x86_64"
+ BUILD_MODE="macos_x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${REQUESTED_ARCH}" >&2
+ echo "Usage: $0 [arm64|x86_64]" >&2
+ exit 1
+ ;;
+ esac
+else
+ # Detect architecture automatically
+ ARCH="$(uname -m)"
+ case "${ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ BUILD_MODE="macos_arm64"
+ ;;
+ x86_64)
+ TARGET_ARCH="x86_64"
+ BUILD_MODE="macos_x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+BIN_DIR="${PROJECT_ROOT}/bin/macos/${TARGET_ARCH}"
+
+echo "========================================="
+echo "Building FPC Atomic for macOS (${TARGET_ARCH})"
+echo "========================================="
+echo ""
+
+# Check if lazbuild is available
+if ! command -v lazbuild &> /dev/null; then
+ echo "Error: lazbuild not found in PATH" >&2
+ echo "Please install Lazarus IDE or add lazbuild to PATH" >&2
+ exit 1
+fi
+
+# Create bin directory if it doesn't exist
+mkdir -p "${BIN_DIR}"
+
+# Try to find Lazarus directory
+LAZARUS_DIR=""
+if [[ -d "/Applications/Lazarus.app" ]]; then
+ LAZARUS_DIR="/Applications/Lazarus.app/Contents/MacOS"
+elif [[ -d "/Applications/Lazarus_3.9" ]]; then
+ LAZARUS_DIR="/Applications/Lazarus_3.9"
+elif [[ -d "/usr/local/share/lazarus" ]]; then
+ LAZARUS_DIR="/usr/local/share/lazarus"
+fi
+
+LAZBUILD_ARGS=""
+if [[ -n "${LAZARUS_DIR}" ]]; then
+ LAZBUILD_ARGS="--lazarusdir=${LAZARUS_DIR}"
+ echo "Using Lazarus directory: ${LAZARUS_DIR}"
+fi
+
+# Set compiler for cross-compilation if needed
+if [[ "${TARGET_ARCH}" == "x86_64" && "$(uname -m)" == "arm64" ]]; then
+ # Try to find x86_64 compiler
+ X86_64_COMPILER=""
+ if command -v ppcx64 &> /dev/null; then
+ X86_64_COMPILER="$(which ppcx64)"
+ elif [[ -f "/usr/local/bin/ppcx64" ]]; then
+ X86_64_COMPILER="/usr/local/bin/ppcx64"
+ fi
+
+ if [[ -n "${X86_64_COMPILER}" ]]; then
+ export PP="${X86_64_COMPILER}"
+ LAZBUILD_ARGS="${LAZBUILD_ARGS} --compiler=${X86_64_COMPILER}"
+ echo "Using x86_64 compiler: ${X86_64_COMPILER}"
+ else
+ echo "Warning: x86_64 compiler (ppcx64) not found, lazbuild may use wrong compiler" >&2
+ fi
+fi
+
+# Build applications - use eval to properly handle arguments with spaces
+EVAL_CMD="lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\""
+
+# Function to filter build output - removes unnecessary warnings and hints
+filter_build_output() {
+ grep -vE "^Note:|^Hint:|.*Hint:.*not used|SetupCompilerFilename:|SearchCompilerCandidates|using config file|ld: warning: -dylib_file is deprecated|ld: warning: -ld_classic is deprecated|ld: warning: dylib.*was built for newer macOS version|-macosx_version_min has been renamed|replacing existing signature|^Free Pascal Compiler|^Copyright|^Target OS:|^Compiling |^Assembling |^Compiling resource|^Linking |lines compiled|hint\(s\) issued|warning\(s\) issued|error\(s\) issued|^\([0-9]+\) |Warning: \[TPCTargetConfigCache|cannot find real compiler|no unit paths|invalid fpc|missing FPC_FULLVERSION" || true
+}
+
+# Build applications
+echo "Building client (fpc_atomic)..."
+eval lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\" \"${PROJECT_ROOT}/client/fpc_atomic.lpi\" 2>&1 | filter_build_output || {
+ echo "Error: Failed to build client" >&2
+ exit 1
+}
+
+echo "Building launcher (atomic_launcher)..."
+eval lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\" \"${PROJECT_ROOT}/launcher/atomic_launcher.lpi\" 2>&1 | filter_build_output || {
+ echo "Error: Failed to build launcher" >&2
+ exit 1
+}
+
+echo "Building server (atomic_server)..."
+eval lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\" \"${PROJECT_ROOT}/server/atomic_server.lpi\" 2>&1 | filter_build_output || {
+ echo "Error: Failed to build server" >&2
+ exit 1
+}
+
+echo "Building AI library (ai)..."
+eval lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\" \"${PROJECT_ROOT}/ai/ai.lpi\" 2>&1 | filter_build_output || {
+ echo "Warning: Failed to build AI library (may not be critical)" >&2
+}
+
+echo "Building CD Data Extractor GUI (cd_data_extractor)..."
+eval lazbuild ${LAZBUILD_ARGS} --build-mode=\"${BUILD_MODE}\" \"${PROJECT_ROOT}/cd_data_extractor_src/cd_data_extractor.lpi\" 2>&1 | filter_build_output || {
+ echo "Warning: Failed to build CD Data Extractor GUI (may not be critical)" >&2
+}
+
+echo ""
+echo "========================================="
+echo "Checking data directory..."
+echo "========================================="
+echo ""
+
+# Always copy data directory from project root to bin directory
+DATA_SOURCE="${PROJECT_ROOT}/data"
+DATA_TARGET="${BIN_DIR}/data"
+
+if [[ -d "${DATA_SOURCE}" ]]; then
+ echo "Copying data directory from project root to ${BIN_DIR}..."
+ # Use rsync to sync data directory (preserves existing files, adds new ones)
+ mkdir -p "${DATA_TARGET}"
+ rsync -a "${DATA_SOURCE}/" "${DATA_TARGET}/"
+ echo " ✓ Synchronized data directory to ${DATA_TARGET}"
+else
+ echo " ⚠ Warning: Data directory not found at ${DATA_SOURCE}" >&2
+ if [[ ! -d "${DATA_TARGET}" ]]; then
+ echo " ⚠ Warning: Data directory not found at ${DATA_TARGET}" >&2
+ fi
+fi
+
+echo ""
+echo "========================================="
+echo "Creating app bundles..."
+echo "========================================="
+echo ""
+
+# Build app bundles
+"${SCRIPT_DIR}/build_app_bundles.command" "${TARGET_ARCH}"
+
+echo ""
+echo "========================================="
+echo "Build complete!"
+echo "========================================="
+echo "App bundles are in: ${PROJECT_ROOT}/macos/app_${TARGET_ARCH}/"
+echo " - FPCAtomic.app"
+echo " - FPCAtomicLauncher.app"
+echo " - FPCAtomicServer.app"
+echo ""
+
diff --git a/macos/tools/build_all_arm64.command b/macos/tools/build_all_arm64.command
new file mode 100755
index 0000000..7d8b94a
--- /dev/null
+++ b/macos/tools/build_all_arm64.command
@@ -0,0 +1,11 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Build script for FPC Atomic macOS - ARM64 (Apple Silicon)
+# This is a convenience wrapper that calls build_all.command with arm64 parameter
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+
+# Call the main build script with arm64 architecture
+"${SCRIPT_DIR}/build_all.command" arm64
+
diff --git a/macos/tools/build_all_universal.command b/macos/tools/build_all_universal.command
new file mode 100755
index 0000000..6d01a87
--- /dev/null
+++ b/macos/tools/build_all_universal.command
@@ -0,0 +1,230 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Build script for FPC Atomic macOS Universal Binary
+# This script compiles both architectures (arm64 and x86_64) and creates universal binaries
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+echo "========================================="
+echo "Building FPC Atomic for macOS (Universal)"
+echo "========================================="
+echo ""
+
+# Check if lazbuild is available
+if ! command -v lazbuild &> /dev/null; then
+ echo "Error: lazbuild not found in PATH" >&2
+ echo "Please install Lazarus IDE or add lazbuild to PATH" >&2
+ exit 1
+fi
+
+# Check if lipo is available
+if ! command -v lipo &> /dev/null; then
+ echo "Error: lipo not found in PATH" >&2
+ echo "Please install Xcode Command Line Tools" >&2
+ exit 1
+fi
+
+# Try to find Lazarus directory
+LAZARUS_DIR=""
+if [[ -d "/Applications/Lazarus.app" ]]; then
+ LAZARUS_DIR="/Applications/Lazarus.app/Contents/MacOS"
+elif [[ -d "/Applications/Lazarus_3.9" ]]; then
+ LAZARUS_DIR="/Applications/Lazarus_3.9"
+elif [[ -d "/usr/local/share/lazarus" ]]; then
+ LAZARUS_DIR="/usr/local/share/lazarus"
+fi
+
+LAZBUILD_ARGS=""
+if [[ -n "${LAZARUS_DIR}" ]]; then
+ LAZBUILD_ARGS="--lazarusdir=${LAZARUS_DIR}"
+ echo "Using Lazarus directory: ${LAZARUS_DIR}"
+fi
+
+# Note: x86_64 build will be handled by build_all_x86_64.command
+# which properly handles Rosetta and library preparation
+
+# Directories
+BIN_DIR_ARM64="${PROJECT_ROOT}/bin/macos/arm64"
+BIN_DIR_X86_64="${PROJECT_ROOT}/bin/macos/x86_64"
+BIN_DIR_UNIVERSAL="${PROJECT_ROOT}/bin/macos/universal"
+LIB_DIR_ARM64="${PROJECT_ROOT}/lib/macos/arm64"
+LIB_DIR_X86_64="${PROJECT_ROOT}/lib/macos/x86_64"
+LIB_DIR_UNIVERSAL="${PROJECT_ROOT}/lib/macos/universal"
+
+# Create directories
+mkdir -p "${BIN_DIR_UNIVERSAL}" "${LIB_DIR_UNIVERSAL}"
+
+# Function to create universal binary
+create_universal_binary() {
+ local arm64_file="$1"
+ local x86_64_file="$2"
+ local output_file="$3"
+
+ if [[ ! -f "${arm64_file}" ]]; then
+ echo "Error: ARM64 binary not found: ${arm64_file}" >&2
+ return 1
+ fi
+
+ if [[ ! -f "${x86_64_file}" ]]; then
+ echo "Error: x86_64 binary not found: ${x86_64_file}" >&2
+ return 1
+ fi
+
+ echo " Creating universal binary: $(basename "${output_file}")"
+ lipo -create "${arm64_file}" "${x86_64_file}" -output "${output_file}"
+
+ # Verify the universal binary
+ if lipo -info "${output_file}" | grep -q "arm64.*x86_64\|x86_64.*arm64"; then
+ echo " ✓ Universal binary created successfully"
+ else
+ echo " ⚠ Warning: Universal binary verification failed" >&2
+ fi
+}
+
+# Step 1: Build ARM64
+echo "========================================="
+echo "Step 1: Building ARM64 architecture..."
+echo "========================================="
+echo ""
+
+"${SCRIPT_DIR}/build_all.command" arm64 || {
+ echo "Error: Failed to build ARM64 architecture" >&2
+ exit 1
+}
+
+# Step 2: Build x86_64
+echo ""
+echo "========================================="
+echo "Step 2: Building x86_64 architecture..."
+echo "========================================="
+echo ""
+
+# Step 2a: Prepare x86_64 libraries (same as build_all_x86_64.command)
+if [[ "${SKIP_LIB_CHECK:-0}" != "1" ]]; then
+ echo "Step 2a: Preparing x86_64 libraries..."
+ "${SCRIPT_DIR}/prepare_x86_64_libs.command" || {
+ echo "Warning: Library check failed, but continuing build..." >&2
+ }
+ echo ""
+fi
+
+# Step 2b: Build x86_64 (use build_all_x86_64.command which handles Rosetta properly)
+"${SCRIPT_DIR}/build_all_x86_64.command" || {
+ echo "Error: Failed to build x86_64 architecture" >&2
+ exit 1
+}
+
+# Step 3: Create universal binaries
+echo ""
+echo "========================================="
+echo "Step 3: Creating universal binaries..."
+echo "========================================="
+echo ""
+
+# Binaries to merge
+BINARIES=(
+ "fpc_atomic"
+ "atomic_launcher"
+ "atomic_server"
+ "cd_data_extractor"
+)
+
+for binary in "${BINARIES[@]}"; do
+ if [[ -f "${BIN_DIR_ARM64}/${binary}" ]] && [[ -f "${BIN_DIR_X86_64}/${binary}" ]]; then
+ create_universal_binary \
+ "${BIN_DIR_ARM64}/${binary}" \
+ "${BIN_DIR_X86_64}/${binary}" \
+ "${BIN_DIR_UNIVERSAL}/${binary}"
+ else
+ echo " ⚠ Warning: ${binary} not found for both architectures, skipping" >&2
+ fi
+done
+
+# Step 4: Create universal libraries
+echo ""
+echo "========================================="
+echo "Step 4: Creating universal libraries..."
+echo "========================================="
+echo ""
+
+# Libraries to merge (only those that are not already universal)
+LIBRARIES=(
+ "libai.dylib"
+ "libSDL2.dylib"
+)
+
+for lib in "${LIBRARIES[@]}"; do
+ if [[ -f "${LIB_DIR_ARM64}/${lib}" ]] && [[ -f "${LIB_DIR_X86_64}/${lib}" ]]; then
+ # Check if library is already universal
+ if lipo -info "${LIB_DIR_ARM64}/${lib}" 2>/dev/null | grep -q "arm64.*x86_64\|x86_64.*arm64"; then
+ echo " ${lib} is already universal, copying from ARM64"
+ cp "${LIB_DIR_ARM64}/${lib}" "${LIB_DIR_UNIVERSAL}/${lib}"
+ else
+ create_universal_binary \
+ "${LIB_DIR_ARM64}/${lib}" \
+ "${LIB_DIR_X86_64}/${lib}" \
+ "${LIB_DIR_UNIVERSAL}/${lib}"
+ fi
+ else
+ echo " ⚠ Warning: ${lib} not found for both architectures, skipping" >&2
+ fi
+done
+
+# Copy already universal libraries (libbass.dylib, etc.)
+echo " Copying already universal libraries..."
+for lib in "${LIB_DIR_ARM64}"/*.dylib; do
+ lib_name=$(basename "${lib}")
+ if [[ ! -f "${LIB_DIR_UNIVERSAL}/${lib_name}" ]]; then
+ # Check if it's already universal
+ if lipo -info "${lib}" 2>/dev/null | grep -q "arm64.*x86_64\|x86_64.*arm64"; then
+ echo " Copying universal library: ${lib_name}"
+ cp "${lib}" "${LIB_DIR_UNIVERSAL}/${lib_name}"
+ fi
+ fi
+done
+
+# Copy data directory (same for both architectures)
+echo ""
+echo "========================================="
+echo "Step 5: Copying data directory..."
+echo "========================================="
+echo ""
+
+DATA_SOURCE="${PROJECT_ROOT}/data"
+DATA_TARGET="${BIN_DIR_UNIVERSAL}/data"
+
+if [[ -d "${DATA_SOURCE}" ]]; then
+ echo "Copying data directory to ${DATA_TARGET}..."
+ mkdir -p "${DATA_TARGET}"
+ rsync -a "${DATA_SOURCE}/" "${DATA_TARGET}/"
+ echo " ✓ Data directory copied"
+else
+ echo " ⚠ Warning: Data directory not found at ${DATA_SOURCE}" >&2
+fi
+
+# Step 6: Create universal app bundles
+echo ""
+echo "========================================="
+echo "Step 6: Creating universal app bundles..."
+echo "========================================="
+echo ""
+
+"${SCRIPT_DIR}/build_app_bundles.command" universal || {
+ echo "Error: Failed to create universal app bundles" >&2
+ exit 1
+}
+
+echo ""
+echo "========================================="
+echo "Universal build complete!"
+echo "========================================="
+echo "Universal binaries are in: ${BIN_DIR_UNIVERSAL}/"
+echo "Universal libraries are in: ${LIB_DIR_UNIVERSAL}/"
+echo "App bundles are in: ${PROJECT_ROOT}/macos/app_universal/"
+echo " - FPCAtomic.app"
+echo " - FPCAtomicLauncher.app"
+echo " - FPCAtomicServer.app"
+echo ""
+
diff --git a/macos/tools/build_all_x86_64.command b/macos/tools/build_all_x86_64.command
new file mode 100755
index 0000000..b680f06
--- /dev/null
+++ b/macos/tools/build_all_x86_64.command
@@ -0,0 +1,26 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Build script for FPC Atomic macOS - x86_64 (Intel)
+# This is a convenience wrapper that calls build_all.command with x86_64 parameter
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+
+echo "========================================="
+echo "Building FPC Atomic for macOS (x86_64)"
+echo "========================================="
+echo ""
+
+# Step 1: Prepare x86_64 libraries (skip if SKIP_LIB_CHECK is set)
+if [[ "${SKIP_LIB_CHECK:-0}" != "1" ]]; then
+ echo "Step 1: Preparing x86_64 libraries..."
+ "${SCRIPT_DIR}/prepare_x86_64_libs.command" || {
+ echo "Warning: Library check failed, but continuing build..." >&2
+ }
+ echo ""
+fi
+
+# Step 2: Build applications
+echo "Step 2: Building applications..."
+"${SCRIPT_DIR}/build_all.command" x86_64
+
diff --git a/macos/tools/build_app_bundles.command b/macos/tools/build_app_bundles.command
new file mode 100755
index 0000000..ccd01a4
--- /dev/null
+++ b/macos/tools/build_app_bundles.command
@@ -0,0 +1,319 @@
+#!/bin/zsh
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+# Allow architecture to be specified as first argument
+if [[ $# -gt 0 ]]; then
+ REQUESTED_ARCH="$1"
+ case "${REQUESTED_ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64|intel)
+ TARGET_ARCH="x86_64"
+ ;;
+ universal)
+ TARGET_ARCH="universal"
+ ;;
+ *)
+ echo "Unsupported architecture: ${REQUESTED_ARCH}" >&2
+ echo "Usage: $0 [arm64|x86_64|universal]" >&2
+ exit 1
+ ;;
+ esac
+else
+ # Detect architecture automatically
+ ARCH="$(uname -m)"
+ case "${ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64)
+ TARGET_ARCH="x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+BIN_DIR="${PROJECT_ROOT}/bin/macos/${TARGET_ARCH}"
+LIB_DIR="${PROJECT_ROOT}/lib/macos/${TARGET_ARCH}"
+APP_ROOT="${PROJECT_ROOT}/macos/app_${TARGET_ARCH}"
+SHARED_DATA_DIR="${APP_ROOT}/data"
+TEMPLATE_ROOT="${PROJECT_ROOT}/macos/app_templates"
+# Assets directory relative to macos/ directory (where PROJECT_ROOT points)
+ASSETS_DIR="${PROJECT_ROOT}/macos/assets"
+# Check for Icon Composer .icon format first (new format from 2025)
+ICON_DIR="${ASSETS_DIR}/AtomicBomberIcon.icon"
+ICON_FILE="${ASSETS_DIR}/AtomicBomberIcon.icns"
+ICON_USE_FORMAT=""
+
+# Priority 1: Use existing .icns file if it exists
+if [[ -f "${ICON_FILE}" ]]; then
+ ICON_USE_FORMAT="icns"
+# Priority 2: Use .icon format directly (Icon Composer format)
+elif [[ -d "${ICON_DIR}" ]] && [[ -f "${ICON_DIR}/icon.json" ]]; then
+ ICON_USE_FORMAT="icon"
+ # Try to generate .icns from .icon format if .iconset exists
+ if [[ -d "${ASSETS_DIR}/AtomicBomberIcon.iconset" ]] && command -v iconutil &> /dev/null; then
+ iconutil -c icns "${ASSETS_DIR}/AtomicBomberIcon.iconset" -o "${ICON_FILE}" &>/dev/null
+ if [[ -f "${ICON_FILE}" ]]; then
+ ICON_USE_FORMAT="icns"
+ fi
+ fi
+# Priority 3: Generate .icns from PNG source
+elif [[ -d "${ICON_DIR}" ]] && [[ -f "${ICON_DIR}/Assets/bomberman-ikona-2.png" ]] && command -v iconutil &> /dev/null && command -v sips &> /dev/null; then
+ local iconset_dir="${ASSETS_DIR}/AtomicBomberIcon.iconset"
+ mkdir -p "${iconset_dir}"
+ local source_img="${ICON_DIR}/Assets/bomberman-ikona-2.png"
+ sips -z 16 16 "${source_img}" --out "${iconset_dir}/icon_16x16.png" &>/dev/null
+ sips -z 32 32 "${source_img}" --out "${iconset_dir}/icon_16x16@2x.png" &>/dev/null
+ sips -z 32 32 "${source_img}" --out "${iconset_dir}/icon_32x32.png" &>/dev/null
+ sips -z 64 64 "${source_img}" --out "${iconset_dir}/icon_32x32@2x.png" &>/dev/null
+ sips -z 128 128 "${source_img}" --out "${iconset_dir}/icon_128x128.png" &>/dev/null
+ sips -z 256 256 "${source_img}" --out "${iconset_dir}/icon_128x128@2x.png" &>/dev/null
+ sips -z 256 256 "${source_img}" --out "${iconset_dir}/icon_256x256.png" &>/dev/null
+ sips -z 512 512 "${source_img}" --out "${iconset_dir}/icon_256x256@2x.png" &>/dev/null
+ sips -z 512 512 "${source_img}" --out "${iconset_dir}/icon_512x512.png" &>/dev/null
+ sips -z 1024 1024 "${source_img}" --out "${iconset_dir}/icon_512x512@2x.png" &>/dev/null
+ iconutil -c icns "${iconset_dir}" -o "${ICON_FILE}" &>/dev/null
+ if [[ -f "${ICON_FILE}" ]]; then
+ ICON_USE_FORMAT="icns"
+ fi
+fi
+
+if [[ ! -x "${BIN_DIR}/fpc_atomic" ]]; then
+ echo "Missing client binary at ${BIN_DIR}/fpc_atomic. Build it first (lazbuild --build-mode=macos_${TARGET_ARCH})." >&2
+ exit 1
+fi
+
+if [[ ! -x "${BIN_DIR}/atomic_launcher" ]]; then
+ echo "Missing launcher binary at ${BIN_DIR}/atomic_launcher. Build it first." >&2
+ exit 1
+fi
+
+if [[ ! -x "${BIN_DIR}/atomic_server" ]]; then
+ echo "Missing server binary at ${BIN_DIR}/atomic_server. Build it first." >&2
+ exit 1
+fi
+
+if [[ ! -d "${BIN_DIR}/data" ]]; then
+ echo "Missing data directory at ${BIN_DIR}/data. Run the data extractor and copy results before packaging." >&2
+ exit 1
+fi
+
+if [[ ! -d "${LIB_DIR}" ]]; then
+ echo "Missing library directory at ${LIB_DIR}. Ensure macOS libraries are prepared." >&2
+ exit 1
+fi
+
+function sync_libs() {
+ local dest_dir="$1"
+ mkdir -p "${dest_dir}"
+ rsync -a --delete "${LIB_DIR}/" "${dest_dir}/"
+}
+
+function ensure_shared_data() {
+ mkdir -p "${SHARED_DATA_DIR}"
+ rsync -a --delete "${BIN_DIR}/data/" "${SHARED_DATA_DIR}/"
+}
+
+function copy_binary() {
+ local source_path="$1"
+ local dest_path="$2"
+ install -m 755 "${source_path}" "${dest_path}"
+}
+
+function link_shared_data() {
+ local macos_dir="$1"
+ local link_path="${macos_dir}/data"
+
+ if [[ -e "${link_path}" || -L "${link_path}" ]]; then
+ rm -rf "${link_path}"
+ fi
+
+ ln -s "../../../data" "${link_path}"
+}
+
+function copy_icon() {
+ local app_bundle="$1"
+ local resources_dir="${app_bundle}/Contents/Resources"
+
+ mkdir -p "${resources_dir}"
+ local info_plist="${app_bundle}/Contents/Info.plist"
+
+ # Use the format determined at the top of the script
+ if [[ "${ICON_USE_FORMAT}" == "icon" ]] && [[ -d "${ICON_DIR}" ]]; then
+ # Use .icon format directly (Icon Composer format from 2025)
+ # Copy the entire .icon directory to Resources
+ local icon_bundle_name="AppIcon.icon"
+ local icon_bundle_path="${resources_dir}/${icon_bundle_name}"
+
+ # Remove old icon bundle if it exists
+ if [[ -d "${icon_bundle_path}" ]] || [[ -L "${icon_bundle_path}" ]]; then
+ rm -rf "${icon_bundle_path}"
+ fi
+
+ # Copy .icon directory
+ cp -R "${ICON_DIR}" "${icon_bundle_path}"
+ echo " ✓ Copied .icon bundle from ${ICON_DIR} to ${icon_bundle_path}"
+
+ # Set CFBundleIconFile to .icon (new format - may require macOS Sequoia 15.1+)
+ if [[ -f "${info_plist}" ]] && command -v plutil &> /dev/null; then
+ plutil -replace CFBundleIconFile -string "${icon_bundle_name}" "${info_plist}" 2>/dev/null || \
+ plutil -insert CFBundleIconFile -string "${icon_bundle_name}" "${info_plist}" 2>/dev/null || true
+ fi
+ elif [[ "${ICON_USE_FORMAT}" == "icns" ]] && [[ -f "${ICON_FILE}" ]]; then
+ # Use traditional .icns format
+ cp "${ICON_FILE}" "${resources_dir}/AppIcon.icns"
+ echo " ✓ Copied .icns icon from ${ICON_FILE} to ${resources_dir}/AppIcon.icns"
+
+ # Set CFBundleIconFile to AppIcon (without extension - macOS requirement for Dock icon)
+ if [[ -f "${info_plist}" ]] && command -v plutil &> /dev/null; then
+ plutil -replace CFBundleIconFile -string "AppIcon" "${info_plist}" 2>/dev/null || \
+ plutil -insert CFBundleIconFile -string "AppIcon" "${info_plist}" 2>/dev/null || true
+ fi
+ else
+ # Icon is optional - silently skip if not found
+ return 0
+ fi
+
+ # Disable fullscreen capability to prevent "Game Mode" / "Capture Display" issues
+ # This prevents macOS from automatically switching to fullscreen when window is maximized
+ if [[ -f "${info_plist}" ]] && command -v plutil &> /dev/null; then
+ # Set LSUIElement to false (if not set) - ensure app appears in dock
+ plutil -replace LSUIElement -bool false "${info_plist}" 2>/dev/null || true
+ # Note: Unfortunately, macOS doesn't provide a direct Info.plist key to disable
+ # fullscreen mode. We prevent it in code by:
+ # 1. Setting Constraints.MaxWidth/Height to Screen.Width/Height - 1 (prevents fullscreen trigger)
+ # 2. Never using wsFullScreen/wsMaximized WindowState
+ # 3. Monitoring WindowState in Timer1Timer and FormResize to immediately revert any fullscreen attempts
+ fi
+}
+
+function ensure_template() {
+ local template_name="$1"
+ local bundle_name="$2"
+ local template_dir="${TEMPLATE_ROOT}/${template_name}"
+ local app_dir="${APP_ROOT}/${bundle_name}"
+
+ if [[ ! -d "${template_dir}" ]]; then
+ echo "Missing template directory ${template_dir}" >&2
+ exit 1
+ fi
+
+ mkdir -p "${app_dir}"
+ rsync -a --delete "${template_dir}/" "${app_dir}/"
+}
+
+if [[ "${TARGET_ARCH}" == "universal" ]]; then
+ echo "Preparing FPCAtomic.app (Universal: arm64 + x86_64)"
+else
+ echo "Preparing FPCAtomic.app (${TARGET_ARCH})"
+fi
+ensure_template "Game" "FPCAtomic.app"
+GAME_APP="${APP_ROOT}/FPCAtomic.app"
+GAME_MACOS_DIR="${GAME_APP}/Contents/MacOS"
+GAME_LIB_DIR="${GAME_APP}/Contents/lib"
+
+mkdir -p "${GAME_MACOS_DIR}" "${GAME_LIB_DIR}"
+copy_binary "${BIN_DIR}/fpc_atomic" "${GAME_MACOS_DIR}/fpc_atomic"
+sync_libs "${GAME_LIB_DIR}"
+copy_icon "${GAME_APP}"
+
+if [[ "${TARGET_ARCH}" == "universal" ]]; then
+ echo "Preparing FPCAtomicLauncher.app (Universal: arm64 + x86_64)"
+else
+ echo "Preparing FPCAtomicLauncher.app (${TARGET_ARCH})"
+fi
+ensure_template "Launcher" "FPCAtomicLauncher.app"
+LAUNCHER_APP="${APP_ROOT}/FPCAtomicLauncher.app"
+LAUNCHER_MACOS_DIR="${LAUNCHER_APP}/Contents/MacOS"
+LAUNCHER_LIB_DIR="${LAUNCHER_APP}/Contents/lib"
+
+mkdir -p "${LAUNCHER_MACOS_DIR}" "${LAUNCHER_LIB_DIR}"
+copy_binary "${BIN_DIR}/atomic_launcher" "${LAUNCHER_MACOS_DIR}/atomic_launcher"
+copy_binary "${BIN_DIR}/fpc_atomic" "${LAUNCHER_MACOS_DIR}/fpc_atomic"
+copy_binary "${BIN_DIR}/atomic_server" "${LAUNCHER_MACOS_DIR}/atomic_server"
+# Copy CD Data Extractor GUI for launcher
+if [[ -x "${BIN_DIR}/cd_data_extractor" ]]; then
+ copy_binary "${BIN_DIR}/cd_data_extractor" "${LAUNCHER_MACOS_DIR}/cd_data_extractor"
+ echo " ✓ Copied cd_data_extractor to ${LAUNCHER_MACOS_DIR}/cd_data_extractor"
+else
+ echo " ⚠ Warning: cd_data_extractor not found at ${BIN_DIR}/cd_data_extractor" >&2
+fi
+sync_libs "${LAUNCHER_LIB_DIR}"
+copy_icon "${LAUNCHER_APP}"
+
+if [[ "${TARGET_ARCH}" == "universal" ]]; then
+ echo "Preparing FPCAtomicServer.app (Universal: arm64 + x86_64)"
+else
+ echo "Preparing FPCAtomicServer.app (${TARGET_ARCH})"
+fi
+ensure_template "Server" "FPCAtomicServer.app"
+SERVER_APP="${APP_ROOT}/FPCAtomicServer.app"
+SERVER_MACOS_DIR="${SERVER_APP}/Contents/MacOS"
+SERVER_LIB_DIR="${SERVER_APP}/Contents/lib"
+
+mkdir -p "${SERVER_MACOS_DIR}" "${SERVER_LIB_DIR}"
+copy_binary "${BIN_DIR}/atomic_server" "${SERVER_MACOS_DIR}/atomic_server"
+chmod +x "${SERVER_MACOS_DIR}/run_server"
+sync_libs "${SERVER_LIB_DIR}"
+copy_icon "${SERVER_APP}"
+
+echo "Synchronising shared data directory"
+ensure_shared_data
+
+echo "Signing app bundles"
+for app in "${GAME_APP}" "${LAUNCHER_APP}" "${SERVER_APP}"; do
+ # Sign all libraries first (required for proper bundle signing)
+ echo "Signing libraries in $(basename "${app}")..."
+ if [[ -d "${app}/Contents/lib" ]]; then
+ for lib in "${app}/Contents/lib"/*.dylib; do
+ if [[ -f "${lib}" ]]; then
+ /usr/bin/codesign --force --sign - "${lib}" 2>&1 | grep -v "already signed" | grep -v "replacing existing signature" || true
+ fi
+ done
+ fi
+
+ # Sign all executables in MacOS directory (skip symlinks and directories)
+ if [[ -d "${app}/Contents/MacOS" ]]; then
+ for exe in "${app}/Contents/MacOS"/*; do
+ if [[ -f "${exe}" ]] && [[ -x "${exe}" ]] && ! [[ -L "${exe}" ]]; then
+ /usr/bin/codesign --force --sign - "${exe}" 2>&1 | grep -v "already signed" | grep -v "replacing existing signature" || true
+ fi
+ done
+ fi
+
+ # Check if entitlements file exists for this app
+ ENTITLEMENTS_FILE="${app}/Contents/entitlements.plist"
+ if [[ -f "${ENTITLEMENTS_FILE}" ]]; then
+ echo "Signing $(basename "${app}") bundle with entitlements..."
+ /usr/bin/codesign --force --deep --sign - --entitlements "${ENTITLEMENTS_FILE}" "${app}" 2>&1 | grep -v "replacing existing signature" || true
+ else
+ echo "Signing $(basename "${app}") bundle without entitlements..."
+ /usr/bin/codesign --force --deep --sign - "${app}" 2>&1 | grep -v "replacing existing signature" || true
+ fi
+done
+
+# Copy remove_quarantine.command to app directory
+REMOVE_QUARANTINE_SCRIPT="${SCRIPT_DIR}/remove_quarantine.command"
+if [[ -f "${REMOVE_QUARANTINE_SCRIPT}" ]]; then
+ cp "${REMOVE_QUARANTINE_SCRIPT}" "${APP_ROOT}/"
+ chmod +x "${APP_ROOT}/remove_quarantine.command"
+ echo " ✓ Copied remove_quarantine.command to ${APP_ROOT}"
+else
+ echo " ⚠ Warning: remove_quarantine.command not found at ${REMOVE_QUARANTINE_SCRIPT}" >&2
+fi
+
+echo "Done. Bundles are in ${APP_ROOT}:"
+echo " - FPCAtomic.app"
+echo " - FPCAtomicLauncher.app"
+echo " - FPCAtomicServer.app"
+echo " - remove_quarantine.command"
+
+
diff --git a/macos/tools/build_windows.command b/macos/tools/build_windows.command
new file mode 100755
index 0000000..9bc3ee5
--- /dev/null
+++ b/macos/tools/build_windows.command
@@ -0,0 +1,154 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Build script for FPC Atomic Windows
+# This script attempts to cross-compile for Windows from macOS
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+LAZARUS_DIR="${LAZARUS_DIR:-/Applications/Lazarus_3.9}"
+
+echo "========================================="
+echo "Building FPC Atomic for Windows"
+echo "========================================="
+echo ""
+
+# Check for Windows cross-compiler
+WINDOWS_COMPILER=""
+if command -v ppcrossx64 >/dev/null 2>&1; then
+ WINDOWS_COMPILER="ppcrossx64"
+ echo "✓ Found Windows cross-compiler: ppcrossx64"
+elif [ -f "/usr/local/bin/ppcrossx64" ]; then
+ WINDOWS_COMPILER="/usr/local/bin/ppcrossx64"
+ echo "✓ Found Windows cross-compiler: /usr/local/bin/ppcrossx64"
+elif [ -f "/usr/local/lib/fpc/3.2.2/bin/ppcrossx64" ]; then
+ WINDOWS_COMPILER="/usr/local/lib/fpc/3.2.2/bin/ppcrossx64"
+ echo "✓ Found Windows cross-compiler: /usr/local/lib/fpc/3.2.2/bin/ppcrossx64"
+else
+ echo "✗ Windows cross-compiler (ppcrossx64) not found!"
+ echo ""
+ echo "To build for Windows, you need to install the Windows cross-compiler."
+ echo ""
+ echo "Options:"
+ echo "1. Download from Free Pascal website:"
+ echo " https://www.freepascal.org/download.html"
+ echo " Look for 'cross-compilers' section"
+ echo ""
+ echo "2. Or use MacPorts (if installed):"
+ echo " sudo port install fpc-cross-x86_64-win64"
+ echo ""
+ echo "3. Or download pre-built cross-compiler:"
+ echo " https://sourceforge.net/projects/freepascal/files/Mac%20OS%20X/"
+ echo ""
+ exit 1
+fi
+
+# Check Lazarus
+if [ ! -d "${LAZARUS_DIR}" ]; then
+ echo "✗ Lazarus directory not found: ${LAZARUS_DIR}"
+ echo "Set LAZARUS_DIR environment variable to point to your Lazarus installation"
+ exit 1
+fi
+
+echo "Using Lazarus directory: ${LAZARUS_DIR}"
+echo ""
+
+# Create output directory
+WINDOWS_BIN_DIR="${PROJECT_ROOT}/windows/bin"
+mkdir -p "${WINDOWS_BIN_DIR}"
+
+# Build client
+echo "Building client (fpc_atomic)..."
+cd "${PROJECT_ROOT}/client"
+if lazbuild \
+ --lazarusdir="${LAZARUS_DIR}" \
+ --build-mode="default" \
+ --os=win64 \
+ --cpu=x86_64 \
+ fpc_atomic.lpi 2>&1 | tee "${WINDOWS_BIN_DIR}/client_build.log"; then
+ if [ -f "${PROJECT_ROOT}/fpc_atomic.exe" ]; then
+ mv "${PROJECT_ROOT}/fpc_atomic.exe" "${WINDOWS_BIN_DIR}/fpc_atomic.exe"
+ echo "✓ Client built successfully: ${WINDOWS_BIN_DIR}/fpc_atomic.exe"
+ else
+ echo "✗ Client executable not found after build"
+ exit 1
+ fi
+else
+ echo "✗ Failed to build client"
+ exit 1
+fi
+
+# Build launcher
+echo ""
+echo "Building launcher (atomic_launcher)..."
+cd "${PROJECT_ROOT}/launcher"
+if lazbuild \
+ --lazarusdir="${LAZARUS_DIR}" \
+ --build-mode="default" \
+ --os=win64 \
+ --cpu=x86_64 \
+ atomic_launcher.lpi 2>&1 | tee "${WINDOWS_BIN_DIR}/launcher_build.log"; then
+ if [ -f "${PROJECT_ROOT}/atomic_launcher.exe" ]; then
+ mv "${PROJECT_ROOT}/atomic_launcher.exe" "${WINDOWS_BIN_DIR}/atomic_launcher.exe"
+ echo "✓ Launcher built successfully: ${WINDOWS_BIN_DIR}/atomic_launcher.exe"
+ else
+ echo "✗ Launcher executable not found after build"
+ exit 1
+ fi
+else
+ echo "✗ Failed to build launcher"
+ exit 1
+fi
+
+# Build server
+echo ""
+echo "Building server (atomic_server)..."
+cd "${PROJECT_ROOT}/server"
+if lazbuild \
+ --lazarusdir="${LAZARUS_DIR}" \
+ --build-mode="default" \
+ --os=win64 \
+ --cpu=x86_64 \
+ atomic_server.lpi 2>&1 | tee "${WINDOWS_BIN_DIR}/server_build.log"; then
+ if [ -f "${PROJECT_ROOT}/atomic_server.exe" ]; then
+ mv "${PROJECT_ROOT}/atomic_server.exe" "${WINDOWS_BIN_DIR}/atomic_server.exe"
+ echo "✓ Server built successfully: ${WINDOWS_BIN_DIR}/atomic_server.exe"
+ else
+ echo "✗ Server executable not found after build"
+ exit 1
+ fi
+else
+ echo "✗ Failed to build server"
+ exit 1
+fi
+
+# Build CD data extractor
+echo ""
+echo "Building CD data extractor (cd_data_extractor)..."
+cd "${PROJECT_ROOT}/cd_data_extractor_src"
+if lazbuild \
+ --lazarusdir="${LAZARUS_DIR}" \
+ --build-mode="default" \
+ --os=win64 \
+ --cpu=x86_64 \
+ cd_data_extractor.lpi 2>&1 | tee "${WINDOWS_BIN_DIR}/extractor_build.log"; then
+ if [ -f "${PROJECT_ROOT}/cd_data_extractor.exe" ]; then
+ mv "${PROJECT_ROOT}/cd_data_extractor.exe" "${WINDOWS_BIN_DIR}/cd_data_extractor.exe"
+ echo "✓ CD data extractor built successfully: ${WINDOWS_BIN_DIR}/cd_data_extractor.exe"
+ else
+ echo "✗ CD data extractor executable not found after build"
+ exit 1
+ fi
+else
+ echo "✗ Failed to build CD data extractor"
+ exit 1
+fi
+
+echo ""
+echo "========================================="
+echo "Build complete!"
+echo "========================================="
+echo "Windows executables are in: ${WINDOWS_BIN_DIR}"
+echo ""
+
diff --git a/macos/tools/create_dmg.command b/macos/tools/create_dmg.command
new file mode 100755
index 0000000..fcfcedb
--- /dev/null
+++ b/macos/tools/create_dmg.command
@@ -0,0 +1,223 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Script to create DMG files for macOS distribution using create-dmg
+# Creates a DMG with the app bundle and installation instructions
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+# Allow architecture to be specified as first argument
+if [[ $# -gt 0 ]]; then
+ REQUESTED_ARCH="$1"
+ case "${REQUESTED_ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64|intel)
+ TARGET_ARCH="x86_64"
+ ;;
+ universal)
+ TARGET_ARCH="universal"
+ ;;
+ *)
+ echo "Unsupported architecture: ${REQUESTED_ARCH}" >&2
+ echo "Usage: $0 [arm64|x86_64|universal]" >&2
+ exit 1
+ ;;
+ esac
+else
+ # Detect architecture automatically
+ ARCH="$(uname -m)"
+ case "${ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64)
+ TARGET_ARCH="x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+APP_ROOT="${PROJECT_ROOT}/macos/app_${TARGET_ARCH}"
+DMG_OUTPUT_DIR="${PROJECT_ROOT}/releases"
+DMG_NAME="FPCAtomic-${TARGET_ARCH}"
+DMG_PATH="${DMG_OUTPUT_DIR}/${DMG_NAME}.dmg"
+
+# Get version if available
+VERSION="${VERSION:-}"
+if [[ -z "${VERSION}" ]] && [[ -f "${PROJECT_ROOT}/bin/fpc_atomic.version" ]]; then
+ VERSION=$(grep -E "^version=" "${PROJECT_ROOT}/bin/fpc_atomic.version" | cut -d'=' -f2 | tr -d '"' || echo "")
+fi
+
+if [[ -n "${VERSION}" ]]; then
+ DMG_NAME="FPCAtomic-${VERSION}-${TARGET_ARCH}"
+ DMG_PATH="${DMG_OUTPUT_DIR}/${DMG_NAME}.dmg"
+else
+ DMG_NAME="FPCAtomic-${TARGET_ARCH}"
+ DMG_PATH="${DMG_OUTPUT_DIR}/${DMG_NAME}.dmg"
+fi
+
+# Check if app bundles exist
+if [[ ! -d "${APP_ROOT}/FPCAtomic.app" ]]; then
+ echo "Error: FPCAtomic.app not found at ${APP_ROOT}/FPCAtomic.app" >&2
+ echo "Please build app bundles first using build_app_bundles.command" >&2
+ exit 1
+fi
+
+# Check if create-dmg is installed
+if ! command -v create-dmg &> /dev/null; then
+ echo "Error: create-dmg is not installed" >&2
+ echo "Please install it using:" >&2
+ echo " brew install create-dmg" >&2
+ echo "Or download from: https://github.com/create-dmg/create-dmg" >&2
+ exit 1
+fi
+
+# Check if data directory exists
+DATA_DIR="${PROJECT_ROOT}/data"
+if [[ ! -d "${DATA_DIR}" ]]; then
+ echo "Warning: Data directory not found at ${DATA_DIR}" >&2
+ echo "The DMG will be created without the data directory." >&2
+ echo "Users will need to run the CD data extractor after installation." >&2
+fi
+
+# Create output directory
+mkdir -p "${DMG_OUTPUT_DIR}"
+
+# Create temporary source directory for DMG
+DMG_SOURCE_DIR=$(mktemp -d -t fpc_atomic_dmg_source.XXXXXX)
+trap "rm -rf '${DMG_SOURCE_DIR}'" EXIT
+
+echo "========================================="
+echo "Creating DMG for ${TARGET_ARCH}"
+echo "========================================="
+
+# Create FPCAtomic directory in source
+FPCATOMIC_DIR="${DMG_SOURCE_DIR}/FPCAtomic"
+mkdir -p "${FPCATOMIC_DIR}"
+
+# Copy app bundles to FPCAtomic directory
+echo "Copying app bundles..."
+cp -R "${APP_ROOT}/FPCAtomic.app" "${FPCATOMIC_DIR}/"
+cp -R "${APP_ROOT}/FPCAtomicLauncher.app" "${FPCATOMIC_DIR}/"
+cp -R "${APP_ROOT}/FPCAtomicServer.app" "${FPCATOMIC_DIR}/"
+
+# Copy remove_quarantine.command if it exists
+if [[ -f "${APP_ROOT}/remove_quarantine.command" ]]; then
+ echo "Copying remove_quarantine.command..."
+ cp "${APP_ROOT}/remove_quarantine.command" "${FPCATOMIC_DIR}/"
+ chmod +x "${FPCATOMIC_DIR}/remove_quarantine.command"
+fi
+
+# Copy data directory if it exists
+if [[ -d "${DATA_DIR}" ]]; then
+ echo "Copying data directory..."
+ cp -R "${DATA_DIR}" "${FPCATOMIC_DIR}/"
+fi
+
+# Create README with installation instructions
+echo "Creating README..."
+cat > "${FPCATOMIC_DIR}/README.txt" << 'EOF'
+FPC Atomic - Installation Instructions
+======================================
+
+To install FPC Atomic:
+
+1. Drag the FPCAtomic folder to your Applications folder (or any location you prefer).
+
+2. Open the FPCAtomic folder and double-click FPCAtomicLauncher.app to start the launcher.
+
+3. If the data directory is included, the game is ready to play!
+ If not, you will need to:
+ - Click "Run CD data extractor"
+ - Set the path to your Atomic Bomberman CD data
+ - Click "Start extraction" to extract game assets
+
+4. If you copied the apps via AirDrop or downloaded them, you may need to:
+ - Double-click "remove_quarantine.command" to remove macOS quarantine
+ - This allows the apps to run without security warnings
+
+5. After extraction, you can launch the game from the launcher.
+
+System Requirements:
+- macOS 11.0 (Big Sur) or later
+- For arm64 version: Apple Silicon Mac (M1/M2/M3 or later)
+- For x86_64 version: Intel Mac
+- For universal version: Any Mac (automatically uses the correct architecture)
+
+For more information, visit:
+https://github.com/PascalCorpsman/fpc_atomic
+
+Enjoy the game!
+EOF
+
+# Prepare background image for DMG
+BACKGROUND_IMAGE="${PROJECT_ROOT}/macos/assets/dmg_background.png"
+
+# Remove existing DMG if it exists
+if [[ -f "${DMG_PATH}" ]]; then
+ rm -f "${DMG_PATH}"
+fi
+
+echo "Creating DMG file using create-dmg..."
+
+# Build create-dmg command
+CREATE_DMG_CMD=(
+ create-dmg
+ --volname "FPC Atomic ${TARGET_ARCH}"
+ --window-pos 400 100
+ --window-size 600 400
+ --icon-size 96
+ --text-size 14
+ --app-drop-link 480 180
+)
+
+# Add background image if it exists
+if [[ -f "${BACKGROUND_IMAGE}" ]]; then
+ echo "Using custom background image: ${BACKGROUND_IMAGE}"
+ CREATE_DMG_CMD+=(--background "${BACKGROUND_IMAGE}")
+else
+ echo "Note: Custom background not found at ${BACKGROUND_IMAGE}"
+ echo " You can add a custom background image with an arrow at that location"
+fi
+
+# Add icon positions
+CREATE_DMG_CMD+=(
+ --icon "FPCAtomic" 120 180
+ --hide-extension "FPCAtomic"
+)
+
+# Add final DMG path and source directory
+CREATE_DMG_CMD+=(
+ "${DMG_PATH}"
+ "${DMG_SOURCE_DIR}"
+)
+
+# Execute create-dmg
+"${CREATE_DMG_CMD[@]}" || {
+ echo "Error: Failed to create DMG" >&2
+ exit 1
+}
+
+# Verify DMG was created
+if [[ ! -f "${DMG_PATH}" ]]; then
+ echo "Error: DMG was not created" >&2
+ exit 1
+fi
+
+# Get DMG size for display
+DMG_SIZE_MB=$(du -m "${DMG_PATH}" | cut -f1)
+
+echo "========================================="
+echo "DMG created successfully!"
+echo "========================================="
+echo "File: ${DMG_PATH}"
+echo "Size: ${DMG_SIZE_MB}MB"
+echo ""
+echo "DMG files are saved in: ${DMG_OUTPUT_DIR}"
+echo "========================================="
diff --git a/macos/tools/create_release.command b/macos/tools/create_release.command
new file mode 100755
index 0000000..484ec93
--- /dev/null
+++ b/macos/tools/create_release.command
@@ -0,0 +1,154 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Master script to build, sign, notarize, and create DMG for release
+# Usage: ./create_release.command [arm64|x86_64|universal] [--skip-notarize]
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+# Load .env file if it exists
+ENV_FILE="${PROJECT_ROOT}/.env"
+if [[ -f "${ENV_FILE}" ]]; then
+ echo "Loading configuration from .env file..."
+ # Export variables from .env file (skip comments and empty lines)
+ # This uses zsh's built-in source with set -a to auto-export
+ set -a
+ source "${ENV_FILE}" 2>/dev/null || {
+ # Fallback: manually parse if source fails
+ while IFS= read -r line || [[ -n "$line" ]]; do
+ # Skip comments and empty lines
+ [[ "$line" =~ ^[[:space:]]*# ]] && continue
+ [[ -z "$line" ]] && continue
+ # Remove 'export ' prefix if present
+ line="${line#export }"
+ # Export the line (assuming format KEY=value)
+ export "$line"
+ done < "${ENV_FILE}"
+ }
+ set +a
+
+ # Map alternative variable names to expected names
+ # Support both NOTARY_APP_SPECIFIC_PASSWORD and APPLE_ID_PASSWORD
+ if [[ -n "${NOTARY_APP_SPECIFIC_PASSWORD:-}" ]] && [[ -z "${APPLE_ID_PASSWORD:-}" ]]; then
+ export APPLE_ID_PASSWORD="${NOTARY_APP_SPECIFIC_PASSWORD}"
+ fi
+ # Support both APPLE_TEAM_ID and TEAM_ID
+ if [[ -n "${APPLE_TEAM_ID:-}" ]] && [[ -z "${TEAM_ID:-}" ]]; then
+ export TEAM_ID="${APPLE_TEAM_ID}"
+ fi
+ # Support SKIP_NOTARIZATION (inverted logic)
+ if [[ -n "${SKIP_NOTARIZATION:-}" ]]; then
+ if [[ "${SKIP_NOTARIZATION}" == "1" ]] || [[ "${SKIP_NOTARIZATION}" == "true" ]]; then
+ export NOTARIZE="false"
+ else
+ export NOTARIZE="true"
+ fi
+ fi
+fi
+
+# Parse arguments
+TARGET_ARCH=""
+SKIP_NOTARIZE=false
+
+for arg in "$@"; do
+ case "${arg}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64|intel)
+ TARGET_ARCH="x86_64"
+ ;;
+ universal)
+ TARGET_ARCH="universal"
+ ;;
+ --skip-notarize)
+ SKIP_NOTARIZE=true
+ ;;
+ *)
+ echo "Unknown argument: ${arg}" >&2
+ ;;
+ esac
+done
+
+# If no architecture specified, detect automatically
+if [[ -z "${TARGET_ARCH}" ]]; then
+ ARCH="$(uname -m)"
+ case "${ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64)
+ TARGET_ARCH="x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+echo "========================================="
+echo "Creating Release for ${TARGET_ARCH}"
+echo "========================================="
+
+# Step 1: Build binaries and app bundles
+echo ""
+echo "Step 1: Building binaries and app bundles..."
+echo "========================================="
+if [[ "${TARGET_ARCH}" == "universal" ]]; then
+ "${SCRIPT_DIR}/build_all_universal.command" || {
+ echo "Error: Build failed" >&2
+ exit 1
+ }
+else
+ "${SCRIPT_DIR}/build_all.command" "${TARGET_ARCH}" || {
+ echo "Error: Build failed" >&2
+ exit 1
+ }
+fi
+
+# Step 2: Sign and notarize
+echo ""
+echo "Step 2: Signing and notarizing app bundles..."
+echo "========================================="
+if [[ "${SKIP_NOTARIZE}" == "true" ]]; then
+ export NOTARIZE=false
+ echo "Skipping notarization (--skip-notarize flag set)"
+else
+ export NOTARIZE=true
+fi
+
+"${SCRIPT_DIR}/sign_and_notarize.command" "${TARGET_ARCH}" || {
+ echo "Error: Signing/notarization failed" >&2
+ echo "You can continue without notarization using --skip-notarize flag" >&2
+ exit 1
+}
+
+# Step 3: Create DMG
+echo ""
+echo "Step 3: Creating DMG..."
+echo "========================================="
+"${SCRIPT_DIR}/create_dmg.command" "${TARGET_ARCH}" || {
+ echo "Error: DMG creation failed" >&2
+ exit 1
+}
+
+# Get version if available for display
+VERSION="${VERSION:-}"
+if [[ -z "${VERSION}" ]] && [[ -f "${PROJECT_ROOT}/bin/fpc_atomic.version" ]]; then
+ VERSION=$(grep -E "^version=" "${PROJECT_ROOT}/bin/fpc_atomic.version" | cut -d'=' -f2 | tr -d '"' || echo "")
+fi
+
+echo ""
+echo "========================================="
+echo "Release created successfully!"
+echo "========================================="
+echo "DMG file location:"
+if [[ -n "${VERSION}" ]]; then
+ echo " releases/FPCAtomic-${VERSION}-${TARGET_ARCH}.dmg"
+else
+ echo " releases/FPCAtomic-${TARGET_ARCH}.dmg"
+fi
+echo "========================================="
+
diff --git a/macos/tools/install_rosetta_homebrew.command b/macos/tools/install_rosetta_homebrew.command
new file mode 100755
index 0000000..bf1aecd
--- /dev/null
+++ b/macos/tools/install_rosetta_homebrew.command
@@ -0,0 +1,96 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Script to install Rosetta Homebrew and OpenSSL@3 for x86_64
+# This installs Homebrew in /usr/local (x86_64) which doesn't conflict
+# with ARM64 Homebrew in /opt/homebrew
+
+echo "========================================="
+echo "Installing Rosetta Homebrew (x86_64)"
+echo "========================================="
+echo ""
+echo "This will install Homebrew in /usr/local (x86_64)"
+echo "Your existing Homebrew in /opt/homebrew (ARM64) will not be affected."
+echo ""
+
+# Check if already installed
+if [[ -f "/usr/local/bin/brew" ]]; then
+ echo "✓ Rosetta Homebrew already installed at /usr/local/bin/brew"
+ arch -x86_64 /usr/local/bin/brew --version | head -1
+else
+ echo "Installing Rosetta Homebrew..."
+ echo "You may be prompted for your password."
+ echo ""
+
+ arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+ if [[ -f "/usr/local/bin/brew" ]]; then
+ echo ""
+ echo "✓ Rosetta Homebrew installed successfully!"
+ else
+ echo ""
+ echo "✗ Installation failed. Please check the output above."
+ exit 1
+ fi
+fi
+
+echo ""
+echo "========================================="
+echo "Installing OpenSSL@3 (x86_64)"
+echo "========================================="
+echo ""
+
+# Install OpenSSL@3 via Rosetta Homebrew
+if arch -x86_64 /usr/local/bin/brew list openssl@3 &>/dev/null; then
+ echo "✓ OpenSSL@3 already installed"
+else
+ echo "Installing OpenSSL@3..."
+ arch -x86_64 /usr/local/bin/brew install openssl@3
+fi
+
+echo ""
+echo "========================================="
+echo "Copying OpenSSL libraries to project"
+echo "========================================="
+echo ""
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+LIB_DIR="${PROJECT_ROOT}/lib/macos/x86_64"
+
+# Get Rosetta Homebrew prefix
+ROSETTA_PREFIX=$(arch -x86_64 /usr/local/bin/brew --prefix)
+
+# Copy libraries
+for lib_name in "libssl.3.dylib" "libcrypto.3.dylib"; do
+ source_lib="${ROSETTA_PREFIX}/lib/${lib_name}"
+ dest_lib="${LIB_DIR}/${lib_name}"
+
+ if [[ -f "${source_lib}" ]]; then
+ echo "Copying ${lib_name}..."
+ cp "${source_lib}" "${dest_lib}"
+
+ # Verify architecture
+ arch_info=$(file "${dest_lib}" | grep -oE "(x86_64|arm64)" | head -1)
+ if [[ "${arch_info}" == "x86_64" ]]; then
+ echo " ✓ ${lib_name} is x86_64"
+ else
+ echo " ⚠ ${lib_name} is ${arch_info} (expected x86_64)"
+ fi
+ else
+ echo " ✗ ${lib_name} not found at ${source_lib}"
+ fi
+done
+
+echo ""
+echo "========================================="
+echo "Done!"
+echo "========================================="
+echo ""
+echo "OpenSSL libraries have been copied to:"
+echo " ${LIB_DIR}/"
+echo ""
+echo "You can now rebuild the x86_64 version:"
+echo " ./macos/tools/build_all_x86_64.command"
+echo ""
+
diff --git a/macos/tools/prepare_x86_64_libs.command b/macos/tools/prepare_x86_64_libs.command
new file mode 100755
index 0000000..815516d
--- /dev/null
+++ b/macos/tools/prepare_x86_64_libs.command
@@ -0,0 +1,387 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Script to prepare x86_64 libraries for cross-compilation
+# This script verifies and fixes library architectures
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+LIB_DIR="${PROJECT_ROOT}/lib/macos/x86_64"
+
+echo "========================================="
+echo "Preparing x86_64 libraries"
+echo "========================================="
+echo ""
+
+# Function to check architecture of a library
+check_arch() {
+ local lib_path="$1"
+ if [[ ! -f "${lib_path}" ]]; then
+ return 1
+ fi
+
+ # Check with lipo first
+ local lipo_output=$(lipo -info "${lib_path}" 2>/dev/null || echo "")
+
+ if [[ -z "${lipo_output}" ]]; then
+ # lipo failed, try file command
+ local file_output=$(file "${lib_path}" 2>/dev/null || echo "")
+ if echo "${file_output}" | grep -q "x86_64"; then
+ echo "x86_64"
+ return 0
+ elif echo "${file_output}" | grep -q "arm64"; then
+ echo "arm64"
+ return 0
+ else
+ echo "unknown"
+ return 1
+ fi
+ fi
+
+ # Parse lipo output
+ if echo "${lipo_output}" | grep -q "Non-fat file"; then
+ # Single architecture - extract the architecture name
+ if echo "${lipo_output}" | grep -qE "architecture: x86_64"; then
+ echo "x86_64"
+ return 0
+ elif echo "${lipo_output}" | grep -qE "architecture: arm64"; then
+ echo "arm64"
+ return 0
+ else
+ # Try to extract any architecture mentioned
+ local extracted_arch=$(echo "${lipo_output}" | grep -oE "architecture: [^ ]+" | cut -d' ' -f2 || echo "")
+ if [[ -n "${extracted_arch}" ]]; then
+ echo "${extracted_arch}"
+ return 0
+ else
+ echo "unknown"
+ return 1
+ fi
+ fi
+ elif echo "${lipo_output}" | grep -q "Architectures in the fat file"; then
+ # Universal binary
+ if echo "${lipo_output}" | grep -q "x86_64"; then
+ echo "x86_64 (universal)"
+ return 0
+ else
+ echo "no-x86_64"
+ return 1
+ fi
+ else
+ # Fallback to file command
+ local file_output=$(file "${lib_path}" 2>/dev/null || echo "")
+ if echo "${file_output}" | grep -q "x86_64"; then
+ echo "x86_64"
+ return 0
+ elif echo "${file_output}" | grep -q "arm64"; then
+ echo "arm64"
+ return 0
+ else
+ echo "unknown"
+ return 1
+ fi
+ fi
+}
+
+# Function to extract x86_64 slice from universal binary
+extract_x86_64() {
+ local lib_path="$1"
+ local temp_path="${lib_path}.tmp"
+
+ if lipo -extract x86_64 "${lib_path}" -output "${temp_path}" 2>/dev/null; then
+ mv "${temp_path}" "${lib_path}"
+ echo " ✓ Extracted x86_64 slice"
+ return 0
+ else
+ rm -f "${temp_path}"
+ return 1
+ fi
+}
+
+# Function to get x86_64 OpenSSL libraries
+get_openssl_x86_64() {
+ local lib_name="$1"
+ local dest_path="${LIB_DIR}/${lib_name}"
+
+ # Try to find Homebrew universal binary and extract x86_64
+ local brew_paths=(
+ "/opt/homebrew/lib/${lib_name}"
+ "$(brew --prefix 2>/dev/null)/lib/${lib_name}"
+ )
+
+ for brew_path in "${brew_paths[@]}"; do
+ if [[ -f "${brew_path}" ]]; then
+ local arch=$(check_arch "${brew_path}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " → Found x86_64 version at ${brew_path}"
+ cp "${brew_path}" "${dest_path}"
+ return 0
+ elif [[ "${arch}" == *"universal"* ]]; then
+ echo " → Found universal binary, extracting x86_64..."
+ cp "${brew_path}" "${dest_path}"
+ if extract_x86_64 "${dest_path}"; then
+ return 0
+ fi
+ fi
+ fi
+ done
+
+ # Try Rosetta-based Homebrew (x86_64 Homebrew installed via Rosetta)
+ if command -v arch &> /dev/null; then
+ # Try different possible locations for Rosetta Homebrew
+ local rosetta_brew_paths=(
+ "/usr/local/bin/brew"
+ "$(which brew 2>/dev/null || echo "")"
+ )
+
+ for brew_bin in "${rosetta_brew_paths[@]}"; do
+ if [[ -f "${brew_bin}" ]] || command -v "${brew_bin}" &> /dev/null; then
+ echo " → Checking Rosetta Homebrew at ${brew_bin}..."
+ local rosetta_prefix=$(arch -x86_64 "${brew_bin}" --prefix 2>/dev/null || echo "")
+ if [[ -n "${rosetta_prefix}" ]] && [[ "${rosetta_prefix}" != "$(brew --prefix 2>/dev/null)" ]]; then
+ # This is a different Homebrew installation (likely Rosetta)
+ local rosetta_lib="${rosetta_prefix}/lib/${lib_name}"
+ if [[ -f "${rosetta_lib}" ]]; then
+ local arch=$(check_arch "${rosetta_lib}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " → Found x86_64 version in Rosetta Homebrew at ${rosetta_lib}"
+ cp "${rosetta_lib}" "${dest_path}"
+ return 0
+ elif [[ "${arch}" == *"universal"* ]]; then
+ echo " → Found universal binary in Rosetta Homebrew, extracting x86_64..."
+ cp "${rosetta_lib}" "${dest_path}"
+ if extract_x86_64 "${dest_path}"; then
+ return 0
+ fi
+ fi
+ fi
+ fi
+ fi
+ done
+
+ # Also try direct path check for /usr/local (common Rosetta Homebrew location)
+ if [[ -d "/usr/local/lib" ]]; then
+ local direct_rosetta_lib="/usr/local/lib/${lib_name}"
+ if [[ -f "${direct_rosetta_lib}" ]]; then
+ local arch=$(check_arch "${direct_rosetta_lib}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " → Found x86_64 version in /usr/local/lib at ${direct_rosetta_lib}"
+ cp "${direct_rosetta_lib}" "${dest_path}"
+ return 0
+ elif [[ "${arch}" == *"universal"* ]]; then
+ echo " → Found universal binary in /usr/local/lib, extracting x86_64..."
+ cp "${direct_rosetta_lib}" "${dest_path}"
+ if extract_x86_64 "${dest_path}"; then
+ return 0
+ fi
+ fi
+ fi
+ fi
+ fi
+
+ # Try system libraries (macOS may have OpenSSL in /usr/lib)
+ local system_paths=(
+ "/usr/lib/libssl.dylib"
+ "/usr/lib/libcrypto.dylib"
+ )
+
+ # Map lib names to system names
+ local system_lib_name="${lib_name}"
+ if [[ "${lib_name}" == "libssl.3.dylib" ]]; then
+ system_lib_name="libssl.dylib"
+ elif [[ "${lib_name}" == "libcrypto.3.dylib" ]]; then
+ system_lib_name="libcrypto.dylib"
+ fi
+
+ for sys_path in "/usr/lib/${system_lib_name}"; do
+ if [[ -f "${sys_path}" ]]; then
+ local arch=$(check_arch "${sys_path}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " → Found x86_64 version in system at ${sys_path}"
+ cp "${sys_path}" "${dest_path}"
+ # Fix install name if needed
+ install_name_tool -id "@rpath/${lib_name}" "${dest_path}" 2>/dev/null || true
+ return 0
+ elif [[ "${arch}" == *"universal"* ]]; then
+ echo " → Found universal binary in system, extracting x86_64..."
+ cp "${sys_path}" "${dest_path}"
+ if extract_x86_64 "${dest_path}"; then
+ install_name_tool -id "@rpath/${lib_name}" "${dest_path}" 2>/dev/null || true
+ return 0
+ fi
+ fi
+ fi
+ done
+
+ echo " ⚠ Could not find x86_64 OpenSSL. Options:"
+ echo " 1. Install x86_64 Homebrew via Rosetta:"
+ echo " arch -x86_64 /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
+ echo " Then: arch -x86_64 brew install openssl@3"
+ echo " 2. Manually copy x86_64 libraries to ${LIB_DIR}/"
+ echo " 3. Continue anyway (application may not work on x86_64 Mac)"
+
+ return 1
+}
+
+# Ensure lib directory exists
+mkdir -p "${LIB_DIR}"
+
+# List of required libraries (using zsh associative array syntax)
+typeset -A REQUIRED_LIBS
+REQUIRED_LIBS[libSDL2.dylib]="SDL2"
+REQUIRED_LIBS[libbass.dylib]="BASS"
+REQUIRED_LIBS[libai.dylib]="AI"
+REQUIRED_LIBS[libcrypto.3.dylib]="OpenSSL"
+REQUIRED_LIBS[libssl.3.dylib]="OpenSSL"
+
+ERRORS=0
+
+# Check each library
+for lib_name in "${(@k)REQUIRED_LIBS}"; do
+ lib_path="${LIB_DIR}/${lib_name}"
+ lib_type="${REQUIRED_LIBS[${lib_name}]}"
+
+ echo "Checking ${lib_name} (${lib_type})..."
+
+ if [[ ! -f "${lib_path}" ]]; then
+ echo " ✗ Missing: ${lib_name}"
+
+ # Try to fix based on library type
+ case "${lib_type}" in
+ "SDL2")
+ # Try to copy from framework
+ framework_path="${LIB_DIR}/frameworks/SDL2.framework/SDL2"
+ if [[ -f "${framework_path}" ]]; then
+ local arch=$(check_arch "${framework_path}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " → Copying from SDL2.framework..."
+ cp "${framework_path}" "${lib_path}"
+ # Fix install name for dylib
+ install_name_tool -id "@rpath/${lib_name}" "${lib_path}" 2>/dev/null || true
+ echo " ✓ Created ${lib_name} from framework"
+ else
+ echo " ✗ Framework is not x86_64"
+ ((ERRORS++))
+ fi
+ else
+ echo " ✗ SDL2.framework not found"
+ ((ERRORS++))
+ fi
+ ;;
+ "OpenSSL")
+ if get_openssl_x86_64 "${lib_name}"; then
+ echo " ✓ Retrieved x86_64 version"
+ else
+ echo " ✗ Could not get x86_64 version"
+ ((ERRORS++))
+ fi
+ ;;
+ *)
+ echo " ✗ Don't know how to fix this library"
+ ((ERRORS++))
+ ;;
+ esac
+ continue
+ fi
+
+ # Check architecture
+ arch=$(check_arch "${lib_path}")
+
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo " ✓ ${lib_name} is ${arch}"
+ elif [[ "${arch}" == "arm64" ]]; then
+ echo " ✗ ${lib_name} is ARM64 (should be x86_64)"
+
+ # Try to fix
+ case "${lib_type}" in
+ "OpenSSL")
+ if get_openssl_x86_64 "${lib_name}"; then
+ echo " ✓ Fixed: replaced with x86_64 version"
+ else
+ echo " ✗ Could not fix"
+ ((ERRORS++))
+ fi
+ ;;
+ "SDL2")
+ # Try framework
+ framework_path="${LIB_DIR}/frameworks/SDL2.framework/SDL2"
+ if [[ -f "${framework_path}" ]]; then
+ local framework_arch=$(check_arch "${framework_path}")
+ if [[ "${framework_arch}" == "x86_64"* ]]; then
+ echo " → Copying from SDL2.framework..."
+ cp "${framework_path}" "${lib_path}"
+ install_name_tool -id "@rpath/${lib_name}" "${lib_path}" 2>/dev/null || true
+ echo " ✓ Fixed: replaced with x86_64 version from framework"
+ else
+ echo " ✗ Framework is also wrong architecture"
+ ((ERRORS++))
+ fi
+ else
+ echo " ✗ Could not fix"
+ ((ERRORS++))
+ fi
+ ;;
+ *)
+ echo " ✗ Don't know how to fix this library"
+ ((ERRORS++))
+ ;;
+ esac
+ elif [[ "${arch}" == "no-x86_64" ]]; then
+ echo " ✗ ${lib_name} is universal but doesn't contain x86_64"
+ if extract_x86_64 "${lib_path}"; then
+ echo " ✓ Fixed: extracted x86_64 slice"
+ else
+ echo " ✗ Could not extract x86_64"
+ ((ERRORS++))
+ fi
+ else
+ echo " ✗ ${lib_name} has unknown architecture"
+ ((ERRORS++))
+ fi
+done
+
+echo ""
+echo "========================================="
+echo "Verifying library architectures"
+echo "========================================="
+echo ""
+
+# Final verification
+ALL_OK=true
+for lib_name in "${(@k)REQUIRED_LIBS}"; do
+ lib_path="${LIB_DIR}/${lib_name}"
+ if [[ ! -f "${lib_path}" ]]; then
+ echo "✗ ${lib_name}: MISSING"
+ ALL_OK=false
+ continue
+ fi
+
+ arch=$(check_arch "${lib_path}")
+ if [[ "${arch}" == "x86_64"* ]]; then
+ echo "✓ ${lib_name}: ${arch}"
+ else
+ echo "✗ ${lib_name}: ${arch} (should be x86_64)"
+ ALL_OK=false
+ fi
+done
+
+echo ""
+if [[ "${ALL_OK}" == "true" && "${ERRORS}" -eq 0 ]]; then
+ echo "========================================="
+ echo "All x86_64 libraries are ready!"
+ echo "========================================="
+ exit 0
+else
+ echo "========================================="
+ echo "WARNING: Some libraries are missing or have wrong architecture"
+ echo "========================================="
+ echo ""
+ echo "The build will continue, but the application may not work correctly"
+ echo "on x86_64 Macs. Please fix the library issues before distributing."
+ echo ""
+ echo "To skip this check in the future, set SKIP_LIB_CHECK=1"
+ echo ""
+ # Allow build to continue with warning
+ exit 0
+fi
+
diff --git a/macos/tools/remove_quarantine.command b/macos/tools/remove_quarantine.command
new file mode 100755
index 0000000..5f78588
--- /dev/null
+++ b/macos/tools/remove_quarantine.command
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Remove quarantine attribute from all app bundles in this directory
+# Run this after copying the apps to a new Mac
+
+cd "$(dirname "$0")"
+
+echo "Removing quarantine attribute from app bundles..."
+echo "(You may be prompted for your password)"
+
+for app in *.app; do
+ if [[ -d "$app" ]]; then
+ echo " → $app"
+ sudo xattr -cr "$app"
+ fi
+done
+
+echo "Done. You can now run the applications."
+
+# If this does not work, try the following:
+# 1. Open the Terminal app
+# Method 1: sudo xattr -d com.apple.quarantine (odstraní jen karanténu)
+# Method 2: sudo xattr -cr (odstraní všechny extended attributes recursively)
+# Method 3: bez sudo (pro soubory vlastněné uživatelem)
+# Method 4: xattr -c bez sudo
\ No newline at end of file
diff --git a/macos/tools/run_client.command b/macos/tools/run_client.command
new file mode 100755
index 0000000..e8025ce
--- /dev/null
+++ b/macos/tools/run_client.command
@@ -0,0 +1,29 @@
+#!/bin/zsh
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+ARCH="$(uname -m)"
+case "$ARCH" in
+ arm64|aarch64)
+ BIN_PATH="${REPO_ROOT}/bin/macos/arm64/fpc_atomic"
+ LIB_PATH="${REPO_ROOT}/lib/macos/arm64"
+ ;;
+ x86_64)
+ BIN_PATH="${REPO_ROOT}/bin/macos/x86_64/fpc_atomic"
+ LIB_PATH="${REPO_ROOT}/lib/macos/x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+
+ esac
+
+if [ ! -x "$BIN_PATH" ]; then
+ echo "Binary not found or not executable: $BIN_PATH" >&2
+ echo "Build the project with lazbuild --build-mode=macos_${ARCH} before running." >&2
+ exit 1
+fi
+
+export DYLD_LIBRARY_PATH="${LIB_PATH}:${DYLD_LIBRARY_PATH}"
+cd "${REPO_ROOT}"
+exec "$BIN_PATH" "$@"
diff --git a/macos/tools/run_launcher.command b/macos/tools/run_launcher.command
new file mode 100755
index 0000000..f3d9082
--- /dev/null
+++ b/macos/tools/run_launcher.command
@@ -0,0 +1,28 @@
+#!/bin/zsh
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+ARCH="$(uname -m)"
+case "$ARCH" in
+ arm64|aarch64)
+ BIN_PATH="${PROJECT_ROOT}/bin/macos/arm64/atomic_launcher"
+ LIB_PATH="${PROJECT_ROOT}/lib/macos/arm64"
+ ;;
+ x86_64)
+ BIN_PATH="${PROJECT_ROOT}/bin/macos/x86_64/atomic_launcher"
+ LIB_PATH="${PROJECT_ROOT}/lib/macos/x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+
+if [ ! -x "$BIN_PATH" ]; then
+ echo "Binary not found or not executable: $BIN_PATH" >&2
+ echo "Build the project with lazbuild --build-mode=macos_${ARCH} before running." >&2
+ exit 1
+fi
+
+export DYLD_LIBRARY_PATH="${LIB_PATH}:${DYLD_LIBRARY_PATH}"
+cd "${PROJECT_ROOT}" || exit 1
+exec "$BIN_PATH" "$@"
diff --git a/macos/tools/run_server.command b/macos/tools/run_server.command
new file mode 100755
index 0000000..0de701f
--- /dev/null
+++ b/macos/tools/run_server.command
@@ -0,0 +1,56 @@
+#!/bin/zsh
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+ARCH="$(uname -m)"
+case "$ARCH" in
+ arm64|aarch64)
+ BIN_PATH="${PROJECT_ROOT}/bin/macos/arm64/atomic_server"
+ LIB_PATH="${PROJECT_ROOT}/lib/macos/arm64"
+ ;;
+ x86_64)
+ BIN_PATH="${PROJECT_ROOT}/bin/macos/x86_64/atomic_server"
+ LIB_PATH="${PROJECT_ROOT}/lib/macos/x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+
+if [ ! -x "$BIN_PATH" ]; then
+ echo "Binary not found or not executable: $BIN_PATH" >&2
+ echo "Build the project with lazbuild --build-mode=macos_${ARCH} before running." >&2
+ exit 1
+fi
+
+export DYLD_LIBRARY_PATH="${LIB_PATH}:${DYLD_LIBRARY_PATH}"
+
+ARGS=("$@")
+HAS_PORT=0
+HAS_TIMEOUT=0
+
+i=0
+while [ $i -lt ${#ARGS[@]} ]; do
+ case "${ARGS[$i]}" in
+ -p)
+ HAS_PORT=1
+ i=$((i + 2))
+ continue
+ ;;
+ -t)
+ HAS_TIMEOUT=1
+ i=$((i + 2))
+ continue
+ ;;
+ esac
+ i=$((i + 1))
+done
+
+if [ $HAS_PORT -eq 0 ]; then
+ ARGS+=("-p" "5521")
+fi
+if [ $HAS_TIMEOUT -eq 0 ]; then
+ ARGS+=("-t" "0")
+fi
+
+exec "$BIN_PATH" "${ARGS[@]}"
diff --git a/macos/tools/sign_and_notarize.command b/macos/tools/sign_and_notarize.command
new file mode 100755
index 0000000..6fe8545
--- /dev/null
+++ b/macos/tools/sign_and_notarize.command
@@ -0,0 +1,355 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Script to sign and notarize macOS app bundles for distribution
+# Requires:
+# - Developer ID Application certificate installed in Keychain
+# - Apple ID credentials configured for notarization
+# - Environment variables: APPLE_ID, APPLE_ID_PASSWORD (or app-specific password), TEAM_ID
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+# Load .env file if it exists
+ENV_FILE="${PROJECT_ROOT}/.env"
+if [[ -f "${ENV_FILE}" ]]; then
+ echo "Loading configuration from .env file..."
+ # Export variables from .env file (skip comments and empty lines)
+ # This uses zsh's built-in source with set -a to auto-export
+ set -a
+ source "${ENV_FILE}" 2>/dev/null || {
+ # Fallback: manually parse if source fails
+ while IFS= read -r line || [[ -n "$line" ]]; do
+ # Skip comments and empty lines
+ [[ "$line" =~ ^[[:space:]]*# ]] && continue
+ [[ -z "$line" ]] && continue
+ # Remove 'export ' prefix if present
+ line="${line#export }"
+ # Export the line (assuming format KEY=value)
+ export "$line"
+ done < "${ENV_FILE}"
+ }
+ set +a
+
+ # Map alternative variable names to expected names
+ # Support both NOTARY_APP_SPECIFIC_PASSWORD and APPLE_ID_PASSWORD
+ if [[ -n "${NOTARY_APP_SPECIFIC_PASSWORD:-}" ]] && [[ -z "${APPLE_ID_PASSWORD:-}" ]]; then
+ export APPLE_ID_PASSWORD="${NOTARY_APP_SPECIFIC_PASSWORD}"
+ fi
+ # Support both APPLE_TEAM_ID and TEAM_ID
+ if [[ -n "${APPLE_TEAM_ID:-}" ]] && [[ -z "${TEAM_ID:-}" ]]; then
+ export TEAM_ID="${APPLE_TEAM_ID}"
+ fi
+ # Support SKIP_NOTARIZATION (inverted logic)
+ if [[ -n "${SKIP_NOTARIZATION:-}" ]]; then
+ if [[ "${SKIP_NOTARIZATION}" == "1" ]] || [[ "${SKIP_NOTARIZATION}" == "true" ]]; then
+ export NOTARIZE="false"
+ else
+ export NOTARIZE="true"
+ fi
+ fi
+fi
+
+# Allow architecture to be specified as first argument
+if [[ $# -gt 0 ]]; then
+ REQUESTED_ARCH="$1"
+ case "${REQUESTED_ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64|intel)
+ TARGET_ARCH="x86_64"
+ ;;
+ universal)
+ TARGET_ARCH="universal"
+ ;;
+ *)
+ echo "Unsupported architecture: ${REQUESTED_ARCH}" >&2
+ echo "Usage: $0 [arm64|x86_64|universal]" >&2
+ exit 1
+ ;;
+ esac
+else
+ # Detect architecture automatically
+ ARCH="$(uname -m)"
+ case "${ARCH}" in
+ arm64|aarch64)
+ TARGET_ARCH="arm64"
+ ;;
+ x86_64)
+ TARGET_ARCH="x86_64"
+ ;;
+ *)
+ echo "Unsupported architecture: ${ARCH}" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+APP_ROOT="${PROJECT_ROOT}/macos/app_${TARGET_ARCH}"
+
+# Check if app bundles exist
+if [[ ! -d "${APP_ROOT}/FPCAtomic.app" ]]; then
+ echo "Error: FPCAtomic.app not found at ${APP_ROOT}/FPCAtomic.app" >&2
+ echo "Please build app bundles first using build_app_bundles.command" >&2
+ exit 1
+fi
+
+# Configuration
+# These can be set via environment variables or will prompt
+DEVELOPER_ID="${DEVELOPER_ID:-}"
+APPLE_ID="${APPLE_ID:-}"
+APPLE_ID_PASSWORD="${APPLE_ID_PASSWORD:-}"
+TEAM_ID="${TEAM_ID:-}"
+NOTARIZE="${NOTARIZE:-true}"
+
+# Function to find Developer ID certificate
+find_developer_id() {
+ local cert_name
+ # Try common Developer ID certificate names
+ for cert_name in "Developer ID Application" "Developer ID Application:"; do
+ if security find-identity -v -p codesigning | grep -q "${cert_name}"; then
+ security find-identity -v -p codesigning | grep "${cert_name}" | head -1 | sed 's/.*"\(.*\)".*/\1/'
+ return 0
+ fi
+ done
+ return 1
+}
+
+# Function to prompt for credentials if not set
+prompt_credentials() {
+ if [[ -z "${DEVELOPER_ID}" ]]; then
+ echo "Looking for Developer ID certificate..."
+ DEVELOPER_ID=$(find_developer_id || echo "")
+ if [[ -z "${DEVELOPER_ID}" ]]; then
+ echo "Error: No Developer ID Application certificate found in Keychain" >&2
+ echo "Please install a Developer ID Application certificate from Apple Developer portal" >&2
+ echo "Or set DEVELOPER_ID in .env file (${ENV_FILE})" >&2
+ echo "See macos/tools/.env.example for an example" >&2
+ exit 1
+ fi
+ echo "Found certificate: ${DEVELOPER_ID}"
+ fi
+
+ if [[ "${NOTARIZE}" == "true" ]]; then
+ if [[ -z "${APPLE_ID}" ]]; then
+ echo "Error: APPLE_ID not set" >&2
+ echo "Please set APPLE_ID in .env file (${ENV_FILE}) or as environment variable" >&2
+ echo "See macos/tools/.env.example for an example" >&2
+ exit 1
+ fi
+
+ if [[ -z "${APPLE_ID_PASSWORD}" ]]; then
+ echo "Error: APPLE_ID_PASSWORD not set" >&2
+ echo "Please set APPLE_ID_PASSWORD in .env file (${ENV_FILE}) or as environment variable" >&2
+ echo "See macos/tools/.env.example for an example" >&2
+ exit 1
+ fi
+
+ if [[ -z "${TEAM_ID}" ]]; then
+ # Try to extract Team ID from certificate
+ TEAM_ID=$(security find-certificate -c "${DEVELOPER_ID}" -p 2>/dev/null | openssl x509 -noout -subject 2>/dev/null | sed -n 's/.*OU=\([^/]*\).*/\1/p' | head -1)
+ if [[ -z "${TEAM_ID}" ]]; then
+ echo "Error: TEAM_ID not set and could not extract from certificate" >&2
+ echo "Please set TEAM_ID in .env file (${ENV_FILE}) or as environment variable" >&2
+ echo "See macos/tools/.env.example for an example" >&2
+ exit 1
+ fi
+ fi
+ fi
+}
+
+# Function to sign a single file or bundle
+sign_item() {
+ local item="$1"
+ local entitlements_file="$2"
+
+ if [[ ! -e "${item}" ]]; then
+ echo " ⚠ Warning: ${item} does not exist, skipping"
+ return 0
+ fi
+
+ if [[ -f "${entitlements_file}" ]]; then
+ /usr/bin/codesign --force --sign "${DEVELOPER_ID}" --entitlements "${entitlements_file}" --timestamp --options runtime "${item}" 2>&1 | grep -v "replacing existing signature" || true
+ else
+ /usr/bin/codesign --force --sign "${DEVELOPER_ID}" --timestamp --options runtime "${item}" 2>&1 | grep -v "replacing existing signature" || true
+ fi
+}
+
+# Function to sign an app bundle
+sign_app_bundle() {
+ local app_bundle="$1"
+ local app_name=$(basename "${app_bundle}")
+
+ echo "Signing ${app_name}..."
+
+ # Sign all libraries first (required for proper bundle signing)
+ if [[ -d "${app_bundle}/Contents/lib" ]]; then
+ for lib in "${app_bundle}/Contents/lib"/*.dylib; do
+ if [[ -f "${lib}" ]]; then
+ echo " Signing library: $(basename "${lib}")"
+ sign_item "${lib}" ""
+ fi
+ done
+ fi
+
+ # Sign all executables in MacOS directory (skip symlinks and directories)
+ if [[ -d "${app_bundle}/Contents/MacOS" ]]; then
+ for exe in "${app_bundle}/Contents/MacOS"/*; do
+ if [[ -f "${exe}" ]] && [[ -x "${exe}" ]] && ! [[ -L "${exe}" ]]; then
+ echo " Signing executable: $(basename "${exe}")"
+ sign_item "${exe}" ""
+ fi
+ done
+ fi
+
+ # Check if entitlements file exists
+ local entitlements_file="${app_bundle}/Contents/entitlements.plist"
+ if [[ -f "${entitlements_file}" ]]; then
+ echo " Signing bundle with entitlements..."
+ sign_item "${app_bundle}" "${entitlements_file}"
+ else
+ echo " Signing bundle without entitlements..."
+ sign_item "${app_bundle}" ""
+ fi
+
+ # Verify signature
+ echo " Verifying signature..."
+ if /usr/bin/codesign --verify --verbose "${app_bundle}" 2>&1; then
+ echo " ✓ ${app_name} signed successfully"
+ else
+ echo " ✗ Error: Failed to verify signature for ${app_name}" >&2
+ return 1
+ fi
+
+ # Note: --check-requirements is not available in all macOS versions
+ # The signature verification above is sufficient for distribution
+}
+
+# Function to notarize an app bundle
+notarize_app_bundle() {
+ local app_bundle="$1"
+ local app_name=$(basename "${app_bundle}")
+ local zip_path="${app_bundle%.app}.zip"
+
+ echo "Notarizing ${app_name}..."
+
+ # Create a zip file for notarization
+ echo " Creating zip file for notarization..."
+ cd "$(dirname "${app_bundle}")"
+ /usr/bin/ditto -c -k --keepParent "${app_bundle}" "${zip_path}"
+
+ # Submit for notarization
+ echo " Submitting to Apple for notarization..."
+ local submission_output
+ submission_output=$(xcrun notarytool submit "${zip_path}" \
+ --apple-id "${APPLE_ID}" \
+ --password "${APPLE_ID_PASSWORD}" \
+ --team-id "${TEAM_ID}" \
+ --wait \
+ 2>&1)
+
+ local submission_id
+ submission_id=$(echo "${submission_output}" | grep -i "id:" | head -1 | sed 's/.*[Ii][Dd]:[[:space:]]*\([^[:space:]]*\).*/\1/')
+
+ if [[ -z "${submission_id}" ]]; then
+ echo " ✗ Error: Failed to submit for notarization" >&2
+ echo "${submission_output}" >&2
+ rm -f "${zip_path}"
+ return 1
+ fi
+
+ echo " Submission ID: ${submission_id}"
+
+ # Check notarization status
+ # Note: 'status' is a reserved variable in zsh, so we use 'notarization_status'
+ # Parse the LAST status line (final status after processing completes)
+ local notarization_status
+ notarization_status=$(echo "${submission_output}" | grep -i "status:" | tail -1 | sed 's/.*[Ss]tatus:[[:space:]]*\([^[:space:]]*\).*/\1/' | sed 's/\..*$//')
+
+ # Also check if output contains "Processing complete" and "status: Accepted" together
+ if echo "${submission_output}" | grep -qi "Processing complete" && echo "${submission_output}" | grep -qi "status:.*Accepted"; then
+ notarization_status="Accepted"
+ fi
+
+ if [[ "${notarization_status}" == "Accepted" ]]; then
+ echo " ✓ Notarization successful"
+
+ # Staple the notarization ticket
+ echo " Stapling notarization ticket..."
+ if xcrun stapler staple "${app_bundle}" 2>&1; then
+ echo " ✓ Stapling successful"
+
+ # Verify stapling
+ if xcrun stapler validate "${app_bundle}" 2>&1; then
+ echo " ✓ Validation successful"
+ else
+ echo " ⚠ Warning: Validation failed" >&2
+ fi
+ else
+ echo " ✗ Error: Stapling failed" >&2
+ rm -f "${zip_path}"
+ return 1
+ fi
+ else
+ echo " ✗ Error: Notarization failed with status: ${notarization_status}" >&2
+ echo "${submission_output}" >&2
+ rm -f "${zip_path}"
+ return 1
+ fi
+
+ # Clean up zip file
+ rm -f "${zip_path}"
+}
+
+# Main execution
+echo "========================================="
+echo "Signing and Notarizing macOS App Bundles"
+echo "Architecture: ${TARGET_ARCH}"
+echo "========================================="
+
+prompt_credentials
+
+# Sign all app bundles
+APPS=(
+ "${APP_ROOT}/FPCAtomic.app"
+ "${APP_ROOT}/FPCAtomicLauncher.app"
+ "${APP_ROOT}/FPCAtomicServer.app"
+)
+
+for app in "${APPS[@]}"; do
+ if [[ -d "${app}" ]]; then
+ sign_app_bundle "${app}"
+ echo
+ else
+ echo "⚠ Warning: ${app} not found, skipping" >&2
+ fi
+done
+
+# Notarize if requested
+if [[ "${NOTARIZE}" == "true" ]]; then
+ echo "========================================="
+ echo "Notarizing App Bundles"
+ echo "========================================="
+ echo "Note: Notarization may take up to 5 minutes per app bundle."
+ echo "Please be patient while Apple processes your submission..."
+ echo ""
+
+ for app in "${APPS[@]}"; do
+ if [[ -d "${app}" ]]; then
+ notarize_app_bundle "${app}"
+ echo
+ fi
+ done
+else
+ echo "========================================="
+ echo "Skipping notarization (NOTARIZE=false)"
+ echo "========================================="
+fi
+
+echo "========================================="
+echo "Done!"
+echo "Signed (and notarized) app bundles are in:"
+echo " ${APP_ROOT}"
+echo "========================================="
+
diff --git a/macos/tools/sync_upstream.command b/macos/tools/sync_upstream.command
new file mode 100755
index 0000000..fe24d69
--- /dev/null
+++ b/macos/tools/sync_upstream.command
@@ -0,0 +1,98 @@
+#!/bin/zsh
+set -euo pipefail
+
+# Script pro synchronizaci s upstream repozitářem
+# Tento script stáhne nové změny z upstream a integruje je do aktuální větve
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+
+cd "${PROJECT_ROOT}"
+
+echo "========================================="
+echo "Synchronizace s upstream repozitářem"
+echo "========================================="
+echo ""
+
+# Zkontrolovat, že upstream je nastaven
+if ! git remote | grep -q "^upstream$"; then
+ echo "✗ Upstream remote není nastaven!"
+ echo ""
+ echo "Nastav upstream pomocí:"
+ echo " git remote add upstream https://github.com/PascalCorpsman/fpc_atomic.git"
+ exit 1
+fi
+
+# Zkontrolovat, že nejsou necommitnuté změny
+if ! git diff-index --quiet HEAD --; then
+ echo "⚠ Máte necommitnuté změny!"
+ echo ""
+ echo "Možnosti:"
+ echo "1. Commitnout změny:"
+ echo " git add ."
+ echo " git commit -m 'Your commit message'"
+ echo ""
+ echo "2. Uložit změny do stash:"
+ echo " git stash"
+ echo ""
+ read -q "response?Chcete pokračovat? (y/N) "
+ echo ""
+ if [[ "${response}" != "y" && "${response}" != "Y" ]]; then
+ echo "Zrušeno."
+ exit 0
+ fi
+fi
+
+# Zjistit aktuální branch
+CURRENT_BRANCH=$(git branch --show-current)
+echo "Aktuální branch: ${CURRENT_BRANCH}"
+echo ""
+
+# 1. Fetchnout změny z upstream
+echo "1. Stahování změn z upstream..."
+git fetch upstream
+echo "✓ Změny staženy"
+echo ""
+
+# 2. Zobrazit nové commity
+echo "2. Nové commity v upstream/main:"
+git log ${CURRENT_BRANCH}..upstream/main --oneline | head -10
+if [ $? -ne 0 ]; then
+ echo " (žádné nové commity nebo upstream/main neexistuje)"
+fi
+echo ""
+
+# 3. Zeptat se, jestli merge nebo rebase
+echo "Jak chcete integrovat změny?"
+echo "1. Merge - vytvoří merge commit (doporučeno pro začátečníky)"
+echo "2. Rebase - přepíše historii (čistší, ale složitější)"
+echo ""
+read -q "response?Zvolte merge (1) nebo rebase (2): "
+echo ""
+
+if [[ "${response}" == "2" ]]; then
+ echo ""
+ echo "3. Rebase upstream/main do ${CURRENT_BRANCH}..."
+ git rebase upstream/main
+ echo "✓ Rebase dokončen"
+else
+ echo ""
+ echo "3. Merge upstream/main do ${CURRENT_BRANCH}..."
+ git merge upstream/main --no-edit
+ echo "✓ Merge dokončen"
+fi
+
+echo ""
+echo "========================================="
+echo "Synchronizace dokončena!"
+echo "========================================="
+echo ""
+echo "Pokud došlo ke konfliktům:"
+echo "1. Vyřešte konflikty v souborech"
+echo "2. git add "
+echo "3. git commit (pro merge) nebo git rebase --continue (pro rebase)"
+echo ""
+echo "Pro push změn:"
+echo " git push origin ${CURRENT_BRANCH}"
+echo ""
+
diff --git a/ppaslink.sh b/ppaslink.sh
new file mode 100755
index 0000000..cc8e482
--- /dev/null
+++ b/ppaslink.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+DoExitAsm ()
+{ echo "An error occurred while assembling $1"; exit 1; }
+DoExitLink ()
+{ echo "An error occurred while linking $1"; exit 1; }
+OFS=$IFS
+IFS="
+"
+/Library/Developer/CommandLineTools/usr/bin/ld -framework Cocoa -weak_framework UserNotifications -order_file /Users/pavelzverina/AiProjects/fpc_atomic/symbol_order.fpc -multiply_defined suppress -L. -o /Users/pavelzverina/AiProjects/fpc_atomic/cd_data_extractor_nogui `cat /Users/pavelzverina/AiProjects/fpc_atomic/link91806.res` -filelist /Users/pavelzverina/AiProjects/fpc_atomic/linkfiles91806.res
+if [ $? != 0 ]; then DoExitLink ; fi
+IFS=$OFS
diff --git a/server/atomic_server.lpi b/server/atomic_server.lpi
index 9f65297..7c7744a 100644
--- a/server/atomic_server.lpi
+++ b/server/atomic_server.lpi
@@ -17,7 +17,7 @@
-
+
@@ -27,7 +27,7 @@
-
+
@@ -60,6 +60,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -77,13 +119,10 @@
-
+
-
-
-
@@ -123,7 +162,7 @@
-
+
diff --git a/server/atomic_server.lpr b/server/atomic_server.lpr
index b7f77be..52f11b5 100644
--- a/server/atomic_server.lpr
+++ b/server/atomic_server.lpr
@@ -26,12 +26,21 @@
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Program atomic_server;
Uses
- sysutils, lazutf8, LazFileUtils
+{$IFDEF UNIX}
+ cthreads, // Thread support for Unix-like systems
+{$ENDIF}
+ sysutils // Standard Pascal units (no Lazarus dependencies)
, uatomic_server
, uatomic_common
+ , uip // For GetLocalIPs() to get server IP address
;
Procedure PrintHelp;
@@ -57,10 +66,12 @@
Server: TServer;
Autotimeout: integer = ServerAutoTimeout;
Port: integer = -1;
- i: integer;
+ i, j: integer;
s: String;
si: Single;
Params: Array Of Boolean = Nil; // Zum Prüfen ob auch alle übergebenen Parameter verwendet wurden.
+ adapters: TNetworkAdapterList;
+ serverIP: String;
Begin
(*
OPL: - Alle Krankheiten (Speed Up, Switch Bombermen, Fast Bomb, Small Flame, Eject Bomb Fast + Kick)
@@ -107,11 +118,11 @@
Params[i + 1] := true;
End;
If lowercase(paramstr(i)) = '-f' Then Begin
- s := ExtractFilePath(ParamStrutf8(i + 1));
+ s := ExtractFilePath(ParamStr(i + 1));
Params[i] := true;
Params[i + 1] := true;
- If Not DirectoryExistsutf8(s) Then Begin
- If Not CreateDirUTF8(s) Then Begin
+ If Not DirectoryExists(s) Then Begin
+ If Not CreateDir(s) Then Begin
Log('Could not create : ' + s, llWarning);
Continue;
End;
@@ -127,7 +138,7 @@
s := '';
For i := 1 To high(Params) Do Begin
If Not params[i] Then Begin
- s := s + ' ' + ParamStrUTF8(i);
+ s := s + ' ' + ParamStr(i);
End;
End;
If s <> '' Then Begin
@@ -141,7 +152,32 @@
exit;
End
Else Begin
- Log('Launching on Port : ' + inttostr(port), llinfo);
+ // Get server IP address for display
+ serverIP := '127.0.0.1'; // Default to localhost
+ Try
+ adapters := GetLocalIPs();
+ // Find first non-localhost IP address (prefer network IP over localhost)
+ For j := 0 To High(adapters) Do Begin
+ If (adapters[j].IpAddress <> '127.0.0.1') And (adapters[j].IpAddress <> '') Then Begin
+ serverIP := adapters[j].IpAddress;
+ break;
+ End;
+ End;
+ Except
+ // If we can't get IP address, use localhost
+ serverIP := '127.0.0.1';
+ End;
+
+ // Display server connection info in a nice formatted box
+ Log('===========================================', llinfo);
+ Log('', llinfo);
+ Log(' Server is Running on address', llinfo);
+ Log('', llinfo);
+ Log(' ' + serverIP, llinfo);
+ Log('', llinfo);
+ Log(' Port: ' + inttostr(port), llinfo);
+ Log('', llinfo);
+ Log('===========================================', llinfo);
If Autotimeout = 0 Then Begin
Log('Autotimeout = 0, press "ESC" to terminate.', llinfo);
End;
diff --git a/server/uai.pas b/server/uai.pas
index 586ee21..cd5afc2 100644
--- a/server/uai.pas
+++ b/server/uai.pas
@@ -1,156 +1,206 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uai;
-
-{$MODE ObjFPC}{$H+}
-
-Interface
-
-Uses
- Classes, SysUtils
- , uai_types
- , ctypes
- ;
-
-Type
-
- (*
- * Initialize the Lib with the Playercount (normally 10, only in Debuggmode different)
- *)
- TAiInit = Function(): cBool; cdecl;
-
- (*
- * Will be called on lib unloading
- *)
- TAiDeInit = Procedure(); cdecl;
-
- (*
- * Tells the Lib to start a new "round" = Reset all old values if needed
- * Strenght in [0% .. 100%] -> 100% means "Best / Strongest"
- *)
- TAiNewRound = Procedure(Strength: cuint8); cdecl;
-
- (*
- * Will be Called every 10ms, this is the main routine where the Ai should be implemented
- *)
- TAiHandlePlayer = Function(PlayerIndex: cuint32; Var AiInfo: TAiInfo): TAiCommand; Cdecl;
-
- (*
- * Callback to get Interface version
- *)
- TAiInterfaceVersion = Function(): cuint32; Cdecl;
-
- (*
- * Callback for versionstring of ai lib
- *)
- TAiVersion = Function(): pchar; cdecl;
-
-Var
- AiInit: TAiInit = Nil;
- AiDeInit: TAiDeInit = Nil;
- AiNewRound: TAiNewRound = Nil;
- AiHandlePlayer: TAiHandlePlayer = Nil;
- AiInterfaceVersion: TAiInterfaceVersion = Nil;
- AiVersion: TAiVersion = Nil;
-
-Function LoadAiLib(): Boolean;
-Procedure UnLoadAiLib;
-
-Implementation
-
-Uses dynlibs, uatomic_common;
-
-Var
- Lib: TLibHandle = 0;
-
-Function LoadAiLib(): Boolean;
-Var
- Filename: String;
-Begin
-{$IFDEF Windows}
- Filename := 'ai.dll';
-{$ELSE}
- Filename := 'libai.so';
-{$ENDIF}
- Filename := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + Filename;
- result := false;
- If lib <> 0 Then UnloadLibrary(lib);
- If Not FileExists(Filename) Then exit;
- lib := LoadLibrary(Filename);
- If lib = 0 Then exit;
- AiInterfaceVersion := TAiInterfaceVersion(GetProcAddress(lib, 'AiInterfaceVersion'));
- If Not assigned(AiInterfaceVersion) Then Begin
- UnLoadAiLib;
- exit;
- End;
-
- If AiInterfaceVersion() <> AiLibInterfaceVersion Then Begin
- logshow(format('Error, invalid ai interface version. Got %d need %d', [AiInterfaceVersion(), AiLibInterfaceVersion]), llError);
- UnLoadAiLib;
- exit;
- End;
-
- AiInit := TAiInit(GetProcAddress(lib, 'AiInit'));
- If Not assigned(AiInit) Then Begin
- UnLoadAiLib;
- exit;
- End;
- AiNewRound := TAiNewRound(GetProcAddress(lib, 'AiNewRound'));
- If Not assigned(AiNewRound) Then Begin
- UnLoadAiLib;
- exit;
- End;
-
- AiHandlePlayer := TAiHandlePlayer(GetProcAddress(lib, 'AiHandlePlayer'));
- If Not assigned(AiHandlePlayer) Then Begin
- UnLoadAiLib;
- exit;
- End;
-
- AiDeInit := TAiDeInit(GetProcAddress(lib, 'AiDeInit'));
- If Not assigned(AiDeInit) Then Begin
- UnLoadAiLib;
- exit;
- End;
-
- AiVersion := TAiVersion(GetProcAddress(lib, 'AiVersion'));
- If Not assigned(AiVersion) Then Begin
- UnLoadAiLib;
- exit;
- End;
-
- result := true;
-End;
-
-Procedure UnLoadAiLib;
-Begin
- (*
- * Beim Entladen vorher immer ein Deinit !
- *)
- If assigned(AiDeInit) Then Begin
- AiDeInit();
- End;
- If lib <> 0 Then UnloadLibrary(Lib);
- Lib := 0;
- AiInit := Nil;
- AiNewRound := Nil;
- AiDeInit := Nil;
- AiHandlePlayer := Nil;
- AiInterfaceVersion := Nil;
- AiVersion := Nil;
-End;
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uai;
+
+{$MODE ObjFPC}{$H+}
+
+Interface
+
+Uses
+ Classes, SysUtils
+ , uai_types
+ , ctypes
+ ;
+
+Type
+
+ (*
+ * Initialize the Lib with the Playercount (normally 10, only in Debuggmode different)
+ *)
+ TAiInit = Function(): cBool; cdecl;
+
+ (*
+ * Will be called on lib unloading
+ *)
+ TAiDeInit = Procedure(); cdecl;
+
+ (*
+ * Tells the Lib to start a new "round" = Reset all old values if needed
+ * Strenght in [0% .. 100%] -> 100% means "Best / Strongest"
+ *)
+ TAiNewRound = Procedure(Strength: cuint8); cdecl;
+
+ (*
+ * Will be Called every 10ms, this is the main routine where the Ai should be implemented
+ *)
+ TAiHandlePlayer = Function(PlayerIndex: cuint32; Var AiInfo: TAiInfo): TAiCommand; Cdecl;
+
+ (*
+ * Callback to get Interface version
+ *)
+ TAiInterfaceVersion = Function(): cuint32; Cdecl;
+
+ (*
+ * Callback for versionstring of ai lib
+ *)
+ TAiVersion = Function(): pchar; cdecl;
+
+Var
+ AiInit: TAiInit = Nil;
+ AiDeInit: TAiDeInit = Nil;
+ AiNewRound: TAiNewRound = Nil;
+ AiHandlePlayer: TAiHandlePlayer = Nil;
+ AiInterfaceVersion: TAiInterfaceVersion = Nil;
+ AiVersion: TAiVersion = Nil;
+
+Function LoadAiLib(): Boolean;
+Procedure UnLoadAiLib;
+
+Implementation
+
+Uses dynlibs, uatomic_common;
+
+Var
+ Lib: TLibHandle = 0;
+
+Function LoadAiLib(): Boolean;
+Var
+ Filename, BasePath: String;
+{$IFDEF Darwin}
+ ArchDir: String = '';
+{$ENDIF}
+
+ Function TryLoad(const BasePath: String): Boolean;
+ Var
+ Candidate: String;
+ Begin
+ Candidate := IncludeTrailingPathDelimiter(BasePath) + Filename;
+ If Not FileExists(Candidate) Then Begin
+ Exit(False);
+ End;
+ Lib := LoadLibrary(Candidate);
+ If Lib = 0 Then
+ log(format('AI: LoadLibrary failed for: %s', [Candidate]), llError);
+ TryLoad := Lib <> 0;
+ End;
+Begin
+{$IFDEF Windows}
+ Filename := 'ai.dll';
+{$ELSE}
+ {$IFDEF DARWIN}
+ Filename := 'libai.dylib';
+{$ELSE}
+ Filename := 'libai.so';
+{$ENDIF}
+{$ENDIF}
+ Result := False;
+ If lib <> 0 Then UnloadLibrary(lib);
+ Lib := 0;
+
+ BasePath := ExtractFilePath(ParamStr(0));
+ If Not TryLoad(BasePath) Then
+ Begin
+{$IFDEF Darwin}
+ {$IFDEF CPUAARCH64}
+ ArchDir := 'arm64';
+ {$ENDIF}
+ {$IFDEF CPUX86_64}
+ ArchDir := 'x86_64';
+ {$ENDIF}
+ If ArchDir <> '' Then
+ TryLoad(ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + '../../lib/' + ArchDir));
+ If (Lib = 0) Then
+ TryLoad(ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + '../lib'));
+{$ENDIF}
+ End;
+ If lib = 0 Then Begin
+ log('AI: Failed to load AI library from all attempted paths', llError);
+ exit;
+ End;
+ AiInterfaceVersion := TAiInterfaceVersion(GetProcAddress(lib, 'AiInterfaceVersion'));
+ If Not assigned(AiInterfaceVersion) Then Begin
+ log('AI: Failed to load AiInterfaceVersion function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+ If AiInterfaceVersion() <> AiLibInterfaceVersion Then Begin
+ logshow(format('Error, invalid ai interface version. Got %d need %d', [AiInterfaceVersion(), AiLibInterfaceVersion]), llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ AiInit := TAiInit(GetProcAddress(lib, 'AiInit'));
+ If Not assigned(AiInit) Then Begin
+ log('AI: Failed to load AiInit function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ AiNewRound := TAiNewRound(GetProcAddress(lib, 'AiNewRound'));
+ If Not assigned(AiNewRound) Then Begin
+ log('AI: Failed to load AiNewRound function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ AiHandlePlayer := TAiHandlePlayer(GetProcAddress(lib, 'AiHandlePlayer'));
+ If Not assigned(AiHandlePlayer) Then Begin
+ log('AI: Failed to load AiHandlePlayer function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ AiDeInit := TAiDeInit(GetProcAddress(lib, 'AiDeInit'));
+ If Not assigned(AiDeInit) Then Begin
+ log('AI: Failed to load AiDeInit function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ AiVersion := TAiVersion(GetProcAddress(lib, 'AiVersion'));
+ If Not assigned(AiVersion) Then Begin
+ log('AI: Failed to load AiVersion function', llError);
+ UnLoadAiLib;
+ exit;
+ End;
+
+ result := true;
+End;
+
+Procedure UnLoadAiLib;
+Begin
+ (*
+ * Beim Entladen vorher immer ein Deinit !
+ *)
+ If assigned(AiDeInit) Then Begin
+ AiDeInit();
+ End;
+ If lib <> 0 Then UnloadLibrary(Lib);
+ Lib := 0;
+ AiInit := Nil;
+ AiNewRound := Nil;
+ AiDeInit := Nil;
+ AiHandlePlayer := Nil;
+ AiInterfaceVersion := Nil;
+ AiVersion := Nil;
+End;
+
+End.
+
diff --git a/server/uatomic_server.pas b/server/uatomic_server.pas
index b77e91b..50b1e6e 100644
--- a/server/uatomic_server.pas
+++ b/server/uatomic_server.pas
@@ -1,2221 +1,2468 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uatomic_server;
-
-{$MODE ObjFPC}{$H+}
-
-{$I ../client/globaldefines.inc}
-
-Interface
-
-Uses
- Classes, SysUtils, Lnet, crt,
- uChunkmanager, uatomic_common, uatomic_messages, uatomic_field, uai_types;
-
-Type
-
- TGameStatistik = Record
- Total: Array[TStatSelector] Of UInt64;
- LastRun: Array[TStatSelector] Of UInt64;
- End;
-
- TGameState = (
- gsWaitForPlayersToConnect // Wir warten auf Spieler die Mit Spielen wollen
- , gsPlayerSetup // Die Spieler wollen ihre Farben Editieren
- , gsMapSetup // Die Spieler wollen die Eigenschaften der Karte Editieren
- , gsPlaying // Die Spieler Spielen auf der Karte
- , gsShowHighscore // Anzeige der Highscores
- );
-
- TUidInfos = Record
- Uid: Integer;
- Fields: TFieldHashNameList;
- End;
-
- tFrameLog = Record
- TimeStamp: QWord;
- AccumulatedSize: uint64;
- Count: integer;
- End;
-
- { TServer }
-
- TServer = Class
- private
- fKickAllPlayer: boolean; // If True, the server kicks every player during the next "Idle"
- fFrameLog: tFrameLog;
- fStatistik: TGameStatistik;
- fRandomMap: Boolean;
- fLastHeartbeatTimestamp: int64; // Der Zeitpunkt an welchen der Letzte Heartbeat versendet wird
- fPlayingTimeasc: int64; // Zeit in ms die die runde schon läuft
- fPlayingTimedesc: int64; // Zeit in ms die die Runde noch läuft
-
- fpausing: Boolean;
- fSyncPause: Boolean;
- foldpausevalue: Boolean;
- fPauseTimestamp: int64; // Der Zeitpunkt, an dem eine Pause gestartet wurde
- FLastFrameTimestamp: int64; // Zeitpunkt an dem das Letzte "Frame" Berechnet wurde
- fLastClientUpdateTimestamp: int64; // Zeitpunkt an dem zuletzt alle Clients Aktualisiert wurden
-
- fSettings: TAtomicSettings;
- fFields: Array Of TAtomicField;
- fConnectedClientCount: integer; // Anzahl der Tatsächlich verbundenen Clients, wird bestimmt bei HandleSwitchToPlayerSetup und ist immer <= GetActivePlayerCount()
- fActualField: TAtomicField; // Das Feld, welches für dieses Match Aktiv ist, Wird mittels miUpdateFieldSetup gesetzt
-
- fUDP: TLUdp; // Zum Empfangen und Senden der Aktiven Server Verbindungen
- fTCP: TLTcp; // Die L-Net TCP Komponente
- fChunkManager: TChunkManager; // Der Chunkmanager zum senden der Daten
- fTCPPort: integer; // Der Port auf welchem wir den Chunkmanager gestaret haben (für die UDP-Broadcaster)
- factive: Boolean; // True, so lange clients verbunden sind
- fLastActiveTickTimestamp: Int64; // Zum Bestimmen ob der Server sich automatisch beenden soll, wenn Keine Spieler mehr aktiv sind.
-
- fGameState: TGameState;
- fAutotimeout: integer;
- fPLayer: TPlayers;
- fUidInfos: Array Of TUidInfos; // Informationen die am Spieler hängen aber nicht an den Positionen ..
-
- Procedure OnAccept(aSocket: TLSocket);
- Procedure OnDisconnect(aSocket: TLSocket);
- Procedure OnError(Const msg: String; aSocket: TLSocket);
-
- Procedure OnUDPReceiveEvent(aSocket: TLSocket);
- Procedure OnUDPError(Const msg: String; aSocket: TLSocket);
- Procedure OnUDPDisconnect(aSocket: TLSocket);
-
- Procedure OnReceivedChunk(Sender: TObject; Const Chunk: TChunk);
- Procedure ResetFieldAvailabe();
- Function SendChunk(UserDefinedID: Integer; Data: TStream; UID: integer): Boolean;
- Procedure SendSplashMessage(msg: String; TargetUID: integer);
- Procedure SendSettings();
-
- Procedure HandleRequestUserLogin(Const Stream: TStream; UID: integer);
- Procedure HandleSwitchToPlayerSetup;
- Procedure HandleSwitchToMapProperties(UID: Integer);
- Procedure HandleStartGame();
- Procedure HandleStartRound();
- Procedure HandleTogglePause();
- Procedure HandleShowVictory();
- Procedure HandlePlayerGetsPowerUp(Var Player: TPlayer; PlayerIndex: integer;
- PowerUp: TPowerUps);
- Procedure HandlePlaySoundEffect(PlayerIndex: integer; Effect: TSoundEffect);
- Procedure HandleStatisticCallback(StatSelector: TStatSelector; Value: uint64 = 1);
-
- Procedure HandleLoadSettings(Const Stream: TStream);
- Procedure HandleChangePlayerKey(PlayerIndex, Direction: Integer; PlayerName: String; UID: Integer);
- Procedure HandleSwitchToWaitForPlayersToConnect;
- Procedure HandleUpdateFieldSetup(Const Stream: TStream; Uid: integer);
- Procedure HandleReceiveHeartBeat(p: integer; t: int64);
- Procedure HandleClientKeyEvent(Const Stream: TStream);
-
- Procedure RefreshAllPlayerStats(Uid: integer);
- Procedure PlayerLeaves(PlayerUid: integer);
- Function GetActivePlayerCount(): Integer; // Ermittelt alle Spieler, derren UID <> NoPlayer ist !
- Procedure EvalFieldHashList(Const List: TFieldHashNameList; SendToMaster: Boolean);
-
- Procedure CheckSynchrons;
- Procedure ApplyPause(Value: Boolean);
- Procedure CreateNewFrame; // Quasi das Virtuelle render
- Procedure UpdateAllClients; // Aktualisierung aller Clients
- Procedure SendPlayerStatistiks; // Am Ende einer Runde müssen alle Spieler über die Aktuelle Statistik informiert werden
- Procedure EndGameCheck;
- Function MatchFinished(): Boolean;
-
- Procedure LoadAi();
- Procedure HurryHandling;
- public
- Constructor Create(Port, AutoTimeOut: Integer);
- Destructor Destroy(); override;
- Procedure Execute;
- Procedure LoadStatistiks();
- Procedure SaveStatistiks();
- End;
-
-Implementation
-
-Uses FileUtil, uvectormath, math, IniFiles, uai;
-
-{ TServer }
-
-Constructor TServer.Create(Port, AutoTimeOut: Integer);
-Var
- sl: TStringList;
- i: Integer;
-Begin
- log('TServer.create', lltrace);
- Inherited create;
- fChunkManager := Nil;
- factive := false;
- fFields := Nil;
- HandleSwitchToWaitForPlayersToConnect;
- fAutotimeout := AutoTimeOut;
- fTCP := TLTcp.Create(Nil);
- fTCP.ReuseAddress := true; // Bei Absturz kann so sofort wieder neu verbunden werden
- fTCP.OnAccept := @OnAccept;
- fTCP.OnError := @OnError;
- fTCP.OnDisconnect := @OnDisconnect;
- fUDP := TLUdp.Create(Nil);
- fUDP.OnReceive := @OnUDPReceiveEvent;
- fUDP.OnError := @OnUDPError;
- fUDP.OnDisconnect := @OnUDPDisconnect;
-
- fChunkManager := TChunkManager.create;
- fChunkManager.RegisterConnection(fTCP);
- fChunkManager.OnReceivedChunk := @OnReceivedChunk;
-
- fLastActiveTickTimestamp := GetTickCount64;
- fTCPPort := Port;
-
- // Laden aller Felder
- sl := FindAllDirectories(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'data' + PathDelim + 'maps', false);
- sl.Sorted := true;
- sl.Sort; // Ist beim Client wichtig, beim Server wäre es theoretisch egal, so ists aber leichter zum debuggen
- setlength(fFields, sl.Count);
- For i := 0 To sl.Count - 1 Do Begin
- fFields[i] := TAtomicField.Create(@HandlePlaySoundEffect, @HandleStatisticCallback);
- If Not fFields[i].loadFromDirectory(sl[i]) Then Begin
- Raise exception.create('Error, unable to load field:' + sl[i]);
- End;
- End;
- sl.free;
- setlength(fFields, high(fFields) + 2);
- fFields[high(fFields)] := TAtomicRandomField.Create(Nil, Nil); // Die initialisiert sich bereits richtig ;)
- LoadAi();
- If Not fUDP.Listen(UDPPingPort) Then Begin
- log('Error, unable to listen on port: ' + inttostr(UDPPingPort), llFatal);
- LogLeave;
- exit;
- End;
- If Not fChunkManager.Listen(Port) Then Begin
- log('Error could not listen on port: ' + inttostr(port), llFatal);
- LogLeave;
- exit;
- End;
- factive := true; // Haben wir es bis hier her geschafft, darf die Execute auch "laufen"
- LogLeave;
-End;
-
-Destructor TServer.Destroy;
-Var
- i: Integer;
-Begin
- log('TServer.destroy', lltrace);
- If assigned(fChunkManager) Then Begin
- fChunkManager.Disconnect(true);
- fChunkManager.free;
- End;
- // Das Disconnect macht ja der ChunkManager !
- While fTCP.Connected Do Begin
- fTCP.CallAction;
- End;
- ftcp.free;
- // Den UDP auch sauber platt machen
- If fUDP.Connected Then Begin
- fUDP.Disconnect(true);
- While fUDP.Connected Do Begin
- fUDP.CallAction;
- End;
- End;
- fUDP.free;
- For i := 0 To high(fFields) Do Begin
- fFields[i].Free;
- End;
- setlength(fFields, 0);
- UnLoadAiLib(); // da ist das AiDeInit mit drin ;)
- LogLeave;
-End;
-
-Procedure TServer.OnAccept(aSocket: TLSocket);
-Begin
- // Wir Aktzeptieren eine Engehende Verbindung
- log('TServer.OnAccept : ' + aSocket.PeerAddress, llTrace);
- fChunkManager.SetNoDelay(true);
- LogLeave;
-End;
-
-Procedure TServer.OnDisconnect(aSocket: TLSocket);
-Var
- uid: integer;
-Begin
- // Wir verlieren einen Spieler
- If assigned(asocket) Then Begin
- log('TServer.OnDisconnect : ' + aSocket.PeerAddress, llTrace);
- End
- Else Begin
- log('TServer.OnDisconnect', llTrace);
- End;
- uid := fChunkManager.SocketToUID(aSocket);
- PlayerLeaves(uid);
- LogLeave;
-End;
-
-Procedure TServer.OnError(Const msg: String; aSocket: TLSocket);
-Begin
- log('TServer.OnError', llTrace);
- If assigned(asocket) Then Begin
- log(asocket.PeerAddress + msg, llError)
- End
- Else Begin
- log(msg, llError)
- End;
- LogLeave;
-End;
-
-Procedure TServer.OnUDPError(Const msg: String; aSocket: TLSocket);
-Begin
- log('TServer.OnUDPError', llTrace);
- If assigned(asocket) Then Begin
- log(asocket.PeerAddress + msg, llError)
- End
- Else Begin
- log(msg, llError)
- End;
- LogLeave;
-End;
-
-Procedure TServer.OnUDPDisconnect(aSocket: TLSocket);
-Begin
- log('TServer.OnUDPDisconnect', llTrace);
- If assigned(asocket) Then Begin
- log('TServer.OnUDPDisconnect: ' + asocket.PeerAddress, llError)
- End
- Else Begin
- log('TServer.OnUDPDisconnect', llError)
- End;
- LogLeave;
-End;
-
-Procedure TServer.OnUDPReceiveEvent(aSocket: TLSocket);
-Var
- UserName: String;
- Buffer: Array[0..1024 - 1] Of byte;
- cnt, i, ReadCnt: Integer;
- b: Byte;
-Begin
- If assigned(aSocket) Then Begin
- log('TServer.OnUDPReceiveEvent : ' + aSocket.PeerAddress, llTrace);
- End
- Else Begin
- log('TServer.OnUDPReceiveEvent', llTrace);
- End;
- Repeat
- (*
- * Es muss immer alles gelesen werden, sonst passieren merkwürdige Dinge
- *)
- ReadCnt := aSocket.Get(buffer, 1024);
- If fGameState = gsWaitForPlayersToConnect Then Begin // Nur im Editor Modus, aktzeptieren wir Spieler, also Antworten wir auch nur wenn wir im Editor Modus sind
- If GetActivePlayerCount() <> 0 Then Begin // Es ist midnestens 1 Spieler Angemeldet, also geben wir den Namen des 1. Spielers an
- (*
- * Das ist hier zwar Richtig, aber eigentlich Falsch, korrekt wäre das Suchen des 1. Spielers mit UID <> NoPlayer !
- * -> Aktuell wertet der Client den String aber eh nicht aus, von daher, who cares...
- *)
- UserName := fPLayer[0].UserName + 's game';
- End
- Else Begin // Gar kleine Spieler, dann nur den Servernamen
- UserName := 'no user connected';
- End;
- username := username + ':' + inttostr(fTCPPort);
- cnt := length(username);
- b := 21; // CTD hat hier 42 -> Wir wollen das die beiden nicht "Kompatibel" sind !
- For i := 0 To cnt - 1 Do Begin
- buffer[i] := ord(username[i + 1]);
- b := b Xor buffer[i];
- End;
- Buffer[cnt] := b;
- aSocket.Send(buffer, cnt + 1);
- End;
- Until ReadCnt = 0;
- LogLeave;
-End;
-
-Procedure TServer.OnReceivedChunk(Sender: TObject; Const Chunk: TChunk);
-Var
- s: String;
- i, j: integer;
- ts: QWord;
-Begin
- //responceID := Chunk.UserDefinedID And $FFFF0000;
- HandleStatisticCallback(sTotalNetworkPacketsIn);
- HandleStatisticCallback(sTotalNetworkBytesIn, Chunk.Data.Size + ChunkManagerHeaderLen);
-{$IFDEF DoNotLog_CyclicMessages}
- If ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
- ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
-{$ENDIF}
- log(format('TServer.OnReceivedChunk : %d, %s', [Chunk.UID, MessageIdentifierToString(Chunk.UserDefinedID)]), llTrace);
-
- Case (Chunk.UserDefinedID And $FFFF) Of
- miTogglePause: Begin
- HandleTogglePause();
- End;
- miClientKeyEvent: Begin
- HandleClientKeyEvent(Chunk.Data);
- End;
- miHeartBeat: Begin
- i := -1;
- chunk.Data.Read(i, sizeof(i));
- ts := 0;
- chunk.Data.Read(ts, sizeof(ts));
- HandleReceiveHeartBeat(i, ts);
- End;
- miRequestLogin: Begin
- HandleRequestUserLogin(Chunk.data, chunk.UID);
- End;
- miSwitchToPlayerSetup: Begin
- HandleSwitchToPlayerSetup();
- End;
- miUpdateSettings: Begin
- HandleLoadSettings(Chunk.Data);
- End;
- miChangePlayerKey: Begin
- i := -1;
- chunk.Data.Read(i, sizeof(i));
- j := 0;
- chunk.Data.Read(j, sizeof(j));
- s := Chunk.Data.ReadAnsiString;
- HandleChangePlayerKey(i, j, s, Chunk.UID);
- End;
- miSwitchToFieldSetup: Begin
- HandleSwitchToMapProperties(Chunk.UID);
- End;
- miUpdateFieldSetup: Begin
- HandleUpdateFieldSetup(Chunk.Data, Chunk.UID);
- End;
- miStartGame: Begin
- If fGameState = gsShowHighscore Then Begin
- If MatchFinished() Then Begin
- HandleShowVictory();
- End
- Else Begin
- HandleStartRound();
- End;
- End
- Else Begin
- HandleStartGame();
- End;
- End;
- Else Begin
- log('Unknown user defined id : ' + inttostr(Chunk.UserDefinedID And $FFFF), llError);
- End;
- End;
-{$IFDEF DoNotLog_CyclicMessages}
- If ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
- ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
- LogLeave;
-{$ENDIF}
-End;
-
-Procedure TServer.ResetFieldAvailabe;
-Var
- i: integer;
-Begin
- log('TServer.ResetFieldAvailabe', lltrace);
- For i := 0 To high(fFields) Do Begin
- fFields[i].Available := true;
- End;
- LogLeave;
-End;
-
-Function TServer.SendChunk(UserDefinedID: Integer; Data: TStream; UID: integer
- ): Boolean;
-Var
- i: integer;
- dataLen: int64;
-Begin
-{$IFDEF DoNotLog_CyclicMessages}
- If ((UserDefinedID And $FFFF) <> miUpdateGameData) And
- ((UserDefinedID And $FFFF) <> miHeartBeat) Then
-{$ENDIF}
- log(format('TServer.SendChunk : %d, %s', [uid, MessageIdentifierToString(UserDefinedID)]), llTrace);
- datalen := ChunkManagerHeaderLen;
- If assigned(data) Then dataLen := dataLen + Data.Size;
- result := fChunkManager.SendChunk(UserDefinedID, data, uid);
- If uid = 0 Then Begin
- datalen := dataLen * max(1, fConnectedClientCount);
- End
- Else Begin
- If uid < 0 Then Begin
- // An Alle außer einem
- datalen := dataLen * max(0, fConnectedClientCount - 1);
- End
- Else Begin
- // Die Länge stimmt es geht ja nur an einen ;)
- End;
- End;
- HandleStatisticCallback(sTotalNetworkPacketsOut);
- HandleStatisticCallback(sTotalNetworkBytesOut, dataLen);
- fFrameLog.AccumulatedSize := fFrameLog.AccumulatedSize + dataLen;
- fFrameLog.Count := fFrameLog.Count + 1;
- If Not result Then Begin
- For i := low(fPLayer) To high(fPLayer) Do Begin
- If fPLayer[i].UID = UID Then Begin
- log('Could not send to player : ' + fPLayer[i].UserName, llCritical);
- LogLeave;
- exit;
- End;
- End;
- If uid < 0 Then Begin
- (*
- * Ein Broadcast bringt nur was wenn wir mehr als 1 Spieler haben ;)
- *)
- If GetActivePlayerCount() > 1 Then Begin
- log('Could not send, maybe no more clients connected.', llWarning);
- End;
- End
- Else Begin
- log('Could not send to player : ' + inttostr(uid), llCritical);
- End;
- End;
-{$IFDEF DoNotLog_CyclicMessages}
- If (UserDefinedID <> miUpdateGameData) And
- (UserDefinedID <> miHeartBeat) Then
-{$ENDIF}
- LogLeave;
-End;
-
-Procedure TServer.SendSplashMessage(msg: String; TargetUID: integer);
-Var
- m: TMemoryStream;
-Begin
- m := TMemoryStream.Create;
- m.WriteAnsiString(msg);
- SendChunk(miSplashHint, m, TargetUID);
-End;
-
-Procedure TServer.HandleRequestUserLogin(Const Stream: TStream; UID: integer);
-Var
- m: TMemoryStream;
- index, i, j, cnt: integer;
- Username: String;
- ClientVersion: uint32;
- fieldlist: TFieldHashNameList;
- ClientMode: Byte;
-Begin
- log('TServer.HandleUserLoginRequest', llTrace);
- ClientVersion := $FFFFFFFF;
- Stream.Read(ClientVersion, sizeof(ClientVersion));
- m := TMemoryStream.Create;
- // 0. Check ob die beiden Versionen Compatibel sind
- If ProtocollVersion <> ClientVersion Then Begin
- i := EC_Invalid_Versions;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- LogLeave;
- exit;
- End;
-
- ClientMode := 0;
- Stream.Read(ClientMode, sizeof(ClientMode));
- Username := Stream.ReadAnsiString;
-
-{$IFDEF Release}
- If ClientMode <> GameModeRelease Then
-{$ELSE}
- If ClientMode <> GameModeDebug Then
-{$ENDIF}Begin
- i := EC_Invalid_Mode_Versions;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- LogLeave;
- exit;
- End;
- //// 1. Check : Passwort
- //If Password <> fPassword Then Begin
- // i := EC_Invalid_Password;
- // m.Write(i, sizeof(i));
- // SendChunk(miRequestLoginResult, m, UID);
- // LogLeave;
- // exit;
- //End;
- // 2. Check : Darf der Spieler überhaupt verbinden = Läuft gerade ein Spiel ?
- If (fGameState <> gsWaitForPlayersToConnect) Then Begin
- i := EC_game_full;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- LogLeave;
- exit;
- End;
- // 3. Check : Gibt es den Spielernamen bereits ?
- cnt := 0;
- For j := low(fPLayer) To high(fPLayer) Do Begin
- If (fPLayer[j].UID <> NoPlayer) Then Begin
- inc(cnt);
- If (fPLayer[j].UserName = Username) Then Begin
- i := EC_User_already_exists;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- LogLeave;
- exit;
- End;
- End;
- End;
- // 4. Check: Max 10 Spieler
- If cnt >= length(fPLayer) Then Begin
- i := EC_Too_Much_Player;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- LogLeave;
- exit;
- End;
- // Alles I.O. Der User kann beitreten
- // Suchen eines Freien Platzes für den neuen Spieler ;)
- index := -1;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID = NoPlayer Then Begin
- index := i;
- break;
- End;
- End;
- (*
- * Oben der Check ging durch und hier finden wir nix, das darf nicht sein, alles canceln !
- *)
- If index = -1 Then Begin
- log('Error player overflow', llCritical);
- HandleSwitchToWaitForPlayersToConnect;
- LogLeave;
- exit;
- End;
- // Der erste Spieler Loggt sich ein -> Wird zum Bestimmenden ;)
- If cnt = 0 Then Begin
- assert(fSettings.MasterUid = -1, 'First player connects, but old data was not cleared.');
- fSettings.MasterUid := UID;
- ResetFieldAvailabe();
- End;
- fPLayer[index].UID := UID;
- fPLayer[index].UserName := Username;
- fPLayer[index].Keyboard := ks0; // Beim Anlegen gibt es nur den Spieler 1 mit Keyboard 1
- fPLayer[index].Kills := 0;
- fPLayer[index].Score := 0;
- i := -1;
- Stream.Read(i, SizeOf(i));
- fieldlist := Nil;
- setlength(fieldlist, i);
- For i := 0 To high(fieldlist) Do Begin
- fieldlist[i].Name := Stream.ReadAnsiString;
- Stream.Read(fieldlist[i].Hash, sizeof(fieldlist[i].Hash));
- End;
- setlength(fUidInfos, high(fUidInfos) + 2);
- fUidInfos[high(fUidInfos)].Uid := UID;
- fUidInfos[high(fUidInfos)].Fields := fieldlist;
- log(format('Accepted player : %s as %d, now %d player in logged in', [Username, uid, cnt + 1]), llInfo);
- i := EC_No_Error;
- m.Write(i, sizeof(i));
- i := uid;
- m.Write(i, sizeof(i));
- i := fSettings.MasterUid;
- m.Write(i, sizeof(i));
- SendChunk(miRequestLoginResult, m, UID);
- // Allen Mitteilen das wir nen neuen Spieler haben
- RefreshAllPlayerStats(0); // Allen Anwesenden Mitteilen Welche Spieler es so gibt
- // Der Spieler ist Drin, nun müssen wir noch die Verfügbaren Karten von Beiden "Checken"
- // Und dem Master Die Schnittmenge Mitteilen
- EvalFieldHashList(fieldlist, true);
- LogLeave;
-End;
-
-Procedure TServer.HandleSwitchToPlayerSetup;
-Begin
- log('TServer.HandleSwitchToPlayerSetup', llTrace);
- SendSettings(); // Alle Clients werden nun Settingstechnisch Gleich Geschaltet
- fConnectedClientCount := GetActivePlayerCount();
- fGameState := gsPlayerSetup;
- SendChunk(miSwitchToPlayerSetup, Nil, 0);
- LogLeave;
-End;
-
-Procedure TServer.SendSettings;
-Var
- m: TMemoryStream;
-Begin
- log('TServer.SendSettings', llTrace);
- m := TMemoryStream.Create;
- m.write(fSettings.TeamPlay, sizeof(fSettings.TeamPlay));
- m.write(fSettings.RandomStart, sizeof(fSettings.RandomStart));
- // Nodename hat der Server nicht
- m.write(fSettings.ConveyorSpeed, sizeof(fSettings.ConveyorSpeed));
- SchemeToStream(m, fSettings.Scheme);
- m.write(fSettings.PlayTime, sizeof(fSettings.PlayTime));
- m.write(fSettings.LostPlayersRevertToAI, sizeof(fSettings.LostPlayersRevertToAI));
- // Playsounds hat der Server nicht
- // Keyboard hat der Server nicht
- m.WriteAnsiString(fSettings.LastPlayedField);
- m.write(fSettings.LastPlayedFieldHash, sizeof(fSettings.LastPlayedFieldHash));
- m.write(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
- // Port hat der Server nicht
- // CheckForUpdates hat der Server nicht
- (*
- * Die Settings kamen ja von der MasterUid, also kriegen sie Alle bis auf der Master ;)
- *)
- SendChunk(miUpdateSettings, m, -fSettings.MasterUid);
- LogLeave;
-End;
-
-Procedure TServer.HandleLoadSettings(Const Stream: TStream);
-Var
- i: Integer;
-Begin
- log('TServer.HandleLoadSettings', llTrace);
- Stream.read(fSettings.TeamPlay, sizeof(fSettings.TeamPlay));
- Stream.read(fSettings.RandomStart, sizeof(fSettings.RandomStart));
- // Nodename hat der Server nicht
- Stream.read(fSettings.ConveyorSpeed, sizeof(fSettings.ConveyorSpeed));
- If Not SchemeFromStream(Stream, fSettings.Scheme) Then Begin
- log('Error, could not load scheme from stream', llCritical);
- HandleSwitchToWaitForPlayersToConnect();
- LogLeave;
- exit;
- End;
- Stream.read(fSettings.PlayTime, sizeof(fSettings.PlayTime));
- Stream.read(fSettings.LostPlayersRevertToAI, sizeof(fSettings.LostPlayersRevertToAI));
- // Playsounds hat der Server nicht
- // Keyboard hat der Server nicht
- fSettings.LastPlayedField := Stream.ReadAnsiString();
- Stream.read(fSettings.LastPlayedFieldHash, sizeof(fSettings.LastPlayedFieldHash));
- Stream.read(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
- // Port hat der Server nicht
- // CheckForUpdates hat der Server nicht
-
- // Übernehmen der Team Informationen in die FPLayer
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].Team := fSettings.Scheme.PlayerStartPositions[i].Team;
- End;
- LogLeave;
-End;
-
-
-(*
- * Direction = 1
- * Master:
- * Off -> Uid (key0)
- * Uid (key0) -> Uid (key1)
- * Uid (key1) -> AI
- * AI -> Off
- * Jeder Andere:
- * Off -> Uid (key0)
- * Uid (key0) -> Uid (key1)
- * Uid (key1) -> Off
- * Directoin = -1
- * Master:
- * Off -> AI
- * AI -> Uid (key1)
- * Uid (key1) -> Uid (key0)
- * Uid (key0) -> Off
- * Jeder Andere:
- * Off -> Uid (key1)
- * Uid (key1) -> Uid (key0)
- * Uid (key0) -> Off
- * Alles Andere ist nicht erlaubt -> Keine Änderung
- *)
-
-Procedure TServer.HandleChangePlayerKey(PlayerIndex, Direction: Integer;
- PlayerName: String; UID: Integer);
-Begin
- log(format('TServer.HandleChangePlayerKey (%d, %d, %s)', [PlayerIndex, Direction, PlayerName]), llTrace);
- If (PlayerIndex = -1) Or (Direction = 0) Or (UID = 0) Then Begin
- LogLeave;
- exit;
- End;
- If Direction > 0 Then Begin
- If UID = fSettings.MasterUid Then Begin
- If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
- fPLayer[PlayerIndex].UID := UID;
- fPLayer[PlayerIndex].Keyboard := ks0;
- fPLayer[PlayerIndex].UserName := PlayerName;
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = uid Then Begin
- If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
- fPLayer[PlayerIndex].Keyboard := ks1;
- End
- Else Begin
- fPLayer[PlayerIndex].UID := AIPlayer;
- fPLayer[PlayerIndex].UserName := '';
- End;
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = AIPlayer Then Begin
- fPLayer[PlayerIndex].UID := NoPlayer;
- fPLayer[PlayerIndex].UserName := '';
- RefreshAllPlayerStats(0);
- End;
- End;
- End;
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
- fPLayer[PlayerIndex].UID := UID;
- fPLayer[PlayerIndex].Keyboard := ks0;
- fPLayer[PlayerIndex].UserName := PlayerName;
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = UID Then Begin
- If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
- fPLayer[PlayerIndex].Keyboard := ks1;
- End
- Else Begin
- fPLayer[PlayerIndex].UID := NoPlayer;
- fPLayer[PlayerIndex].UserName := '';
- End;
- RefreshAllPlayerStats(0);
- End;
- End;
- End;
- End
- Else Begin
- If UID = fSettings.MasterUid Then Begin
- If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
- fPLayer[PlayerIndex].UID := AIPlayer;
- fPLayer[PlayerIndex].UserName := '';
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = AIPlayer Then Begin
- fPLayer[PlayerIndex].UID := UID;
- fPLayer[PlayerIndex].Keyboard := ks1;
- fPLayer[PlayerIndex].UserName := PlayerName;
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = UID Then Begin
- If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
- fPLayer[PlayerIndex].Keyboard := ks0;
- End
- Else Begin
- fPLayer[PlayerIndex].UID := NoPlayer;
- fPLayer[PlayerIndex].UserName := '';
- End;
- RefreshAllPlayerStats(0);
- End;
- End;
- End;
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
- fPLayer[PlayerIndex].UID := UID;
- fPLayer[PlayerIndex].Keyboard := ks1;
- fPLayer[PlayerIndex].UserName := PlayerName;
- RefreshAllPlayerStats(0);
- End
- Else Begin
- If fPLayer[PlayerIndex].UID = UID Then Begin
- If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
- fPLayer[PlayerIndex].Keyboard := ks0;
- End
- Else Begin
- fPLayer[PlayerIndex].UID := NoPlayer;
- fPLayer[PlayerIndex].UserName := '';
- End;
- RefreshAllPlayerStats(0);
- End;
- End;
- End;
- End;
- LogLeave;
-End;
-
-Procedure TServer.HandleSwitchToMapProperties(UID: Integer);
-Var
- t1, t2, i, j, aicnt, pcnt: integer;
- a: Array Of Integer;
- b: Boolean;
-Begin
- log('TServer.HandleSwitchToMapProperties', llTrace);
- aicnt := 0;
- pcnt := 0;
- t1 := 0;
- t2 := 0;
- // Prüfen ob Genug Spieler verfügbar sind und diese auch in den Richtigen Teams !
- For i := 0 To high(fPlayer) Do Begin
- If fPlayer[i].UID > 0 Then inc(pcnt);
- If fPlayer[i].UID = AIPlayer Then inc(aicnt);
- If fPlayer[i].UID <> NoPlayer Then Begin
- If fPlayer[i].Team = 0 Then Begin
- inc(t1);
- End
- Else Begin
- inc(t2);
- End;
- End;
- End;
- If (pcnt = 1) And (aicnt = 0) Then Begin
- SendSplashMessage('Only one player on the map makes no sense, please wait for other players or activate at least one ai player.', UID);
- LogLeave;
- exit;
- End;
-
- If fSettings.TeamPlay Then Begin
- If (t1 = 0) Or (t2 = 0) Then Begin
- SendSplashMessage('In teamplay at least one player per team ist needed.', UID);
- LogLeave;
- exit;
- End;
- End;
-
- // Suchen auf Doppelt vergebene Spieler
- For i := 0 To high(fPLayer) Do Begin
- For j := i + 1 To high(fPLayer) Do Begin
- If (fPLayer[i].UID > 0) And (fPLayer[i].UID = fPLayer[j].UID) And (fPLayer[i].Keyboard = fPLayer[j].Keyboard) Then Begin
- SendSplashMessage('Error, client "' + fPLayer[i].UserName + '" uses two playerslots with the same key settings.', UID);
- LogLeave;
- exit;
- End;
- End;
- End;
-
- // Sind auch Alle Clients noch wenigstens 1 mal mit dabei ?
- (*
- * Zählen der Spieler mit unterschiedlicher Uid
- *)
- a := Nil;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID > NoPlayer Then Begin
- b := false;
- For j := 0 To high(a) Do Begin
- If a[j] = fPLayer[i].UID Then Begin
- b := true;
- break;
- End;
- End;
- If Not b Then Begin
- setlength(a, high(a) + 2);
- a[high(a)] := fPLayer[i].UID;
- End;
- End;
- End;
- If length(a) <> fConnectedClientCount Then Begin
- SendSplashMessage('Error, not all connected clients are connected to at least one playerslot.', UID);
- LogLeave;
- exit;
- End;
- // Alle Checks gut -> Umschalten auf die Karteneigenschaften
- fGameState := gsMapSetup;
- SendChunk(miSwitchToFieldSetup, Nil, 0);
- LogLeave;
-End;
-
-Procedure TServer.HandleStartGame;
-Var
- i: Integer;
-Begin
- log('TServer.HandleStartGame', llTrace);
- HandleStatisticCallback(sMatchesStarted);
- // 1. Alle Player "Initialisieren
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].Score := 0;
- fPLayer[i].Kills := 0;
- End;
- fRandomMap := (fActualField.Hash = 0) And (fActualField.Name = '');
- HandleStartRound;
- LogLeave;
-End;
-
-Procedure TServer.HandleStartRound;
- Function PowersFromScheme(Const Scheme: TScheme): TAtomicPowers;
- Begin
- result.Speed := AtomicDefaultSpeed;
- result.AvailableBombs := 1;
- // result.OverAllBombs := 1; -- Egal weil es unten "Hart" noch mal gesetzt wird
- result.FlameLen := 1;
- result.CanKickBombs := false;
- result.CanPunchBombs := false;
- result.CanGrabBombs := false;
- result.CanSpooger := false;
- result.TriggerBomb := 0;
- result.JellyBombs := false;
- If Scheme.PowerUps[puExtraBomb].Bornwith <> 0 Then Begin
- result.AvailableBombs := max(1, Scheme.PowerUps[puExtraBomb].BornWith);
- End;
- result.OverAllBombs := result.AvailableBombs;
- If Scheme.PowerUps[puLongerFlameLength].Bornwith > 1 Then Begin
- result.FlameLen := Scheme.PowerUps[puLongerFlameLength].Bornwith;
- End;
- If Scheme.PowerUps[puExtraSpeed].Bornwith > 0 Then Begin
- result.Speed := min(AtomicDefaultSpeed * power(AtomicSpeedChange, max(0, Scheme.PowerUps[puExtraSpeed].Bornwith)), AtomicMaxSpeed);
- End;
- // Manche Powerups schließen sich gegenseitig aus, dass muss hier und in HandlePlayerGetsPowerUp berücksichtigt werden
- // Die Reihenfolge hier gibt dabei die Prio mit an, im Spiel nachher löscht das neueste immer die alten
-
- If Scheme.PowerUps[puCanCick].Bornwith > 0 Then Begin
- result.CanKickBombs := true;
- End;
- If Scheme.PowerUps[puCanPunch].Bornwith > 0 Then Begin
- result.CanPunchBombs := true;
- End;
- If Scheme.PowerUps[puCanSpooger].Bornwith > 0 Then Begin
- result.CanSpooger := true;
- result.CanGrabBombs := false;
- End;
- If Scheme.PowerUps[puCanGrab].Bornwith > 0 Then Begin
- result.CanGrabBombs := true;
- result.CanSpooger := false;
- End;
- If Scheme.PowerUps[puGoldFlame].Bornwith > 0 Then Begin
- result.FlameLen := 99; // Egal hauptsache mehr als 15 !
- End;
- If Scheme.PowerUps[puTrigger].Bornwith > 0 Then Begin
- result.TriggerBomb := result.OverAllBombs;
- End;
- If Scheme.PowerUps[puCanJelly].Bornwith > 0 Then Begin
- result.JellyBombs := true;
- End;
- End;
-
-Var
- a, b, c, i: Integer;
- n: QWord;
- m: TMemoryStream;
- Startindex: Array[0..length(PlayerColors) - 1] Of Integer;
- pu: TPowerUps;
-Begin
- log('TServer.HandleStartRound', llTrace);
- HandleStatisticCallback(sGamesStarted);
-
- If fSettings.PlayTime = 0 Then Begin
- fPlayingTimedesc := -1000; // Unendlich ;)
- End
- Else Begin
- fPlayingTimedesc := fSettings.PlayTime * 1000;
- End;
- fPlayingTimeasc := 0;
- For i := 0 To high(Startindex) Do Begin
- Startindex[i] := i;
- End;
- // Wenn Random Start -> dann permutieren wir hier die Startpositionen ;)
- If fSettings.RandomStart Then Begin
- For i := 0 To 100 Do Begin
- a := random(length(Startindex));
- b := random(length(Startindex));
- If a <> b Then Begin
- c := Startindex[a];
- Startindex[a] := Startindex[b];
- Startindex[b] := c;
- End;
- End;
- End;
- // 1. Alle Player "Initialisieren
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].Info.Alive := fPLayer[i].UID <> NoPlayer;
- fPLayer[i].Info.Animation := raStandStill;
- fPLayer[i].Info.Value := 0;
- fPLayer[i].Info.Position := v2(fSettings.Scheme.PlayerStartPositions[Startindex[i]].x + 0.5, fSettings.Scheme.PlayerStartPositions[Startindex[i]].y + 0.5);
- fPLayer[i].Info.Direction := 0;
- fPLayer[i].Info.ColorIndex := i;
- fPLayer[i].MoveState := msStill;
- fPLayer[i].Action := aaNone;
- fPLayer[i].Flying := false;
- fPLayer[i].IsInHohle := false;
- fPLayer[i].Disease := [];
- fPLayer[i].DiseaseCounter := 0;
- fPLayer[i].IdleTimer := 0;
- fPLayer[i].Info.Dying := false; // Wir Sind alle wieder am Leben ;)
- // fPLayer[i].Team := fSettings.Scheme.PlayerStartPositions[i].Team; -- Wurde schon gemacht in HandleLoadSettings
- fPLayer[i].Powers := PowersFromScheme(fSettings.Scheme);
- For pu In TPowerUps Do Begin
- fPLayer[i].PowerUpCounter[pu] := 0;
- End;
- End;
- // 2. Init der Karte
- // Steht das Match gerade auf "Zufällige" Karten dann wählen wir hier eine neue Zufällige Karte aus
- If fRandomMap Then Begin
- fActualField := fFields[Random(Length(fFields))];
- While ((fActualField.Hash = 0) And (fActualField.Name = '')) Or (Not fActualField.Available) Do Begin
- fActualField := fFields[Random(Length(fFields))];
- End;
- // Die Clients auf die Richtigen Karten Umschalten,
- // !! Achtung das ist doppelt implementiert (siehe TServer.HandleUpdateFieldSetup)
- m := TMemoryStream.Create;
- m.WriteAnsiString(fActualField.Name);
- m.Write(fActualField.Hash, sizeof(fActualField.Hash));
- m.write(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
- SendChunk(miUpdateFieldSetup, m, 0);
- End;
-
- fActualField.Initialize(fPLayer, fSettings.Scheme);
- SendChunk(miStartGame, Nil, 0);
- n := GetTickCount64;
- For i := 0 To high(fPLayer) Do Begin // Egal das das alle sind ..
- fPLayer[i].LastSynchronTimeStamp := n;
- End;
- FLastFrameTimestamp := n;
- fLastHeartbeatTimestamp := n;
- fLastClientUpdateTimestamp := n;
- fpausing := false;
- fSyncPause := false;
- foldpausevalue := false;
- fGameState := gsPlaying;
- fFrameLog.Count := 0;
- fFrameLog.AccumulatedSize := 0;
- If assigned(AiNewRound) Then Begin
- // TODO: diese 100% müssen noch einstellbar gemacht werden
- AiNewRound(100);
- End;
- UpdateAllClients(); // Sofort alle Clients informieren, auf dass die auch gleich was sinnvolles sehen ..
- LogLeave;
-End;
-
-Procedure TServer.HandleTogglePause;
-Var
- m: TMemoryStream;
- i: Integer;
-Begin
- log('TServer.HandleTogglePause', llTrace);
- fpausing := Not fpausing;
- ApplyPause(fpausing);
- If fpausing Then Begin
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].MoveState := msStill;
- fPLayer[i].Action := aaNone;
- End;
- End;
- m := TMemoryStream.Create;
- m.Write(fpausing, sizeof(fpausing));
- SendChunk(miTogglePause, m, 0);
- LogLeave;
-End;
-
-Procedure TServer.HandleShowVictory;
-Begin
- // Den Victory Screen auswählen
- // Der Gewinner wurde bereits in EndGameCheck bestimmt.
- SendChunk(miShowVictory, Nil, 0);
- fKickAllPlayer := true;
-End;
-
-Procedure TServer.HandlePlayerGetsPowerUp(Var Player: TPlayer;
- PlayerIndex: integer; PowerUp: TPowerUps);
-Var
- index, cnt, i: integer;
- tmppos: TVector2;
-Begin
- log('TServer.HandlePlayerGetsPowerUp', llTrace);
- // TODO: Die Force, Override, forbidden dinge müssen hier noch berücksichtigt werden..
- // \-> Das Forbidden wird in TAtomicField.Initialize bereits gemacht.
- If PowerUp <> puNone Then Begin
- HandleStatisticCallback(sPowerupsCollected);
- (*
- * Mit Zählen, was der Spieler so aufsammelt
- *)
- Player.PowerUpCounter[PowerUp] := Player.PowerUpCounter[PowerUp] + 1;
- End;
- Case PowerUp Of
- puNone: Begin
- End;
- puExtraBomb: Begin
- Player.Powers.AvailableBombs := Player.Powers.AvailableBombs + 1;
- Player.Powers.OverAllBombs := Player.Powers.OverAllBombs + 1;
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- End;
- puLongerFlameLength: Begin
- Player.Powers.FlameLen := min(99, Player.Powers.FlameLen + 1);
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- End;
- puDisease: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
- Case random(3) Of
- 0: Player.Disease := Player.Disease + [dInvertedKeyboard];
- 1: Begin
- Player.Disease := Player.Disease + [dNoBombs];
- Player.Action := aaNone;
- End;
- 2: Player.Disease := Player.Disease + [dDudBombs];
- 3: Begin
- If Not (dSuperSlow In Player.Disease) Then Begin
- Player.BeforeSlowDiseaseSpeed := Player.powers.Speed;
- Player.Disease := Player.Disease + [dSuperSlow];
- Player.powers.Speed := AtomicSlowSpeed / (AtomicSpeedChange * AtomicSpeedChange);
- End;
- End;
- End;
- Player.DiseaseCounter := AtomicDiseaseTime;
- End;
- puCanCick: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.CanKickBombs := true;
- End;
- puCanPunch: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.CanPunchBombs := true;
- End;
- puExtraSpeed: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.Speed := min(Player.Powers.Speed * AtomicSpeedChange, AtomicMaxSpeed);
- End;
- puCanGrab: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.CanGrabBombs := true;
- Player.Powers.CanSpooger := false;
- End;
- puCanSpooger: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.CanSpooger := true;
- Player.Powers.CanGrabBombs := false;
- End;
- puGoldFlame: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.FlameLen := 99;
- End;
- puTrigger: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.TriggerBomb := Player.Powers.TriggerBomb + Player.Powers.OverAllBombs;
- End;
- puCanJelly: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
- Player.Powers.JellyBombs := true;
- End;
- puSuperBadDisease: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
- If random(100) < 10 Then Begin
- cnt := 0;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Info.Alive Then inc(cnt);
- End;
- (*
- * Mit Einer Wahrscheinlichkeit von 10 % tauschen wir die Plätze mit einem anderen Spieler ;)
- *)
- If cnt > 1 Then Begin
- Repeat
- index := random(Length(fPLayer));
- Until fPLayer[index].Info.Alive And (PlayerIndex <> index);
- tmppos := fPLayer[index].Info.Position;
- fPLayer[index].Info.Position := fPLayer[PlayerIndex].Info.Position;
- fPLayer[PlayerIndex].Info.Position := tmppos;
- End;
- End
- Else Begin
- Player.Disease := Player.Disease + [dEbola];
- Player.Powers.TriggerBomb := 0;
- Player.DiseaseCounter := AtomicDiseaseTime;
- End;
- End;
- puSlow: Begin
- HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
- Player.Powers.Speed := AtomicSlowSpeed;
- End;
- purandom: Begin
- log('TServer.HandlePlayerGetsPowerUp: Missing implementation for purandom', llError);
- End;
- End;
- LogLeave;
-End;
-
-Procedure TServer.HandlePlaySoundEffect(PlayerIndex: integer;
- Effect: TSoundEffect);
-Var
- m: TMemoryStream;
-Begin
- log('TServer.HandlePlaySoundEffect', llTrace);
- m := TMemoryStream.Create;
- m.Write(Effect, sizeof(Effect));
- If Effect = seOtherPlayerDied Then Begin
- SendChunk(miPlaySoundEffekt, m, -fPLayer[PlayerIndex].UID);
- End
- Else Begin
- SendChunk(miPlaySoundEffekt, m, fPLayer[PlayerIndex].UID);
- End;
- LogLeave;
-End;
-
-Procedure TServer.HandleStatisticCallback(StatSelector: TStatSelector;
- Value: uint64);
-Begin
- fStatistik.LastRun[StatSelector] := fStatistik.LastRun[StatSelector] + Value;
-End;
-
-Procedure TServer.HandleSwitchToWaitForPlayersToConnect;
-Var
- cnt, i: Integer;
-Begin
- log('TServer.HandleSwitchToWaitForPlayersToConnect', llTrace);
- fGameState := gsWaitForPlayersToConnect;
- fConnectedClientCount := 0;
- cnt := GetActivePlayerCount();
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].UID := NoPlayer;
- fPLayer[i].UserName := '';
- fPLayer[i].Kills := 0;
- fPLayer[i].Score := 0;
- End;
- If assigned(fChunkManager) And (cnt > 0) Then Begin
- SendChunk(miCommandoBackToMainMenu, Nil, 0);
- End;
- // TODO: Klären was noch alles zurück gesetzt werden muss ..
- fSettings.MasterUid := -1;
- fActualField := Nil;
- fSettings.LastWinsToWinMatch := 3; // Default der Clients
- LogLeave;
-End;
-
-Procedure TServer.HandleUpdateFieldSetup(Const Stream: TStream; Uid: integer);
-Var
- FieldName: String;
- FieldHash: UInt64;
- Wins, i: INteger;
- m: TMemoryStream;
-Begin
- log('TServer.HandleUpdateFieldSetup', llTrace);
- m := TMemoryStream.Create;
- m.CopyFrom(Stream, Stream.Size - Stream.Position);
- m.Position := 0;
- FieldName := m.ReadAnsiString;
- FieldHash := 0;
- Wins := 0;
- m.Read(FieldHash, SizeOf(FieldHash));
- m.Read(Wins, SizeOf(Wins));
-
- For i := 0 To high(fFields) Do Begin
- If (fFields[i].Name = FieldName)
- And (fFields[i].Hash = FieldHash) Then Begin
- fActualField := fFields[i];
- fSettings.LastWinsToWinMatch := Wins;
- // Weiterleiten an alle Clients,
- // !! Achtung, das ist doppelt implementiert (siehe TServer.HandleStartRound;);
- m.Position := 0;
- SendChunk(miUpdateFieldSetup, m, -uid);
- LogLeave;
- exit;
- End;
- End;
- (*
- * Fehler, alle fliegen raus !
- *)
- Log('Error, could not find field: ' + FieldName, llCritical);
- HandleSwitchToWaitForPlayersToConnect();
- LogLeave;
-End;
-
-Procedure TServer.HandleReceiveHeartBeat(p: integer; t: int64);
-Var
- i: Integer;
-Begin
- If fGameState <> gsPlaying Then exit;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID = p Then Begin
- fPLayer[i].LastSynchronTimeStamp := t;
- End;
- End;
-End;
-
-Procedure TServer.HandleClientKeyEvent(Const Stream: TStream);
-Var
- Player: integer;
- Double, State: Boolean;
- Key: TAtomicKey;
-Begin
- If fpausing Then exit;
- player := -1;
- State := false;
- Double := false;
- key := akFirstAction;
- stream.Read(Player, sizeof(Player));
- stream.Read(State, sizeof(State));
- stream.Read(key, sizeof(key));
- stream.Read(Double, sizeof(Double));
- fPLayer[Player].IdleTimer := 0; // Der Spieler hat eine Eingabe gemacht -> reset des Idle Timers ;)
- If State Then Begin
- If dInvertedKeyboard In fPLayer[Player].Disease Then Begin
- Case key Of
- akUp: key := akDown;
- akDown: key := akUp;
- akLeft: key := akRight;
- akRight: key := akLeft;
- End;
- End;
- Case Key Of
- akUp: fPLayer[Player].MoveState := msUp;
- akDown: fPLayer[Player].MoveState := msDown;
- akLeft: fPLayer[Player].MoveState := msLeft;
- akRight: fPLayer[Player].MoveState := msRight;
- akFirstAction: Begin
- If (Not (dNoBombs In fPLayer[Player].Disease)) Then Begin
- If Double Then Begin
- fPLayer[Player].Action := aaFirstDouble;
- End
- Else Begin
- fPLayer[Player].Action := aaFirst;
- End;
- End;
- End;
- akSecondAction: Begin
- If (Not (dNoBombs In fPLayer[Player].Disease)) Then Begin
- If Double Then Begin
- fPLayer[Player].Action := aaSecondDouble;
- End
- Else Begin
- fPLayer[Player].Action := aaSecond;
- End;
- End;
- End;
- End;
- End
- Else Begin
- // Nur die "Cursor" werden false gemacht -> immer Stillstand
- fPLayer[Player].MoveState := msStill;
- End;
-End;
-
-Procedure TServer.RefreshAllPlayerStats(Uid: integer);
-Var
- m: TMemoryStream;
- j, i: Integer;
- k: TKeySet;
-Begin
- log('TServer.RefreshAllPlayerStats', llTrace);
- m := TMemoryStream.Create;
- // Einfügen aller Spielerinformationen, dass diese übernommen werden können (z.B. nach Load Game)
- j := length(fPLayer);
- m.write(j, sizeof(j));
- For i := 0 To high(fPLayer) Do Begin
- j := fPLayer[i].UID;
- m.write(j, sizeof(j));
- k := fPLayer[i].Keyboard;
- m.write(k, sizeof(k));
- j := fPLayer[i].Kills;
- m.write(j, sizeof(j));
- j := fPLayer[i].Score;
- m.write(j, sizeof(j));
- m.WriteAnsiString(fPLayer[i].UserName);
- End;
- SendChunk(miRefreshPlayerStats, m, UID);
- LogLeave;
-End;
-
-Procedure TServer.PlayerLeaves(PlayerUid: integer);
-Var
- t0, t1, i, cnt, c: integer;
- m: TMemoryStream;
-Begin
- log('TServer.PlayerLeaves', llTrace);
- If PlayerUid = 0 Then Begin
- Log('Disconnect user with unknown uid', llCritical);
- LogLeave;
- exit;
- End;
- cnt := 0;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID = PlayerUid Then Begin
- log('Lost player : ' + fPLayer[i].UserName, llInfo);
- If fSettings.LostPlayersRevertToAI Then Begin
- fPLayer[i].UID := AIPlayer;
- End
- Else Begin
- fPLayer[i].UID := NoPlayer;
- End;
- fPLayer[i].UserName := '';
- If fPLayer[i].Info.Alive Then Begin // Sollte der Spieler noch am Leben sein -> stirbt er evtl jetzt
- fPLayer[i].Info.Alive := fPLayer[i].UID <> NoPlayer;
- End;
- If Not fPLayer[i].Info.Alive Then Begin
- fPLayer[i].Kills := 0;
- fPLayer[i].Score := 0;
- End;
- // TODO: Alles andere des Spielers auch noch löschen ?
- End;
- // Zählen der Noch aktiven Spieler
- If fPLayer[i].UID > 0 Then inc(cnt);
- End;
- For i := 0 To high(fUidInfos) Do Begin
- If fUidInfos[i].Uid = PlayerUid Then Begin
- For c := i To high(fUidInfos) - 1 Do Begin
- fUidInfos[c] := fUidInfos[c + 1];
- End;
- setlength(fUidInfos, high(fUidInfos));
- break;
- End;
- End;
- // Der "Master" Spieler geht
- If PlayerUid = fSettings.MasterUid Then Begin // TODO: Klären ob es Sinnvoll ist das bei allen Spielern zu machen und nicht nur beim Master ..
- // So lange wir im Spiel definierenden Teil sind
- // Bedeutet der Verlust des Master Spielers den Ausstieg ins
- // Hauptmenü
- If fGameState In [gsWaitForPlayersToConnect, gsPlayerSetup, gsMapSetup] Then Begin
- cnt := 0;
- End;
- // Der Master ist gegangen und wir sind mitten im Spielen, wir müssen einen neuen Bestimmen, sonst können die anderen das Match nicht zu ende Spielen..
- If cnt <> 0 Then Begin
- fSettings.MasterUid := -1;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID > NoPlayer Then Begin
- fSettings.MasterUid := fPLayer[i].UID;
- log('Lost primary player, selected ' + fPLayer[i].UserName + ' as new primary player.', llWarning);
- break;
- End;
- End;
- m := TMemoryStream.Create;
- i := fSettings.MasterUid;
- m.Write(i, SizeOf(i));
- SendChunk(miUpdateMasterID, m, -PlayerUid);
- End;
- End;
- // Wenn im TeamSpiel kann es sein, dass nur noch 1 Team übrig ist und alle Spieler des anderen Rausgeflogen sind ..
- If fSettings.TeamPlay Then Begin
- t0 := 0;
- t1 := 0;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID <> NoPlayer Then Begin
- If fPLayer[i].Team = 0 Then Begin
- inc(t0);
- End
- Else Begin
- inc(t1);
- End;
- End;
- End;
- // Das Spiel so Manipulieren, dass nach dem MatchStatistik Screen der ShowVictory Screen kommt
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].UID <> NoPlayer Then Begin
- If fPLayer[i].Team = 0 Then Begin
- If (t1 = 0) Then Begin
- fSettings.LastWinsToWinMatch := fPLayer[i].Score;
- End;
- End
- Else Begin
- If (t0 = 0) Then Begin
- fSettings.LastWinsToWinMatch := fPLayer[i].Score;
- End;
- End;
- End;
- End;
- End;
- If cnt > 0 Then Begin
- // Wenn es noch andere Spieler gibt Aktualisieren der Spielerliste (z.B. im Start Game Mode wichtig..)
- RefreshAllPlayerStats(0);
- ResetFieldAvailabe();
- For i := 0 To high(fUidInfos) Do Begin
- EvalFieldHashList(fUidInfos[i].Fields, i = high(fUidInfos)); // Nur beim Letzten auch Tatsächlich senden, das Spart Traffic
- End;
- End
- Else Begin
- // Der letzte Geht, zurück in den Edit Modus, macht nur im Timeout=0 Modus sinn, sonst beeden wir eh nach 1000ms
- HandleSwitchToWaitForPlayersToConnect;
- End;
- fConnectedClientCount := fConnectedClientCount - 1;
- If (cnt = 0) And (fAutotimeout <> 0) Then Begin
- log(format('Lost last client, will shut down in %0.3fs', [fAutotimeout / 1000]), llInfo);
- End;
- LogLeave;
-End;
-
-Function TServer.GetActivePlayerCount: Integer;
-Var
- i: Integer;
-Begin
- // !! Hier kein Logger, dass ist sonst zu viel
- result := 0;
- For i := 0 To high(fPLayer) Do Begin
- If (fPLayer[i].UID <> NoPlayer) And (fPLayer[i].UID > 0) Then inc(result);
- End;
-End;
-
-Procedure TServer.EvalFieldHashList(Const List: TFieldHashNameList;
- SendToMaster: Boolean);
-Var
- m: TMemorystream;
- i, j: Integer;
- found: Boolean;
-Begin
- (*
- * Gleicht List mit der Eigenen Fieldliste ab, und streicht aus der Fieldliste
- * alle die raus die nicht in List sind
- *
- * Danach wird diese "kleinste" Schnittmenge an den Master gesendet.
- *)
- log('TServer.EvalMapHashList', lltrace);
- m := TMemoryStream.Create;
- For i := 0 To high(fFields) Do Begin
- found := false;
- If fFields[i].Available Then Begin // karten die Früher schon ausgeschlossen wurden brauchen nicht mehr geprüft werden..
- For j := 0 To high(List) Do Begin
- If (fFields[i].Name = list[j].Name) And
- (fFields[i].Hash = list[j].Hash) Then Begin
- found := true;
- break;
- End;
- End;
- End;
- If found Then Begin
- m.WriteAnsiString(fFields[i].Name);
- m.write(fFields[i].hash, sizeof(fFields[i].hash));
- End
- Else Begin
- log(fFields[i].Name + ' will be disabled as it is not present on all game instances.', llWarning);
- fFields[i].Available := false;
- End;
- End;
- If SendToMaster Then Begin
- SendChunk(miAvailableFieldList, m, fSettings.MasterUid);
- End
- Else Begin
- m.free;
- End;
- LogLeave;
-End;
-
-Procedure TServer.CheckSynchrons;
-Var
- n: int64;
- i: integer;
- b: Boolean;
- s: String;
- m: TMemoryStream;
-Begin
- If fpausing Then exit;
- n := GetTickCount64;
- // versenden der HeartBeat Aufforderung an die Clients
- If n - fLastHeartbeatTimestamp >= HeartBeatTime Then Begin
- fLastHeartbeatTimestamp := n;
- m := TMemoryStream.Create;
- m.Write(n, SizeOf(n));
- SendChunk(miHeartBeat, m, 0);
- End;
- // Prüfen der Empfangenen HeartBeat Aufforderungen
- s := '';
- b := false;
- For i := 0 To high(fplayer) Do Begin
- (*
- * Nur die "Lebendigen" und nicht AI Spieler gehen in die Rechnung mit ein.
- *)
- If fplayer[i].Info.Alive And (fplayer[i].UID > 0) And (n - fplayer[i].LastSynchronTimeStamp > SynchonizeTimeOut) Then Begin
- s := fplayer[i].UserName;
- b := true;
- break;
- End;
- End;
- // Mindestens 1 Client ist asynchron, wir leiten eine Zwangspause ein / aus
- If b Then Begin
- If Not fSyncPause Then Begin // Positive Flanke der SyncPausierung
- log(format('Activate synchronising pause. %s is out of sync', [s]), llInfo);
- fSyncPause := true;
- ApplyPause(fpausing);
- End;
- End
- Else Begin
- If fSyncPause Then Begin // Negative Flanke der SyncPausierung
- log('Deactivate synchronising pause.', llInfo);
- fSyncPause := false;
- ApplyPause(fpausing);
- End;
- End;
-End;
-
-Procedure TServer.ApplyPause(Value: Boolean);
-Var
- t: int64;
- i: integer;
-Begin
- value := value Or fSyncPause;
- // fmap.Pause(Value);
- // fSpawnModul.Pause(Value);
- If Value Then Begin // Wir Starten die Pause
- If Not foldpausevalue Then Begin
- fPauseTimestamp := GetTickCount64;
- End;
- End
- Else Begin //Wir Beenden die Pause, nun müssen alle Zeitbasen passend Verschoben werden
- If foldpausevalue Then Begin
- t := GetTickCount64() - fPauseTimestamp; // T = Zeit in ms wie lange die Pause gedauert hat
- FLastFrameTimestamp := FLastFrameTimestamp + t;
- fLastClientUpdateTimestamp := fLastClientUpdateTimestamp + t;
- // fLastActiveTickTimestamp := fLastActiveTickTimestamp + t; -- Egal ob das gemacht wird oder nicht ..
- (*
- * Verschieben aller Zeitbasen für die Bandbreitenlimitierung
- *)
- fLastHeartbeatTimestamp := fLastHeartbeatTimestamp + t;
- For i := 0 To high(fPLayer) Do Begin
- fPLayer[i].LastSynchronTimeStamp := fPLayer[i].LastSynchronTimeStamp + t;
- End;
- // fFrameLog wird nicht gesetzt, läuft paralell weiter auch während einer Pause.
- End;
- End;
- foldpausevalue := value;
-End;
-
-Procedure TServer.CreateNewFrame;
-Var
- Alive: Array[0..1] Of Integer;
- i, j: Integer;
- aiInfo: TaiInfo;
- AiCommand: TAiCommand;
- OldCounter: UInt16;
-Begin
- HandleStatisticCallback(sFramesRendered);
- If fPlayingTimedesc <> -1000 Then Begin
- fPlayingTimedesc := fPlayingTimedesc - FrameRate;
- End;
- fPlayingTimeasc := fPlayingTimeasc + FrameRate;
- (*
- * im Teamplay die Teamfarben anwählen, und der Blocker, dass das nicht andauernd gemacht wird
- *)
- If fSettings.TeamPlay And
- (fPlayingTimeasc > AtomicTeamSwitchTime) And
- (fPlayingTimeasc < AtomicTeamSwitchTime + 2 * FrameRate) Then Begin
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Team = TeamIndexWhite Then Begin
- fPLayer[i].Info.ColorIndex := WhiteColorIndex;
- End
- Else Begin
- fPLayer[i].Info.ColorIndex := RedColorIndex;
- End;
- End;
- End;
- If assigned(AiHandlePlayer) Then Begin
- aiInfo := fActualField.GetAiInfo(fPLayer, fSettings.TeamPlay);
- End;
- // Die Spieler Bewegen
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
- fPLayer[i].IdleTimer := fPLayer[i].IdleTimer + FrameRate; // Wir zählen den immer hoch, der läuft erst nach 41 Tagen über...
- If fPLayer[i].UID = AIPlayer Then Begin
- If assigned(AiHandlePlayer) Then Begin
- Try
- AiCommand := AiHandlePlayer(i, aiInfo);
- Except
- On e: exception Do Begin
- log('Ai raised an exception: ' + e.Message, llCritical);
- End;
- End;
- Case AiCommand.MoveState Of
- amNone: fPLayer[i].MoveState := msStill;
- amLeft: fPLayer[i].MoveState := msLeft;
- amRight: fPLayer[i].MoveState := msRight;
- amUp: fPLayer[i].MoveState := msUp;
- amDown: fPLayer[i].MoveState := msDown;
- End;
- Case AiCommand.Action Of
- apNone: fPLayer[i].Action := aaNone;
- apFirst: fPLayer[i].Action := aaFirst;
- apFirstDouble: fPLayer[i].Action := aaFirstDouble;
- apSecond: fPLayer[i].Action := aaSecond;
- apSecondDouble: fPLayer[i].Action := aaSecondDouble;
- End;
- End;
- End;
- If fActualField.HandleMovePlayer(fPLayer, i, fSettings.ConveyorSpeed) Then Begin
- // im Hurry mode kann der Spieler sterben, wenn ein Solid Brick an seiner Koordinate "entsteht"
- fActualField.KillPlayer(fPLayer, i);
- End;
-
- (*
- * Das "Krank" sein ;)
- *)
- If fPLayer[i].Disease <> [] Then Begin
- (*
- * Das Anstecken
- *)
- For j := 0 To high(fPLayer) Do Begin
- If (i <> j) And
- (LenV2SQR(fPLayer[i].Info.Position - fPLayer[j].Info.Position) <= 0.5 * 0.5) And
- (fPLayer[i].Disease <> fPLayer[j].Disease) Then Begin
- fPLayer[j].Disease := fPLayer[i].Disease;
- fPLayer[j].DiseaseCounter := AtomicDiseaseTime;
- End;
- End;
- (*
- * Das Heilen
- *)
- fPLayer[i].DiseaseCounter := max(0, fPLayer[i].DiseaseCounter - FrameRate);
- If fPLayer[i].DiseaseCounter = 0 Then Begin
- If dSuperSlow In fPLayer[i].Disease Then Begin
- fPLayer[i].Powers.Speed := fPLayer[i].BeforeSlowDiseaseSpeed;
- End;
- fPLayer[i].Disease := [];
- End;
- End;
- End;
- End;
- // Aktions durchführen
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
- If dEbola In fPLayer[i].Disease Then fPLayer[i].Action := aaFirst; // Wenn der Spieler "Ebola" hat, legt er wann immer möglich eine Bombe
- // TODO: Feature oder Bug, wenn der Spieler Ebola hat und dNoBombs wird er hier verschont ...
- If (fPLayer[i].Action <> aaNone) And (Not (dNoBombs In fPLayer[i].Disease)) Then Begin
- fActualField.HandleActionPlayer(fPLayer[i], i);
- fPLayer[i].Action := aaNone;
- End;
- End;
- End;
- // Bomben Handeln
- // TODO: Magic Numbers -> entfernen klären ...
- fActualField.HandleBombs(fPLayer, (fPlayingTimedesc <= 80000) And (fPlayingTimedesc <> -1000), fSettings.ConveyorSpeed);
- // Kollision mit Flammen
- fActualField.HandlePlayerVsMap(fPLayer, @HandlePlayerGetsPowerUp);
-
- fActualField.HandleFieldAnims;
-
- (* Das Sterben der Spieler Einleiten *)
- Alive[0] := 0;
- Alive[1] := 0;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Info.Alive Then Begin // Hier darf Dieing nicht stehen, da es ja genau darum geht unten die Todeszeit ab zu prüfen !
- (*
- * Den Zähler lassen wir mal immer Zählen und damit nichts schief geht alle 1 min überlaufen, sollte er grad nicht gebraucht werden ...
- * Jede Animation die den Counter Braucht setzt ihn beim Start auf 0 zurück, damit ist dann alles Save ;)
- *)
- OldCounter := fPLayer[i].Info.Counter;
- fPLayer[i].Info.Counter := (fPLayer[i].Info.Counter + FrameRate) Mod 60000;
- // Der Teleporter versetzt den Spieler genau 1 mal und zwar bei der Hälfte der Animationszeit
- If (fPLayer[i].Info.Animation = raTeleport) And
- (OldCounter < AtomicAnimationTimeTeleport Div 2) And
- (fPLayer[i].Info.Counter >= AtomicAnimationTimeTeleport Div 2) Then Begin
- fActualField.TelePortPlayer(fPLayer[i]);
- End;
- If fPLayer[i].Info.Dying Then Begin
- If fPLayer[i].Info.Counter > AtomicDietimeout Then Begin
- fPLayer[i].Info.Alive := false; // Wir sind gestorben und die Animation ist nun auch durch..
- fPLayer[i].Info.Dying := false;
- fActualField.RepopulatePlayersCollectedPowerUps(fPLayer, i);
- End;
- End
- Else Begin
- inc(alive[fPLayer[i].Team]);
- End;
- End
- Else Begin
- fPLayer[i].Info.Dying := false;
- End;
- End;
- If fSettings.TeamPlay Then Begin
- If (Alive[0] < 1) Or (Alive[1] < 1) Then Begin // Abschalten sobald das andere Team Platt gemacht wurde !
- fActualField.DisableAllBombs;
- End;
- End
- Else Begin
- If Alive[0] + Alive[1] <= 1 Then Begin // Abschalten Aller Bomben sobald nur noch einer am Leben ist bzw noch nicht am Sterben ;)
- fActualField.DisableAllBombs;
- End;
- End;
- HurryHandling;
- EndGameCheck();
-End;
-
-Procedure TServer.UpdateAllClients;
-Var
- m: TMemoryStream;
- i: Integer;
- DiseasedInfo: TAtomicInfo;
-Begin
- // Gesendet werden immer 3 Datensätze
- m := TMemoryStream.Create;
- // Die Rundenzeit mit übertragen
- i := fPlayingTimedesc Div 1000;
- m.write(i, sizeof(i));
- // 1. Alles was die Spieler angeht
- For i := 0 To high(fplayer) Do Begin
- (*
- * Der Spieler langweilt sich und wird nicht zufällig gerade gegrillt
- *)
- If (fPLayer[i].IdleTimer > AtomicIdleTimeout) And (fPLayer[i].Info.Animation <> raDie) And (fPLayer[i].Info.Animation <> raLockedIn) Then Begin
- fPLayer[i].IdleTimer := 0;
- fPLayer[i].Info.Animation := raZen;
- fPLayer[i].Info.Counter := 0;
- fPLayer[i].Info.Value := random(65536); // Eine Zufällige Zen Animation auswählen ;)
- If fPLayer[i].UID > 0 Then HandlePlaySoundEffect(i, seZen); // Nur "echte" spieler kriegen den Ton
- End;
- (*
- * Wenn der Spieler eine Krankheit hat, dann wechselt seine Farbe alle AtomicDiseaseColorChangeTime
- *)
- If (fPLayer[i].Disease <> []) And ((fPLayer[i].DiseaseCounter Mod AtomicDiseaseColorChangePeriodTime) < AtomicDiseaseColorChangePeriodTime - AtomicDiseaseColorChangePeriodRelaxTime) Then Begin
- DiseasedInfo := fPLayer[i].Info;
- DiseasedInfo.ColorIndex := (fPLayer[i].DiseaseCounter Div AtomicDiseaseColorChangeTime) Mod length(PlayerColors);
- m.Write(DiseasedInfo, sizeof(DiseasedInfo));
- End
- Else Begin
- m.Write(fPLayer[i].Info, sizeof(fPLayer[i].Info));
- End;
- // Der Client Wertet die Flanke der animation aus und hällt diese Selbst so lange wie er sie braucht
- // d.h. Die Animation wird hier direkt wieder Platt gemacht.
- If fPLayer[i].Info.Animation In OneTimeAnimations Then Begin
- fPLayer[i].Info.Animation := raStandStill;
- End;
- End;
- // 2. Alles was das zu Rendernde Feld angeht
- fActualField.AppendGamingData(m);
- SendChunk(miUpdateGameData, m, 0);
-End;
-
-Procedure TServer.SendPlayerStatistiks;
-Var
- m: TMemoryStream;
- i: Integer;
-Begin
- log('TServer.SendPlayerStatistiks', lltrace);
- m := TMemoryStream.Create;
- For i := 0 To high(fPLayer) Do Begin
- m.Write(fPLayer[i].Score, sizeof(fPLayer[i].Score));
- m.Write(fPLayer[i].Kills, sizeof(fPLayer[i].Kills));
- End;
- SendChunk(miUpdatePlayerStatistik, m, 0);
- LogLeave;
-End;
-
-Procedure TServer.EndGameCheck;
-Var
- (*
- Merken wem wir alles schon einen "Winner" gesendet haben
- -> Das Verhindert, dass wenn 2 Spieler am Selben Rechner sitzen
- diese den "GewinnerSound" doppelt hören.
- *)
- SoundSends: Array Of Integer;
- Procedure SendWinner(uid, playerindex: integer);
- Var
- i: Integer;
- Begin
- For i := 0 To high(SoundSends) Do Begin
- If SoundSends[i] = uid Then exit;
- End;
- setlength(SoundSends, high(SoundSends) + 2);
- SoundSends[high(SoundSends)] := uid;
- HandlePlaySoundEffect(playerindex, seWinner);
- End;
-
-Var
- WinnerTeamIndex, teamwhite, teamred, cnt, cntindex, i: Integer;
- m: TMemoryStream;
- v: TVictor;
-Begin
- (*
- * Bedingungen zum "Ende"
- *)
- // 1. Nur noch <=1 Spieler am Leben, oder im Team Modus nur noch 1 Team am Leben
- teamwhite := 0;
- teamred := 0;
- cnt := 0;
- cntindex := -1;
- SoundSends := Nil;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Info.Alive Then Begin
- inc(cnt);
- cntindex := i;
- If fPLayer[i].Team = TeamIndexWhite Then Begin
- inc(teamwhite);
- End
- Else Begin
- inc(teamred);
- End;
- End;
- End;
- If fSettings.TeamPlay Then Begin
- // Nur noch 1 Team am Leben
- If (teamwhite = 0) Or (teamred = 0) Then Begin
- // Draw Game Check
- // => Es kann passieren, dass das andere Team gerade am "Sterben" ist aber eben auch tot
- // Aus diesem Grund muss hier noch mal extra geprüft werden ob die Gewinner Mannschaft
- // auch wirklich am Leben ist..
- WinnerTeamIndex := IfThen((teamred = 0), TeamIndexWhite, TeamIndexRed);
- cnt := 0;
- For i := 0 To high(fPLayer) Do Begin
- If (fPLayer[i].Team = WinnerTeamIndex) And fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
- inc(cnt);
- End;
- End;
- If cnt <> 0 Then Begin // Wir haben wirklich einen Gewinner ;)
- // Die Scores erhöhen
- If teamred = 0 Then Begin // Team weis hat gewonnen
- v := vWhiteTeam;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Team = 0 Then Begin
- SendWinner(fPLayer[i].UID, i);
- inc(fPLayer[i].Score);
- End;
- End;
- End
- Else Begin // Team 2 hat gewonnen
- v := vRedTeam;
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Team = 1 Then Begin
- SendWinner(fPLayer[i].UID, i);
- inc(fPLayer[i].Score);
- End;
- End;
- End;
- SendPlayerStatistiks(); // Damit alle Clients auch die Richtigen Scores anzeigen diese nun Aktualisieren
- m := TMemoryStream.Create;
- m.Write(v, SizeOf(v));
- SendChunk(miShowMatchStatistik, m, 0);
- fGameState := gsShowHighscore;
- End
- Else Begin
- // Draw Game, aber es laufen noch Todesanimationen,
- // -> Damit der Code unten nicht direkt das DrawGame triggert mus cnt
- // manipuliert werden ;)
- For i := 0 To high(fPLayer) Do Begin
- If (fPLayer[i].Team = WinnerTeamIndex) And (fPLayer[i].Info.Dying) Then Begin
- cnt := 1; // Egal hauptsache <> 0
- End;
- End;
- End;
- End;
- End
- Else Begin
- // Nur noch 1 Überlebender Spieler
- If cnt = 1 Then Begin
- // Dem Sieger den Punkt geben, aber nur, wenn er nicht auch gerade am sterben ist ..
- // Wenn der Spieler Gestorben ist geht dann cnt von alleine Später auf 0 ;)
- If Not fPLayer[cntindex].Info.Dying Then Begin
- SendWinner(fPLayer[cntindex].UID, cntindex);
- fPLayer[cntindex].Score := fPLayer[cntindex].Score + 1;
- SendPlayerStatistiks(); // Damit alle Clients auch die Richtigen Scores anzeigen diese nun Aktualisieren
- v := TVictor(integer(vCol0) + cntindex);
- m := TMemoryStream.Create;
- m.Write(v, SizeOf(v));
- SendChunk(miShowMatchStatistik, m, 0);
- fGameState := gsShowHighscore;
- End;
- End;
- End;
- // 2. Zeit abgelaufen (wenn Zeitlimit Aktiv)
- If ((fPlayingTimedesc <> -1000) And (fPlayingTimedesc <= 0)) Or (cnt = 0) Then Begin
- (*
- * Nachdem auf Jedenfall oben niemand gewonnen hat ist nun schluss mittels draw
- *)
- SendChunk(miDrawGame, Nil, 0);
- fGameState := gsShowHighscore;
- End;
-End;
-
-Function TServer.MatchFinished: Boolean;
-Var
- i: Integer;
-Begin
- result := false;
- (*
- * Hat wenigstens 1 Spieler die Notwendige Anzahl an Runden gewonnen ?
- * Hier ist es tatsächlich egal ob Teamplay oder nicht, da beim Teamplay
- * ja jeder im Team einen Score bekommt ;)
- *)
- For i := 0 To high(fPLayer) Do Begin
- If fPLayer[i].Score >= fSettings.LastWinsToWinMatch Then Begin
- result := true;
- break;
- End;
- End;
-End;
-
-Procedure TServer.LoadAi;
-Begin
- log('TServer.LoadAi', lltrace);
- If Not LoadAiLib() Then Begin
- logshow('Could not load ai, ai functions are not available.', llError);
- LogLeave;
- exit;
- End;
- If AiInit() Then Begin
- log(format('Ai "%s" loaded..', [AiVersion()]), llInfo);
- End
- Else Begin
- log('Failure on Ai load.', llInfo);
- UnLoadAiLib;
- End;
- If fGameState = gsPlaying Then Begin
- // TODO: Diese 100% müssen noch einstellbar gemacht werden !
- AiNewRound(100);
- End;
- LogLeave;
-End;
-
-Procedure TServer.HurryHandling;
-Begin
- If fPlayingTimedesc = -1000 Then exit; // Nicht im Infinity Mode
- If Not fActualField.BombsEnabled Then exit; // Es gibt wohl keine Spieler mehr auf der Karte -> kein Hurry mehr ;)
- If fPlayingTimedesc = 85000 Then Begin
- SendChunk(miShowHurry, Nil, 0);
- End;
- If fPlayingTimedesc <= 80000 Then Begin
- If fPlayingTimedesc Mod 500 = 0 Then Begin
- fActualField.IncHurry();
- HandlePlaySoundEffect(0, seHurryBrick);
- End;
- End;
-End;
-
-Procedure TServer.Execute;
-Var
- n: QWord;
-Begin
- log('TServer.Execute', lltrace);
- // Loop in einer Endlosschleife, so lange bis 1000ms lang kein Client mehr connected ist, dann raus
- While factive Do Begin
- fChunkManager.CallAction(); // Alle Aktuellen Aufgaben des TCP-Stacks Abbarbeiten
- fUDP.CallAction();
- If fKickAllPlayer Then Begin
- log('KickAllPlayer', lltrace);
- fKickAllPlayer := false;
- HandleSwitchToWaitForPlayersToConnect();
- LogLeave;
- End;
- If fGameState = gsPlaying Then Begin // Im Spielmodus Frames und Updates der Clients Berechnen
- // alle 10 s Loggen wie Groß die Spieldaten waren, welche gesandt
- n := GetTickCount64();
- If fFrameLog.TimeStamp + 10000 <= n Then Begin
- fFrameLog.TimeStamp := n;
- If fFrameLog.Count <> 0 Then Begin
- log(Format('Send %d frames with avg size of %.1f Bytes.', [fFrameLog.Count, fFrameLog.AccumulatedSize / fFrameLog.Count]), lldebug);
- End
- Else Begin
- log('Send 0 frames.', lldebug);
- End;
- fFrameLog.Count := 0;
- fFrameLog.AccumulatedSize := 0;
- End;
- CheckSynchrons; //Sind alle Player noch Synchron, wenn nein Warten
- // If fpausing Then Begin // Zählen der Pausenzeit
- // n := GetTickCount64;
- // If n <> pt Then Begin
- // fOverAllPausingTime := fOverAllPausingTime + n - pt;
- // pt := n;
- // End;
- // End
- // Else Begin
- // pt := GetTickCount64;
- // End;
- If (Not (fpausing Or fSyncPause)) Then Begin
- n := GetTickCount64();
- If FLastFrameTimestamp + FrameRate <= n Then Begin
- // Durch das Aufaddieren der Zeit und nicht direkt setzen auf n könnte hier eine
- // Überpropertionale rechenlast erzeugt werden, besonders, wenn CreateNewFrame, länger dauert als (FrameRate Div Speedup)
-{$IFDEF Release}
- FLastFrameTimestamp := FLastFrameTimestamp + FrameRate;
-{$ELSE}
- // Sonst scrollt die Zeit ewig weiter, wenn man mim Debugger die Zeit anhällt
- FLastFrameTimestamp := n;
-{$ENDIF}
- CreateNewFrame;
- End;
- // Egal, welcher Speedup, das Spiel wird mit konstanter Rate Aktualisiert
- If fLastClientUpdateTimestamp + UpdateRate <= n Then Begin
- fLastClientUpdateTimestamp := n; // fLastClientUpdateTimestamp + UpdateRate; Verhindern von oben beschriebener Situation
- UpdateAllClients;
- End;
- End;
- End;
- (*
- * Ab hier geht es nur noch darum zu erkennen ob die Anwendung beendet werden
- * soll.
- *)
- If KeyPressed Then Begin
- Case ReadKey() Of
- #27: Begin
- Log('Close by user input.', llInfo);
- factive := false;
- End;
- 'a', 'A': Begin
- LoadAi;
- End;
- 'u', 'U': Begin
- UnLoadAiLib;
- LogShow('Disabled ai', llInfo);
- End;
- End;
- End;
- // Beenden Bedingung erkennen
- If GetActivePlayerCount() <> 0 Then Begin
- fLastActiveTickTimestamp := GetTickCount64();
- End
- Else Begin
- // fAutotimeout ms lang keine Activen Clients, dieser Server kann geschlossen werden
- If (fAutotimeout <> 0) Then Begin
- If (fLastActiveTickTimestamp + fAutotimeout < GetTickCount64()) Then Begin
- factive := false;
- End;
- End;
- {
- // Zwangsabbruch, weil der Server sich selbst geschlossen hat
- If Not fChunkManager.Connected Then Begin
- log('Chunkmanager lost connection.', llfatal);
- factive := false;
- End;
- }
- End;
- If fGameState = gsPlaying Then Begin
-{$IFDEF Windows}
- sleep(0);
-{$ELSE}
- sleep(1);
-{$ENDIF}
- End
- Else Begin
- sleep(1);
- End;
- End;
- LogLeave;
-End;
-
-Procedure TServer.LoadStatistiks;
-Var
- ini: TIniFile;
- p: String;
-Begin
- p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
- ini := TIniFile.Create(p + 'stats.txt');
- fStatistik.Total[sMatchesStarted] := ini.ReadInt64('Total', 'MatchesStarted', 0);
- fStatistik.Total[sGamesStarted] := ini.ReadInt64('Total', 'GamesStarted', 0);
- fStatistik.Total[sFramesRendered] := ini.ReadInt64('Total', 'FramesRendered', 0);
- fStatistik.Total[sBombsDropped] := ini.ReadInt64('Total', 'BombsDropped', 0);
- fStatistik.Total[sPowerupsCollected] := ini.ReadInt64('Total', 'PowerupsCollected', 0);
- fStatistik.Total[sPlayerDeaths] := ini.ReadInt64('Total', 'PlayerDeaths', 0);
- fStatistik.Total[sBricksDestroyed] := ini.ReadInt64('Total', 'BricksDestroyed', 0);
- fStatistik.Total[sPowerUpDestroyed] := ini.ReadInt64('Total', 'PowerUpDestroyed', 0);
- fStatistik.Total[sTotalNetworkBytesIn] := ini.ReadInt64('Total', 'TotalNetworkBytesIn', 0);
- fStatistik.Total[sTotalNetworkBytesOut] := ini.ReadInt64('Total', 'TotalNetworkBytesOut', 0);
- fStatistik.Total[sTotalNetworkPacketsIn] := ini.ReadInt64('Total', 'TotalNetworkPacketsIn', 0);
- fStatistik.Total[sTotalNetworkPacketsOut] := ini.ReadInt64('Total', 'TotalNetworkPacketsOut', 0);
-
- (*
- * Alles Aktuelle = 0 ;)
- *)
- FillChar(fStatistik.LastRun, sizeof(fStatistik.LastRun), 0);
- ini.free;
-End;
-
-Procedure TServer.SaveStatistiks;
-Var
- ini: TIniFile;
- p: String;
-Begin
- p := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
- ini := TIniFile.Create(p + 'stats.txt');
- Try
- ini.writeInt64('Total', 'MatchesStarted', fStatistik.Total[sMatchesStarted] + fStatistik.LastRun[sMatchesStarted]);
- ini.writeInt64('Total', 'GamesStarted', fStatistik.Total[sGamesStarted] + fStatistik.LastRun[sGamesStarted]);
- ini.writeInt64('Total', 'FramesRendered', fStatistik.Total[sFramesRendered] + fStatistik.LastRun[sFramesRendered]);
- ini.writeInt64('Total', 'BombsDropped', fStatistik.Total[sBombsDropped] + fStatistik.LastRun[sBombsDropped]);
- ini.writeInt64('Total', 'PowerupsCollected', fStatistik.Total[sPowerupsCollected] + fStatistik.LastRun[sPowerupsCollected]);
- ini.writeInt64('Total', 'PlayerDeaths', fStatistik.Total[sPlayerDeaths] + fStatistik.LastRun[sPlayerDeaths]);
- ini.writeInt64('Total', 'BricksDestroyed', fStatistik.Total[sBricksDestroyed] + fStatistik.LastRun[sBricksDestroyed]);
- ini.writeInt64('Total', 'PowerUpDestroyed', fStatistik.Total[sPowerUpDestroyed] + fStatistik.LastRun[sPowerUpDestroyed]);
- ini.writeInt64('Total', 'TotalNetworkBytesIn', fStatistik.Total[sTotalNetworkBytesIn] + fStatistik.LastRun[sTotalNetworkBytesIn]);
- ini.writeInt64('Total', 'TotalNetworkBytesOut', fStatistik.Total[sTotalNetworkBytesOut] + fStatistik.LastRun[sTotalNetworkBytesOut]);
- ini.writeInt64('Total', 'TotalNetworkPacketsIn', fStatistik.Total[sTotalNetworkPacketsIn] + fStatistik.LastRun[sTotalNetworkPacketsIn]);
- ini.writeInt64('Total', 'TotalNetworkPacketsOut', fStatistik.Total[sTotalNetworkPacketsOut] + fStatistik.LastRun[sTotalNetworkPacketsOut]);
-
- ini.writeInt64('LastRun', 'MatchesStarted', fStatistik.LastRun[sMatchesStarted]);
- ini.writeInt64('LastRun', 'GamesStarted', fStatistik.LastRun[sGamesStarted]);
- ini.writeInt64('LastRun', 'FramesRendered', fStatistik.LastRun[sFramesRendered]);
- ini.writeInt64('LastRun', 'BombsDropped', fStatistik.LastRun[sBombsDropped]);
- ini.writeInt64('LastRun', 'PowerupsCollected', fStatistik.LastRun[sPowerupsCollected]);
- ini.writeInt64('LastRun', 'PlayerDeaths', fStatistik.LastRun[sPlayerDeaths]);
- ini.writeInt64('LastRun', 'BricksDestroyed', fStatistik.LastRun[sBricksDestroyed]);
- ini.writeInt64('LastRun', 'PowerUpDestroyed', fStatistik.LastRun[sPowerUpDestroyed]);
- ini.writeInt64('LastRun', 'TotalNetworkBytesIn', fStatistik.LastRun[sTotalNetworkBytesIn]);
- ini.writeInt64('LastRun', 'TotalNetworkBytesOut', fStatistik.LastRun[sTotalNetworkBytesOut]);
- ini.writeInt64('LastRun', 'TotalNetworkPacketsIn', fStatistik.LastRun[sTotalNetworkPacketsIn]);
- ini.writeInt64('LastRun', 'TotalNetworkPacketsOut', fStatistik.LastRun[sTotalNetworkPacketsOut]);
- Finally
- ini.free;
- End;
-End;
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uatomic_server;
+
+{$MODE ObjFPC}{$H+}
+
+{$I ../client/globaldefines.inc}
+
+Interface
+
+Uses
+ Classes, SysUtils, Lnet, crt,
+ uChunkmanager, uatomic_common, uatomic_messages, uatomic_field, uai_types;
+
+Type
+
+ TGameStatistik = Record
+ Total: Array[TStatSelector] Of UInt64;
+ LastRun: Array[TStatSelector] Of UInt64;
+ End;
+
+ TGameState = (
+ gsWaitForPlayersToConnect // Wir warten auf Spieler die Mit Spielen wollen
+ , gsPlayerSetup // Die Spieler wollen ihre Farben Editieren
+ , gsMapSetup // Die Spieler wollen die Eigenschaften der Karte Editieren
+ , gsPlaying // Die Spieler Spielen auf der Karte
+ , gsShowHighscore // Anzeige der Highscores
+ );
+
+ TUidInfos = Record
+ Uid: Integer;
+ Fields: TFieldHashNameList;
+ End;
+
+ tFrameLog = Record
+ TimeStamp: QWord;
+ AccumulatedSize: uint64;
+ Count: integer;
+ End;
+
+ { TServer }
+
+ TServer = Class
+ private
+ fKickAllPlayer: boolean; // If True, the server kicks every player during the next "Idle"
+ fFrameLog: tFrameLog;
+ fStatistik: TGameStatistik;
+ fRandomMap: Boolean;
+ fLastHeartbeatTimestamp: int64; // Der Zeitpunkt an welchen der Letzte Heartbeat versendet wird
+ fPlayingTimeasc: int64; // Zeit in ms die die runde schon läuft
+ fPlayingTimedesc: int64; // Zeit in ms die die Runde noch läuft
+
+ fpausing: Boolean;
+ fSyncPause: Boolean;
+ foldpausevalue: Boolean;
+ fPauseTimestamp: int64; // Der Zeitpunkt, an dem eine Pause gestartet wurde
+ FLastFrameTimestamp: int64; // Zeitpunkt an dem das Letzte "Frame" Berechnet wurde
+ fLastClientUpdateTimestamp: int64; // Zeitpunkt an dem zuletzt alle Clients Aktualisiert wurden
+
+ fSettings: TAtomicSettings;
+ fFields: Array Of TAtomicField;
+ fConnectedClientCount: integer; // Anzahl der Tatsächlich verbundenen Clients, wird bestimmt bei HandleSwitchToPlayerSetup und ist immer <= GetActivePlayerCount()
+ fActualField: TAtomicField; // Das Feld, welches für dieses Match Aktiv ist, Wird mittels miUpdateFieldSetup gesetzt
+
+ fUDP: TLUdp; // Zum Empfangen und Senden der Aktiven Server Verbindungen
+ fTCP: TLTcp; // Die L-Net TCP Komponente
+ fChunkManager: TChunkManager; // Der Chunkmanager zum senden der Daten
+ fTCPPort: integer; // Der Port auf welchem wir den Chunkmanager gestaret haben (für die UDP-Broadcaster)
+ factive: Boolean; // True, so lange clients verbunden sind
+ fLastActiveTickTimestamp: Int64; // Zum Bestimmen ob der Server sich automatisch beenden soll, wenn Keine Spieler mehr aktiv sind.
+
+ fGameState: TGameState;
+ fAutotimeout: integer;
+ fPLayer: TPlayers;
+ fUidInfos: Array Of TUidInfos; // Informationen die am Spieler hängen aber nicht an den Positionen ..
+
+ Procedure OnAccept(aSocket: TLSocket);
+ Procedure OnDisconnect(aSocket: TLSocket);
+ Procedure OnError(Const msg: String; aSocket: TLSocket);
+
+ Procedure OnUDPReceiveEvent(aSocket: TLSocket);
+ Procedure OnUDPError(Const msg: String; aSocket: TLSocket);
+ Procedure OnUDPDisconnect(aSocket: TLSocket);
+
+ Procedure OnReceivedChunk(Sender: TObject; Const Chunk: TChunk);
+ Procedure ResetFieldAvailabe();
+ Function SendChunk(UserDefinedID: Integer; Data: TStream; UID: integer): Boolean;
+ Procedure SendSplashMessage(msg: String; TargetUID: integer);
+ Procedure SendSettings();
+
+ Procedure HandleRequestUserLogin(Const Stream: TStream; UID: integer);
+ Procedure HandleSwitchToPlayerSetup;
+ Procedure HandleSwitchToMapProperties(UID: Integer);
+ Procedure HandleStartGame();
+ Procedure HandleStartRound();
+ Procedure HandleTogglePause();
+ Procedure HandleShowVictory();
+ Procedure HandlePlayerGetsPowerUp(Var Player: TPlayer; PlayerIndex: integer;
+ PowerUp: TPowerUps);
+ Procedure HandlePlaySoundEffect(PlayerIndex: integer; Effect: TSoundEffect);
+ Procedure HandleStatisticCallback(StatSelector: TStatSelector; Value: uint64 = 1);
+
+ Procedure HandleLoadSettings(Const Stream: TStream);
+ Procedure HandleChangePlayerKey(PlayerIndex, Direction: Integer; PlayerName: String; UID: Integer);
+ Procedure HandleSwitchToWaitForPlayersToConnect;
+ Procedure HandleUpdateFieldSetup(Const Stream: TStream; Uid: integer);
+ Procedure HandleReceiveHeartBeat(p: integer; t: int64);
+ Procedure HandleClientKeyEvent(Const Stream: TStream);
+
+ Procedure RefreshAllPlayerStats(Uid: integer);
+ Procedure PlayerLeaves(PlayerUid: integer);
+ Function GetActivePlayerCount(): Integer; // Ermittelt alle Spieler, derren UID <> NoPlayer ist !
+ Procedure EvalFieldHashList(Const List: TFieldHashNameList; SendToMaster: Boolean);
+
+ Procedure CheckSynchrons;
+ Procedure ApplyPause(Value: Boolean);
+ Procedure CreateNewFrame; // Quasi das Virtuelle render
+ Procedure UpdateAllClients; // Aktualisierung aller Clients
+ Procedure SendPlayerStatistiks; // Am Ende einer Runde müssen alle Spieler über die Aktuelle Statistik informiert werden
+ Procedure EndGameCheck;
+ Function MatchFinished(): Boolean;
+
+ Procedure LoadAi();
+ Procedure HurryHandling;
+ Function GetStatsFilePath: String; // Returns correct path for stats.txt (Application Support on macOS)
+ public
+ Constructor Create(Port, AutoTimeOut: Integer);
+ Destructor Destroy(); override;
+ Procedure Execute;
+ Procedure LoadStatistiks();
+ Procedure SaveStatistiks();
+ End;
+
+Implementation
+
+Uses FileUtil, LazUTF8, LazFileUtils, uvectormath, math, IniFiles, uai, uip;
+
+{ Helper function to resolve data directory path }
+
+Function ResolveResourceBase(BasePath: String): String;
+Var
+ testPath: String;
+ appBundlePath: String;
+Begin
+ // Normalize base path to absolute path
+ BasePath := ExpandFileName(IncludeTrailingPathDelimiter(BasePath));
+
+ // Try multiple locations for data directory
+ // 1. Direct relative to executable (works with symlinks)
+ testPath := BasePath + 'data';
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 2. Relative path from MacOS directory in .app bundle
+ testPath := ExpandFileName(BasePath + '../Resources/data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 3. Try symlink path (../../data from MacOS) - for shared data directory
+ testPath := ExpandFileName(BasePath + '../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 4. Try symlink path (../../../data from MacOS) - alternative symlink location
+ testPath := ExpandFileName(BasePath + '../../../data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ // 5. Try path next to .app bundle (for cases where data is outside the bundle)
+ // If BasePath contains ".app/Contents/MacOS/", try going up to the .app bundle's parent directory
+ If Pos('.app/Contents/MacOS/', BasePath) > 0 Then Begin
+ appBundlePath := Copy(BasePath, 1, Pos('.app/Contents/MacOS/', BasePath) + 4); // Get path up to ".app"
+ appBundlePath := ExtractFilePath(ExcludeTrailingPathDelimiter(appBundlePath)); // Get parent directory of .app
+ testPath := ExpandFileName(appBundlePath + 'data');
+ If DirectoryExistsUTF8(testPath) Then Begin
+ Result := IncludeTrailingPathDelimiter(testPath);
+ exit;
+ End;
+ End;
+ // Fallback: use base path (may not exist, but at least we tried)
+ Result := BasePath + 'data' + PathDelim;
+End;
+
+{ TServer }
+
+Constructor TServer.Create(Port, AutoTimeOut: Integer);
+Var
+ sl: TStringList;
+ i: Integer;
+ adapters: TNetworkAdapterList;
+ serverIP: String;
+ j: Integer;
+Begin
+ log('TServer.create', lltrace);
+ Inherited create;
+ fChunkManager := Nil;
+ factive := false;
+ fFields := Nil;
+ HandleSwitchToWaitForPlayersToConnect;
+ fAutotimeout := AutoTimeOut;
+ fTCP := TLTcp.Create(Nil);
+ fTCP.ReuseAddress := true; // Bei Absturz kann so sofort wieder neu verbunden werden
+ fTCP.OnAccept := @OnAccept;
+ fTCP.OnError := @OnError;
+ fTCP.OnDisconnect := @OnDisconnect;
+ fUDP := TLUdp.Create(Nil);
+ fUDP.OnReceive := @OnUDPReceiveEvent;
+ fUDP.OnError := @OnUDPError;
+ fUDP.OnDisconnect := @OnUDPDisconnect;
+
+ fChunkManager := TChunkManager.create;
+ fChunkManager.RegisterConnection(fTCP);
+ fChunkManager.OnReceivedChunk := @OnReceivedChunk;
+ // Start network thread for non-blocking network processing
+ fChunkManager.StartNetworkThread();
+ log('Network thread started for server', llInfo);
+
+ fLastActiveTickTimestamp := GetTickCount64;
+ fTCPPort := Port;
+
+ // Laden aller Felder
+ // Resolve data directory path - check multiple locations for .app bundle compatibility
+ sl := FindAllDirectories(ResolveResourceBase(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))) + 'maps', false);
+ sl.Sorted := true;
+ sl.Sort; // Ist beim Client wichtig, beim Server wäre es theoretisch egal, so ists aber leichter zum debuggen
+ setlength(fFields, sl.Count);
+ For i := 0 To sl.Count - 1 Do Begin
+ fFields[i] := TAtomicField.Create(@HandlePlaySoundEffect, @HandleStatisticCallback);
+ If Not fFields[i].loadFromDirectory(sl[i]) Then Begin
+ Raise exception.create('Error, unable to load field:' + sl[i]);
+ End;
+ End;
+ sl.free;
+ setlength(fFields, high(fFields) + 2);
+ fFields[high(fFields)] := TAtomicRandomField.Create(Nil, Nil); // Die initialisiert sich bereits richtig ;)
+ LoadAi();
+
+ If Not fUDP.Listen(UDPPingPort) Then Begin
+ log('Error, unable to listen on port: ' + inttostr(UDPPingPort), llFatal);
+ LogLeave;
+ exit;
+ End;
+ If Not fChunkManager.Listen(Port) Then Begin
+ log('Error could not listen on port: ' + inttostr(port), llFatal);
+ LogLeave;
+ exit;
+ End;
+ factive := true; // Haben wir es bis hier her geschafft, darf die Execute auch "laufen"
+ LogLeave;
+End;
+
+Destructor TServer.Destroy;
+Var
+ i: Integer;
+Begin
+ log('TServer.destroy', lltrace);
+ If assigned(fChunkManager) Then Begin
+ fChunkManager.Disconnect(true);
+ fChunkManager.free;
+ End;
+ // Das Disconnect macht ja der ChunkManager !
+ While fTCP.Connected Do Begin
+ fTCP.CallAction;
+ End;
+ ftcp.free;
+ // Den UDP auch sauber platt machen
+ If fUDP.Connected Then Begin
+ fUDP.Disconnect(true);
+ While fUDP.Connected Do Begin
+ fUDP.CallAction;
+ End;
+ End;
+ fUDP.free;
+ For i := 0 To high(fFields) Do Begin
+ fFields[i].Free;
+ End;
+ setlength(fFields, 0);
+ UnLoadAiLib(); // da ist das AiDeInit mit drin ;)
+ LogLeave;
+End;
+
+Procedure TServer.OnAccept(aSocket: TLSocket);
+Begin
+ // Wir Aktzeptieren eine Engehende Verbindung
+ log('TServer.OnAccept : ' + aSocket.PeerAddress, llTrace);
+ fChunkManager.SetNoDelay(true);
+ LogLeave;
+End;
+
+Procedure TServer.OnDisconnect(aSocket: TLSocket);
+Var
+ uid: integer;
+Begin
+ // Wir verlieren einen Spieler
+ If assigned(asocket) Then Begin
+ log('TServer.OnDisconnect : ' + aSocket.PeerAddress, llTrace);
+ End
+ Else Begin
+ log('TServer.OnDisconnect', llTrace);
+ End;
+ uid := fChunkManager.SocketToUID(aSocket);
+ PlayerLeaves(uid);
+ LogLeave;
+End;
+
+Procedure TServer.OnError(Const msg: String; aSocket: TLSocket);
+Begin
+ log('TServer.OnError', llTrace);
+ If assigned(asocket) Then Begin
+ log(asocket.PeerAddress + msg, llError)
+ End
+ Else Begin
+ log(msg, llError)
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.OnUDPError(Const msg: String; aSocket: TLSocket);
+Begin
+ log('TServer.OnUDPError', llTrace);
+ If assigned(asocket) Then Begin
+ log(asocket.PeerAddress + msg, llError)
+ End
+ Else Begin
+ log(msg, llError)
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.OnUDPDisconnect(aSocket: TLSocket);
+Begin
+ log('TServer.OnUDPDisconnect', llTrace);
+ If assigned(asocket) Then Begin
+ log('TServer.OnUDPDisconnect: ' + asocket.PeerAddress, llError)
+ End
+ Else Begin
+ log('TServer.OnUDPDisconnect', llError)
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.OnUDPReceiveEvent(aSocket: TLSocket);
+Var
+ UserName: String;
+ Buffer: Array[0..1024 - 1] Of byte;
+ cnt, i, ReadCnt: Integer;
+ b: Byte;
+Begin
+ If assigned(aSocket) Then Begin
+ log('TServer.OnUDPReceiveEvent : ' + aSocket.PeerAddress, llTrace);
+ End
+ Else Begin
+ log('TServer.OnUDPReceiveEvent', llTrace);
+ End;
+ Repeat
+ (*
+ * Es muss immer alles gelesen werden, sonst passieren merkwürdige Dinge
+ *)
+ ReadCnt := aSocket.Get(buffer, 1024);
+ If fGameState = gsWaitForPlayersToConnect Then Begin // Nur im Editor Modus, aktzeptieren wir Spieler, also Antworten wir auch nur wenn wir im Editor Modus sind
+ If GetActivePlayerCount() <> 0 Then Begin // Es ist midnestens 1 Spieler Angemeldet, also geben wir den Namen des 1. Spielers an
+ (*
+ * Das ist hier zwar Richtig, aber eigentlich Falsch, korrekt wäre das Suchen des 1. Spielers mit UID <> NoPlayer !
+ * -> Aktuell wertet der Client den String aber eh nicht aus, von daher, who cares...
+ *)
+ UserName := fPLayer[0].UserName + 's game';
+ End
+ Else Begin // Gar kleine Spieler, dann nur den Servernamen
+ UserName := 'no user connected';
+ End;
+ username := username + ':' + inttostr(fTCPPort);
+ cnt := length(username);
+ b := 21; // CTD hat hier 42 -> Wir wollen das die beiden nicht "Kompatibel" sind !
+ For i := 0 To cnt - 1 Do Begin
+ buffer[i] := ord(username[i + 1]);
+ b := b Xor buffer[i];
+ End;
+ Buffer[cnt] := b;
+ aSocket.Send(buffer, cnt + 1);
+ End;
+ Until ReadCnt = 0;
+ LogLeave;
+End;
+
+Procedure TServer.OnReceivedChunk(Sender: TObject; Const Chunk: TChunk);
+Var
+ s: String;
+ i, j: integer;
+ ts: QWord;
+Begin
+ //responceID := Chunk.UserDefinedID And $FFFF0000;
+ HandleStatisticCallback(sTotalNetworkPacketsIn);
+ HandleStatisticCallback(sTotalNetworkBytesIn, Chunk.Data.Size + ChunkManagerHeaderLen);
+{$IFDEF DoNotLog_CyclicMessages}
+ If ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
+ ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
+{$ENDIF}
+ log(format('TServer.OnReceivedChunk : %d, %s', [Chunk.UID, MessageIdentifierToString(Chunk.UserDefinedID)]), llTrace);
+
+ Case (Chunk.UserDefinedID And $FFFF) Of
+ miTogglePause: Begin
+ HandleTogglePause();
+ End;
+ miClientKeyEvent: Begin
+ HandleClientKeyEvent(Chunk.Data);
+ End;
+ miHeartBeat: Begin
+ i := -1;
+ chunk.Data.Read(i, sizeof(i));
+ ts := 0;
+ chunk.Data.Read(ts, sizeof(ts));
+ HandleReceiveHeartBeat(i, ts);
+ End;
+ miRequestLogin: Begin
+ HandleRequestUserLogin(Chunk.data, chunk.UID);
+ End;
+ miSwitchToPlayerSetup: Begin
+ HandleSwitchToPlayerSetup();
+ End;
+ miUpdateSettings: Begin
+ HandleLoadSettings(Chunk.Data);
+ End;
+ miChangePlayerKey: Begin
+ i := -1;
+ chunk.Data.Read(i, sizeof(i));
+ j := 0;
+ chunk.Data.Read(j, sizeof(j));
+ s := Chunk.Data.ReadAnsiString;
+ HandleChangePlayerKey(i, j, s, Chunk.UID);
+ End;
+ miSwitchToFieldSetup: Begin
+ HandleSwitchToMapProperties(Chunk.UID);
+ End;
+ miUpdateFieldSetup: Begin
+ HandleUpdateFieldSetup(Chunk.Data, Chunk.UID);
+ End;
+ miStartGame: Begin
+ If fGameState = gsShowHighscore Then Begin
+ If MatchFinished() Then Begin
+ HandleShowVictory();
+ End
+ Else Begin
+ HandleStartRound();
+ End;
+ End
+ Else Begin
+ HandleStartGame();
+ End;
+ End;
+ Else Begin
+ log('Unknown user defined id : ' + inttostr(Chunk.UserDefinedID And $FFFF), llError);
+ End;
+ End;
+{$IFDEF DoNotLog_CyclicMessages}
+ If ((Chunk.UserDefinedID And $FFFF) <> miHeartBeat) And
+ ((Chunk.UserDefinedID And $FFFF) <> miClientKeyEvent) Then
+ LogLeave;
+{$ENDIF}
+End;
+
+Procedure TServer.ResetFieldAvailabe;
+Var
+ i: integer;
+Begin
+ log('TServer.ResetFieldAvailabe', lltrace);
+ For i := 0 To high(fFields) Do Begin
+ fFields[i].Available := true;
+ End;
+ LogLeave;
+End;
+
+Function TServer.SendChunk(UserDefinedID: Integer; Data: TStream; UID: integer
+ ): Boolean;
+Var
+ i: integer;
+ dataLen: int64;
+Begin
+{$IFDEF DoNotLog_CyclicMessages}
+ If ((UserDefinedID And $FFFF) <> miUpdateGameData) And
+ ((UserDefinedID And $FFFF) <> miHeartBeat) Then
+{$ENDIF}
+ log(format('TServer.SendChunk : %d, %s', [uid, MessageIdentifierToString(UserDefinedID)]), llTrace);
+ datalen := ChunkManagerHeaderLen;
+ If assigned(data) Then dataLen := dataLen + Data.Size;
+ result := fChunkManager.SendChunk(UserDefinedID, data, uid);
+ If uid = 0 Then Begin
+ datalen := dataLen * max(1, fConnectedClientCount);
+ End
+ Else Begin
+ If uid < 0 Then Begin
+ // An Alle außer einem
+ datalen := dataLen * max(0, fConnectedClientCount - 1);
+ End
+ Else Begin
+ // Die Länge stimmt es geht ja nur an einen ;)
+ End;
+ End;
+ HandleStatisticCallback(sTotalNetworkPacketsOut);
+ HandleStatisticCallback(sTotalNetworkBytesOut, dataLen);
+ fFrameLog.AccumulatedSize := fFrameLog.AccumulatedSize + dataLen;
+ fFrameLog.Count := fFrameLog.Count + 1;
+ If Not result Then Begin
+ If uid < 0 Then Begin
+ (*
+ * Ein Broadcast (negativer UID) zu allen außer einem Spieler
+ * Ein Broadcast bringt nur was wenn wir mehr als 1 Spieler haben ;)
+ *)
+ If GetActivePlayerCount() > 1 Then Begin
+ log('Could not send broadcast (uid=' + inttostr(uid) + '), maybe no more clients connected.', llWarning);
+ End
+ Else Begin
+ log('Could not send broadcast (uid=' + inttostr(uid) + '), only one or no active players.', llWarning);
+ End;
+ End
+ Else Begin
+ // Try to find the player with this UID
+ For i := low(fPLayer) To high(fPLayer) Do Begin
+ If fPLayer[i].UID = UID Then Begin
+ log('Could not send to player : ' + fPLayer[i].UserName + ' (uid=' + inttostr(uid) + ')', llCritical);
+ LogLeave;
+ exit;
+ End;
+ End;
+ // Player not found
+ log('Could not send to player with uid=' + inttostr(uid) + ' (player not found)', llCritical);
+ End;
+ End;
+{$IFDEF DoNotLog_CyclicMessages}
+ If (UserDefinedID <> miUpdateGameData) And
+ (UserDefinedID <> miHeartBeat) Then
+{$ENDIF}
+ LogLeave;
+End;
+
+Procedure TServer.SendSplashMessage(msg: String; TargetUID: integer);
+Var
+ m: TMemoryStream;
+Begin
+ m := TMemoryStream.Create;
+ m.WriteAnsiString(msg);
+ SendChunk(miSplashHint, m, TargetUID);
+End;
+
+Procedure TServer.HandleRequestUserLogin(Const Stream: TStream; UID: integer);
+Var
+ m: TMemoryStream;
+ index, i, j, cnt: integer;
+ Username: String;
+ ClientVersion: uint32;
+ fieldlist: TFieldHashNameList;
+ ClientMode: Byte;
+Begin
+ log('TServer.HandleUserLoginRequest', llTrace);
+ ClientVersion := $FFFFFFFF;
+ Stream.Read(ClientVersion, sizeof(ClientVersion));
+ m := TMemoryStream.Create;
+ // 0. Check ob die beiden Versionen Compatibel sind
+ If ProtocollVersion <> ClientVersion Then Begin
+ i := EC_Invalid_Versions;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ LogLeave;
+ exit;
+ End;
+
+ ClientMode := 0;
+ Stream.Read(ClientMode, sizeof(ClientMode));
+ Username := Stream.ReadAnsiString;
+
+{$IFDEF Release}
+ If ClientMode <> GameModeRelease Then
+{$ELSE}
+ If ClientMode <> GameModeDebug Then
+{$ENDIF}Begin
+ i := EC_Invalid_Mode_Versions;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ LogLeave;
+ exit;
+ End;
+ //// 1. Check : Passwort
+ //If Password <> fPassword Then Begin
+ // i := EC_Invalid_Password;
+ // m.Write(i, sizeof(i));
+ // SendChunk(miRequestLoginResult, m, UID);
+ // LogLeave;
+ // exit;
+ //End;
+ // 2. Check : Darf der Spieler überhaupt verbinden = Läuft gerade ein Spiel ?
+ If (fGameState <> gsWaitForPlayersToConnect) Then Begin
+ i := EC_game_full;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ LogLeave;
+ exit;
+ End;
+ // 3. Check : Gibt es den Spielernamen bereits ?
+ cnt := 0;
+ For j := low(fPLayer) To high(fPLayer) Do Begin
+ If (fPLayer[j].UID <> NoPlayer) Then Begin
+ inc(cnt);
+ If (fPLayer[j].UserName = Username) Then Begin
+ i := EC_User_already_exists;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ LogLeave;
+ exit;
+ End;
+ End;
+ End;
+ // 4. Check: Max 10 Spieler
+ If cnt >= length(fPLayer) Then Begin
+ i := EC_Too_Much_Player;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ LogLeave;
+ exit;
+ End;
+ // Alles I.O. Der User kann beitreten
+ // Suchen eines Freien Platzes für den neuen Spieler ;)
+ index := -1;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID = NoPlayer Then Begin
+ index := i;
+ break;
+ End;
+ End;
+ (*
+ * Oben der Check ging durch und hier finden wir nix, das darf nicht sein, alles canceln !
+ *)
+ If index = -1 Then Begin
+ log('Error player overflow', llCritical);
+ HandleSwitchToWaitForPlayersToConnect;
+ LogLeave;
+ exit;
+ End;
+ // Der erste Spieler Loggt sich ein -> Wird zum Bestimmenden ;)
+ If cnt = 0 Then Begin
+ assert(fSettings.MasterUid = -1, 'First player connects, but old data was not cleared.');
+ fSettings.MasterUid := UID;
+ ResetFieldAvailabe();
+ End;
+ fPLayer[index].UID := UID;
+ fPLayer[index].UserName := Username;
+ fPLayer[index].Keyboard := ks0; // Beim Anlegen gibt es nur den Spieler 1 mit Keyboard 1
+ fPLayer[index].Kills := 0;
+ fPLayer[index].Score := 0;
+ i := -1;
+ Stream.Read(i, SizeOf(i));
+ fieldlist := Nil;
+ setlength(fieldlist, i);
+ For i := 0 To high(fieldlist) Do Begin
+ fieldlist[i].Name := Stream.ReadAnsiString;
+ Stream.Read(fieldlist[i].Hash, sizeof(fieldlist[i].Hash));
+ End;
+ setlength(fUidInfos, high(fUidInfos) + 2);
+ fUidInfos[high(fUidInfos)].Uid := UID;
+ fUidInfos[high(fUidInfos)].Fields := fieldlist;
+ log(format('Accepted player : %s as %d, now %d player in logged in', [Username, uid, cnt + 1]), llInfo);
+ i := EC_No_Error;
+ m.Write(i, sizeof(i));
+ i := uid;
+ m.Write(i, sizeof(i));
+ i := fSettings.MasterUid;
+ m.Write(i, sizeof(i));
+ SendChunk(miRequestLoginResult, m, UID);
+ // Allen Mitteilen das wir nen neuen Spieler haben
+ RefreshAllPlayerStats(0); // Allen Anwesenden Mitteilen Welche Spieler es so gibt
+ // Der Spieler ist Drin, nun müssen wir noch die Verfügbaren Karten von Beiden "Checken"
+ // Und dem Master Die Schnittmenge Mitteilen
+ EvalFieldHashList(fieldlist, true);
+ // CRITICAL: Always send available field list to all clients after evaluation
+ // This ensures all clients (including newly connected ones) receive the updated field list
+ // The master already got it from EvalFieldHashList above, but we need to send to all
+ // to ensure remote clients get the field list even if they're not the master
+ EvalFieldHashList(fieldlist, false); // Send to all clients (including the new one)
+ LogLeave;
+End;
+
+Procedure TServer.HandleSwitchToPlayerSetup;
+Begin
+ log('TServer.HandleSwitchToPlayerSetup', llTrace);
+ SendSettings(); // Alle Clients werden nun Settingstechnisch Gleich Geschaltet
+ fConnectedClientCount := GetActivePlayerCount();
+ fGameState := gsPlayerSetup;
+ SendChunk(miSwitchToPlayerSetup, Nil, 0);
+ LogLeave;
+End;
+
+Procedure TServer.SendSettings;
+Var
+ m: TMemoryStream;
+Begin
+ log('TServer.SendSettings', llTrace);
+ m := TMemoryStream.Create;
+ m.write(fSettings.TeamPlay, sizeof(fSettings.TeamPlay));
+ m.write(fSettings.RandomStart, sizeof(fSettings.RandomStart));
+ // Nodename hat der Server nicht
+ m.write(fSettings.ConveyorSpeed, sizeof(fSettings.ConveyorSpeed));
+ SchemeToStream(m, fSettings.Scheme);
+ m.write(fSettings.PlayTime, sizeof(fSettings.PlayTime));
+ m.write(fSettings.LostPlayersRevertToAI, sizeof(fSettings.LostPlayersRevertToAI));
+ // Playsounds hat der Server nicht
+ // Keyboard hat der Server nicht
+ m.WriteAnsiString(fSettings.LastPlayedField);
+ m.write(fSettings.LastPlayedFieldHash, sizeof(fSettings.LastPlayedFieldHash));
+ m.write(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
+ // Port hat der Server nicht
+ // CheckForUpdates hat der Server nicht
+ (*
+ * Die Settings kamen ja von der MasterUid, also kriegen sie Alle bis auf der Master ;)
+ *)
+ SendChunk(miUpdateSettings, m, -fSettings.MasterUid);
+ LogLeave;
+End;
+
+Procedure TServer.HandleLoadSettings(Const Stream: TStream);
+Var
+ i: Integer;
+Begin
+ log('TServer.HandleLoadSettings', llTrace);
+ Stream.read(fSettings.TeamPlay, sizeof(fSettings.TeamPlay));
+ Stream.read(fSettings.RandomStart, sizeof(fSettings.RandomStart));
+ // Nodename hat der Server nicht
+ Stream.read(fSettings.ConveyorSpeed, sizeof(fSettings.ConveyorSpeed));
+ If Not SchemeFromStream(Stream, fSettings.Scheme) Then Begin
+ log('Error, could not load scheme from stream', llCritical);
+ HandleSwitchToWaitForPlayersToConnect();
+ LogLeave;
+ exit;
+ End;
+ Stream.read(fSettings.PlayTime, sizeof(fSettings.PlayTime));
+ Stream.read(fSettings.LostPlayersRevertToAI, sizeof(fSettings.LostPlayersRevertToAI));
+ // Playsounds hat der Server nicht
+ // Keyboard hat der Server nicht
+ fSettings.LastPlayedField := Stream.ReadAnsiString();
+ Stream.read(fSettings.LastPlayedFieldHash, sizeof(fSettings.LastPlayedFieldHash));
+ Stream.read(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
+ // Port hat der Server nicht
+ // CheckForUpdates hat der Server nicht
+
+ // Übernehmen der Team Informationen in die FPLayer
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].Team := fSettings.Scheme.PlayerStartPositions[i].Team;
+ End;
+ LogLeave;
+End;
+
+
+(*
+ * Direction = 1
+ * Master:
+ * Off -> Uid (key0)
+ * Uid (key0) -> Uid (key1)
+ * Uid (key1) -> AI
+ * AI -> Off
+ * Jeder Andere:
+ * Off -> Uid (key0)
+ * Uid (key0) -> Uid (key1)
+ * Uid (key1) -> Off
+ * Directoin = -1
+ * Master:
+ * Off -> AI
+ * AI -> Uid (key1)
+ * Uid (key1) -> Uid (key0)
+ * Uid (key0) -> Off
+ * Jeder Andere:
+ * Off -> Uid (key1)
+ * Uid (key1) -> Uid (key0)
+ * Uid (key0) -> Off
+ * Alles Andere ist nicht erlaubt -> Keine Änderung
+ *)
+
+Procedure TServer.HandleChangePlayerKey(PlayerIndex, Direction: Integer;
+ PlayerName: String; UID: Integer);
+
+ // Helper function to get next input method in cycle
+ Function GetNextKeySet(Current: TKeySet; IsMaster: Boolean): TKeySet;
+ Begin
+ Case Current Of
+ ks0: result := ks1;
+ ks1: result := ksJoy1;
+ ksJoy1: result := ksJoy2;
+ ksJoy2: Begin
+ If IsMaster Then Begin
+ result := ks0; // Will be set to AI, this is just a placeholder
+ End
+ Else Begin
+ result := ks0; // Will be set to NoPlayer, this is just a placeholder
+ End;
+ End;
+ Else
+ result := ks0;
+ End;
+ End;
+
+ // Helper function to get previous input method in cycle
+ Function GetPrevKeySet(Current: TKeySet; IsMaster: Boolean): TKeySet;
+ Begin
+ Case Current Of
+ ks0: Begin
+ If IsMaster Then Begin
+ result := ksJoy2; // Will be set to AI, this is just a placeholder
+ End
+ Else Begin
+ result := ksJoy2; // Will be set to NoPlayer, this is just a placeholder
+ End;
+ End;
+ ks1: result := ks0;
+ ksJoy1: result := ks1;
+ ksJoy2: result := ksJoy1;
+ Else
+ result := ks0;
+ End;
+ End;
+
+Begin
+ log(format('TServer.HandleChangePlayerKey (%d, %d, %s)', [PlayerIndex, Direction, PlayerName]), llTrace);
+ If (PlayerIndex = -1) Or (Direction = 0) Or (UID = 0) Then Begin
+ LogLeave;
+ exit;
+ End;
+
+ // Master cycle: Off -> Keyboard 0 -> Keyboard 1 -> Joy 1 -> Joy 2 -> AI -> Off
+ // Non-Master cycle: Off -> Keyboard 0 -> Keyboard 1 -> Joy 1 -> Joy 2 -> Off
+
+ If Direction > 0 Then Begin
+ // Forward cycle
+ If UID = fSettings.MasterUid Then Begin
+ // Master player
+ If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
+ // Off -> Keyboard 0
+ fPLayer[PlayerIndex].UID := UID;
+ fPLayer[PlayerIndex].Keyboard := ks0;
+ fPLayer[PlayerIndex].UserName := PlayerName;
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = UID Then Begin
+ // Same player, cycle through input methods
+ If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy2;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy2 Then Begin
+ // Joy 2 -> AI
+ fPLayer[PlayerIndex].UID := AIPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ End;
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = AIPlayer Then Begin
+ // AI -> Off
+ fPLayer[PlayerIndex].UID := NoPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ RefreshAllPlayerStats(0);
+ End;
+ End
+ Else Begin
+ // Non-Master player
+ If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
+ // Off -> Keyboard 0
+ fPLayer[PlayerIndex].UID := UID;
+ fPLayer[PlayerIndex].Keyboard := ks0;
+ fPLayer[PlayerIndex].UserName := PlayerName;
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = UID Then Begin
+ // Same player, cycle through input methods
+ If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy2;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy2 Then Begin
+ // Joy 2 -> Off
+ fPLayer[PlayerIndex].UID := NoPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ End;
+ RefreshAllPlayerStats(0);
+ End;
+ End;
+ End
+ Else Begin
+ // Backward cycle
+ If UID = fSettings.MasterUid Then Begin
+ // Master player
+ If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
+ // Off -> AI
+ fPLayer[PlayerIndex].UID := AIPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = AIPlayer Then Begin
+ // AI -> Joy 2
+ fPLayer[PlayerIndex].UID := UID;
+ fPLayer[PlayerIndex].Keyboard := ksJoy2;
+ fPLayer[PlayerIndex].UserName := PlayerName;
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = UID Then Begin
+ // Same player, cycle backwards through input methods
+ If fPLayer[PlayerIndex].Keyboard = ksJoy2 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks0;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
+ // Keyboard 0 -> Off
+ fPLayer[PlayerIndex].UID := NoPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ End;
+ RefreshAllPlayerStats(0);
+ End;
+ End
+ Else Begin
+ // Non-Master player
+ If fPLayer[PlayerIndex].UID = NoPlayer Then Begin
+ // Off -> Joy 2
+ fPLayer[PlayerIndex].UID := UID;
+ fPLayer[PlayerIndex].Keyboard := ksJoy2;
+ fPLayer[PlayerIndex].UserName := PlayerName;
+ RefreshAllPlayerStats(0);
+ End
+ Else If fPLayer[PlayerIndex].UID = UID Then Begin
+ // Same player, cycle backwards through input methods
+ If fPLayer[PlayerIndex].Keyboard = ksJoy2 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ksJoy1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ksJoy1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks1;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks1 Then Begin
+ fPLayer[PlayerIndex].Keyboard := ks0;
+ End
+ Else If fPLayer[PlayerIndex].Keyboard = ks0 Then Begin
+ // Keyboard 0 -> Off
+ fPLayer[PlayerIndex].UID := NoPlayer;
+ fPLayer[PlayerIndex].UserName := '';
+ End;
+ RefreshAllPlayerStats(0);
+ End;
+ End;
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.HandleSwitchToMapProperties(UID: Integer);
+Var
+ t1, t2, i, j, aicnt, pcnt: integer;
+ a: Array Of Integer;
+ b: Boolean;
+Begin
+ log(format('TServer.HandleSwitchToMapProperties (UID=%d)', [UID]), llInfo);
+ aicnt := 0;
+ pcnt := 0;
+ t1 := 0;
+ t2 := 0;
+ // Prüfen ob Genug Spieler verfügbar sind und diese auch in den Richtigen Teams !
+ For i := 0 To high(fPlayer) Do Begin
+ If fPlayer[i].UID > 0 Then inc(pcnt);
+ If fPlayer[i].UID = AIPlayer Then inc(aicnt);
+ If fPlayer[i].UID <> NoPlayer Then Begin
+ If fPlayer[i].Team = 0 Then Begin
+ inc(t1);
+ End
+ Else Begin
+ inc(t2);
+ End;
+ End;
+ End;
+ If (pcnt = 1) And (aicnt = 0) Then Begin
+ SendSplashMessage('Only one player on the map makes no sense, please wait for other players or activate at least one ai player.', UID);
+ LogLeave;
+ exit;
+ End;
+
+ If fSettings.TeamPlay Then Begin
+ If (t1 = 0) Or (t2 = 0) Then Begin
+ SendSplashMessage('In teamplay at least one player per team ist needed.', UID);
+ LogLeave;
+ exit;
+ End;
+ End;
+
+ // Suchen auf Doppelt vergebene Spieler
+ For i := 0 To high(fPLayer) Do Begin
+ For j := i + 1 To high(fPLayer) Do Begin
+ If (fPLayer[i].UID > 0) And (fPLayer[i].UID = fPLayer[j].UID) And (fPLayer[i].Keyboard = fPLayer[j].Keyboard) Then Begin
+ SendSplashMessage('Error, client "' + fPLayer[i].UserName + '" uses two playerslots with the same key settings.', UID);
+ LogLeave;
+ exit;
+ End;
+ End;
+ End;
+
+ // Debug logging: Show all active player slots
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID > NoPlayer Then Begin
+ log(format(' Slot %d: UID=%d, Username=%s, Keyboard=%d',
+ [i, fPLayer[i].UID, fPLayer[i].UserName, Ord(fPLayer[i].Keyboard)]), llInfo);
+ End;
+ End;
+
+ // Note: The check "all connected clients have at least one slot" was removed
+ // because it incorrectly flagged local co-op as an error (one UID with multiple keyboards).
+ // The existing checks are sufficient:
+ // 1. Duplicate slot check (line 925-933) prevents same UID + same Keyboard
+ // 2. Minimum player check (line 910-914) ensures enough players to start
+ // Alle Checks gut -> Umschalten auf die Karteneigenschaften
+ fGameState := gsMapSetup;
+ SendChunk(miSwitchToFieldSetup, Nil, 0);
+ LogLeave;
+End;
+
+Procedure TServer.HandleStartGame;
+Var
+ i: Integer;
+Begin
+ log('TServer.HandleStartGame', llTrace);
+ HandleStatisticCallback(sMatchesStarted);
+ // 1. Alle Player "Initialisieren
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].Score := 0;
+ fPLayer[i].Kills := 0;
+ End;
+ fRandomMap := (fActualField.Hash = 0) And (fActualField.Name = '');
+ HandleStartRound;
+ LogLeave;
+End;
+
+Procedure TServer.HandleStartRound;
+ Function PowersFromScheme(Const Scheme: TScheme): TAtomicPowers;
+ Begin
+ result.Speed := AtomicDefaultSpeed;
+ result.AvailableBombs := 1;
+ // result.OverAllBombs := 1; -- Egal weil es unten "Hart" noch mal gesetzt wird
+ result.FlameLen := 1;
+ result.CanKickBombs := false;
+ result.CanPunchBombs := false;
+ result.CanGrabBombs := false;
+ result.CanSpooger := false;
+ result.TriggerBomb := 0;
+ result.JellyBombs := false;
+ If Scheme.PowerUps[puExtraBomb].Bornwith <> 0 Then Begin
+ result.AvailableBombs := max(1, Scheme.PowerUps[puExtraBomb].BornWith);
+ End;
+ result.OverAllBombs := result.AvailableBombs;
+ If Scheme.PowerUps[puLongerFlameLength].Bornwith > 1 Then Begin
+ result.FlameLen := Scheme.PowerUps[puLongerFlameLength].Bornwith;
+ End;
+ If Scheme.PowerUps[puExtraSpeed].Bornwith > 0 Then Begin
+ result.Speed := min(AtomicDefaultSpeed * power(AtomicSpeedChange, max(0, Scheme.PowerUps[puExtraSpeed].Bornwith)), AtomicMaxSpeed);
+ End;
+ // Manche Powerups schließen sich gegenseitig aus, dass muss hier und in HandlePlayerGetsPowerUp berücksichtigt werden
+ // Die Reihenfolge hier gibt dabei die Prio mit an, im Spiel nachher löscht das neueste immer die alten
+
+ If Scheme.PowerUps[puCanCick].Bornwith > 0 Then Begin
+ result.CanKickBombs := true;
+ End;
+ If Scheme.PowerUps[puCanPunch].Bornwith > 0 Then Begin
+ result.CanPunchBombs := true;
+ End;
+ If Scheme.PowerUps[puCanSpooger].Bornwith > 0 Then Begin
+ result.CanSpooger := true;
+ result.CanGrabBombs := false;
+ End;
+ If Scheme.PowerUps[puCanGrab].Bornwith > 0 Then Begin
+ result.CanGrabBombs := true;
+ result.CanSpooger := false;
+ End;
+ If Scheme.PowerUps[puGoldFlame].Bornwith > 0 Then Begin
+ result.FlameLen := 99; // Egal hauptsache mehr als 15 !
+ End;
+ If Scheme.PowerUps[puTrigger].Bornwith > 0 Then Begin
+ result.TriggerBomb := result.OverAllBombs;
+ End;
+ If Scheme.PowerUps[puCanJelly].Bornwith > 0 Then Begin
+ result.JellyBombs := true;
+ End;
+ End;
+
+Var
+ a, b, c, i: Integer;
+ n: QWord;
+ m: TMemoryStream;
+ Startindex: Array[0..length(PlayerColors) - 1] Of Integer;
+ pu: TPowerUps;
+Begin
+ log('TServer.HandleStartRound', llTrace);
+ HandleStatisticCallback(sGamesStarted);
+
+ If fSettings.PlayTime = 0 Then Begin
+ fPlayingTimedesc := -1000; // Unendlich ;)
+ End
+ Else Begin
+ fPlayingTimedesc := fSettings.PlayTime * 1000;
+ End;
+ fPlayingTimeasc := 0;
+ For i := 0 To high(Startindex) Do Begin
+ Startindex[i] := i;
+ End;
+ // Wenn Random Start -> dann permutieren wir hier die Startpositionen ;)
+ If fSettings.RandomStart Then Begin
+ For i := 0 To 100 Do Begin
+ a := random(length(Startindex));
+ b := random(length(Startindex));
+ If a <> b Then Begin
+ c := Startindex[a];
+ Startindex[a] := Startindex[b];
+ Startindex[b] := c;
+ End;
+ End;
+ End;
+ // 1. Alle Player "Initialisieren
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].Info.Alive := fPLayer[i].UID <> NoPlayer;
+ fPLayer[i].Info.Animation := raStandStill;
+ fPLayer[i].Info.Value := 0;
+ fPLayer[i].Info.Position := v2(fSettings.Scheme.PlayerStartPositions[Startindex[i]].x + 0.5, fSettings.Scheme.PlayerStartPositions[Startindex[i]].y + 0.5);
+ fPLayer[i].Info.Direction := 0;
+ fPLayer[i].Info.ColorIndex := i;
+ fPLayer[i].MoveState := msStill;
+ fPLayer[i].Action := aaNone;
+ fPLayer[i].Flying := false;
+ fPLayer[i].IsInHohle := false;
+ fPLayer[i].Disease := [];
+ fPLayer[i].DiseaseCounter := 0;
+ fPLayer[i].IdleTimer := 0;
+ fPLayer[i].Info.Dying := false; // Wir Sind alle wieder am Leben ;)
+ // fPLayer[i].Team := fSettings.Scheme.PlayerStartPositions[i].Team; -- Wurde schon gemacht in HandleLoadSettings
+ fPLayer[i].Powers := PowersFromScheme(fSettings.Scheme);
+ For pu In TPowerUps Do Begin
+ fPLayer[i].PowerUpCounter[pu] := 0;
+ End;
+ End;
+ // 2. Init der Karte
+ // Steht das Match gerade auf "Zufällige" Karten dann wählen wir hier eine neue Zufällige Karte aus
+ If fRandomMap Then Begin
+ fActualField := fFields[Random(Length(fFields))];
+ While ((fActualField.Hash = 0) And (fActualField.Name = '')) Or (Not fActualField.Available) Do Begin
+ fActualField := fFields[Random(Length(fFields))];
+ End;
+ // Die Clients auf die Richtigen Karten Umschalten,
+ // !! Achtung das ist doppelt implementiert (siehe TServer.HandleUpdateFieldSetup)
+ m := TMemoryStream.Create;
+ m.WriteAnsiString(fActualField.Name);
+ m.Write(fActualField.Hash, sizeof(fActualField.Hash));
+ m.write(fSettings.LastWinsToWinMatch, sizeof(fSettings.LastWinsToWinMatch));
+ SendChunk(miUpdateFieldSetup, m, 0);
+ End;
+
+ fActualField.Initialize(fPLayer, fSettings.Scheme);
+ SendChunk(miStartGame, Nil, 0);
+ n := GetTickCount64;
+ For i := 0 To high(fPLayer) Do Begin // Egal das das alle sind ..
+ fPLayer[i].LastSynchronTimeStamp := n;
+ End;
+ FLastFrameTimestamp := n;
+ fLastHeartbeatTimestamp := n;
+ fLastClientUpdateTimestamp := n;
+ fpausing := false;
+ fSyncPause := false;
+ foldpausevalue := false;
+ fGameState := gsPlaying;
+ fFrameLog.Count := 0;
+ fFrameLog.AccumulatedSize := 0;
+ If assigned(AiNewRound) Then Begin
+ // TODO: diese 100% müssen noch einstellbar gemacht werden
+ AiNewRound(100);
+ End;
+ UpdateAllClients(); // Sofort alle Clients informieren, auf dass die auch gleich was sinnvolles sehen ..
+ LogLeave;
+End;
+
+Procedure TServer.HandleTogglePause;
+Var
+ m: TMemoryStream;
+ i: Integer;
+Begin
+ log('TServer.HandleTogglePause', llTrace);
+ fpausing := Not fpausing;
+ ApplyPause(fpausing);
+ If fpausing Then Begin
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].MoveState := msStill;
+ fPLayer[i].Action := aaNone;
+ End;
+ End;
+ m := TMemoryStream.Create;
+ m.Write(fpausing, sizeof(fpausing));
+ SendChunk(miTogglePause, m, 0);
+ LogLeave;
+End;
+
+Procedure TServer.HandleShowVictory;
+Begin
+ // Den Victory Screen auswählen
+ // Der Gewinner wurde bereits in EndGameCheck bestimmt.
+ SendChunk(miShowVictory, Nil, 0);
+ fKickAllPlayer := true;
+End;
+
+Procedure TServer.HandlePlayerGetsPowerUp(Var Player: TPlayer;
+ PlayerIndex: integer; PowerUp: TPowerUps);
+Var
+ index, cnt, i: integer;
+ tmppos: TVector2;
+Begin
+ log('TServer.HandlePlayerGetsPowerUp', llTrace);
+ // TODO: Die Force, Override, forbidden dinge müssen hier noch berücksichtigt werden..
+ // \-> Das Forbidden wird in TAtomicField.Initialize bereits gemacht.
+ If PowerUp <> puNone Then Begin
+ HandleStatisticCallback(sPowerupsCollected);
+ (*
+ * Mit Zählen, was der Spieler so aufsammelt
+ *)
+ Player.PowerUpCounter[PowerUp] := Player.PowerUpCounter[PowerUp] + 1;
+ End;
+ Case PowerUp Of
+ puNone: Begin
+ End;
+ puExtraBomb: Begin
+ Player.Powers.AvailableBombs := Player.Powers.AvailableBombs + 1;
+ Player.Powers.OverAllBombs := Player.Powers.OverAllBombs + 1;
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ End;
+ puLongerFlameLength: Begin
+ Player.Powers.FlameLen := min(99, Player.Powers.FlameLen + 1);
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ End;
+ puDisease: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
+ Case random(3) Of
+ 0: Player.Disease := Player.Disease + [dInvertedKeyboard];
+ 1: Begin
+ Player.Disease := Player.Disease + [dNoBombs];
+ Player.Action := aaNone;
+ End;
+ 2: Player.Disease := Player.Disease + [dDudBombs];
+ 3: Begin
+ If Not (dSuperSlow In Player.Disease) Then Begin
+ Player.BeforeSlowDiseaseSpeed := Player.powers.Speed;
+ Player.Disease := Player.Disease + [dSuperSlow];
+ Player.powers.Speed := AtomicSlowSpeed / (AtomicSpeedChange * AtomicSpeedChange);
+ End;
+ End;
+ End;
+ Player.DiseaseCounter := AtomicDiseaseTime;
+ End;
+ puCanCick: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.CanKickBombs := true;
+ End;
+ puCanPunch: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.CanPunchBombs := true;
+ End;
+ puExtraSpeed: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.Speed := min(Player.Powers.Speed * AtomicSpeedChange, AtomicMaxSpeed);
+ End;
+ puCanGrab: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.CanGrabBombs := true;
+ Player.Powers.CanSpooger := false;
+ End;
+ puCanSpooger: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.CanSpooger := true;
+ Player.Powers.CanGrabBombs := false;
+ End;
+ puGoldFlame: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.FlameLen := 99;
+ End;
+ puTrigger: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.TriggerBomb := Player.Powers.TriggerBomb + Player.Powers.OverAllBombs;
+ End;
+ puCanJelly: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetGoodPowerUp);
+ Player.Powers.JellyBombs := true;
+ End;
+ puSuperBadDisease: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
+ If random(100) < 10 Then Begin
+ cnt := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Info.Alive Then inc(cnt);
+ End;
+ (*
+ * Mit Einer Wahrscheinlichkeit von 10 % tauschen wir die Plätze mit einem anderen Spieler ;)
+ *)
+ If cnt > 1 Then Begin
+ Repeat
+ index := random(Length(fPLayer));
+ Until fPLayer[index].Info.Alive And (PlayerIndex <> index);
+ tmppos := fPLayer[index].Info.Position;
+ fPLayer[index].Info.Position := fPLayer[PlayerIndex].Info.Position;
+ fPLayer[PlayerIndex].Info.Position := tmppos;
+ End;
+ End
+ Else Begin
+ Player.Disease := Player.Disease + [dEbola];
+ Player.Powers.TriggerBomb := 0;
+ Player.DiseaseCounter := AtomicDiseaseTime;
+ End;
+ End;
+ puSlow: Begin
+ HandlePlaySoundEffect(PlayerIndex, seGetBadPowerUp);
+ Player.Powers.Speed := AtomicSlowSpeed;
+ End;
+ purandom: Begin
+ log('TServer.HandlePlayerGetsPowerUp: Missing implementation for purandom', llError);
+ End;
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.HandlePlaySoundEffect(PlayerIndex: integer;
+ Effect: TSoundEffect);
+Var
+ m, m2: TMemoryStream;
+ targetUID: Integer;
+ i: Integer;
+ playerUID: Integer;
+Begin
+ log('TServer.HandlePlaySoundEffect', llTrace);
+ // Check if player is valid
+ If (PlayerIndex < 0) Or (PlayerIndex > high(fPLayer)) Then Begin
+ log('Invalid PlayerIndex: ' + inttostr(PlayerIndex), llError);
+ LogLeave;
+ exit;
+ End;
+
+ playerUID := fPLayer[PlayerIndex].UID;
+
+ // Skip inactive slots (UID = NoPlayer = 0)
+ If playerUID = NoPlayer Then Begin
+ log('Skipping sound for inactive player slot: ' + inttostr(PlayerIndex), llTrace);
+ LogLeave;
+ exit;
+ End;
+
+ m := TMemoryStream.Create;
+ m.Write(Effect, sizeof(Effect));
+
+ // Handle AI players (UID = AIPlayer = -1) - send sounds to all other players
+ If playerUID = AIPlayer Then Begin
+ // For AI players, send sounds to all connected players (broadcast)
+ // Use negative UID to indicate broadcast to all except sender (but sender is AI, so send to all)
+ If GetActivePlayerCount() > 0 Then Begin
+ // Send to all connected players (UID > 0)
+ targetUID := 0; // 0 means broadcast to all connected players
+ // Actually, we need to send to each connected player individually
+ // because SendChunk with negative UID excludes the sender, but we want to include all
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID > 0 Then Begin
+ // Create a new stream for each player
+ m2 := TMemoryStream.Create;
+ m2.Write(Effect, sizeof(Effect));
+ SendChunk(miPlaySoundEffekt, m2, fPLayer[i].UID);
+ End;
+ End;
+ m.Free; // Free the original stream
+ End
+ Else Begin
+ log('Skipping AI sound - no connected players', llInfo);
+ m.Free;
+ End;
+ End
+ Else If playerUID > 0 Then Begin
+ // Normal player (UID > 0)
+ If Effect = seOtherPlayerDied Then Begin
+ // Send to all players except this one (broadcast with negative UID)
+ // Only send if there are at least 2 active players
+ If GetActivePlayerCount() > 1 Then Begin
+ targetUID := -playerUID;
+ SendChunk(miPlaySoundEffekt, m, targetUID);
+ End
+ Else Begin
+ log('Skipping seOtherPlayerDied sound - only one player connected', llInfo);
+ m.Free;
+ End;
+ End
+ Else Begin
+ // Send to this specific player
+ targetUID := playerUID;
+ SendChunk(miPlaySoundEffekt, m, targetUID);
+ End;
+ End
+ Else Begin
+ // Unknown UID value
+ log('Unknown player UID: ' + inttostr(playerUID) + ' for player index: ' + inttostr(PlayerIndex), llWarning);
+ m.Free;
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.HandleStatisticCallback(StatSelector: TStatSelector;
+ Value: uint64);
+Begin
+ fStatistik.LastRun[StatSelector] := fStatistik.LastRun[StatSelector] + Value;
+End;
+
+Procedure TServer.HandleSwitchToWaitForPlayersToConnect;
+Var
+ cnt, i: Integer;
+Begin
+ log('TServer.HandleSwitchToWaitForPlayersToConnect', llTrace);
+ fGameState := gsWaitForPlayersToConnect;
+ fConnectedClientCount := 0;
+ cnt := GetActivePlayerCount();
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].UID := NoPlayer;
+ fPLayer[i].UserName := '';
+ fPLayer[i].Kills := 0;
+ fPLayer[i].Score := 0;
+ End;
+ If assigned(fChunkManager) And (cnt > 0) Then Begin
+ SendChunk(miCommandoBackToMainMenu, Nil, 0);
+ End;
+ // TODO: Klären was noch alles zurück gesetzt werden muss ..
+ fSettings.MasterUid := -1;
+ fActualField := Nil;
+ fSettings.LastWinsToWinMatch := 3; // Default der Clients
+ LogLeave;
+End;
+
+Procedure TServer.HandleUpdateFieldSetup(Const Stream: TStream; Uid: integer);
+Var
+ FieldName: String;
+ FieldHash: UInt64;
+ Wins, i: INteger;
+ m: TMemoryStream;
+Begin
+ log('TServer.HandleUpdateFieldSetup', llTrace);
+ m := TMemoryStream.Create;
+ m.CopyFrom(Stream, Stream.Size - Stream.Position);
+ m.Position := 0;
+ FieldName := m.ReadAnsiString;
+ FieldHash := 0;
+ Wins := 0;
+ m.Read(FieldHash, SizeOf(FieldHash));
+ m.Read(Wins, SizeOf(Wins));
+
+ For i := 0 To high(fFields) Do Begin
+ If (fFields[i].Name = FieldName)
+ And (fFields[i].Hash = FieldHash) Then Begin
+ fActualField := fFields[i];
+ fSettings.LastWinsToWinMatch := Wins;
+ // Weiterleiten an alle Clients,
+ // !! Achtung, das ist doppelt implementiert (siehe TServer.HandleStartRound;);
+ m.Position := 0;
+ SendChunk(miUpdateFieldSetup, m, -uid);
+ LogLeave;
+ exit;
+ End;
+ End;
+ (*
+ * Fehler, alle fliegen raus !
+ *)
+ Log('Error, could not find field: ' + FieldName, llCritical);
+ HandleSwitchToWaitForPlayersToConnect();
+ LogLeave;
+End;
+
+Procedure TServer.HandleReceiveHeartBeat(p: integer; t: int64);
+Var
+ i: Integer;
+Begin
+ If fGameState <> gsPlaying Then exit;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID = p Then Begin
+ fPLayer[i].LastSynchronTimeStamp := t;
+ End;
+ End;
+End;
+
+Procedure TServer.HandleClientKeyEvent(Const Stream: TStream);
+Var
+ Player: integer;
+ Double, State: Boolean;
+ Key: TAtomicKey;
+Begin
+ If fpausing Then exit;
+ player := -1;
+ State := false;
+ Double := false;
+ key := akFirstAction;
+ stream.Read(Player, sizeof(Player));
+ stream.Read(State, sizeof(State));
+ stream.Read(key, sizeof(key));
+ stream.Read(Double, sizeof(Double));
+ fPLayer[Player].IdleTimer := 0; // Der Spieler hat eine Eingabe gemacht -> reset des Idle Timers ;)
+ If State Then Begin
+ If dInvertedKeyboard In fPLayer[Player].Disease Then Begin
+ Case key Of
+ akUp: key := akDown;
+ akDown: key := akUp;
+ akLeft: key := akRight;
+ akRight: key := akLeft;
+ End;
+ End;
+ Case Key Of
+ akUp: fPLayer[Player].MoveState := msUp;
+ akDown: fPLayer[Player].MoveState := msDown;
+ akLeft: fPLayer[Player].MoveState := msLeft;
+ akRight: fPLayer[Player].MoveState := msRight;
+ akFirstAction: Begin
+ If (Not (dNoBombs In fPLayer[Player].Disease)) Then Begin
+ If Double Then Begin
+ fPLayer[Player].Action := aaFirstDouble;
+ End
+ Else Begin
+ fPLayer[Player].Action := aaFirst;
+ End;
+ End;
+ End;
+ akSecondAction: Begin
+ If (Not (dNoBombs In fPLayer[Player].Disease)) Then Begin
+ If Double Then Begin
+ fPLayer[Player].Action := aaSecondDouble;
+ End
+ Else Begin
+ fPLayer[Player].Action := aaSecond;
+ End;
+ End;
+ End;
+ End;
+ End
+ Else Begin
+ // Nur die "Cursor" werden false gemacht -> immer Stillstand
+ fPLayer[Player].MoveState := msStill;
+ End;
+End;
+
+Procedure TServer.RefreshAllPlayerStats(Uid: integer);
+Var
+ m: TMemoryStream;
+ j, i: Integer;
+ k: TKeySet;
+Begin
+ // Removed log/logleave - was causing stack overflow on frequent calls
+ m := TMemoryStream.Create;
+ // Einfügen aller Spielerinformationen, dass diese übernommen werden können (z.B. nach Load Game)
+ j := length(fPLayer);
+ m.write(j, sizeof(j));
+ For i := 0 To high(fPLayer) Do Begin
+ j := fPLayer[i].UID;
+ m.write(j, sizeof(j));
+ k := fPLayer[i].Keyboard;
+ m.write(k, sizeof(k));
+ j := fPLayer[i].Kills;
+ m.write(j, sizeof(j));
+ j := fPLayer[i].Score;
+ m.write(j, sizeof(j));
+ m.WriteAnsiString(fPLayer[i].UserName);
+ End;
+ SendChunk(miRefreshPlayerStats, m, UID);
+End;
+
+Procedure TServer.PlayerLeaves(PlayerUid: integer);
+Var
+ t0, t1, i, cnt, c: integer;
+ m: TMemoryStream;
+Begin
+ log('TServer.PlayerLeaves', llTrace);
+ If PlayerUid = 0 Then Begin
+ Log('Disconnect user with unknown uid', llCritical);
+ LogLeave;
+ exit;
+ End;
+ cnt := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID = PlayerUid Then Begin
+ log('Lost player : ' + fPLayer[i].UserName, llInfo);
+ If fSettings.LostPlayersRevertToAI Then Begin
+ fPLayer[i].UID := AIPlayer;
+ End
+ Else Begin
+ fPLayer[i].UID := NoPlayer;
+ End;
+ fPLayer[i].UserName := '';
+ If fPLayer[i].Info.Alive Then Begin // Sollte der Spieler noch am Leben sein -> stirbt er evtl jetzt
+ fPLayer[i].Info.Alive := fPLayer[i].UID <> NoPlayer;
+ End;
+ If Not fPLayer[i].Info.Alive Then Begin
+ fPLayer[i].Kills := 0;
+ fPLayer[i].Score := 0;
+ End;
+ // TODO: Alles andere des Spielers auch noch löschen ?
+ End;
+ // Zählen der Noch aktiven Spieler
+ If fPLayer[i].UID > 0 Then inc(cnt);
+ End;
+ For i := 0 To high(fUidInfos) Do Begin
+ If fUidInfos[i].Uid = PlayerUid Then Begin
+ For c := i To high(fUidInfos) - 1 Do Begin
+ fUidInfos[c] := fUidInfos[c + 1];
+ End;
+ setlength(fUidInfos, high(fUidInfos));
+ break;
+ End;
+ End;
+ // Der "Master" Spieler geht
+ If PlayerUid = fSettings.MasterUid Then Begin // TODO: Klären ob es Sinnvoll ist das bei allen Spielern zu machen und nicht nur beim Master ..
+ // So lange wir im Spiel definierenden Teil sind
+ // Bedeutet der Verlust des Master Spielers den Ausstieg ins
+ // Hauptmenü
+ If fGameState In [gsWaitForPlayersToConnect, gsPlayerSetup, gsMapSetup] Then Begin
+ cnt := 0;
+ End;
+ // Der Master ist gegangen und wir sind mitten im Spielen, wir müssen einen neuen Bestimmen, sonst können die anderen das Match nicht zu ende Spielen..
+ If cnt <> 0 Then Begin
+ fSettings.MasterUid := -1;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID > NoPlayer Then Begin
+ fSettings.MasterUid := fPLayer[i].UID;
+ log('Lost primary player, selected ' + fPLayer[i].UserName + ' as new primary player.', llWarning);
+ break;
+ End;
+ End;
+ m := TMemoryStream.Create;
+ i := fSettings.MasterUid;
+ m.Write(i, SizeOf(i));
+ SendChunk(miUpdateMasterID, m, -PlayerUid);
+ End;
+ End;
+ // Wenn im TeamSpiel kann es sein, dass nur noch 1 Team übrig ist und alle Spieler des anderen Rausgeflogen sind ..
+ If fSettings.TeamPlay Then Begin
+ t0 := 0;
+ t1 := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID <> NoPlayer Then Begin
+ If fPLayer[i].Team = 0 Then Begin
+ inc(t0);
+ End
+ Else Begin
+ inc(t1);
+ End;
+ End;
+ End;
+ // Das Spiel so Manipulieren, dass nach dem MatchStatistik Screen der ShowVictory Screen kommt
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].UID <> NoPlayer Then Begin
+ If fPLayer[i].Team = 0 Then Begin
+ If (t1 = 0) Then Begin
+ fSettings.LastWinsToWinMatch := fPLayer[i].Score;
+ End;
+ End
+ Else Begin
+ If (t0 = 0) Then Begin
+ fSettings.LastWinsToWinMatch := fPLayer[i].Score;
+ End;
+ End;
+ End;
+ End;
+ End;
+ If cnt > 0 Then Begin
+ // Wenn es noch andere Spieler gibt Aktualisieren der Spielerliste (z.B. im Start Game Mode wichtig..)
+ RefreshAllPlayerStats(0);
+ ResetFieldAvailabe();
+ For i := 0 To high(fUidInfos) Do Begin
+ EvalFieldHashList(fUidInfos[i].Fields, i = high(fUidInfos)); // Nur beim Letzten auch Tatsächlich senden, das Spart Traffic
+ End;
+ End
+ Else Begin
+ // Der letzte Geht, zurück in den Edit Modus, macht nur im Timeout=0 Modus sinn, sonst beeden wir eh nach 1000ms
+ HandleSwitchToWaitForPlayersToConnect;
+ End;
+ fConnectedClientCount := fConnectedClientCount - 1;
+ If (cnt = 0) And (fAutotimeout <> 0) Then Begin
+ log(format('Lost last client, will shut down in %0.3fs', [fAutotimeout / 1000]), llInfo);
+ End;
+ LogLeave;
+End;
+
+Function TServer.GetActivePlayerCount: Integer;
+Var
+ i: Integer;
+Begin
+ // !! Hier kein Logger, dass ist sonst zu viel
+ result := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If (fPLayer[i].UID <> NoPlayer) And (fPLayer[i].UID > 0) Then inc(result);
+ End;
+End;
+
+Procedure TServer.EvalFieldHashList(Const List: TFieldHashNameList;
+ SendToMaster: Boolean);
+Var
+ m, m2: TMemorystream;
+ i, j: Integer;
+ found: Boolean;
+Begin
+ (*
+ * Gleicht List mit der Eigenen Fieldliste ab, und streicht aus der Fieldliste
+ * alle die raus die nicht in List sind
+ *
+ * Danach wird diese "kleinste" Schnittmenge an den Master gesendet.
+ *)
+ log('TServer.EvalMapHashList', lltrace);
+ m := TMemoryStream.Create;
+ For i := 0 To high(fFields) Do Begin
+ found := false;
+ If fFields[i].Available Then Begin // karten die Früher schon ausgeschlossen wurden brauchen nicht mehr geprüft werden..
+ For j := 0 To high(List) Do Begin
+ // Use case-insensitive comparison for field names to handle Windows/Mac differences
+ // For cross-platform compatibility, accept fields if names match, even if hashes differ
+ // This handles cases where Windows and Mac have different file versions or hash calculation differences
+ If CompareText(fFields[i].Name, list[j].Name) = 0 Then Begin
+ If fFields[i].Hash = list[j].Hash Then Begin
+ // Perfect match - name and hash both match
+ found := true;
+ break;
+ End
+ Else Begin
+ // Name matches but hash differs - accept for cross-platform compatibility
+ // Log warning for debugging (commented out - too noisy in production)
+ // log(format('Field name match but hash mismatch (accepting for cross-platform): Server "%s" (hash: %d) vs Client "%s" (hash: %d)',
+ // [fFields[i].Name, fFields[i].Hash, list[j].Name, list[j].Hash]), llWarning);
+ found := true;
+ break;
+ End;
+ End;
+ End;
+ End;
+ If found Then Begin
+ m.WriteAnsiString(fFields[i].Name);
+ m.write(fFields[i].hash, sizeof(fFields[i].hash));
+ End
+ Else Begin
+ log(fFields[i].Name + ' will be disabled as it is not present on all game instances.', llWarning);
+ fFields[i].Available := false;
+ End;
+ End;
+ If SendToMaster Then Begin
+ SendChunk(miAvailableFieldList, m, fSettings.MasterUid);
+ End
+ Else Begin
+ // Send to all connected clients (not just master)
+ // This is needed when a new client connects and needs the field list
+ // Create a copy of the stream for each client since SendChunk takes ownership
+ For i := 0 To high(fUidInfos) Do Begin
+ m2 := TMemoryStream.Create;
+ m.Position := 0;
+ m2.CopyFrom(m, m.Size);
+ SendChunk(miAvailableFieldList, m2, fUidInfos[i].Uid);
+ End;
+ m.free;
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.CheckSynchrons;
+Var
+ n: int64;
+ i: integer;
+ b: Boolean;
+ s: String;
+ m: TMemoryStream;
+Begin
+ If fpausing Then exit;
+ n := GetTickCount64;
+ // versenden der HeartBeat Aufforderung an die Clients
+ If n - fLastHeartbeatTimestamp >= HeartBeatTime Then Begin
+ fLastHeartbeatTimestamp := n;
+ m := TMemoryStream.Create;
+ m.Write(n, SizeOf(n));
+ SendChunk(miHeartBeat, m, 0);
+ End;
+ // Prüfen der Empfangenen HeartBeat Aufforderungen
+ s := '';
+ b := false;
+ For i := 0 To high(fplayer) Do Begin
+ (*
+ * Nur die "Lebendigen" und nicht AI Spieler gehen in die Rechnung mit ein.
+ *)
+ If fplayer[i].Info.Alive And (fplayer[i].UID > 0) And (n - fplayer[i].LastSynchronTimeStamp > SynchonizeTimeOut) Then Begin
+ s := fplayer[i].UserName;
+ b := true;
+ break;
+ End;
+ End;
+ // Mindestens 1 Client ist asynchron, wir leiten eine Zwangspause ein / aus
+ If b Then Begin
+ If Not fSyncPause Then Begin // Positive Flanke der SyncPausierung
+ // Removed logging - was spamming logs on slow clients
+ fSyncPause := true;
+ ApplyPause(fpausing);
+ End;
+ End
+ Else Begin
+ If fSyncPause Then Begin // Negative Flanke der SyncPausierung
+ // Removed logging - was spamming logs
+ fSyncPause := false;
+ ApplyPause(fpausing);
+ End;
+ End;
+End;
+
+Procedure TServer.ApplyPause(Value: Boolean);
+Var
+ t: int64;
+ i: integer;
+Begin
+ value := value Or fSyncPause;
+ // fmap.Pause(Value);
+ // fSpawnModul.Pause(Value);
+ If Value Then Begin // Wir Starten die Pause
+ If Not foldpausevalue Then Begin
+ fPauseTimestamp := GetTickCount64;
+ End;
+ End
+ Else Begin //Wir Beenden die Pause, nun müssen alle Zeitbasen passend Verschoben werden
+ If foldpausevalue Then Begin
+ t := GetTickCount64() - fPauseTimestamp; // T = Zeit in ms wie lange die Pause gedauert hat
+ FLastFrameTimestamp := FLastFrameTimestamp + t;
+ fLastClientUpdateTimestamp := fLastClientUpdateTimestamp + t;
+ // fLastActiveTickTimestamp := fLastActiveTickTimestamp + t; -- Egal ob das gemacht wird oder nicht ..
+ (*
+ * Verschieben aller Zeitbasen für die Bandbreitenlimitierung
+ *)
+ fLastHeartbeatTimestamp := fLastHeartbeatTimestamp + t;
+ For i := 0 To high(fPLayer) Do Begin
+ fPLayer[i].LastSynchronTimeStamp := fPLayer[i].LastSynchronTimeStamp + t;
+ End;
+ // fFrameLog wird nicht gesetzt, läuft paralell weiter auch während einer Pause.
+ End;
+ End;
+ foldpausevalue := value;
+End;
+
+Procedure TServer.CreateNewFrame;
+Var
+ Alive: Array[0..1] Of Integer;
+ i, j: Integer;
+ aiInfo: TaiInfo;
+ AiCommand: TAiCommand;
+ OldCounter: UInt16;
+Begin
+ HandleStatisticCallback(sFramesRendered);
+ If fPlayingTimedesc <> -1000 Then Begin
+ fPlayingTimedesc := fPlayingTimedesc - FrameRate;
+ End;
+ fPlayingTimeasc := fPlayingTimeasc + FrameRate;
+ (*
+ * im Teamplay die Teamfarben anwählen, und der Blocker, dass das nicht andauernd gemacht wird
+ *)
+ If fSettings.TeamPlay And
+ (fPlayingTimeasc > AtomicTeamSwitchTime) And
+ (fPlayingTimeasc < AtomicTeamSwitchTime + 2 * FrameRate) Then Begin
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Team = TeamIndexWhite Then Begin
+ fPLayer[i].Info.ColorIndex := WhiteColorIndex;
+ End
+ Else Begin
+ fPLayer[i].Info.ColorIndex := RedColorIndex;
+ End;
+ End;
+ End;
+ If assigned(AiHandlePlayer) Then Begin
+ aiInfo := fActualField.GetAiInfo(fPLayer, fSettings.TeamPlay);
+ End;
+ // Die Spieler Bewegen
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
+ fPLayer[i].IdleTimer := fPLayer[i].IdleTimer + FrameRate; // Wir zählen den immer hoch, der läuft erst nach 41 Tagen über...
+ If fPLayer[i].UID = AIPlayer Then Begin
+ If assigned(AiHandlePlayer) Then Begin
+ // Removed debug logging - was causing stack overflow due to frequency
+ Try
+ AiCommand := AiHandlePlayer(i, aiInfo);
+ Except
+ On e: exception Do Begin
+ log('Ai raised an exception: ' + e.Message, llCritical);
+ End;
+ End;
+ Case AiCommand.MoveState Of
+ amNone: fPLayer[i].MoveState := msStill;
+ amLeft: fPLayer[i].MoveState := msLeft;
+ amRight: fPLayer[i].MoveState := msRight;
+ amUp: fPLayer[i].MoveState := msUp;
+ amDown: fPLayer[i].MoveState := msDown;
+ End;
+ Case AiCommand.Action Of
+ apNone: fPLayer[i].Action := aaNone;
+ apFirst: fPLayer[i].Action := aaFirst;
+ apFirstDouble: fPLayer[i].Action := aaFirstDouble;
+ apSecond: fPLayer[i].Action := aaSecond;
+ apSecondDouble: fPLayer[i].Action := aaSecondDouble;
+ End;
+ End;
+ End;
+ If fActualField.HandleMovePlayer(fPLayer, i, fSettings.ConveyorSpeed) Then Begin
+ // im Hurry mode kann der Spieler sterben, wenn ein Solid Brick an seiner Koordinate "entsteht"
+ fActualField.KillPlayer(fPLayer, i);
+ End;
+
+ (*
+ * Das "Krank" sein ;)
+ *)
+ If fPLayer[i].Disease <> [] Then Begin
+ (*
+ * Das Anstecken
+ *)
+ For j := 0 To high(fPLayer) Do Begin
+ If (i <> j) And
+ (LenV2SQR(fPLayer[i].Info.Position - fPLayer[j].Info.Position) <= 0.5 * 0.5) And
+ (fPLayer[i].Disease <> fPLayer[j].Disease) Then Begin
+ fPLayer[j].Disease := fPLayer[i].Disease;
+ fPLayer[j].DiseaseCounter := AtomicDiseaseTime;
+ End;
+ End;
+ (*
+ * Das Heilen
+ *)
+ fPLayer[i].DiseaseCounter := max(0, fPLayer[i].DiseaseCounter - FrameRate);
+ If fPLayer[i].DiseaseCounter = 0 Then Begin
+ If dSuperSlow In fPLayer[i].Disease Then Begin
+ fPLayer[i].Powers.Speed := fPLayer[i].BeforeSlowDiseaseSpeed;
+ End;
+ fPLayer[i].Disease := [];
+ End;
+ End;
+ End;
+ End;
+ // Aktions durchführen
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
+ If dEbola In fPLayer[i].Disease Then fPLayer[i].Action := aaFirst; // Wenn der Spieler "Ebola" hat, legt er wann immer möglich eine Bombe
+ // TODO: Feature oder Bug, wenn der Spieler Ebola hat und dNoBombs wird er hier verschont ...
+ If (fPLayer[i].Action <> aaNone) And (Not (dNoBombs In fPLayer[i].Disease)) Then Begin
+ fActualField.HandleActionPlayer(fPLayer[i], i);
+ fPLayer[i].Action := aaNone;
+ End;
+ End;
+ End;
+ // Bomben Handeln
+ // TODO: Magic Numbers -> entfernen klären ...
+ fActualField.HandleBombs(fPLayer, (fPlayingTimedesc <= 80000) And (fPlayingTimedesc <> -1000), fSettings.ConveyorSpeed);
+ // Kollision mit Flammen
+ fActualField.HandlePlayerVsMap(fPLayer, @HandlePlayerGetsPowerUp);
+
+ fActualField.HandleFieldAnims;
+
+ (* Das Sterben der Spieler Einleiten *)
+ Alive[0] := 0;
+ Alive[1] := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Info.Alive Then Begin // Hier darf Dieing nicht stehen, da es ja genau darum geht unten die Todeszeit ab zu prüfen !
+ (*
+ * Den Zähler lassen wir mal immer Zählen und damit nichts schief geht alle 1 min überlaufen, sollte er grad nicht gebraucht werden ...
+ * Jede Animation die den Counter Braucht setzt ihn beim Start auf 0 zurück, damit ist dann alles Save ;)
+ *)
+ OldCounter := fPLayer[i].Info.Counter;
+ fPLayer[i].Info.Counter := (fPLayer[i].Info.Counter + FrameRate) Mod 60000;
+ // Der Teleporter versetzt den Spieler genau 1 mal und zwar bei der Hälfte der Animationszeit
+ If (fPLayer[i].Info.Animation = raTeleport) And
+ (OldCounter < AtomicAnimationTimeTeleport Div 2) And
+ (fPLayer[i].Info.Counter >= AtomicAnimationTimeTeleport Div 2) Then Begin
+ fActualField.TelePortPlayer(fPLayer[i]);
+ End;
+ If fPLayer[i].Info.Dying Then Begin
+ If fPLayer[i].Info.Counter > AtomicDietimeout Then Begin
+ fPLayer[i].Info.Alive := false; // Wir sind gestorben und die Animation ist nun auch durch..
+ fPLayer[i].Info.Dying := false;
+ fActualField.RepopulatePlayersCollectedPowerUps(fPLayer, i);
+ End;
+ End
+ Else Begin
+ inc(alive[fPLayer[i].Team]);
+ End;
+ End
+ Else Begin
+ fPLayer[i].Info.Dying := false;
+ End;
+ End;
+ If fSettings.TeamPlay Then Begin
+ If (Alive[0] < 1) Or (Alive[1] < 1) Then Begin // Abschalten sobald das andere Team Platt gemacht wurde !
+ fActualField.DisableAllBombs;
+ End;
+ End
+ Else Begin
+ If Alive[0] + Alive[1] <= 1 Then Begin // Abschalten Aller Bomben sobald nur noch einer am Leben ist bzw noch nicht am Sterben ;)
+ fActualField.DisableAllBombs;
+ End;
+ End;
+ HurryHandling;
+ EndGameCheck();
+End;
+
+Procedure TServer.UpdateAllClients;
+Var
+ m: TMemoryStream;
+ i: Integer;
+ DiseasedInfo: TAtomicInfo;
+ StartTime: QWord;
+Begin
+ StartTime := GetTickCount64;
+ // Gesendet werden immer 3 Datensätze
+ m := TMemoryStream.Create;
+ // Die Rundenzeit mit übertragen
+ i := fPlayingTimedesc Div 1000;
+ m.write(i, sizeof(i));
+ // 1. Alles was die Spieler angeht
+ For i := 0 To high(fplayer) Do Begin
+ (*
+ * Der Spieler langweilt sich und wird nicht zufällig gerade gegrillt
+ *)
+ If (fPLayer[i].IdleTimer > AtomicIdleTimeout) And (fPLayer[i].Info.Animation <> raDie) And (fPLayer[i].Info.Animation <> raLockedIn) Then Begin
+ fPLayer[i].IdleTimer := 0;
+ fPLayer[i].Info.Animation := raZen;
+ fPLayer[i].Info.Counter := 0;
+ fPLayer[i].Info.Value := random(65536); // Eine Zufällige Zen Animation auswählen ;)
+ If fPLayer[i].UID > 0 Then HandlePlaySoundEffect(i, seZen); // Nur "echte" spieler kriegen den Ton
+ End;
+ (*
+ * Wenn der Spieler eine Krankheit hat, dann wechselt seine Farbe alle AtomicDiseaseColorChangeTime
+ *)
+ If (fPLayer[i].Disease <> []) And ((fPLayer[i].DiseaseCounter Mod AtomicDiseaseColorChangePeriodTime) < AtomicDiseaseColorChangePeriodTime - AtomicDiseaseColorChangePeriodRelaxTime) Then Begin
+ DiseasedInfo := fPLayer[i].Info;
+ DiseasedInfo.ColorIndex := (fPLayer[i].DiseaseCounter Div AtomicDiseaseColorChangeTime) Mod length(PlayerColors);
+ m.Write(DiseasedInfo, sizeof(DiseasedInfo));
+ End
+ Else Begin
+ m.Write(fPLayer[i].Info, sizeof(fPLayer[i].Info));
+ End;
+ // Der Client Wertet die Flanke der animation aus und hällt diese Selbst so lange wie er sie braucht
+ // d.h. Die Animation wird hier direkt wieder Platt gemacht.
+ If fPLayer[i].Info.Animation In OneTimeAnimations Then Begin
+ fPLayer[i].Info.Animation := raStandStill;
+ End;
+ End;
+ // 2. Alles was das zu Rendernde Feld angeht
+ fActualField.AppendGamingData(m);
+
+ // Removed performance logging - was causing log spam and potential stack overflow
+ SendChunk(miUpdateGameData, m, 0);
+End;
+
+Procedure TServer.SendPlayerStatistiks;
+Var
+ m: TMemoryStream;
+ i: Integer;
+Begin
+ log('TServer.SendPlayerStatistiks', lltrace);
+ m := TMemoryStream.Create;
+ For i := 0 To high(fPLayer) Do Begin
+ m.Write(fPLayer[i].Score, sizeof(fPLayer[i].Score));
+ m.Write(fPLayer[i].Kills, sizeof(fPLayer[i].Kills));
+ End;
+ SendChunk(miUpdatePlayerStatistik, m, 0);
+ LogLeave;
+End;
+
+Procedure TServer.EndGameCheck;
+Var
+ (*
+ Merken wem wir alles schon einen "Winner" gesendet haben
+ -> Das Verhindert, dass wenn 2 Spieler am Selben Rechner sitzen
+ diese den "GewinnerSound" doppelt hören.
+ *)
+ SoundSends: Array Of Integer;
+ Procedure SendWinner(uid, playerindex: integer);
+ Var
+ i: Integer;
+ Begin
+ For i := 0 To high(SoundSends) Do Begin
+ If SoundSends[i] = uid Then exit;
+ End;
+ setlength(SoundSends, high(SoundSends) + 2);
+ SoundSends[high(SoundSends)] := uid;
+ HandlePlaySoundEffect(playerindex, seWinner);
+ End;
+
+Var
+ WinnerTeamIndex, teamwhite, teamred, cnt, cntindex, i: Integer;
+ m: TMemoryStream;
+ v: TVictor;
+Begin
+ (*
+ * Bedingungen zum "Ende"
+ *)
+ // 1. Nur noch <=1 Spieler am Leben, oder im Team Modus nur noch 1 Team am Leben
+ teamwhite := 0;
+ teamred := 0;
+ cnt := 0;
+ cntindex := -1;
+ SoundSends := Nil;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Info.Alive Then Begin
+ inc(cnt);
+ cntindex := i;
+ If fPLayer[i].Team = TeamIndexWhite Then Begin
+ inc(teamwhite);
+ End
+ Else Begin
+ inc(teamred);
+ End;
+ End;
+ End;
+ If fSettings.TeamPlay Then Begin
+ // Nur noch 1 Team am Leben
+ If (teamwhite = 0) Or (teamred = 0) Then Begin
+ // Draw Game Check
+ // => Es kann passieren, dass das andere Team gerade am "Sterben" ist aber eben auch tot
+ // Aus diesem Grund muss hier noch mal extra geprüft werden ob die Gewinner Mannschaft
+ // auch wirklich am Leben ist..
+ WinnerTeamIndex := IfThen((teamred = 0), TeamIndexWhite, TeamIndexRed);
+ cnt := 0;
+ For i := 0 To high(fPLayer) Do Begin
+ If (fPLayer[i].Team = WinnerTeamIndex) And fPLayer[i].Info.Alive And (Not fPLayer[i].Info.Dying) Then Begin
+ inc(cnt);
+ End;
+ End;
+ If cnt <> 0 Then Begin // Wir haben wirklich einen Gewinner ;)
+ // Die Scores erhöhen
+ If teamred = 0 Then Begin // Team weis hat gewonnen
+ v := vWhiteTeam;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Team = 0 Then Begin
+ SendWinner(fPLayer[i].UID, i);
+ inc(fPLayer[i].Score);
+ End;
+ End;
+ End
+ Else Begin // Team 2 hat gewonnen
+ v := vRedTeam;
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Team = 1 Then Begin
+ SendWinner(fPLayer[i].UID, i);
+ inc(fPLayer[i].Score);
+ End;
+ End;
+ End;
+ SendPlayerStatistiks(); // Damit alle Clients auch die Richtigen Scores anzeigen diese nun Aktualisieren
+ m := TMemoryStream.Create;
+ m.Write(v, SizeOf(v));
+ SendChunk(miShowMatchStatistik, m, 0);
+ fGameState := gsShowHighscore;
+ End
+ Else Begin
+ // Draw Game, aber es laufen noch Todesanimationen,
+ // -> Damit der Code unten nicht direkt das DrawGame triggert mus cnt
+ // manipuliert werden ;)
+ For i := 0 To high(fPLayer) Do Begin
+ If (fPLayer[i].Team = WinnerTeamIndex) And (fPLayer[i].Info.Dying) Then Begin
+ cnt := 1; // Egal hauptsache <> 0
+ End;
+ End;
+ End;
+ End;
+ End
+ Else Begin
+ // Nur noch 1 Überlebender Spieler
+ If cnt = 1 Then Begin
+ // Dem Sieger den Punkt geben, aber nur, wenn er nicht auch gerade am sterben ist ..
+ // Wenn der Spieler Gestorben ist geht dann cnt von alleine Später auf 0 ;)
+ If Not fPLayer[cntindex].Info.Dying Then Begin
+ SendWinner(fPLayer[cntindex].UID, cntindex);
+ fPLayer[cntindex].Score := fPLayer[cntindex].Score + 1;
+ SendPlayerStatistiks(); // Damit alle Clients auch die Richtigen Scores anzeigen diese nun Aktualisieren
+ v := TVictor(integer(vCol0) + cntindex);
+ m := TMemoryStream.Create;
+ m.Write(v, SizeOf(v));
+ SendChunk(miShowMatchStatistik, m, 0);
+ fGameState := gsShowHighscore;
+ End;
+ End;
+ End;
+ // 2. Zeit abgelaufen (wenn Zeitlimit Aktiv)
+ If ((fPlayingTimedesc <> -1000) And (fPlayingTimedesc <= 0)) Or (cnt = 0) Then Begin
+ (*
+ * Nachdem auf Jedenfall oben niemand gewonnen hat ist nun schluss mittels draw
+ *)
+ SendChunk(miDrawGame, Nil, 0);
+ fGameState := gsShowHighscore;
+ End;
+End;
+
+Function TServer.MatchFinished: Boolean;
+Var
+ i: Integer;
+Begin
+ result := false;
+ (*
+ * Hat wenigstens 1 Spieler die Notwendige Anzahl an Runden gewonnen ?
+ * Hier ist es tatsächlich egal ob Teamplay oder nicht, da beim Teamplay
+ * ja jeder im Team einen Score bekommt ;)
+ *)
+ For i := 0 To high(fPLayer) Do Begin
+ If fPLayer[i].Score >= fSettings.LastWinsToWinMatch Then Begin
+ result := true;
+ break;
+ End;
+ End;
+End;
+
+Procedure TServer.LoadAi;
+Begin
+ log('TServer.LoadAi', lltrace);
+ If Not LoadAiLib() Then Begin
+ logshow('Could not load ai, ai functions are not available.', llError);
+ LogLeave;
+ exit;
+ End;
+ If AiInit() Then Begin
+ logshow(format('Ai "%s" loaded successfully!', [AiVersion()]), llInfo);
+ End
+ Else Begin
+ logshow('Failure on Ai load (AiInit returned false).', llError);
+ UnLoadAiLib;
+ End;
+ If fGameState = gsPlaying Then Begin
+ // TODO: Diese 100% müssen noch einstellbar gemacht werden !
+ AiNewRound(100);
+ End;
+ LogLeave;
+End;
+
+Procedure TServer.HurryHandling;
+Begin
+ If fPlayingTimedesc = -1000 Then exit; // Nicht im Infinity Mode
+ If Not fActualField.BombsEnabled Then exit; // Es gibt wohl keine Spieler mehr auf der Karte -> kein Hurry mehr ;)
+ If fPlayingTimedesc = 85000 Then Begin
+ SendChunk(miShowHurry, Nil, 0);
+ End;
+ If fPlayingTimedesc <= 80000 Then Begin
+ If fPlayingTimedesc Mod 500 = 0 Then Begin
+ fActualField.IncHurry();
+ HandlePlaySoundEffect(0, seHurryBrick);
+ End;
+ End;
+End;
+
+Procedure TServer.Execute;
+Var
+ n: QWord;
+Begin
+ log('TServer.Execute', lltrace);
+ // Loop in einer Endlosschleife, so lange bis 1000ms lang kein Client mehr connected ist, dann raus
+ While factive Do Begin
+ // Process incoming network chunks from network thread
+ fChunkManager.ProcessIncomingChunks();
+ fUDP.CallAction();
+ If fKickAllPlayer Then Begin
+ log('KickAllPlayer', lltrace);
+ fKickAllPlayer := false;
+ HandleSwitchToWaitForPlayersToConnect();
+ LogLeave;
+ End;
+ If fGameState = gsPlaying Then Begin // Im Spielmodus Frames und Updates der Clients Berechnen
+ // alle 10 s Loggen wie Groß die Spieldaten waren, welche gesandt
+ n := GetTickCount64();
+ If fFrameLog.TimeStamp + 10000 <= n Then Begin
+ fFrameLog.TimeStamp := n;
+ If fFrameLog.Count <> 0 Then Begin
+ log(Format('Send %d frames with avg size of %.1f Bytes.', [fFrameLog.Count, fFrameLog.AccumulatedSize / fFrameLog.Count]), lldebug);
+ End
+ Else Begin
+ log('Send 0 frames.', lldebug);
+ End;
+ fFrameLog.Count := 0;
+ fFrameLog.AccumulatedSize := 0;
+ End;
+ CheckSynchrons; //Sind alle Player noch Synchron, wenn nein Warten
+ // If fpausing Then Begin // Zählen der Pausenzeit
+ // n := GetTickCount64;
+ // If n <> pt Then Begin
+ // fOverAllPausingTime := fOverAllPausingTime + n - pt;
+ // pt := n;
+ // End;
+ // End
+ // Else Begin
+ // pt := GetTickCount64;
+ // End;
+ If (Not (fpausing Or fSyncPause)) Then Begin
+ n := GetTickCount64();
+ If FLastFrameTimestamp + FrameRate <= n Then Begin
+ // Durch das Aufaddieren der Zeit und nicht direkt setzen auf n könnte hier eine
+ // Überpropertionale rechenlast erzeugt werden, besonders, wenn CreateNewFrame, länger dauert als (FrameRate Div Speedup)
+{$IFDEF Release}
+ FLastFrameTimestamp := FLastFrameTimestamp + FrameRate;
+{$ELSE}
+ // Sonst scrollt die Zeit ewig weiter, wenn man mim Debugger die Zeit anhällt
+ FLastFrameTimestamp := n;
+{$ENDIF}
+ CreateNewFrame;
+ End;
+ // Egal, welcher Speedup, das Spiel wird mit konstanter Rate Aktualisiert
+ If fLastClientUpdateTimestamp + UpdateRate <= n Then Begin
+ fLastClientUpdateTimestamp := n; // fLastClientUpdateTimestamp + UpdateRate; Verhindern von oben beschriebener Situation
+ // Only send updates if there are connected clients
+ If GetActivePlayerCount() > 0 Then Begin
+ UpdateAllClients;
+ End;
+ End;
+ End;
+ End;
+ (*
+ * Ab hier geht es nur noch darum zu erkennen ob die Anwendung beendet werden
+ * soll.
+ *)
+ If KeyPressed Then Begin
+ Case ReadKey() Of
+ #27: Begin
+ Log('Close by user input.', llInfo);
+ factive := false;
+ End;
+ 'a', 'A': Begin
+ LoadAi;
+ End;
+ 'u', 'U': Begin
+ UnLoadAiLib;
+ LogShow('Disabled ai', llInfo);
+ End;
+ End;
+ End;
+ // Beenden Bedingung erkennen
+ If GetActivePlayerCount() <> 0 Then Begin
+ fLastActiveTickTimestamp := GetTickCount64();
+ End
+ Else Begin
+ // fAutotimeout ms lang keine Activen Clients, dieser Server kann geschlossen werden
+ If (fAutotimeout <> 0) Then Begin
+ If (fLastActiveTickTimestamp + fAutotimeout < GetTickCount64()) Then Begin
+ factive := false;
+ End;
+ End;
+ {
+ // Zwangsabbruch, weil der Server sich selbst geschlossen hat
+ If Not fChunkManager.Connected Then Begin
+ log('Chunkmanager lost connection.', llfatal);
+ factive := false;
+ End;
+ }
+ End;
+ If fGameState = gsPlaying Then Begin
+{$IFDEF Windows}
+ sleep(0);
+{$ELSE}
+ sleep(1);
+{$ENDIF}
+ End
+ Else Begin
+ sleep(1);
+ End;
+ End;
+ LogLeave;
+End;
+
+Function TServer.GetStatsFilePath: String;
+{$IFDEF DARWIN}
+Var
+ ConfigDir: String;
+Begin
+ // On macOS, use Application Support directory like client does
+ ConfigDir := IncludeTrailingPathDelimiter(GetUserDir) + 'Library/Application Support/fpc_atomic/';
+ If Not ForceDirectoriesUTF8(ConfigDir) Then
+ ConfigDir := IncludeTrailingPathDelimiter(GetAppConfigDirUTF8(False));
+ Result := ConfigDir + 'stats.txt';
+End;
+{$ELSE}
+Begin
+ // On Windows and Linux, use directory where executable is located
+ Result := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'stats.txt';
+End;
+{$ENDIF}
+
+Procedure TServer.LoadStatistiks;
+Var
+ ini: TIniFile;
+Begin
+ ini := TIniFile.Create(Self.GetStatsFilePath);
+ fStatistik.Total[sMatchesStarted] := ini.ReadInt64('Total', 'MatchesStarted', 0);
+ fStatistik.Total[sGamesStarted] := ini.ReadInt64('Total', 'GamesStarted', 0);
+ fStatistik.Total[sFramesRendered] := ini.ReadInt64('Total', 'FramesRendered', 0);
+ fStatistik.Total[sBombsDropped] := ini.ReadInt64('Total', 'BombsDropped', 0);
+ fStatistik.Total[sPowerupsCollected] := ini.ReadInt64('Total', 'PowerupsCollected', 0);
+ fStatistik.Total[sPlayerDeaths] := ini.ReadInt64('Total', 'PlayerDeaths', 0);
+ fStatistik.Total[sBricksDestroyed] := ini.ReadInt64('Total', 'BricksDestroyed', 0);
+ fStatistik.Total[sPowerUpDestroyed] := ini.ReadInt64('Total', 'PowerUpDestroyed', 0);
+ fStatistik.Total[sTotalNetworkBytesIn] := ini.ReadInt64('Total', 'TotalNetworkBytesIn', 0);
+ fStatistik.Total[sTotalNetworkBytesOut] := ini.ReadInt64('Total', 'TotalNetworkBytesOut', 0);
+ fStatistik.Total[sTotalNetworkPacketsIn] := ini.ReadInt64('Total', 'TotalNetworkPacketsIn', 0);
+ fStatistik.Total[sTotalNetworkPacketsOut] := ini.ReadInt64('Total', 'TotalNetworkPacketsOut', 0);
+
+ (*
+ * Alles Aktuelle = 0 ;)
+ *)
+ FillChar(fStatistik.LastRun, sizeof(fStatistik.LastRun), 0);
+ ini.free;
+End;
+
+Procedure TServer.SaveStatistiks;
+Var
+ ini: TIniFile;
+Begin
+ ini := TIniFile.Create(Self.GetStatsFilePath);
+ Try
+ ini.writeInt64('Total', 'MatchesStarted', fStatistik.Total[sMatchesStarted] + fStatistik.LastRun[sMatchesStarted]);
+ ini.writeInt64('Total', 'GamesStarted', fStatistik.Total[sGamesStarted] + fStatistik.LastRun[sGamesStarted]);
+ ini.writeInt64('Total', 'FramesRendered', fStatistik.Total[sFramesRendered] + fStatistik.LastRun[sFramesRendered]);
+ ini.writeInt64('Total', 'BombsDropped', fStatistik.Total[sBombsDropped] + fStatistik.LastRun[sBombsDropped]);
+ ini.writeInt64('Total', 'PowerupsCollected', fStatistik.Total[sPowerupsCollected] + fStatistik.LastRun[sPowerupsCollected]);
+ ini.writeInt64('Total', 'PlayerDeaths', fStatistik.Total[sPlayerDeaths] + fStatistik.LastRun[sPlayerDeaths]);
+ ini.writeInt64('Total', 'BricksDestroyed', fStatistik.Total[sBricksDestroyed] + fStatistik.LastRun[sBricksDestroyed]);
+ ini.writeInt64('Total', 'PowerUpDestroyed', fStatistik.Total[sPowerUpDestroyed] + fStatistik.LastRun[sPowerUpDestroyed]);
+ ini.writeInt64('Total', 'TotalNetworkBytesIn', fStatistik.Total[sTotalNetworkBytesIn] + fStatistik.LastRun[sTotalNetworkBytesIn]);
+ ini.writeInt64('Total', 'TotalNetworkBytesOut', fStatistik.Total[sTotalNetworkBytesOut] + fStatistik.LastRun[sTotalNetworkBytesOut]);
+ ini.writeInt64('Total', 'TotalNetworkPacketsIn', fStatistik.Total[sTotalNetworkPacketsIn] + fStatistik.LastRun[sTotalNetworkPacketsIn]);
+ ini.writeInt64('Total', 'TotalNetworkPacketsOut', fStatistik.Total[sTotalNetworkPacketsOut] + fStatistik.LastRun[sTotalNetworkPacketsOut]);
+
+ ini.writeInt64('LastRun', 'MatchesStarted', fStatistik.LastRun[sMatchesStarted]);
+ ini.writeInt64('LastRun', 'GamesStarted', fStatistik.LastRun[sGamesStarted]);
+ ini.writeInt64('LastRun', 'FramesRendered', fStatistik.LastRun[sFramesRendered]);
+ ini.writeInt64('LastRun', 'BombsDropped', fStatistik.LastRun[sBombsDropped]);
+ ini.writeInt64('LastRun', 'PowerupsCollected', fStatistik.LastRun[sPowerupsCollected]);
+ ini.writeInt64('LastRun', 'PlayerDeaths', fStatistik.LastRun[sPlayerDeaths]);
+ ini.writeInt64('LastRun', 'BricksDestroyed', fStatistik.LastRun[sBricksDestroyed]);
+ ini.writeInt64('LastRun', 'PowerUpDestroyed', fStatistik.LastRun[sPowerUpDestroyed]);
+ ini.writeInt64('LastRun', 'TotalNetworkBytesIn', fStatistik.LastRun[sTotalNetworkBytesIn]);
+ ini.writeInt64('LastRun', 'TotalNetworkBytesOut', fStatistik.LastRun[sTotalNetworkBytesOut]);
+ ini.writeInt64('LastRun', 'TotalNetworkPacketsIn', fStatistik.LastRun[sTotalNetworkPacketsIn]);
+ ini.writeInt64('LastRun', 'TotalNetworkPacketsOut', fStatistik.LastRun[sTotalNetworkPacketsOut]);
+ Finally
+ ini.free;
+ End;
+End;
+
+End.
+
diff --git a/symbol_order.fpc b/symbol_order.fpc
new file mode 100644
index 0000000..1d35f7e
--- /dev/null
+++ b/symbol_order.fpc
@@ -0,0 +1,1124 @@
+_RESSTR_$INIFILES_$$_START
+_RESSTR_$INIFILES_$$_SERRCOULDNOTCREATEPATH
+_RESSTR_$INIFILES_$$_END
+_RESSTR_$MATH_$$_START
+_RESSTR_$MATH_$$_SMATHERROR
+_RESSTR_$MATH_$$_SINVALIDARGUMENT
+_RESSTR_$MATH_$$_END
+_RESSTR_$SYSCONST_$$_START
+_RESSTR_$SYSCONST_$$_SLISTINDEXERROR
+_RESSTR_$SYSCONST_$$_SPARAMISNEGATIVE
+_RESSTR_$SYSCONST_$$_SLISTCAPACITYERROR
+_RESSTR_$SYSCONST_$$_SABORTERROR
+_RESSTR_$SYSCONST_$$_SABSTRACTERROR
+_RESSTR_$SYSCONST_$$_SACCESSDENIED
+_RESSTR_$SYSCONST_$$_SACCESSVIOLATION
+_RESSTR_$SYSCONST_$$_SARGUMENTMISSING
+_RESSTR_$SYSCONST_$$_SASSERTERROR
+_RESSTR_$SYSCONST_$$_SASSERTIONFAILED
+_RESSTR_$SYSCONST_$$_SBUSERROR
+_RESSTR_$SYSCONST_$$_SCANNOTCREATEEMPTYDIR
+_RESSTR_$SYSCONST_$$_SCONTROLC
+_RESSTR_$SYSCONST_$$_SDISKFULL
+_RESSTR_$SYSCONST_$$_SDISPATCHERROR
+_RESSTR_$SYSCONST_$$_SDIVBYZERO
+_RESSTR_$SYSCONST_$$_SENDOFFILE
+_RESSTR_$SYSCONST_$$_SERRINVALIDDATEMONTHWEEK
+_RESSTR_$SYSCONST_$$_SERRINVALIDHOURMINUTESECMSEC
+_RESSTR_$SYSCONST_$$_SERRINVALIDDATEWEEK
+_RESSTR_$SYSCONST_$$_SERRINVALIDDAYOFWEEK
+_RESSTR_$SYSCONST_$$_SERRINVALIDDAYOFWEEKINMONTH
+_RESSTR_$SYSCONST_$$_SERRINVALIDDAYOFYEAR
+_RESSTR_$SYSCONST_$$_SERRINVALIDTIMESTAMP
+_RESSTR_$SYSCONST_$$_SINVALIDJULIANDATE
+_RESSTR_$SYSCONST_$$_SERRILLEGALDATEFORMATSTRING
+_RESSTR_$SYSCONST_$$_SERRINVALIDTIMEFORMAT
+_RESSTR_$SYSCONST_$$_SEXCEPTIONERRORMESSAGE
+_RESSTR_$SYSCONST_$$_SEXCEPTIONSTACK
+_RESSTR_$SYSCONST_$$_SEXECUTEPROCESSFAILED
+_RESSTR_$SYSCONST_$$_SEXTERNALEXCEPTION
+_RESSTR_$SYSCONST_$$_SFILENOTASSIGNED
+_RESSTR_$SYSCONST_$$_SFILENOTFOUND
+_RESSTR_$SYSCONST_$$_SFILENOTOPEN
+_RESSTR_$SYSCONST_$$_SFILENOTOPENFORINPUT
+_RESSTR_$SYSCONST_$$_SFILENOTOPENFOROUTPUT
+_RESSTR_$SYSCONST_$$_SINVALIDFILENAME
+_RESSTR_$SYSCONST_$$_SINTOVERFLOW
+_RESSTR_$SYSCONST_$$_SINTFCASTERROR
+_RESSTR_$SYSCONST_$$_SINVALIDARGINDEX
+_RESSTR_$SYSCONST_$$_SINVALIDBCD
+_RESSTR_$SYSCONST_$$_SINVALIDBOOLEAN
+_RESSTR_$SYSCONST_$$_SINVALIDCAST
+_RESSTR_$SYSCONST_$$_SINVALIDCURRENCY
+_RESSTR_$SYSCONST_$$_SINVALIDDATETIME
+_RESSTR_$SYSCONST_$$_SINVALIDDATETIMEFLOAT
+_RESSTR_$SYSCONST_$$_SINVALIDDRIVE
+_RESSTR_$SYSCONST_$$_SINVALIDFILEHANDLE
+_RESSTR_$SYSCONST_$$_SINVALIDFLOAT
+_RESSTR_$SYSCONST_$$_SINVALIDFORMAT
+_RESSTR_$SYSCONST_$$_SINVALIDGUID
+_RESSTR_$SYSCONST_$$_SINVALIDINPUT
+_RESSTR_$SYSCONST_$$_SINVALIDINTEGER
+_RESSTR_$SYSCONST_$$_SINVALIDOP
+_RESSTR_$SYSCONST_$$_SINVALIDPOINTER
+_RESSTR_$SYSCONST_$$_SINVALIDVARCAST
+_RESSTR_$SYSCONST_$$_SINVALIDVARNULLOP
+_RESSTR_$SYSCONST_$$_SINVALIDVAROP
+_RESSTR_$SYSCONST_$$_SINVALIDBINARYVAROP
+_RESSTR_$SYSCONST_$$_SINVALIDUNARYVAROP
+_RESSTR_$SYSCONST_$$_SINVALIDVAROPWITHHRESULTWITHPREFIX
+_RESSTR_$SYSCONST_$$_SNOERROR
+_RESSTR_$SYSCONST_$$_SNOTHREADSUPPORT
+_RESSTR_$SYSCONST_$$_SNODYNLIBSSUPPORT
+_RESSTR_$SYSCONST_$$_SMISSINGWSTRINGMANAGER
+_RESSTR_$SYSCONST_$$_SSIGQUIT
+_RESSTR_$SYSCONST_$$_SOBJECTCHECKERROR
+_RESSTR_$SYSCONST_$$_SOSERROR
+_RESSTR_$SYSCONST_$$_SOUTOFMEMORY
+_RESSTR_$SYSCONST_$$_SOVERFLOW
+_RESSTR_$SYSCONST_$$_SPRIVILEGE
+_RESSTR_$SYSCONST_$$_SRANGEERROR
+_RESSTR_$SYSCONST_$$_SSTACKOVERFLOW
+_RESSTR_$SYSCONST_$$_SSAFECALLEXCEPTION
+_RESSTR_$SYSCONST_$$_SICONVERROR
+_RESSTR_$SYSCONST_$$_STHREADERROR
+_RESSTR_$SYSCONST_$$_STOOMANYOPENFILES
+_RESSTR_$SYSCONST_$$_SUNKNOWNRUNTIMEERROR
+_RESSTR_$SYSCONST_$$_SUNDERFLOW
+_RESSTR_$SYSCONST_$$_SUNKOSERROR
+_RESSTR_$SYSCONST_$$_SUNKNOWN
+_RESSTR_$SYSCONST_$$_SUNKNOWNERRORCODE
+_RESSTR_$SYSCONST_$$_SVARARRAYBOUNDS
+_RESSTR_$SYSCONST_$$_SVARARRAYCREATE
+_RESSTR_$SYSCONST_$$_SVARARRAYLOCKED
+_RESSTR_$SYSCONST_$$_SVARBADTYPE
+_RESSTR_$SYSCONST_$$_SVARINVALID
+_RESSTR_$SYSCONST_$$_SVARINVALID1
+_RESSTR_$SYSCONST_$$_SVARNOTARRAY
+_RESSTR_$SYSCONST_$$_SVARNOTIMPLEMENTED
+_RESSTR_$SYSCONST_$$_SVAROUTOFMEMORY
+_RESSTR_$SYSCONST_$$_SVAROVERFLOW
+_RESSTR_$SYSCONST_$$_SVARPARAMNOTFOUND
+_RESSTR_$SYSCONST_$$_SVARTYPEALREADYUSEDWITHPREFIX
+_RESSTR_$SYSCONST_$$_SVARTYPECONVERTOVERFLOW
+_RESSTR_$SYSCONST_$$_SVARTYPECOULDNOTCONVERT
+_RESSTR_$SYSCONST_$$_SVARTYPENOTUSABLEWITHPREFIX
+_RESSTR_$SYSCONST_$$_SVARTYPEOUTOFRANGEWITHPREFIX
+_RESSTR_$SYSCONST_$$_SVARTYPERANGECHECK1
+_RESSTR_$SYSCONST_$$_SVARTYPERANGECHECK2
+_RESSTR_$SYSCONST_$$_SVARTYPETOOMANYCUSTOM
+_RESSTR_$SYSCONST_$$_SVARUNEXPECTED
+_RESSTR_$SYSCONST_$$_SZERODIVIDE
+_RESSTR_$SYSCONST_$$_SFALLBACKERROR
+_RESSTR_$SYSCONST_$$_SNOTOOLSERVER
+_RESSTR_$SYSCONST_$$_SNOTVALIDCODEPAGENAME
+_RESSTR_$SYSCONST_$$_SINVALIDCOUNT
+_RESSTR_$SYSCONST_$$_SCHARACTERINDEXOUTOFBOUNDS
+_RESSTR_$SYSCONST_$$_SINVALIDDESTINATIONARRAY
+_RESSTR_$SYSCONST_$$_SINVALIDDESTINATIONINDEX
+_RESSTR_$SYSCONST_$$_SNOARRAYMATCH
+_RESSTR_$SYSCONST_$$_SNOCHARMATCH
+_RESSTR_$SYSCONST_$$_SHHMMERROR
+_RESSTR_$SYSCONST_$$_SFULLPATTERN
+_RESSTR_$SYSCONST_$$_SPATTERNCHARMISMATCH
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEJAN
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEFEB
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEMAR
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEAPR
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEMAY
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEJUN
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEJUL
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEAUG
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMESEP
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEOCT
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMENOV
+_RESSTR_$SYSCONST_$$_SSHORTMONTHNAMEDEC
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEJAN
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEFEB
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEMAR
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEAPR
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEMAY
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEJUN
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEJUL
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEAUG
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMESEP
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEOCT
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMENOV
+_RESSTR_$SYSCONST_$$_SLONGMONTHNAMEDEC
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMEMON
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMETUE
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMEWED
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMETHU
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMEFRI
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMESAT
+_RESSTR_$SYSCONST_$$_SSHORTDAYNAMESUN
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMEMON
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMETUE
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMEWED
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMETHU
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMEFRI
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMESAT
+_RESSTR_$SYSCONST_$$_SLONGDAYNAMESUN
+_RESSTR_$SYSCONST_$$_END
+_RESSTR_$TYPINFO_$$_START
+_RESSTR_$TYPINFO_$$_SERRNOTANENUMERATED
+_RESSTR_$TYPINFO_$$_SERRINVALIDENUMERATEDCOUNT
+_RESSTR_$TYPINFO_$$_SERRDUPLICATEENUMERATED
+_RESSTR_$TYPINFO_$$_END
+_RESSTR_$RTLCONSTS_$$_START
+_RESSTR_$RTLCONSTS_$$_HNOCONTEXT
+_RESSTR_$RTLCONSTS_$$_HNOSYSTEM
+_RESSTR_$RTLCONSTS_$$_HNOTABLEOFCONTENTS
+_RESSTR_$RTLCONSTS_$$_HNOTHINGFOUND
+_RESSTR_$RTLCONSTS_$$_HNOTOPICS
+_RESSTR_$RTLCONSTS_$$_SABORTBUTTON
+_RESSTR_$RTLCONSTS_$$_SALLBUTTON
+_RESSTR_$RTLCONSTS_$$_SALLFILTER
+_RESSTR_$RTLCONSTS_$$_SANCESTORNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SASSIGNERROR
+_RESSTR_$RTLCONSTS_$$_SASYNCSOCKETERROR
+_RESSTR_$RTLCONSTS_$$_SBG
+_RESSTR_$RTLCONSTS_$$_SBITMAPEMPTY
+_RESSTR_$RTLCONSTS_$$_SBITSINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SBOLDFONT
+_RESSTR_$RTLCONSTS_$$_SBOLDITALICFONT
+_RESSTR_$RTLCONSTS_$$_SBUCKETLISTLOCKED
+_RESSTR_$RTLCONSTS_$$_SCANCELBUTTON
+_RESSTR_$RTLCONSTS_$$_SCANNOTCREATEDIR
+_RESSTR_$RTLCONSTS_$$_SCANNOTCREATENAME
+_RESSTR_$RTLCONSTS_$$_SCANNOTCREATESOCKET
+_RESSTR_$RTLCONSTS_$$_SCANNOTDRAGFORM
+_RESSTR_$RTLCONSTS_$$_SCANNOTFOCUS
+_RESSTR_$RTLCONSTS_$$_SCANNOTLISTENONOPEN
+_RESSTR_$RTLCONSTS_$$_SCANNOTOPENAVI
+_RESSTR_$RTLCONSTS_$$_SCANNOTSHOWMODAL
+_RESSTR_$RTLCONSTS_$$_SCANTCHANGEWHILEACTIVE
+_RESSTR_$RTLCONSTS_$$_SCANTWRITERESOURCESTREAMERROR
+_RESSTR_$RTLCONSTS_$$_SCARDDLLNOTLOADED
+_RESSTR_$RTLCONSTS_$$_SLIBRARYALREADYLOADED
+_RESSTR_$RTLCONSTS_$$_SLIBRARYNOTLOADED
+_RESSTR_$RTLCONSTS_$$_SLIBRARYUNKNOWNSYM
+_RESSTR_$RTLCONSTS_$$_SCHANGEICONSIZE
+_RESSTR_$RTLCONSTS_$$_SCHAREXPECTED
+_RESSTR_$RTLCONSTS_$$_SCHECKSYNCHRONIZEERROR
+_RESSTR_$RTLCONSTS_$$_SCLASSMISMATCH
+_RESSTR_$RTLCONSTS_$$_SCLASSNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SCLIENTNOTSET
+_RESSTR_$RTLCONSTS_$$_SCLOSEBUTTON
+_RESSTR_$RTLCONSTS_$$_SCMPLXCOULDNOTPARSEIMAGINARY
+_RESSTR_$RTLCONSTS_$$_SCMPLXCOULDNOTPARSEPLUS
+_RESSTR_$RTLCONSTS_$$_SCMPLXCOULDNOTPARSEREAL
+_RESSTR_$RTLCONSTS_$$_SCMPLXCOULDNOTPARSESYMBOL
+_RESSTR_$RTLCONSTS_$$_SCMPLXERRORSUFFIX
+_RESSTR_$RTLCONSTS_$$_SCMPLXUNEXPECTEDCHARS
+_RESSTR_$RTLCONSTS_$$_SCMPLXUNEXPECTEDEOS
+_RESSTR_$RTLCONSTS_$$_SCOLORPREFIX
+_RESSTR_$RTLCONSTS_$$_SCOLORTAGS
+_RESSTR_$RTLCONSTS_$$_SCOMPONENTDOESNTIMPLEMENT
+_RESSTR_$RTLCONSTS_$$_SCOMPONENTNAMETOOLONG
+_RESSTR_$RTLCONSTS_$$_SCONFIRMCREATEDIR
+_RESSTR_$RTLCONSTS_$$_SCONTROLPARENTSETTOSELF
+_RESSTR_$RTLCONSTS_$$_SCONVDUPLICATEFAMILY
+_RESSTR_$RTLCONSTS_$$_SCONVDUPLICATETYPE
+_RESSTR_$RTLCONSTS_$$_SCONVFACTORZERO
+_RESSTR_$RTLCONSTS_$$_SCONVILLEGALFAMILY
+_RESSTR_$RTLCONSTS_$$_SCONVILLEGALTYPE
+_RESSTR_$RTLCONSTS_$$_SCONVINCOMPATIBLETYPES2
+_RESSTR_$RTLCONSTS_$$_SCONVINCOMPATIBLETYPES3
+_RESSTR_$RTLCONSTS_$$_SCONVINCOMPATIBLETYPES4
+_RESSTR_$RTLCONSTS_$$_SCONVSTRPARSEERROR
+_RESSTR_$RTLCONSTS_$$_SCONVUNKNOWNDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCONVUNKNOWNDESCRIPTIONWITHPREFIX
+_RESSTR_$RTLCONSTS_$$_SCONVUNKNOWNFAMILY
+_RESSTR_$RTLCONSTS_$$_SCONVUNKNOWNTYPE
+_RESSTR_$RTLCONSTS_$$_SCUSTOMCOLORS
+_RESSTR_$RTLCONSTS_$$_SDATEENCODEERROR
+_RESSTR_$RTLCONSTS_$$_SDDECONVERR
+_RESSTR_$RTLCONSTS_$$_SDDEERR
+_RESSTR_$RTLCONSTS_$$_SDDEMEMERR
+_RESSTR_$RTLCONSTS_$$_SDDENOCONNECT
+_RESSTR_$RTLCONSTS_$$_SDEFAULT
+_RESSTR_$RTLCONSTS_$$_SDEFAULTFILTER
+_RESSTR_$RTLCONSTS_$$_SDELIMITERQUOTECHARERROR
+_RESSTR_$RTLCONSTS_$$_SDEVICEONPORT
+_RESSTR_$RTLCONSTS_$$_SDIMSDONOTMATCH
+_RESSTR_$RTLCONSTS_$$_SDIRNAMECAP
+_RESSTR_$RTLCONSTS_$$_SDIRSCAP
+_RESSTR_$RTLCONSTS_$$_SDRIVESCAP
+_RESSTR_$RTLCONSTS_$$_SDUPLICATECARDID
+_RESSTR_$RTLCONSTS_$$_SDUPLICATECLASS
+_RESSTR_$RTLCONSTS_$$_SDUPLICATEITEM
+_RESSTR_$RTLCONSTS_$$_SDUPLICATEMENUS
+_RESSTR_$RTLCONSTS_$$_SDUPLICATENAME
+_RESSTR_$RTLCONSTS_$$_SDUPLICATEREFERENCE
+_RESSTR_$RTLCONSTS_$$_SDUPLICATESTRING
+_RESSTR_$RTLCONSTS_$$_SEMPTYSTREAMILLEGALREADER
+_RESSTR_$RTLCONSTS_$$_SEMPTYSTREAMILLEGALWRITER
+_RESSTR_$RTLCONSTS_$$_SERRINDEXTOOLARGE
+_RESSTR_$RTLCONSTS_$$_SERRINVALIDBITINDEX
+_RESSTR_$RTLCONSTS_$$_SERRNOSTREAMING
+_RESSTR_$RTLCONSTS_$$_SERRNOVARIANTSUPPORT
+_RESSTR_$RTLCONSTS_$$_SERROUTOFMEMORY
+_RESSTR_$RTLCONSTS_$$_SERRNOTOBSERVER
+_RESSTR_$RTLCONSTS_$$_SERRPROPERTYNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SERRINVALIDPROPERTYTYPE
+_RESSTR_$RTLCONSTS_$$_SERRUNKNOWNENUMVALUE
+_RESSTR_$RTLCONSTS_$$_SFAILEDTOCALLCONSTRUCTOR
+_RESSTR_$RTLCONSTS_$$_SFB
+_RESSTR_$RTLCONSTS_$$_SFCREATEERROR
+_RESSTR_$RTLCONSTS_$$_SFCREATEERROREX
+_RESSTR_$RTLCONSTS_$$_SFG
+_RESSTR_$RTLCONSTS_$$_SFILESCAP
+_RESSTR_$RTLCONSTS_$$_SFIXEDCOLTOOBIG
+_RESSTR_$RTLCONSTS_$$_SFIXEDROWTOOBIG
+_RESSTR_$RTLCONSTS_$$_SFOPENERROR
+_RESSTR_$RTLCONSTS_$$_SFOPENERROREX
+_RESSTR_$RTLCONSTS_$$_SGRIDTOOLARGE
+_RESSTR_$RTLCONSTS_$$_SGROUPINDEXTOOLOW
+_RESSTR_$RTLCONSTS_$$_SHELPBUTTON
+_RESSTR_$RTLCONSTS_$$_SICONTOCLIPBOARD
+_RESSTR_$RTLCONSTS_$$_SIDENTIFIEREXPECTED
+_RESSTR_$RTLCONSTS_$$_SIGNOREBUTTON
+_RESSTR_$RTLCONSTS_$$_SIMAGECANVASNEEDSBITMAP
+_RESSTR_$RTLCONSTS_$$_SIMAGEINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SIMAGEREADFAIL
+_RESSTR_$RTLCONSTS_$$_SIMAGEWRITEFAIL
+_RESSTR_$RTLCONSTS_$$_SINDEXOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SPARAMISNIL
+_RESSTR_$RTLCONSTS_$$_SINIFILEWRITEERROR
+_RESSTR_$RTLCONSTS_$$_SINSERTLINEERROR
+_RESSTR_$RTLCONSTS_$$_SINTERFACENOIIDSTR
+_RESSTR_$RTLCONSTS_$$_SINVALIDACTIONCREATION
+_RESSTR_$RTLCONSTS_$$_SINVALIDACTIONENUMERATION
+_RESSTR_$RTLCONSTS_$$_SINVALIDACTIONREGISTRATION
+_RESSTR_$RTLCONSTS_$$_SINVALIDACTIONUNREGISTRATION
+_RESSTR_$RTLCONSTS_$$_SINVALIDBINARY
+_RESSTR_$RTLCONSTS_$$_SINVALIDBITMAP
+_RESSTR_$RTLCONSTS_$$_SINVALIDCLIPFMT
+_RESSTR_$RTLCONSTS_$$_SINVALIDCURRENTITEM
+_RESSTR_$RTLCONSTS_$$_SINVALIDDATEDAY
+_RESSTR_$RTLCONSTS_$$_SINVALIDDATEMONTHWEEK
+_RESSTR_$RTLCONSTS_$$_SINVALIDDATEWEEK
+_RESSTR_$RTLCONSTS_$$_SINVALIDDAYOFWEEKINMONTH
+_RESSTR_$RTLCONSTS_$$_SERRILLEGALDATEFORMATSTRING
+_RESSTR_$RTLCONSTS_$$_SINVALIDFILENAME
+_RESSTR_$RTLCONSTS_$$_SINVALIDICON
+_RESSTR_$RTLCONSTS_$$_SINVALIDIMAGE
+_RESSTR_$RTLCONSTS_$$_SINVALIDIMAGELIST
+_RESSTR_$RTLCONSTS_$$_SINVALIDIMAGESIZE
+_RESSTR_$RTLCONSTS_$$_SINVALIDMASK
+_RESSTR_$RTLCONSTS_$$_SINVALIDMEMOSIZE
+_RESSTR_$RTLCONSTS_$$_SINVALIDMETAFILE
+_RESSTR_$RTLCONSTS_$$_SINVALIDNAME
+_RESSTR_$RTLCONSTS_$$_SINVALIDNUMBER
+_RESSTR_$RTLCONSTS_$$_SINVALIDPIXELFORMAT
+_RESSTR_$RTLCONSTS_$$_SINVALIDPRINTER
+_RESSTR_$RTLCONSTS_$$_SINVALIDPRINTEROP
+_RESSTR_$RTLCONSTS_$$_SINVALIDPROPERTY
+_RESSTR_$RTLCONSTS_$$_SINVALIDPROPERTYELEMENT
+_RESSTR_$RTLCONSTS_$$_SINVALIDPROPERTYPATH
+_RESSTR_$RTLCONSTS_$$_SINVALIDPROPERTYTYPE
+_RESSTR_$RTLCONSTS_$$_SINVALIDPROPERTYVALUE
+_RESSTR_$RTLCONSTS_$$_SINVALIDREGTYPE
+_RESSTR_$RTLCONSTS_$$_SINVALIDROMANNUMERAL
+_RESSTR_$RTLCONSTS_$$_SINVALIDSTRING
+_RESSTR_$RTLCONSTS_$$_SINVALIDSTRINGGRIDOP
+_RESSTR_$RTLCONSTS_$$_SINVALIDTABINDEX
+_RESSTR_$RTLCONSTS_$$_SITALICFONT
+_RESSTR_$RTLCONSTS_$$_SITEMNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SLINETOOLONG
+_RESSTR_$RTLCONSTS_$$_SLISTCAPACITYERROR
+_RESSTR_$RTLCONSTS_$$_SLISTCOUNTERROR
+_RESSTR_$RTLCONSTS_$$_SLISTINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SLISTITEMSIZEERROR
+_RESSTR_$RTLCONSTS_$$_SMAPKEYERROR
+_RESSTR_$RTLCONSTS_$$_SMASKEDITERR
+_RESSTR_$RTLCONSTS_$$_SMASKERR
+_RESSTR_$RTLCONSTS_$$_SMDICHILDNOTVISIBLE
+_RESSTR_$RTLCONSTS_$$_SMEMORYSTREAMERROR
+_RESSTR_$RTLCONSTS_$$_SMENUINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SMENUNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SMENUREINSERTED
+_RESSTR_$RTLCONSTS_$$_SMISSINGDATETIMEFIELD
+_RESSTR_$RTLCONSTS_$$_SMPOPENFILTER
+_RESSTR_$RTLCONSTS_$$_SNETWORKCAP
+_RESSTR_$RTLCONSTS_$$_SNOADDRESS
+_RESSTR_$RTLCONSTS_$$_SNOBUTTON
+_RESSTR_$RTLCONSTS_$$_SNOCANVASHANDLE
+_RESSTR_$RTLCONSTS_$$_SNOCOMSUPPORT
+_RESSTR_$RTLCONSTS_$$_SNODEFAULTPRINTER
+_RESSTR_$RTLCONSTS_$$_SNOMDIFORM
+_RESSTR_$RTLCONSTS_$$_SNOTIMERS
+_RESSTR_$RTLCONSTS_$$_SNOTOPENERR
+_RESSTR_$RTLCONSTS_$$_SNOTPRINTING
+_RESSTR_$RTLCONSTS_$$_SNOPROCGIVEN
+_RESSTR_$RTLCONSTS_$$_SNOVOLUMELABEL
+_RESSTR_$RTLCONSTS_$$_SNUMBEREXPECTED
+_RESSTR_$RTLCONSTS_$$_SOKBUTTON
+_RESSTR_$RTLCONSTS_$$_SOLDTSHAPE
+_RESSTR_$RTLCONSTS_$$_SOLEGRAPHIC
+_RESSTR_$RTLCONSTS_$$_SOUTLINEBADLEVEL
+_RESSTR_$RTLCONSTS_$$_SOUTLINEERROR
+_RESSTR_$RTLCONSTS_$$_SOUTLINEEXPANDERROR
+_RESSTR_$RTLCONSTS_$$_SOUTLINEFILELOAD
+_RESSTR_$RTLCONSTS_$$_SOUTLINEINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SOUTLINELONGLINE
+_RESSTR_$RTLCONSTS_$$_SOUTLINEMAXLEVELS
+_RESSTR_$RTLCONSTS_$$_SOUTLINESELECTION
+_RESSTR_$RTLCONSTS_$$_SOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SOUTOFRESOURCES
+_RESSTR_$RTLCONSTS_$$_SPARENTREQUIRED
+_RESSTR_$RTLCONSTS_$$_SPARSEERROR
+_RESSTR_$RTLCONSTS_$$_SPARLOCINFO
+_RESSTR_$RTLCONSTS_$$_SPAREXPECTED
+_RESSTR_$RTLCONSTS_$$_SPARWRONGTOKENTYPE
+_RESSTR_$RTLCONSTS_$$_SPARWRONGTOKENSYMBOL
+_RESSTR_$RTLCONSTS_$$_SPARINVALIDINTEGER
+_RESSTR_$RTLCONSTS_$$_SPARINVALIDFLOAT
+_RESSTR_$RTLCONSTS_$$_SPARUNTERMINATEDSTRING
+_RESSTR_$RTLCONSTS_$$_SPARUNTERMINATEDBINVALUE
+_RESSTR_$RTLCONSTS_$$_SPICTUREDESC
+_RESSTR_$RTLCONSTS_$$_SPICTURELABEL
+_RESSTR_$RTLCONSTS_$$_SPREVIEWLABEL
+_RESSTR_$RTLCONSTS_$$_SPRINTERINDEXERROR
+_RESSTR_$RTLCONSTS_$$_SPRINTING
+_RESSTR_$RTLCONSTS_$$_SPROPERTIESVERB
+_RESSTR_$RTLCONSTS_$$_SPROPERTYEXCEPTION
+_RESSTR_$RTLCONSTS_$$_SPROPERTYOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SPUTOBJECTERROR
+_RESSTR_$RTLCONSTS_$$_SRANGEERROR
+_RESSTR_$RTLCONSTS_$$_SREADERROR
+_RESSTR_$RTLCONSTS_$$_SREADONLYPROPERTY
+_RESSTR_$RTLCONSTS_$$_SREGCREATEFAILED
+_RESSTR_$RTLCONSTS_$$_SREGGETDATAFAILED
+_RESSTR_$RTLCONSTS_$$_SREGISTERERROR
+_RESSTR_$RTLCONSTS_$$_SREGSETDATAFAILED
+_RESSTR_$RTLCONSTS_$$_SREGULARFONT
+_RESSTR_$RTLCONSTS_$$_SREPLACEIMAGE
+_RESSTR_$RTLCONSTS_$$_SRESNOTFOUND
+_RESSTR_$RTLCONSTS_$$_SRETRYBUTTON
+_RESSTR_$RTLCONSTS_$$_SRNONE
+_RESSTR_$RTLCONSTS_$$_SRUNKNOWN
+_RESSTR_$RTLCONSTS_$$_SSCANLINE
+_RESSTR_$RTLCONSTS_$$_SSCROLLBARRANGE
+_RESSTR_$RTLCONSTS_$$_SSEEKNOTIMPLEMENTED
+_RESSTR_$RTLCONSTS_$$_SSELECTDIRCAP
+_RESSTR_$RTLCONSTS_$$_SSOCKETALREADYOPEN
+_RESSTR_$RTLCONSTS_$$_SSOCKETIOERROR
+_RESSTR_$RTLCONSTS_$$_SSOCKETMUSTBEBLOCKING
+_RESSTR_$RTLCONSTS_$$_SSOCKETREAD
+_RESSTR_$RTLCONSTS_$$_SSOCKETWRITE
+_RESSTR_$RTLCONSTS_$$_SSORTEDLISTERROR
+_RESSTR_$RTLCONSTS_$$_SSTREAMINVALIDSEEK
+_RESSTR_$RTLCONSTS_$$_SSTREAMNOREADING
+_RESSTR_$RTLCONSTS_$$_SSTREAMNOWRITING
+_RESSTR_$RTLCONSTS_$$_SSTREAMSETSIZE
+_RESSTR_$RTLCONSTS_$$_SSTRINGEXPECTED
+_RESSTR_$RTLCONSTS_$$_SSYMBOLEXPECTED
+_RESSTR_$RTLCONSTS_$$_STHREADCREATEERROR
+_RESSTR_$RTLCONSTS_$$_STHREADERROR
+_RESSTR_$RTLCONSTS_$$_STHREADEXTERNAL
+_RESSTR_$RTLCONSTS_$$_STOOMANYDELETED
+_RESSTR_$RTLCONSTS_$$_STOOMANYIMAGES
+_RESSTR_$RTLCONSTS_$$_STWOMDIFORMS
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNCLIPBOARDFORMAT
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNCONVERSION
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNEXTENSION
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNGROUP
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNPROPERTY
+_RESSTR_$RTLCONSTS_$$_SUNKNOWNPROPERTYTYPE
+_RESSTR_$RTLCONSTS_$$_SUNSUPPORTEDPROPERTYVARIANTTYPE
+_RESSTR_$RTLCONSTS_$$_SUNTITLED
+_RESSTR_$RTLCONSTS_$$_SVBITMAPS
+_RESSTR_$RTLCONSTS_$$_SVENHMETAFILES
+_RESSTR_$RTLCONSTS_$$_SVICONS
+_RESSTR_$RTLCONSTS_$$_SVISIBLECHANGED
+_RESSTR_$RTLCONSTS_$$_SVMETAFILES
+_RESSTR_$RTLCONSTS_$$_SWINDOWCLASS
+_RESSTR_$RTLCONSTS_$$_SWINDOWCREATE
+_RESSTR_$RTLCONSTS_$$_SWINDOWDCERROR
+_RESSTR_$RTLCONSTS_$$_SWINDOWSSOCKETERROR
+_RESSTR_$RTLCONSTS_$$_SWRITEERROR
+_RESSTR_$RTLCONSTS_$$_SYESBUTTON
+_RESSTR_$RTLCONSTS_$$_SSTRINGINDEXOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SHIGHSURROGATEOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SLOWSURROGATEOUTOFRANGE
+_RESSTR_$RTLCONSTS_$$_SINVALIDUTF32CHAR
+_RESSTR_$RTLCONSTS_$$_SINVALIDHIGHSURROGATE
+_RESSTR_$RTLCONSTS_$$_SINVALIDUNICODECODEPOINTSEQUENCE
+_RESSTR_$RTLCONSTS_$$_SCLASSCANTBECONSTRUCTED
+_RESSTR_$RTLCONSTS_$$_SERRSTATUSCALLBACKREQUIRED
+_RESSTR_$RTLCONSTS_$$_SERRFINDNEEDSSORTEDLIST
+_RESSTR_$RTLCONSTS_$$_SPARAMISNEGATIVE
+_RESSTR_$RTLCONSTS_$$_SERRCANNOTWRITETOPROPERTY
+_RESSTR_$RTLCONSTS_$$_SERRCANNOTREADPROPERTY
+_RESSTR_$RTLCONSTS_$$_SERRNONAMEVALUEPAIRAT
+_RESSTR_$RTLCONSTS_$$_SERRCANNOTCONVERTNULLTOTYPE
+_RESSTR_$RTLCONSTS_$$_SMKCALT
+_RESSTR_$RTLCONSTS_$$_SMKCBKSP
+_RESSTR_$RTLCONSTS_$$_SMKCCTRL
+_RESSTR_$RTLCONSTS_$$_SMKCDEL
+_RESSTR_$RTLCONSTS_$$_SMKCDOWN
+_RESSTR_$RTLCONSTS_$$_SMKCEND
+_RESSTR_$RTLCONSTS_$$_SMKCENTER
+_RESSTR_$RTLCONSTS_$$_SMKCESC
+_RESSTR_$RTLCONSTS_$$_SMKCHOME
+_RESSTR_$RTLCONSTS_$$_SMKCINS
+_RESSTR_$RTLCONSTS_$$_SMKCLEFT
+_RESSTR_$RTLCONSTS_$$_SMKCPGDN
+_RESSTR_$RTLCONSTS_$$_SMKCPGUP
+_RESSTR_$RTLCONSTS_$$_SMKCRIGHT
+_RESSTR_$RTLCONSTS_$$_SMKCSHIFT
+_RESSTR_$RTLCONSTS_$$_SMKCSPACE
+_RESSTR_$RTLCONSTS_$$_SMKCTAB
+_RESSTR_$RTLCONSTS_$$_SMKCUP
+_RESSTR_$RTLCONSTS_$$_SANGSTROMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SASTRONOMICALUNITSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCENTIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCHAINSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBITSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECAMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDISTANCEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFATHOMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFEETDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFURLONGSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SGIGAMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHANDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHECTOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SINCHESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SKILOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SLIGHTYEARSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SLINKSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMEGAMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMICROMICRONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMICRONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLIMICRONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SNAUTICALMILESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SPACESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SPARSECSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SPICASDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SPOINTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SRODSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SYARDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SACRESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SAREADESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SARESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCENTARESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHECTARESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUARECENTIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREDECAMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREDECIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREFEETDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREHECTOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREINCHESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREKILOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREMILESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREMILLIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUARERODSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSQUAREYARDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SACREFEETDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SACREINCHESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCENTILITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCORDFEETDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCORDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICCENTIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICDECAMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICDECIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICFEETDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICHECTOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICINCHESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICKILOMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICMILESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICMILLIMETERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCUBICYARDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECALITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECASTERESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECILITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECISTERESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHECTOLITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SKILOLITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SLITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLILITERSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSTERESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SVOLUMEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDCUPSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDGALLONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDGILLSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDOUNCESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDPINTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDQUARTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDTABLESPOONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFLUIDTEASPOONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYBUCKETSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYBUSHELSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYGALLONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYPECKSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYPINTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRYQUARTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKBUCKETSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKBUSHELSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKGALLONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKGILLSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKOUNCESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKPECKSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKPINTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKPOTTLESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SUKQUARTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCENTIGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECAGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECIGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SGRAINSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHECTOGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SKILOGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SLONGTONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMASSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMETRICTONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMICROGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLIGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SNANOGRAMSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SOUNCESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SPOUNDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSTONESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_STONSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCELSIUSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFAHRENHEITDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SKELVINDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SRANKINEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SREAUMURDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_STEMPERATUREDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SCENTURIESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDATETIMEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDAYSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SDECADESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SFORTNIGHTSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SHOURSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SJULIANDATEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLENNIADESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMILLISECONDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMINUTESDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMODIFIEDJULIANDATEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SMONTHSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SSECONDSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_STIMEDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SWEEKSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SYEARSDESCRIPTION
+_RESSTR_$RTLCONSTS_$$_SINVALIDDATE
+_RESSTR_$RTLCONSTS_$$_SINVALIDDATETIME
+_RESSTR_$RTLCONSTS_$$_SINVALIDINTEGER
+_RESSTR_$RTLCONSTS_$$_SINVALIDTIME
+_RESSTR_$RTLCONSTS_$$_STIMEENCODEERROR
+_RESSTR_$RTLCONSTS_$$_SMCIAVIVIDEO
+_RESSTR_$RTLCONSTS_$$_SMCICDAUDIO
+_RESSTR_$RTLCONSTS_$$_SMCIDAT
+_RESSTR_$RTLCONSTS_$$_SMCIDIGITALVIDEO
+_RESSTR_$RTLCONSTS_$$_SMCIMMMOVIE
+_RESSTR_$RTLCONSTS_$$_SMCINIL
+_RESSTR_$RTLCONSTS_$$_SMCIOTHER
+_RESSTR_$RTLCONSTS_$$_SMCIOVERLAY
+_RESSTR_$RTLCONSTS_$$_SMCISCANNER
+_RESSTR_$RTLCONSTS_$$_SMCISEQUENCER
+_RESSTR_$RTLCONSTS_$$_SMCIUNKNOWNERROR
+_RESSTR_$RTLCONSTS_$$_SMCIVCR
+_RESSTR_$RTLCONSTS_$$_SMCIVIDEODISC
+_RESSTR_$RTLCONSTS_$$_SMCIWAVEAUDIO
+_RESSTR_$RTLCONSTS_$$_SMSGDLGABORT
+_RESSTR_$RTLCONSTS_$$_SMSGDLGALL
+_RESSTR_$RTLCONSTS_$$_SMSGDLGCANCEL
+_RESSTR_$RTLCONSTS_$$_SMSGDLGCLOSE
+_RESSTR_$RTLCONSTS_$$_SMSGDLGCONFIRM
+_RESSTR_$RTLCONSTS_$$_SMSGDLGERROR
+_RESSTR_$RTLCONSTS_$$_SMSGDLGHELP
+_RESSTR_$RTLCONSTS_$$_SMSGDLGHELPHELP
+_RESSTR_$RTLCONSTS_$$_SMSGDLGHELPNONE
+_RESSTR_$RTLCONSTS_$$_SMSGDLGIGNORE
+_RESSTR_$RTLCONSTS_$$_SMSGDLGINFORMATION
+_RESSTR_$RTLCONSTS_$$_SMSGDLGNO
+_RESSTR_$RTLCONSTS_$$_SMSGDLGNOTOALL
+_RESSTR_$RTLCONSTS_$$_SMSGDLGOK
+_RESSTR_$RTLCONSTS_$$_SMSGDLGRETRY
+_RESSTR_$RTLCONSTS_$$_SMSGDLGWARNING
+_RESSTR_$RTLCONSTS_$$_SMSGDLGYES
+_RESSTR_$RTLCONSTS_$$_SMSGDLGYESTOALL
+_RESSTR_$RTLCONSTS_$$_END
+_RESSTR_$LCLSTRCONSTS_$$_START
+_RESSTR_$LCLSTRCONSTS_$$_RSMBYES
+_RESSTR_$LCLSTRCONSTS_$$_RSMBNO
+_RESSTR_$LCLSTRCONSTS_$$_RSMBOK
+_RESSTR_$LCLSTRCONSTS_$$_RSMBCANCEL
+_RESSTR_$LCLSTRCONSTS_$$_RSMBABORT
+_RESSTR_$LCLSTRCONSTS_$$_RSMBRETRY
+_RESSTR_$LCLSTRCONSTS_$$_RSMBIGNORE
+_RESSTR_$LCLSTRCONSTS_$$_RSMBALL
+_RESSTR_$LCLSTRCONSTS_$$_RSMBNOTOALL
+_RESSTR_$LCLSTRCONSTS_$$_RSMBYESTOALL
+_RESSTR_$LCLSTRCONSTS_$$_RSMBHELP
+_RESSTR_$LCLSTRCONSTS_$$_RSMBCLOSE
+_RESSTR_$LCLSTRCONSTS_$$_RSMBOPEN
+_RESSTR_$LCLSTRCONSTS_$$_RSMBSAVE
+_RESSTR_$LCLSTRCONSTS_$$_RSMBUNLOCK
+_RESSTR_$LCLSTRCONSTS_$$_RSMTWARNING
+_RESSTR_$LCLSTRCONSTS_$$_RSMTERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSMTINFORMATION
+_RESSTR_$LCLSTRCONSTS_$$_RSMTCONFIRMATION
+_RESSTR_$LCLSTRCONSTS_$$_RSMTAUTHENTICATION
+_RESSTR_$LCLSTRCONSTS_$$_RSMTCUSTOM
+_RESSTR_$LCLSTRCONSTS_$$_RSFDOPENFILE
+_RESSTR_$LCLSTRCONSTS_$$_RSFDOVERWRITEFILE
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILEALREADYEXISTS
+_RESSTR_$LCLSTRCONSTS_$$_RSFDPATHMUSTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFDPATHNOEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILEMUSTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFDDIRECTORYMUSTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILENOTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFDDIRECTORYNOTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSFIND
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILEREADONLYTITLE
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILEREADONLY
+_RESSTR_$LCLSTRCONSTS_$$_RSFDFILESAVEAS
+_RESSTR_$LCLSTRCONSTS_$$_RSALLFILES
+_RESSTR_$LCLSTRCONSTS_$$_RSFDSELECTDIRECTORY
+_RESSTR_$LCLSTRCONSTS_$$_RSDIRECTORY
+_RESSTR_$LCLSTRCONSTS_$$_RSSELECTCOLORTITLE
+_RESSTR_$LCLSTRCONSTS_$$_RSSELECTFONTTITLE
+_RESSTR_$LCLSTRCONSTS_$$_RSFINDMORE
+_RESSTR_$LCLSTRCONSTS_$$_RSREPLACE
+_RESSTR_$LCLSTRCONSTS_$$_RSREPLACEALL
+_RESSTR_$LCLSTRCONSTS_$$_RSHELP
+_RESSTR_$LCLSTRCONSTS_$$_RSDELETERECORD
+_RESSTR_$LCLSTRCONSTS_$$_RSFIRSTRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSPRIORRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSNEXTRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSLASTRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSINSERTRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSDELETERECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSEDITRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSPOSTRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSCANCELRECORDHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSREFRESHRECORDSHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSMENUHIDE
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSMENUHIDEOTHERS
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSMENUQUIT
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSMENUSERVICES
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSMENUSHOWALL
+_RESSTR_$LCLSTRCONSTS_$$_RSMACOSFILEFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSWARNINGUNREMOVEDPAINTMESSAGES
+_RESSTR_$LCLSTRCONSTS_$$_RSWARNINGUNRELEASEDDCSDUMP
+_RESSTR_$LCLSTRCONSTS_$$_RSWARNINGUNRELEASEDGDIOBJECTSDUMP
+_RESSTR_$LCLSTRCONSTS_$$_RSWARNINGUNRELEASEDMESSAGESINQUEUE
+_RESSTR_$LCLSTRCONSTS_$$_RSWARNINGUNRELEASEDTIMERINFOS
+_RESSTR_$LCLSTRCONSTS_$$_RSFILEINFORMATION
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKFILTER
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKHISTORY
+_RESSTR_$LCLSTRCONSTS_$$_RSDEFAULTFILEINFOVALUE
+_RESSTR_$LCLSTRCONSTS_$$_RSBLANK
+_RESSTR_$LCLSTRCONSTS_$$_RSUNABLETOLOADDEFAULTFONT
+_RESSTR_$LCLSTRCONSTS_$$_RSFILEINFOFILENOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONNOTRANSIENT
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONMODULE
+_RESSTR_$LCLSTRCONSTS_$$_RSGOPTIONFATALWARNINGS
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONDEBUG
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONNODEBUG
+_RESSTR_$LCLSTRCONSTS_$$_RSGDKOPTIONDEBUG
+_RESSTR_$LCLSTRCONSTS_$$_RSGDKOPTIONNODEBUG
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONDISPLAY
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONSYNC
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONNOXSHM
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONNAME
+_RESSTR_$LCLSTRCONSTS_$$_RSGTKOPTIONCLASS
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONNOGRAB
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONDOGRAB
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONSYNC
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONSTYLE
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONSTYLESHEET
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONGRAPHICSSTYLE
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONSESSION
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONWIDGETCOUNT
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONREVERSE
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11DISPLAY
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11GEOMETRY
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11FONT
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11BGCOLOR
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11FGCOLOR
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11BTNCOLOR
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11NAME
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11TITLE
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11VISUAL
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11NCOLS
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11CMAP
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11IM
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONX11INPUTSTYLE
+_RESSTR_$LCLSTRCONSTS_$$_RSQTOPTIONDISABLEACCURATEFRAME
+_RESSTR_$LCLSTRCONSTS_$$_RSWIN32WARNING
+_RESSTR_$LCLSTRCONSTS_$$_RSWIN32ERROR
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDACTIONREGISTRATION
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDACTIONUNREGISTRATION
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDACTIONENUMERATION
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDACTIONCREATION
+_RESSTR_$LCLSTRCONSTS_$$_SMENUNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_SMENUINDEXERROR
+_RESSTR_$LCLSTRCONSTS_$$_SMENUITEMISNIL
+_RESSTR_$LCLSTRCONSTS_$$_SNOTIMERS
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDINDEX
+_RESSTR_$LCLSTRCONSTS_$$_SINVALIDIMAGESIZE
+_RESSTR_$LCLSTRCONSTS_$$_SDUPLICATEMENUS
+_RESSTR_$LCLSTRCONSTS_$$_SCANNOTFOCUS
+_RESSTR_$LCLSTRCONSTS_$$_SPARENTREQUIRED
+_RESSTR_$LCLSTRCONSTS_$$_SMASKEDITNOMATCH
+_RESSTR_$LCLSTRCONSTS_$$_RSINVALIDPROPERTYVALUE
+_RESSTR_$LCLSTRCONSTS_$$_RSPROPERTYDOESNOTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSINVALIDSTREAMFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSINVALIDFORMOBJECTSTREAM
+_RESSTR_$LCLSTRCONSTS_$$_RSSCROLLBAROUTOFRANGE
+_RESSTR_$LCLSTRCONSTS_$$_RSINVALIDDATE
+_RESSTR_$LCLSTRCONSTS_$$_RSINVALIDDATERANGEHINT
+_RESSTR_$LCLSTRCONSTS_$$_RSDATETOOLARGE
+_RESSTR_$LCLSTRCONSTS_$$_RSDATETOOSMALL
+_RESSTR_$LCLSTRCONSTS_$$_RSERROROCCURREDINATADDRESSFRAME
+_RESSTR_$LCLSTRCONSTS_$$_RSEXCEPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSFORMSTREAMINGERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSFIXEDCOLSTOOBIG
+_RESSTR_$LCLSTRCONSTS_$$_RSFIXEDROWSTOOBIG
+_RESSTR_$LCLSTRCONSTS_$$_RSGRIDFILEDOESNOTEXIST
+_RESSTR_$LCLSTRCONSTS_$$_RSNOTAVALIDGRIDFILE
+_RESSTR_$LCLSTRCONSTS_$$_RSINDEXOUTOFRANGE
+_RESSTR_$LCLSTRCONSTS_$$_RSGRIDINDEXOUTOFRANGE
+_RESSTR_$LCLSTRCONSTS_$$_RSGRIDHASNOROWS
+_RESSTR_$LCLSTRCONSTS_$$_RSGRIDHASNOCOLS
+_RESSTR_$LCLSTRCONSTS_$$_RSACONTROLCANNOTHAVEITSELFASPARENT
+_RESSTR_$LCLSTRCONSTS_$$_RSCONTROLHASNOPARENTFORMORFRAME
+_RESSTR_$LCLSTRCONSTS_$$_RSCONTROLISNOTAPARENT
+_RESSTR_$LCLSTRCONSTS_$$_RSCONTROLCLASSCANTCONTAINCHILDCLASS
+_RESSTR_$LCLSTRCONSTS_$$_RSASCANNOTHAVEASPARENT
+_RESSTR_$LCLSTRCONSTS_$$_LISLCLRESOURCESNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSFORMRESOURCESNOTFOUNDFORRESOURCELESSFORMSCREATENEW
+_RESSTR_$LCLSTRCONSTS_$$_RSERRORCREATINGDEVICECONTEXT
+_RESSTR_$LCLSTRCONSTS_$$_RSINDEXOUTOFBOUNDS
+_RESSTR_$LCLSTRCONSTS_$$_RSUNKNOWNPICTUREEXTENSION
+_RESSTR_$LCLSTRCONSTS_$$_RSUNKNOWNPICTUREFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSBITMAPS
+_RESSTR_$LCLSTRCONSTS_$$_RSPIXMAP
+_RESSTR_$LCLSTRCONSTS_$$_RSPORTABLENETWORKGRAPHIC
+_RESSTR_$LCLSTRCONSTS_$$_RSPORTABLEPIXMAP
+_RESSTR_$LCLSTRCONSTS_$$_RSICON
+_RESSTR_$LCLSTRCONSTS_$$_RSICNS
+_RESSTR_$LCLSTRCONSTS_$$_RSCURSOR
+_RESSTR_$LCLSTRCONSTS_$$_RSJPEG
+_RESSTR_$LCLSTRCONSTS_$$_RSTIFF
+_RESSTR_$LCLSTRCONSTS_$$_RSGIF
+_RESSTR_$LCLSTRCONSTS_$$_RSTGA
+_RESSTR_$LCLSTRCONSTS_$$_RSGRAPHIC
+_RESSTR_$LCLSTRCONSTS_$$_RSUNSUPPORTEDCLIPBOARDFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSGROUPINDEXCANNOTBELESSTHANPREVIOUS
+_RESSTR_$LCLSTRCONSTS_$$_RSISALREADYASSOCIATEDWITH
+_RESSTR_$LCLSTRCONSTS_$$_RSCANVASDOESNOTALLOWDRAWING
+_RESSTR_$LCLSTRCONSTS_$$_RSUNSUPPORTEDBITMAPFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSERRORWHILESAVINGBITMAP
+_RESSTR_$LCLSTRCONSTS_$$_RSDUPLICATEICONFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSICONIMAGEEMPTY
+_RESSTR_$LCLSTRCONSTS_$$_RSICONIMAGESIZE
+_RESSTR_$LCLSTRCONSTS_$$_RSICONNOCURRENT
+_RESSTR_$LCLSTRCONSTS_$$_RSICONIMAGEFORMAT
+_RESSTR_$LCLSTRCONSTS_$$_RSICONIMAGEFORMATCHANGE
+_RESSTR_$LCLSTRCONSTS_$$_RSICONIMAGESIZECHANGE
+_RESSTR_$LCLSTRCONSTS_$$_RSRASTERIMAGEUPDATEALL
+_RESSTR_$LCLSTRCONSTS_$$_RSRASTERIMAGEENDUPDATE
+_RESSTR_$LCLSTRCONSTS_$$_RSRASTERIMAGESAVEINUPDATE
+_RESSTR_$LCLSTRCONSTS_$$_RSNOWIDGETSET
+_RESSTR_$LCLSTRCONSTS_$$_RSPRESSOKTOIGNOREANDRISKDATACORRUPTIONPRESSABORTTOK
+_RESSTR_$LCLSTRCONSTS_$$_RSCANNOTFOCUS
+_RESSTR_$LCLSTRCONSTS_$$_RSLISTINDEXEXCEEDSBOUNDS
+_RESSTR_$LCLSTRCONSTS_$$_RSRESOURCENOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSCALCULATOR
+_RESSTR_$LCLSTRCONSTS_$$_RSERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSPICKDATE
+_RESSTR_$LCLSTRCONSTS_$$_RSSIZE
+_RESSTR_$LCLSTRCONSTS_$$_RSMODIFIED
+_RESSTR_$LCLSTRCONSTS_$$_RSDOCOPY
+_RESSTR_$LCLSTRCONSTS_$$_RSDOPASTE
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSNAME
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSSIZE
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSTYPE
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSMB
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSKB
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSBYTES
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSINVALIDROOT
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSSELECTEDITEMDOESNOTEXISTS
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSINVALIDPATH
+_RESSTR_$LCLSTRCONSTS_$$_SSHELLCTRLSINVALIDPATHRELATIVE
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_UNKNOWN
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_SHIFT
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_META
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_CMD
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_SUPER
+_RESSTR_$LCLSTRCONSTS_$$_IFSVK_HELP
+_RESSTR_$LCLSTRCONSTS_$$_IFSCTRL
+_RESSTR_$LCLSTRCONSTS_$$_IFSALT
+_RESSTR_$LCLSTRCONSTS_$$_RSWHOLEWORDSONLY
+_RESSTR_$LCLSTRCONSTS_$$_RSCASESENSITIVE
+_RESSTR_$LCLSTRCONSTS_$$_RSPROMPTONREPLACE
+_RESSTR_$LCLSTRCONSTS_$$_RSENTIRESCOPE
+_RESSTR_$LCLSTRCONSTS_$$_RSTEXT
+_RESSTR_$LCLSTRCONSTS_$$_RSDIRECTION
+_RESSTR_$LCLSTRCONSTS_$$_RSFORWARD
+_RESSTR_$LCLSTRCONSTS_$$_RSBACKWARD
+_RESSTR_$LCLSTRCONSTS_$$_SMKCBKSP
+_RESSTR_$LCLSTRCONSTS_$$_SMKCTAB
+_RESSTR_$LCLSTRCONSTS_$$_SMKCESC
+_RESSTR_$LCLSTRCONSTS_$$_SMKCENTER
+_RESSTR_$LCLSTRCONSTS_$$_SMKCSPACE
+_RESSTR_$LCLSTRCONSTS_$$_SMKCPGUP
+_RESSTR_$LCLSTRCONSTS_$$_SMKCPGDN
+_RESSTR_$LCLSTRCONSTS_$$_SMKCEND
+_RESSTR_$LCLSTRCONSTS_$$_SMKCHOME
+_RESSTR_$LCLSTRCONSTS_$$_SMKCLEFT
+_RESSTR_$LCLSTRCONSTS_$$_SMKCUP
+_RESSTR_$LCLSTRCONSTS_$$_SMKCRIGHT
+_RESSTR_$LCLSTRCONSTS_$$_SMKCDOWN
+_RESSTR_$LCLSTRCONSTS_$$_SMKCINS
+_RESSTR_$LCLSTRCONSTS_$$_SMKCDEL
+_RESSTR_$LCLSTRCONSTS_$$_SMKCSHIFT
+_RESSTR_$LCLSTRCONSTS_$$_SMKCCTRL
+_RESSTR_$LCLSTRCONSTS_$$_SMKCALT
+_RESSTR_$LCLSTRCONSTS_$$_SMKCMETA
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPNODEHASNOHELPDATABASE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPTHEREISNOVIEWERFORHELPTYPE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPDATABASEDIDNOTFOUNDAVIEWERFORAHELPPAGEOFTYPE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPALREADYREGISTERED
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPNOTREGISTERED
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPDATABASENOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPKEYWORDNOTFOUNDINDATABASE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPKEYWORDNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPFORDIRECTIVENOTFOUNDINDATABASE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPFORDIRECTIVENOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPCONTEXTNOTFOUNDINDATABASE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPHELPCONTEXTNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPNOHELPFOUNDFORSOURCE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPNOHELPNODESAVAILABLE
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPDATABASENOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPCONTEXTNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPVIEWERNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPVIEWERERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSHELPSELECTORERROR
+_RESSTR_$LCLSTRCONSTS_$$_RSUNKNOWNERRORPLEASEREPORTTHISBUG
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPTHEHELPDATABASEWASUNABLETOFINDFILE
+_RESSTR_$LCLSTRCONSTS_$$_RSTHEBUILTINURLISREADONLYCHANGETHEBASEURLINSTEAD
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPTHEMACROSINBROWSERPARAMSWILLBEREPLACEDBYTHEURL
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPNOHTMLBROWSERFOUNDPLEASEDEFINEONE
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPNOHTMLBROWSERFOUND
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPBROWSERNOTFOUND
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPBROWSERNOTEXECUTABLE
+_RESSTR_$LCLSTRCONSTS_$$_HHSHELPERRORWHILEEXECUTING
+_RESSTR_$LCLSTRCONSTS_$$_SPAREXPECTED
+_RESSTR_$LCLSTRCONSTS_$$_SPARINVALIDINTEGER
+_RESSTR_$LCLSTRCONSTS_$$_SPARWRONGTOKENTYPE
+_RESSTR_$LCLSTRCONSTS_$$_SPARINVALIDFLOAT
+_RESSTR_$LCLSTRCONSTS_$$_SPARWRONGTOKENSYMBOL
+_RESSTR_$LCLSTRCONSTS_$$_SPARUNTERMINATEDSTRING
+_RESSTR_$LCLSTRCONSTS_$$_SPARLOCINFO
+_RESSTR_$LCLSTRCONSTS_$$_SPARUNTERMINATEDBINVALUE
+_RESSTR_$LCLSTRCONSTS_$$_RSCUSTOMCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBLACKCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMAROONCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSGREENCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSOLIVECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSNAVYCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSPURPLECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSTEALCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSGRAYCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSSILVERCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSREDCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSLIMECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSYELLOWCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBLUECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSFUCHSIACOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSAQUACOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSWHITECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMONEYGREENCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSSKYBLUECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSCREAMCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMEDGRAYCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSNONECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSDEFAULTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSSCROLLBARCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBACKGROUNDCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSACTIVECAPTIONCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSINACTIVECAPTIONCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMENUCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSWINDOWCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSWINDOWFRAMECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMENUTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSWINDOWTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSCAPTIONTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSACTIVEBORDERCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSINACTIVEBORDERCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSAPPWORKSPACECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSHIGHLIGHTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSHIGHLIGHTTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBTNFACECOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBTNSHADOWCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSGRAYTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSBTNTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSINACTIVECAPTIONTEXT
+_RESSTR_$LCLSTRCONSTS_$$_RSBTNHIGHLIGHTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RS3DDKSHADOWCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RS3DLIGHTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSINFOTEXTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSINFOBKCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSHOTLIGHTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSGRADIENTACTIVECAPTIONCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSGRADIENTINACTIVECAPTIONCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMENUHIGHLIGHTCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSMENUBARCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSFORMCOLORCAPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSFILTER
+_RESSTR_$LCLSTRCONSTS_$$_RSTTREEVIEWACCESSIBILITYDESCRIPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSTPANELACCESSIBILITYDESCRIPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSTSPLITTERACCESSIBILITYDESCRIPTION
+_RESSTR_$LCLSTRCONSTS_$$_RSTCUSTOMTABCONTROLACCESSIBILITYDESCRIPTION
+_RESSTR_$LCLSTRCONSTS_$$_END
+_RESSTR_$LAZUTILSSTRCONSTS_$$_START
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSMODIFIED
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSIZE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSFILEDOESNOTEXIST
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSFILEISADIRECTORYANDNOTANEXECUTABLE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSREADACCESSDENIEDFOR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSADIRECTORYCOMPONENTINDOESNOTEXISTORISADANGLINGSYML2
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSADIRECTORYCOMPONENTINISNOTADIRECTORY2
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSADIRECTORYCOMPONENTINDOESNOTEXISTORISADANGLINGSYML
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSADIRECTORYCOMPONENTINISNOTADIRECTORY
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSINSUFFICIENTMEMORY
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSHASACIRCULARSYMBOLICLINK
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSISNOTASYMBOLICLINK
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSISNOTEXECUTABLE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSUNABLETOCREATECONFIGDIRECTORYS
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPROGRAMFILENOTFOUND
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSCANNOTEXECUTE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSLISTMUSTBEEMPTY
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSLISTINDEXEXCEEDSBOUNDS
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSERRORINCODE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSCREATINGGDBCATCHABLEERROR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSINVALIDCHARMASKAT
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSINVALIDCHARMASK
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSMISSINGCLOSECHARMASKAT
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSMISSINGCLOSECHARMASK
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSINCOMPLETEMASK
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSINVALIDESCAPECHAR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_RSINTERNALERROR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSNODESET
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSBOOLEAN
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSNUMBER
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSTRING
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSVARNOCONVERSION
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSCANNERUNCLOSEDSTRING
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSCANNERINVALIDCHAR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSCANNERMALFORMEDQNAME
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSSCANNEREXPECTEDVARNAME
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSEREXPECTEDLEFTBRACKET
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSEREXPECTEDRIGHTBRACKET
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSERBADAXISNAME
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSERBADNODETYPE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSEREXPECTEDRIGHTSQUAREBRACKET
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSERINVALIDPRIMEXPR
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSERGARBAGEAFTEREXPRESSION
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSPARSERINVALIDNODETEST
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSEVALUNKNOWNFUNCTION
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSEVALUNKNOWNVARIABLE
+_RESSTR_$LAZUTILSSTRCONSTS_$$_LRSEVALINVALIDARGCOUNT
+_RESSTR_$LAZUTILSSTRCONSTS_$$_END
+_RESSTR_$STRUTILS_$$_START
+_RESSTR_$STRUTILS_$$_SERRAMOUNTSTRINGS
+_RESSTR_$STRUTILS_$$_SINVALIDROMANNUMERAL
+_RESSTR_$STRUTILS_$$_END
+_RESSTR_$JSONSCANNER_$$_START
+_RESSTR_$JSONSCANNER_$$_SERRINVALIDCHARACTER
+_RESSTR_$JSONSCANNER_$$_SUNTERMINATEDCOMMENT
+_RESSTR_$JSONSCANNER_$$_SERROPENSTRING
+_RESSTR_$JSONSCANNER_$$_END
+_RESSTR_$JSONPARSER_$$_START
+_RESSTR_$JSONPARSER_$$_SERRSTRUCTURE
+_RESSTR_$JSONPARSER_$$_END
+_RESSTR_$FPJSON_$$_START
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTFROMNULL
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTTONULL
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTFROMARRAY
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTTOARRAY
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTFROMOBJECT
+_RESSTR_$FPJSON_$$_SERRCANNOTCONVERTTOOBJECT
+_RESSTR_$FPJSON_$$_SERRINVALIDFLOAT
+_RESSTR_$FPJSON_$$_SERRCANNOTSETNOTISNULL
+_RESSTR_$FPJSON_$$_SERRCANNOTADDARRAYTWICE
+_RESSTR_$FPJSON_$$_SERRCANNOTADDOBJECTTWICE
+_RESSTR_$FPJSON_$$_SERRUNKNOWNTYPEINCONSTRUCTOR
+_RESSTR_$FPJSON_$$_SERRNOTJSONDATA
+_RESSTR_$FPJSON_$$_SERRODDNUMBER
+_RESSTR_$FPJSON_$$_SERRNAMEMUSTBESTRING
+_RESSTR_$FPJSON_$$_SERRNONEXISTENTELEMENT
+_RESSTR_$FPJSON_$$_SERRDUPLICATEVALUE
+_RESSTR_$FPJSON_$$_SERRPATHELEMENTNOTFOUND
+_RESSTR_$FPJSON_$$_SERRWRONGINSTANCECLASS
+_RESSTR_$FPJSON_$$_SERRPOINTERNOTNIL
+_RESSTR_$FPJSON_$$_SERRNOPARSERHANDLER
+_RESSTR_$FPJSON_$$_END
+_RESSTR_$JSONREADER_$$_START
+_RESSTR_$JSONREADER_$$_SERRUNEXPECTEDEOF
+_RESSTR_$JSONREADER_$$_SERRUNEXPECTEDTOKEN
+_RESSTR_$JSONREADER_$$_SERREXPECTEDCOLON
+_RESSTR_$JSONREADER_$$_SERREXPECTEDELEMENTNAME
+_RESSTR_$JSONREADER_$$_SEXPECTEDCOMMAORBRACECLOSE
+_RESSTR_$JSONREADER_$$_SERRINVALIDNUMBER
+_RESSTR_$JSONREADER_$$_SERRNOSCANNER
+_RESSTR_$JSONREADER_$$_SERRORAT
+_RESSTR_$JSONREADER_$$_SERRGARBAGEFOUND
+_RESSTR_$JSONREADER_$$_END
+_RESSTR_$VARIANTS_$$_START
+_RESSTR_$VARIANTS_$$_SERRVARISEMPTY
+_RESSTR_$VARIANTS_$$_SERRINVALIDINTEGERRANGE
+_RESSTR_$VARIANTS_$$_END
+_RESSTR_$CONTNRS_$$_START
+_RESSTR_$CONTNRS_$$_DUPLICATEMSG
+_RESSTR_$CONTNRS_$$_KEYNOTFOUNDMSG
+_RESSTR_$CONTNRS_$$_NOTEMPTYMSG
+_RESSTR_$CONTNRS_$$_SERRNOSUCHITEM
+_RESSTR_$CONTNRS_$$_SDUPLICATEITEM
+_RESSTR_$CONTNRS_$$_END
+_RESSTR_$ZSTREAM_$$_START
+_RESSTR_$ZSTREAM_$$_SGZ_OPEN_ERROR
+_RESSTR_$ZSTREAM_$$_SGZ_READ_ONLY
+_RESSTR_$ZSTREAM_$$_SGZ_WRITE_ONLY
+_RESSTR_$ZSTREAM_$$_SSEEK_FAILED
+_RESSTR_$ZSTREAM_$$_END
+_RESSTR_$ZBASE_$$_START
+_RESSTR_$ZBASE_$$_SNEED_DICT
+_RESSTR_$ZBASE_$$_SSTREAM_END
+_RESSTR_$ZBASE_$$_SFILE_ERROR
+_RESSTR_$ZBASE_$$_SSTREAM_ERROR
+_RESSTR_$ZBASE_$$_SDATA_ERROR
+_RESSTR_$ZBASE_$$_SMEM_ERROR
+_RESSTR_$ZBASE_$$_SBUF_ERROR
+_RESSTR_$ZBASE_$$_SVERSION_ERROR
+_RESSTR_$ZBASE_$$_END
+_RESSTR_$SYNCOBJS_$$_START
+_RESSTR_$SYNCOBJS_$$_SERREVENTCREATEFAILED
+_RESSTR_$SYNCOBJS_$$_END
+_RESSTR_$PROCESS_$$_START
+_RESSTR_$PROCESS_$$_SNOCOMMANDLINE
+_RESSTR_$PROCESS_$$_SERRNOSUCHPROGRAM
+_RESSTR_$PROCESS_$$_SERRNOTERMINALPROGRAM
+_RESSTR_$PROCESS_$$_SERRCANNOTFORK
+_RESSTR_$PROCESS_$$_SERRCANNOTCREATEPIPES
+_RESSTR_$PROCESS_$$_END
+_RESSTR_$CUSTAPP_$$_START
+_RESSTR_$CUSTAPP_$$_SERRINVALIDOPTION
+_RESSTR_$CUSTAPP_$$_SERRNOOPTIONALLOWED
+_RESSTR_$CUSTAPP_$$_SERROPTIONNEEDED
+_RESSTR_$CUSTAPP_$$_END
diff --git a/units/bass.pas b/units/bass.pas
new file mode 100644
index 0000000..4682564
--- /dev/null
+++ b/units/bass.pas
@@ -0,0 +1,1087 @@
+{
+ BASS 2.4 Delphi/Pascal unit
+ Copyright (c) 1999-2025 Un4seen Developments Ltd.
+
+ See the BASS.CHM file for more detailed documentation
+
+ How to install
+ --------------
+ Copy BASS.PAS to the \LIB subdirectory of your Delphi path or your project dir
+
+ NOTE: Delphi users should use the BASS_UNICODE flag where possible
+}
+
+unit BASS;
+
+interface
+
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+{$IFDEF MSWINDOWS}
+uses
+ Windows;
+{$ENDIF}
+
+const
+ BASSVERSION = $204; // API version
+ BASSVERSIONTEXT = '2.4';
+
+ // Use these to test for error from functions that return a DWORD or QWORD
+ DW_ERROR = Cardinal(-1); // -1 (DWORD)
+ QW_ERROR = Int64(-1); // -1 (QWORD)
+
+ // Error codes returned by BASS_ErrorGetCode()
+ BASS_OK = 0; // all is OK
+ BASS_ERROR_MEM = 1; // memory error
+ BASS_ERROR_FILEOPEN = 2; // can't open the file
+ BASS_ERROR_DRIVER = 3; // can't find a free sound driver
+ BASS_ERROR_BUFLOST = 4; // the sample buffer was lost
+ BASS_ERROR_HANDLE = 5; // invalid handle
+ BASS_ERROR_FORMAT = 6; // unsupported sample format
+ BASS_ERROR_POSITION = 7; // invalid position
+ BASS_ERROR_INIT = 8; // BASS_Init has not been successfully called
+ BASS_ERROR_START = 9; // BASS_Start has not been successfully called
+ BASS_ERROR_SSL = 10; // SSL/HTTPS support isn't available
+ BASS_ERROR_REINIT = 11; // device needs to be reinitialized
+ BASS_ERROR_ALREADY = 14; // already initialized/paused/whatever
+ BASS_ERROR_NOTAUDIO = 17; // file does not contain audio
+ BASS_ERROR_NOCHAN = 18; // can't get a free channel
+ BASS_ERROR_ILLTYPE = 19; // an illegal type was specified
+ BASS_ERROR_ILLPARAM = 20; // an illegal parameter was specified
+ BASS_ERROR_NO3D = 21; // no 3D support
+ BASS_ERROR_NOEAX = 22; // no EAX support
+ BASS_ERROR_DEVICE = 23; // illegal device number
+ BASS_ERROR_NOPLAY = 24; // not playing
+ BASS_ERROR_FREQ = 25; // illegal sample rate
+ BASS_ERROR_NOTFILE = 27; // the stream is not a file stream
+ BASS_ERROR_NOHW = 29; // no hardware voices available
+ BASS_ERROR_EMPTY = 31; // the file has no sample data
+ BASS_ERROR_NONET = 32; // no internet connection could be opened
+ BASS_ERROR_CREATE = 33; // couldn't create the file
+ BASS_ERROR_NOFX = 34; // effects are not available
+ BASS_ERROR_NOTAVAIL = 37; // requested data/action is not available
+ BASS_ERROR_DECODE = 38; // the channel is/isn't a "decoding channel"
+ BASS_ERROR_DX = 39; // a sufficient DirectX version is not installed
+ BASS_ERROR_TIMEOUT = 40; // connection timedout
+ BASS_ERROR_FILEFORM = 41; // unsupported file format
+ BASS_ERROR_SPEAKER = 42; // unavailable speaker
+ BASS_ERROR_VERSION = 43; // invalid BASS version (used by add-ons)
+ BASS_ERROR_CODEC = 44; // codec is not available/supported
+ BASS_ERROR_ENDED = 45; // the channel/file has ended
+ BASS_ERROR_BUSY = 46; // the device is busy
+ BASS_ERROR_UNSTREAMABLE = 47; // unstreamable file
+ BASS_ERROR_PROTOCOL = 48; // unsupported protocol
+ BASS_ERROR_DENIED = 49; // access denied
+ BASS_ERROR_FREEING = 50; // being freed
+ BASS_ERROR_CANCEL = 51; // cancelled
+ BASS_ERROR_UNKNOWN = -1; // some other mystery problem
+
+ // BASS_SetConfig options
+ BASS_CONFIG_BUFFER = 0;
+ BASS_CONFIG_UPDATEPERIOD = 1;
+ BASS_CONFIG_GVOL_SAMPLE = 4;
+ BASS_CONFIG_GVOL_STREAM = 5;
+ BASS_CONFIG_GVOL_MUSIC = 6;
+ BASS_CONFIG_CURVE_VOL = 7;
+ BASS_CONFIG_CURVE_PAN = 8;
+ BASS_CONFIG_FLOATDSP = 9;
+ BASS_CONFIG_3DALGORITHM = 10;
+ BASS_CONFIG_NET_TIMEOUT = 11;
+ BASS_CONFIG_NET_BUFFER = 12;
+ BASS_CONFIG_PAUSE_NOPLAY = 13;
+ BASS_CONFIG_NET_PREBUF = 15;
+ BASS_CONFIG_NET_PASSIVE = 18;
+ BASS_CONFIG_REC_BUFFER = 19;
+ BASS_CONFIG_NET_PLAYLIST = 21;
+ BASS_CONFIG_MUSIC_VIRTUAL = 22;
+ BASS_CONFIG_VERIFY = 23;
+ BASS_CONFIG_UPDATETHREADS = 24;
+ BASS_CONFIG_DEV_BUFFER = 27;
+ BASS_CONFIG_REC_LOOPBACK = 28;
+ BASS_CONFIG_IOS_SESSION = 34;
+ BASS_CONFIG_IOS_MIXAUDIO = 34;
+ BASS_CONFIG_DEV_DEFAULT = 36;
+ BASS_CONFIG_NET_READTIMEOUT = 37;
+ BASS_CONFIG_VISTA_SPEAKERS = 38;
+ BASS_CONFIG_IOS_SPEAKER = 39;
+ BASS_CONFIG_MF_DISABLE = 40;
+ BASS_CONFIG_HANDLES = 41;
+ BASS_CONFIG_UNICODE = 42;
+ BASS_CONFIG_SRC = 43;
+ BASS_CONFIG_SRC_SAMPLE = 44;
+ BASS_CONFIG_ASYNCFILE_BUFFER = 45;
+ BASS_CONFIG_OGG_PRESCAN = 47;
+ BASS_CONFIG_VIDEO = 48;
+ BASS_CONFIG_MF_VIDEO = BASS_CONFIG_VIDEO;
+ BASS_CONFIG_AIRPLAY = 49;
+ BASS_CONFIG_DEV_NONSTOP = 50;
+ BASS_CONFIG_IOS_NOCATEGORY = 51;
+ BASS_CONFIG_VERIFY_NET = 52;
+ BASS_CONFIG_DEV_PERIOD = 53;
+ BASS_CONFIG_FLOAT = 54;
+ BASS_CONFIG_NET_SEEK = 56;
+ BASS_CONFIG_AM_DISABLE = 58;
+ BASS_CONFIG_NET_PLAYLIST_DEPTH = 59;
+ BASS_CONFIG_NET_PREBUF_WAIT = 60;
+ BASS_CONFIG_ANDROID_SESSIONID = 62;
+ BASS_CONFIG_WASAPI_PERSIST = 65;
+ BASS_CONFIG_REC_WASAPI = 66;
+ BASS_CONFIG_ANDROID_AAUDIO = 67;
+ BASS_CONFIG_SAMPLE_ONEHANDLE = 69;
+ BASS_CONFIG_NET_META = 71;
+ BASS_CONFIG_NET_RESTRATE = 72;
+ BASS_CONFIG_REC_DEFAULT = 73;
+ BASS_CONFIG_NORAMP = 74;
+ BASS_CONFIG_NOSOUND_MAXDELAY = 76;
+ BASS_CONFIG_STACKALLOC = 79;
+ BASS_CONFIG_DOWNMIX = 80;
+
+ // BASS_SetConfigPtr options
+ BASS_CONFIG_NET_AGENT = 16;
+ BASS_CONFIG_NET_PROXY = 17;
+ BASS_CONFIG_DEV_NOTIFY = 33;
+ BASS_CONFIG_ANDROID_JAVAVM = 63;
+ BASS_CONFIG_LIBSSL = 64;
+ BASS_CONFIG_FILENAME = 75;
+ BASS_CONFIG_FILEOPENPROCS = 77;
+
+ BASS_CONFIG_THREAD = $40000000; // flag: thread-specific setting
+
+ // BASS_CONFIG_IOS_SESSION flags
+ BASS_IOS_SESSION_MIX = 1;
+ BASS_IOS_SESSION_DUCK = 2;
+ BASS_IOS_SESSION_AMBIENT = 4;
+ BASS_IOS_SESSION_SPEAKER = 8;
+ BASS_IOS_SESSION_DISABLE = $10;
+ BASS_IOS_SESSION_DEACTIVATE = $20;
+ BASS_IOS_SESSION_AIRPLAY = $40;
+ BASS_IOS_SESSION_BTHFP = $80;
+ BASS_IOS_SESSION_BTA2DP = $100;
+
+ // BASS_Init flags
+ BASS_DEVICE_8BITS = 1; // unused
+ BASS_DEVICE_MONO = 2; // mono
+ BASS_DEVICE_3D = 4; // unused
+ BASS_DEVICE_16BITS = 8; // limit output to 16-bit
+ BASS_DEVICE_REINIT = $80; // reinitialize
+ BASS_DEVICE_LATENCY = $100; // unused
+ BASS_DEVICE_CPSPEAKERS = $400; // unused
+ BASS_DEVICE_SPEAKERS = $800; // force enabling of speaker assignment
+ BASS_DEVICE_NOSPEAKER = $1000; // ignore speaker arrangement
+ BASS_DEVICE_DMIX = $2000; // use ALSA "dmix" plugin
+ BASS_DEVICE_FREQ = $4000; // set device sample rate
+ BASS_DEVICE_STEREO = $8000; // limit output to stereo
+ BASS_DEVICE_AUDIOTRACK = $20000; // use AudioTrack output
+ BASS_DEVICE_DSOUND = $40000; // use DirectSound output
+ BASS_DEVICE_SOFTWARE = $80000; // disable hardware/fastpath output
+ BASS_DEVICE_OPENSLES = $100000; // use OpenSLES output
+ BASS_DEVICE_APPLEVOICE = $200000; // use Apple voice processing
+
+ // DirectSound interfaces (for use with BASS_GetDSoundObject)
+ BASS_OBJECT_DS = 1; // IDirectSound
+ BASS_OBJECT_DS3DL = 2; // IDirectSound3DListener
+
+ // BASS_DEVICEINFO flags
+ BASS_DEVICE_ENABLED = 1;
+ BASS_DEVICE_DEFAULT = 2;
+ BASS_DEVICE_INIT = 4;
+ BASS_DEVICE_LOOPBACK = 8;
+ BASS_DEVICE_DEFAULTCOM = $80;
+
+ BASS_DEVICE_TYPE_MASK = $ff000000;
+ BASS_DEVICE_TYPE_NETWORK = $01000000;
+ BASS_DEVICE_TYPE_SPEAKERS = $02000000;
+ BASS_DEVICE_TYPE_LINE = $03000000;
+ BASS_DEVICE_TYPE_HEADPHONES = $04000000;
+ BASS_DEVICE_TYPE_MICROPHONE = $05000000;
+ BASS_DEVICE_TYPE_HEADSET = $06000000;
+ BASS_DEVICE_TYPE_HANDSET = $07000000;
+ BASS_DEVICE_TYPE_DIGITAL = $08000000;
+ BASS_DEVICE_TYPE_SPDIF = $09000000;
+ BASS_DEVICE_TYPE_HDMI = $0a000000;
+ BASS_DEVICE_TYPE_DISPLAYPORT = $40000000;
+
+ // BASS_GetDeviceInfo flags
+ BASS_DEVICES_AIRPLAY = $1000000;
+
+ // BASS_INFO flags (from DSOUND.H)
+ DSCAPS_EMULDRIVER = $00000020; // device does not have hardware DirectSound support
+ DSCAPS_CERTIFIED = $00000040; // device driver has been certified by Microsoft
+
+ DSCAPS_HARDWARE = $80000000; // hardware mixed
+
+ // BASS_RECORDINFO flags (from DSOUND.H)
+ DSCCAPS_EMULDRIVER = DSCAPS_EMULDRIVER; // device does not have hardware DirectSound recording support
+ DSCCAPS_CERTIFIED = DSCAPS_CERTIFIED; // device driver has been certified by Microsoft
+
+ // filetypes
+ BASS_FILE_NAME = 0; // filename
+ BASS_FILE_MEM = 1; // memory
+ BASS_FILE_MEMCOPY = 3; // memory to copy
+ BASS_FILE_HANDLE = 4; // handle/descriptor
+
+ BASS_SAMPLE_8BITS = 1; // 8 bit
+ BASS_SAMPLE_MONO = 2; // mono
+ BASS_SAMPLE_LOOP = 4; // looped
+ BASS_SAMPLE_3D = 8; // 3D functionality
+ BASS_SAMPLE_SOFTWARE = $10; // unused
+ BASS_SAMPLE_MUTEMAX = $20; // mute at max distance (3D only)
+ BASS_SAMPLE_NOREORDER = $40; // don't reorder channels to match speakers
+ BASS_SAMPLE_FX = $80; // unused
+ BASS_SAMPLE_FLOAT = $100; // 32 bit floating-point
+ BASS_SAMPLE_OVER_VOL = $10000; // override lowest volume
+ BASS_SAMPLE_OVER_POS = $20000; // override longest playing
+ BASS_SAMPLE_OVER_DIST = $30000; // override furthest from listener (3D only)
+
+ BASS_STREAM_PRESCAN = $20000; // scan file for accurate seeking and length
+ BASS_STREAM_AUTOFREE = $40000; // automatically free the stream when it stops/ends
+ BASS_STREAM_RESTRATE = $80000; // restrict the download rate of internet file streams
+ BASS_STREAM_BLOCK = $100000;// download/play internet file stream in small blocks
+ BASS_STREAM_DECODE = $200000;// don't play the stream, only decode
+ BASS_STREAM_STATUS = $800000;// give server status info (HTTP/ICY tags) in DOWNLOADPROC
+
+ BASS_MP3_IGNOREDELAY = $200; // ignore LAME/Xing/VBRI/iTunes delay & padding info
+ BASS_MP3_SETPOS = BASS_STREAM_PRESCAN;
+
+ BASS_MUSIC_FLOAT = BASS_SAMPLE_FLOAT;
+ BASS_MUSIC_MONO = BASS_SAMPLE_MONO;
+ BASS_MUSIC_LOOP = BASS_SAMPLE_LOOP;
+ BASS_MUSIC_3D = BASS_SAMPLE_3D;
+ BASS_MUSIC_FX = BASS_SAMPLE_FX;
+ BASS_MUSIC_AUTOFREE = BASS_STREAM_AUTOFREE;
+ BASS_MUSIC_DECODE = BASS_STREAM_DECODE;
+ BASS_MUSIC_PRESCAN = BASS_STREAM_PRESCAN; // calculate playback length
+ BASS_MUSIC_CALCLEN = BASS_MUSIC_PRESCAN;
+ BASS_MUSIC_RAMP = $200; // normal ramping
+ BASS_MUSIC_RAMPS = $400; // sensitive ramping
+ BASS_MUSIC_SURROUND = $800; // surround sound
+ BASS_MUSIC_SURROUND2 = $1000; // surround sound (mode 2)
+ BASS_MUSIC_FT2PAN = $2000; // apply FastTracker 2 panning to XM files
+ BASS_MUSIC_FT2MOD = $2000; // play .MOD as FastTracker 2 does
+ BASS_MUSIC_PT1MOD = $4000; // play .MOD as ProTracker 1 does
+ BASS_MUSIC_NONINTER = $10000; // non-interpolated sample mixing
+ BASS_MUSIC_SINCINTER = $800000; // sinc interpolated sample mixing
+ BASS_MUSIC_POSRESET = $8000; // stop all notes when moving position
+ BASS_MUSIC_POSRESETEX = $400000; // stop all notes and reset bmp/etc when moving position
+ BASS_MUSIC_STOPBACK = $80000; // stop the music on a backwards jump effect
+ BASS_MUSIC_NOSAMPLE = $100000; // don't load the samples
+
+ // Speaker assignment flags
+ BASS_SPEAKER_FRONT = $1000000; // front speakers
+ BASS_SPEAKER_REAR = $2000000; // rear speakers
+ BASS_SPEAKER_CENLFE = $3000000; // center & LFE speakers (5.1)
+ BASS_SPEAKER_SIDE = $4000000; // side speakers (7.1)
+ BASS_SPEAKER_LEFT = $10000000; // modifier: left
+ BASS_SPEAKER_RIGHT = $20000000; // modifier: right
+ BASS_SPEAKER_FRONTLEFT = BASS_SPEAKER_FRONT or BASS_SPEAKER_LEFT;
+ BASS_SPEAKER_FRONTRIGHT = BASS_SPEAKER_FRONT or BASS_SPEAKER_RIGHT;
+ BASS_SPEAKER_REARLEFT = BASS_SPEAKER_REAR or BASS_SPEAKER_LEFT;
+ BASS_SPEAKER_REARRIGHT = BASS_SPEAKER_REAR or BASS_SPEAKER_RIGHT;
+ BASS_SPEAKER_CENTER = BASS_SPEAKER_CENLFE or BASS_SPEAKER_LEFT;
+ BASS_SPEAKER_LFE = BASS_SPEAKER_CENLFE or BASS_SPEAKER_RIGHT;
+ BASS_SPEAKER_SIDELEFT = BASS_SPEAKER_SIDE or BASS_SPEAKER_LEFT;
+ BASS_SPEAKER_SIDERIGHT = BASS_SPEAKER_SIDE or BASS_SPEAKER_RIGHT;
+ BASS_SPEAKER_REAR2 = BASS_SPEAKER_SIDE;
+ BASS_SPEAKER_REAR2LEFT = BASS_SPEAKER_SIDELEFT;
+ BASS_SPEAKER_REAR2RIGHT = BASS_SPEAKER_SIDERIGHT;
+
+ BASS_ASYNCFILE = $40000000; // read file asynchronously
+ BASS_UNICODE = $80000000; // UTF-16
+
+ BASS_RECORD_OPENSLES = $1000; // use OpenSLES
+ BASS_RECORD_PAUSE = $8000; // start recording paused
+
+ BASS_ORIGRES_FLOAT = $10000;
+
+ // BASS_CHANNELINFO types
+ BASS_CTYPE_SAMPLE = 1;
+ BASS_CTYPE_RECORD = 2;
+ BASS_CTYPE_STREAM = $10000;
+ BASS_CTYPE_STREAM_VORBIS = $10002;
+ BASS_CTYPE_STREAM_OGG = $10002;
+ BASS_CTYPE_STREAM_MP1 = $10003;
+ BASS_CTYPE_STREAM_MP2 = $10004;
+ BASS_CTYPE_STREAM_MP3 = $10005;
+ BASS_CTYPE_STREAM_AIFF = $10006;
+ BASS_CTYPE_STREAM_CA = $10007;
+ BASS_CTYPE_STREAM_MF = $10008;
+ BASS_CTYPE_STREAM_AM = $10009;
+ BASS_CTYPE_STREAM_SAMPLE = $1000a;
+ BASS_CTYPE_STREAM_DUMMY = $18000;
+ BASS_CTYPE_STREAM_DEVICE = $18001;
+ BASS_CTYPE_STREAM_WAV = $40000; // WAVE flag (LOWORD=codec)
+ BASS_CTYPE_STREAM_WAV_PCM = $50001;
+ BASS_CTYPE_STREAM_WAV_FLOAT = $50003;
+ BASS_CTYPE_MUSIC_MOD = $20000;
+ BASS_CTYPE_MUSIC_MTM = $20001;
+ BASS_CTYPE_MUSIC_S3M = $20002;
+ BASS_CTYPE_MUSIC_XM = $20003;
+ BASS_CTYPE_MUSIC_IT = $20004;
+ BASS_CTYPE_MUSIC_MO3 = $00100; // MO3 flag
+
+ // BASS_PluginLoad flags
+ BASS_PLUGIN_PROC = 1;
+
+ // 3D channel modes
+ BASS_3DMODE_NORMAL = 0; // normal 3D processing
+ BASS_3DMODE_RELATIVE = 1; // position is relative to the listener
+ BASS_3DMODE_OFF = 2; // no 3D processing
+
+ // software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM)
+ BASS_3DALG_DEFAULT = 0;
+ BASS_3DALG_OFF = 1;
+
+ // BASS_SampleGetChannel flags
+ BASS_SAMCHAN_NEW = 1; // get a new playback channel
+ BASS_SAMCHAN_STREAM = 2; // create a stream
+
+ // STREAMPROC flags
+ BASS_STREAMPROC_AGAIN = $40000000; // call again for remainder
+ BASS_STREAMPROC_END = $80000000; // end the stream
+
+ // BASS_StreamCreateFileUser file systems
+ STREAMFILE_NOBUFFER = 0;
+ STREAMFILE_BUFFER = 1;
+ STREAMFILE_BUFFERPUSH = 2;
+
+ // BASS_StreamPutFileData options
+ BASS_FILEDATA_END = 0; // end & close the file
+
+ // BASS_StreamGetFilePosition modes
+ BASS_FILEPOS_CURRENT = 0;
+ BASS_FILEPOS_DECODE = BASS_FILEPOS_CURRENT;
+ BASS_FILEPOS_DOWNLOAD = 1;
+ BASS_FILEPOS_END = 2;
+ BASS_FILEPOS_START = 3;
+ BASS_FILEPOS_CONNECTED = 4;
+ BASS_FILEPOS_BUFFER = 5;
+ BASS_FILEPOS_SOCKET = 6;
+ BASS_FILEPOS_ASYNCBUF = 7;
+ BASS_FILEPOS_SIZE = 8;
+ BASS_FILEPOS_BUFFERING = 9;
+ BASS_FILEPOS_AVAILABLE = 10;
+ BASS_FILEPOS_ASYNCSIZE = 12;
+
+ // BASS_ChannelSetSync types
+ BASS_SYNC_POS = 0;
+ BASS_SYNC_END = 2;
+ BASS_SYNC_META = 4;
+ BASS_SYNC_SLIDE = 5;
+ BASS_SYNC_STALL = 6;
+ BASS_SYNC_DOWNLOAD = 7;
+ BASS_SYNC_FREE = 8;
+ BASS_SYNC_SETPOS = 11;
+ BASS_SYNC_MUSICPOS = 10;
+ BASS_SYNC_MUSICINST = 1;
+ BASS_SYNC_MUSICFX = 3;
+ BASS_SYNC_OGG_CHANGE = 12;
+ BASS_SYNC_ATTRIB = 13;
+ BASS_SYNC_DEV_FAIL = 14;
+ BASS_SYNC_DEV_FORMAT = 15;
+ BASS_SYNC_POS_RAW = 16;
+ BASS_SYNC_THREAD = $20000000; // flag: call sync in other thread
+ BASS_SYNC_MIXTIME = $40000000; // flag: sync at mixtime, else at playtime
+ BASS_SYNC_ONETIME = $80000000; // flag: sync only once, else continuously
+
+ // BASS_ChannelIsActive return values
+ BASS_ACTIVE_STOPPED = 0;
+ BASS_ACTIVE_PLAYING = 1;
+ BASS_ACTIVE_STALLED = 2;
+ BASS_ACTIVE_PAUSED = 3;
+ BASS_ACTIVE_PAUSED_DEVICE = 4;
+
+ // Channel attributes
+ BASS_ATTRIB_FREQ = 1;
+ BASS_ATTRIB_VOL = 2;
+ BASS_ATTRIB_PAN = 3;
+ BASS_ATTRIB_EAXMIX = 4;
+ BASS_ATTRIB_NOBUFFER = 5;
+ BASS_ATTRIB_VBR = 6;
+ BASS_ATTRIB_CPU = 7;
+ BASS_ATTRIB_SRC = 8;
+ BASS_ATTRIB_NET_RESUME = 9;
+ BASS_ATTRIB_SCANINFO = 10;
+ BASS_ATTRIB_NORAMP = 11;
+ BASS_ATTRIB_BITRATE = 12;
+ BASS_ATTRIB_BUFFER = 13;
+ BASS_ATTRIB_GRANULE = 14;
+ BASS_ATTRIB_USER = 15;
+ BASS_ATTRIB_TAIL = 16;
+ BASS_ATTRIB_PUSH_LIMIT = 17;
+ BASS_ATTRIB_DOWNLOADPROC = 18;
+ BASS_ATTRIB_VOLDSP = 19;
+ BASS_ATTRIB_VOLDSP_PRIORITY = 20;
+ BASS_ATTRIB_DOWNMIX = 21;
+ BASS_ATTRIB_MUSIC_AMPLIFY = $100;
+ BASS_ATTRIB_MUSIC_PANSEP = $101;
+ BASS_ATTRIB_MUSIC_PSCALER = $102;
+ BASS_ATTRIB_MUSIC_BPM = $103;
+ BASS_ATTRIB_MUSIC_SPEED = $104;
+ BASS_ATTRIB_MUSIC_VOL_GLOBAL = $105;
+ BASS_ATTRIB_MUSIC_ACTIVE = $106;
+ BASS_ATTRIB_MUSIC_VOL_CHAN = $200; // + channel #
+ BASS_ATTRIB_MUSIC_VOL_INST = $300; // + instrument #
+
+ // Channel attribute types
+ BASS_ATTRIBTYPE_FLOAT = -1;
+ BASS_ATTRIBTYPE_INT = -2;
+
+ // BASS_ChannelSlideAttribute flags
+ BASS_SLIDE_LOG = $1000000;
+
+ // BASS_ChannelGetData flags
+ BASS_DATA_AVAILABLE = 0; // query how much data is buffered
+ BASS_DATA_NOREMOVE = $10000000; // flag: don't remove data from recording buffer
+ BASS_DATA_FIXED = $20000000; // unused
+ BASS_DATA_FLOAT = $40000000; // flag: return floating-point sample data
+ BASS_DATA_FFT256 = $80000000; // 256 sample FFT
+ BASS_DATA_FFT512 = $80000001; // 512 FFT
+ BASS_DATA_FFT1024 = $80000002; // 1024 FFT
+ BASS_DATA_FFT2048 = $80000003; // 2048 FFT
+ BASS_DATA_FFT4096 = $80000004; // 4096 FFT
+ BASS_DATA_FFT8192 = $80000005; // 8192 FFT
+ BASS_DATA_FFT16384 = $80000006; // 16384 FFT
+ BASS_DATA_FFT32768 = $80000007; // 32768 FFT
+ BASS_DATA_FFT_INDIVIDUAL = $10; // FFT flag: FFT for each channel, else all combined
+ BASS_DATA_FFT_NOWINDOW = $20; // FFT flag: no Hanning window
+ BASS_DATA_FFT_REMOVEDC = $40; // FFT flag: pre-remove DC bias
+ BASS_DATA_FFT_COMPLEX = $80; // FFT flag: return complex data
+ BASS_DATA_FFT_NYQUIST = $100; // FFT flag: return extra Nyquist value
+
+ // BASS_ChannelGetLevelEx flags
+ BASS_LEVEL_MONO = 1; // get mono level
+ BASS_LEVEL_STEREO = 2; // get stereo level
+ BASS_LEVEL_RMS = 4; // get RMS levels
+ BASS_LEVEL_VOLPAN = 8; // apply VOL/PAN attributes to the levels
+ BASS_LEVEL_NOREMOVE = $10; // don't remove data from recording buffer
+
+ // BASS_ChannelGetTags types : what's returned
+ BASS_TAG_ID3 = 0; // ID3v1 tags : TAG_ID3 structure
+ BASS_TAG_ID3V2 = 1; // ID3v2 tags : variable length block
+ BASS_TAG_OGG = 2; // OGG comments : series of null-terminated UTF-8 strings
+ BASS_TAG_HTTP = 3; // HTTP headers : series of null-terminated ASCII strings
+ BASS_TAG_ICY = 4; // ICY headers : series of null-terminated ANSI strings
+ BASS_TAG_META = 5; // ICY metadata : ANSI string
+ BASS_TAG_APE = 6; // APEv2 tags : series of null-terminated UTF-8 strings
+ BASS_TAG_MP4 = 7; // MP4/iTunes metadata : series of null-terminated UTF-8 strings
+ BASS_TAG_WMA = 8; // WMA tags : series of null-terminated UTF-8 strings
+ BASS_TAG_VENDOR = 9; // OGG encoder : UTF-8 string
+ BASS_TAG_LYRICS3 = 10; // Lyric3v2 tag : ASCII string
+ BASS_TAG_CA_CODEC = 11; // CoreAudio codec info : TAG_CA_CODEC structure
+ BASS_TAG_MF = 13; // Media Foundation tags : series of null-terminated UTF-8 strings
+ BASS_TAG_WAVEFORMAT = 14; // WAVE format : WAVEFORMATEEX structure
+ BASS_TAG_AM_NAME = 16; // Android Media codec name : ASCII string
+ BASS_TAG_ID3V2_2 = 17; // ID3v2 tags (2nd block) : variable length block
+ BASS_TAG_AM_MIME = 18; // Android Media MIME type : ASCII string
+ BASS_TAG_LOCATION = 19; // redirected URL : ASCII string
+ BASS_TAG_ID3V2_BINARY = 20; // ID3v2 tags : TAB_BINARY
+ BASS_TAG_ID3V2_2_BINARY = 21; // ID3v2 tags (2nd block) : TAB_BINARY
+ BASS_TAG_RIFF_INFO = $100; // RIFF "INFO" tags : series of null-terminated ANSI strings
+ BASS_TAG_RIFF_BEXT = $101; // RIFF/BWF "bext" tags : TAG_BEXT structure
+ BASS_TAG_RIFF_CART = $102; // RIFF/BWF "cart" tags : TAG_CART structure
+ BASS_TAG_RIFF_DISP = $103; // RIFF "DISP" text tag : ANSI string
+ BASS_TAG_RIFF_CUE = $104; // RIFF "cue " chunk : TAG_CUE structure
+ BASS_TAG_RIFF_SMPL = $105; // RIFF "smpl" chunk : TAG_SMPL structure
+ BASS_TAG_APE_BINARY = $1000; // + index #, binary APEv2 tag : TAG_APE_BINARY structure
+ BASS_TAG_MP4_COVERART = $1400; // + index #, MP4 cover art : TAG_BINARY structure
+ BASS_TAG_MUSIC_NAME = $10000; // MOD music name : ANSI string
+ BASS_TAG_MUSIC_MESSAGE = $10001; // MOD message : ANSI string
+ BASS_TAG_MUSIC_ORDERS = $10002; // MOD order list : BYTE array of pattern numbers
+ BASS_TAG_MUSIC_AUTH = $10003; // MOD author : UTF-8 string
+ BASS_TAG_MUSIC_INST = $10100; // + instrument #, MOD instrument name : ANSI string
+ BASS_TAG_MUSIC_CHAN = $10200; // + channel #, MOD channel name : ANSI string
+ BASS_TAG_MUSIC_SAMPLE = $10300; // + sample #, MOD sample name : ANSI string
+ BASS_TAG_INCREF = $20000000; // flag: increment channel's reference count
+
+ // BASS_ChannelGetLength/GetPosition/SetPosition modes
+ BASS_POS_BYTE = 0; // byte position
+ BASS_POS_MUSIC_ORDER = 1; // order.row position, MAKELONG(order,row)
+ BASS_POS_OGG = 3; // OGG bitstream number
+ BASS_POS_RAW = 6; // monotonic byte position
+ BASS_POS_END = $10; // trimmed end position
+ BASS_POS_LOOP = $11; // loop start positiom
+ BASS_POS_FLUSH = $1000000; // flag: flush decoder/FX buffers
+ BASS_POS_RESET = $2000000; // flag: reset user file buffers
+ BASS_POS_RELATIVE = $4000000; // flag: seek relative to the current position
+ BASS_POS_INEXACT = $8000000; // flag: allow seeking to inexact position
+ BASS_POS_DECODE = $10000000; // flag: get the decoding (not playing) position
+ BASS_POS_DECODETO = $20000000; // flag: decode to the position instead of seeking
+ BASS_POS_SCAN = $40000000; // flag: scan to the position
+
+ // BASS_ChannelSetDevice/GetDevice option
+ BASS_NODEVICE = $20000;
+
+ // BASS_RecordSetInput flags
+ BASS_INPUT_OFF = $10000;
+ BASS_INPUT_ON = $20000;
+
+ BASS_INPUT_TYPE_MASK = $FF000000;
+ BASS_INPUT_TYPE_UNDEF = $00000000;
+ BASS_INPUT_TYPE_DIGITAL = $01000000;
+ BASS_INPUT_TYPE_LINE = $02000000;
+ BASS_INPUT_TYPE_MIC = $03000000;
+ BASS_INPUT_TYPE_SYNTH = $04000000;
+ BASS_INPUT_TYPE_CD = $05000000;
+ BASS_INPUT_TYPE_PHONE = $06000000;
+ BASS_INPUT_TYPE_SPEAKER = $07000000;
+ BASS_INPUT_TYPE_WAVE = $08000000;
+ BASS_INPUT_TYPE_AUX = $09000000;
+ BASS_INPUT_TYPE_ANALOG = $0A000000;
+
+ // BASS_ChannelSetDSPEx flags
+ BASS_DSP_READONLY = 1;
+ BASS_DSP_FLOAT = 2;
+ BASS_DSP_FREECALL = 4;
+ BASS_DSP_BYPASS = $400000;
+
+ // BASS_ChannelSetFX effect types
+ BASS_FX_DX8_CHORUS = 0;
+ BASS_FX_DX8_COMPRESSOR = 1;
+ BASS_FX_DX8_DISTORTION = 2;
+ BASS_FX_DX8_ECHO = 3;
+ BASS_FX_DX8_FLANGER = 4;
+ BASS_FX_DX8_GARGLE = 5;
+ BASS_FX_DX8_I3DL2REVERB = 6;
+ BASS_FX_DX8_PARAMEQ = 7;
+ BASS_FX_DX8_REVERB = 8;
+ BASS_FX_VOLUME = 9;
+
+ BASS_DX8_PHASE_NEG_180 = 0;
+ BASS_DX8_PHASE_NEG_90 = 1;
+ BASS_DX8_PHASE_ZERO = 2;
+ BASS_DX8_PHASE_90 = 3;
+ BASS_DX8_PHASE_180 = 4;
+
+ BASS_DEVICENOTIFY_ENABLED = 0; // a device has been added or removed
+ BASS_DEVICENOTIFY_DEFAULT = 1; // the default output device has changed
+ BASS_DEVICENOTIFY_REC_DEFAULT = 2; // the default recording device has changed
+ BASS_DEVICENOTIFY_DEFAULTCOM = 3; // the default communication output device has changed
+ BASS_DEVICENOTIFY_REC_DEFAULTCOM = 4; // the default communication recording device has changed
+
+type
+ DWORD = Cardinal;
+ BOOL = LongBool;
+ QWORD = Int64;
+
+ HMUSIC = DWORD; // MOD music handle
+ HSAMPLE = DWORD; // sample handle
+ HCHANNEL = DWORD; // sample playback handle
+ HSTREAM = DWORD; // sample stream handle
+ HRECORD = DWORD; // recording handle
+ HSYNC = DWORD; // synchronizer handle
+ HDSP = DWORD; // DSP handle
+ HFX = DWORD; // effect handle
+ HPLUGIN = DWORD; // plugin handle
+
+ // Device info structure
+ BASS_DEVICEINFO = record
+ name: PAnsiChar; // description
+ driver: PAnsiChar; // driver
+ flags: DWORD;
+ end;
+
+ // Output device info structure
+ BASS_INFO = record
+ flags: DWORD; // DirectSound capabilities (DSCAPS_xxx flags)
+ reserved: Array[0..6] of DWORD;
+ minbuf: DWORD; // recommended minimum buffer length in ms
+ dsver: DWORD; // DirectSound version
+ latency: DWORD; // average delay (in ms) before start of playback
+ initflags: DWORD; // BASS_Init "flags" parameter
+ speakers: DWORD; // number of speakers available
+ freq: DWORD; // current output rate
+ end;
+
+ // Recording device info structure
+ BASS_RECORDINFO = record
+ flags: DWORD; // DirectSound capabilities (DSCCAPS_xxx flags)
+ formats: DWORD; // number of channels (in high 8 bits)
+ inputs: DWORD; // number of inputs
+ singlein: BOOL; // only 1 input can be set at a time
+ freq: DWORD; // current sample rate
+ end;
+
+ // Sample info structure
+ BASS_SAMPLE = record
+ freq: DWORD; // default playback rate
+ volume: Single; // default volume (0-100)
+ pan: Single; // default pan (-100=left, 0=middle, 100=right)
+ flags: DWORD; // BASS_SAMPLE_xxx flags
+ length: DWORD; // length (in samples, not bytes)
+ max: DWORD; // maximum simultaneous playbacks
+ origres: DWORD; // original resolution
+ chans: DWORD; // number of channels
+ mingap: DWORD; // minimum gap (ms) between creating channels
+ mode3d: DWORD; // BASS_3DMODE_xxx mode
+ mindist: Single; // minimum distance
+ maxdist: Single; // maximum distance
+ iangle: DWORD; // angle of inside projection cone
+ oangle: DWORD; // angle of outside projection cone
+ outvol: Single; // delta-volume outside the projection cone
+ reserved: Array[0..1] of DWORD;
+ end;
+
+ // Channel info structure
+ BASS_CHANNELINFO = record
+ freq: DWORD; // default playback rate
+ chans: DWORD; // channels
+ flags: DWORD;
+ ctype: DWORD; // type of channel
+ origres: DWORD; // original resolution
+ plugin: HPLUGIN;
+ sample: HSAMPLE;
+ {$IFDEF CPUX64}
+ padding: DWORD;
+ {$ENDIF}
+ filename: PChar;
+ end;
+
+ BASS_PLUGINFORM = record
+ ctype: DWORD; // channel type
+ {$IFDEF CPUX64}
+ padding: DWORD;
+ {$ENDIF}
+ name: PAnsiChar; // format description
+ exts: PAnsiChar; // file extension filter (*.ext1;*.ext2;etc...)
+ end;
+ PBASS_PLUGINFORMS = ^TBASS_PLUGINFORMS;
+ TBASS_PLUGINFORMS = array[0..maxInt div sizeOf(BASS_PLUGINFORM) - 1] of BASS_PLUGINFORM;
+
+ PBASS_PLUGININFO = ^BASS_PLUGININFO;
+ BASS_PLUGININFO = record
+ version: DWORD; // version (same form as BASS_GetVersion)
+ formatc: DWORD; // number of formats
+ formats: PBASS_PLUGINFORMS; // the array of formats
+ end;
+
+ // 3D vector (for 3D positions/velocities/orientations)
+ BASS_3DVECTOR = record
+ x: Single; // +=right, -=left
+ y: Single; // +=up, -=down
+ z: Single; // +=front, -=behind
+ end;
+
+ // User file callback functions
+ FILECLOSEPROC = procedure(user: Pointer); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ FILELENPROC = function(user: Pointer): QWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ FILEREADPROC = function(buffer: Pointer; length: DWORD; user: Pointer): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ FILESEEKPROC = function(offset: QWORD; user: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ FILEOPENPROC = function(filename: PChar; flags: DWORD): Pointer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+
+ BASS_FILEPROCS = record
+ close: FILECLOSEPROC;
+ length: FILELENPROC;
+ read: FILEREADPROC;
+ seek: FILESEEKPROC;
+ end;
+
+ BASS_FILEOPENPROCS = record
+ close: FILECLOSEPROC;
+ length: FILELENPROC;
+ read: FILEREADPROC;
+ seek: FILESEEKPROC;
+ open: FILEOPENPROC;
+ end;
+
+ // ID3v1 tag structure
+ PTAG_ID3 = ^TAG_ID3;
+ TAG_ID3 = record
+ id: Array[0..2] of AnsiChar;
+ title: Array[0..29] of AnsiChar;
+ artist: Array[0..29] of AnsiChar;
+ album: Array[0..29] of AnsiChar;
+ year: Array[0..3] of AnsiChar;
+ comment: Array[0..29] of AnsiChar;
+ genre: Byte;
+ end;
+
+ // Binary tag structure
+ PTAG_BINARY = ^TAG_BINARY;
+ TAG_BINARY = record
+ data: Pointer;
+ length: DWORD;
+ end;
+
+ // Binary APEv2 tag structure
+ PTAG_APE_BINARY = ^TAG_APE_BINARY;
+ TAG_APE_BINARY = record
+ key: PAnsiChar;
+ data: Pointer;
+ length: DWORD;
+ end;
+
+ // BWF "bext" tag structure
+ PTAG_BEXT = ^TAG_BEXT;
+ TAG_BEXT = packed record
+ Description: Array[0..255] of AnsiChar; // description
+ Originator: Array[0..31] of AnsiChar; // name of the originator
+ OriginatorReference: Array[0..31] of AnsiChar; // reference of the originator
+ OriginationDate: Array[0..9] of AnsiChar; // date of creation (yyyy-mm-dd)
+ OriginationTime: Array[0..7] of AnsiChar; // time of creation (hh-mm-ss)
+ TimeReference: QWORD; // first sample count since midnight (little-endian)
+ Version: Word; // BWF version (little-endian)
+ UMID: Array[0..63] of Byte; // SMPTE UMID
+ Reserved: Array[0..189] of Byte;
+ CodingHistory: AnsiChar; // history
+ end;
+
+ BASS_DX8_CHORUS = record
+ fWetDryMix: Single;
+ fDepth: Single;
+ fFeedback: Single;
+ fFrequency: Single;
+ lWaveform: DWORD; // 0=triangle, 1=sine
+ fDelay: Single;
+ lPhase: DWORD; // BASS_DX8_PHASE_xxx
+ end;
+
+ BASS_DX8_COMPRESSOR = record
+ fGain: Single;
+ fAttack: Single;
+ fRelease: Single;
+ fThreshold: Single;
+ fRatio: Single;
+ fPredelay: Single;
+ end;
+
+ BASS_DX8_DISTORTION = record
+ fGain: Single;
+ fEdge: Single;
+ fPostEQCenterFrequency: Single;
+ fPostEQBandwidth: Single;
+ fPreLowpassCutoff: Single;
+ end;
+
+ BASS_DX8_ECHO = record
+ fWetDryMix: Single;
+ fFeedback: Single;
+ fLeftDelay: Single;
+ fRightDelay: Single;
+ lPanDelay: BOOL;
+ end;
+
+ BASS_DX8_FLANGER = record
+ fWetDryMix: Single;
+ fDepth: Single;
+ fFeedback: Single;
+ fFrequency: Single;
+ lWaveform: DWORD; // 0=triangle, 1=sine
+ fDelay: Single;
+ lPhase: DWORD; // BASS_DX8_PHASE_xxx
+ end;
+
+ BASS_DX8_GARGLE = record
+ dwRateHz: DWORD; // Rate of modulation in hz
+ dwWaveShape: DWORD; // 0=triangle, 1=square
+ end;
+
+ BASS_DX8_I3DL2REVERB = record
+ lRoom: Integer; // [-10000, 0] default: -1000 mB
+ lRoomHF: Integer; // [-10000, 0] default: 0 mB
+ flRoomRolloffFactor: Single; // [0.0, 10.0] default: 0.0
+ flDecayTime: Single; // [0.1, 20.0] default: 1.49s
+ flDecayHFRatio: Single; // [0.1, 2.0] default: 0.83
+ lReflections: Integer; // [-10000, 1000] default: -2602 mB
+ flReflectionsDelay: Single; // [0.0, 0.3] default: 0.007 s
+ lReverb: Integer; // [-10000, 2000] default: 200 mB
+ flReverbDelay: Single; // [0.0, 0.1] default: 0.011 s
+ flDiffusion: Single; // [0.0, 100.0] default: 100.0 %
+ flDensity: Single; // [0.0, 100.0] default: 100.0 %
+ flHFReference: Single; // [20.0, 20000.0] default: 5000.0 Hz
+ end;
+
+ BASS_DX8_PARAMEQ = record
+ fCenter: Single;
+ fBandwidth: Single;
+ fGain: Single;
+ end;
+
+ BASS_DX8_REVERB = record
+ fInGain: Single; // [-96.0,0.0] default: 0.0 dB
+ fReverbMix: Single; // [-96.0,0.0] default: 0.0 db
+ fReverbTime: Single; // [0.001,3000.0] default: 1000.0 ms
+ fHighFreqRTRatio: Single; // [0.001,0.999] default: 0.001
+ end;
+
+ BASS_FX_VOLUME_PARAM = record
+ fTarget: Single;
+ fCurrent: Single;
+ fTime: Single;
+ lCurve: DWORD;
+ end;
+
+ // callback function types
+ STREAMPROC = function(handle: HSTREAM; buffer: Pointer; length: DWORD; user: Pointer): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ User stream callback function.
+ handle : The stream that needs writing
+ buffer : Buffer to write the samples in
+ length : Number of bytes to write
+ user : The 'user' parameter value given when calling BASS_StreamCreate
+ RETURN : Number of bytes written and BASS_STREAMPROC_xxx flags
+ }
+
+const
+ // Special STREAMPROCs
+ STREAMPROC_DUMMY = Pointer(0); // "dummy" stream
+ STREAMPROC_PUSH = Pointer(-1); // push stream
+ STREAMPROC_DEVICE = Pointer(-2); // device mix stream
+ STREAMPROC_DEVICE_3D = Pointer(-3); // device 3D mix stream
+
+type
+ DOWNLOADPROC = procedure(buffer: Pointer; length: DWORD; user: Pointer); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ Internet stream download callback function.
+ buffer : Buffer containing the downloaded data... NULL=end of download
+ length : Number of bytes in the buffer
+ user : The 'user' parameter value given when calling BASS_StreamCreateURL
+ }
+
+ SYNCPROC = procedure(handle: HSYNC; channel, data: DWORD; user: Pointer); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ Sync callback function.
+ handle : The sync that has occured
+ channel: Channel that the sync occured in
+ data : Additional data associated with the sync's occurance
+ user : The 'user' parameter given when calling BASS_ChannelSetSync
+ }
+
+ DSPPROC = procedure(handle: HDSP; channel: DWORD; buffer: Pointer; length: DWORD; user: Pointer); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ DSP callback function.
+ handle : The DSP handle
+ channel: Channel that the DSP is being applied to
+ buffer : Buffer to apply the DSP to
+ length : Number of bytes in the buffer
+ user : The 'user' parameter given when calling BASS_ChannelSetDSP
+ }
+
+ RECORDPROC = function(handle: HRECORD; buffer: Pointer; length: DWORD; user: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ Recording callback function.
+ handle : The recording handle
+ buffer : Buffer containing the recorded sample data
+ length : Number of bytes
+ user : The 'user' parameter value given when calling BASS_RecordStart
+ RETURN : TRUE = continue recording, FALSE = stop
+ }
+
+const
+ // Special RECORDPROCs
+ RECORDPROC_NONE = Pointer(0); // no RECORDPROC
+ RECORDPROC_TRUE = Pointer(-1); // only "return true"
+
+type
+ DEVICENOTIFYPROC = procedure(notify: DWORD); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
+ {
+ Device notification callback function.
+ notify : The notification (BASS_DEVICENOTIFY_xxx)
+ }
+
+
+// Functions
+const
+{$IF defined(MSWINDOWS)}
+ bassdll = 'bass.dll';
+{$ELSEIF defined(LINUX)}
+ bassdll = 'libbass.so';
+{$ELSEIF defined(ANDROID)}
+ bassdll = 'libbass.so';
+{$ELSEIF defined(IOS)}
+ bassdll = 'bass.framework/bass';
+{$ELSEIF defined(DARWIN)}
+ bassdll = 'libbass.dylib';
+{$ELSE}
+ bassdll = 'libbass.dylib';
+{$IFEND}
+
+function BASS_SetConfig(option, value: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetConfig(option: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SetConfigPtr(option: DWORD; value: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetConfigPtr(option: DWORD): Pointer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetVersion: DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ErrorGetCode: Integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetDeviceInfo(device: DWORD; var info: BASS_DEVICEINFO): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+{$IFDEF MSWINDOWS}
+function BASS_Init(device: Integer; freq, flags: DWORD; win: HWND; clsid: Pointer): BOOL; stdcall; external bassdll;
+{$ELSE}
+function BASS_Init(device: Integer; freq, flags: DWORD; win: Pointer; clsid: Pointer): BOOL; cdecl; external bassdll;
+{$ENDIF}
+function BASS_SetDevice(device: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetDevice: DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Free: BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+{$IFDEF MSWINDOWS}
+function BASS_GetDSoundObject(obj: DWORD): Pointer; stdcall; external bassdll;
+{$ENDIF}
+function BASS_GetInfo(var info: BASS_INFO): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Update(length: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetCPU: Single; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Start: BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Stop: BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Pause: BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_IsStarted: DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SetVolume(volume: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_GetVolume: Single; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_Set3DFactors(distf, rollf, doppf: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Get3DFactors(var distf, rollf, doppf: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Set3DPosition(var pos, vel, front, top: BASS_3DVECTOR): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_Get3DPosition(var pos, vel, front, top: BASS_3DVECTOR): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+procedure BASS_Apply3D; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_PluginLoad(filename: PChar; flags: DWORD): HPLUGIN; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_PluginFree(handle: HPLUGIN): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_PluginEnable(handle: HPLUGIN; enable: BOOL): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_PluginGetInfo(handle: HPLUGIN): PBASS_PLUGININFO; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_SampleLoad(filetype: DWORD; f: Pointer; offset: QWORD; length, max, flags: DWORD): HSAMPLE; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleCreate(length, freq, chans, max, flags: DWORD): HSAMPLE; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleFree(handle: HSAMPLE): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleSetData(handle: HSAMPLE; buffer: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleGetData(handle: HSAMPLE; buffer: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleGetInfo(handle: HSAMPLE; var info: BASS_SAMPLE): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleSetInfo(handle: HSAMPLE; var info: BASS_SAMPLE): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleGetChannel(handle: HSAMPLE; flags: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleGetChannels(handle: HSAMPLE; channels: Pointer): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_SampleStop(handle: HSAMPLE): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_StreamCreate(freq, chans, flags: DWORD; proc: STREAMPROC; user: Pointer): HSTREAM; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamCreateFile(filetype: DWORD; f: Pointer; offset, length: QWORD; flags: DWORD): HSTREAM; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamCreateURL(url: PChar; offset: DWORD; flags: DWORD; proc: DOWNLOADPROC; user: Pointer):HSTREAM; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamCreateFileUser(system, flags: DWORD; var procs: BASS_FILEPROCS; user: Pointer): HSTREAM; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamCancel(user: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamFree(handle: HSTREAM): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamGetFilePosition(handle: HSTREAM; mode: DWORD): QWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamPutData(handle: HSTREAM; buffer: Pointer; length: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_StreamPutFileData(handle: HSTREAM; buffer: Pointer; length: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_MusicLoad(filetype: DWORD; f: Pointer; offset: QWORD; length, flags, freq: DWORD): HMUSIC; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_MusicFree(handle: HMUSIC): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_RecordGetDeviceInfo(device: DWORD; var info: BASS_DEVICEINFO): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordInit(device: Integer):BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordSetDevice(device: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordGetDevice: DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordFree: BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordGetInfo(var info: BASS_RECORDINFO): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordGetInputName(input: Integer): PAnsiChar; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordSetInput(input: Integer; flags: DWORD; volume: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordGetInput(input: Integer; var volume: Single): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_RecordStart(freq, chans, flags: DWORD; proc: RECORDPROC; user: Pointer): HRECORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_ChannelBytes2Seconds(handle: DWORD; pos: QWORD): Double; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelSeconds2Bytes(handle: DWORD; pos: Double): QWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelGetDevice(handle: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetDevice(handle, device: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelIsActive(handle: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelGetInfo(handle: DWORD; var info: BASS_CHANNELINFO):BOOL;{$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelGetTags(handle: HSTREAM; tags: DWORD): PAnsiChar; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelFlags(handle, flags, mask: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelLock(handle: DWORD; lock: BOOL): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelRef(handle: DWORD; inc: BOOL): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelFree(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelPlay(handle: DWORD; restart: BOOL): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelStart(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelStop(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelPause(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelUpdate(handle, length: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetAttribute(handle, attrib: DWORD; value: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetAttribute(handle, attrib: DWORD; var value: Single): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSlideAttribute(handle, attrib: DWORD; value: Single; time: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelIsSliding(handle, attrib: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelSetAttributeEx(handle, attrib: DWORD; value: Pointer; typesize: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelGetAttributeEx(handle, attrib: DWORD; value: Pointer; typesize: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};external bassdll;
+function BASS_ChannelSet3DAttributes(handle: DWORD; mode: Integer; min, max: Single; iangle, oangle, outvol: Integer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGet3DAttributes(handle: DWORD; var mode: DWORD; var min, max: Single; var iangle, oangle, outvol: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSet3DPosition(handle: DWORD; var pos, orient, vel: BASS_3DVECTOR): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGet3DPosition(handle: DWORD; var pos, orient, vel: BASS_3DVECTOR): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetLength(handle, mode: DWORD): QWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetPosition(handle: DWORD; pos: QWORD; mode: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetPosition(handle, mode: DWORD): QWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetLevel(handle: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetLevelEx(handle: DWORD; levels: PSingle; length: Single; flags: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelGetData(handle: DWORD; buffer: Pointer; length: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetSync(handle: DWORD; type_: DWORD; param: QWORD; proc: SYNCPROC; user: Pointer): HSYNC; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelRemoveSync(handle: DWORD; sync: HSYNC): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetDSP(handle: DWORD; proc: DSPPROC; user: Pointer; priority: Integer): HDSP; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetDSPEx(handle: DWORD; proc: DSPPROC; user: Pointer; priority: Integer; flags: DWORD): HDSP; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelRemoveDSP(handle: DWORD; dsp: HDSP): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetLink(handle, chan: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelRemoveLink(handle, chan: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelSetFX(handle, type_: DWORD; priority: Integer): HFX; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_ChannelRemoveFX(handle: DWORD; fx: HFX): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_FXSetParameters(handle: HFX; par: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_FXGetParameters(handle: HFX; par: Pointer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_FXSetPriority(handle: DWORD; priority: Integer): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_FXSetBypass(handle: DWORD; bypass: BOOL): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_FXReset(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+function BASS_FXFree(handle: DWORD): BOOL; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassdll;
+
+function BASS_SPEAKER_N(const n: DWORD): DWORD;
+function BASS_DSP_MONO_N(const n: DWORD): DWORD;
+function BASS_DSP_STEREO_N(const n: DWORD): DWORD;
+
+{$IFNDEF MSWINDOWS}
+function LOBYTE(const n: DWORD): BYTE;
+function HIBYTE(const n: DWORD): BYTE;
+function LOWORD(const n: DWORD): WORD;
+function HIWORD(const n: DWORD): WORD;
+function MAKEWORD(const a, b: BYTE): WORD;
+function MAKELONG(const a, b: WORD): DWORD;
+{$ENDIF}
+
+implementation
+
+function BASS_SPEAKER_N(const n: DWORD): DWORD;
+begin
+ Result := n shl 24;
+end;
+
+function BASS_DSP_MONO_N(const n: DWORD): DWORD;
+begin
+ Result := n shl 24;
+end;
+
+function BASS_DSP_STEREO_N(const n: DWORD): DWORD;
+begin
+ Result := BASS_DSP_MONO_N(n) or $800000;
+end;
+
+{$IFNDEF MSWINDOWS}
+function LOBYTE(const n: DWORD): BYTE;
+begin
+ Result := n;
+end;
+
+function HIBYTE(const n: DWORD): BYTE;
+begin
+ Result := n shr 8;
+end;
+
+function LOWORD(const n: DWORD): WORD;
+begin
+ Result := n;
+end;
+
+function HIWORD(const n: DWORD): WORD;
+begin
+ Result := n shr 16;
+end;
+
+function MAKEWORD(const a, b: BYTE): WORD;
+begin
+ Result := a or (b shl 8);
+end;
+
+function MAKELONG(const a, b: WORD): DWORD;
+begin
+ Result := a or (b shl 16);
+end;
+{$ENDIF}
+
+end.
+
diff --git a/units/dglOpenGL.pas b/units/dglOpenGL.pas
new file mode 100644
index 0000000..1d53533
--- /dev/null
+++ b/units/dglOpenGL.pas
@@ -0,0 +1,20732 @@
+{ ============================================================================
+
+ OpenGL 4.6 - Headertranslation
+
+ Supported environments and targets :
+ - (Win32) Delphi 6 and up
+ - (Win32, Win64) Delphi XE2
+ - (Win32, Win64, Linux, MacOSX) FreePascal (1.9.3 and up)
+
+==============================================================================
+
+ Copyright (C) DGL-OpenGL-Portteam
+ All Rights Reserved
+
+ Obtained through:
+ Bitbucket source repository - https://bitbucket.org/saschawillems/dglopengl
+ Delphi OpenGL Community(DGL) - www.delphigl.com
+
+ Converted and maintained by DGL's OpenGL-Portteam :
+ - Sascha Willems - http://www.saschawillems.de
+ - Steffen Xonna (Lossy eX) - http://www.dev-center.de
+ Additional input :
+ - Andrey Gruzdev (Mac OS X patch for XE2 / FPC)
+ - Lars Middendorf
+ - Martin Waldegger (Mars)
+ - Benjamin Rosseaux (BeRo) - http://www.0ok.de
+ Additional thanks:
+ sigsegv (libdl.so)
+
+==============================================================================
+
+ You may retrieve the latest version of this file at the Delphi OpenGL
+ Community home page, located at http://www.delphigl.com/
+
+ This Source Code Form is subject to the terms of the Mozilla Public License,
+ v. 2.0. If a copy of the MPL was not distributed with this file,
+ You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ Software distributed under the License is distributed on an
+ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+============================================================================== }
+
+{$define DGL_DEPRECATED}
+{
+ This define defines if the header should use deprecated ARB stuff or not.
+ per Default the Header use deprecated Stuff.
+}
+
+
+{.$define DGL_TINY_HEADER}
+{
+ If you enable the define DGL_TINY_HEADER no function automatically will be loaded if you
+ call ActivateRenderingContext. This may some bit faster and the smart linker can delete
+ all non used functions. This will reduce the filesize of your binary file. But in this
+ case you have to load the functions by yourself. There are two ways to do this.
+
+ 1. You can load whole extension by calling the func Read_Extensionname. But if you do
+ this it's possible to load functions you dont use. So you have the same "problem"
+ like before. But it's only an bit smaler.
+ > Read_GL_ARB_multitexture;
+
+ 2. You are able to load only the functions you exactly need. In this case you are able
+ to use the variables of the dglOpenGL.pas. So you only need to load the functions
+ and you can use the header like before.
+ To do this you have to created and activated an opengl context and than you can load
+ the needed functions.
+ > ActivateRenderingContext(fDC, fRC);
+ > glActiveTextureARB := dglGetProcAddress('glActiveTextureARB');
+ > glMultiTexCoord2fARB := dglGetProcAddress('glMultiTexCoord2fARB');
+
+ So only the function "glActiveTextureARB" and "glMultiTexCoord2fARB" will be loaded.
+
+
+ Please notice that the extension variables won't be loaded if this define is active. But
+ you can call dglCheckExtension to check if any extension exists. You can assign them to
+ the variables of the dglOpenGL.pas so all code they use this will find them.
+
+ > GL_ARB_shading_language_100 := dglCheckExtension('GL_ARB_shading_language_100');
+}
+
+
+unit dglOpenGL;
+
+interface
+
+// defines to configure freepascal
+{$IFDEF FPC}
+ {$MODE Delphi}
+
+ {$IFNDEF WINDOWS}
+ {$LINKLIB c}
+ {$ENDIF}
+{$ENDIF}
+
+// known delphi versions
+{$IFNDEF FPC} // if freepascal isnt defined
+ {$IFDEF VER140} // Delphi 6
+ {$DEFINE DELPHI6_AND_DOWN}
+ {$ENDIF}
+
+ {$IFDEF VER130} // Delphi 5
+ {$DEFINE DELPHI6_AND_DOWN}
+ {$ENDIF}
+
+ {$IFDEF VER120} // Delphi 4
+ {$DEFINE DELPHI6_AND_DOWN}
+ {$ENDIF}
+
+ {$IFDEF VER110} // C++ Builder 3
+ {$DEFINE DELPHI6_AND_DOWN}
+ {$ENDIF}
+
+ {$IFDEF VER100} // Delphi 3
+ {$DEFINE DELPHI6_AND_DOWN}
+ {$ENDIF}
+{$ENDIF}
+
+// Options for Delphi < 5
+{$IFDEF DELPHI6_AND_DOWN}
+ {$A+}
+{$ELSE}
+ {$A4}
+{$ENDIF}
+
+// 64 BIT architecture
+// Free pascal
+{$IFDEF CPU64}
+ {$DEFINE DGL_64BIT}
+{$ENDIF}
+// Delphi
+{$IFDEF WIN64}
+ {$DEFINE DGL_64BIT}
+{$ENDIF}
+
+
+// generell options
+{$H+,O+,X+}
+
+// detecting Windows
+{$IFDEF Win32} // Delphi and fpc of 32 Bit Windows
+ {$DEFINE DGL_WIN}
+{$ENDIF}
+
+{$IFDEF Win64} // Delphi and fpc of 32 Bit Windows
+ {$DEFINE DGL_WIN}
+{$ENDIF}
+
+// detecting Linux
+{$IFDEF linux} // Linux
+ {$DEFINE DGL_LINUX}
+{$ENDIF}
+
+{$IFDEF DARWIN} // Mac OS X and FPC
+ {$DEFINE DGL_MAC}
+{$ENDIF}
+
+{$IFDEF DELPHI} // Mac OS X add Delphi
+{$IFDEF MACOS}
+ {$DEFINE DGL_MAC}
+{$ENDIF}
+{$ENDIF}
+
+uses
+ {$IFDEF FPC}{$IFDEF DARWIN}dynlibs,{$ENDIF}{$ENDIF} // LoadLibrary functions
+ SysUtils
+ {$IFDEF DGL_WIN}, Windows{$ENDIF}
+ {$IFDEF DGL_64BIT} ,math {$ENDIF}
+ {$IFDEF DGL_LINUX}, X, XLib, XUtil{$ENDIF}
+ ;
+
+type
+ {$IFDEF DELPHI6_AND_DOWN}
+ // Delphi 6 compatibility
+ PPointer = ^Pointer;
+ PCardinal = ^Cardinal;
+ {$ENDIF}
+
+ GLenum = Cardinal;
+ GLboolean = BYTEBOOL;
+ GLbitfield = Cardinal;
+ GLbyte = Shortint;
+ GLshort = SmallInt;
+ GLint = Integer;
+ GLsizei = Integer;
+ GLubyte = Byte;
+ GLushort = Word;
+ GLuint = Cardinal;
+ GLfloat = Single;
+ GLclampf = Single;
+ GLdouble = Double;
+ GLclampd = Double;
+ GLvoid = Pointer;
+ GLint64 = Int64;
+ GLuint64 = {$IFDEF DELPHI6_AND_DOWN} Int64 {$ELSE} UInt64 {$ENDIF};
+
+ TGLenum = GLenum;
+ TGLboolean = GLboolean;
+ TGLbitfield = GLbitfield;
+ TGLbyte = GLbyte;
+ TGLshort = GLshort;
+ TGLint = GLint;
+ TGLsizei = GLsizei;
+ TGLubyte = GLubyte;
+ TGLushort = GLushort;
+ TGLuint = GLuint;
+ TGLfloat = GLfloat;
+ TGLclampf = GLclampf;
+ TGLdouble = GLdouble;
+ TGLclampd = GLclampd;
+ TGLvoid = GLvoid;
+ TGLint64 = GLint64;
+ TGLuint64 = GLuint64;
+
+ PGLboolean = ^GLboolean;
+ PGLbyte = ^GLbyte;
+ PGLshort = ^GLshort;
+ PGLint = ^GLint;
+ PGLsizei = ^GLsizei;
+ PGLubyte = ^GLubyte;
+ PGLushort = ^GLushort;
+ PGLuint = ^GLuint;
+ PGLclampf = ^GLclampf;
+ PGLfloat = ^GLfloat;
+ PGLdouble = ^GLdouble;
+ PGLclampd = ^GLclampd;
+ PGLenum = ^GLenum;
+ PGLvoid = Pointer;
+ PPGLvoid = ^PGLvoid;
+ PGLint64 = ^GLint64;
+ PGLuint64 = ^GLuint64;
+
+ // GL_NV_half_float
+ GLhalfNV = WORD;
+ TGLhalfNV = GLhalfNV;
+ PGLhalfNV = ^GLhalfNV;
+
+ // GL_ARB_shader_objects
+ PGLHandleARB = ^GLHandleARB;
+ GLHandleARB = Integer;
+ GLcharARB = AnsiChar;
+ PGLcharARB = PAnsiChar;
+ PPGLcharARB = ^PGLcharARB;
+
+ // GL_VERSION_1_5
+ GLintptr = GLint;
+ PGLintptr = ^GLintptr;
+ GLsizeiptr = GLsizei;
+
+ // GL_ARB_vertex_buffer_object
+ GLintptrARB = GLint;
+ GLsizeiptrARB = GLsizei;
+
+ // GL_VERSION_2_0
+ GLHandle = Integer;
+ PGLchar = PAnsiChar;
+ PPGLchar = ^PGLChar;
+
+ // GL_EXT_timer_query
+ GLint64EXT = Int64;
+ TGLint64EXT = GLint64EXT;
+ PGLint64EXT = ^GLint64EXT;
+
+ GLuint64EXT = GLuint64;
+ TGLuint64EXT = GLuint64EXT;
+ PGLuint64EXT = ^GLuint64EXT;
+
+ // WGL_ARB_pbuffer
+ HPBUFFERARB = THandle;
+
+ // WGL_EXT_pbuffer
+ HPBUFFEREXT = THandle;
+
+ // WGL_NV_present_video
+ PHVIDEOOUTPUTDEVICENV = ^HVIDEOOUTPUTDEVICENV;
+ HVIDEOOUTPUTDEVICENV = THandle;
+
+ // WGL_NV_video_output
+ PHPVIDEODEV = ^HPVIDEODEV;
+ HPVIDEODEV = THandle;
+
+ // WGL_NV_gpu_affinity
+ PHPGPUNV = ^HPGPUNV;
+ PHGPUNV = ^HGPUNV;
+
+ // WGL_NV_video_capture
+ HVIDEOINPUTDEVICENV = THandle;
+ PHVIDEOINPUTDEVICENV = ^HVIDEOINPUTDEVICENV;
+
+ HPGPUNV = THandle;
+ HGPUNV = THandle;
+
+ // GL_ARB_sync
+ GLsync = Pointer;
+
+ // GL_ARB_cl_event
+ { These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event }
+ _cl_context = record end;
+ _cl_event = record end;
+ p_cl_context = ^_cl_context;
+ p_cl_event = ^_cl_event;
+
+ // GL_ARB_compute_variable_group_size
+ TglDispatchComputeGroupSizeARB = procedure (num_groups_x : GLuint; num_groups_y : GLuint; num_groups_z : GLuint; group_size_x : GLuint; group_size_y : GLuint; group_size_z : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_debug_output
+ TglDebugProcARB = procedure (source: GLenum; type_: GLenum; id: GLuint; severity: GLenum; length: GLsizei; const message_: PGLchar; userParam: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_debug_output
+ TglDebugProcAMD = procedure (id: GLuint; category: GLenum; severity: GLenum; length: GLsizei; const message_: PGLchar; userParam: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_KHR_debug (4.3)
+ TglDebugProc = procedure(source : GLEnum; type_ : GLEnum; id : GLUInt; severity : GLUInt; length : GLsizei; const message_ : PGLCHar; userParam : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vdpau_interop
+ GLvdpauSurfaceNV = GLintptr;
+ PGLvdpauSurfaceNV = ^GLvdpauSurfaceNV;
+
+
+ // GLX
+ {$IFDEF DGL_LINUX}
+ GLXContext = Pointer;
+ GLXContextID = TXID;
+ GLXDrawable = TXID;
+ GLXFBConfig = Pointer;
+ GLXPbuffer = TXID;
+ GLXPixmap = TXID;
+ GLXWindow = TXID;
+
+ Window = TXID;
+ Colormap = TXID;
+ Pixmap = TXID;
+ Font = TXID;
+ {$ENDIF}
+
+ // Datatypes corresponding to GL's types TGL(name)(type)(count)
+ TGLVectorub2 = array[0..1] of GLubyte;
+ TGLVectori2 = array[0..1] of GLint;
+ TGLVectorf2 = array[0..1] of GLfloat;
+ TGLVectord2 = array[0..1] of GLdouble;
+ TGLVectorp2 = array[0..1] of Pointer;
+
+ TGLVectorub3 = array[0..2] of GLubyte;
+ TGLVectori3 = array[0..2] of GLint;
+ TGLVectorf3 = array[0..2] of GLfloat;
+ TGLVectord3 = array[0..2] of GLdouble;
+ TGLVectorp3 = array[0..2] of Pointer;
+
+ TGLVectorub4 = array[0..3] of GLubyte;
+ TGLVectori4 = array[0..3] of GLint;
+ TGLVectorf4 = array[0..3] of GLfloat;
+ TGLVectord4 = array[0..3] of GLdouble;
+ TGLVectorp4 = array[0..3] of Pointer;
+
+ TGLArrayf4 = TGLVectorf4;
+ TGLArrayf3 = TGLVectorf3;
+ TGLArrayd3 = TGLVectord3;
+ TGLArrayi4 = TGLVectori4;
+ TGLArrayp4 = TGLVectorp4;
+
+ TGlMatrixub3 = array[0..2, 0..2] of GLubyte;
+ TGlMatrixi3 = array[0..2, 0..2] of GLint;
+ TGLMatrixf3 = array[0..2, 0..2] of GLfloat;
+ TGLMatrixd3 = array[0..2, 0..2] of GLdouble;
+
+ TGlMatrixub4 = array[0..3, 0..3] of GLubyte;
+ TGlMatrixi4 = array[0..3, 0..3] of GLint;
+ TGLMatrixf4 = array[0..3, 0..3] of GLfloat;
+ TGLMatrixd4 = array[0..3, 0..3] of GLdouble;
+
+ TGLVector3f = TGLVectorf3;
+
+ // Datatypes corresponding to OpenGL12.pas for easy porting
+ TVector3f = TGLVectorf3;
+ TVector3d = TGLVectord3;
+
+ TVector4i = TGLVectori4;
+ TVector4f = TGLVectorf4;
+ TVector4p = TGLVectorp4;
+
+ TMatrix4f = TGLMatrixf4;
+ TMatrix4d = TGLMatrixd4;
+
+ PGLMatrixd4 = ^TGLMatrixd4;
+ PVector4i = ^TVector4i;
+{$IFDEF DGL_WIN}
+ PGPU_DEVICE = ^GPU_DEVICE;
+ GPU_DEVICE = record
+ cb: DWORD;
+ DeviceName: array [0..31] of AnsiChar;
+ DeviceString: array [0..127] of AnsiChar;
+ Flags: DWORD;
+ rcVirtualScreen: TRect;
+ end;
+{$ENDIF}
+
+type
+{$IFDEF FPC}
+ {$IFDEF DGL_WIN}
+ PWGLSwap = ^TWGLSwap;
+ {$EXTERNALSYM _WGLSWAP}
+ _WGLSWAP = packed record
+ hdc: HDC;
+ uiFlags: UINT;
+ end;
+
+ TWGLSwap = _WGLSWAP;
+ {$EXTERNALSYM WGLSWAP}
+ WGLSWAP = _WGLSWAP;
+
+ {$ENDIF}
+{$ENDIF}
+
+ // GLU types
+ TGLUNurbs = record
+ end;
+ TGLUQuadric = record
+ end;
+ TGLUTesselator = record
+ end;
+ PGLUNurbs = ^TGLUNurbs;
+ PGLUQuadric = ^TGLUQuadric;
+ PGLUTesselator = ^TGLUTesselator;
+ // backwards compatibility
+ TGLUNurbsObj = TGLUNurbs;
+ TGLUQuadricObj = TGLUQuadric;
+ TGLUTesselatorObj = TGLUTesselator;
+ TGLUTriangulatorObj = TGLUTesselator;
+ PGLUNurbsObj = PGLUNurbs;
+ PGLUQuadricObj = PGLUQuadric;
+ PGLUTesselatorObj = PGLUTesselator;
+ PGLUTriangulatorObj = PGLUTesselator;
+
+ // GLUQuadricCallback
+ TGLUQuadricErrorProc = procedure(errorCode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ // GLUTessCallback
+ TGLUTessBeginProc = procedure(AType: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessEdgeFlagProc = procedure(Flag: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessVertexProc = procedure(VertexData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessEndProc = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessErrorProc = procedure(ErrNo: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessCombineProc = procedure(Coords: TGLArrayd3; VertexData: TGLArrayp4; Weight: TGLArrayf4; OutData: PPointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessBeginDataProc = procedure(AType: GLenum; UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessEdgeFlagDataProc = procedure(Flag: GLboolean; UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessVertexDataProc = procedure(VertexData: Pointer; UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessEndDataProc = procedure(UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessErrorDataProc = procedure(ErrNo: GLenum; UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TGLUTessCombineDataProc = procedure(Coords: TGLArrayd3; VertexData: TGLArrayp4; Weight: TGLArrayf4; OutData: PPointer; UserData: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ // GLUNurbsCallback
+ TGLUNurbsErrorProc = procedure(ErrorCode: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+var
+ GL_VERSION_1_0,
+ GL_VERSION_1_1,
+ GL_VERSION_1_2,
+ GL_VERSION_1_3,
+ GL_VERSION_1_4,
+ GL_VERSION_1_5,
+ GL_VERSION_2_0,
+ GL_VERSION_2_1,
+ GL_VERSION_3_0,
+ GL_VERSION_3_1,
+ GL_VERSION_3_2,
+ GL_VERSION_3_3,
+ GL_VERSION_4_0,
+ GL_VERSION_4_1,
+ GL_VERSION_4_2,
+ GL_VERSION_4_3,
+ GL_VERSION_4_4,
+ GL_VERSION_4_5,
+ GL_VERSION_4_6,
+ GLU_VERSION_1_1,
+ GLU_VERSION_1_2,
+ GLU_VERSION_1_3,
+ GL_3DFX_multisample,
+ GL_3DFX_tbuffer,
+ GL_3DFX_texture_compression_FXT1,
+ GL_APPLE_client_storage,
+ GL_APPLE_element_array,
+ GL_APPLE_fence,
+ GL_APPLE_specular_vector,
+ GL_APPLE_transform_hint,
+ GL_APPLE_vertex_array_object,
+ GL_APPLE_vertex_array_range,
+ GL_APPLE_ycbcr_422,
+ GL_APPLE_texture_range,
+ GL_APPLE_float_pixels,
+ GL_APPLE_vertex_program_evaluators,
+ GL_APPLE_aux_depth_stencil,
+ GL_APPLE_object_purgeable,
+ GL_APPLE_row_bytes,
+ GL_APPLE_rgb_422,
+ GL_ARB_depth_texture,
+ GL_ARB_fragment_program,
+ GL_ARB_imaging,
+ GL_ARB_matrix_palette,
+ GL_ARB_multisample,
+ GL_ARB_multitexture,
+ GL_ARB_point_parameters,
+ GL_ARB_shadow,
+ GL_ARB_shadow_ambient,
+ GL_ARB_texture_border_clamp,
+ GL_ARB_texture_compression,
+ GL_ARB_texture_cube_map,
+ GL_ARB_texture_env_add,
+ GL_ARB_texture_env_combine,
+ GL_ARB_texture_env_crossbar,
+ GL_ARB_texture_env_dot3,
+ GL_ARB_texture_filter_minmax,
+ GL_ARB_texture_mirrored_repeat,
+ GL_ARB_transpose_matrix,
+ GL_ARB_vertex_blend,
+ GL_ARB_vertex_buffer_object,
+ GL_ARB_vertex_program,
+ GL_ARB_window_pos,
+ GL_ARB_shader_objects,
+ GL_ARB_vertex_shader,
+ GL_ARB_fragment_shader,
+ GL_ARB_fragment_shader_interlock,
+ GL_ARB_shading_language_100,
+ GL_ARB_occlusion_query,
+ GL_ARB_texture_non_power_of_two,
+ GL_ARB_point_sprite,
+ GL_ARB_fragment_program_shadow,
+ GL_ARB_draw_buffers,
+ GL_ARB_texture_rectangle,
+ GL_ARB_color_buffer_float,
+ GL_ARB_half_float_pixel,
+ GL_ARB_texture_float,
+ GL_ARB_pixel_buffer_object,
+ GL_ARB_depth_buffer_float,
+ GL_ARB_draw_instanced,
+ GL_ARB_framebuffer_object,
+ GL_ARB_framebuffer_sRGB,
+ GL_ARB_geometry_shader4,
+ GL_ARB_half_float_vertex,
+ GL_ARB_instanced_arrays,
+ GL_ARB_map_buffer_range,
+ GL_ARB_texture_buffer_object,
+ GL_ARB_texture_compression_rgtc,
+ GL_ARB_texture_rg,
+ GL_ARB_vertex_array_object,
+ GL_ARB_uniform_buffer_object,
+ GL_ARB_compatibility,
+ GL_ARB_copy_buffer,
+ GL_ARB_shader_texture_lod,
+ GL_ARB_shader_viewport_layer_array,
+ GL_ARB_depth_clamp,
+ GL_ARB_draw_elements_base_vertex,
+ GL_ARB_fragment_coord_conventions,
+ GL_ARB_provoking_vertex,
+ GL_ARB_seamless_cube_map,
+ GL_ARB_sync,
+ GL_ARB_texture_multisample,
+ GL_ARB_vertex_array_bgra,
+ GL_ARB_draw_buffers_blend,
+ GL_ARB_sample_shading,
+ GL_ARB_sample_locations,
+ GL_ARB_sparse_texture2,
+ GL_ARB_sparse_texture_clamp,
+ GL_ARB_texture_cube_map_array,
+ GL_ARB_texture_gather,
+ GL_ARB_texture_query_lod,
+ GL_ARB_shading_language_include,
+ GL_ARB_texture_compression_bptc,
+ GL_ARB_blend_func_extended,
+ GL_ARB_explicit_attrib_location,
+ GL_ARB_occlusion_query2,
+ GL_ARB_parallel_shader_compile,
+ GL_ARB_post_depth_coverage,
+ GL_ARB_sampler_objects,
+ GL_ARB_shader_bit_encoding,
+ GL_ARB_shader_clock,
+ GL_ARB_texture_rgb10_a2ui,
+ GL_ARB_texture_swizzle,
+ GL_ARB_timer_query,
+ GL_ARB_vertex_type_2_10_10_10_rev,
+ GL_ARB_draw_indirect,
+ GL_ARB_gpu_shader5,
+ GL_ARB_gpu_shader_fp64,
+ GL_ARB_gpu_shader_int64,
+ GL_ARB_shader_subroutine,
+ GL_ARB_tessellation_shader,
+ GL_ARB_texture_buffer_object_rgb32,
+ GL_ARB_transform_feedback2,
+ GL_ARB_transform_feedback3,
+ GL_ARB_ES2_compatibility,
+ GL_ARB_ES3_2_compatibility,
+ GL_ARB_get_program_binary,
+ GL_ARB_separate_shader_objects,
+ GL_ARB_shader_precision,
+ GL_ARB_shader_ballot,
+ GL_ARB_vertex_attrib_64bit,
+ GL_ARB_viewport_array,
+
+ // GL 4.2
+ GL_ARB_base_instance,
+ GL_ARB_shading_language_420pack,
+ GL_ARB_transform_feedback_instanced,
+ GL_ARB_compressed_texture_pixel_storage,
+ GL_ARB_conservative_depth,
+ GL_ARB_internalformat_query,
+ GL_ARB_map_buffer_alignment,
+ GL_ARB_shader_atomic_counters,
+ GL_ARB_shader_image_load_store,
+ GL_ARB_shading_language_packing,
+ GL_ARB_texture_storage,
+
+
+ // GL 4.3
+ GL_ARB_arrays_of_arrays,
+ GL_ARB_fragment_layer_viewport,
+ GL_ARB_shader_image_size,
+ GL_ARB_ES3_compatibility,
+ GL_ARB_clear_buffer_object,
+ GL_ARB_compute_shader,
+ GL_ARB_copy_image,
+ GL_KHR_debug,
+ GL_ARB_explicit_uniform_location,
+ GL_ARB_framebuffer_no_attachments,
+ GL_ARB_internalformat_query2,
+ GL_ARB_invalidate_subdata,
+ GL_ARB_multi_draw_indirect,
+ GL_ARB_program_interface_query,
+ GL_ARB_robust_buffer_access_behavior,
+ GL_ARB_shader_storage_buffer_object,
+ GL_ARB_stencil_texturing,
+ GL_ARB_texture_buffer_range,
+ GL_ARB_texture_query_levels,
+ GL_ARB_texture_storage_multisample,
+ GL_ARB_texture_view,
+ GL_ARB_vertex_attrib_binding,
+ GL_NV_path_rendering,
+ GL_AMD_pinned_memory,
+ GL_AMD_stencil_operation_extended,
+ GL_AMD_vertex_shader_viewport_index,
+ GL_AMD_vertex_shader_layer,
+ GL_NV_bindless_texture,
+ GL_NV_shader_atomic_float,
+ GL_AMD_query_buffer_object,
+
+
+ // GL 4.4
+ GL_ARB_buffer_storage,
+ GL_ARB_clear_texture,
+ GL_ARB_enhanced_layouts,
+ GL_ARB_multi_bind,
+ GL_ARB_query_buffer_object,
+ GL_ARB_texture_mirror_clamp_to_edge,
+ GL_ARB_texture_stencil8,
+ GL_ARB_vertex_type_10f_11f_11f_rev,
+ GL_ARB_bindless_texture,
+ GL_ARB_sparse_texture,
+
+ // GL 4.5
+ GL_ARB_clip_control,
+ GL_ARB_cull_distance,
+ GL_ARB_ES3_1_compatibility,
+ GL_ARB_conditional_render_inverted,
+ GL_KHR_context_flush_control,
+ GL_ARB_derivative_control,
+ GL_ARB_direct_state_access,
+ GL_ARB_get_texture_sub_image,
+ GL_KHR_robustness,
+ GL_KHR_blend_equation_advanced,
+ GL_KHR_blend_equation_advanced_coherent,
+ GL_KHR_robust_buffer_access_behavior,
+ GL_ARB_shader_texture_image_samples,
+ GL_ARB_texture_barrier,
+
+ // GL 4.6
+ GL_ARB_indirect_parameters,
+ GL_ARB_pipeline_statistics_query,
+ GL_ARB_polygon_offset_clamp,
+ GL_KHR_no_error,
+ GL_ARB_shader_atomic_counter_ops,
+ GL_ARB_shader_draw_parameters,
+ GL_ARB_shader_group_vote,
+ GL_ARB_gl_spirv,
+ GL_ARB_spirv_extensions,
+ GL_ARB_texture_filter_anisotropic,
+ GL_ARB_transform_feedback_overflow_query,
+
+ GL_ARB_cl_event,
+ GL_ARB_compute_variable_group_size,
+ GL_ARB_debug_output,
+ GL_ARB_robustness,
+ GL_ARB_shader_stencil_export,
+ GL_ATI_draw_buffers,
+ GL_ATI_element_array,
+ GL_ATI_envmap_bumpmap,
+ GL_ATI_fragment_shader,
+ GL_ATI_map_object_buffer,
+ GL_ATI_pn_triangles,
+ GL_ATI_separate_stencil,
+ GL_ATI_text_fragment_shader,
+ GL_ATI_texture_env_combine3,
+ GL_ATI_texture_float,
+ GL_ATI_texture_mirror_once,
+ GL_ATI_vertex_array_object,
+ GL_ATI_vertex_attrib_array_object,
+ GL_ATI_vertex_streams,
+ GL_ATI_meminfo,
+ GL_AMD_performance_monitor,
+ GL_AMD_texture_texture4,
+ GL_AMD_vertex_shader_tesselator,
+ GL_AMD_draw_buffers_blend,
+ GL_AMD_shader_stencil_export,
+ GL_AMD_seamless_cubemap_per_texture,
+ GL_AMD_conservative_depth,
+ GL_AMD_name_gen_delete,
+ GL_AMD_debug_output,
+ GL_AMD_transform_feedback3_lines_triangles,
+ GL_AMD_depth_clamp_separate,
+ GL_EXT_422_pixels,
+ GL_EXT_abgr,
+ GL_EXT_bgra,
+ GL_EXT_blend_color,
+ GL_EXT_blend_func_separate,
+ GL_EXT_blend_logic_op,
+ GL_EXT_blend_minmax,
+ GL_EXT_blend_subtract,
+ GL_EXT_clip_volume_hint,
+ GL_EXT_cmyka,
+ GL_EXT_color_matrix,
+ GL_EXT_color_subtable,
+ GL_EXT_compiled_vertex_array,
+ GL_EXT_convolution,
+ GL_EXT_coordinate_frame,
+ GL_EXT_copy_texture,
+ GL_EXT_cull_vertex,
+ GL_EXT_draw_range_elements,
+ GL_EXT_fog_coord,
+ GL_EXT_framebuffer_object,
+ GL_EXT_histogram,
+ GL_EXT_index_array_formats,
+ GL_EXT_index_func,
+ GL_EXT_index_material,
+ GL_EXT_index_texture,
+ GL_EXT_light_texture,
+ GL_EXT_misc_attribute,
+ GL_EXT_multi_draw_arrays,
+ GL_EXT_multisample,
+ GL_EXT_packed_pixels,
+ GL_EXT_paletted_texture,
+ GL_EXT_pixel_transform,
+ GL_EXT_pixel_transform_color_table,
+ GL_EXT_point_parameters,
+ GL_EXT_polygon_offset,
+ GL_EXT_rescale_normal,
+ GL_EXT_secondary_color,
+ GL_EXT_separate_specular_color,
+ GL_EXT_shadow_funcs,
+ GL_EXT_shared_texture_palette,
+ GL_EXT_stencil_two_side,
+ GL_EXT_stencil_wrap,
+ GL_EXT_subtexture,
+ GL_EXT_texture,
+ GL_EXT_texture3D,
+ GL_EXT_texture_compression_s3tc,
+ GL_EXT_texture_cube_map,
+ GL_EXT_texture_edge_clamp,
+ GL_EXT_texture_env_add,
+ GL_EXT_texture_env_combine,
+ GL_EXT_texture_env_dot3,
+ GL_EXT_texture_filter_anisotropic,
+ GL_EXT_texture_lod_bias,
+ GL_EXT_texture_object,
+ GL_EXT_texture_perturb_normal,
+ GL_EXT_texture_rectangle,
+ GL_EXT_vertex_array,
+ GL_EXT_vertex_shader,
+ GL_EXT_vertex_weighting,
+ GL_EXT_depth_bounds_test,
+ GL_EXT_texture_mirror_clamp,
+ GL_EXT_blend_equation_separate,
+ GL_EXT_pixel_buffer_object,
+ GL_EXT_texture_compression_dxt1,
+ GL_EXT_stencil_clear_tag,
+ GL_EXT_packed_depth_stencil,
+ GL_EXT_texture_sRGB,
+ GL_EXT_framebuffer_blit,
+ GL_EXT_framebuffer_multisample,
+ GL_EXT_timer_query,
+ GL_EXT_gpu_program_parameters,
+ GL_EXT_bindable_uniform,
+ GL_EXT_draw_buffers2,
+ GL_EXT_draw_instanced,
+ GL_EXT_framebuffer_sRGB,
+ GL_EXT_geometry_shader4,
+ GL_EXT_gpu_shader4,
+ GL_EXT_packed_float,
+ GL_EXT_texture_array,
+ GL_EXT_texture_buffer_object,
+ GL_EXT_texture_compression_latc,
+ GL_EXT_texture_compression_rgtc,
+ GL_EXT_texture_integer,
+ GL_EXT_texture_shared_exponent,
+ GL_EXT_transform_feedback,
+ GL_EXT_direct_state_access,
+ GL_EXT_vertex_array_bgra,
+ GL_EXT_texture_swizzle,
+ GL_EXT_provoking_vertex,
+ GL_EXT_texture_snorm,
+ GL_EXT_separate_shader_objects,
+ GL_EXT_shader_image_load_store,
+ GL_EXT_vertex_attrib_64bit,
+ GL_EXT_texture_sRGB_decode,
+ GL_FfdMaskSGIX,
+ GL_HP_convolution_border_modes,
+ GL_HP_image_transform,
+ GL_HP_occlusion_test,
+ GL_HP_texture_lighting,
+ GL_IBM_cull_vertex,
+ GL_IBM_multimode_draw_arrays,
+ GL_IBM_rasterpos_clip,
+ GL_IBM_texture_mirrored_repeat,
+ GL_IBM_vertex_array_lists,
+ GL_INGR_blend_func_separate,
+ GL_INGR_color_clamp,
+ GL_INGR_interlace_read,
+ GL_INGR_palette_buffer,
+ GL_INTEL_framebuffer_CMAA,
+ GL_INTEL_parallel_arrays,
+ GL_INTEL_texture_scissor,
+ GL_MESA_resize_buffers,
+ GL_MESA_window_pos,
+ GL_NV_blend_square,
+ GL_NV_copy_depth_to_color,
+ GL_NV_depth_clamp,
+ GL_NV_evaluators,
+ GL_NV_fence,
+ GL_NV_float_buffer,
+ GL_NV_fog_distance,
+ GL_NV_fragment_program,
+ GL_NV_half_float,
+ GL_NV_light_max_exponent,
+ GL_NV_multisample_filter_hint,
+ GL_NV_occlusion_query,
+ GL_NV_packed_depth_stencil,
+ GL_NV_pixel_data_range,
+ GL_NV_point_sprite,
+ GL_NV_primitive_restart,
+ GL_NV_register_combiners,
+ GL_NV_register_combiners2,
+ GL_NV_texgen_emboss,
+ GL_NV_texgen_reflection,
+ GL_NV_texture_compression_vtc,
+ GL_NV_texture_env_combine4,
+ GL_NV_texture_expand_normal,
+ GL_NV_texture_rectangle,
+ GL_NV_texture_shader,
+ GL_NV_texture_shader2,
+ GL_NV_texture_shader3,
+ GL_NV_vertex_array_range,
+ GL_NV_vertex_array_range2,
+ GL_NV_vertex_program,
+ GL_NV_vertex_program1_1,
+ GL_NV_vertex_program2,
+ GL_NV_fragment_program_option,
+ GL_NV_fragment_program2,
+ GL_NV_vertex_program2_option,
+ GL_NV_vertex_program3,
+ GL_NV_depth_buffer_float,
+ GL_NV_fragment_program4,
+ GL_NV_framebuffer_multisample_coverage,
+ GL_NV_geometry_program4,
+ GL_NV_gpu_program4,
+ GL_NV_parameter_buffer_object,
+ GL_NV_transform_feedback,
+ GL_NV_vertex_program4,
+ GL_NV_conditional_render,
+ GL_NV_conservative_raster,
+ GL_NV_conservative_raster_dilate,
+
+ GL_NV_present_video,
+ GL_NV_explicit_multisample,
+ GL_NV_transform_feedback2,
+ GL_NV_video_capture,
+ GL_NV_copy_image,
+ GL_NV_parameter_buffer_object2,
+ GL_NV_shader_buffer_load,
+ GL_NV_vertex_buffer_unified_memory,
+ GL_NV_gpu_program5,
+ GL_NV_gpu_shader5,
+ GL_NV_shader_buffer_store,
+ GL_NV_tessellation_program5,
+ GL_NV_vertex_attrib_integer_64bit,
+ GL_NV_multisample_coverage,
+ GL_NV_vdpau_interop,
+ GL_NV_texture_barrier,
+ GL_OML_interlace,
+ GL_OML_resample,
+ GL_OML_subsample,
+
+ GL_OVR_multiview,
+ GL_OVR_multiview2,
+
+ GL_PGI_misc_hints,
+ GL_PGI_vertex_hints,
+ GL_REND_screen_coordinates,
+ GL_S3_s3tc,
+ GL_SGIS_detail_texture,
+ GL_SGIS_fog_function,
+ GL_SGIS_generate_mipmap,
+ GL_SGIS_multisample,
+ GL_SGIS_pixel_texture,
+ GL_SGIS_point_line_texgen,
+ GL_SGIS_point_parameters,
+ GL_SGIS_sharpen_texture,
+ GL_SGIS_texture4D,
+ GL_SGIS_texture_border_clamp,
+ GL_SGIS_texture_color_mask,
+ GL_SGIS_texture_edge_clamp,
+ GL_SGIS_texture_filter4,
+ GL_SGIS_texture_lod,
+ GL_SGIS_texture_select,
+ GL_SGIX_async,
+ GL_SGIX_async_histogram,
+ GL_SGIX_async_pixel,
+ GL_SGIX_blend_alpha_minmax,
+ GL_SGIX_calligraphic_fragment,
+ GL_SGIX_clipmap,
+ GL_SGIX_convolution_accuracy,
+ GL_SGIX_depth_pass_instrument,
+ GL_SGIX_depth_texture,
+ GL_SGIX_flush_raster,
+ GL_SGIX_fog_offset,
+ GL_SGIX_fog_scale,
+ GL_SGIX_fragment_lighting,
+ GL_SGIX_framezoom,
+ GL_SGIX_igloo_interface,
+ GL_SGIX_impact_pixel_texture,
+ GL_SGIX_instruments,
+ GL_SGIX_interlace,
+ GL_SGIX_ir_instrument1,
+ GL_SGIX_list_priority,
+ GL_SGIX_pixel_texture,
+ GL_SGIX_pixel_tiles,
+ GL_SGIX_polynomial_ffd,
+ GL_SGIX_reference_plane,
+ GL_SGIX_resample,
+ GL_SGIX_scalebias_hint,
+ GL_SGIX_shadow,
+ GL_SGIX_shadow_ambient,
+ GL_SGIX_sprite,
+ GL_SGIX_subsample,
+ GL_SGIX_tag_sample_buffer,
+ GL_SGIX_texture_add_env,
+ GL_SGIX_texture_coordinate_clamp,
+ GL_SGIX_texture_lod_bias,
+ GL_SGIX_texture_multi_buffer,
+ GL_SGIX_texture_scale_bias,
+ GL_SGIX_texture_select,
+ GL_SGIX_vertex_preclip,
+ GL_SGIX_ycrcb,
+ GL_SGIX_ycrcb_subsample,
+ GL_SGIX_ycrcba,
+ GL_SGI_color_matrix,
+ GL_SGI_color_table,
+ GL_SGI_depth_pass_instrument,
+ GL_SGI_texture_color_table,
+ GL_SUNX_constant_data,
+ GL_SUN_convolution_border_modes,
+ GL_SUN_global_alpha,
+ GL_SUN_mesh_array,
+ GL_SUN_slice_accum,
+ GL_SUN_triangle_list,
+ GL_SUN_vertex,
+
+ // WGL
+ GL_WIN_phong_shading,
+ GL_WIN_specular_fog,
+ WGL_3DFX_multisample,
+ WGL_ARB_buffer_region,
+ WGL_ARB_extensions_string,
+ WGL_ARB_make_current_read,
+ WGL_ARB_multisample,
+ WGL_ARB_pbuffer,
+ WGL_ARB_pixel_format,
+ WGL_ARB_pixel_format_float,
+ WGL_ARB_render_texture,
+ WGL_ARB_create_context,
+ WGL_ARB_create_context_profile,
+ WGL_ARB_framebuffer_sRGB,
+ WGL_ARB_create_context_robustness,
+ WGL_ATI_pixel_format_float,
+ WGL_AMD_gpu_association,
+ WGL_EXT_depth_float,
+ WGL_EXT_display_color_table,
+ WGL_EXT_extensions_string,
+ WGL_EXT_make_current_read,
+ WGL_EXT_multisample,
+ WGL_EXT_pbuffer,
+ WGL_EXT_pixel_format,
+ WGL_EXT_swap_control,
+ WGL_EXT_create_context_es2_profile,
+ WGL_I3D_digital_video_control,
+ WGL_I3D_gamma,
+ WGL_I3D_genlock,
+ WGL_I3D_image_buffer,
+ WGL_I3D_swap_frame_lock,
+ WGL_I3D_swap_frame_usage,
+ WGL_NV_float_buffer,
+ WGL_NV_render_depth_texture,
+ WGL_NV_render_texture_rectangle,
+ WGL_NV_vertex_array_range,
+ WGL_NV_present_video,
+ WGL_NV_video_output,
+ WGL_NV_swap_group,
+ WGL_NV_gpu_affinity,
+ WGL_NV_video_capture,
+ WGL_NV_copy_image,
+ WGL_NV_multisample_coverage,
+ WGL_NV_DX_interop,
+ WGL_OML_sync_control,
+ WGL_3DL_stereo_control,
+ WGL_ARB_context_flush_control,
+ WIN_draw_range_elements,
+ WIN_swap_hint,
+
+ // GLX
+ GLX_VERSION_1_3,
+ GLX_VERSION_1_4,
+ GLX_ARB_multisample,
+ GLX_ARB_fbconfig_float,
+ GLX_ARB_get_proc_address,
+ GLX_ARB_create_context,
+ GLX_ARB_create_context_profile,
+ GLX_ARB_vertex_buffer_object,
+ GLX_ARB_framebuffer_sRGB,
+ GLX_ARB_create_context_robustness,
+ GLX_EXT_visual_info,
+ GLX_EXT_visual_rating,
+ GLX_EXT_import_context,
+ GLX_EXT_fbconfig_packed_float,
+ GLX_EXT_framebuffer_sRGB,
+ GLX_EXT_texture_from_pixmap,
+ GLX_EXT_swap_control,
+ GLX_ARB_context_flush_control,
+ GLX_EXT_create_context_es2_profile : Boolean;
+
+const
+ // GL_VERSION_1_1
+ { AttribMask }
+ GL_DEPTH_BUFFER_BIT = $00000100;
+ GL_STENCIL_BUFFER_BIT = $00000400;
+ GL_COLOR_BUFFER_BIT = $00004000;
+ { Boolean }
+ GL_TRUE: ByteBool = True;
+ GL_FALSE: ByteBool = False;
+ { BeginMode }
+ GL_POINTS = $0000;
+ GL_LINES = $0001;
+ GL_LINE_LOOP = $0002;
+ GL_LINE_STRIP = $0003;
+ GL_TRIANGLES = $0004;
+ GL_TRIANGLE_STRIP = $0005;
+ GL_TRIANGLE_FAN = $0006;
+ { AlphaFunction }
+ GL_NEVER = $0200;
+ GL_LESS = $0201;
+ GL_EQUAL = $0202;
+ GL_LEQUAL = $0203;
+ GL_GREATER = $0204;
+ GL_NOTEQUAL = $0205;
+ GL_GEQUAL = $0206;
+ GL_ALWAYS = $0207;
+ { BlendingFactorDest }
+ GL_ZERO = 0;
+ GL_ONE = 1;
+ GL_SRC_COLOR = $0300;
+ GL_ONE_MINUS_SRC_COLOR = $0301;
+ GL_SRC_ALPHA = $0302;
+ GL_ONE_MINUS_SRC_ALPHA = $0303;
+ GL_DST_ALPHA = $0304;
+ GL_ONE_MINUS_DST_ALPHA = $0305;
+ { BlendingFactorSrc }
+ GL_DST_COLOR = $0306;
+ GL_ONE_MINUS_DST_COLOR = $0307;
+ GL_SRC_ALPHA_SATURATE = $0308;
+ { DrawBufferMode }
+ GL_NONE = 0;
+ GL_FRONT_LEFT = $0400;
+ GL_FRONT_RIGHT = $0401;
+ GL_BACK_LEFT = $0402;
+ GL_BACK_RIGHT = $0403;
+ GL_FRONT = $0404;
+ GL_BACK = $0405;
+ GL_LEFT = $0406;
+ GL_RIGHT = $0407;
+ GL_FRONT_AND_BACK = $0408;
+ { ErrorCode }
+ GL_NO_ERROR = 0;
+ GL_INVALID_ENUM = $0500;
+ GL_INVALID_VALUE = $0501;
+ GL_INVALID_OPERATION = $0502;
+ GL_OUT_OF_MEMORY = $0505;
+ { FrontFaceDirection }
+ GL_CW = $0900;
+ GL_CCW = $0901;
+ { GetPName }
+ GL_POINT_SIZE = $0B11;
+ GL_POINT_SIZE_RANGE = $0B12;
+ GL_POINT_SIZE_GRANULARITY = $0B13;
+ GL_LINE_SMOOTH = $0B20;
+ GL_LINE_WIDTH = $0B21;
+ GL_LINE_WIDTH_RANGE = $0B22;
+ GL_LINE_WIDTH_GRANULARITY = $0B23;
+ GL_POLYGON_SMOOTH = $0B41;
+ GL_CULL_FACE = $0B44;
+ GL_CULL_FACE_MODE = $0B45;
+ GL_FRONT_FACE = $0B46;
+ GL_DEPTH_RANGE = $0B70;
+ GL_DEPTH_TEST = $0B71;
+ GL_DEPTH_WRITEMASK = $0B72;
+ GL_DEPTH_CLEAR_VALUE = $0B73;
+ GL_DEPTH_FUNC = $0B74;
+ GL_STENCIL_TEST = $0B90;
+ GL_STENCIL_CLEAR_VALUE = $0B91;
+ GL_STENCIL_FUNC = $0B92;
+ GL_STENCIL_VALUE_MASK = $0B93;
+ GL_STENCIL_FAIL = $0B94;
+ GL_STENCIL_PASS_DEPTH_FAIL = $0B95;
+ GL_STENCIL_PASS_DEPTH_PASS = $0B96;
+ GL_STENCIL_REF = $0B97;
+ GL_STENCIL_WRITEMASK = $0B98;
+ GL_VIEWPORT = $0BA2;
+ GL_DITHER = $0BD0;
+ GL_BLEND_DST = $0BE0;
+ GL_BLEND_SRC = $0BE1;
+ GL_BLEND = $0BE2;
+ GL_LOGIC_OP_MODE = $0BF0;
+ GL_COLOR_LOGIC_OP = $0BF2;
+ GL_DRAW_BUFFER = $0C01;
+ GL_READ_BUFFER = $0C02;
+ GL_SCISSOR_BOX = $0C10;
+ GL_SCISSOR_TEST = $0C11;
+ GL_COLOR_CLEAR_VALUE = $0C22;
+ GL_COLOR_WRITEMASK = $0C23;
+ GL_DOUBLEBUFFER = $0C32;
+ GL_STEREO = $0C33;
+ GL_LINE_SMOOTH_HINT = $0C52;
+ GL_POLYGON_SMOOTH_HINT = $0C53;
+ GL_UNPACK_SWAP_BYTES = $0CF0;
+ GL_UNPACK_LSB_FIRST = $0CF1;
+ GL_UNPACK_ROW_LENGTH = $0CF2;
+ GL_UNPACK_SKIP_ROWS = $0CF3;
+ GL_UNPACK_SKIP_PIXELS = $0CF4;
+ GL_UNPACK_ALIGNMENT = $0CF5;
+ GL_PACK_SWAP_BYTES = $0D00;
+ GL_PACK_LSB_FIRST = $0D01;
+ GL_PACK_ROW_LENGTH = $0D02;
+ GL_PACK_SKIP_ROWS = $0D03;
+ GL_PACK_SKIP_PIXELS = $0D04;
+ GL_PACK_ALIGNMENT = $0D05;
+ GL_MAX_TEXTURE_SIZE = $0D33;
+ GL_MAX_VIEWPORT_DIMS = $0D3A;
+ GL_SUBPIXEL_BITS = $0D50;
+ GL_TEXTURE_1D = $0DE0;
+ GL_TEXTURE_2D = $0DE1;
+ GL_POLYGON_OFFSET_UNITS = $2A00;
+ GL_POLYGON_OFFSET_POINT = $2A01;
+ GL_POLYGON_OFFSET_LINE = $2A02;
+ GL_POLYGON_OFFSET_FILL = $8037;
+ GL_POLYGON_OFFSET_FACTOR = $8038;
+ GL_TEXTURE_BINDING_1D = $8068;
+ GL_TEXTURE_BINDING_2D = $8069;
+ { GetTextureParameter }
+ GL_TEXTURE_WIDTH = $1000;
+ GL_TEXTURE_HEIGHT = $1001;
+ GL_TEXTURE_INTERNAL_FORMAT = $1003;
+ GL_TEXTURE_BORDER_COLOR = $1004;
+ GL_TEXTURE_BORDER = $1005;
+ GL_TEXTURE_RED_SIZE = $805C;
+ GL_TEXTURE_GREEN_SIZE = $805D;
+ GL_TEXTURE_BLUE_SIZE = $805E;
+ GL_TEXTURE_ALPHA_SIZE = $805F;
+ { HintMode }
+ GL_DONT_CARE = $1100;
+ GL_FASTEST = $1101;
+ GL_NICEST = $1102;
+ { DataType }
+ GL_BYTE = $1400;
+ GL_UNSIGNED_BYTE = $1401;
+ GL_SHORT = $1402;
+ GL_UNSIGNED_SHORT = $1403;
+ GL_INT = $1404;
+ GL_UNSIGNED_INT = $1405;
+ GL_FLOAT = $1406;
+ GL_DOUBLE = $140A;
+ { LogicOp }
+ GL_CLEAR = $1500;
+ GL_AND = $1501;
+ GL_AND_REVERSE = $1502;
+ GL_COPY = $1503;
+ GL_AND_INVERTED = $1504;
+ GL_NOOP = $1505;
+ GL_XOR = $1506;
+ GL_OR = $1507;
+ GL_NOR = $1508;
+ GL_EQUIV = $1509;
+ GL_INVERT = $150A;
+ GL_OR_REVERSE = $150B;
+ GL_COPY_INVERTED = $150C;
+ GL_OR_INVERTED = $150D;
+ GL_NAND = $150E;
+ GL_SET = $150F;
+ { MatrixMode (for gl3.h, FBO attachment type) }
+ GL_TEXTURE = $1702;
+ { PixelCopyType }
+ GL_COLOR = $1800;
+ GL_DEPTH = $1801;
+ GL_STENCIL = $1802;
+ { PixelFormat }
+ GL_STENCIL_INDEX = $1901;
+ GL_DEPTH_COMPONENT = $1902;
+ GL_RED = $1903;
+ GL_GREEN = $1904;
+ GL_BLUE = $1905;
+ GL_ALPHA = $1906;
+ GL_RGB = $1907;
+ GL_RGBA = $1908;
+ { PolygonMode }
+ GL_POINT = $1B00;
+ GL_LINE = $1B01;
+ GL_FILL = $1B02;
+ { StencilOp }
+ GL_KEEP = $1E00;
+ GL_REPLACE = $1E01;
+ GL_INCR = $1E02;
+ GL_DECR = $1E03;
+ { StringName }
+ GL_VENDOR = $1F00;
+ GL_RENDERER = $1F01;
+ GL_VERSION = $1F02;
+ GL_EXTENSIONS = $1F03;
+ { TextureMagFilter }
+ GL_NEAREST = $2600;
+ GL_LINEAR = $2601;
+ { TextureMinFilter }
+ GL_NEAREST_MIPMAP_NEAREST = $2700;
+ GL_LINEAR_MIPMAP_NEAREST = $2701;
+ GL_NEAREST_MIPMAP_LINEAR = $2702;
+ GL_LINEAR_MIPMAP_LINEAR = $2703;
+ { TextureParameterName }
+ GL_TEXTURE_MAG_FILTER = $2800;
+ GL_TEXTURE_MIN_FILTER = $2801;
+ GL_TEXTURE_WRAP_S = $2802;
+ GL_TEXTURE_WRAP_T = $2803;
+ { TextureTarget }
+ GL_PROXY_TEXTURE_1D = $8063;
+ GL_PROXY_TEXTURE_2D = $8064;
+ { TextureWrapMode }
+ GL_REPEAT = $2901;
+ { PixelInternalFormat }
+ GL_R3_G3_B2 = $2A10;
+ GL_RGB4 = $804F;
+ GL_RGB5 = $8050;
+ GL_RGB8 = $8051;
+ GL_RGB10 = $8052;
+ GL_RGB12 = $8053;
+ GL_RGB16 = $8054;
+ GL_RGBA2 = $8055;
+ GL_RGBA4 = $8056;
+ GL_RGB5_A1 = $8057;
+ GL_RGBA8 = $8058;
+ GL_RGB10_A2 = $8059;
+ GL_RGBA12 = $805A;
+ GL_RGBA16 = $805B;
+{$ifdef DGL_DEPRECATED}
+ GL_ACCUM = $0100;
+ GL_LOAD = $0101;
+ GL_RETURN = $0102;
+ GL_MULT = $0103;
+ GL_ADD = $0104;
+ GL_CURRENT_BIT = $00000001;
+ GL_POINT_BIT = $00000002;
+ GL_LINE_BIT = $00000004;
+ GL_POLYGON_BIT = $00000008;
+ GL_POLYGON_STIPPLE_BIT = $00000010;
+ GL_PIXEL_MODE_BIT = $00000020;
+ GL_LIGHTING_BIT = $00000040;
+ GL_FOG_BIT = $00000080;
+ GL_ACCUM_BUFFER_BIT = $00000200;
+ GL_VIEWPORT_BIT = $00000800;
+ GL_TRANSFORM_BIT = $00001000;
+ GL_ENABLE_BIT = $00002000;
+ GL_HINT_BIT = $00008000;
+ GL_EVAL_BIT = $00010000;
+ GL_LIST_BIT = $00020000;
+ GL_TEXTURE_BIT = $00040000;
+ GL_SCISSOR_BIT = $00080000;
+ GL_ALL_ATTRIB_BITS = $000FFFFF;
+ GL_QUADS = $0007;
+ GL_QUAD_STRIP = $0008;
+ GL_POLYGON = $0009;
+ GL_CLIP_PLANE0 = $3000;
+ GL_CLIP_PLANE1 = $3001;
+ GL_CLIP_PLANE2 = $3002;
+ GL_CLIP_PLANE3 = $3003;
+ GL_CLIP_PLANE4 = $3004;
+ GL_CLIP_PLANE5 = $3005;
+ GL_2_BYTES = $1407;
+ GL_3_BYTES = $1408;
+ GL_4_BYTES = $1409;
+ GL_AUX0 = $0409;
+ GL_AUX1 = $040A;
+ GL_AUX2 = $040B;
+ GL_AUX3 = $040C;
+ GL_STACK_OVERFLOW = $0503;
+ GL_STACK_UNDERFLOW = $0504;
+ GL_2D = $0600;
+ GL_3D = $0601;
+ GL_3D_COLOR = $0602;
+ GL_3D_COLOR_TEXTURE = $0603;
+ GL_4D_COLOR_TEXTURE = $0604;
+ GL_PASS_THROUGH_TOKEN = $0700;
+ GL_POINT_TOKEN = $0701;
+ GL_LINE_TOKEN = $0702;
+ GL_POLYGON_TOKEN = $0703;
+ GL_BITMAP_TOKEN = $0704;
+ GL_DRAW_PIXEL_TOKEN = $0705;
+ GL_COPY_PIXEL_TOKEN = $0706;
+ GL_LINE_RESET_TOKEN = $0707;
+ GL_EXP = $0800;
+ GL_EXP2 = $0801;
+ GL_COEFF = $0A00;
+ GL_ORDER = $0A01;
+ GL_DOMAIN = $0A02;
+ GL_CURRENT_COLOR = $0B00;
+ GL_CURRENT_INDEX = $0B01;
+ GL_CURRENT_NORMAL = $0B02;
+ GL_CURRENT_TEXTURE_COORDS = $0B03;
+ GL_CURRENT_RASTER_COLOR = $0B04;
+ GL_CURRENT_RASTER_INDEX = $0B05;
+ GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06;
+ GL_CURRENT_RASTER_POSITION = $0B07;
+ GL_CURRENT_RASTER_POSITION_VALID = $0B08;
+ GL_CURRENT_RASTER_DISTANCE = $0B09;
+ GL_POINT_SMOOTH = $0B10;
+ GL_LINE_STIPPLE = $0B24;
+ GL_LINE_STIPPLE_PATTERN = $0B25;
+ GL_LINE_STIPPLE_REPEAT = $0B26;
+ GL_LIST_MODE = $0B30;
+ GL_MAX_LIST_NESTING = $0B31;
+ GL_LIST_BASE = $0B32;
+ GL_LIST_INDEX = $0B33;
+ GL_POLYGON_MODE = $0B40;
+ GL_POLYGON_STIPPLE = $0B42;
+ GL_EDGE_FLAG = $0B43;
+ GL_LIGHTING = $0B50;
+ GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51;
+ GL_LIGHT_MODEL_TWO_SIDE = $0B52;
+ GL_LIGHT_MODEL_AMBIENT = $0B53;
+ GL_SHADE_MODEL = $0B54;
+ GL_COLOR_MATERIAL_FACE = $0B55;
+ GL_COLOR_MATERIAL_PARAMETER = $0B56;
+ GL_COLOR_MATERIAL = $0B57;
+ GL_FOG = $0B60;
+ GL_FOG_INDEX = $0B61;
+ GL_FOG_DENSITY = $0B62;
+ GL_FOG_START = $0B63;
+ GL_FOG_END = $0B64;
+ GL_FOG_MODE = $0B65;
+ GL_FOG_COLOR = $0B66;
+ GL_ACCUM_CLEAR_VALUE = $0B80;
+ GL_MATRIX_MODE = $0BA0;
+ GL_NORMALIZE = $0BA1;
+ GL_MODELVIEW_STACK_DEPTH = $0BA3;
+ GL_PROJECTION_STACK_DEPTH = $0BA4;
+ GL_TEXTURE_STACK_DEPTH = $0BA5;
+ GL_MODELVIEW_MATRIX = $0BA6;
+ GL_PROJECTION_MATRIX = $0BA7;
+ GL_TEXTURE_MATRIX = $0BA8;
+ GL_ATTRIB_STACK_DEPTH = $0BB0;
+ GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1;
+ GL_ALPHA_TEST = $0BC0;
+ GL_ALPHA_TEST_FUNC = $0BC1;
+ GL_ALPHA_TEST_REF = $0BC2;
+ GL_INDEX_LOGIC_OP = $0BF1;
+ GL_AUX_BUFFERS = $0C00;
+ GL_INDEX_CLEAR_VALUE = $0C20;
+ GL_INDEX_WRITEMASK = $0C21;
+ GL_INDEX_MODE = $0C30;
+ GL_RGBA_MODE = $0C31;
+ GL_RENDER_MODE = $0C40;
+ GL_PERSPECTIVE_CORRECTION_HINT = $0C50;
+ GL_POINT_SMOOTH_HINT = $0C51;
+ GL_FOG_HINT = $0C54;
+ GL_TEXTURE_GEN_S = $0C60;
+ GL_TEXTURE_GEN_T = $0C61;
+ GL_TEXTURE_GEN_R = $0C62;
+ GL_TEXTURE_GEN_Q = $0C63;
+ GL_PIXEL_MAP_I_TO_I = $0C70;
+ GL_PIXEL_MAP_S_TO_S = $0C71;
+ GL_PIXEL_MAP_I_TO_R = $0C72;
+ GL_PIXEL_MAP_I_TO_G = $0C73;
+ GL_PIXEL_MAP_I_TO_B = $0C74;
+ GL_PIXEL_MAP_I_TO_A = $0C75;
+ GL_PIXEL_MAP_R_TO_R = $0C76;
+ GL_PIXEL_MAP_G_TO_G = $0C77;
+ GL_PIXEL_MAP_B_TO_B = $0C78;
+ GL_PIXEL_MAP_A_TO_A = $0C79;
+ GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0;
+ GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1;
+ GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2;
+ GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3;
+ GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4;
+ GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5;
+ GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6;
+ GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7;
+ GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8;
+ GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9;
+ GL_MAP_COLOR = $0D10;
+ GL_MAP_STENCIL = $0D11;
+ GL_INDEX_SHIFT = $0D12;
+ GL_INDEX_OFFSET = $0D13;
+ GL_RED_SCALE = $0D14;
+ GL_RED_BIAS = $0D15;
+ GL_ZOOM_X = $0D16;
+ GL_ZOOM_Y = $0D17;
+ GL_GREEN_SCALE = $0D18;
+ GL_GREEN_BIAS = $0D19;
+ GL_BLUE_SCALE = $0D1A;
+ GL_BLUE_BIAS = $0D1B;
+ GL_ALPHA_SCALE = $0D1C;
+ GL_ALPHA_BIAS = $0D1D;
+ GL_DEPTH_SCALE = $0D1E;
+ GL_DEPTH_BIAS = $0D1F;
+ GL_MAX_EVAL_ORDER = $0D30;
+ GL_MAX_LIGHTS = $0D31;
+ GL_MAX_CLIP_PLANES = $0D32;
+ GL_MAX_PIXEL_MAP_TABLE = $0D34;
+ GL_MAX_ATTRIB_STACK_DEPTH = $0D35;
+ GL_MAX_MODELVIEW_STACK_DEPTH = $0D36;
+ GL_MAX_NAME_STACK_DEPTH = $0D37;
+ GL_MAX_PROJECTION_STACK_DEPTH = $0D38;
+ GL_MAX_TEXTURE_STACK_DEPTH = $0D39;
+ GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B;
+ GL_INDEX_BITS = $0D51;
+ GL_RED_BITS = $0D52;
+ GL_GREEN_BITS = $0D53;
+ GL_BLUE_BITS = $0D54;
+ GL_ALPHA_BITS = $0D55;
+ GL_DEPTH_BITS = $0D56;
+ GL_STENCIL_BITS = $0D57;
+ GL_ACCUM_RED_BITS = $0D58;
+ GL_ACCUM_GREEN_BITS = $0D59;
+ GL_ACCUM_BLUE_BITS = $0D5A;
+ GL_ACCUM_ALPHA_BITS = $0D5B;
+ GL_NAME_STACK_DEPTH = $0D70;
+ GL_AUTO_NORMAL = $0D80;
+ GL_MAP1_COLOR_4 = $0D90;
+ GL_MAP1_INDEX = $0D91;
+ GL_MAP1_NORMAL = $0D92;
+ GL_MAP1_TEXTURE_COORD_1 = $0D93;
+ GL_MAP1_TEXTURE_COORD_2 = $0D94;
+ GL_MAP1_TEXTURE_COORD_3 = $0D95;
+ GL_MAP1_TEXTURE_COORD_4 = $0D96;
+ GL_MAP1_VERTEX_3 = $0D97;
+ GL_MAP1_VERTEX_4 = $0D98;
+ GL_MAP2_COLOR_4 = $0DB0;
+ GL_MAP2_INDEX = $0DB1;
+ GL_MAP2_NORMAL = $0DB2;
+ GL_MAP2_TEXTURE_COORD_1 = $0DB3;
+ GL_MAP2_TEXTURE_COORD_2 = $0DB4;
+ GL_MAP2_TEXTURE_COORD_3 = $0DB5;
+ GL_MAP2_TEXTURE_COORD_4 = $0DB6;
+ GL_MAP2_VERTEX_3 = $0DB7;
+ GL_MAP2_VERTEX_4 = $0DB8;
+ GL_MAP1_GRID_DOMAIN = $0DD0;
+ GL_MAP1_GRID_SEGMENTS = $0DD1;
+ GL_MAP2_GRID_DOMAIN = $0DD2;
+ GL_MAP2_GRID_SEGMENTS = $0DD3;
+ GL_FEEDBACK_BUFFER_POINTER = $0DF0;
+ GL_FEEDBACK_BUFFER_SIZE = $0DF1;
+ GL_FEEDBACK_BUFFER_TYPE = $0DF2;
+ GL_SELECTION_BUFFER_POINTER = $0DF3;
+ GL_SELECTION_BUFFER_SIZE = $0DF4;
+ GL_LIGHT0 = $4000;
+ GL_LIGHT1 = $4001;
+ GL_LIGHT2 = $4002;
+ GL_LIGHT3 = $4003;
+ GL_LIGHT4 = $4004;
+ GL_LIGHT5 = $4005;
+ GL_LIGHT6 = $4006;
+ GL_LIGHT7 = $4007;
+ GL_AMBIENT = $1200;
+ GL_DIFFUSE = $1201;
+ GL_SPECULAR = $1202;
+ GL_POSITION = $1203;
+ GL_SPOT_DIRECTION = $1204;
+ GL_SPOT_EXPONENT = $1205;
+ GL_SPOT_CUTOFF = $1206;
+ GL_CONSTANT_ATTENUATION = $1207;
+ GL_LINEAR_ATTENUATION = $1208;
+ GL_QUADRATIC_ATTENUATION = $1209;
+ GL_COMPILE = $1300;
+ GL_COMPILE_AND_EXECUTE = $1301;
+ GL_EMISSION = $1600;
+ GL_SHININESS = $1601;
+ GL_AMBIENT_AND_DIFFUSE = $1602;
+ GL_COLOR_INDEXES = $1603;
+ GL_MODELVIEW = $1700;
+ GL_PROJECTION = $1701;
+ GL_COLOR_INDEX = $1900;
+ GL_LUMINANCE = $1909;
+ GL_LUMINANCE_ALPHA = $190A;
+ GL_BITMAP = $1A00;
+ GL_RENDER = $1C00;
+ GL_FEEDBACK = $1C01;
+ GL_SELECT = $1C02;
+ GL_FLAT = $1D00;
+ GL_SMOOTH = $1D01;
+ GL_S = $2000;
+ GL_T = $2001;
+ GL_R = $2002;
+ GL_Q = $2003;
+ GL_MODULATE = $2100;
+ GL_DECAL = $2101;
+ GL_TEXTURE_ENV_MODE = $2200;
+ GL_TEXTURE_ENV_COLOR = $2201;
+ GL_TEXTURE_ENV = $2300;
+ GL_EYE_LINEAR = $2400;
+ GL_OBJECT_LINEAR = $2401;
+ GL_SPHERE_MAP = $2402;
+ GL_TEXTURE_GEN_MODE = $2500;
+ GL_OBJECT_PLANE = $2501;
+ GL_EYE_PLANE = $2502;
+ GL_CLAMP = $2900;
+ GL_CLIENT_PIXEL_STORE_BIT = $00000001;
+ GL_CLIENT_VERTEX_ARRAY_BIT = $00000002;
+ GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF;
+ GL_ALPHA4 = $803B;
+ GL_ALPHA8 = $803C;
+ GL_ALPHA12 = $803D;
+ GL_ALPHA16 = $803E;
+ GL_LUMINANCE4 = $803F;
+ GL_LUMINANCE8 = $8040;
+ GL_LUMINANCE12 = $8041;
+ GL_LUMINANCE16 = $8042;
+ GL_LUMINANCE4_ALPHA4 = $8043;
+ GL_LUMINANCE6_ALPHA2 = $8044;
+ GL_LUMINANCE8_ALPHA8 = $8045;
+ GL_LUMINANCE12_ALPHA4 = $8046;
+ GL_LUMINANCE12_ALPHA12 = $8047;
+ GL_LUMINANCE16_ALPHA16 = $8048;
+ GL_INTENSITY = $8049;
+ GL_INTENSITY4 = $804A;
+ GL_INTENSITY8 = $804B;
+ GL_INTENSITY12 = $804C;
+ GL_INTENSITY16 = $804D;
+ GL_TEXTURE_LUMINANCE_SIZE = $8060;
+ GL_TEXTURE_INTENSITY_SIZE = $8061;
+ GL_TEXTURE_PRIORITY = $8066;
+ GL_TEXTURE_RESIDENT = $8067;
+ GL_VERTEX_ARRAY = $8074;
+ GL_NORMAL_ARRAY = $8075;
+ GL_COLOR_ARRAY = $8076;
+ GL_INDEX_ARRAY = $8077;
+ GL_TEXTURE_COORD_ARRAY = $8078;
+ GL_EDGE_FLAG_ARRAY = $8079;
+ GL_VERTEX_ARRAY_SIZE = $807A;
+ GL_VERTEX_ARRAY_TYPE = $807B;
+ GL_VERTEX_ARRAY_STRIDE = $807C;
+ GL_NORMAL_ARRAY_TYPE = $807E;
+ GL_NORMAL_ARRAY_STRIDE = $807F;
+ GL_COLOR_ARRAY_SIZE = $8081;
+ GL_COLOR_ARRAY_TYPE = $8082;
+ GL_COLOR_ARRAY_STRIDE = $8083;
+ GL_INDEX_ARRAY_TYPE = $8085;
+ GL_INDEX_ARRAY_STRIDE = $8086;
+ GL_TEXTURE_COORD_ARRAY_SIZE = $8088;
+ GL_TEXTURE_COORD_ARRAY_TYPE = $8089;
+ GL_TEXTURE_COORD_ARRAY_STRIDE = $808A;
+ GL_EDGE_FLAG_ARRAY_STRIDE = $808C;
+ GL_VERTEX_ARRAY_POINTER = $808E;
+ GL_NORMAL_ARRAY_POINTER = $808F;
+ GL_COLOR_ARRAY_POINTER = $8090;
+ GL_INDEX_ARRAY_POINTER = $8091;
+ GL_TEXTURE_COORD_ARRAY_POINTER = $8092;
+ GL_EDGE_FLAG_ARRAY_POINTER = $8093;
+ GL_V2F = $2A20;
+ GL_V3F = $2A21;
+ GL_C4UB_V2F = $2A22;
+ GL_C4UB_V3F = $2A23;
+ GL_C3F_V3F = $2A24;
+ GL_N3F_V3F = $2A25;
+ GL_C4F_N3F_V3F = $2A26;
+ GL_T2F_V3F = $2A27;
+ GL_T4F_V4F = $2A28;
+ GL_T2F_C4UB_V3F = $2A29;
+ GL_T2F_C3F_V3F = $2A2A;
+ GL_T2F_N3F_V3F = $2A2B;
+ GL_T2F_C4F_N3F_V3F = $2A2C;
+ GL_T4F_C4F_N3F_V4F = $2A2D;
+ GL_COLOR_TABLE_FORMAT_EXT = $80D8;
+ GL_COLOR_TABLE_WIDTH_EXT = $80D9;
+ GL_COLOR_TABLE_RED_SIZE_EXT = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF;
+ GL_LOGIC_OP = GL_INDEX_LOGIC_OP;
+ GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT;
+{$endif}
+
+ // GL_VERSION_1_2
+ GL_UNSIGNED_BYTE_3_3_2 = $8032;
+ GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
+ GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
+ GL_UNSIGNED_INT_8_8_8_8 = $8035;
+ GL_UNSIGNED_INT_10_10_10_2 = $8036;
+ GL_TEXTURE_BINDING_3D = $806A;
+ GL_PACK_SKIP_IMAGES = $806B;
+ GL_PACK_IMAGE_HEIGHT = $806C;
+ GL_UNPACK_SKIP_IMAGES = $806D;
+ GL_UNPACK_IMAGE_HEIGHT = $806E;
+ GL_TEXTURE_3D = $806F;
+ GL_PROXY_TEXTURE_3D = $8070;
+ GL_TEXTURE_DEPTH = $8071;
+ GL_TEXTURE_WRAP_R = $8072;
+ GL_MAX_3D_TEXTURE_SIZE = $8073;
+ GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
+ GL_UNSIGNED_SHORT_5_6_5 = $8363;
+ GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
+ GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
+ GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
+ GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
+ GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
+ GL_BGR = $80E0;
+ GL_BGRA = $80E1;
+ GL_MAX_ELEMENTS_VERTICES = $80E8;
+ GL_MAX_ELEMENTS_INDICES = $80E9;
+ GL_CLAMP_TO_EDGE = $812F;
+ GL_TEXTURE_MIN_LOD = $813A;
+ GL_TEXTURE_MAX_LOD = $813B;
+ GL_TEXTURE_BASE_LEVEL = $813C;
+ GL_TEXTURE_MAX_LEVEL = $813D;
+ GL_SMOOTH_POINT_SIZE_RANGE = $0B12;
+ GL_SMOOTH_POINT_SIZE_GRANULARITY = $0B13;
+ GL_SMOOTH_LINE_WIDTH_RANGE = $0B22;
+ GL_SMOOTH_LINE_WIDTH_GRANULARITY = $0B23;
+ GL_ALIASED_LINE_WIDTH_RANGE = $846E;
+{$ifdef DGL_DEPRECATED}
+ GL_RESCALE_NORMAL = $803A;
+ GL_LIGHT_MODEL_COLOR_CONTROL = $81F8;
+ GL_SINGLE_COLOR = $81F9;
+ GL_SEPARATE_SPECULAR_COLOR = $81FA;
+ GL_ALIASED_POINT_SIZE_RANGE = $846D;
+{$endif}
+
+ // GL_VERSION_1_3
+ GL_TEXTURE0 = $84C0;
+ GL_TEXTURE1 = $84C1;
+ GL_TEXTURE2 = $84C2;
+ GL_TEXTURE3 = $84C3;
+ GL_TEXTURE4 = $84C4;
+ GL_TEXTURE5 = $84C5;
+ GL_TEXTURE6 = $84C6;
+ GL_TEXTURE7 = $84C7;
+ GL_TEXTURE8 = $84C8;
+ GL_TEXTURE9 = $84C9;
+ GL_TEXTURE10 = $84CA;
+ GL_TEXTURE11 = $84CB;
+ GL_TEXTURE12 = $84CC;
+ GL_TEXTURE13 = $84CD;
+ GL_TEXTURE14 = $84CE;
+ GL_TEXTURE15 = $84CF;
+ GL_TEXTURE16 = $84D0;
+ GL_TEXTURE17 = $84D1;
+ GL_TEXTURE18 = $84D2;
+ GL_TEXTURE19 = $84D3;
+ GL_TEXTURE20 = $84D4;
+ GL_TEXTURE21 = $84D5;
+ GL_TEXTURE22 = $84D6;
+ GL_TEXTURE23 = $84D7;
+ GL_TEXTURE24 = $84D8;
+ GL_TEXTURE25 = $84D9;
+ GL_TEXTURE26 = $84DA;
+ GL_TEXTURE27 = $84DB;
+ GL_TEXTURE28 = $84DC;
+ GL_TEXTURE29 = $84DD;
+ GL_TEXTURE30 = $84DE;
+ GL_TEXTURE31 = $84DF;
+ GL_ACTIVE_TEXTURE = $84E0;
+ GL_MULTISAMPLE = $809D;
+ GL_SAMPLE_ALPHA_TO_COVERAGE = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE = $809F;
+ GL_SAMPLE_COVERAGE = $80A0;
+ GL_SAMPLE_BUFFERS = $80A8;
+ GL_SAMPLES = $80A9;
+ GL_SAMPLE_COVERAGE_VALUE = $80AA;
+ GL_SAMPLE_COVERAGE_INVERT = $80AB;
+ GL_TEXTURE_CUBE_MAP = $8513;
+ GL_TEXTURE_BINDING_CUBE_MAP = $8514;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
+ GL_PROXY_TEXTURE_CUBE_MAP = $851B;
+ GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
+ GL_COMPRESSED_RGB = $84ED;
+ GL_COMPRESSED_RGBA = $84EE;
+ GL_TEXTURE_COMPRESSION_HINT = $84EF;
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE = $86A0;
+ GL_TEXTURE_COMPRESSED = $86A1;
+ GL_NUM_COMPRESSED_TEXTURE_FORMATS = $86A2;
+ GL_COMPRESSED_TEXTURE_FORMATS = $86A3;
+ GL_CLAMP_TO_BORDER = $812D;
+{$ifdef DGL_DEPRECATED}
+ GL_CLIENT_ACTIVE_TEXTURE = $84E1;
+ GL_MAX_TEXTURE_UNITS = $84E2;
+ GL_TRANSPOSE_MODELVIEW_MATRIX = $84E3;
+ GL_TRANSPOSE_PROJECTION_MATRIX = $84E4;
+ GL_TRANSPOSE_TEXTURE_MATRIX = $84E5;
+ GL_TRANSPOSE_COLOR_MATRIX = $84E6;
+ GL_MULTISAMPLE_BIT = $20000000;
+ GL_NORMAL_MAP = $8511;
+ GL_REFLECTION_MAP = $8512;
+ GL_COMPRESSED_ALPHA = $84E9;
+ GL_COMPRESSED_LUMINANCE = $84EA;
+ GL_COMPRESSED_LUMINANCE_ALPHA = $84EB;
+ GL_COMPRESSED_INTENSITY = $84EC;
+ GL_COMBINE = $8570;
+ GL_COMBINE_RGB = $8571;
+ GL_COMBINE_ALPHA = $8572;
+ GL_SOURCE0_RGB = $8580;
+ GL_SOURCE1_RGB = $8581;
+ GL_SOURCE2_RGB = $8582;
+ GL_SOURCE0_ALPHA = $8588;
+ GL_SOURCE1_ALPHA = $8589;
+ GL_SOURCE2_ALPHA = $858A;
+ GL_OPERAND0_RGB = $8590;
+ GL_OPERAND1_RGB = $8591;
+ GL_OPERAND2_RGB = $8592;
+ GL_OPERAND0_ALPHA = $8598;
+ GL_OPERAND1_ALPHA = $8599;
+ GL_OPERAND2_ALPHA = $859A;
+ GL_RGB_SCALE = $8573;
+ GL_ADD_SIGNED = $8574;
+ GL_INTERPOLATE = $8575;
+ GL_SUBTRACT = $84E7;
+ GL_CONSTANT = $8576;
+ GL_PRIMARY_COLOR = $8577;
+ GL_PREVIOUS = $8578;
+ GL_DOT3_RGB = $86AE;
+ GL_DOT3_RGBA = $86AF;
+{$endif}
+
+ // GL_VERSION_1_4
+ GL_BLEND_DST_RGB = $80C8;
+ GL_BLEND_SRC_RGB = $80C9;
+ GL_BLEND_DST_ALPHA = $80CA;
+ GL_BLEND_SRC_ALPHA = $80CB;
+ GL_POINT_FADE_THRESHOLD_SIZE = $8128;
+ GL_DEPTH_COMPONENT16 = $81A5;
+ GL_DEPTH_COMPONENT24 = $81A6;
+ GL_DEPTH_COMPONENT32 = $81A7;
+ GL_MIRRORED_REPEAT = $8370;
+ GL_MAX_TEXTURE_LOD_BIAS = $84FD;
+ GL_TEXTURE_LOD_BIAS = $8501;
+ GL_INCR_WRAP = $8507;
+ GL_DECR_WRAP = $8508;
+ GL_TEXTURE_DEPTH_SIZE = $884A;
+ GL_TEXTURE_COMPARE_MODE = $884C;
+ GL_TEXTURE_COMPARE_FUNC = $884D;
+{$ifdef DGL_DEPRECATED}
+ GL_POINT_SIZE_MIN = $8126;
+ GL_POINT_SIZE_MAX = $8127;
+ GL_POINT_DISTANCE_ATTENUATION = $8129;
+ GL_GENERATE_MIPMAP = $8191;
+ GL_GENERATE_MIPMAP_HINT = $8192;
+ GL_FOG_COORDINATE_SOURCE = $8450;
+ GL_FOG_COORDINATE = $8451;
+ GL_FRAGMENT_DEPTH = $8452;
+ GL_CURRENT_FOG_COORDINATE = $8453;
+ GL_FOG_COORDINATE_ARRAY_TYPE = $8454;
+ GL_FOG_COORDINATE_ARRAY_STRIDE = $8455;
+ GL_FOG_COORDINATE_ARRAY_POINTER = $8456;
+ GL_FOG_COORDINATE_ARRAY = $8457;
+ GL_COLOR_SUM = $8458;
+ GL_CURRENT_SECONDARY_COLOR = $8459;
+ GL_SECONDARY_COLOR_ARRAY_SIZE = $845A;
+ GL_SECONDARY_COLOR_ARRAY_TYPE = $845B;
+ GL_SECONDARY_COLOR_ARRAY_STRIDE = $845C;
+ GL_SECONDARY_COLOR_ARRAY_POINTER = $845D;
+ GL_SECONDARY_COLOR_ARRAY = $845E;
+ GL_TEXTURE_FILTER_CONTROL = $8500;
+ GL_DEPTH_TEXTURE_MODE = $884B;
+ GL_COMPARE_R_TO_TEXTURE = $884E;
+{$endif}
+
+ // GL_VERSION_1_5
+ GL_BUFFER_SIZE = $8764;
+ GL_BUFFER_USAGE = $8765;
+ GL_QUERY_COUNTER_BITS = $8864;
+ GL_CURRENT_QUERY = $8865;
+ GL_QUERY_RESULT = $8866;
+ GL_QUERY_RESULT_AVAILABLE = $8867;
+ GL_ARRAY_BUFFER = $8892;
+ GL_ELEMENT_ARRAY_BUFFER = $8893;
+ GL_ARRAY_BUFFER_BINDING = $8894;
+ GL_ELEMENT_ARRAY_BUFFER_BINDING = $8895;
+ GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = $889F;
+ GL_READ_ONLY = $88B8;
+ GL_WRITE_ONLY = $88B9;
+ GL_READ_WRITE = $88BA;
+ GL_BUFFER_ACCESS = $88BB;
+ GL_BUFFER_MAPPED = $88BC;
+ GL_BUFFER_MAP_POINTER = $88BD;
+ GL_STREAM_DRAW = $88E0;
+ GL_STREAM_READ = $88E1;
+ GL_STREAM_COPY = $88E2;
+ GL_STATIC_DRAW = $88E4;
+ GL_STATIC_READ = $88E5;
+ GL_STATIC_COPY = $88E6;
+ GL_DYNAMIC_DRAW = $88E8;
+ GL_DYNAMIC_READ = $88E9;
+ GL_DYNAMIC_COPY = $88EA;
+ GL_SAMPLES_PASSED = $8914;
+{$ifdef DGL_DEPRECATED}
+ GL_VERTEX_ARRAY_BUFFER_BINDING = $8896;
+ GL_NORMAL_ARRAY_BUFFER_BINDING = $8897;
+ GL_COLOR_ARRAY_BUFFER_BINDING = $8898;
+ GL_INDEX_ARRAY_BUFFER_BINDING = $8899;
+ GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = $889A;
+ GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = $889B;
+ GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = $889C;
+ GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = $889D;
+ GL_WEIGHT_ARRAY_BUFFER_BINDING = $889E;
+ GL_FOG_COORD_SRC = $8450;
+ GL_FOG_COORD = $8451;
+ GL_CURRENT_FOG_COORD = $8453;
+ GL_FOG_COORD_ARRAY_TYPE = $8454;
+ GL_FOG_COORD_ARRAY_STRIDE = $8455;
+ GL_FOG_COORD_ARRAY_POINTER = $8456;
+ GL_FOG_COORD_ARRAY = $8457;
+ GL_FOG_COORD_ARRAY_BUFFER_BINDING = $889D;
+ GL_SRC0_RGB = $8580;
+ GL_SRC1_RGB = $8581;
+ GL_SRC2_RGB = $8582;
+ GL_SRC0_ALPHA = $8588;
+ GL_SRC1_ALPHA = $8589;
+ GL_SRC2_ALPHA = $858A;
+{$endif}
+
+ // GL_VERSION_2_0
+ GL_BLEND_EQUATION_RGB = $8009;
+ GL_VERTEX_ATTRIB_ARRAY_ENABLED = $8622;
+ GL_VERTEX_ATTRIB_ARRAY_SIZE = $8623;
+ GL_VERTEX_ATTRIB_ARRAY_STRIDE = $8624;
+ GL_VERTEX_ATTRIB_ARRAY_TYPE = $8625;
+ GL_CURRENT_VERTEX_ATTRIB = $8626;
+ GL_VERTEX_PROGRAM_POINT_SIZE = $8642;
+ GL_VERTEX_ATTRIB_ARRAY_POINTER = $8645;
+ GL_STENCIL_BACK_FUNC = $8800;
+ GL_STENCIL_BACK_FAIL = $8801;
+ GL_STENCIL_BACK_PASS_DEPTH_FAIL = $8802;
+ GL_STENCIL_BACK_PASS_DEPTH_PASS = $8803;
+ GL_MAX_DRAW_BUFFERS = $8824;
+ GL_DRAW_BUFFER0 = $8825;
+ GL_DRAW_BUFFER1 = $8826;
+ GL_DRAW_BUFFER2 = $8827;
+ GL_DRAW_BUFFER3 = $8828;
+ GL_DRAW_BUFFER4 = $8829;
+ GL_DRAW_BUFFER5 = $882A;
+ GL_DRAW_BUFFER6 = $882B;
+ GL_DRAW_BUFFER7 = $882C;
+ GL_DRAW_BUFFER8 = $882D;
+ GL_DRAW_BUFFER9 = $882E;
+ GL_DRAW_BUFFER10 = $882F;
+ GL_DRAW_BUFFER11 = $8830;
+ GL_DRAW_BUFFER12 = $8831;
+ GL_DRAW_BUFFER13 = $8832;
+ GL_DRAW_BUFFER14 = $8833;
+ GL_DRAW_BUFFER15 = $8834;
+ GL_BLEND_EQUATION_ALPHA = $883D;
+ GL_MAX_VERTEX_ATTRIBS = $8869;
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = $886A;
+ GL_MAX_TEXTURE_IMAGE_UNITS = $8872;
+ GL_FRAGMENT_SHADER = $8B30;
+ GL_VERTEX_SHADER = $8B31;
+ GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = $8B49;
+ GL_MAX_VERTEX_UNIFORM_COMPONENTS = $8B4A;
+ GL_MAX_VARYING_FLOATS = $8B4B;
+ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = $8B4C;
+ GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = $8B4D;
+ GL_SHADER_TYPE = $8B4F;
+ GL_FLOAT_VEC2 = $8B50;
+ GL_FLOAT_VEC3 = $8B51;
+ GL_FLOAT_VEC4 = $8B52;
+ GL_INT_VEC2 = $8B53;
+ GL_INT_VEC3 = $8B54;
+ GL_INT_VEC4 = $8B55;
+ GL_BOOL = $8B56;
+ GL_BOOL_VEC2 = $8B57;
+ GL_BOOL_VEC3 = $8B58;
+ GL_BOOL_VEC4 = $8B59;
+ GL_FLOAT_MAT2 = $8B5A;
+ GL_FLOAT_MAT3 = $8B5B;
+ GL_FLOAT_MAT4 = $8B5C;
+ GL_SAMPLER_1D = $8B5D;
+ GL_SAMPLER_2D = $8B5E;
+ GL_SAMPLER_3D = $8B5F;
+ GL_SAMPLER_CUBE = $8B60;
+ GL_SAMPLER_1D_SHADOW = $8B61;
+ GL_SAMPLER_2D_SHADOW = $8B62;
+ GL_DELETE_STATUS = $8B80;
+ GL_COMPILE_STATUS = $8B81;
+ GL_LINK_STATUS = $8B82;
+ GL_VALIDATE_STATUS = $8B83;
+ GL_INFO_LOG_LENGTH = $8B84;
+ GL_ATTACHED_SHADERS = $8B85;
+ GL_ACTIVE_UNIFORMS = $8B86;
+ GL_ACTIVE_UNIFORM_MAX_LENGTH = $8B87;
+ GL_SHADER_SOURCE_LENGTH = $8B88;
+ GL_ACTIVE_ATTRIBUTES = $8B89;
+ GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = $8B8A;
+ GL_FRAGMENT_SHADER_DERIVATIVE_HINT = $8B8B;
+ GL_SHADING_LANGUAGE_VERSION = $8B8C;
+ GL_CURRENT_PROGRAM = $8B8D;
+ GL_POINT_SPRITE_COORD_ORIGIN = $8CA0;
+ GL_LOWER_LEFT = $8CA1;
+ GL_UPPER_LEFT = $8CA2;
+ GL_STENCIL_BACK_REF = $8CA3;
+ GL_STENCIL_BACK_VALUE_MASK = $8CA4;
+ GL_STENCIL_BACK_WRITEMASK = $8CA5;
+{$ifdef DGL_DEPRECATED}
+ GL_VERTEX_PROGRAM_TWO_SIDE = $8643;
+ GL_POINT_SPRITE = $8861;
+ GL_COORD_REPLACE = $8862;
+ GL_MAX_TEXTURE_COORDS = $8871;
+{$endif}
+
+ // GL_VERSION_2_1
+ GL_PIXEL_PACK_BUFFER = $88EB;
+ GL_PIXEL_UNPACK_BUFFER = $88EC;
+ GL_PIXEL_PACK_BUFFER_BINDING = $88ED;
+ GL_PIXEL_UNPACK_BUFFER_BINDING = $88EF;
+ GL_FLOAT_MAT2x3 = $8B65;
+ GL_FLOAT_MAT2x4 = $8B66;
+ GL_FLOAT_MAT3x2 = $8B67;
+ GL_FLOAT_MAT3x4 = $8B68;
+ GL_FLOAT_MAT4x2 = $8B69;
+ GL_FLOAT_MAT4x3 = $8B6A;
+ GL_SRGB = $8C40;
+ GL_SRGB8 = $8C41;
+ GL_SRGB_ALPHA = $8C42;
+ GL_SRGB8_ALPHA8 = $8C43;
+ GL_COMPRESSED_SRGB = $8C48;
+ GL_COMPRESSED_SRGB_ALPHA = $8C49;
+{$ifdef DGL_DEPRECATED}
+ GL_CURRENT_RASTER_SECONDARY_COLOR = $845F;
+ GL_SLUMINANCE_ALPHA = $8C44;
+ GL_SLUMINANCE8_ALPHA8 = $8C45;
+ GL_SLUMINANCE = $8C46;
+ GL_SLUMINANCE8 = $8C47;
+ GL_COMPRESSED_SLUMINANCE = $8C4A;
+ GL_COMPRESSED_SLUMINANCE_ALPHA = $8C4B;
+{$endif}
+
+ // GL_VERSION_3_0
+ GL_COMPARE_REF_TO_TEXTURE = $884E;
+ GL_CLIP_DISTANCE0 = $3000;
+ GL_CLIP_DISTANCE1 = $3001;
+ GL_CLIP_DISTANCE2 = $3002;
+ GL_CLIP_DISTANCE3 = $3003;
+ GL_CLIP_DISTANCE4 = $3004;
+ GL_CLIP_DISTANCE5 = $3005;
+ GL_CLIP_DISTANCE6 = $3006;
+ GL_CLIP_DISTANCE7 = $3007;
+ GL_MAX_CLIP_DISTANCES = $0D32;
+ GL_MAJOR_VERSION = $821B;
+ GL_MINOR_VERSION = $821C;
+ GL_NUM_EXTENSIONS = $821D;
+ GL_CONTEXT_FLAGS = $821E;
+ GL_DEPTH_BUFFER = $8223;
+ GL_STENCIL_BUFFER = $8224;
+ GL_COMPRESSED_RED = $8225;
+ GL_COMPRESSED_RG = $8226;
+ GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = $0001;
+ GL_RGBA32F = $8814;
+ GL_RGB32F = $8815;
+ GL_RGBA16F = $881A;
+ GL_RGB16F = $881B;
+ GL_VERTEX_ATTRIB_ARRAY_INTEGER = $88FD;
+ GL_MAX_ARRAY_TEXTURE_LAYERS = $88FF;
+ GL_MIN_PROGRAM_TEXEL_OFFSET = $8904;
+ GL_MAX_PROGRAM_TEXEL_OFFSET = $8905;
+ GL_CLAMP_READ_COLOR = $891C;
+ GL_FIXED_ONLY = $891D;
+ GL_MAX_VARYING_COMPONENTS = $8B4B;
+ GL_TEXTURE_1D_ARRAY = $8C18;
+ GL_PROXY_TEXTURE_1D_ARRAY = $8C19;
+ GL_TEXTURE_2D_ARRAY = $8C1A;
+ GL_PROXY_TEXTURE_2D_ARRAY = $8C1B;
+ GL_TEXTURE_BINDING_1D_ARRAY = $8C1C;
+ GL_TEXTURE_BINDING_2D_ARRAY = $8C1D;
+ GL_R11F_G11F_B10F = $8C3A;
+ GL_UNSIGNED_INT_10F_11F_11F_REV = $8C3B;
+ GL_RGB9_E5 = $8C3D;
+ GL_UNSIGNED_INT_5_9_9_9_REV = $8C3E;
+ GL_TEXTURE_SHARED_SIZE = $8C3F;
+ GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = $8C76;
+ GL_TRANSFORM_FEEDBACK_BUFFER_MODE = $8C7F;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = $8C80;
+ GL_TRANSFORM_FEEDBACK_VARYINGS = $8C83;
+ GL_TRANSFORM_FEEDBACK_BUFFER_START = $8C84;
+ GL_TRANSFORM_FEEDBACK_BUFFER_SIZE = $8C85;
+ GL_PRIMITIVES_GENERATED = $8C87;
+ GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = $8C88;
+ GL_RASTERIZER_DISCARD = $8C89;
+ GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = $8C8A;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = $8C8B;
+ GL_INTERLEAVED_ATTRIBS = $8C8C;
+ GL_SEPARATE_ATTRIBS = $8C8D;
+ GL_TRANSFORM_FEEDBACK_BUFFER = $8C8E;
+ GL_TRANSFORM_FEEDBACK_BUFFER_BINDING = $8C8F;
+ GL_RGBA32UI = $8D70;
+ GL_RGB32UI = $8D71;
+ GL_RGBA16UI = $8D76;
+ GL_RGB16UI = $8D77;
+ GL_RGBA8UI = $8D7C;
+ GL_RGB8UI = $8D7D;
+ GL_RGBA32I = $8D82;
+ GL_RGB32I = $8D83;
+ GL_RGBA16I = $8D88;
+ GL_RGB16I = $8D89;
+ GL_RGBA8I = $8D8E;
+ GL_RGB8I = $8D8F;
+ GL_RED_INTEGER = $8D94;
+ GL_GREEN_INTEGER = $8D95;
+ GL_BLUE_INTEGER = $8D96;
+ GL_RGB_INTEGER = $8D98;
+ GL_RGBA_INTEGER = $8D99;
+ GL_BGR_INTEGER = $8D9A;
+ GL_BGRA_INTEGER = $8D9B;
+ GL_SAMPLER_1D_ARRAY = $8DC0;
+ GL_SAMPLER_2D_ARRAY = $8DC1;
+ GL_SAMPLER_1D_ARRAY_SHADOW = $8DC3;
+ GL_SAMPLER_2D_ARRAY_SHADOW = $8DC4;
+ GL_SAMPLER_CUBE_SHADOW = $8DC5;
+ GL_UNSIGNED_INT_VEC2 = $8DC6;
+ GL_UNSIGNED_INT_VEC3 = $8DC7;
+ GL_UNSIGNED_INT_VEC4 = $8DC8;
+ GL_INT_SAMPLER_1D = $8DC9;
+ GL_INT_SAMPLER_2D = $8DCA;
+ GL_INT_SAMPLER_3D = $8DCB;
+ GL_INT_SAMPLER_CUBE = $8DCC;
+ GL_INT_SAMPLER_1D_ARRAY = $8DCE;
+ GL_INT_SAMPLER_2D_ARRAY = $8DCF;
+ GL_UNSIGNED_INT_SAMPLER_1D = $8DD1;
+ GL_UNSIGNED_INT_SAMPLER_2D = $8DD2;
+ GL_UNSIGNED_INT_SAMPLER_3D = $8DD3;
+ GL_UNSIGNED_INT_SAMPLER_CUBE = $8DD4;
+ GL_UNSIGNED_INT_SAMPLER_1D_ARRAY = $8DD6;
+ GL_UNSIGNED_INT_SAMPLER_2D_ARRAY = $8DD7;
+ GL_QUERY_WAIT = $8E13;
+ GL_QUERY_NO_WAIT = $8E14;
+ GL_QUERY_BY_REGION_WAIT = $8E15;
+ GL_QUERY_BY_REGION_NO_WAIT = $8E16;
+ GL_BUFFER_ACCESS_FLAGS = $911F;
+ GL_BUFFER_MAP_LENGTH = $9120;
+ GL_BUFFER_MAP_OFFSET = $9121;
+ { Reuse tokens from ARB_depth_buffer_float }
+ { reuse GL_DEPTH_COMPONENT32F }
+ { reuse GL_DEPTH32F_STENCIL8 }
+ { reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV }
+ { Reuse tokens from ARB_framebuffer_object }
+ { reuse GL_INVALID_FRAMEBUFFER_OPERATION }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE }
+ { reuse GL_FRAMEBUFFER_DEFAULT }
+ { reuse GL_FRAMEBUFFER_UNDEFINED }
+ { reuse GL_DEPTH_STENCIL_ATTACHMENT }
+ { reuse GL_INDEX }
+ { reuse GL_MAX_RENDERBUFFER_SIZE }
+ { reuse GL_DEPTH_STENCIL }
+ { reuse GL_UNSIGNED_INT_24_8 }
+ { reuse GL_DEPTH24_STENCIL8 }
+ { reuse GL_TEXTURE_STENCIL_SIZE }
+ { reuse GL_TEXTURE_RED_TYPE }
+ { reuse GL_TEXTURE_GREEN_TYPE }
+ { reuse GL_TEXTURE_BLUE_TYPE }
+ { reuse GL_TEXTURE_ALPHA_TYPE }
+ { reuse GL_TEXTURE_DEPTH_TYPE }
+ { reuse GL_UNSIGNED_NORMALIZED }
+ { reuse GL_FRAMEBUFFER_BINDING }
+ { reuse GL_DRAW_FRAMEBUFFER_BINDING }
+ { reuse GL_RENDERBUFFER_BINDING }
+ { reuse GL_READ_FRAMEBUFFER }
+ { reuse GL_DRAW_FRAMEBUFFER }
+ { reuse GL_READ_FRAMEBUFFER_BINDING }
+ { reuse GL_RENDERBUFFER_SAMPLES }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER }
+ { reuse GL_FRAMEBUFFER_COMPLETE }
+ { reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT }
+ { reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT }
+ { reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER }
+ { reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER }
+ { reuse GL_FRAMEBUFFER_UNSUPPORTED }
+ { reuse GL_MAX_COLOR_ATTACHMENTS }
+ { reuse GL_COLOR_ATTACHMENT0 }
+ { reuse GL_COLOR_ATTACHMENT1 }
+ { reuse GL_COLOR_ATTACHMENT2 }
+ { reuse GL_COLOR_ATTACHMENT3 }
+ { reuse GL_COLOR_ATTACHMENT4 }
+ { reuse GL_COLOR_ATTACHMENT5 }
+ { reuse GL_COLOR_ATTACHMENT6 }
+ { reuse GL_COLOR_ATTACHMENT7 }
+ { reuse GL_COLOR_ATTACHMENT8 }
+ { reuse GL_COLOR_ATTACHMENT9 }
+ { reuse GL_COLOR_ATTACHMENT10 }
+ { reuse GL_COLOR_ATTACHMENT11 }
+ { reuse GL_COLOR_ATTACHMENT12 }
+ { reuse GL_COLOR_ATTACHMENT13 }
+ { reuse GL_COLOR_ATTACHMENT14 }
+ { reuse GL_COLOR_ATTACHMENT15 }
+ { reuse GL_DEPTH_ATTACHMENT }
+ { reuse GL_STENCIL_ATTACHMENT }
+ { reuse GL_FRAMEBUFFER }
+ { reuse GL_RENDERBUFFER }
+ { reuse GL_RENDERBUFFER_WIDTH }
+ { reuse GL_RENDERBUFFER_HEIGHT }
+ { reuse GL_RENDERBUFFER_INTERNAL_FORMAT }
+ { reuse GL_STENCIL_INDEX1 }
+ { reuse GL_STENCIL_INDEX4 }
+ { reuse GL_STENCIL_INDEX8 }
+ { reuse GL_STENCIL_INDEX16 }
+ { reuse GL_RENDERBUFFER_RED_SIZE }
+ { reuse GL_RENDERBUFFER_GREEN_SIZE }
+ { reuse GL_RENDERBUFFER_BLUE_SIZE }
+ { reuse GL_RENDERBUFFER_ALPHA_SIZE }
+ { reuse GL_RENDERBUFFER_DEPTH_SIZE }
+ { reuse GL_RENDERBUFFER_STENCIL_SIZE }
+ { reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE }
+ { reuse GL_MAX_SAMPLES }
+ { Reuse tokens from ARB_framebuffer_sRGB }
+ { reuse GL_FRAMEBUFFER_SRGB }
+ { Reuse tokens from ARB_half_float_vertex }
+ { reuse GL_HALF_FLOAT }
+ { Reuse tokens from ARB_map_buffer_range }
+ { reuse GL_MAP_READ_BIT }
+ { reuse GL_MAP_WRITE_BIT }
+ { reuse GL_MAP_INVALIDATE_RANGE_BIT }
+ { reuse GL_MAP_INVALIDATE_BUFFER_BIT }
+ { reuse GL_MAP_FLUSH_EXPLICIT_BIT }
+ { reuse GL_MAP_UNSYNCHRONIZED_BIT }
+ { Reuse tokens from ARB_texture_compression_rgtc }
+ { reuse GL_COMPRESSED_RED_RGTC1 }
+ { reuse GL_COMPRESSED_SIGNED_RED_RGTC1 }
+ { reuse GL_COMPRESSED_RG_RGTC2 }
+ { reuse GL_COMPRESSED_SIGNED_RG_RGTC2 }
+ { Reuse tokens from ARB_texture_rg }
+ { reuse GL_RG }
+ { reuse GL_RG_INTEGER }
+ { reuse GL_R8 }
+ { reuse GL_R16 }
+ { reuse GL_RG8 }
+ { reuse GL_RG16 }
+ { reuse GL_R16F }
+ { reuse GL_R32F }
+ { reuse GL_RG16F }
+ { reuse GL_RG32F }
+ { reuse GL_R8I }
+ { reuse GL_R8UI }
+ { reuse GL_R16I }
+ { reuse GL_R16UI }
+ { reuse GL_R32I }
+ { reuse GL_R32UI }
+ { reuse GL_RG8I }
+ { reuse GL_RG8UI }
+ { reuse GL_RG16I }
+ { reuse GL_RG16UI }
+ { reuse GL_RG32I }
+ { reuse GL_RG32UI }
+ { Reuse tokens from ARB_vertex_array_object }
+ { reuse GL_VERTEX_ARRAY_BINDING }
+{$ifdef DGL_DEPRECATED}
+ GL_CLAMP_VERTEX_COLOR = $891A;
+ GL_CLAMP_FRAGMENT_COLOR = $891B;
+ GL_ALPHA_INTEGER = $8D97;
+ { Reuse tokens from ARB_framebuffer_object }
+ { reuse GL_TEXTURE_LUMINANCE_TYPE }
+ { reuse GL_TEXTURE_INTENSITY_TYPE }
+{$endif}
+
+ // GL_VERSION_3_1
+ GL_SAMPLER_2D_RECT = $8B63;
+ GL_SAMPLER_2D_RECT_SHADOW = $8B64;
+ GL_SAMPLER_BUFFER = $8DC2;
+ GL_INT_SAMPLER_2D_RECT = $8DCD;
+ GL_INT_SAMPLER_BUFFER = $8DD0;
+ GL_UNSIGNED_INT_SAMPLER_2D_RECT = $8DD5;
+ GL_UNSIGNED_INT_SAMPLER_BUFFER = $8DD8;
+ GL_TEXTURE_BUFFER = $8C2A;
+ GL_MAX_TEXTURE_BUFFER_SIZE = $8C2B;
+ GL_TEXTURE_BINDING_BUFFER = $8C2C;
+ GL_TEXTURE_BUFFER_DATA_STORE_BINDING = $8C2D;
+ GL_TEXTURE_BUFFER_FORMAT = $8C2E;
+ GL_TEXTURE_RECTANGLE = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE = $84F8;
+ GL_RED_SNORM = $8F90;
+ GL_RG_SNORM = $8F91;
+ GL_RGB_SNORM = $8F92;
+ GL_RGBA_SNORM = $8F93;
+ GL_R8_SNORM = $8F94;
+ GL_RG8_SNORM = $8F95;
+ GL_RGB8_SNORM = $8F96;
+ GL_RGBA8_SNORM = $8F97;
+ GL_R16_SNORM = $8F98;
+ GL_RG16_SNORM = $8F99;
+ GL_RGB16_SNORM = $8F9A;
+ GL_RGBA16_SNORM = $8F9B;
+ GL_SIGNED_NORMALIZED = $8F9C;
+ GL_PRIMITIVE_RESTART = $8F9D;
+ GL_PRIMITIVE_RESTART_INDEX = $8F9E;
+ { Reuse tokens from ARB_copy_buffer }
+ { reuse GL_COPY_READ_BUFFER }
+ { reuse GL_COPY_WRITE_BUFFER }
+ { Reuse tokens from ARB_draw_instanced (none) }
+ { Reuse tokens from ARB_uniform_buffer_object }
+ { reuse GL_UNIFORM_BUFFER }
+ { reuse GL_UNIFORM_BUFFER_BINDING }
+ { reuse GL_UNIFORM_BUFFER_START }
+ { reuse GL_UNIFORM_BUFFER_SIZE }
+ { reuse GL_MAX_VERTEX_UNIFORM_BLOCKS }
+ { reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS }
+ { reuse GL_MAX_COMBINED_UNIFORM_BLOCKS }
+ { reuse GL_MAX_UNIFORM_BUFFER_BINDINGS }
+ { reuse GL_MAX_UNIFORM_BLOCK_SIZE }
+ { reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS }
+ { reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT }
+ { reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH }
+ { reuse GL_ACTIVE_UNIFORM_BLOCKS }
+ { reuse GL_UNIFORM_TYPE }
+ { reuse GL_UNIFORM_SIZE }
+ { reuse GL_UNIFORM_NAME_LENGTH }
+ { reuse GL_UNIFORM_BLOCK_INDEX }
+ { reuse GL_UNIFORM_OFFSET }
+ { reuse GL_UNIFORM_ARRAY_STRIDE }
+ { reuse GL_UNIFORM_MATRIX_STRIDE }
+ { reuse GL_UNIFORM_IS_ROW_MAJOR }
+ { reuse GL_UNIFORM_BLOCK_BINDING }
+ { reuse GL_UNIFORM_BLOCK_DATA_SIZE }
+ { reuse GL_UNIFORM_BLOCK_NAME_LENGTH }
+ { reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS }
+ { reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES }
+ { reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER }
+ { reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER }
+ { reuse GL_INVALID_INDEX }
+
+ // GL_VERSION_3_2
+ GL_CONTEXT_CORE_PROFILE_BIT = $00000001;
+ GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = $00000002;
+ GL_LINES_ADJACENCY = $000A;
+ GL_LINE_STRIP_ADJACENCY = $000B;
+ GL_TRIANGLES_ADJACENCY = $000C;
+ GL_TRIANGLE_STRIP_ADJACENCY = $000D;
+ GL_PROGRAM_POINT_SIZE = $8642;
+ GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = $8C29;
+ GL_FRAMEBUFFER_ATTACHMENT_LAYERED = $8DA7;
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = $8DA8;
+ GL_GEOMETRY_SHADER = $8DD9;
+ GL_GEOMETRY_VERTICES_OUT = $8916;
+ GL_GEOMETRY_INPUT_TYPE = $8917;
+ GL_GEOMETRY_OUTPUT_TYPE = $8918;
+ GL_MAX_GEOMETRY_UNIFORM_COMPONENTS = $8DDF;
+ GL_MAX_GEOMETRY_OUTPUT_VERTICES = $8DE0;
+ GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = $8DE1;
+ GL_MAX_VERTEX_OUTPUT_COMPONENTS = $9122;
+ GL_MAX_GEOMETRY_INPUT_COMPONENTS = $9123;
+ GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = $9124;
+ GL_MAX_FRAGMENT_INPUT_COMPONENTS = $9125;
+ GL_CONTEXT_PROFILE_MASK = $9126;
+ { reuse GL_MAX_VARYING_COMPONENTS }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER }
+ { Reuse tokens from ARB_depth_clamp }
+ { reuse GL_DEPTH_CLAMP }
+ { Reuse tokens from ARB_draw_elements_base_vertex (none) }
+ { Reuse tokens from ARB_fragment_coord_conventions (none) }
+ { Reuse tokens from ARB_provoking_vertex }
+ { reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION }
+ { reuse GL_FIRST_VERTEX_CONVENTION }
+ { reuse GL_LAST_VERTEX_CONVENTION }
+ { reuse GL_PROVOKING_VERTEX }
+ { Reuse tokens from ARB_seamless_cube_map }
+ { reuse GL_TEXTURE_CUBE_MAP_SEAMLESS }
+ { Reuse tokens from ARB_sync }
+ { reuse GL_MAX_SERVER_WAIT_TIMEOUT }
+ { reuse GL_OBJECT_TYPE }
+ { reuse GL_SYNC_CONDITION }
+ { reuse GL_SYNC_STATUS }
+ { reuse GL_SYNC_FLAGS }
+ { reuse GL_SYNC_FENCE }
+ { reuse GL_SYNC_GPU_COMMANDS_COMPLETE }
+ { reuse GL_UNSIGNALED }
+ { reuse GL_SIGNALED }
+ { reuse GL_ALREADY_SIGNALED }
+ { reuse GL_TIMEOUT_EXPIRED }
+ { reuse GL_CONDITION_SATISFIED }
+ { reuse GL_WAIT_FAILED }
+ { reuse GL_TIMEOUT_IGNORED }
+ { reuse GL_SYNC_FLUSH_COMMANDS_BIT }
+ { reuse GL_TIMEOUT_IGNORED }
+ { Reuse tokens from ARB_texture_multisample }
+ { reuse GL_SAMPLE_POSITION }
+ { reuse GL_SAMPLE_MASK }
+ { reuse GL_SAMPLE_MASK_VALUE }
+ { reuse GL_MAX_SAMPLE_MASK_WORDS }
+ { reuse GL_TEXTURE_2D_MULTISAMPLE }
+ { reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE }
+ { reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE }
+ { reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_TEXTURE_SAMPLES }
+ { reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS }
+ { reuse GL_SAMPLER_2D_MULTISAMPLE }
+ { reuse GL_INT_SAMPLER_2D_MULTISAMPLE }
+ { reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE }
+ { reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_MAX_COLOR_TEXTURE_SAMPLES }
+ { reuse GL_MAX_DEPTH_TEXTURE_SAMPLES }
+ { reuse GL_MAX_INTEGER_SAMPLES }
+ { Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core }
+
+ // GL_VERSION_3_3
+ GL_VERTEX_ATTRIB_ARRAY_DIVISOR = $88FE;
+ { Reuse tokens from ARB_blend_func_extended }
+ { reuse GL_SRC1_COLOR }
+ { reuse GL_ONE_MINUS_SRC1_COLOR }
+ { reuse GL_ONE_MINUS_SRC1_ALPHA }
+ { reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS }
+ { Reuse tokens from ARB_explicit_attrib_location (none) }
+ { Reuse tokens from ARB_occlusion_query2 }
+ { reuse GL_ANY_SAMPLES_PASSED }
+ { Reuse tokens from ARB_sampler_objects }
+ { reuse GL_SAMPLER_BINDING }
+ { Reuse tokens from ARB_shader_bit_encoding (none) }
+ { Reuse tokens from ARB_texture_rgb10_a2ui }
+ { reuse GL_RGB10_A2UI }
+ { Reuse tokens from ARB_texture_swizzle }
+ { reuse GL_TEXTURE_SWIZZLE_R }
+ { reuse GL_TEXTURE_SWIZZLE_G }
+ { reuse GL_TEXTURE_SWIZZLE_B }
+ { reuse GL_TEXTURE_SWIZZLE_A }
+ { reuse GL_TEXTURE_SWIZZLE_RGBA }
+ { Reuse tokens from ARB_timer_query }
+ { reuse GL_TIME_ELAPSED }
+ { reuse GL_TIMESTAMP }
+ { Reuse tokens from ARB_vertex_type_2_10_10_10_rev }
+ { reuse GL_INT_2_10_10_10_REV }
+
+ // GL_VERSION_4_0
+ GL_SAMPLE_SHADING = $8C36;
+ GL_MIN_SAMPLE_SHADING_VALUE = $8C37;
+ GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET = $8E5E;
+ GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET = $8E5F;
+ GL_TEXTURE_CUBE_MAP_ARRAY = $9009;
+ GL_TEXTURE_BINDING_CUBE_MAP_ARRAY = $900A;
+ GL_PROXY_TEXTURE_CUBE_MAP_ARRAY = $900B;
+ GL_SAMPLER_CUBE_MAP_ARRAY = $900C;
+ GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW = $900D;
+ GL_INT_SAMPLER_CUBE_MAP_ARRAY = $900E;
+ GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = $900F;
+ { Reuse tokens from ARB_texture_query_lod (none) }
+ { Reuse tokens from ARB_draw_buffers_blend (none) }
+ { Reuse tokens from ARB_draw_indirect }
+ { reuse GL_DRAW_INDIRECT_BUFFER }
+ { reuse GL_DRAW_INDIRECT_BUFFER_BINDING }
+ { Reuse tokens from ARB_gpu_shader5 }
+ { reuse GL_GEOMETRY_SHADER_INVOCATIONS }
+ { reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS }
+ { reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET }
+ { reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET }
+ { reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS }
+ { reuse GL_MAX_VERTEX_STREAMS }
+ { Reuse tokens from ARB_gpu_shader_fp64 }
+ { reuse GL_DOUBLE_VEC2 }
+ { reuse GL_DOUBLE_VEC3 }
+ { reuse GL_DOUBLE_VEC4 }
+ { reuse GL_DOUBLE_MAT2 }
+ { reuse GL_DOUBLE_MAT3 }
+ { reuse GL_DOUBLE_MAT4 }
+ { reuse GL_DOUBLE_MAT2x3 }
+ { reuse GL_DOUBLE_MAT2x4 }
+ { reuse GL_DOUBLE_MAT3x2 }
+ { reuse GL_DOUBLE_MAT3x4 }
+ { reuse GL_DOUBLE_MAT4x2 }
+ { reuse GL_DOUBLE_MAT4x3 }
+ { Reuse tokens from ARB_shader_subroutine }
+ { reuse GL_ACTIVE_SUBROUTINES }
+ { reuse GL_ACTIVE_SUBROUTINE_UNIFORMS }
+ { reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS }
+ { reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH }
+ { reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH }
+ { reuse GL_MAX_SUBROUTINES }
+ { reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS }
+ { reuse GL_NUM_COMPATIBLE_SUBROUTINES }
+ { reuse GL_COMPATIBLE_SUBROUTINES }
+ { Reuse tokens from ARB_tessellation_shader }
+ { reuse GL_PATCHES }
+ { reuse GL_PATCH_VERTICES }
+ { reuse GL_PATCH_DEFAULT_INNER_LEVEL }
+ { reuse GL_PATCH_DEFAULT_OUTER_LEVEL }
+ { reuse GL_TESS_CONTROL_OUTPUT_VERTICES }
+ { reuse GL_TESS_GEN_MODE }
+ { reuse GL_TESS_GEN_SPACING }
+ { reuse GL_TESS_GEN_VERTEX_ORDER }
+ { reuse GL_TESS_GEN_POINT_MODE }
+ { reuse GL_ISOLINES }
+ { reuse GL_FRACTIONAL_ODD }
+ { reuse GL_FRACTIONAL_EVEN }
+ { reuse GL_MAX_PATCH_VERTICES }
+ { reuse GL_MAX_TESS_GEN_LEVEL }
+ { reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS }
+ { reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS }
+ { reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS }
+ { reuse GL_MAX_TESS_PATCH_COMPONENTS }
+ { reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS }
+ { reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS }
+ { reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS }
+ { reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS }
+ { reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS }
+ { reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS }
+ { reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS }
+ { reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER }
+ { reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER }
+ { reuse GL_TESS_EVALUATION_SHADER }
+ { reuse GL_TESS_CONTROL_SHADER }
+ { Reuse tokens from ARB_texture_buffer_object_rgb32 (none) }
+ { Reuse tokens from ARB_transform_feedback2 }
+ { reuse GL_TRANSFORM_FEEDBACK }
+ { reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED }
+ { reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE }
+ { reuse GL_TRANSFORM_FEEDBACK_BINDING }
+ { Reuse tokens from ARB_transform_feedback3 }
+ { reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS }
+ { reuse GL_MAX_VERTEX_STREAMS }
+
+ // GL_VERSION_4_1
+ { Reuse tokens from ARB_ES2_compatibility }
+ { reuse GL_FIXED }
+ { reuse GL_IMPLEMENTATION_COLOR_READ_TYPE }
+ { reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT }
+ { reuse GL_LOW_FLOAT }
+ { reuse GL_MEDIUM_FLOAT }
+ { reuse GL_HIGH_FLOAT }
+ { reuse GL_LOW_INT }
+ { reuse GL_MEDIUM_INT }
+ { reuse GL_HIGH_INT }
+ { reuse GL_SHADER_COMPILER }
+ { reuse GL_NUM_SHADER_BINARY_FORMATS }
+ { reuse GL_MAX_VERTEX_UNIFORM_VECTORS }
+ { reuse GL_MAX_VARYING_VECTORS }
+ { reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS }
+ { reuse GL_RGB565 }
+ { Reuse tokens from ARB_get_program_binary }
+ { reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT }
+ { reuse GL_PROGRAM_BINARY_LENGTH }
+ { reuse GL_NUM_PROGRAM_BINARY_FORMATS }
+ { reuse GL_PROGRAM_BINARY_FORMATS }
+ { Reuse tokens from ARB_separate_shader_objects }
+ { reuse GL_VERTEX_SHADER_BIT }
+ { reuse GL_FRAGMENT_SHADER_BIT }
+ { reuse GL_GEOMETRY_SHADER_BIT }
+ { reuse GL_TESS_CONTROL_SHADER_BIT }
+ { reuse GL_TESS_EVALUATION_SHADER_BIT }
+ { reuse GL_ALL_SHADER_BITS }
+ { reuse GL_PROGRAM_SEPARABLE }
+ { reuse GL_ACTIVE_PROGRAM }
+ { reuse GL_PROGRAM_PIPELINE_BINDING }
+ { Reuse tokens from ARB_shader_precision (none) }
+ { Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already }
+ { Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already }
+ { reuse GL_MAX_VIEWPORTS }
+ { reuse GL_VIEWPORT_SUBPIXEL_BITS }
+ { reuse GL_VIEWPORT_BOUNDS_RANGE }
+ { reuse GL_LAYER_PROVOKING_VERTEX }
+ { reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX }
+ { reuse GL_UNDEFINED_VERTEX }
+
+ // GL_VERSION_4_2
+ { Reuse tokens from ARB_base_instance (none) }
+ { Reuse tokens from ARB_shading_language_420pack (none) }
+ { Reuse tokens from ARB_transform_feedback_instanced (none) }
+ { Reuse tokens from ARB_compressed_texture_pixel_storage }
+ { reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH }
+ { reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT }
+ { reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH }
+ { reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE }
+ { reuse GL_PACK_COMPRESSED_BLOCK_WIDTH }
+ { reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT }
+ { reuse GL_PACK_COMPRESSED_BLOCK_DEPTH }
+ { reuse GL_PACK_COMPRESSED_BLOCK_SIZE }
+ { Reuse tokens from ARB_conservative_depth (none) }
+ { Reuse tokens from ARB_internalformat_query }
+ { reuse GL_NUM_SAMPLE_COUNTS }
+ { Reuse tokens from ARB_map_buffer_alignment }
+ { reuse GL_MIN_MAP_BUFFER_ALIGNMENT }
+ { Reuse tokens from ARB_shader_atomic_counters }
+ { reuse GL_ATOMIC_COUNTER_BUFFER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_BINDING }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_START }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_SIZE }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER }
+ { reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_VERTEX_ATOMIC_COUNTERS }
+ { reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS }
+ { reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS }
+ { reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS }
+ { reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS }
+ { reuse GL_MAX_COMBINED_ATOMIC_COUNTERS }
+ { reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE }
+ { reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS }
+ { reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX }
+ { reuse GL_UNSIGNED_INT_ATOMIC_COUNTER }
+ { Reuse tokens from ARB_shader_image_load_store }
+ { reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT }
+ { reuse GL_ELEMENT_ARRAY_BARRIER_BIT }
+ { reuse GL_UNIFORM_BARRIER_BIT }
+ { reuse GL_TEXTURE_FETCH_BARRIER_BIT }
+ { reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT }
+ { reuse GL_COMMAND_BARRIER_BIT }
+ { reuse GL_PIXEL_BUFFER_BARRIER_BIT }
+ { reuse GL_TEXTURE_UPDATE_BARRIER_BIT }
+ { reuse GL_BUFFER_UPDATE_BARRIER_BIT }
+ { reuse GL_FRAMEBUFFER_BARRIER_BIT }
+ { reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT }
+ { reuse GL_ATOMIC_COUNTER_BARRIER_BIT }
+ { reuse GL_ALL_BARRIER_BITS }
+ { reuse GL_MAX_IMAGE_UNITS }
+ { reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS }
+ { reuse GL_IMAGE_BINDING_NAME }
+ { reuse GL_IMAGE_BINDING_LEVEL }
+ { reuse GL_IMAGE_BINDING_LAYERED }
+ { reuse GL_IMAGE_BINDING_LAYER }
+ { reuse GL_IMAGE_BINDING_ACCESS }
+ { reuse GL_IMAGE_1D }
+ { reuse GL_IMAGE_2D }
+ { reuse GL_IMAGE_3D }
+ { reuse GL_IMAGE_2D_RECT }
+ { reuse GL_IMAGE_CUBE }
+ { reuse GL_IMAGE_BUFFER }
+ { reuse GL_IMAGE_1D_ARRAY }
+ { reuse GL_IMAGE_2D_ARRAY }
+ { reuse GL_IMAGE_CUBE_MAP_ARRAY }
+ { reuse GL_IMAGE_2D_MULTISAMPLE }
+ { reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_INT_IMAGE_1D }
+ { reuse GL_INT_IMAGE_2D }
+ { reuse GL_INT_IMAGE_3D }
+ { reuse GL_INT_IMAGE_2D_RECT }
+ { reuse GL_INT_IMAGE_CUBE }
+ { reuse GL_INT_IMAGE_BUFFER }
+ { reuse GL_INT_IMAGE_1D_ARRAY }
+ { reuse GL_INT_IMAGE_2D_ARRAY }
+ { reuse GL_INT_IMAGE_CUBE_MAP_ARRAY }
+ { reuse GL_INT_IMAGE_2D_MULTISAMPLE }
+ { reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_UNSIGNED_INT_IMAGE_1D }
+ { reuse GL_UNSIGNED_INT_IMAGE_2D }
+ { reuse GL_UNSIGNED_INT_IMAGE_3D }
+ { reuse GL_UNSIGNED_INT_IMAGE_2D_RECT }
+ { reuse GL_UNSIGNED_INT_IMAGE_CUBE }
+ { reuse GL_UNSIGNED_INT_IMAGE_BUFFER }
+ { reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY }
+ { reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY }
+ { reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY }
+ { reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE }
+ { reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY }
+ { reuse GL_MAX_IMAGE_SAMPLES }
+ { reuse GL_IMAGE_BINDING_FORMAT }
+ { reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE }
+ { reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE }
+ { reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS }
+ { reuse GL_MAX_VERTEX_IMAGE_UNIFORMS }
+ { reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS }
+ { reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS }
+ { reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS }
+ { reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS }
+ { reuse GL_MAX_COMBINED_IMAGE_UNIFORMS }
+ { Reuse tokens from ARB_shading_language_packing (none) }
+ { Reuse tokens from ARB_texture_storage }
+ { reuse GL_TEXTURE_IMMUTABLE_FORMAT }
+
+ // GL_VERSION_4_3
+ GL_NUM_SHADING_LANGUAGE_VERSIONS = $82E9;
+ GL_VERTEX_ATTRIB_ARRAY_LONG = $874E;
+ { Reuse tokens from ARB_arrays_of_arrays (none, GLSL only) }
+ { Reuse tokens from ARB_fragment_layer_viewport (none, GLSL only) }
+ { Reuse tokens from ARB_shader_image_size (none, GLSL only) }
+ { Reuse tokens from ARB_ES3_compatibility }
+ { reuse GL_COMPRESSED_RGB8_ETC2 }
+ { reuse GL_COMPRESSED_SRGB8_ETC2 }
+ { reuse GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 }
+ { reuse GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 }
+ { reuse GL_COMPRESSED_RGBA8_ETC2_EAC }
+ { reuse GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC }
+ { reuse GL_COMPRESSED_R11_EAC }
+ { reuse GL_COMPRESSED_SIGNED_R11_EAC }
+ { reuse GL_COMPRESSED_RG11_EAC }
+ { reuse GL_COMPRESSED_SIGNED_RG11_EAC }
+ { reuse GL_PRIMITIVE_RESTART_FIXED_INDEX }
+ { reuse GL_ANY_SAMPLES_PASSED_CONSERVATIVE }
+ { reuse GL_MAX_ELEMENT_INDEX }
+ { Reuse tokens from ARB_clear_buffer_object (none) }
+ { Reuse tokens from ARB_compute_shader }
+ { reuse GL_COMPUTE_SHADER }
+ { reuse GL_MAX_COMPUTE_UNIFORM_BLOCKS }
+ { reuse GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS }
+ { reuse GL_MAX_COMPUTE_IMAGE_UNIFORMS }
+ { reuse GL_MAX_COMPUTE_SHARED_MEMORY_SIZE }
+ { reuse GL_MAX_COMPUTE_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS }
+ { reuse GL_MAX_COMPUTE_ATOMIC_COUNTERS }
+ { reuse GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS }
+ { reuse GL_MAX_COMPUTE_LOCAL_INVOCATIONS }
+ { reuse GL_MAX_COMPUTE_WORK_GROUP_COUNT }
+ { reuse GL_MAX_COMPUTE_WORK_GROUP_SIZE }
+ { reuse GL_COMPUTE_LOCAL_WORK_SIZE }
+ { reuse GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER }
+ { reuse GL_DISPATCH_INDIRECT_BUFFER }
+ { reuse GL_DISPATCH_INDIRECT_BUFFER_BINDING }
+ { Reuse tokens from ARB_copy_image (none) }
+ { Reuse tokens from KHR_debug }
+ { reuse GL_DEBUG_OUTPUT_SYNCHRONOUS }
+ { reuse GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH }
+ { reuse GL_DEBUG_CALLBACK_FUNCTION }
+ { reuse GL_DEBUG_CALLBACK_USER_PARAM }
+ { reuse GL_DEBUG_SOURCE_API }
+ { reuse GL_DEBUG_SOURCE_WINDOW_SYSTEM }
+ { reuse GL_DEBUG_SOURCE_SHADER_COMPILER }
+ { reuse GL_DEBUG_SOURCE_THIRD_PARTY }
+ { reuse GL_DEBUG_SOURCE_APPLICATION }
+ { reuse GL_DEBUG_SOURCE_OTHER }
+ { reuse GL_DEBUG_TYPE_ERROR }
+ { reuse GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR }
+ { reuse GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR }
+ { reuse GL_DEBUG_TYPE_PORTABILITY }
+ { reuse GL_DEBUG_TYPE_PERFORMANCE }
+ { reuse GL_DEBUG_TYPE_OTHER }
+ { reuse GL_MAX_DEBUG_MESSAGE_LENGTH }
+ { reuse GL_MAX_DEBUG_LOGGED_MESSAGES }
+ { reuse GL_DEBUG_LOGGED_MESSAGES }
+ { reuse GL_DEBUG_SEVERITY_HIGH }
+ { reuse GL_DEBUG_SEVERITY_MEDIUM }
+ { reuse GL_DEBUG_SEVERITY_LOW }
+ { reuse GL_DEBUG_TYPE_MARKER }
+ { reuse GL_DEBUG_TYPE_PUSH_GROUP }
+ { reuse GL_DEBUG_TYPE_POP_GROUP }
+ { reuse GL_DEBUG_SEVERITY_NOTIFICATION }
+ { reuse GL_MAX_DEBUG_GROUP_STACK_DEPTH }
+ { reuse GL_DEBUG_GROUP_STACK_DEPTH }
+ { reuse GL_BUFFER }
+ { reuse GL_SHADER }
+ { reuse GL_PROGRAM }
+ { reuse GL_QUERY }
+ { reuse GL_PROGRAM_PIPELINE }
+ { reuse GL_SAMPLER }
+ { reuse GL_DISPLAY_LIST }
+ { reuse GL_MAX_LABEL_LENGTH }
+ { reuse GL_DEBUG_OUTPUT }
+ { reuse GL_CONTEXT_FLAG_DEBUG_BIT }
+ { reuse GL_STACK_UNDERFLOW }
+ { reuse GL_STACK_OVERFLOW }
+ { Reuse tokens from ARB_explicit_uniform_location }
+ { reuse GL_MAX_UNIFORM_LOCATIONS }
+ { Reuse tokens from ARB_framebuffer_no_attachments }
+ { reuse GL_FRAMEBUFFER_DEFAULT_WIDTH }
+ { reuse GL_FRAMEBUFFER_DEFAULT_HEIGHT }
+ { reuse GL_FRAMEBUFFER_DEFAULT_LAYERS }
+ { reuse GL_FRAMEBUFFER_DEFAULT_SAMPLES }
+ { reuse GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS }
+ { reuse GL_MAX_FRAMEBUFFER_WIDTH }
+ { reuse GL_MAX_FRAMEBUFFER_HEIGHT }
+ { reuse GL_MAX_FRAMEBUFFER_LAYERS }
+ { reuse GL_MAX_FRAMEBUFFER_SAMPLES }
+ { Reuse tokens from ARB_internalformat_query2 }
+ { reuse GL_INTERNALFORMAT_SUPPORTED }
+ { reuse GL_INTERNALFORMAT_PREFERRED }
+ { reuse GL_INTERNALFORMAT_RED_SIZE }
+ { reuse GL_INTERNALFORMAT_GREEN_SIZE }
+ { reuse GL_INTERNALFORMAT_BLUE_SIZE }
+ { reuse GL_INTERNALFORMAT_ALPHA_SIZE }
+ { reuse GL_INTERNALFORMAT_DEPTH_SIZE }
+ { reuse GL_INTERNALFORMAT_STENCIL_SIZE }
+ { reuse GL_INTERNALFORMAT_SHARED_SIZE }
+ { reuse GL_INTERNALFORMAT_RED_TYPE }
+ { reuse GL_INTERNALFORMAT_GREEN_TYPE }
+ { reuse GL_INTERNALFORMAT_BLUE_TYPE }
+ { reuse GL_INTERNALFORMAT_ALPHA_TYPE }
+ { reuse GL_INTERNALFORMAT_DEPTH_TYPE }
+ { reuse GL_INTERNALFORMAT_STENCIL_TYPE }
+ { reuse GL_MAX_WIDTH }
+ { reuse GL_MAX_HEIGHT }
+ { reuse GL_MAX_DEPTH }
+ { reuse GL_MAX_LAYERS }
+ { reuse GL_MAX_COMBINED_DIMENSIONS }
+ { reuse GL_COLOR_COMPONENTS }
+ { reuse GL_DEPTH_COMPONENTS }
+ { reuse GL_STENCIL_COMPONENTS }
+ { reuse GL_COLOR_RENDERABLE }
+ { reuse GL_DEPTH_RENDERABLE }
+ { reuse GL_STENCIL_RENDERABLE }
+ { reuse GL_FRAMEBUFFER_RENDERABLE }
+ { reuse GL_FRAMEBUFFER_RENDERABLE_LAYERED }
+ { reuse GL_FRAMEBUFFER_BLEND }
+ { reuse GL_READ_PIXELS }
+ { reuse GL_READ_PIXELS_FORMAT }
+ { reuse GL_READ_PIXELS_TYPE }
+ { reuse GL_TEXTURE_IMAGE_FORMAT }
+ { reuse GL_TEXTURE_IMAGE_TYPE }
+ { reuse GL_GET_TEXTURE_IMAGE_FORMAT }
+ { reuse GL_GET_TEXTURE_IMAGE_TYPE }
+ { reuse GL_MIPMAP }
+ { reuse GL_MANUAL_GENERATE_MIPMAP }
+ { reuse GL_AUTO_GENERATE_MIPMAP }
+ { reuse GL_COLOR_ENCODING }
+ { reuse GL_SRGB_READ }
+ { reuse GL_SRGB_WRITE }
+ { reuse GL_FILTER }
+ { reuse GL_VERTEX_TEXTURE }
+ { reuse GL_TESS_CONTROL_TEXTURE }
+ { reuse GL_TESS_EVALUATION_TEXTURE }
+ { reuse GL_GEOMETRY_TEXTURE }
+ { reuse GL_FRAGMENT_TEXTURE }
+ { reuse GL_COMPUTE_TEXTURE }
+ { reuse GL_TEXTURE_SHADOW }
+ { reuse GL_TEXTURE_GATHER }
+ { reuse GL_TEXTURE_GATHER_SHADOW }
+ { reuse GL_SHADER_IMAGE_LOAD }
+ { reuse GL_SHADER_IMAGE_STORE }
+ { reuse GL_SHADER_IMAGE_ATOMIC }
+ { reuse GL_IMAGE_TEXEL_SIZE }
+ { reuse GL_IMAGE_COMPATIBILITY_CLASS }
+ { reuse GL_IMAGE_PIXEL_FORMAT }
+ { reuse GL_IMAGE_PIXEL_TYPE }
+ { reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST }
+ { reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST }
+ { reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE }
+ { reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE }
+ { reuse GL_TEXTURE_COMPRESSED_BLOCK_WIDTH }
+ { reuse GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT }
+ { reuse GL_TEXTURE_COMPRESSED_BLOCK_SIZE }
+ { reuse GL_CLEAR_BUFFER }
+ { reuse GL_TEXTURE_VIEW }
+ { reuse GL_VIEW_COMPATIBILITY_CLASS }
+ { reuse GL_FULL_SUPPORT }
+ { reuse GL_CAVEAT_SUPPORT }
+ { reuse GL_IMAGE_CLASS_4_X_32 }
+ { reuse GL_IMAGE_CLASS_2_X_32 }
+ { reuse GL_IMAGE_CLASS_1_X_32 }
+ { reuse GL_IMAGE_CLASS_4_X_16 }
+ { reuse GL_IMAGE_CLASS_2_X_16 }
+ { reuse GL_IMAGE_CLASS_1_X_16 }
+ { reuse GL_IMAGE_CLASS_4_X_8 }
+ { reuse GL_IMAGE_CLASS_2_X_8 }
+ { reuse GL_IMAGE_CLASS_1_X_8 }
+ { reuse GL_IMAGE_CLASS_11_11_10 }
+ { reuse GL_IMAGE_CLASS_10_10_10_2 }
+ { reuse GL_VIEW_CLASS_128_BITS }
+ { reuse GL_VIEW_CLASS_96_BITS }
+ { reuse GL_VIEW_CLASS_64_BITS }
+ { reuse GL_VIEW_CLASS_48_BITS }
+ { reuse GL_VIEW_CLASS_32_BITS }
+ { reuse GL_VIEW_CLASS_24_BITS }
+ { reuse GL_VIEW_CLASS_16_BITS }
+ { reuse GL_VIEW_CLASS_8_BITS }
+ { reuse GL_VIEW_CLASS_S3TC_DXT1_RGB }
+ { reuse GL_VIEW_CLASS_S3TC_DXT1_RGBA }
+ { reuse GL_VIEW_CLASS_S3TC_DXT3_RGBA }
+ { reuse GL_VIEW_CLASS_S3TC_DXT5_RGBA }
+ { reuse GL_VIEW_CLASS_RGTC1_RED }
+ { reuse GL_VIEW_CLASS_RGTC2_RG }
+ { reuse GL_VIEW_CLASS_BPTC_UNORM }
+ { reuse GL_VIEW_CLASS_BPTC_FLOAT }
+ { Reuse tokens from ARB_invalidate_subdata (none) }
+ { Reuse tokens from ARB_multi_draw_indirect (none) }
+ { Reuse tokens from ARB_program_interface_query }
+ { reuse GL_UNIFORM }
+ { reuse GL_UNIFORM_BLOCK }
+ { reuse GL_PROGRAM_INPUT }
+ { reuse GL_PROGRAM_OUTPUT }
+ { reuse GL_BUFFER_VARIABLE }
+ { reuse GL_SHADER_STORAGE_BLOCK }
+ { reuse GL_VERTEX_SUBROUTINE }
+ { reuse GL_TESS_CONTROL_SUBROUTINE }
+ { reuse GL_TESS_EVALUATION_SUBROUTINE }
+ { reuse GL_GEOMETRY_SUBROUTINE }
+ { reuse GL_FRAGMENT_SUBROUTINE }
+ { reuse GL_COMPUTE_SUBROUTINE }
+ { reuse GL_VERTEX_SUBROUTINE_UNIFORM }
+ { reuse GL_TESS_CONTROL_SUBROUTINE_UNIFORM }
+ { reuse GL_TESS_EVALUATION_SUBROUTINE_UNIFORM }
+ { reuse GL_GEOMETRY_SUBROUTINE_UNIFORM }
+ { reuse GL_FRAGMENT_SUBROUTINE_UNIFORM }
+ { reuse GL_COMPUTE_SUBROUTINE_UNIFORM }
+ { reuse GL_TRANSFORM_FEEDBACK_VARYING }
+ { reuse GL_ACTIVE_RESOURCES }
+ { reuse GL_MAX_NAME_LENGTH }
+ { reuse GL_MAX_NUM_ACTIVE_VARIABLES }
+ { reuse GL_MAX_NUM_COMPATIBLE_SUBROUTINES }
+ { reuse GL_NAME_LENGTH }
+ { reuse GL_TYPE }
+ { reuse GL_ARRAY_SIZE }
+ { reuse GL_OFFSET }
+ { reuse GL_BLOCK_INDEX }
+ { reuse GL_ARRAY_STRIDE }
+ { reuse GL_MATRIX_STRIDE }
+ { reuse GL_IS_ROW_MAJOR }
+ { reuse GL_ATOMIC_COUNTER_BUFFER_INDEX }
+ { reuse GL_BUFFER_BINDING }
+ { reuse GL_BUFFER_DATA_SIZE }
+ { reuse GL_NUM_ACTIVE_VARIABLES }
+ { reuse GL_ACTIVE_VARIABLES }
+ { reuse GL_REFERENCED_BY_VERTEX_SHADER }
+ { reuse GL_REFERENCED_BY_TESS_CONTROL_SHADER }
+ { reuse GL_REFERENCED_BY_TESS_EVALUATION_SHADER }
+ { reuse GL_REFERENCED_BY_GEOMETRY_SHADER }
+ { reuse GL_REFERENCED_BY_FRAGMENT_SHADER }
+ { reuse GL_REFERENCED_BY_COMPUTE_SHADER }
+ { reuse GL_TOP_LEVEL_ARRAY_SIZE }
+ { reuse GL_TOP_LEVEL_ARRAY_STRIDE }
+ { reuse GL_LOCATION }
+ { reuse GL_LOCATION_INDEX }
+ { reuse GL_IS_PER_PATCH }
+ { Reuse tokens from ARB_robust_buffer_access_behavior (none) }
+ { Reuse tokens from ARB_shader_storage_buffer_object }
+ { reuse GL_SHADER_STORAGE_BUFFER }
+ { reuse GL_SHADER_STORAGE_BUFFER_BINDING }
+ { reuse GL_SHADER_STORAGE_BUFFER_START }
+ { reuse GL_SHADER_STORAGE_BUFFER_SIZE }
+ { reuse GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS }
+ { reuse GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS }
+ { reuse GL_MAX_SHADER_STORAGE_BLOCK_SIZE }
+ { reuse GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT }
+ { reuse GL_SHADER_STORAGE_BARRIER_BIT }
+ { reuse GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES }
+ { Reuse tokens from ARB_stencil_texturing }
+ { reuse GL_DEPTH_STENCIL_TEXTURE_MODE }
+ { Reuse tokens from ARB_texture_buffer_range }
+ { reuse GL_TEXTURE_BUFFER_OFFSET }
+ { reuse GL_TEXTURE_BUFFER_SIZE }
+ { reuse GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT }
+ { Reuse tokens from ARB_texture_query_levels (none) }
+ { Reuse tokens from ARB_texture_storage_multisample (none) }
+ { Reuse tokens from ARB_texture_view }
+ { reuse GL_TEXTURE_VIEW_MIN_LEVEL }
+ { reuse GL_TEXTURE_VIEW_NUM_LEVELS }
+ { reuse GL_TEXTURE_VIEW_MIN_LAYER }
+ { reuse GL_TEXTURE_VIEW_NUM_LAYERS }
+ { reuse GL_TEXTURE_IMMUTABLE_LEVELS }
+ { Reuse tokens from ARB_vertex_attrib_binding }
+ { reuse GL_VERTEX_ATTRIB_BINDING }
+ { reuse GL_VERTEX_ATTRIB_RELATIVE_OFFSET }
+ { reuse GL_VERTEX_BINDING_DIVISOR }
+ { reuse GL_VERTEX_BINDING_OFFSET }
+ { reuse GL_VERTEX_BINDING_STRIDE }
+ { reuse GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET }
+ { reuse GL_MAX_VERTEX_ATTRIB_BINDINGS }
+
+
+ // GL_3DFX_multisample
+ GL_MULTISAMPLE_3DFX = $86B2;
+ GL_SAMPLE_BUFFERS_3DFX = $86B3;
+ GL_SAMPLES_3DFX = $86B4;
+ GL_MULTISAMPLE_BIT_3DFX = $20000000;
+
+ // GL_3DFX_texture_compression_FXT1
+ GL_COMPRESSED_RGB_FXT1_3DFX = $86B0;
+ GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1;
+
+ // GL_APPLE_client_storage
+ GL_UNPACK_CLIENT_STORAGE_APPLE = $85B2;
+
+ // GL_APPLE_element_array
+ GL_ELEMENT_ARRAY_APPLE = $8A0C;
+ GL_ELEMENT_ARRAY_TYPE_APPLE = $8A0D;
+ GL_ELEMENT_ARRAY_POINTER_APPLE = $8A0E;
+
+ // GL_APPLE_fence
+ GL_DRAW_PIXELS_APPLE = $8A0A;
+ GL_FENCE_APPLE = $8A0B;
+
+ // GL_APPLE_specular_vector
+ GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE = $85B0;
+
+ // GL_APPLE_transform_hint
+ GL_TRANSFORM_HINT_APPLE = $85B1;
+
+ // GL_APPLE_vertex_array_object
+ GL_VERTEX_ARRAY_BINDING_APPLE = $85B5;
+
+ // GL_APPLE_vertex_array_range
+ GL_VERTEX_ARRAY_RANGE_APPLE = $851D;
+ GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = $851E;
+ GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = $851F;
+ GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = $8521;
+ GL_STORAGE_CLIENT_APPLE = $85B4;
+ GL_STORAGE_CACHED_APPLE = $85BE;
+ GL_STORAGE_SHARED_APPLE = $85BF;
+
+ // GL_APPLE_ycbcr_422
+ GL_YCBCR_422_APPLE = $85B9;
+ GL_UNSIGNED_SHORT_8_8_APPLE = $85BA;
+ GL_UNSIGNED_SHORT_8_8_REV_APPLE = $85BB;
+ GL_RGB_RAW_422_APPLE = $8A51;
+
+ // GL_APPLE_texture_range
+ GL_TEXTURE_RANGE_LENGTH_APPLE = $85B7;
+ GL_TEXTURE_RANGE_POINTER_APPLE = $85B8;
+ GL_TEXTURE_STORAGE_HINT_APPLE = $85BC;
+ GL_STORAGE_PRIVATE_APPLE = $85BD;
+ { reuse GL_STORAGE_CACHED_APPLE }
+ { reuse GL_STORAGE_SHARED_APPLE }
+
+ // GL_APPLE_float_pixels
+ GL_HALF_APPLE = $140B;
+ GL_RGBA_FLOAT32_APPLE = $8814;
+ GL_RGB_FLOAT32_APPLE = $8815;
+ GL_ALPHA_FLOAT32_APPLE = $8816;
+ GL_INTENSITY_FLOAT32_APPLE = $8817;
+ GL_LUMINANCE_FLOAT32_APPLE = $8818;
+ GL_LUMINANCE_ALPHA_FLOAT32_APPLE = $8819;
+ GL_RGBA_FLOAT16_APPLE = $881A;
+ GL_RGB_FLOAT16_APPLE = $881B;
+ GL_ALPHA_FLOAT16_APPLE = $881C;
+ GL_INTENSITY_FLOAT16_APPLE = $881D;
+ GL_LUMINANCE_FLOAT16_APPLE = $881E;
+ GL_LUMINANCE_ALPHA_FLOAT16_APPLE = $881F;
+ GL_COLOR_FLOAT_APPLE = $8A0F;
+
+ // GL_APPLE_vertex_program_evaluators
+ GL_VERTEX_ATTRIB_MAP1_APPLE = $8A00;
+ GL_VERTEX_ATTRIB_MAP2_APPLE = $8A01;
+ GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE = $8A02;
+ GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE = $8A03;
+ GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE = $8A04;
+ GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE = $8A05;
+ GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE = $8A06;
+ GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE = $8A07;
+ GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE = $8A08;
+ GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE = $8A09;
+
+ // GL_APPLE_aux_depth_stencil
+ GL_AUX_DEPTH_STENCIL_APPLE = $8A14;
+
+ // GL_APPLE_object_purgeable
+ GL_BUFFER_OBJECT_APPLE = $85B3;
+ GL_RELEASED_APPLE = $8A19;
+ GL_VOLATILE_APPLE = $8A1A;
+ GL_RETAINED_APPLE = $8A1B;
+ GL_UNDEFINED_APPLE = $8A1C;
+ GL_PURGEABLE_APPLE = $8A1D;
+
+ // GL_APPLE_row_bytes
+ GL_PACK_ROW_BYTES_APPLE = $8A15;
+ GL_UNPACK_ROW_BYTES_APPLE = $8A16;
+
+ // GL_APPLE_rgb_422
+ { reuse GL_UNSIGNED_SHORT_8_8_APPLE }
+ { reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE }
+
+ // GL_ARB_depth_texture
+ GL_DEPTH_COMPONENT16_ARB = $81A5;
+ GL_DEPTH_COMPONENT24_ARB = $81A6;
+ GL_DEPTH_COMPONENT32_ARB = $81A7;
+ GL_TEXTURE_DEPTH_SIZE_ARB = $884A;
+ GL_DEPTH_TEXTURE_MODE_ARB = $884B;
+
+ // GL_ARB_fragment_program
+ GL_FRAGMENT_PROGRAM_ARB = $8804;
+ GL_PROGRAM_ALU_INSTRUCTIONS_ARB = $8805;
+ GL_PROGRAM_TEX_INSTRUCTIONS_ARB = $8806;
+ GL_PROGRAM_TEX_INDIRECTIONS_ARB = $8807;
+ GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $8808;
+ GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $8809;
+ GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $880A;
+ GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = $880B;
+ GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = $880C;
+ GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = $880D;
+ GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $880E;
+ GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $880F;
+ GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $8810;
+ GL_MAX_TEXTURE_COORDS_ARB = $8871;
+ GL_MAX_TEXTURE_IMAGE_UNITS_ARB = $8872;
+
+ // GL_ARB_imaging
+ GL_CONSTANT_COLOR_ARB = $8001;
+ GL_ONE_MINUS_CONSTANT_COLOR = $8002;
+ GL_CONSTANT_ALPHA = $8003;
+ GL_ONE_MINUS_CONSTANT_ALPHA = $8004;
+ GL_BLEND_COLOR = $8005;
+ GL_FUNC_ADD = $8006;
+ GL_MIN = $8007;
+ GL_MAX = $8008;
+ GL_BLEND_EQUATION = $8009;
+ GL_FUNC_SUBTRACT = $800A;
+ GL_FUNC_REVERSE_SUBTRACT = $800B;
+{$ifdef DGL_DEPRECATED}
+ GL_CONVOLUTION_1D = $8010;
+ GL_CONVOLUTION_2D = $8011;
+ GL_SEPARABLE_2D = $8012;
+ GL_CONVOLUTION_BORDER_MODE = $8013;
+ GL_CONVOLUTION_FILTER_SCALE = $8014;
+ GL_CONVOLUTION_FILTER_BIAS = $8015;
+ GL_REDUCE = $8016;
+ GL_CONVOLUTION_FORMAT = $8017;
+ GL_CONVOLUTION_WIDTH = $8018;
+ GL_CONVOLUTION_HEIGHT = $8019;
+ GL_MAX_CONVOLUTION_WIDTH = $801A;
+ GL_MAX_CONVOLUTION_HEIGHT = $801B;
+ GL_POST_CONVOLUTION_RED_SCALE = $801C;
+ GL_POST_CONVOLUTION_GREEN_SCALE = $801D;
+ GL_POST_CONVOLUTION_BLUE_SCALE = $801E;
+ GL_POST_CONVOLUTION_ALPHA_SCALE = $801F;
+ GL_POST_CONVOLUTION_RED_BIAS = $8020;
+ GL_POST_CONVOLUTION_GREEN_BIAS = $8021;
+ GL_POST_CONVOLUTION_BLUE_BIAS = $8022;
+ GL_POST_CONVOLUTION_ALPHA_BIAS = $8023;
+ GL_HISTOGRAM = $8024;
+ GL_PROXY_HISTOGRAM = $8025;
+ GL_HISTOGRAM_WIDTH = $8026;
+ GL_HISTOGRAM_FORMAT = $8027;
+ GL_HISTOGRAM_RED_SIZE = $8028;
+ GL_HISTOGRAM_GREEN_SIZE = $8029;
+ GL_HISTOGRAM_BLUE_SIZE = $802A;
+ GL_HISTOGRAM_ALPHA_SIZE = $802B;
+ GL_HISTOGRAM_LUMINANCE_SIZE = $802C;
+ GL_HISTOGRAM_SINK = $802D;
+ GL_MINMAX = $802E;
+ GL_MINMAX_FORMAT = $802F;
+ GL_MINMAX_SINK = $8030;
+ GL_TABLE_TOO_LARGE = $8031;
+ GL_COLOR_MATRIX = $80B1;
+ GL_COLOR_MATRIX_STACK_DEPTH = $80B2;
+ GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3;
+ GL_POST_COLOR_MATRIX_RED_SCALE = $80B4;
+ GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5;
+ GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6;
+ GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7;
+ GL_POST_COLOR_MATRIX_RED_BIAS = $80B8;
+ GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9;
+ GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA;
+ GL_POST_COLOR_MATRIX_ALPHA_BIAS = $80BB;
+ GL_COLOR_TABLE = $80D0;
+ GL_POST_CONVOLUTION_COLOR_TABLE = $80D1;
+ GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2;
+ GL_PROXY_COLOR_TABLE = $80D3;
+ GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4;
+ GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5;
+ GL_COLOR_TABLE_SCALE = $80D6;
+ GL_COLOR_TABLE_BIAS = $80D7;
+ GL_COLOR_TABLE_FORMAT = $80D8;
+ GL_COLOR_TABLE_WIDTH = $80D9;
+ GL_COLOR_TABLE_RED_SIZE = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE = $80DF;
+ GL_CONSTANT_BORDER = $8151;
+ GL_REPLICATE_BORDER = $8153;
+ GL_CONVOLUTION_BORDER_COLOR = $8154;
+{$endif}
+
+ // GL_ARB_matrix_palette
+ GL_MATRIX_PALETTE_ARB = $8840;
+ GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = $8841;
+ GL_MAX_PALETTE_MATRICES_ARB = $8842;
+ GL_CURRENT_PALETTE_MATRIX_ARB = $8843;
+ GL_MATRIX_INDEX_ARRAY_ARB = $8844;
+ GL_CURRENT_MATRIX_INDEX_ARB = $8845;
+ GL_MATRIX_INDEX_ARRAY_SIZE_ARB = $8846;
+ GL_MATRIX_INDEX_ARRAY_TYPE_ARB = $8847;
+ GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = $8848;
+ GL_MATRIX_INDEX_ARRAY_POINTER_ARB = $8849;
+
+ // GL_ARB_multisample
+ GL_MULTISAMPLE_ARB = $809D;
+ GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F;
+ GL_SAMPLE_COVERAGE_ARB = $80A0;
+ GL_SAMPLE_BUFFERS_ARB = $80A8;
+ GL_SAMPLES_ARB = $80A9;
+ GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA;
+ GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB;
+ GL_MULTISAMPLE_BIT_ARB = $20000000;
+
+ // GL_ARB_multitexture
+ GL_TEXTURE0_ARB = $84C0;
+ GL_TEXTURE1_ARB = $84C1;
+ GL_TEXTURE2_ARB = $84C2;
+ GL_TEXTURE3_ARB = $84C3;
+ GL_TEXTURE4_ARB = $84C4;
+ GL_TEXTURE5_ARB = $84C5;
+ GL_TEXTURE6_ARB = $84C6;
+ GL_TEXTURE7_ARB = $84C7;
+ GL_TEXTURE8_ARB = $84C8;
+ GL_TEXTURE9_ARB = $84C9;
+ GL_TEXTURE10_ARB = $84CA;
+ GL_TEXTURE11_ARB = $84CB;
+ GL_TEXTURE12_ARB = $84CC;
+ GL_TEXTURE13_ARB = $84CD;
+ GL_TEXTURE14_ARB = $84CE;
+ GL_TEXTURE15_ARB = $84CF;
+ GL_TEXTURE16_ARB = $84D0;
+ GL_TEXTURE17_ARB = $84D1;
+ GL_TEXTURE18_ARB = $84D2;
+ GL_TEXTURE19_ARB = $84D3;
+ GL_TEXTURE20_ARB = $84D4;
+ GL_TEXTURE21_ARB = $84D5;
+ GL_TEXTURE22_ARB = $84D6;
+ GL_TEXTURE23_ARB = $84D7;
+ GL_TEXTURE24_ARB = $84D8;
+ GL_TEXTURE25_ARB = $84D9;
+ GL_TEXTURE26_ARB = $84DA;
+ GL_TEXTURE27_ARB = $84DB;
+ GL_TEXTURE28_ARB = $84DC;
+ GL_TEXTURE29_ARB = $84DD;
+ GL_TEXTURE30_ARB = $84DE;
+ GL_TEXTURE31_ARB = $84DF;
+ GL_ACTIVE_TEXTURE_ARB = $84E0;
+ GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1;
+ GL_MAX_TEXTURE_UNITS_ARB = $84E2;
+
+ // GL_ARB_point_parameters
+ GL_POINT_SIZE_MIN_ARB = $8126;
+ GL_POINT_SIZE_MAX_ARB = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE_ARB = $8128;
+ GL_POINT_DISTANCE_ATTENUATION_ARB = $8129;
+
+ // GL_ARB_shadow
+ GL_TEXTURE_COMPARE_MODE_ARB = $884C;
+ GL_TEXTURE_COMPARE_FUNC_ARB = $884D;
+ GL_COMPARE_R_TO_TEXTURE_ARB = $884E;
+
+ // GL_ARB_shadow_ambient
+ GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = $80BF;
+
+ // GL_ARB_sparse_buffer
+ GL_SPARSE_STORAGE_BIT_ARB = $0400;
+ GL_SPARSE_BUFFER_PAGE_SIZE_ARB = $82F8;
+
+ // GL_ARB_texture_border_clamp
+ GL_CLAMP_TO_BORDER_ARB = $812D;
+
+ // GL_ARB_texture_compression
+ GL_COMPRESSED_ALPHA_ARB = $84E9;
+ GL_COMPRESSED_LUMINANCE_ARB = $84EA;
+ GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB;
+ GL_COMPRESSED_INTENSITY_ARB = $84EC;
+ GL_COMPRESSED_RGB_ARB = $84ED;
+ GL_COMPRESSED_RGBA_ARB = $84EE;
+ GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF;
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0;
+ GL_TEXTURE_COMPRESSED_ARB = $86A1;
+ GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2;
+ GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3;
+
+ // GL_ARB_texture_cube_map
+ GL_NORMAL_MAP_ARB = $8511;
+ GL_REFLECTION_MAP_ARB = $8512;
+ GL_TEXTURE_CUBE_MAP_ARB = $8513;
+ GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A;
+ GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B;
+ GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C;
+
+ // GL_ARB_texture_env_combine
+ GL_COMBINE_ARB = $8570;
+ GL_COMBINE_RGB_ARB = $8571;
+ GL_COMBINE_ALPHA_ARB = $8572;
+ GL_SOURCE0_RGB_ARB = $8580;
+ GL_SOURCE1_RGB_ARB = $8581;
+ GL_SOURCE2_RGB_ARB = $8582;
+ GL_SOURCE0_ALPHA_ARB = $8588;
+ GL_SOURCE1_ALPHA_ARB = $8589;
+ GL_SOURCE2_ALPHA_ARB = $858A;
+ GL_OPERAND0_RGB_ARB = $8590;
+ GL_OPERAND1_RGB_ARB = $8591;
+ GL_OPERAND2_RGB_ARB = $8592;
+ GL_OPERAND0_ALPHA_ARB = $8598;
+ GL_OPERAND1_ALPHA_ARB = $8599;
+ GL_OPERAND2_ALPHA_ARB = $859A;
+ GL_RGB_SCALE_ARB = $8573;
+ GL_ADD_SIGNED_ARB = $8574;
+ GL_INTERPOLATE_ARB = $8575;
+ GL_SUBTRACT_ARB = $84E7;
+ GL_CONSTANT_ARB = $8576;
+ GL_PRIMARY_COLOR_ARB = $8577;
+ GL_PREVIOUS_ARB = $8578;
+
+ // GL_ARB_texture_env_dot3
+ GL_DOT3_RGB_ARB = $86AE;
+ GL_DOT3_RGBA_ARB = $86AF;
+
+ // GL_ARB_texture_filter_minmax
+ GL_TEXTURE_REDUCTION_MODE_ARB = $9366;
+ GL_WEIGHTED_AVERAGE_ARB = $9367;
+
+ // GL_ARB_texture_mirrored_repeat
+ GL_MIRRORED_REPEAT_ARB = $8370;
+
+ // GL_ARB_transpose_matrix
+ GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3;
+ GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4;
+ GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5;
+ GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6;
+
+ // GL_ARB_vertex_blend
+ GL_MAX_VERTEX_UNITS_ARB = $86A4;
+ GL_ACTIVE_VERTEX_UNITS_ARB = $86A5;
+ GL_WEIGHT_SUM_UNITY_ARB = $86A6;
+ GL_VERTEX_BLEND_ARB = $86A7;
+ GL_CURRENT_WEIGHT_ARB = $86A8;
+ GL_WEIGHT_ARRAY_TYPE_ARB = $86A9;
+ GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA;
+ GL_WEIGHT_ARRAY_SIZE_ARB = $86AB;
+ GL_WEIGHT_ARRAY_POINTER_ARB = $86AC;
+ GL_WEIGHT_ARRAY_ARB = $86AD;
+ GL_MODELVIEW0_ARB = $1700;
+ GL_MODELVIEW1_ARB = $850A;
+ GL_MODELVIEW2_ARB = $8722;
+ GL_MODELVIEW3_ARB = $8723;
+ GL_MODELVIEW4_ARB = $8724;
+ GL_MODELVIEW5_ARB = $8725;
+ GL_MODELVIEW6_ARB = $8726;
+ GL_MODELVIEW7_ARB = $8727;
+ GL_MODELVIEW8_ARB = $8728;
+ GL_MODELVIEW9_ARB = $8729;
+ GL_MODELVIEW10_ARB = $872A;
+ GL_MODELVIEW11_ARB = $872B;
+ GL_MODELVIEW12_ARB = $872C;
+ GL_MODELVIEW13_ARB = $872D;
+ GL_MODELVIEW14_ARB = $872E;
+ GL_MODELVIEW15_ARB = $872F;
+ GL_MODELVIEW16_ARB = $8730;
+ GL_MODELVIEW17_ARB = $8731;
+ GL_MODELVIEW18_ARB = $8732;
+ GL_MODELVIEW19_ARB = $8733;
+ GL_MODELVIEW20_ARB = $8734;
+ GL_MODELVIEW21_ARB = $8735;
+ GL_MODELVIEW22_ARB = $8736;
+ GL_MODELVIEW23_ARB = $8737;
+ GL_MODELVIEW24_ARB = $8738;
+ GL_MODELVIEW25_ARB = $8739;
+ GL_MODELVIEW26_ARB = $873A;
+ GL_MODELVIEW27_ARB = $873B;
+ GL_MODELVIEW28_ARB = $873C;
+ GL_MODELVIEW29_ARB = $873D;
+ GL_MODELVIEW30_ARB = $873E;
+ GL_MODELVIEW31_ARB = $873F;
+
+ // GL_ARB_vertex_buffer_object
+ GL_BUFFER_SIZE_ARB = $8764;
+ GL_BUFFER_USAGE_ARB = $8765;
+ GL_ARRAY_BUFFER_ARB = $8892;
+ GL_ELEMENT_ARRAY_BUFFER_ARB = $8893;
+ GL_ARRAY_BUFFER_BINDING_ARB = $8894;
+ GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = $8895;
+ GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = $8896;
+ GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = $8897;
+ GL_COLOR_ARRAY_BUFFER_BINDING_ARB = $8898;
+ GL_INDEX_ARRAY_BUFFER_BINDING_ARB = $8899;
+ GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = $889A;
+ GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = $889B;
+ GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = $889C;
+ GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = $889D;
+ GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = $889E;
+ GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = $889F;
+ GL_READ_ONLY_ARB = $88B8;
+ GL_WRITE_ONLY_ARB = $88B9;
+ GL_READ_WRITE_ARB = $88BA;
+ GL_BUFFER_ACCESS_ARB = $88BB;
+ GL_BUFFER_MAPPED_ARB = $88BC;
+ GL_BUFFER_MAP_POINTER_ARB = $88BD;
+ GL_STREAM_DRAW_ARB = $88E0;
+ GL_STREAM_READ_ARB = $88E1;
+ GL_STREAM_COPY_ARB = $88E2;
+ GL_STATIC_DRAW_ARB = $88E4;
+ GL_STATIC_READ_ARB = $88E5;
+ GL_STATIC_COPY_ARB = $88E6;
+ GL_DYNAMIC_DRAW_ARB = $88E8;
+ GL_DYNAMIC_READ_ARB = $88E9;
+ GL_DYNAMIC_COPY_ARB = $88EA;
+
+ // GL_ARB_vertex_program
+ GL_COLOR_SUM_ARB = $8458;
+ GL_VERTEX_PROGRAM_ARB = $8620;
+ GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = $8622;
+ GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = $8623;
+ GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = $8624;
+ GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = $8625;
+ GL_CURRENT_VERTEX_ATTRIB_ARB = $8626;
+ GL_PROGRAM_LENGTH_ARB = $8627;
+ GL_PROGRAM_STRING_ARB = $8628;
+ GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = $862E;
+ GL_MAX_PROGRAM_MATRICES_ARB = $862F;
+ GL_CURRENT_MATRIX_STACK_DEPTH_ARB = $8640;
+ GL_CURRENT_MATRIX_ARB = $8641;
+ GL_VERTEX_PROGRAM_POINT_SIZE_ARB = $8642;
+ GL_VERTEX_PROGRAM_TWO_SIDE_ARB = $8643;
+ GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = $8645;
+ GL_PROGRAM_ERROR_POSITION_ARB = $864B;
+ GL_PROGRAM_BINDING_ARB = $8677;
+ GL_MAX_VERTEX_ATTRIBS_ARB = $8869;
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = $886A;
+ GL_PROGRAM_ERROR_STRING_ARB = $8874;
+ GL_PROGRAM_FORMAT_ASCII_ARB = $8875;
+ GL_PROGRAM_FORMAT_ARB = $8876;
+ GL_PROGRAM_INSTRUCTIONS_ARB = $88A0;
+ GL_MAX_PROGRAM_INSTRUCTIONS_ARB = $88A1;
+ GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A2;
+ GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A3;
+ GL_PROGRAM_TEMPORARIES_ARB = $88A4;
+ GL_MAX_PROGRAM_TEMPORARIES_ARB = $88A5;
+ GL_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A6;
+ GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A7;
+ GL_PROGRAM_PARAMETERS_ARB = $88A8;
+ GL_MAX_PROGRAM_PARAMETERS_ARB = $88A9;
+ GL_PROGRAM_NATIVE_PARAMETERS_ARB = $88AA;
+ GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = $88AB;
+ GL_PROGRAM_ATTRIBS_ARB = $88AC;
+ GL_MAX_PROGRAM_ATTRIBS_ARB = $88AD;
+ GL_PROGRAM_NATIVE_ATTRIBS_ARB = $88AE;
+ GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = $88AF;
+ GL_PROGRAM_ADDRESS_REGISTERS_ARB = $88B0;
+ GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = $88B1;
+ GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B2;
+ GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B3;
+ GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = $88B4;
+ GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = $88B5;
+ GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = $88B6;
+ GL_TRANSPOSE_CURRENT_MATRIX_ARB = $88B7;
+ GL_MATRIX0_ARB = $88C0;
+ GL_MATRIX1_ARB = $88C1;
+ GL_MATRIX2_ARB = $88C2;
+ GL_MATRIX3_ARB = $88C3;
+ GL_MATRIX4_ARB = $88C4;
+ GL_MATRIX5_ARB = $88C5;
+ GL_MATRIX6_ARB = $88C6;
+ GL_MATRIX7_ARB = $88C7;
+ GL_MATRIX8_ARB = $88C8;
+ GL_MATRIX9_ARB = $88C9;
+ GL_MATRIX10_ARB = $88CA;
+ GL_MATRIX11_ARB = $88CB;
+ GL_MATRIX12_ARB = $88CC;
+ GL_MATRIX13_ARB = $88CD;
+ GL_MATRIX14_ARB = $88CE;
+ GL_MATRIX15_ARB = $88CF;
+ GL_MATRIX16_ARB = $88D0;
+ GL_MATRIX17_ARB = $88D1;
+ GL_MATRIX18_ARB = $88D2;
+ GL_MATRIX19_ARB = $88D3;
+ GL_MATRIX20_ARB = $88D4;
+ GL_MATRIX21_ARB = $88D5;
+ GL_MATRIX22_ARB = $88D6;
+ GL_MATRIX23_ARB = $88D7;
+ GL_MATRIX24_ARB = $88D8;
+ GL_MATRIX25_ARB = $88D9;
+ GL_MATRIX26_ARB = $88DA;
+ GL_MATRIX27_ARB = $88DB;
+ GL_MATRIX28_ARB = $88DC;
+ GL_MATRIX29_ARB = $88DD;
+ GL_MATRIX30_ARB = $88DE;
+ GL_MATRIX31_ARB = $88DF;
+
+ // GL_ARB_draw_buffers
+ GL_MAX_DRAW_BUFFERS_ARB = $8824;
+ GL_DRAW_BUFFER0_ARB = $8825;
+ GL_DRAW_BUFFER1_ARB = $8826;
+ GL_DRAW_BUFFER2_ARB = $8827;
+ GL_DRAW_BUFFER3_ARB = $8828;
+ GL_DRAW_BUFFER4_ARB = $8829;
+ GL_DRAW_BUFFER5_ARB = $882A;
+ GL_DRAW_BUFFER6_ARB = $882B;
+ GL_DRAW_BUFFER7_ARB = $882C;
+ GL_DRAW_BUFFER8_ARB = $882D;
+ GL_DRAW_BUFFER9_ARB = $882E;
+ GL_DRAW_BUFFER10_ARB = $882F;
+ GL_DRAW_BUFFER11_ARB = $8830;
+ GL_DRAW_BUFFER12_ARB = $8831;
+ GL_DRAW_BUFFER13_ARB = $8832;
+ GL_DRAW_BUFFER14_ARB = $8833;
+ GL_DRAW_BUFFER15_ARB = $8834;
+
+ // GL_ARB_texture_rectangle
+ GL_TEXTURE_RECTANGLE_ARB = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_ARB = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_ARB = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = $84F8;
+
+ // GL_ARB_color_buffer_float
+ GL_RGBA_FLOAT_MODE_ARB = $8820;
+ GL_CLAMP_VERTEX_COLOR_ARB = $891A;
+ GL_CLAMP_FRAGMENT_COLOR_ARB = $891B;
+ GL_CLAMP_READ_COLOR_ARB = $891C;
+ GL_FIXED_ONLY_ARB = $891D;
+ WGL_TYPE_RGBA_FLOAT_ARB = $21A0;
+ GLX_RGBA_FLOAT_TYPE = $20B9;
+ GLX_RGBA_FLOAT_BIT = $00000004;
+
+ // GL_ARB_compute_variable_group_size
+ GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB = $9344;
+ GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB = $90EB;
+ GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB = $9345;
+ GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB = $91BF;
+
+ // GL_ARB_half_float_pixel
+ GL_HALF_FLOAT_ARB = $140B;
+
+ // GL_ARB_texture_float
+ GL_TEXTURE_RED_TYPE_ARB = $8C10;
+ GL_TEXTURE_GREEN_TYPE_ARB = $8C11;
+ GL_TEXTURE_BLUE_TYPE_ARB = $8C12;
+ GL_TEXTURE_ALPHA_TYPE_ARB = $8C13;
+ GL_TEXTURE_LUMINANCE_TYPE_ARB = $8C14;
+ GL_TEXTURE_INTENSITY_TYPE_ARB = $8C15;
+ GL_TEXTURE_DEPTH_TYPE_ARB = $8C16;
+ GL_UNSIGNED_NORMALIZED_ARB = $8C17;
+ GL_RGBA32F_ARB = $8814;
+ GL_RGB32F_ARB = $8815;
+ GL_ALPHA32F_ARB = $8816;
+ GL_INTENSITY32F_ARB = $8817;
+ GL_LUMINANCE32F_ARB = $8818;
+ GL_LUMINANCE_ALPHA32F_ARB = $8819;
+ GL_RGBA16F_ARB = $881A;
+ GL_RGB16F_ARB = $881B;
+ GL_ALPHA16F_ARB = $881C;
+ GL_INTENSITY16F_ARB = $881D;
+ GL_LUMINANCE16F_ARB = $881E;
+ GL_LUMINANCE_ALPHA16F_ARB = $881F;
+
+ // GL_ARB_pixel_buffer_object
+ GL_PIXEL_PACK_BUFFER_ARB = $88EB;
+ GL_PIXEL_UNPACK_BUFFER_ARB = $88EC;
+ GL_PIXEL_PACK_BUFFER_BINDING_ARB = $88ED;
+ GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = $88EF;
+
+ // GL_ARB_depth_buffer_float
+ GL_DEPTH_COMPONENT32F = $8CAC;
+ GL_DEPTH32F_STENCIL8 = $8CAD;
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV = $8DAD;
+
+ // GL_ARB_framebuffer_object
+ GL_INVALID_FRAMEBUFFER_OPERATION = $0506;
+ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = $8210;
+ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = $8211;
+ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = $8212;
+ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = $8213;
+ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = $8214;
+ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = $8215;
+ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = $8216;
+ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = $8217;
+ GL_FRAMEBUFFER_DEFAULT = $8218;
+ GL_FRAMEBUFFER_UNDEFINED = $8219;
+ GL_DEPTH_STENCIL_ATTACHMENT = $821A;
+ GL_MAX_RENDERBUFFER_SIZE = $84E8;
+ GL_DEPTH_STENCIL = $84F9;
+ GL_UNSIGNED_INT_24_8 = $84FA;
+ GL_DEPTH24_STENCIL8 = $88F0;
+ GL_TEXTURE_STENCIL_SIZE = $88F1;
+ GL_TEXTURE_RED_TYPE = $8C10;
+ GL_TEXTURE_GREEN_TYPE = $8C11;
+ GL_TEXTURE_BLUE_TYPE = $8C12;
+ GL_TEXTURE_ALPHA_TYPE = $8C13;
+ GL_TEXTURE_DEPTH_TYPE = $8C16;
+ GL_UNSIGNED_NORMALIZED = $8C17;
+ GL_FRAMEBUFFER_BINDING = $8CA6;
+ GL_DRAW_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING;
+ GL_RENDERBUFFER_BINDING = $8CA7;
+ GL_READ_FRAMEBUFFER = $8CA8;
+ GL_DRAW_FRAMEBUFFER = $8CA9;
+ GL_READ_FRAMEBUFFER_BINDING = $8CAA;
+ GL_RENDERBUFFER_SAMPLES = $8CAB;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = $8CD0;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = $8CD1;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = $8CD2;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = $8CD3;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = $8CD4;
+ GL_FRAMEBUFFER_COMPLETE = $8CD5;
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = $8CD6;
+ GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = $8CD7;
+ GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = $8CDB;
+ GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = $8CDC;
+ GL_FRAMEBUFFER_UNSUPPORTED = $8CDD;
+ GL_MAX_COLOR_ATTACHMENTS = $8CDF;
+ GL_COLOR_ATTACHMENT0 = $8CE0;
+ GL_COLOR_ATTACHMENT1 = $8CE1;
+ GL_COLOR_ATTACHMENT2 = $8CE2;
+ GL_COLOR_ATTACHMENT3 = $8CE3;
+ GL_COLOR_ATTACHMENT4 = $8CE4;
+ GL_COLOR_ATTACHMENT5 = $8CE5;
+ GL_COLOR_ATTACHMENT6 = $8CE6;
+ GL_COLOR_ATTACHMENT7 = $8CE7;
+ GL_COLOR_ATTACHMENT8 = $8CE8;
+ GL_COLOR_ATTACHMENT9 = $8CE9;
+ GL_COLOR_ATTACHMENT10 = $8CEA;
+ GL_COLOR_ATTACHMENT11 = $8CEB;
+ GL_COLOR_ATTACHMENT12 = $8CEC;
+ GL_COLOR_ATTACHMENT13 = $8CED;
+ GL_COLOR_ATTACHMENT14 = $8CEE;
+ GL_COLOR_ATTACHMENT15 = $8CEF;
+ GL_DEPTH_ATTACHMENT = $8D00;
+ GL_STENCIL_ATTACHMENT = $8D20;
+ GL_FRAMEBUFFER = $8D40;
+ GL_RENDERBUFFER = $8D41;
+ GL_RENDERBUFFER_WIDTH = $8D42;
+ GL_RENDERBUFFER_HEIGHT = $8D43;
+ GL_RENDERBUFFER_INTERNAL_FORMAT = $8D44;
+ GL_STENCIL_INDEX1 = $8D46;
+ GL_STENCIL_INDEX4 = $8D47;
+ GL_STENCIL_INDEX8 = $8D48;
+ GL_STENCIL_INDEX16 = $8D49;
+ GL_RENDERBUFFER_RED_SIZE = $8D50;
+ GL_RENDERBUFFER_GREEN_SIZE = $8D51;
+ GL_RENDERBUFFER_BLUE_SIZE = $8D52;
+ GL_RENDERBUFFER_ALPHA_SIZE = $8D53;
+ GL_RENDERBUFFER_DEPTH_SIZE = $8D54;
+ GL_RENDERBUFFER_STENCIL_SIZE = $8D55;
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = $8D56;
+ GL_MAX_SAMPLES = $8D57;
+{$ifdef DGL_DEPRECATED}
+ GL_INDEX = $8222;
+ GL_TEXTURE_LUMINANCE_TYPE = $8C14;
+ GL_TEXTURE_INTENSITY_TYPE = $8C15;
+{$endif}
+
+ // GL_ARB_framebuffer_sRGB
+ GL_FRAMEBUFFER_SRGB = $8DB9;
+
+ // GL_ARB_geometry_shader4
+ GL_LINES_ADJACENCY_ARB = $000A;
+ GL_LINE_STRIP_ADJACENCY_ARB = $000B;
+ GL_TRIANGLES_ADJACENCY_ARB = $000C;
+ GL_TRIANGLE_STRIP_ADJACENCY_ARB = $000D;
+ GL_PROGRAM_POINT_SIZE_ARB = $8642;
+ GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB = $8C29;
+ GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB = $8DA7;
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB = $8DA8;
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB = $8DA9;
+ GL_GEOMETRY_SHADER_ARB = $8DD9;
+ GL_GEOMETRY_VERTICES_OUT_ARB = $8DDA;
+ GL_GEOMETRY_INPUT_TYPE_ARB = $8DDB;
+ GL_GEOMETRY_OUTPUT_TYPE_ARB = $8DDC;
+ GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB = $8DDD;
+ GL_MAX_VERTEX_VARYING_COMPONENTS_ARB = $8DDE;
+ GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB = $8DDF;
+ GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB = $8DE0;
+ GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB = $8DE1;
+ { reuse GL_MAX_VARYING_COMPONENTS }
+ { reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER }
+
+ // GL_ARB_gl_spirv
+ GL_SHADER_BINARY_FORMAT_SPIR_V_ARB = $9551;
+ GL_SPIR_V_BINARY_ARB = $9552;
+
+ // GL_ARB_half_float_vertex
+ GL_HALF_FLOAT = $140B;
+
+ // GL_ARB_instanced_arrays
+ GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB = $88FE;
+
+ // GL_ARB_map_buffer_range
+ GL_MAP_READ_BIT = $0001;
+ GL_MAP_WRITE_BIT = $0002;
+ GL_MAP_INVALIDATE_RANGE_BIT = $0004;
+ GL_MAP_INVALIDATE_BUFFER_BIT = $0008;
+ GL_MAP_FLUSH_EXPLICIT_BIT = $0010;
+ GL_MAP_UNSYNCHRONIZED_BIT = $0020;
+
+ // GL_ARB_texture_buffer_object
+ GL_TEXTURE_BUFFER_ARB = $8C2A;
+ GL_MAX_TEXTURE_BUFFER_SIZE_ARB = $8C2B;
+ GL_TEXTURE_BINDING_BUFFER_ARB = $8C2C;
+ GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB = $8C2D;
+ GL_TEXTURE_BUFFER_FORMAT_ARB = $8C2E;
+
+ // GL_ARB_texture_compression_rgtc
+ GL_COMPRESSED_RED_RGTC1 = $8DBB;
+ GL_COMPRESSED_SIGNED_RED_RGTC1 = $8DBC;
+ GL_COMPRESSED_RG_RGTC2 = $8DBD;
+ GL_COMPRESSED_SIGNED_RG_RGTC2 = $8DBE;
+
+ // GL_ARB_texture_rg
+ GL_RG = $8227;
+ GL_RG_INTEGER = $8228;
+ GL_R8 = $8229;
+ GL_R16 = $822A;
+ GL_RG8 = $822B;
+ GL_RG16 = $822C;
+ GL_R16F = $822D;
+ GL_R32F = $822E;
+ GL_RG16F = $822F;
+ GL_RG32F = $8230;
+ GL_R8I = $8231;
+ GL_R8UI = $8232;
+ GL_R16I = $8233;
+ GL_R16UI = $8234;
+ GL_R32I = $8235;
+ GL_R32UI = $8236;
+ GL_RG8I = $8237;
+ GL_RG8UI = $8238;
+ GL_RG16I = $8239;
+ GL_RG16UI = $823A;
+ GL_RG32I = $823B;
+ GL_RG32UI = $823C;
+
+ // GL_ARB_vertex_array_object
+ GL_VERTEX_ARRAY_BINDING = $85B5;
+
+ // GL_ARB_uniform_buffer_object
+ GL_UNIFORM_BUFFER = $8A11;
+ GL_UNIFORM_BUFFER_BINDING = $8A28;
+ GL_UNIFORM_BUFFER_START = $8A29;
+ GL_UNIFORM_BUFFER_SIZE = $8A2A;
+ GL_MAX_VERTEX_UNIFORM_BLOCKS = $8A2B;
+ GL_MAX_GEOMETRY_UNIFORM_BLOCKS = $8A2C;
+ GL_MAX_FRAGMENT_UNIFORM_BLOCKS = $8A2D;
+ GL_MAX_COMBINED_UNIFORM_BLOCKS = $8A2E;
+ GL_MAX_UNIFORM_BUFFER_BINDINGS = $8A2F;
+ GL_MAX_UNIFORM_BLOCK_SIZE = $8A30;
+ GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = $8A31;
+ GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = $8A32;
+ GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = $8A33;
+ GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = $8A34;
+ GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = $8A35;
+ GL_ACTIVE_UNIFORM_BLOCKS = $8A36;
+ GL_UNIFORM_TYPE = $8A37;
+ GL_UNIFORM_SIZE = $8A38;
+ GL_UNIFORM_NAME_LENGTH = $8A39;
+ GL_UNIFORM_BLOCK_INDEX = $8A3A;
+ GL_UNIFORM_OFFSET = $8A3B;
+ GL_UNIFORM_ARRAY_STRIDE = $8A3C;
+ GL_UNIFORM_MATRIX_STRIDE = $8A3D;
+ GL_UNIFORM_IS_ROW_MAJOR = $8A3E;
+ GL_UNIFORM_BLOCK_BINDING = $8A3F;
+ GL_UNIFORM_BLOCK_DATA_SIZE = $8A40;
+ GL_UNIFORM_BLOCK_NAME_LENGTH = $8A41;
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = $8A42;
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = $8A43;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = $8A44;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = $8A45;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = $8A46;
+ GL_INVALID_INDEX = $FFFFFFFF;
+
+ // GL_ARB_compatibility
+ { ARB_compatibility just defines tokens from core 3.0 }
+
+ // GL_ARB_copy_buffer
+ GL_COPY_READ_BUFFER_BINDING = $8F36;
+ GL_COPY_READ_BUFFER = GL_COPY_READ_BUFFER_BINDING;
+ GL_COPY_WRITE_BUFFER_BINDING = $8F37;
+ GL_COPY_WRITE_BUFFER = GL_COPY_WRITE_BUFFER_BINDING;
+
+ // GL_ARB_depth_clamp
+ GL_DEPTH_CLAMP = $864F;
+
+ // GL_ARB_provoking_vertex
+ GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = $8E4C;
+ GL_FIRST_VERTEX_CONVENTION = $8E4D;
+ GL_LAST_VERTEX_CONVENTION = $8E4E;
+ GL_PROVOKING_VERTEX = $8E4F;
+
+ // GL_ARB_seamless_cube_map
+ GL_TEXTURE_CUBE_MAP_SEAMLESS = $884F;
+
+ // GL_ARB_sync
+ GL_MAX_SERVER_WAIT_TIMEOUT = $9111;
+ GL_OBJECT_TYPE = $9112;
+ GL_SYNC_CONDITION = $9113;
+ GL_SYNC_STATUS = $9114;
+ GL_SYNC_FLAGS = $9115;
+ GL_SYNC_FENCE = $9116;
+ GL_SYNC_GPU_COMMANDS_COMPLETE = $9117;
+ GL_UNSIGNALED = $9118;
+ GL_SIGNALED = $9119;
+ GL_ALREADY_SIGNALED = $911A;
+ GL_TIMEOUT_EXPIRED = $911B;
+ GL_CONDITION_SATISFIED = $911C;
+ GL_WAIT_FAILED = $911D;
+ GL_SYNC_FLUSH_COMMANDS_BIT = $00000001;
+ GL_TIMEOUT_IGNORED = $FFFFFFFFFFFFFFFF;
+
+ // GL_ARB_texture_multisample
+ GL_SAMPLE_POSITION = $8E50;
+ GL_SAMPLE_MASK = $8E51;
+ GL_SAMPLE_MASK_VALUE = $8E52;
+ GL_MAX_SAMPLE_MASK_WORDS = $8E59;
+ GL_TEXTURE_2D_MULTISAMPLE = $9100;
+ GL_PROXY_TEXTURE_2D_MULTISAMPLE = $9101;
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY = $9102;
+ GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = $9103;
+ GL_TEXTURE_BINDING_2D_MULTISAMPLE = $9104;
+ GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = $9105;
+ GL_TEXTURE_SAMPLES = $9106;
+ GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = $9107;
+ GL_SAMPLER_2D_MULTISAMPLE = $9108;
+ GL_INT_SAMPLER_2D_MULTISAMPLE = $9109;
+ GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = $910A;
+ GL_SAMPLER_2D_MULTISAMPLE_ARRAY = $910B;
+ GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910C;
+ GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910D;
+ GL_MAX_COLOR_TEXTURE_SAMPLES = $910E;
+ GL_MAX_DEPTH_TEXTURE_SAMPLES = $910F;
+ GL_MAX_INTEGER_SAMPLES = $9110;
+
+ // GL_ARB_vertex_array_bgra
+ { reuse GL_BGRA }
+
+ // GL_ARB_sample_shading
+ GL_SAMPLE_SHADING_ARB = $8C36;
+ GL_MIN_SAMPLE_SHADING_VALUE_ARB = $8C37;
+
+ // GL_ARB_sample_locations
+ GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB = $933D;
+ GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB = $933E;
+ GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB = $933F;
+ GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB = $9340;
+ GL_SAMPLE_LOCATION_ARB = $8E50;
+ GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB = $9341;
+ GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB = $9342;
+ GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB = $9343;
+
+ // GL_ARB_texture_cube_map_array
+ GL_TEXTURE_CUBE_MAP_ARRAY_ARB = $9009;
+ GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB = $900A;
+ GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB = $900B;
+ GL_SAMPLER_CUBE_MAP_ARRAY_ARB = $900C;
+ GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB = $900D;
+ GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = $900E;
+ GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = $900F;
+
+ // GL_ARB_texture_gather
+ GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = $8E5E;
+ GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = $8E5F;
+
+ // GL_ARB_shading_language_include
+ GL_SHADER_INCLUDE_ARB = $8DAE;
+ GL_NAMED_STRING_LENGTH_ARB = $8DE9;
+ GL_NAMED_STRING_TYPE_ARB = $8DEA;
+
+ // GL_ARB_texture_compression_bptc
+ GL_COMPRESSED_RGBA_BPTC_UNORM_ARB = $8E8C;
+ GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB = $8E8D;
+ GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB = $8E8E;
+ GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB = $8E8F;
+
+ // GL_ARB_blend_func_extended
+ GL_SRC1_COLOR = $88F9;
+ { reuse GL_SRC1_ALPHA }
+ GL_ONE_MINUS_SRC1_COLOR = $88FA;
+ GL_ONE_MINUS_SRC1_ALPHA = $88FB;
+ GL_MAX_DUAL_SOURCE_DRAW_BUFFERS = $88FC;
+
+ // GL_ARB_occlusion_query2
+ GL_ANY_SAMPLES_PASSED = $8C2F;
+
+ // GL_ARB_parallel_shader_compile
+ GL_MAX_SHADER_COMPILER_THREADS_ARB = $91B0;
+ GL_COMPLETION_STATUS_ARB = $91B1;
+
+ // GL_ARB_sampler_objects
+ GL_SAMPLER_BINDING = $8919;
+
+ // GL_ARB_texture_rgb10_a2ui
+ GL_RGB10_A2UI = $906F;
+
+ // GL_ARB_texture_swizzle
+ GL_TEXTURE_SWIZZLE_R = $8E42;
+ GL_TEXTURE_SWIZZLE_G = $8E43;
+ GL_TEXTURE_SWIZZLE_B = $8E44;
+ GL_TEXTURE_SWIZZLE_A = $8E45;
+ GL_TEXTURE_SWIZZLE_RGBA = $8E46;
+
+ // GL_ARB_SPARSE_TEXTURE
+ GL_TEXTURE_SPARSE_ARB = $91A6;
+ GL_VIRTUAL_PAGE_SIZE_INDEX_ARB = $91A7;
+ GL_NUM_VIRTUAL_PAGE_SIZES_ARB = $91A8;
+ GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB = $91A9;
+ GL_NUM_SPARSE_LEVELS_ARB = $91AA;
+ GL_VIRTUAL_PAGE_SIZE_X_ARB = $9195;
+ GL_VIRTUAL_PAGE_SIZE_Y_ARB = $9196;
+ GL_VIRTUAL_PAGE_SIZE_Z_ARB = $9197;
+ GL_MAX_SPARSE_TEXTURE_SIZE_ARB = $9198;
+ GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB = $9199;
+ GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB = $919A;
+ GL_MIN_SPARSE_LEVEL_ARB = $919B;
+
+ // GL_ARB_timer_query
+ GL_TIME_ELAPSED = $88BF;
+ GL_TIMESTAMP = $8E28;
+
+ // GL_ARB_vertex_type_2_10_10_10_rev
+ { reuse GL_UNSIGNED_INT_2_10_10_10_REV }
+ GL_INT_2_10_10_10_REV = $8D9F;
+
+ // GL_ARB_draw_indirect
+ GL_DRAW_INDIRECT_BUFFER = $8F3F;
+ GL_DRAW_INDIRECT_BUFFER_BINDING = $8F43;
+
+ // GL_ARB_gpu_shader5
+ GL_GEOMETRY_SHADER_INVOCATIONS = $887F;
+ GL_MAX_GEOMETRY_SHADER_INVOCATIONS = $8E5A;
+ GL_MIN_FRAGMENT_INTERPOLATION_OFFSET = $8E5B;
+ GL_MAX_FRAGMENT_INTERPOLATION_OFFSET = $8E5C;
+ GL_FRAGMENT_INTERPOLATION_OFFSET_BITS = $8E5D;
+ { reuse GL_MAX_VERTEX_STREAMS }
+
+ // GL_ARB_gpu_shader_fp64
+ { reuse GL_DOUBLE }
+ GL_DOUBLE_VEC2 = $8FFC;
+ GL_DOUBLE_VEC3 = $8FFD;
+ GL_DOUBLE_VEC4 = $8FFE;
+ GL_DOUBLE_MAT2 = $8F46;
+ GL_DOUBLE_MAT3 = $8F47;
+ GL_DOUBLE_MAT4 = $8F48;
+ GL_DOUBLE_MAT2x3 = $8F49;
+ GL_DOUBLE_MAT2x4 = $8F4A;
+ GL_DOUBLE_MAT3x2 = $8F4B;
+ GL_DOUBLE_MAT3x4 = $8F4C;
+ GL_DOUBLE_MAT4x2 = $8F4D;
+ GL_DOUBLE_MAT4x3 = $8F4E;
+
+ // GL_ARB_gpu_shader_int64
+ GL_INT64_ARB = $140E;
+ GL_INT64_VEC2_ARB = $8FE9;
+ GL_INT64_VEC3_ARB = $8FEA;
+ GL_INT64_VEC4_ARB = $8FEB;
+ GL_UNSIGNED_INT64_VEC2_ARB = $8FF5;
+ GL_UNSIGNED_INT64_VEC3_ARB = $8FF6;
+ GL_UNSIGNED_INT64_VEC4_ARB = $8FF7;
+
+ // GL_ARB_shader_subroutine
+ GL_ACTIVE_SUBROUTINES = $8DE5;
+ GL_ACTIVE_SUBROUTINE_UNIFORMS = $8DE6;
+ GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = $8E47;
+ GL_ACTIVE_SUBROUTINE_MAX_LENGTH = $8E48;
+ GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = $8E49;
+ GL_MAX_SUBROUTINES = $8DE7;
+ GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = $8DE8;
+ GL_NUM_COMPATIBLE_SUBROUTINES = $8E4A;
+ GL_COMPATIBLE_SUBROUTINES = $8E4B;
+ { reuse GL_UNIFORM_SIZE }
+ { reuse GL_UNIFORM_NAME_LENGTH }
+
+ // GL_ARB_tessellation_shader
+ GL_PATCHES = $000E;
+ GL_PATCH_VERTICES = $8E72;
+ GL_PATCH_DEFAULT_INNER_LEVEL = $8E73;
+ GL_PATCH_DEFAULT_OUTER_LEVEL = $8E74;
+ GL_TESS_CONTROL_OUTPUT_VERTICES = $8E75;
+ GL_TESS_GEN_MODE = $8E76;
+ GL_TESS_GEN_SPACING = $8E77;
+ GL_TESS_GEN_VERTEX_ORDER = $8E78;
+ GL_TESS_GEN_POINT_MODE = $8E79;
+ { reuse GL_TRIANGLES }
+ { reuse GL_QUADS }
+ GL_ISOLINES = $8E7A;
+ { reuse GL_EQUAL }
+ GL_FRACTIONAL_ODD = $8E7B;
+ GL_FRACTIONAL_EVEN = $8E7C;
+ { reuse GL_CCW }
+ { reuse GL_CW }
+ GL_MAX_PATCH_VERTICES = $8E7D;
+ GL_MAX_TESS_GEN_LEVEL = $8E7E;
+ GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = $8E7F;
+ GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E80;
+ GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = $8E81;
+ GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = $8E82;
+ GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = $8E83;
+ GL_MAX_TESS_PATCH_COMPONENTS = $8E84;
+ GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = $8E85;
+ GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = $8E86;
+ GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = $8E89;
+ GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = $8E8A;
+ GL_MAX_TESS_CONTROL_INPUT_COMPONENTS = $886C;
+ GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = $886D;
+ GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = $8E1E;
+ GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E1F;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = $84F0;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = $84F1;
+ GL_TESS_EVALUATION_SHADER = $8E87;
+ GL_TESS_CONTROL_SHADER = $8E88;
+
+ // GL_ARB_texture_buffer_object_rgb32
+ { reuse GL_RGB32F }
+ { reuse GL_RGB32UI }
+ { reuse GL_RGB32I }
+
+ // GL_ARB_transform_feedback2
+ GL_TRANSFORM_FEEDBACK = $8E22;
+ GL_TRANSFORM_FEEDBACK_PAUSED = $8E23;
+ GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = GL_TRANSFORM_FEEDBACK_PAUSED;
+ GL_TRANSFORM_FEEDBACK_ACTIVE = $8E24;
+ GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = GL_TRANSFORM_FEEDBACK_ACTIVE;
+ GL_TRANSFORM_FEEDBACK_BINDING = $8E25;
+
+ // GL_ARB_transform_feedback_overflow_query
+ GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB = $82EC;
+ GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB = $82ED;
+
+ // GL_ARB_transform_feedback3
+ GL_MAX_TRANSFORM_FEEDBACK_BUFFERS = $8E70;
+ GL_MAX_VERTEX_STREAMS = $8E71;
+
+ // GL_ARB_ES2_compatibility
+ GL_FIXED = $140C;
+ GL_IMPLEMENTATION_COLOR_READ_TYPE = $8B9A;
+ GL_IMPLEMENTATION_COLOR_READ_FORMAT = $8B9B;
+ GL_LOW_FLOAT = $8DF0;
+ GL_MEDIUM_FLOAT = $8DF1;
+ GL_HIGH_FLOAT = $8DF2;
+ GL_LOW_INT = $8DF3;
+ GL_MEDIUM_INT = $8DF4;
+ GL_HIGH_INT = $8DF5;
+ GL_SHADER_COMPILER = $8DFA;
+ GL_NUM_SHADER_BINARY_FORMATS = $8DF9;
+ GL_MAX_VERTEX_UNIFORM_VECTORS = $8DFB;
+ GL_MAX_VARYING_VECTORS = $8DFC;
+ GL_MAX_FRAGMENT_UNIFORM_VECTORS = $8DFD;
+ GL_RGB565 = $8D62;
+
+ // GL_ARB_ES3_2_compatibility
+ GL_PRIMITIVE_BOUNDING_BOX_ARB = $092BE;
+ GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB = $09381;
+ GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB = $09382;
+
+ // GL_ARB_get_program_binary
+ GL_PROGRAM_BINARY_RETRIEVABLE_HINT = $8257;
+ GL_PROGRAM_BINARY_LENGTH = $8741;
+ GL_NUM_PROGRAM_BINARY_FORMATS = $87FE;
+ GL_PROGRAM_BINARY_FORMATS = $87FF;
+
+ // GL_ARB_separate_shader_objects
+ GL_VERTEX_SHADER_BIT = $00000001;
+ GL_FRAGMENT_SHADER_BIT = $00000002;
+ GL_GEOMETRY_SHADER_BIT = $00000004;
+ GL_TESS_CONTROL_SHADER_BIT = $00000008;
+ GL_TESS_EVALUATION_SHADER_BIT = $00000010;
+ GL_ALL_SHADER_BITS = $FFFFFFFF;
+ GL_PROGRAM_SEPARABLE = $8258;
+ GL_ACTIVE_PROGRAM = $8259;
+ GL_PROGRAM_PIPELINE_BINDING = $825A;
+
+ // GL_ARB_vertex_attrib_64bit
+ { reuse GL_RGB32I }
+ { reuse GL_DOUBLE_VEC2 }
+ { reuse GL_DOUBLE_VEC3 }
+ { reuse GL_DOUBLE_VEC4 }
+ { reuse GL_DOUBLE_MAT2 }
+ { reuse GL_DOUBLE_MAT3 }
+ { reuse GL_DOUBLE_MAT4 }
+ { reuse GL_DOUBLE_MAT2x3 }
+ { reuse GL_DOUBLE_MAT2x4 }
+ { reuse GL_DOUBLE_MAT3x2 }
+ { reuse GL_DOUBLE_MAT3x4 }
+ { reuse GL_DOUBLE_MAT4x2 }
+ { reuse GL_DOUBLE_MAT4x3 }
+
+ // GL_ARB_viewport_array
+ { reuse GL_SCISSOR_BOX }
+ { reuse GL_VIEWPORT }
+ { reuse GL_DEPTH_RANGE }
+ { reuse GL_SCISSOR_TEST }
+ GL_MAX_VIEWPORTS = $825B;
+ GL_VIEWPORT_SUBPIXEL_BITS = $825C;
+ GL_VIEWPORT_BOUNDS_RANGE = $825D;
+ GL_LAYER_PROVOKING_VERTEX = $825E;
+ GL_VIEWPORT_INDEX_PROVOKING_VERTEX = $825F;
+ GL_UNDEFINED_VERTEX = $8260;
+ { reuse GL_FIRST_VERTEX_CONVENTION }
+ { reuse GL_LAST_VERTEX_CONVENTION }
+ { reuse GL_PROVOKING_VERTEX }
+
+ // GL_ARB_cl_event
+ GL_SYNC_CL_EVENT_ARB = $8240;
+ GL_SYNC_CL_EVENT_COMPLETE_ARB = $8241;
+
+ // GL_ARB_debug_output
+ GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB = $8242;
+ GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB = $8243;
+ GL_DEBUG_CALLBACK_FUNCTION_ARB = $8244;
+ GL_DEBUG_CALLBACK_USER_PARAM_ARB = $8245;
+ GL_DEBUG_SOURCE_API_ARB = $8246;
+ GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB = $8247;
+ GL_DEBUG_SOURCE_SHADER_COMPILER_ARB = $8248;
+ GL_DEBUG_SOURCE_THIRD_PARTY_ARB = $8249;
+ GL_DEBUG_SOURCE_APPLICATION_ARB = $824A;
+ GL_DEBUG_SOURCE_OTHER_ARB = $824B;
+ GL_DEBUG_TYPE_ERROR_ARB = $824C;
+ GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB = $824D;
+ GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB = $824E;
+ GL_DEBUG_TYPE_PORTABILITY_ARB = $824F;
+ GL_DEBUG_TYPE_PERFORMANCE_ARB = $8250;
+ GL_DEBUG_TYPE_OTHER_ARB = $8251;
+ GL_MAX_DEBUG_MESSAGE_LENGTH_ARB = $9143;
+ GL_MAX_DEBUG_LOGGED_MESSAGES_ARB = $9144;
+ GL_DEBUG_LOGGED_MESSAGES_ARB = $9145;
+ GL_DEBUG_SEVERITY_HIGH_ARB = $9146;
+ GL_DEBUG_SEVERITY_MEDIUM_ARB = $9147;
+ GL_DEBUG_SEVERITY_LOW_ARB = $9148;
+
+ // GL_ARB_robustness
+ { reuse GL_NO_ERROR }
+ GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB = $00000004;
+ GL_LOSE_CONTEXT_ON_RESET_ARB = $8252;
+ GL_GUILTY_CONTEXT_RESET_ARB = $8253;
+ GL_INNOCENT_CONTEXT_RESET_ARB = $8254;
+ GL_UNKNOWN_CONTEXT_RESET_ARB = $8255;
+ GL_RESET_NOTIFICATION_STRATEGY_ARB = $8256;
+ GL_NO_RESET_NOTIFICATION_ARB = $8261;
+
+ // GL_ARB_compressed_texture_pixel_storage
+ GL_UNPACK_COMPRESSED_BLOCK_WIDTH = $09127;
+ GL_UNPACK_COMPRESSED_BLOCK_HEIGHT = $09128;
+ GL_UNPACK_COMPRESSED_BLOCK_DEPTH = $09129;
+ GL_UNPACK_COMPRESSED_BLOCK_SIZE = $0912A;
+ GL_PACK_COMPRESSED_BLOCK_WIDTH = $0912B;
+ GL_PACK_COMPRESSED_BLOCK_HEIGHT = $0912C;
+ GL_PACK_COMPRESSED_BLOCK_DEPTH = $0912D;
+ GL_PACK_COMPRESSED_BLOCK_SIZE = $0912E;
+
+ // GL_ARB_internalformat_query
+ GL_NUM_SAMPLE_COUNTS = $09380;
+
+ // GL_ARB_map_buffer_alignment
+ GL_MIN_MAP_BUFFER_ALIGNMENT = $090BC;
+
+ // GL_ARB_shader_atomic_counters
+ GL_ATOMIC_COUNTER_BUFFER = $92C0;
+ GL_ATOMIC_COUNTER_BUFFER_BINDING = $92C1;
+ GL_ATOMIC_COUNTER_BUFFER_START = $92C2;
+ GL_ATOMIC_COUNTER_BUFFER_SIZE = $92C3;
+ GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE = $92C4;
+ GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS = $92C5;
+ GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES = $92C6;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER = $92C7;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER = $92C8;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER = $92C9;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER = $92CA;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER = $92CB;
+ GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = $92CC;
+ GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS = $92CD;
+ GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS = $92CE;
+ GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS = $92CF;
+ GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = $92D0;
+ GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = $92D1;
+ GL_MAX_VERTEX_ATOMIC_COUNTERS = $92D2;
+ GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS = $92D3;
+ GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS = $92D4;
+ GL_MAX_GEOMETRY_ATOMIC_COUNTERS = $92D5;
+ GL_MAX_FRAGMENT_ATOMIC_COUNTERS = $92D6;
+ GL_MAX_COMBINED_ATOMIC_COUNTERS = $92D7;
+ GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = $92D8;
+ GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = $92DC;
+ GL_ACTIVE_ATOMIC_COUNTER_BUFFERS = $92D9;
+ GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX = $92DA;
+ GL_UNSIGNED_INT_ATOMIC_COUNTER = $92DB;
+
+ // GL_ARB_shader_image_load_store
+ GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = $00000001;
+ GL_ELEMENT_ARRAY_BARRIER_BIT = $00000002;
+ GL_UNIFORM_BARRIER_BIT = $00000004;
+ GL_TEXTURE_FETCH_BARRIER_BIT = $00000008;
+ GL_SHADER_IMAGE_ACCESS_BARRIER_BIT = $00000020;
+ GL_COMMAND_BARRIER_BIT = $00000040;
+ GL_PIXEL_BUFFER_BARRIER_BIT = $00000080;
+ GL_TEXTURE_UPDATE_BARRIER_BIT = $00000100;
+ GL_BUFFER_UPDATE_BARRIER_BIT = $00000200;
+ GL_FRAMEBUFFER_BARRIER_BIT = $00000400;
+ GL_TRANSFORM_FEEDBACK_BARRIER_BIT = $00000800;
+ GL_ATOMIC_COUNTER_BARRIER_BIT = $00001000;
+ GL_ALL_BARRIER_BITS = $FFFFFFFF;
+ GL_MAX_IMAGE_UNITS = $8F38;
+ GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS = $8F39;
+ GL_IMAGE_BINDING_NAME = $8F3A;
+ GL_IMAGE_BINDING_LEVEL = $8F3B;
+ GL_IMAGE_BINDING_LAYERED = $8F3C;
+ GL_IMAGE_BINDING_LAYER = $8F3D;
+ GL_IMAGE_BINDING_ACCESS = $8F3E;
+ GL_IMAGE_1D = $904C;
+ GL_IMAGE_2D = $904D;
+ GL_IMAGE_3D = $904E;
+ GL_IMAGE_2D_RECT = $904F;
+ GL_IMAGE_CUBE = $9050;
+ GL_IMAGE_BUFFER = $9051;
+ GL_IMAGE_1D_ARRAY = $9052;
+ GL_IMAGE_2D_ARRAY = $9053;
+ GL_IMAGE_CUBE_MAP_ARRAY = $9054;
+ GL_IMAGE_2D_MULTISAMPLE = $9055;
+ GL_IMAGE_2D_MULTISAMPLE_ARRAY = $9056;
+ GL_INT_IMAGE_1D = $9057;
+ GL_INT_IMAGE_2D = $9058;
+ GL_INT_IMAGE_3D = $9059;
+ GL_INT_IMAGE_2D_RECT = $905A;
+ GL_INT_IMAGE_CUBE = $905B;
+ GL_INT_IMAGE_BUFFER = $905C;
+ GL_INT_IMAGE_1D_ARRAY = $905D;
+ GL_INT_IMAGE_2D_ARRAY = $905E;
+ GL_INT_IMAGE_CUBE_MAP_ARRAY = $905F;
+ GL_INT_IMAGE_2D_MULTISAMPLE = $9060;
+ GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY = $9061;
+ GL_UNSIGNED_INT_IMAGE_1D = $9062;
+ GL_UNSIGNED_INT_IMAGE_2D = $9063;
+ GL_UNSIGNED_INT_IMAGE_3D = $9064;
+ GL_UNSIGNED_INT_IMAGE_2D_RECT = $9065;
+ GL_UNSIGNED_INT_IMAGE_CUBE = $9066;
+ GL_UNSIGNED_INT_IMAGE_BUFFER = $9067;
+ GL_UNSIGNED_INT_IMAGE_1D_ARRAY = $9068;
+ GL_UNSIGNED_INT_IMAGE_2D_ARRAY = $9069;
+ GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = $906A;
+ GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = $906B;
+ GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = $906C;
+ GL_MAX_IMAGE_SAMPLES = $906D;
+ GL_IMAGE_BINDING_FORMAT = $906E;
+ GL_IMAGE_FORMAT_COMPATIBILITY_TYPE = $90C7;
+ GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = $90C8;
+ GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = $90C9;
+ GL_MAX_VERTEX_IMAGE_UNIFORMS = $90CA;
+ GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS = $90CB;
+ GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS = $90CC;
+ GL_MAX_GEOMETRY_IMAGE_UNIFORMS = $90CD;
+ GL_MAX_FRAGMENT_IMAGE_UNIFORMS = $90CE;
+ GL_MAX_COMBINED_IMAGE_UNIFORMS = $90CF;
+
+ // GL_ARB_texture_storage
+ GL_TEXTURE_IMMUTABLE_FORMAT = $912F;
+
+ // 4.3
+ // GL_KHR_texture_compression_astc_hdr
+ GL_COMPRESSED_RGBA_ASTC_4x4_KHR = $93B0;
+ GL_COMPRESSED_RGBA_ASTC_5x4_KHR = $93B1;
+ GL_COMPRESSED_RGBA_ASTC_5x5_KHR = $93B2;
+ GL_COMPRESSED_RGBA_ASTC_6x5_KHR = $93B3;
+ GL_COMPRESSED_RGBA_ASTC_6x6_KHR = $93B4;
+ GL_COMPRESSED_RGBA_ASTC_8x5_KHR = $93B5;
+ GL_COMPRESSED_RGBA_ASTC_8x6_KHR = $93B6;
+ GL_COMPRESSED_RGBA_ASTC_8x8_KHR = $93B7;
+ GL_COMPRESSED_RGBA_ASTC_105_KHR = $93B8;
+ GL_COMPRESSED_RGBA_ASTC_106_KHR = $93B9;
+ GL_COMPRESSED_RGBA_ASTC_108_KHR = $93BA;
+ GL_COMPRESSED_RGBA_ASTC_110_KHR = $93BB;
+ GL_COMPRESSED_RGBA_ASTC_12x10_KHR = $93BC;
+ GL_COMPRESSED_RGBA_ASTC_12x12_KHR = $93BD;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = $93D0;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = $93D1;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = $93D2;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = $93D3;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = $93D4;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = $93D5;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = $93D6;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = $93D7;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = $93D8;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = $93D9;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = $93DA;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = $93DB;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = $93DC;
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = $93DD;
+ // (4.3) GL_KHR_debug
+ GL_DEBUG_OUTPUT_SYNCHRONOUS = $8242;
+ GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH = $8243;
+ GL_DEBUG_CALLBACK_FUNCTION = $8244;
+ GL_DEBUG_CALLBACK_USER_PARAM = $8245;
+ GL_DEBUG_SOURCE_API = $8246;
+ GL_DEBUG_SOURCE_WINDOW_SYSTEM = $8247;
+ GL_DEBUG_SOURCE_SHADER_COMPILER = $8248;
+ GL_DEBUG_SOURCE_THIRD_PARTY = $8249;
+ GL_DEBUG_SOURCE_APPLICATION = $824A;
+ GL_DEBUG_SOURCE_OTHER = $824B;
+ GL_DEBUG_TYPE_ERROR = $824C;
+ GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = $824D;
+ GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR = $824E;
+ GL_DEBUG_TYPE_PORTABILITY = $824F;
+ GL_DEBUG_TYPE_PERFORMANCE = $8250;
+ GL_DEBUG_TYPE_OTHER = $8251;
+ GL_DEBUG_TYPE_MARKER = $8268;
+ GL_DEBUG_TYPE_PUSH_GROUP = $8269;
+ GL_DEBUG_TYPE_POP_GROUP = $826A;
+ GL_DEBUG_SEVERITY_NOTIFICATION = $826B;
+ GL_MAX_DEBUG_GROUP_STACK_DEPTH = $826C;
+ GL_DEBUG_GROUP_STACK_DEPTH = $826D;
+ GL_BUFFER = $82E0;
+ GL_SHADER = $82E1;
+ GL_PROGRAM = $82E2;
+ GL_QUERY = $82E3;
+ GL_PROGRAM_PIPELINE = $82E4;
+ GL_SAMPLER = $82E6;
+ GL_DISPLAY_LIST = $82E7;
+ GL_MAX_LABEL_LENGTH = $82E8;
+ GL_MAX_DEBUG_MESSAGE_LENGTH = $9143;
+ GL_MAX_DEBUG_LOGGED_MESSAGES = $9144;
+ GL_DEBUG_LOGGED_MESSAGES = $9145;
+ GL_DEBUG_SEVERITY_HIGH = $9146;
+ GL_DEBUG_SEVERITY_MEDIUM = $9147;
+ GL_DEBUG_SEVERITY_LOW = $9148;
+ GL_DEBUG_OUTPUT = $92E0;
+ GL_CONTEXT_FLAG_DEBUG_BIT = $00000002;
+ GL_COMPUTE_SHADER = $91B9;
+ GL_MAX_COMPUTE_UNIFORM_BLOCKS = $91BB;
+ GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS = $91BC;
+ GL_MAX_COMPUTE_IMAGE_UNIFORMS = $91BD;
+ GL_MAX_COMPUTE_SHARED_MEMORY_SIZE = $8262;
+ GL_MAX_COMPUTE_UNIFORM_COMPONENTS = $8263;
+ GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = $8264;
+ GL_MAX_COMPUTE_ATOMIC_COUNTERS = $8265;
+ GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = $8266;
+ GL_MAX_COMPUTE_LOCAL_INVOCATIONS = $90EB;
+ GL_MAX_COMPUTE_WORK_GROUP_COUNT = $91BE;
+ GL_MAX_COMPUTE_WORK_GROUP_SIZE = $91BF;
+ GL_COMPUTE_LOCAL_WORK_SIZE = $8267;
+ GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = $90EC;
+ GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER = $90ED;
+ GL_DISPATCH_INDIRECT_BUFFER = $90EE;
+ GL_DISPATCH_INDIRECT_BUFFER_BINDING = $90EF;
+ GL_COMPUTE_SHADER_BIT = $00000020;
+ GL_COMPRESSED_RGB8_ETC2 = $9274;
+ GL_COMPRESSED_SRGB8_ETC2 = $9275;
+ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = $9276;
+ GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = $9277;
+ GL_COMPRESSED_RGBA8_ETC2_EAC = $9278;
+ GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = $9279;
+ GL_COMPRESSED_R11_EAC = $9270;
+ GL_COMPRESSED_SIGNED_R11_EAC = $9271;
+ GL_COMPRESSED_RG11_EAC = $9272;
+ GL_COMPRESSED_SIGNED_RG11_EAC = $9273;
+ GL_PRIMITIVE_RESTART_FIXED_INDEX = $8D69;
+ GL_ANY_SAMPLES_PASSED_CONSERVATIVE = $8D6A;
+ GL_MAX_ELEMENT_INDEX = $8D6B;
+ GL_MAX_UNIFORM_LOCATIONS = $826E;
+ GL_FRAMEBUFFER_DEFAULT_WIDTH = $9310;
+ GL_FRAMEBUFFER_DEFAULT_HEIGHT = $9311;
+ GL_FRAMEBUFFER_DEFAULT_LAYERS = $9312;
+ GL_FRAMEBUFFER_DEFAULT_SAMPLES = $9313;
+ GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS = $9314;
+ GL_MAX_FRAMEBUFFER_WIDTH = $9315;
+ GL_MAX_FRAMEBUFFER_HEIGHT = $9316;
+ GL_MAX_FRAMEBUFFER_LAYERS = $9317;
+ GL_MAX_FRAMEBUFFER_SAMPLES = $9318;
+ GL_INTERNALFORMAT_SUPPORTED = $826F;
+ GL_INTERNALFORMAT_PREFERRED = $8270;
+ GL_INTERNALFORMAT_RED_SIZE = $8271;
+ GL_INTERNALFORMAT_GREEN_SIZE = $8272;
+ GL_INTERNALFORMAT_BLUE_SIZE = $8273;
+ GL_INTERNALFORMAT_ALPHA_SIZE = $8274;
+ GL_INTERNALFORMAT_DEPTH_SIZE = $8275;
+ GL_INTERNALFORMAT_STENCIL_SIZE = $8276;
+ GL_INTERNALFORMAT_SHARED_SIZE = $8277;
+ GL_INTERNALFORMAT_RED_TYPE = $8278;
+ GL_INTERNALFORMAT_GREEN_TYPE = $8279;
+ GL_INTERNALFORMAT_BLUE_TYPE = $827A;
+ GL_INTERNALFORMAT_ALPHA_TYPE = $827B;
+ GL_INTERNALFORMAT_DEPTH_TYPE = $827C;
+ GL_INTERNALFORMAT_STENCIL_TYPE = $827D;
+ GL_MAX_WIDTH = $827E;
+ GL_MAX_HEIGHT = $827F;
+ GL_MAX_DEPTH = $8280;
+ GL_MAX_LAYERS = $8281;
+ GL_MAX_COMBINED_DIMENSIONS = $8282;
+ GL_COLOR_COMPONENTS = $8283;
+ GL_DEPTH_COMPONENTS = $8284;
+ GL_STENCIL_COMPONENTS = $8285;
+ GL_COLOR_RENDERABLE = $8286;
+ GL_DEPTH_RENDERABLE = $8287;
+ GL_STENCIL_RENDERABLE = $8288;
+ GL_FRAMEBUFFER_RENDERABLE = $8289;
+ GL_FRAMEBUFFER_RENDERABLE_LAYERED = $828A;
+ GL_FRAMEBUFFER_BLEND = $828B;
+ GL_READ_PIXELS = $828C;
+ GL_READ_PIXELS_FORMAT = $828D;
+ GL_READ_PIXELS_TYPE = $828E;
+ GL_TEXTURE_IMAGE_FORMAT = $828F;
+ GL_TEXTURE_IMAGE_TYPE = $8290;
+ GL_GET_TEXTURE_IMAGE_FORMAT = $8291;
+ GL_GET_TEXTURE_IMAGE_TYPE = $8292;
+ GL_MIPMAP = $8293;
+ GL_MANUAL_GENERATE_MIPMAP = $8294;
+ GL_AUTO_GENERATE_MIPMAP = $8295;
+ GL_COLOR_ENCODING = $8296;
+ GL_SRGB_READ = $8297;
+ GL_SRGB_WRITE = $8298;
+ GL_SRGB_DECODE_ARB = $8299;
+ GL_FILTER = $829A;
+ GL_VERTEX_TEXTURE = $829B;
+ GL_TESS_CONTROL_TEXTURE = $829C;
+ GL_TESS_EVALUATION_TEXTURE = $829D;
+ GL_GEOMETRY_TEXTURE = $829E;
+ GL_FRAGMENT_TEXTURE = $829F;
+ GL_COMPUTE_TEXTURE = $82A0;
+ GL_TEXTURE_SHADOW = $82A1;
+ GL_TEXTURE_GATHER = $82A2;
+ GL_TEXTURE_GATHER_SHADOW = $82A3;
+ GL_SHADER_IMAGE_LOAD = $82A4;
+ GL_SHADER_IMAGE_STORE = $82A5;
+ GL_SHADER_IMAGE_ATOMIC = $82A6;
+ GL_IMAGE_TEXEL_SIZE = $82A7;
+ GL_IMAGE_COMPATIBILITY_CLASS = $82A8;
+ GL_IMAGE_PIXEL_FORMAT = $82A9;
+ GL_IMAGE_PIXEL_TYPE = $82AA;
+ GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST = $82AC;
+ GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST = $82AD;
+ GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE = $82AE;
+ GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE = $82AF;
+ GL_TEXTURE_COMPRESSED_BLOCK_WIDTH = $82B1;
+ GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT = $82B2;
+ GL_TEXTURE_COMPRESSED_BLOCK_SIZE = $82B3;
+ GL_CLEAR_BUFFER = $82B4;
+ GL_TEXTURE_VIEW = $82B5;
+ GL_VIEW_COMPATIBILITY_CLASS = $82B6;
+ GL_FULL_SUPPORT = $82B7;
+ GL_CAVEAT_SUPPORT = $82B8;
+ GL_IMAGE_CLASS_4_X_32 = $82B9;
+ GL_IMAGE_CLASS_2_X_32 = $82BA;
+ GL_IMAGE_CLASS_1_X_32 = $82BB;
+ GL_IMAGE_CLASS_4_X_16 = $82BC;
+ GL_IMAGE_CLASS_2_X_16 = $82BD;
+ GL_IMAGE_CLASS_1_X_16 = $82BE;
+ GL_IMAGE_CLASS_4_X_8 = $82BF;
+ GL_IMAGE_CLASS_2_X_8 = $82C0;
+ GL_IMAGE_CLASS_1_X_8 = $82C1;
+ GL_IMAGE_CLASS_11_11_10 = $82C2;
+ GL_IMAGE_CLASS_10_10_10_2 = $82C3;
+ GL_VIEW_CLASS_128_BITS = $82C4;
+ GL_VIEW_CLASS_96_BITS = $82C5;
+ GL_VIEW_CLASS_64_BITS = $82C6;
+ GL_VIEW_CLASS_48_BITS = $82C7;
+ GL_VIEW_CLASS_32_BITS = $82C8;
+ GL_VIEW_CLASS_24_BITS = $82C9;
+ GL_VIEW_CLASS_16_BITS = $82CA;
+ GL_VIEW_CLASS_8_BITS = $82CB;
+ GL_VIEW_CLASS_S3TC_DXT1_RGB = $82CC;
+ GL_VIEW_CLASS_S3TC_DXT1_RGBA = $82CD;
+ GL_VIEW_CLASS_S3TC_DXT3_RGBA = $82CE;
+ GL_VIEW_CLASS_S3TC_DXT5_RGBA = $82CF;
+ GL_VIEW_CLASS_RGTC1_RED = $82D0;
+ GL_VIEW_CLASS_RGTC2_RG = $82D1;
+ GL_VIEW_CLASS_BPTC_UNORM = $82D2;
+ GL_VIEW_CLASS_BPTC_FLOAT = $82D3;
+ GL_UNIFORM = $92E1;
+ GL_UNIFORM_BLOCK = $92E2;
+ GL_PROGRAM_INPUT = $92E3;
+ GL_PROGRAM_OUTPUT = $92E4;
+ GL_BUFFER_VARIABLE = $92E5;
+ GL_SHADER_STORAGE_BLOCK = $92E6;
+ GL_VERTEX_SUBROUTINE = $92E8;
+ GL_TESS_CONTROL_SUBROUTINE = $92E9;
+ GL_TESS_EVALUATION_SUBROUTINE = $92EA;
+ GL_GEOMETRY_SUBROUTINE = $92EB;
+ GL_FRAGMENT_SUBROUTINE = $92EC;
+ GL_COMPUTE_SUBROUTINE = $92ED;
+ GL_VERTEX_SUBROUTINE_UNIFORM = $92EE;
+ GL_TESS_CONTROL_SUBROUTINE_UNIFORM = $92EF;
+ GL_TESS_EVALUATION_SUBROUTINE_UNIFORM = $92F0;
+ GL_GEOMETRY_SUBROUTINE_UNIFORM = $92F1;
+ GL_FRAGMENT_SUBROUTINE_UNIFORM = $92F2;
+ GL_COMPUTE_SUBROUTINE_UNIFORM = $92F3;
+ GL_TRANSFORM_FEEDBACK_VARYING = $92F4;
+ GL_ACTIVE_RESOURCES = $92F5;
+ GL_MAX_NAME_LENGTH = $92F6;
+ GL_MAX_NUM_ACTIVE_VARIABLES = $92F7;
+ GL_MAX_NUM_COMPATIBLE_SUBROUTINES = $92F8;
+ GL_NAME_LENGTH = $92F9;
+ GL_TYPE = $92FA;
+ GL_ARRAY_SIZE = $92FB;
+ GL_OFFSET = $92FC;
+ GL_BLOCK_INDEX = $92FD;
+ GL_ARRAY_STRIDE = $92FE;
+ GL_MATRIX_STRIDE = $92FF;
+ GL_IS_ROW_MAJOR = $9300;
+ GL_ATOMIC_COUNTER_BUFFER_INDEX = $9301;
+ GL_BUFFER_BINDING = $9302;
+ GL_BUFFER_DATA_SIZE = $9303;
+ GL_NUM_ACTIVE_VARIABLES = $9304;
+ GL_ACTIVE_VARIABLES = $9305;
+ GL_REFERENCED_BY_VERTEX_SHADER = $9306;
+ GL_REFERENCED_BY_TESS_CONTROL_SHADER = $9307;
+ GL_REFERENCED_BY_TESS_EVALUATION_SHADER = $9308;
+ GL_REFERENCED_BY_GEOMETRY_SHADER = $9309;
+ GL_REFERENCED_BY_FRAGMENT_SHADER = $930A;
+ GL_REFERENCED_BY_COMPUTE_SHADER = $930B;
+ GL_TOP_LEVEL_ARRAY_SIZE = $930C;
+ GL_TOP_LEVEL_ARRAY_STRIDE = $930D;
+ GL_LOCATION = $930E;
+ GL_LOCATION_INDEX = $930F;
+ GL_IS_PER_PATCH = $92E7;
+ GL_SHADER_STORAGE_BUFFER = $90D2;
+ GL_SHADER_STORAGE_BUFFER_BINDING = $90D3;
+ GL_SHADER_STORAGE_BUFFER_START = $90D4;
+ GL_SHADER_STORAGE_BUFFER_SIZE = $90D5;
+ GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = $90D6;
+ GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS = $90D7;
+ GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS = $90D8;
+ GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS = $90D9;
+ GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = $90DA;
+ GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = $90DB;
+ GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = $90DC;
+ GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = $90DD;
+ GL_MAX_SHADER_STORAGE_BLOCK_SIZE = $90DE;
+ GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = $90DF;
+ GL_SHADER_STORAGE_BARRIER_BIT = $2000;
+ GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES = GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS;
+ GL_DEPTH_STENCIL_TEXTURE_MODE = $90EA;
+
+ GL_TEXTURE_BUFFER_OFFSET = $919D;
+ GL_TEXTURE_BUFFER_SIZE = $919E;
+ GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT = $919F;
+ GL_TEXTURE_VIEW_MIN_LEVEL = $82DB;
+ GL_TEXTURE_VIEW_NUM_LEVELS = $82DC;
+ GL_TEXTURE_VIEW_MIN_LAYER = $82DD;
+ GL_TEXTURE_VIEW_NUM_LAYERS = $82DE;
+ GL_TEXTURE_IMMUTABLE_LEVELS = $82DF;
+ GL_VERTEX_ATTRIB_BINDING = $82D4;
+ GL_VERTEX_ATTRIB_RELATIVE_OFFSET = $82D5;
+ GL_VERTEX_BINDING_DIVISOR = $82D6;
+ GL_VERTEX_BINDING_OFFSET = $82D7;
+ GL_VERTEX_BINDING_STRIDE = $82D8;
+ GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET = $82D9;
+ GL_MAX_VERTEX_ATTRIB_BINDINGS = $82DA;
+
+ // GL 4.4
+ GL_MAX_VERTEX_ATTRIB_STRIDE = $82E5;
+ GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED = $8221;
+ GL_TEXTURE_BUFFER_BINDING = $8C2A;
+ GL_MAP_PERSISTENT_BIT = $0040;
+ GL_MAP_COHERENT_BIT = $0080;
+ GL_DYNAMIC_STORAGE_BIT = $0100;
+ GL_CLIENT_STORAGE_BIT = $0200;
+ GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT = $00004000;
+ GL_BUFFER_IMMUTABLE_STORAGE = $821F;
+ GL_BUFFER_STORAGE_FLAGS = $8220;
+ GL_CLEAR_TEXTURE = $9365;
+ GL_LOCATION_COMPONENT = $934A;
+ GL_TRANSFORM_FEEDBACK_BUFFER_INDEX = $934B;
+ GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE = $934C;
+ GL_QUERY_BUFFER = $9192;
+ GL_QUERY_BUFFER_BARRIER_BIT = $00008000;
+ GL_QUERY_BUFFER_BINDING = $9193;
+ GL_QUERY_RESULT_NO_WAIT = $9194;
+ GL_MIRROR_CLAMP_TO_EDGE = $8743;
+
+ // GL 4.5
+ GL_CONTEXT_LOST = $0507;
+ GL_NEGATIVE_ONE_TO_ONE = $935E;
+ GL_ZERO_TO_ONE = $935F;
+ GL_CLIP_ORIGIN = $935C;
+ GL_CLIP_DEPTH_MODE = $935D;
+ GL_QUERY_WAIT_INVERTED = $8E17;
+ GL_QUERY_NO_WAIT_INVERTED = $8E18;
+ GL_QUERY_BY_REGION_WAIT_INVERTED = $8E19;
+ GL_QUERY_BY_REGION_NO_WAIT_INVERTED = $8E1A;
+ GL_MAX_CULL_DISTANCES = $82F9;
+ GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES = $82FA;
+ GL_TEXTURE_TARGET = $1006;
+ GL_QUERY_TARGET = $82EA;
+ GL_TEXTURE_BINDING = $82EB;
+ GL_GUILTY_CONTEXT_RESET = $8253;
+ GL_INNOCENT_CONTEXT_RESET = $8254;
+ GL_UNKNOWN_CONTEXT_RESET = $8255;
+ GL_RESET_NOTIFICATION_STRATEGY = $8256;
+ GL_LOSE_CONTEXT_ON_RESET = $8252;
+ GL_NO_RESET_NOTIFICATION = $8261;
+ GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT = $00000004;
+ GL_CONTEXT_RELEASE_BEHAVIOR = $82FB;
+ GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = $82FC;
+
+ // 4.6
+ GL_SHADER_BINARY_FORMAT_SPIR_V = $9551;
+ GL_SPIR_V_BINARY = $9552;
+ GL_PARAMETER_BUFFER = $80EE;
+ GL_PARAMETER_BUFFER_BINDING = $80EF;
+ GL_CONTEXT_FLAG_NO_ERROR_BIT = $00000008;
+ GL_VERTICES_SUBMITTED = $82EE;
+ GL_PRIMITIVES_SUBMITTED = $82EF;
+ GL_VERTEX_SHADER_INVOCATIONS = $82F0;
+ GL_TESS_CONTROL_SHADER_PATCHES = $82F1;
+ GL_TESS_EVALUATION_SHADER_INVOCATIONS = $82F2;
+ GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED = $82F3;
+ GL_FRAGMENT_SHADER_INVOCATIONS = $82F4;
+ GL_COMPUTE_SHADER_INVOCATIONS = $82F5;
+ GL_CLIPPING_INPUT_PRIMITIVES = $82F6;
+ GL_CLIPPING_OUTPUT_PRIMITIVES = $82F7;
+ GL_POLYGON_OFFSET_CLAMP = $8E1B;
+ GL_SPIR_V_EXTENSIONS = $9553;
+ GL_NUM_SPIR_V_EXTENSIONS = $9554;
+ GL_TEXTURE_MAX_ANISOTROPY = $84FE;
+ GL_MAX_TEXTURE_MAX_ANISOTROPY = $84FF;
+ GL_TRANSFORM_FEEDBACK_OVERFLOW = $82EC;
+ GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW = $82ED;
+
+ // GL_ATI_draw_buffers
+ GL_MAX_DRAW_BUFFERS_ATI = $8824;
+ GL_DRAW_BUFFER0_ATI = $8825;
+ GL_DRAW_BUFFER1_ATI = $8826;
+ GL_DRAW_BUFFER2_ATI = $8827;
+ GL_DRAW_BUFFER3_ATI = $8828;
+ GL_DRAW_BUFFER4_ATI = $8829;
+ GL_DRAW_BUFFER5_ATI = $882A;
+ GL_DRAW_BUFFER6_ATI = $882B;
+ GL_DRAW_BUFFER7_ATI = $882C;
+ GL_DRAW_BUFFER8_ATI = $882D;
+ GL_DRAW_BUFFER9_ATI = $882E;
+ GL_DRAW_BUFFER10_ATI = $882F;
+ GL_DRAW_BUFFER11_ATI = $8830;
+ GL_DRAW_BUFFER12_ATI = $8831;
+ GL_DRAW_BUFFER13_ATI = $8832;
+ GL_DRAW_BUFFER14_ATI = $8833;
+ GL_DRAW_BUFFER15_ATI = $8834;
+
+ // GL_ATI_element_array
+ GL_ELEMENT_ARRAY_ATI = $8768;
+ GL_ELEMENT_ARRAY_TYPE_ATI = $8769;
+ GL_ELEMENT_ARRAY_POINTER_ATI = $876A;
+
+ // GL_ATI_envmap_bumpmap
+ GL_BUMP_ROT_MATRIX_ATI = $8775;
+ GL_BUMP_ROT_MATRIX_SIZE_ATI = $8776;
+ GL_BUMP_NUM_TEX_UNITS_ATI = $8777;
+ GL_BUMP_TEX_UNITS_ATI = $8778;
+ GL_DUDV_ATI = $8779;
+ GL_DU8DV8_ATI = $877A;
+ GL_BUMP_ENVMAP_ATI = $877B;
+ GL_BUMP_TARGET_ATI = $877C;
+
+ // GL_ATI_fragment_shader
+ GL_FRAGMENT_SHADER_ATI = $8920;
+ GL_REG_0_ATI = $8921;
+ GL_REG_1_ATI = $8922;
+ GL_REG_2_ATI = $8923;
+ GL_REG_3_ATI = $8924;
+ GL_REG_4_ATI = $8925;
+ GL_REG_5_ATI = $8926;
+ GL_REG_6_ATI = $8927;
+ GL_REG_7_ATI = $8928;
+ GL_REG_8_ATI = $8929;
+ GL_REG_9_ATI = $892A;
+ GL_REG_10_ATI = $892B;
+ GL_REG_11_ATI = $892C;
+ GL_REG_12_ATI = $892D;
+ GL_REG_13_ATI = $892E;
+ GL_REG_14_ATI = $892F;
+ GL_REG_15_ATI = $8930;
+ GL_REG_16_ATI = $8931;
+ GL_REG_17_ATI = $8932;
+ GL_REG_18_ATI = $8933;
+ GL_REG_19_ATI = $8934;
+ GL_REG_20_ATI = $8935;
+ GL_REG_21_ATI = $8936;
+ GL_REG_22_ATI = $8937;
+ GL_REG_23_ATI = $8938;
+ GL_REG_24_ATI = $8939;
+ GL_REG_25_ATI = $893A;
+ GL_REG_26_ATI = $893B;
+ GL_REG_27_ATI = $893C;
+ GL_REG_28_ATI = $893D;
+ GL_REG_29_ATI = $893E;
+ GL_REG_30_ATI = $893F;
+ GL_REG_31_ATI = $8940;
+ GL_CON_0_ATI = $8941;
+ GL_CON_1_ATI = $8942;
+ GL_CON_2_ATI = $8943;
+ GL_CON_3_ATI = $8944;
+ GL_CON_4_ATI = $8945;
+ GL_CON_5_ATI = $8946;
+ GL_CON_6_ATI = $8947;
+ GL_CON_7_ATI = $8948;
+ GL_CON_8_ATI = $8949;
+ GL_CON_9_ATI = $894A;
+ GL_CON_10_ATI = $894B;
+ GL_CON_11_ATI = $894C;
+ GL_CON_12_ATI = $894D;
+ GL_CON_13_ATI = $894E;
+ GL_CON_14_ATI = $894F;
+ GL_CON_15_ATI = $8950;
+ GL_CON_16_ATI = $8951;
+ GL_CON_17_ATI = $8952;
+ GL_CON_18_ATI = $8953;
+ GL_CON_19_ATI = $8954;
+ GL_CON_20_ATI = $8955;
+ GL_CON_21_ATI = $8956;
+ GL_CON_22_ATI = $8957;
+ GL_CON_23_ATI = $8958;
+ GL_CON_24_ATI = $8959;
+ GL_CON_25_ATI = $895A;
+ GL_CON_26_ATI = $895B;
+ GL_CON_27_ATI = $895C;
+ GL_CON_28_ATI = $895D;
+ GL_CON_29_ATI = $895E;
+ GL_CON_30_ATI = $895F;
+ GL_CON_31_ATI = $8960;
+ GL_MOV_ATI = $8961;
+ GL_ADD_ATI = $8963;
+ GL_MUL_ATI = $8964;
+ GL_SUB_ATI = $8965;
+ GL_DOT3_ATI = $8966;
+ GL_DOT4_ATI = $8967;
+ GL_MAD_ATI = $8968;
+ GL_LERP_ATI = $8969;
+ GL_CND_ATI = $896A;
+ GL_CND0_ATI = $896B;
+ GL_DOT2_ADD_ATI = $896C;
+ GL_SECONDARY_INTERPOLATOR_ATI = $896D;
+ GL_NUM_FRAGMENT_REGISTERS_ATI = $896E;
+ GL_NUM_FRAGMENT_CONSTANTS_ATI = $896F;
+ GL_NUM_PASSES_ATI = $8970;
+ GL_NUM_INSTRUCTIONS_PER_PASS_ATI = $8971;
+ GL_NUM_INSTRUCTIONS_TOTAL_ATI = $8972;
+ GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI = $8973;
+ GL_NUM_LOOPBACK_COMPONENTS_ATI = $8974;
+ GL_COLOR_ALPHA_PAIRING_ATI = $8975;
+ GL_SWIZZLE_STR_ATI = $8976;
+ GL_SWIZZLE_STQ_ATI = $8977;
+ GL_SWIZZLE_STR_DR_ATI = $8978;
+ GL_SWIZZLE_STQ_DQ_ATI = $8979;
+ GL_SWIZZLE_STRQ_ATI = $897A;
+ GL_SWIZZLE_STRQ_DQ_ATI = $897B;
+ GL_RED_BIT_ATI = $00000001;
+ GL_GREEN_BIT_ATI = $00000002;
+ GL_BLUE_BIT_ATI = $00000004;
+ GL_2X_BIT_ATI = $00000001;
+ GL_4X_BIT_ATI = $00000002;
+ GL_8X_BIT_ATI = $00000004;
+ GL_HALF_BIT_ATI = $00000008;
+ GL_QUARTER_BIT_ATI = $00000010;
+ GL_EIGHTH_BIT_ATI = $00000020;
+ GL_SATURATE_BIT_ATI = $00000040;
+ GL_COMP_BIT_ATI = $00000002;
+ GL_NEGATE_BIT_ATI = $00000004;
+ GL_BIAS_BIT_ATI = $00000008;
+
+ // GL_ATI_pn_triangles
+ GL_PN_TRIANGLES_ATI = $87F0;
+ GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F1;
+ GL_PN_TRIANGLES_POINT_MODE_ATI = $87F2;
+ GL_PN_TRIANGLES_NORMAL_MODE_ATI = $87F3;
+ GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F4;
+ GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = $87F5;
+ GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = $87F6;
+ GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = $87F7;
+ GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = $87F8;
+
+ // GL_ATI_separate_stencil
+ GL_STENCIL_BACK_FUNC_ATI = $8800;
+ GL_STENCIL_BACK_FAIL_ATI = $8801;
+ GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = $8802;
+ GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = $8803;
+
+ // GL_ATI_text_fragment_shader
+ GL_TEXT_FRAGMENT_SHADER_ATI = $8200;
+
+ // GL_ATI_texture_env_combine3
+ GL_MODULATE_ADD_ATI = $8744;
+ GL_MODULATE_SIGNED_ADD_ATI = $8745;
+ GL_MODULATE_SUBTRACT_ATI = $8746;
+
+ // GL_ATI_texture_float
+ GL_RGBA_FLOAT32_ATI = $8814;
+ GL_RGB_FLOAT32_ATI = $8815;
+ GL_ALPHA_FLOAT32_ATI = $8816;
+ GL_INTENSITY_FLOAT32_ATI = $8817;
+ GL_LUMINANCE_FLOAT32_ATI = $8818;
+ GL_LUMINANCE_ALPHA_FLOAT32_ATI = $8819;
+ GL_RGBA_FLOAT16_ATI = $881A;
+ GL_RGB_FLOAT16_ATI = $881B;
+ GL_ALPHA_FLOAT16_ATI = $881C;
+ GL_INTENSITY_FLOAT16_ATI = $881D;
+ GL_LUMINANCE_FLOAT16_ATI = $881E;
+ GL_LUMINANCE_ALPHA_FLOAT16_ATI = $881F;
+
+ // GL_ATI_texture_mirror_once
+ GL_MIRROR_CLAMP_ATI = $8742;
+ GL_MIRROR_CLAMP_TO_EDGE_ATI = $8743;
+
+ // GL_ATI_vertex_array_object
+ GL_STATIC_ATI = $8760;
+ GL_DYNAMIC_ATI = $8761;
+ GL_PRESERVE_ATI = $8762;
+ GL_DISCARD_ATI = $8763;
+ GL_OBJECT_BUFFER_SIZE_ATI = $8764;
+ GL_OBJECT_BUFFER_USAGE_ATI = $8765;
+ GL_ARRAY_OBJECT_BUFFER_ATI = $8766;
+ GL_ARRAY_OBJECT_OFFSET_ATI = $8767;
+
+ // GL_ATI_vertex_streams
+ GL_MAX_VERTEX_STREAMS_ATI = $876B;
+ GL_VERTEX_STREAM0_ATI = $876C;
+ GL_VERTEX_STREAM1_ATI = $876D;
+ GL_VERTEX_STREAM2_ATI = $876E;
+ GL_VERTEX_STREAM3_ATI = $876F;
+ GL_VERTEX_STREAM4_ATI = $8770;
+ GL_VERTEX_STREAM5_ATI = $8771;
+ GL_VERTEX_STREAM6_ATI = $8772;
+ GL_VERTEX_STREAM7_ATI = $8773;
+ GL_VERTEX_SOURCE_ATI = $8774;
+
+ // GL_ATI_meminfo
+ GL_VBO_FREE_MEMORY_ATI = $87FB;
+ GL_TEXTURE_FREE_MEMORY_ATI = $87FC;
+ GL_RENDERBUFFER_FREE_MEMORY_ATI = $87FD;
+
+ // GL_AMD_performance_monitor
+ GL_COUNTER_TYPE_AMD = $8BC0;
+ GL_COUNTER_RANGE_AMD = $8BC1;
+ GL_UNSIGNED_INT64_AMD = $8BC2;
+ GL_PERCENTAGE_AMD = $8BC3;
+ GL_PERFMON_RESULT_AVAILABLE_AMD = $8BC4;
+ GL_PERFMON_RESULT_SIZE_AMD = $8BC5;
+ GL_PERFMON_RESULT_AMD = $8BC6;
+
+ // GL_AMD_vertex_shader_tesselator
+ GL_SAMPLER_BUFFER_AMD = $9001;
+ GL_INT_SAMPLER_BUFFER_AMD = $9002;
+ GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD = $9003;
+ GL_TESSELLATION_MODE_AMD = $9004;
+ GL_TESSELLATION_FACTOR_AMD = $9005;
+ GL_DISCRETE_AMD = $9006;
+ GL_CONTINUOUS_AMD = $9007;
+
+ // GL_AMD_seamless_cubemap_per_texture
+ { reuse GL_TEXTURE_CUBE_MAP_SEAMLESS }
+
+ // GL_AMD_name_gen_delete
+ GL_DATA_BUFFER_AMD = $9151;
+ GL_PERFORMANCE_MONITOR_AMD = $9152;
+ GL_QUERY_OBJECT_AMD = $9153;
+ GL_VERTEX_ARRAY_OBJECT_AMD = $9154;
+ GL_SAMPLER_OBJECT_AMD = $9155;
+
+ // GL_AMD_debug_output
+ GL_MAX_DEBUG_LOGGED_MESSAGES_AMD = $9144;
+ GL_DEBUG_LOGGED_MESSAGES_AMD = $9145;
+ GL_DEBUG_SEVERITY_HIGH_AMD = $9146;
+ GL_DEBUG_SEVERITY_MEDIUM_AMD = $9147;
+ GL_DEBUG_SEVERITY_LOW_AMD = $9148;
+ GL_DEBUG_CATEGORY_API_ERROR_AMD = $9149;
+ GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = $914A;
+ GL_DEBUG_CATEGORY_DEPRECATION_AMD = $914B;
+ GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = $914C;
+ GL_DEBUG_CATEGORY_PERFORMANCE_AMD = $914D;
+ GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = $914E;
+ GL_DEBUG_CATEGORY_APPLICATION_AMD = $914F;
+ GL_DEBUG_CATEGORY_OTHER_AMD = $9150;
+
+ // GL_AMD_depth_clamp_separate
+ GL_DEPTH_CLAMP_NEAR_AMD = $901E;
+ GL_DEPTH_CLAMP_FAR_AMD = $901F;
+
+ // GL_EXT_422_pixels
+ GL_422_EXT = $80CC;
+ GL_422_REV_EXT = $80CD;
+ GL_422_AVERAGE_EXT = $80CE;
+ GL_422_REV_AVERAGE_EXT = $80CF;
+
+ // GL_EXT_abgr
+ GL_ABGR_EXT = $8000;
+
+ // GL_EXT_bgra
+ GL_BGR_EXT = $80E0;
+ GL_BGRA_EXT = $80E1;
+
+ // GL_EXT_blend_color
+ GL_CONSTANT_COLOR_EXT = $8001;
+ GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002;
+ GL_CONSTANT_ALPHA_EXT = $8003;
+ GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004;
+ GL_BLEND_COLOR_EXT = $8005;
+
+ // GL_EXT_blend_func_separate
+ GL_BLEND_DST_RGB_EXT = $80C8;
+ GL_BLEND_SRC_RGB_EXT = $80C9;
+ GL_BLEND_DST_ALPHA_EXT = $80CA;
+ GL_BLEND_SRC_ALPHA_EXT = $80CB;
+
+ // GL_EXT_blend_minmax
+ GL_FUNC_ADD_EXT = $8006;
+ GL_MIN_EXT = $8007;
+ GL_MAX_EXT = $8008;
+ GL_BLEND_EQUATION_EXT = $8009;
+
+ // GL_EXT_blend_subtract
+ GL_FUNC_SUBTRACT_EXT = $800A;
+ GL_FUNC_REVERSE_SUBTRACT_EXT = $800B;
+
+ // GL_EXT_clip_volume_hint
+ GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0;
+
+ // GL_EXT_cmyka
+ GL_CMYK_EXT = $800C;
+ GL_CMYKA_EXT = $800D;
+ GL_PACK_CMYK_HINT_EXT = $800E;
+ GL_UNPACK_CMYK_HINT_EXT = $800F;
+
+ // GL_EXT_compiled_vertex_array
+ GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8;
+ GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9;
+
+ // GL_EXT_convolution
+ GL_CONVOLUTION_1D_EXT = $8010;
+ GL_CONVOLUTION_2D_EXT = $8011;
+ GL_SEPARABLE_2D_EXT = $8012;
+ GL_CONVOLUTION_BORDER_MODE_EXT = $8013;
+ GL_CONVOLUTION_FILTER_SCALE_EXT = $8014;
+ GL_CONVOLUTION_FILTER_BIAS_EXT = $8015;
+ GL_REDUCE_EXT = $8016;
+ GL_CONVOLUTION_FORMAT_EXT = $8017;
+ GL_CONVOLUTION_WIDTH_EXT = $8018;
+ GL_CONVOLUTION_HEIGHT_EXT = $8019;
+ GL_MAX_CONVOLUTION_WIDTH_EXT = $801A;
+ GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B;
+ GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C;
+ GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D;
+ GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E;
+ GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F;
+ GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020;
+ GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021;
+ GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022;
+ GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023;
+
+ // GL_EXT_coordinate_frame
+ GL_TANGENT_ARRAY_EXT = $8439;
+ GL_BINORMAL_ARRAY_EXT = $843A;
+ GL_CURRENT_TANGENT_EXT = $843B;
+ GL_CURRENT_BINORMAL_EXT = $843C;
+ GL_TANGENT_ARRAY_TYPE_EXT = $843E;
+ GL_TANGENT_ARRAY_STRIDE_EXT = $843F;
+ GL_BINORMAL_ARRAY_TYPE_EXT = $8440;
+ GL_BINORMAL_ARRAY_STRIDE_EXT = $8441;
+ GL_TANGENT_ARRAY_POINTER_EXT = $8442;
+ GL_BINORMAL_ARRAY_POINTER_EXT = $8443;
+ GL_MAP1_TANGENT_EXT = $8444;
+ GL_MAP2_TANGENT_EXT = $8445;
+ GL_MAP1_BINORMAL_EXT = $8446;
+ GL_MAP2_BINORMAL_EXT = $8447;
+
+ // GL_EXT_cull_vertex
+ GL_CULL_VERTEX_EXT = $81AA;
+ GL_CULL_VERTEX_EYE_POSITION_EXT = $81AB;
+ GL_CULL_VERTEX_OBJECT_POSITION_EXT = $81AC;
+
+ // GL_EXT_draw_range_elements
+ GL_MAX_ELEMENTS_VERTICES_EXT = $80E8;
+ GL_MAX_ELEMENTS_INDICES_EXT = $80E9;
+
+ // GL_EXT_fog_coord
+ GL_FOG_COORDINATE_SOURCE_EXT = $8450;
+ GL_FOG_COORDINATE_EXT = $8451;
+ GL_FRAGMENT_DEPTH_EXT = $8452;
+ GL_CURRENT_FOG_COORDINATE_EXT = $8453;
+ GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454;
+ GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455;
+ GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456;
+ GL_FOG_COORDINATE_ARRAY_EXT = $8457;
+
+ // GL_EXT_framebuffer_object
+ GL_FRAMEBUFFER_EXT = $8D40;
+ GL_RENDERBUFFER_EXT = $8D41;
+ GL_STENCIL_INDEX_EXT = $8D45;
+ GL_STENCIL_INDEX1_EXT = $8D46;
+ GL_STENCIL_INDEX4_EXT = $8D47;
+ GL_STENCIL_INDEX8_EXT = $8D48;
+ GL_STENCIL_INDEX16_EXT = $8D49;
+ GL_RENDERBUFFER_WIDTH_EXT = $8D42;
+ GL_RENDERBUFFER_HEIGHT_EXT = $8D43;
+ GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = $8D44;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = $8CD0;
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = $8CD1;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = $8CD2;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = $8CD3;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = $8CD4;
+ GL_COLOR_ATTACHMENT0_EXT = $8CE0;
+ GL_COLOR_ATTACHMENT1_EXT = $8CE1;
+ GL_COLOR_ATTACHMENT2_EXT = $8CE2;
+ GL_COLOR_ATTACHMENT3_EXT = $8CE3;
+ GL_COLOR_ATTACHMENT4_EXT = $8CE4;
+ GL_COLOR_ATTACHMENT5_EXT = $8CE5;
+ GL_COLOR_ATTACHMENT6_EXT = $8CE6;
+ GL_COLOR_ATTACHMENT7_EXT = $8CE7;
+ GL_COLOR_ATTACHMENT8_EXT = $8CE8;
+ GL_COLOR_ATTACHMENT9_EXT = $8CE9;
+ GL_COLOR_ATTACHMENT10_EXT = $8CEA;
+ GL_COLOR_ATTACHMENT11_EXT = $8CEB;
+ GL_COLOR_ATTACHMENT12_EXT = $8CEC;
+ GL_COLOR_ATTACHMENT13_EXT = $8CED;
+ GL_COLOR_ATTACHMENT14_EXT = $8CEE;
+ GL_COLOR_ATTACHMENT15_EXT = $8CEF;
+ GL_DEPTH_ATTACHMENT_EXT = $8D00;
+ GL_STENCIL_ATTACHMENT_EXT = $8D20;
+ GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5;
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = $8CD6;
+ GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = $8CD7;
+ GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT = $8CD8;
+ GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = $8CD9;
+ GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = $8CDA;
+ GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = $8CDB;
+ GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = $8CDC;
+ GL_FRAMEBUFFER_UNSUPPORTED_EXT = $8CDD;
+ GL_FRAMEBUFFER_STATUS_ERROR_EXT = $8CDE;
+ GL_FRAMEBUFFER_BINDING_EXT = $8CA6;
+ GL_RENDERBUFFER_BINDING_EXT = $8CA7;
+ GL_MAX_COLOR_ATTACHMENTS_EXT = $8CDF;
+ GL_MAX_RENDERBUFFER_SIZE_EXT = $84E8;
+ GL_INVALID_FRAMEBUFFER_OPERATION_EXT = $0506;
+
+ // GL_EXT_histogram
+ GL_HISTOGRAM_EXT = $8024;
+ GL_PROXY_HISTOGRAM_EXT = $8025;
+ GL_HISTOGRAM_WIDTH_EXT = $8026;
+ GL_HISTOGRAM_FORMAT_EXT = $8027;
+ GL_HISTOGRAM_RED_SIZE_EXT = $8028;
+ GL_HISTOGRAM_GREEN_SIZE_EXT = $8029;
+ GL_HISTOGRAM_BLUE_SIZE_EXT = $802A;
+ GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B;
+ GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C;
+ GL_HISTOGRAM_SINK_EXT = $802D;
+ GL_MINMAX_EXT = $802E;
+ GL_MINMAX_FORMAT_EXT = $802F;
+ GL_MINMAX_SINK_EXT = $8030;
+ GL_TABLE_TOO_LARGE_EXT = $8031;
+
+ // GL_EXT_index_array_formats
+ GL_IUI_V2F_EXT = $81AD;
+ GL_IUI_V3F_EXT = $81AE;
+ GL_IUI_N3F_V2F_EXT = $81AF;
+ GL_IUI_N3F_V3F_EXT = $81B0;
+ GL_T2F_IUI_V2F_EXT = $81B1;
+ GL_T2F_IUI_V3F_EXT = $81B2;
+ GL_T2F_IUI_N3F_V2F_EXT = $81B3;
+ GL_T2F_IUI_N3F_V3F_EXT = $81B4;
+
+ // GL_EXT_index_func
+ GL_INDEX_TEST_EXT = $81B5;
+ GL_INDEX_TEST_FUNC_EXT = $81B6;
+ GL_INDEX_TEST_REF_EXT = $81B7;
+
+ // GL_EXT_index_material
+ GL_INDEX_MATERIAL_EXT = $81B8;
+ GL_INDEX_MATERIAL_PARAMETER_EXT = $81B9;
+ GL_INDEX_MATERIAL_FACE_EXT = $81BA;
+
+ // GL_EXT_light_texture
+ GL_FRAGMENT_MATERIAL_EXT = $8349;
+ GL_FRAGMENT_NORMAL_EXT = $834A;
+ GL_FRAGMENT_COLOR_EXT = $834C;
+ GL_ATTENUATION_EXT = $834D;
+ GL_SHADOW_ATTENUATION_EXT = $834E;
+ GL_TEXTURE_APPLICATION_MODE_EXT = $834F;
+ GL_TEXTURE_LIGHT_EXT = $8350;
+ GL_TEXTURE_MATERIAL_FACE_EXT = $8351;
+ GL_TEXTURE_MATERIAL_PARAMETER_EXT = $8352;
+
+ // GL_EXT_multisample
+ GL_MULTISAMPLE_EXT = $809D;
+ GL_SAMPLE_ALPHA_TO_MASK_EXT = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE_EXT = $809F;
+ GL_SAMPLE_MASK_EXT = $80A0;
+ GL_1PASS_EXT = $80A1;
+ GL_2PASS_0_EXT = $80A2;
+ GL_2PASS_1_EXT = $80A3;
+ GL_4PASS_0_EXT = $80A4;
+ GL_4PASS_1_EXT = $80A5;
+ GL_4PASS_2_EXT = $80A6;
+ GL_4PASS_3_EXT = $80A7;
+ GL_SAMPLE_BUFFERS_EXT = $80A8;
+ GL_SAMPLES_EXT = $80A9;
+ GL_SAMPLE_MASK_VALUE_EXT = $80AA;
+ GL_SAMPLE_MASK_INVERT_EXT = $80AB;
+ GL_SAMPLE_PATTERN_EXT = $80AC;
+ GL_MULTISAMPLE_BIT_EXT = $20000000;
+
+ // GL_EXT_packed_pixels
+ GL_UNSIGNED_BYTE_3_3_2_EXT = $8032;
+ GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033;
+ GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034;
+ GL_UNSIGNED_INT_8_8_8_8_EXT = $8035;
+ GL_UNSIGNED_INT_10_10_10_2_EXT = $8036;
+
+ // GL_EXT_paletted_texture
+ GL_COLOR_INDEX1_EXT = $80E2;
+ GL_COLOR_INDEX2_EXT = $80E3;
+ GL_COLOR_INDEX4_EXT = $80E4;
+ GL_COLOR_INDEX8_EXT = $80E5;
+ GL_COLOR_INDEX12_EXT = $80E6;
+ GL_COLOR_INDEX16_EXT = $80E7;
+ GL_TEXTURE_INDEX_SIZE_EXT = $80ED;
+
+ // GL_EXT_pixel_transform
+ GL_PIXEL_TRANSFORM_2D_EXT = $8330;
+ GL_PIXEL_MAG_FILTER_EXT = $8331;
+ GL_PIXEL_MIN_FILTER_EXT = $8332;
+ GL_PIXEL_CUBIC_WEIGHT_EXT = $8333;
+ GL_CUBIC_EXT = $8334;
+ GL_AVERAGE_EXT = $8335;
+ GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = $8336;
+ GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = $8337;
+ GL_PIXEL_TRANSFORM_2D_MATRIX_EXT = $8338;
+
+ // GL_EXT_point_parameters
+ GL_POINT_SIZE_MIN_EXT = $8126;
+ GL_POINT_SIZE_MAX_EXT = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128;
+ GL_DISTANCE_ATTENUATION_EXT = $8129;
+
+ // GL_EXT_polygon_offset
+ GL_POLYGON_OFFSET_EXT = $8037;
+ GL_POLYGON_OFFSET_FACTOR_EXT = $8038;
+ GL_POLYGON_OFFSET_BIAS_EXT = $8039;
+
+ // GL_EXT_rescale_normal
+ GL_RESCALE_NORMAL_EXT = $803A;
+
+ // GL_EXT_secondary_color
+ GL_COLOR_SUM_EXT = $8458;
+ GL_CURRENT_SECONDARY_COLOR_EXT = $8459;
+ GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A;
+ GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B;
+ GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C;
+ GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D;
+ GL_SECONDARY_COLOR_ARRAY_EXT = $845E;
+
+ // GL_EXT_separate_specular_color
+ GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8;
+ GL_SINGLE_COLOR_EXT = $81F9;
+ GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA;
+
+ // GL_EXT_shared_texture_palette
+ GL_SHARED_TEXTURE_PALETTE_EXT = $81FB;
+
+ // GL_EXT_stencil_two_side
+ GL_STENCIL_TEST_TWO_SIDE_EXT = $8910;
+ GL_ACTIVE_STENCIL_FACE_EXT = $8911;
+
+ // GL_EXT_stencil_wrap
+ GL_INCR_WRAP_EXT = $8507;
+ GL_DECR_WRAP_EXT = $8508;
+
+ // GL_EXT_texture
+ GL_ALPHA4_EXT = $803B;
+ GL_ALPHA8_EXT = $803C;
+ GL_ALPHA12_EXT = $803D;
+ GL_ALPHA16_EXT = $803E;
+ GL_LUMINANCE4_EXT = $803F;
+ GL_LUMINANCE8_EXT = $8040;
+ GL_LUMINANCE12_EXT = $8041;
+ GL_LUMINANCE16_EXT = $8042;
+ GL_LUMINANCE4_ALPHA4_EXT = $8043;
+ GL_LUMINANCE6_ALPHA2_EXT = $8044;
+ GL_LUMINANCE8_ALPHA8_EXT = $8045;
+ GL_LUMINANCE12_ALPHA4_EXT = $8046;
+ GL_LUMINANCE12_ALPHA12_EXT = $8047;
+ GL_LUMINANCE16_ALPHA16_EXT = $8048;
+ GL_INTENSITY_EXT = $8049;
+ GL_INTENSITY4_EXT = $804A;
+ GL_INTENSITY8_EXT = $804B;
+ GL_INTENSITY12_EXT = $804C;
+ GL_INTENSITY16_EXT = $804D;
+ GL_RGB2_EXT = $804E;
+ GL_RGB4_EXT = $804F;
+ GL_RGB5_EXT = $8050;
+ GL_RGB8_EXT = $8051;
+ GL_RGB10_EXT = $8052;
+ GL_RGB12_EXT = $8053;
+ GL_RGB16_EXT = $8054;
+ GL_RGBA2_EXT = $8055;
+ GL_RGBA4_EXT = $8056;
+ GL_RGB5_A1_EXT = $8057;
+ GL_RGBA8_EXT = $8058;
+ GL_RGB10_A2_EXT = $8059;
+ GL_RGBA12_EXT = $805A;
+ GL_RGBA16_EXT = $805B;
+ GL_TEXTURE_RED_SIZE_EXT = $805C;
+ GL_TEXTURE_GREEN_SIZE_EXT = $805D;
+ GL_TEXTURE_BLUE_SIZE_EXT = $805E;
+ GL_TEXTURE_ALPHA_SIZE_EXT = $805F;
+ GL_TEXTURE_LUMINANCE_SIZE_EXT = $8060;
+ GL_TEXTURE_INTENSITY_SIZE_EXT = $8061;
+ GL_REPLACE_EXT = $8062;
+ GL_PROXY_TEXTURE_1D_EXT = $8063;
+ GL_PROXY_TEXTURE_2D_EXT = $8064;
+ GL_TEXTURE_TOO_LARGE_EXT = $8065;
+
+ // GL_EXT_texture3D
+ GL_PACK_SKIP_IMAGES_EXT = $806B;
+ GL_PACK_IMAGE_HEIGHT_EXT = $806C;
+ GL_UNPACK_SKIP_IMAGES_EXT = $806D;
+ GL_UNPACK_IMAGE_HEIGHT_EXT = $806E;
+ GL_TEXTURE_3D_EXT = $806F;
+ GL_PROXY_TEXTURE_3D_EXT = $8070;
+ GL_TEXTURE_DEPTH_EXT = $8071;
+ GL_TEXTURE_WRAP_R_EXT = $8072;
+ GL_MAX_3D_TEXTURE_SIZE_EXT = $8073;
+
+ // GL_EXT_texture_compression_s3tc
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
+
+ // GL_EXT_texture_cube_map
+ GL_NORMAL_MAP_EXT = $8511;
+ GL_REFLECTION_MAP_EXT = $8512;
+ GL_TEXTURE_CUBE_MAP_EXT = $8513;
+ GL_TEXTURE_BINDING_CUBE_MAP_EXT = $8514;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT = $8515;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT = $8516;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT = $8517;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT = $8518;
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT = $8519;
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT = $851A;
+ GL_PROXY_TEXTURE_CUBE_MAP_EXT = $851B;
+ GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT = $851C;
+
+ // GL_EXT_texture_edge_clamp
+ GL_CLAMP_TO_EDGE_EXT = $812F;
+
+ // GL_EXT_texture_env_combine
+ GL_COMBINE_EXT = $8570;
+ GL_COMBINE_RGB_EXT = $8571;
+ GL_COMBINE_ALPHA_EXT = $8572;
+ GL_RGB_SCALE_EXT = $8573;
+ GL_ADD_SIGNED_EXT = $8574;
+ GL_INTERPOLATE_EXT = $8575;
+ GL_CONSTANT_EXT = $8576;
+ GL_PRIMARY_COLOR_EXT = $8577;
+ GL_PREVIOUS_EXT = $8578;
+ GL_SOURCE0_RGB_EXT = $8580;
+ GL_SOURCE1_RGB_EXT = $8581;
+ GL_SOURCE2_RGB_EXT = $8582;
+ GL_SOURCE0_ALPHA_EXT = $8588;
+ GL_SOURCE1_ALPHA_EXT = $8589;
+ GL_SOURCE2_ALPHA_EXT = $858A;
+ GL_OPERAND0_RGB_EXT = $8590;
+ GL_OPERAND1_RGB_EXT = $8591;
+ GL_OPERAND2_RGB_EXT = $8592;
+ GL_OPERAND0_ALPHA_EXT = $8598;
+ GL_OPERAND1_ALPHA_EXT = $8599;
+ GL_OPERAND2_ALPHA_EXT = $859A;
+
+ // GL_EXT_texture_env_dot3
+ GL_DOT3_RGB_EXT = $8740;
+ GL_DOT3_RGBA_EXT = $8741;
+
+ // GL_EXT_texture_filter_anisotropic
+ GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
+
+ // GL_EXT_texture_lod_bias
+ GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD;
+ GL_TEXTURE_FILTER_CONTROL_EXT = $8500;
+ GL_TEXTURE_LOD_BIAS_EXT = $8501;
+
+ // GL_EXT_texture_object
+ GL_TEXTURE_PRIORITY_EXT = $8066;
+ GL_TEXTURE_RESIDENT_EXT = $8067;
+ GL_TEXTURE_1D_BINDING_EXT = $8068;
+ GL_TEXTURE_2D_BINDING_EXT = $8069;
+ GL_TEXTURE_3D_BINDING_EXT = $806A;
+
+ // GL_EXT_texture_perturb_normal
+ GL_PERTURB_EXT = $85AE;
+ GL_TEXTURE_NORMAL_EXT = $85AF;
+
+ // GL_EXT_texture_rectangle
+ GL_TEXTURE_RECTANGLE_EXT = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_EXT = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_EXT = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = $84F8;
+
+ // GL_EXT_vertex_array
+ GL_VERTEX_ARRAY_EXT = $8074;
+ GL_NORMAL_ARRAY_EXT = $8075;
+ GL_COLOR_ARRAY_EXT = $8076;
+ GL_INDEX_ARRAY_EXT = $8077;
+ GL_TEXTURE_COORD_ARRAY_EXT = $8078;
+ GL_EDGE_FLAG_ARRAY_EXT = $8079;
+ GL_VERTEX_ARRAY_SIZE_EXT = $807A;
+ GL_VERTEX_ARRAY_TYPE_EXT = $807B;
+ GL_VERTEX_ARRAY_STRIDE_EXT = $807C;
+ GL_VERTEX_ARRAY_COUNT_EXT = $807D;
+ GL_NORMAL_ARRAY_TYPE_EXT = $807E;
+ GL_NORMAL_ARRAY_STRIDE_EXT = $807F;
+ GL_NORMAL_ARRAY_COUNT_EXT = $8080;
+ GL_COLOR_ARRAY_SIZE_EXT = $8081;
+ GL_COLOR_ARRAY_TYPE_EXT = $8082;
+ GL_COLOR_ARRAY_STRIDE_EXT = $8083;
+ GL_COLOR_ARRAY_COUNT_EXT = $8084;
+ GL_INDEX_ARRAY_TYPE_EXT = $8085;
+ GL_INDEX_ARRAY_STRIDE_EXT = $8086;
+ GL_INDEX_ARRAY_COUNT_EXT = $8087;
+ GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088;
+ GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089;
+ GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A;
+ GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B;
+ GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C;
+ GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D;
+ GL_VERTEX_ARRAY_POINTER_EXT = $808E;
+ GL_NORMAL_ARRAY_POINTER_EXT = $808F;
+ GL_COLOR_ARRAY_POINTER_EXT = $8090;
+ GL_INDEX_ARRAY_POINTER_EXT = $8091;
+ GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092;
+ GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093;
+
+ // GL_EXT_vertex_shader
+ GL_VERTEX_SHADER_EXT = $8780;
+ GL_VERTEX_SHADER_BINDING_EXT = $8781;
+ GL_OP_INDEX_EXT = $8782;
+ GL_OP_NEGATE_EXT = $8783;
+ GL_OP_DOT3_EXT = $8784;
+ GL_OP_DOT4_EXT = $8785;
+ GL_OP_MUL_EXT = $8786;
+ GL_OP_ADD_EXT = $8787;
+ GL_OP_MADD_EXT = $8788;
+ GL_OP_FRAC_EXT = $8789;
+ GL_OP_MAX_EXT = $878A;
+ GL_OP_MIN_EXT = $878B;
+ GL_OP_SET_GE_EXT = $878C;
+ GL_OP_SET_LT_EXT = $878D;
+ GL_OP_CLAMP_EXT = $878E;
+ GL_OP_FLOOR_EXT = $878F;
+ GL_OP_ROUND_EXT = $8790;
+ GL_OP_EXP_BASE_2_EXT = $8791;
+ GL_OP_LOG_BASE_2_EXT = $8792;
+ GL_OP_POWER_EXT = $8793;
+ GL_OP_RECIP_EXT = $8794;
+ GL_OP_RECIP_SQRT_EXT = $8795;
+ GL_OP_SUB_EXT = $8796;
+ GL_OP_CROSS_PRODUCT_EXT = $8797;
+ GL_OP_MULTIPLY_MATRIX_EXT = $8798;
+ GL_OP_MOV_EXT = $8799;
+ GL_OUTPUT_VERTEX_EXT = $879A;
+ GL_OUTPUT_COLOR0_EXT = $879B;
+ GL_OUTPUT_COLOR1_EXT = $879C;
+ GL_OUTPUT_TEXTURE_COORD0_EXT = $879D;
+ GL_OUTPUT_TEXTURE_COORD1_EXT = $879E;
+ GL_OUTPUT_TEXTURE_COORD2_EXT = $879F;
+ GL_OUTPUT_TEXTURE_COORD3_EXT = $87A0;
+ GL_OUTPUT_TEXTURE_COORD4_EXT = $87A1;
+ GL_OUTPUT_TEXTURE_COORD5_EXT = $87A2;
+ GL_OUTPUT_TEXTURE_COORD6_EXT = $87A3;
+ GL_OUTPUT_TEXTURE_COORD7_EXT = $87A4;
+ GL_OUTPUT_TEXTURE_COORD8_EXT = $87A5;
+ GL_OUTPUT_TEXTURE_COORD9_EXT = $87A6;
+ GL_OUTPUT_TEXTURE_COORD10_EXT = $87A7;
+ GL_OUTPUT_TEXTURE_COORD11_EXT = $87A8;
+ GL_OUTPUT_TEXTURE_COORD12_EXT = $87A9;
+ GL_OUTPUT_TEXTURE_COORD13_EXT = $87AA;
+ GL_OUTPUT_TEXTURE_COORD14_EXT = $87AB;
+ GL_OUTPUT_TEXTURE_COORD15_EXT = $87AC;
+ GL_OUTPUT_TEXTURE_COORD16_EXT = $87AD;
+ GL_OUTPUT_TEXTURE_COORD17_EXT = $87AE;
+ GL_OUTPUT_TEXTURE_COORD18_EXT = $87AF;
+ GL_OUTPUT_TEXTURE_COORD19_EXT = $87B0;
+ GL_OUTPUT_TEXTURE_COORD20_EXT = $87B1;
+ GL_OUTPUT_TEXTURE_COORD21_EXT = $87B2;
+ GL_OUTPUT_TEXTURE_COORD22_EXT = $87B3;
+ GL_OUTPUT_TEXTURE_COORD23_EXT = $87B4;
+ GL_OUTPUT_TEXTURE_COORD24_EXT = $87B5;
+ GL_OUTPUT_TEXTURE_COORD25_EXT = $87B6;
+ GL_OUTPUT_TEXTURE_COORD26_EXT = $87B7;
+ GL_OUTPUT_TEXTURE_COORD27_EXT = $87B8;
+ GL_OUTPUT_TEXTURE_COORD28_EXT = $87B9;
+ GL_OUTPUT_TEXTURE_COORD29_EXT = $87BA;
+ GL_OUTPUT_TEXTURE_COORD30_EXT = $87BB;
+ GL_OUTPUT_TEXTURE_COORD31_EXT = $87BC;
+ GL_OUTPUT_FOG_EXT = $87BD;
+ GL_SCALAR_EXT = $87BE;
+ GL_VECTOR_EXT = $87BF;
+ GL_MATRIX_EXT = $87C0;
+ GL_VARIANT_EXT = $87C1;
+ GL_INVARIANT_EXT = $87C2;
+ GL_LOCAL_CONSTANT_EXT = $87C3;
+ GL_LOCAL_EXT = $87C4;
+ GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = $87C5;
+ GL_MAX_VERTEX_SHADER_VARIANTS_EXT = $87C6;
+ GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = $87C7;
+ GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87C8;
+ GL_MAX_VERTEX_SHADER_LOCALS_EXT = $87C9;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CA;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = $87CB;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87CC;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = $87CD;
+ GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = $87CE;
+ GL_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CF;
+ GL_VERTEX_SHADER_VARIANTS_EXT = $87D0;
+ GL_VERTEX_SHADER_INVARIANTS_EXT = $87D1;
+ GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87D2;
+ GL_VERTEX_SHADER_LOCALS_EXT = $87D3;
+ GL_VERTEX_SHADER_OPTIMIZED_EXT = $87D4;
+ GL_X_EXT = $87D5;
+ GL_Y_EXT = $87D6;
+ GL_Z_EXT = $87D7;
+ GL_W_EXT = $87D8;
+ GL_NEGATIVE_X_EXT = $87D9;
+ GL_NEGATIVE_Y_EXT = $87DA;
+ GL_NEGATIVE_Z_EXT = $87DB;
+ GL_NEGATIVE_W_EXT = $87DC;
+ GL_ZERO_EXT = $87DD;
+ GL_ONE_EXT = $87DE;
+ GL_NEGATIVE_ONE_EXT = $87DF;
+ GL_NORMALIZED_RANGE_EXT = $87E0;
+ GL_FULL_RANGE_EXT = $87E1;
+ GL_CURRENT_VERTEX_EXT = $87E2;
+ GL_MVP_MATRIX_EXT = $87E3;
+ GL_VARIANT_VALUE_EXT = $87E4;
+ GL_VARIANT_DATATYPE_EXT = $87E5;
+ GL_VARIANT_ARRAY_STRIDE_EXT = $87E6;
+ GL_VARIANT_ARRAY_TYPE_EXT = $87E7;
+ GL_VARIANT_ARRAY_EXT = $87E8;
+ GL_VARIANT_ARRAY_POINTER_EXT = $87E9;
+ GL_INVARIANT_VALUE_EXT = $87EA;
+ GL_INVARIANT_DATATYPE_EXT = $87EB;
+ GL_LOCAL_CONSTANT_VALUE_EXT = $87EC;
+ GL_LOCAL_CONSTANT_DATATYPE_EXT = $87ED;
+
+ // GL_EXT_vertex_weighting
+ GL_MODELVIEW0_STACK_DEPTH_EXT = $0BA3;
+ GL_MODELVIEW1_STACK_DEPTH_EXT = $8502;
+ GL_MODELVIEW0_MATRIX_EXT = $0BA6;
+ GL_MODELVIEW1_MATRIX_EXT = $8506;
+ GL_VERTEX_WEIGHTING_EXT = $8509;
+ GL_MODELVIEW0_EXT = $1700;
+ GL_MODELVIEW1_EXT = $850A;
+ GL_CURRENT_VERTEX_WEIGHT_EXT = $850B;
+ GL_VERTEX_WEIGHT_ARRAY_EXT = $850C;
+ GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D;
+ GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E;
+ GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F;
+ GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510;
+
+ // GL_EXT_depth_bounds_test
+ GL_DEPTH_BOUNDS_TEST_EXT = $8890;
+ GL_DEPTH_BOUNDS_EXT = $8891;
+
+ // GL_EXT_texture_mirror_clamp
+ GL_MIRROR_CLAMP_EXT = $8742;
+ GL_MIRROR_CLAMP_TO_EDGE_EXT = $8743;
+ GL_MIRROR_CLAMP_TO_BORDER_EXT = $8912;
+
+ // GL_EXT_blend_equation_separate
+ GL_BLEND_EQUATION_RGB_EXT = $8009;
+ GL_BLEND_EQUATION_ALPHA_EXT = $883D;
+
+ // GL_EXT_pixel_buffer_object
+ GL_PIXEL_PACK_BUFFER_EXT = $88EB;
+ GL_PIXEL_UNPACK_BUFFER_EXT = $88EC;
+ GL_PIXEL_PACK_BUFFER_BINDING_EXT = $88ED;
+ GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = $88EF;
+
+ // GL_EXT_stencil_clear_tag
+ GL_STENCIL_TAG_BITS_EXT = $88F2;
+ GL_STENCIL_CLEAR_TAG_VALUE_EXT = $88F3;
+
+ // GL_EXT_packed_depth_stencil
+ GL_DEPTH_STENCIL_EXT = $84F9;
+ GL_UNSIGNED_INT_24_8_EXT = $84FA;
+ GL_DEPTH24_STENCIL8_EXT = $88F0;
+ GL_TEXTURE_STENCIL_SIZE_EXT = $88F1;
+
+ // GL_EXT_texture_sRGB
+ GL_SRGB_EXT = $8C40;
+ GL_SRGB8_EXT = $8C41;
+ GL_SRGB_ALPHA_EXT = $8C42;
+ GL_SRGB8_ALPHA8_EXT = $8C43;
+ GL_SLUMINANCE_ALPHA_EXT = $8C44;
+ GL_SLUMINANCE8_ALPHA8_EXT = $8C45;
+ GL_SLUMINANCE_EXT = $8C46;
+ GL_SLUMINANCE8_EXT = $8C47;
+ GL_COMPRESSED_SRGB_EXT = $8C48;
+ GL_COMPRESSED_SRGB_ALPHA_EXT = $8C49;
+ GL_COMPRESSED_SLUMINANCE_EXT = $8C4A;
+ GL_COMPRESSED_SLUMINANCE_ALPHA_EXT = $8C4B;
+ GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = $8C4C;
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = $8C4D;
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = $8C4E;
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = $8C4F;
+
+ // GL_EXT_framebuffer_blit
+ GL_READ_FRAMEBUFFER_EXT = $8CA8;
+ GL_DRAW_FRAMEBUFFER_EXT = $8CA9;
+ GL_READ_FRAMEBUFFER_BINDING_EXT = GL_FRAMEBUFFER_BINDING_EXT;
+ GL_DRAW_FRAMEBUFFER_BINDING_EXT = $8CAA;
+
+ // GL_EXT_framebuffer_multisample
+ GL_RENDERBUFFER_SAMPLES_EXT = $8CAB;
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT = $8D56;
+ GL_MAX_SAMPLES_EXT = $8D57;
+
+ // GL_EXT_timer_query
+ GL_TIME_ELAPSED_EXT = $88BF;
+
+ // GL_EXT_bindable_uniform
+ GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT = $8DE2;
+ GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT = $8DE3;
+ GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT = $8DE4;
+ GL_MAX_BINDABLE_UNIFORM_SIZE_EXT = $8DED;
+ GL_UNIFORM_BUFFER_EXT = $8DEE;
+ GL_UNIFORM_BUFFER_BINDING_EXT = $8DEF;
+
+ // GL_EXT_framebuffer_sRGB
+ GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT = $20B2;
+ WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = $20A9;
+ GL_FRAMEBUFFER_SRGB_EXT = $8DB9;
+ GL_FRAMEBUFFER_SRGB_CAPABLE_EXT = $8DBA;
+
+ // GL_EXT_geometry_shader4
+ GL_GEOMETRY_SHADER_EXT = $8DD9;
+ GL_GEOMETRY_VERTICES_OUT_EXT = $8DDA;
+ GL_GEOMETRY_INPUT_TYPE_EXT = $8DDB;
+ GL_GEOMETRY_OUTPUT_TYPE_EXT = $8DDC;
+ GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT = $8C29;
+ GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT = $8DDD;
+ GL_MAX_VERTEX_VARYING_COMPONENTS_EXT = $8DDE;
+ GL_MAX_VARYING_COMPONENTS_EXT = $8B4B;
+ GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT = $8DDF;
+ GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT = $8DE0;
+ GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT = $8DE1;
+ GL_LINES_ADJACENCY_EXT = $A;
+ GL_LINE_STRIP_ADJACENCY_EXT = $B;
+ GL_TRIANGLES_ADJACENCY_EXT = $C;
+ GL_TRIANGLE_STRIP_ADJACENCY_EXT = $D;
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT = $8DA8;
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT = $8DA9;
+ GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT = $8DA7;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT = $8CD4;
+ GL_PROGRAM_POINT_SIZE_EXT = $8642;
+
+ // GL_EXT_gpu_shader4
+ GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT = $88FD;
+ GL_SAMPLER_1D_ARRAY_EXT = $8DC0;
+ GL_SAMPLER_2D_ARRAY_EXT = $8DC1;
+ GL_SAMPLER_BUFFER_EXT = $8DC2;
+ GL_SAMPLER_1D_ARRAY_SHADOW_EXT = $8DC3;
+ GL_SAMPLER_2D_ARRAY_SHADOW_EXT = $8DC4;
+ GL_SAMPLER_CUBE_SHADOW_EXT = $8DC5;
+ GL_UNSIGNED_INT_VEC2_EXT = $8DC6;
+ GL_UNSIGNED_INT_VEC3_EXT = $8DC7;
+ GL_UNSIGNED_INT_VEC4_EXT = $8DC8;
+ GL_INT_SAMPLER_1D_EXT = $8DC9;
+ GL_INT_SAMPLER_2D_EXT = $8DCA;
+ GL_INT_SAMPLER_3D_EXT = $8DCB;
+ GL_INT_SAMPLER_CUBE_EXT = $8DCC;
+ GL_INT_SAMPLER_2D_RECT_EXT = $8DCD;
+ GL_INT_SAMPLER_1D_ARRAY_EXT = $8DCE;
+ GL_INT_SAMPLER_2D_ARRAY_EXT = $8DCF;
+ GL_INT_SAMPLER_BUFFER_EXT = $8DD0;
+ GL_UNSIGNED_INT_SAMPLER_1D_EXT = $8DD1;
+ GL_UNSIGNED_INT_SAMPLER_2D_EXT = $8DD2;
+ GL_UNSIGNED_INT_SAMPLER_3D_EXT = $8DD3;
+ GL_UNSIGNED_INT_SAMPLER_CUBE_EXT = $8DD4;
+ GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT = $8DD5;
+ GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT = $8DD6;
+ GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT = $8DD7;
+ GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = $8DD8;
+ GL_MIN_PROGRAM_TEXEL_OFFSET_EXT = $8904;
+ GL_MAX_PROGRAM_TEXEL_OFFSET_EXT = $8905;
+
+ // GL_EXT_packed_float
+ GL_R11F_G11F_B10F_EXT = $8C3A;
+ GL_UNSIGNED_INT_10F_11F_11F_REV_EXT = $8C3B;
+ RGBA_SIGNED_COMPONENTS_EXT = $8C3C;
+ WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT = $20A8;
+ GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT = $20B1;
+ GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT = $00000008;
+
+ // GL_EXT_texture_array
+ GL_TEXTURE_1D_ARRAY_EXT = $8C18;
+ GL_TEXTURE_2D_ARRAY_EXT = $8C1A;
+ GL_PROXY_TEXTURE_2D_ARRAY_EXT = $8C1B;
+ GL_PROXY_TEXTURE_1D_ARRAY_EXT = $8C19;
+ GL_TEXTURE_BINDING_1D_ARRAY_EXT = $8C1C;
+ GL_TEXTURE_BINDING_2D_ARRAY_EXT = $8C1D;
+ GL_MAX_ARRAY_TEXTURE_LAYERS_EXT = $88FF;
+ GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT = $884E;
+
+ // GL_EXT_texture_buffer_object
+ GL_TEXTURE_BUFFER_EXT = $8C2A;
+ GL_MAX_TEXTURE_BUFFER_SIZE_EXT = $8C2B;
+ GL_TEXTURE_BINDING_BUFFER_EXT = $8C2C;
+ GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT = $8C2D;
+ GL_TEXTURE_BUFFER_FORMAT_EXT = $8C2E;
+
+ // GL_EXT_texture_compression_latc
+ GL_COMPRESSED_LUMINANCE_LATC1_EXT = $8C70;
+ GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT = $8C71;
+ GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT = $8C72;
+ GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT = $8C73;
+
+ // GL_EXT_texture_compression_rgtc
+ GL_COMPRESSED_RED_RGTC1_EXT = $8DBB;
+ GL_COMPRESSED_SIGNED_RED_RGTC1_EXT = $8DBC;
+ GL_COMPRESSED_RED_GREEN_RGTC2_EXT = $8DBD;
+ GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = $8DBE;
+
+ // GL_EXT_texture_integer
+ GL_RGBA_INTEGER_MODE_EXT = $8D9E;
+ GL_RGBA32UI_EXT = $8D70;
+ GL_RGB32UI_EXT = $8D71;
+ GL_ALPHA32UI_EXT = $8D72;
+ GL_INTENSITY32UI_EXT = $8D73;
+ GL_LUMINANCE32UI_EXT = $8D74;
+ GL_LUMINANCE_ALPHA32UI_EXT = $8D75;
+ GL_RGBA16UI_EXT = $8D76;
+ GL_RGB16UI_EXT = $8D77;
+ GL_ALPHA16UI_EXT = $8D78;
+ GL_INTENSITY16UI_EXT = $8D79;
+ GL_LUMINANCE16UI_EXT = $8D7A;
+ GL_LUMINANCE_ALPHA16UI_EXT = $8D7B;
+ GL_RGBA8UI_EXT = $8D7C;
+ GL_RGB8UI_EXT = $8D7D;
+ GL_ALPHA8UI_EXT = $8D7E;
+ GL_INTENSITY8UI_EXT = $8D7F;
+ GL_LUMINANCE8UI_EXT = $8D80;
+ GL_LUMINANCE_ALPHA8UI_EXT = $8D81;
+ GL_RGBA32I_EXT = $8D82;
+ GL_RGB32I_EXT = $8D83;
+ GL_ALPHA32I_EXT = $8D84;
+ GL_INTENSITY32I_EXT = $8D85;
+ GL_LUMINANCE32I_EXT = $8D86;
+ GL_LUMINANCE_ALPHA32I_EXT = $8D87;
+ GL_RGBA16I_EXT = $8D88;
+ GL_RGB16I_EXT = $8D89;
+ GL_ALPHA16I_EXT = $8D8A;
+ GL_INTENSITY16I_EXT = $8D8B;
+ GL_LUMINANCE16I_EXT = $8D8C;
+ GL_LUMINANCE_ALPHA16I_EXT = $8D8D;
+ GL_RGBA8I_EXT = $8D8E;
+ GL_RGB8I_EXT = $8D8F;
+ GL_ALPHA8I_EXT = $8D90;
+ GL_INTENSITY8I_EXT = $8D91;
+ GL_LUMINANCE8I_EXT = $8D92;
+ GL_LUMINANCE_ALPHA8I_EXT = $8D93;
+ GL_RED_INTEGER_EXT = $8D94;
+ GL_GREEN_INTEGER_EXT = $8D95;
+ GL_BLUE_INTEGER_EXT = $8D96;
+ GL_ALPHA_INTEGER_EXT = $8D97;
+ GL_RGB_INTEGER_EXT = $8D98;
+ GL_RGBA_INTEGER_EXT = $8D99;
+ GL_BGR_INTEGER_EXT = $8D9A;
+ GL_BGRA_INTEGER_EXT = $8D9B;
+ GL_LUMINANCE_INTEGER_EXT = $8D9C;
+ GL_LUMINANCE_ALPHA_INTEGER_EXT = $8D9D;
+
+ // GL_EXT_texture_shared_exponent
+ GL_RGB9_E5_EXT = $8C3D;
+ GL_UNSIGNED_INT_5_9_9_9_REV_EXT = $8C3E;
+ GL_TEXTURE_SHARED_SIZE_EXT = $8C3F;
+
+ // GL_EXT_transform_feedback
+ GL_TRANSFORM_FEEDBACK_BUFFER_EXT = $8C8E;
+ GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT = $8C84;
+ GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT = $8C85;
+ GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT = $8C8F;
+ GL_INTERLEAVED_ATTRIBS_EXT = $8C8C;
+ GL_SEPARATE_ATTRIBS_EXT = $8C8D;
+ GL_PRIMITIVES_GENERATED_EXT = $8C87;
+ GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT = $8C88;
+ GL_RASTERIZER_DISCARD_EXT = $8C89;
+ GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT = $8C8A;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT = $8C8B;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT = $8C80;
+ GL_TRANSFORM_FEEDBACK_VARYINGS_EXT = $8C83;
+ GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT = $8C7F;
+ GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT = $8C76;
+
+ // GL_EXT_direct_state_access
+ GL_PROGRAM_MATRIX_EXT = $8E2D;
+ GL_TRANSPOSE_PROGRAM_MATRIX_EXT = $8E2E;
+ GL_PROGRAM_MATRIX_STACK_DEPTH_EXT = $8E2F;
+
+ // GL_EXT_texture_swizzle
+ GL_TEXTURE_SWIZZLE_R_EXT = $8E42;
+ GL_TEXTURE_SWIZZLE_G_EXT = $8E43;
+ GL_TEXTURE_SWIZZLE_B_EXT = $8E44;
+ GL_TEXTURE_SWIZZLE_A_EXT = $8E45;
+ GL_TEXTURE_SWIZZLE_RGBA_EXT = $8E46;
+
+ // GL_EXT_provoking_vertex
+ GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT = $8E4C;
+ GL_FIRST_VERTEX_CONVENTION_EXT = $8E4D;
+ GL_LAST_VERTEX_CONVENTION_EXT = $8E4E;
+ GL_PROVOKING_VERTEX_EXT = $8E4F;
+
+ // GL_EXT_texture_snorm
+ GL_ALPHA_SNORM = $9010;
+ GL_LUMINANCE_SNORM = $9011;
+ GL_LUMINANCE_ALPHA_SNORM = $9012;
+ GL_INTENSITY_SNORM = $9013;
+ GL_ALPHA8_SNORM = $9014;
+ GL_LUMINANCE8_SNORM = $9015;
+ GL_LUMINANCE8_ALPHA8_SNORM = $9016;
+ GL_INTENSITY8_SNORM = $9017;
+ GL_ALPHA16_SNORM = $9018;
+ GL_LUMINANCE16_SNORM = $9019;
+ GL_LUMINANCE16_ALPHA16_SNORM = $901A;
+ GL_INTENSITY16_SNORM = $901B;
+ { reuse GL_RED_SNORM }
+ { reuse GL_RG_SNORM }
+ { reuse GL_RGB_SNORM }
+ { reuse GL_RGBA_SNORM }
+ { reuse GL_R8_SNORM }
+ { reuse GL_RG8_SNORM }
+ { reuse GL_RGB8_SNORM }
+ { reuse GL_RGBA8_SNORM }
+ { reuse GL_R16_SNORM }
+ { reuse GL_RG16_SNORM }
+ { reuse GL_RGB16_SNORM }
+ { reuse GL_RGBA16_SNORM }
+ { reuse GL_SIGNED_NORMALIZED }
+
+ // GL_EXT_separate_shader_objects
+ GL_ACTIVE_PROGRAM_EXT = $8B8D;
+
+ // GL_EXT_shader_image_load_store
+ GL_MAX_IMAGE_UNITS_EXT = $8F38;
+ GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT = $8F39;
+ GL_IMAGE_BINDING_NAME_EXT = $8F3A;
+ GL_IMAGE_BINDING_LEVEL_EXT = $8F3B;
+ GL_IMAGE_BINDING_LAYERED_EXT = $8F3C;
+ GL_IMAGE_BINDING_LAYER_EXT = $8F3D;
+ GL_IMAGE_BINDING_ACCESS_EXT = $8F3E;
+ GL_IMAGE_1D_EXT = $904C;
+ GL_IMAGE_2D_EXT = $904D;
+ GL_IMAGE_3D_EXT = $904E;
+ GL_IMAGE_2D_RECT_EXT = $904F;
+ GL_IMAGE_CUBE_EXT = $9050;
+ GL_IMAGE_BUFFER_EXT = $9051;
+ GL_IMAGE_1D_ARRAY_EXT = $9052;
+ GL_IMAGE_2D_ARRAY_EXT = $9053;
+ GL_IMAGE_CUBE_MAP_ARRAY_EXT = $9054;
+ GL_IMAGE_2D_MULTISAMPLE_EXT = $9055;
+ GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = $9056;
+ GL_INT_IMAGE_1D_EXT = $9057;
+ GL_INT_IMAGE_2D_EXT = $9058;
+ GL_INT_IMAGE_3D_EXT = $9059;
+ GL_INT_IMAGE_2D_RECT_EXT = $905A;
+ GL_INT_IMAGE_CUBE_EXT = $905B;
+ GL_INT_IMAGE_BUFFER_EXT = $905C;
+ GL_INT_IMAGE_1D_ARRAY_EXT = $905D;
+ GL_INT_IMAGE_2D_ARRAY_EXT = $905E;
+ GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT = $905F;
+ GL_INT_IMAGE_2D_MULTISAMPLE_EXT = $9060;
+ GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = $9061;
+ GL_UNSIGNED_INT_IMAGE_1D_EXT = $9062;
+ GL_UNSIGNED_INT_IMAGE_2D_EXT = $9063;
+ GL_UNSIGNED_INT_IMAGE_3D_EXT = $9064;
+ GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT = $9065;
+ GL_UNSIGNED_INT_IMAGE_CUBE_EXT = $9066;
+ GL_UNSIGNED_INT_IMAGE_BUFFER_EXT = $9067;
+ GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT = $9068;
+ GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT = $9069;
+ GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT = $906A;
+ GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT = $906B;
+ GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = $906C;
+ GL_MAX_IMAGE_SAMPLES_EXT = $906D;
+ GL_IMAGE_BINDING_FORMAT_EXT = $906E;
+ GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT = $00000001;
+ GL_ELEMENT_ARRAY_BARRIER_BIT_EXT = $00000002;
+ GL_UNIFORM_BARRIER_BIT_EXT = $00000004;
+ GL_TEXTURE_FETCH_BARRIER_BIT_EXT = $00000008;
+ GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT = $00000020;
+ GL_COMMAND_BARRIER_BIT_EXT = $00000040;
+ GL_PIXEL_BUFFER_BARRIER_BIT_EXT = $00000080;
+ GL_TEXTURE_UPDATE_BARRIER_BIT_EXT = $00000100;
+ GL_BUFFER_UPDATE_BARRIER_BIT_EXT = $00000200;
+ GL_FRAMEBUFFER_BARRIER_BIT_EXT = $00000400;
+ GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT = $00000800;
+ GL_ATOMIC_COUNTER_BARRIER_BIT_EXT = $00001000;
+ GL_ALL_BARRIER_BITS_EXT = $FFFFFFFF;
+
+ // GL_EXT_vertex_attrib_64bit
+ { reuse GL_DOUBLE }
+ GL_DOUBLE_VEC2_EXT = $8FFC;
+ GL_DOUBLE_VEC3_EXT = $8FFD;
+ GL_DOUBLE_VEC4_EXT = $8FFE;
+ GL_DOUBLE_MAT2_EXT = $8F46;
+ GL_DOUBLE_MAT3_EXT = $8F47;
+ GL_DOUBLE_MAT4_EXT = $8F48;
+ GL_DOUBLE_MAT2x3_EXT = $8F49;
+ GL_DOUBLE_MAT2x4_EXT = $8F4A;
+ GL_DOUBLE_MAT3x2_EXT = $8F4B;
+ GL_DOUBLE_MAT3x4_EXT = $8F4C;
+ GL_DOUBLE_MAT4x2_EXT = $8F4D;
+ GL_DOUBLE_MAT4x3_EXT = $8F4E;
+
+ // GL_EXT_texture_sRGB_decode
+ GL_TEXTURE_SRGB_DECODE_EXT = $8A48;
+ GL_DECODE_EXT = $8A49;
+ GL_SKIP_DECODE_EXT = $8A4A;
+
+ // GL_NV_texture_multisample
+ GL_TEXTURE_COVERAGE_SAMPLES_NV = $9045;
+ GL_TEXTURE_COLOR_SAMPLES_NV = $9046;
+
+ // GL_AMD_blend_minmax_factor
+ GL_FACTOR_MIN_AMD = $901C;
+ GL_FACTOR_MAX_AMD = $901D;
+
+ // GL_AMD_sample_positions
+ GL_SUBSAMPLE_DISTANCE_AMD = $883F;
+
+ // GL_EXT_x11_sync_object
+ GL_SYNC_X11_FENCE_EXT = $90E1;
+
+ // GL_EXT_framebuffer_multisample_blit_scaled
+ GL_SCALED_RESOLVE_FASTEST_EXT = $90BA;
+ GL_SCALED_RESOLVE_NICEST_EXT = $90BB;
+
+ // (4.3) GL_NV_path_rendering
+ GL_PATH_FORMAT_SVG_NV = $9070;
+ GL_PATH_FORMAT_PS_NV = $9071;
+ GL_STANDARD_FONT_NAME_NV = $9072;
+ GL_SYSTEM_FONT_NAME_NV = $9073;
+ GL_FILE_NAME_NV = $9074;
+ GL_PATH_STROKE_WIDTH_NV = $9075;
+ GL_PATH_END_CAPS_NV = $9076;
+ GL_PATH_INITIAL_END_CAP_NV = $9077;
+ GL_PATH_TERMINAL_END_CAP_NV = $9078;
+ GL_PATH_JOIN_STYLE_NV = $9079;
+ GL_PATH_MITER_LIMIT_NV = $907A;
+ GL_PATH_DASH_CAPS_NV = $907B;
+ GL_PATH_INITIAL_DASH_CAP_NV = $907C;
+ GL_PATH_TERMINAL_DASH_CAP_NV = $907D;
+ GL_PATH_DASH_OFFSET_NV = $907E;
+ GL_PATH_CLIENT_LENGTH_NV = $907F;
+ GL_PATH_FILL_MODE_NV = $9080;
+ GL_PATH_FILL_MASK_NV = $9081;
+ GL_PATH_FILL_COVER_MODE_NV = $9082;
+ GL_PATH_STROKE_COVER_MODE_NV = $9083;
+ GL_PATH_STROKE_MASK_NV = $9084;
+ GL_PATH_SAMPLE_QUALITY_NV = $9085;
+ GL_PATH_STROKE_BOUND_NV = $9086;
+ GL_PATH_STROKE_OVERSAMPLE_COUNT_NV= $9087;
+ GL_COUNT_UP_NV = $9088;
+ GL_COUNT_DOWN_NV = $9089;
+ GL_PATH_OBJECT_BOUNDING_BOX_NV = $908A;
+ GL_CONVEX_HULL_NV = $908B;
+ GL_MULTI_HULLS_NV = $908C;
+ GL_BOUNDING_BOX_NV = $908D;
+ GL_TRANSLATE_X_NV = $908E;
+ GL_TRANSLATE_Y_NV = $908F;
+ GL_TRANSLATE_2D_NV = $9090;
+ GL_TRANSLATE_3D_NV = $9091;
+ GL_AFFINE_2D_NV = $9092;
+ GL_PROJECTIVE_2D_NV = $9093;
+ GL_AFFINE_3D_NV = $9094;
+ GL_PROJECTIVE_3D_NV = $9095;
+ GL_TRANSPOSE_AFFINE_2D_NV = $9096;
+ GL_TRANSPOSE_PROJECTIVE_2D_NV = $9097;
+ GL_TRANSPOSE_AFFINE_3D_NV = $9098;
+ GL_TRANSPOSE_PROJECTIVE_3D_NV = $9099;
+ GL_UTF8_NV = $909A;
+ GL_UTF16_NV = $909B;
+ GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV= $909C;
+ GL_PATH_COMMAND_COUNT_NV = $909D;
+ GL_PATH_COORD_COUNT_NV = $909E;
+ GL_PATH_DASH_ARRAY_COUNT_NV = $909F;
+ GL_PATH_COMPUTED_LENGTH_NV = $90A0;
+ GL_PATH_FILL_BOUNDING_BOX_NV = $90A1;
+ GL_PATH_STROKE_BOUNDING_BOX_NV = $90A2;
+ GL_SQUARE_NV = $90A3;
+ GL_ROUND_NV = $90A4;
+ GL_TRIANGULAR_NV = $90A5;
+ GL_BEVEL_NV = $90A6;
+ GL_MITER_REVERT_NV = $90A7;
+ GL_MITER_TRUNCATE_NV = $90A8;
+ GL_SKIP_MISSING_GLYPH_NV = $90A9;
+ GL_USE_MISSING_GLYPH_NV = $90AA;
+ GL_PATH_ERROR_POSITION_NV = $90AB;
+ GL_PATH_FOG_GEN_MODE_NV = $90AC;
+ GL_ACCUM_ADJACENT_PAIRS_NV = $90AD;
+ GL_ADJACENT_PAIRS_NV = $90AE;
+ GL_FIRST_TO_REST_NV = $90AF;
+ GL_PATH_GEN_MODE_NV = $90B0;
+ GL_PATH_GEN_COEFF_NV = $90B1;
+ GL_PATH_GEN_COLOR_FORMAT_NV = $90B2;
+ GL_PATH_GEN_COMPONENTS_NV = $90B3;
+ GL_PATH_STENCIL_FUNC_NV = $90B7;
+ GL_PATH_STENCIL_REF_NV = $90B8;
+ GL_PATH_STENCIL_VALUE_MASK_NV = $90B9;
+ GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV= $90BD;
+ GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV= $90BE;
+ GL_PATH_COVER_DEPTH_FUNC_NV = $90BF;
+ GL_PATH_DASH_OFFSET_RESET_NV = $90B4;
+ GL_MOVE_TO_RESETS_NV = $90B5;
+ GL_MOVE_TO_CONTINUES_NV = $90B6;
+ GL_CLOSE_PATH_NV = $00;
+ GL_MOVE_TO_NV = $02;
+ GL_RELATIVE_MOVE_TO_NV = $03;
+ GL_LINE_TO_NV = $04;
+ GL_RELATIVE_LINE_TO_NV = $05;
+ GL_HORIZONTAL_LINE_TO_NV = $06;
+ GL_RELATIVE_HORIZONTAL_LINE_TO_NV= $07;
+ GL_VERTICAL_LINE_TO_NV = $08;
+ GL_RELATIVE_VERTICAL_LINE_TO_NV = $09;
+ GL_QUADRATIC_CURVE_TO_NV = $0A;
+ GL_RELATIVE_QUADRATIC_CURVE_TO_NV= $0B;
+ GL_CUBIC_CURVE_TO_NV = $0C;
+ GL_RELATIVE_CUBIC_CURVE_TO_NV = $0D;
+ GL_SMOOTH_QUADRATIC_CURVE_TO_NV = $0E;
+ GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV= $0F;
+ GL_SMOOTH_CUBIC_CURVE_TO_NV = $10;
+ GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV= $11;
+ GL_SMALL_CCW_ARC_TO_NV = $12;
+ GL_RELATIVE_SMALL_CCW_ARC_TO_NV = $13;
+ GL_SMALL_CW_ARC_TO_NV = $14;
+ GL_RELATIVE_SMALL_CW_ARC_TO_NV = $15;
+ GL_LARGE_CCW_ARC_TO_NV = $16;
+ GL_RELATIVE_LARGE_CCW_ARC_TO_NV = $17;
+ GL_LARGE_CW_ARC_TO_NV = $18;
+ GL_RELATIVE_LARGE_CW_ARC_TO_NV = $19;
+ GL_RESTART_PATH_NV = $F0;
+ GL_DUP_FIRST_CUBIC_CURVE_TO_NV = $F2;
+ GL_DUP_LAST_CUBIC_CURVE_TO_NV = $F4;
+ GL_RECT_NV = $F6;
+ GL_CIRCULAR_CCW_ARC_TO_NV = $F8;
+ GL_CIRCULAR_CW_ARC_TO_NV = $FA;
+ GL_CIRCULAR_TANGENT_ARC_TO_NV = $FC;
+ GL_ARC_TO_NV = $FE;
+ GL_RELATIVE_ARC_TO_NV = $FF;
+ GL_BOLD_BIT_NV = $01;
+ GL_ITALIC_BIT_NV = $02;
+ GL_GLYPH_WIDTH_BIT_NV = $01;
+ GL_GLYPH_HEIGHT_BIT_NV = $02;
+ GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV= $04;
+ GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV= $08;
+ GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV= $10;
+ GL_GLYPH_VERTICAL_BEARING_X_BIT_NV= $20;
+ GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV= $40;
+ GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV= $80;
+ GL_GLYPH_HAS_KERNING_NV = $100;
+ GL_FONT_X_MIN_BOUNDS_NV = $00010000;
+ GL_FONT_Y_MIN_BOUNDS_NV = $00020000;
+ GL_FONT_X_MAX_BOUNDS_NV = $00040000;
+ GL_FONT_Y_MAX_BOUNDS_NV = $00080000;
+ GL_FONT_UNITS_PER_EM_NV = $00100000;
+ GL_FONT_ASCENDER_NV = $00200000;
+ GL_FONT_DESCENDER_NV = $00400000;
+ GL_FONT_HEIGHT_NV = $00800000;
+ GL_FONT_MAX_ADVANCE_WIDTH_NV = $01000000;
+ GL_FONT_MAX_ADVANCE_HEIGHT_NV = $02000000;
+ GL_FONT_UNDERLINE_POSITION_NV = $04000000;
+ GL_FONT_UNDERLINE_THICKNESS_NV = $08000000;
+ GL_FONT_HAS_KERNING_NV = $10000000;
+
+ // (4.3) GL_AMD_pinned_memory
+ GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD= $9160;
+
+ // (4.3) GL_AMD_stencil_operation_extended
+ GL_SET_AMD = $874A;
+ GL_REPLACE_VALUE_AMD = $874B;
+ GL_STENCIL_OP_VALUE_AMD = $874C;
+ GL_STENCIL_BACK_OP_VALUE_AMD = $874D;
+
+ // (4.3) GL_AMD_vertex_shader_viewport_index
+
+ // (4.3) GL_AMD_vertex_shader_layer
+
+ // (4.3) GL_NV_bindless_texture
+
+ // (4.3) GL_NV_shader_atomic_float
+
+ // (4.3) GL_AMD_query_buffer_object
+ GL_QUERY_BUFFER_AMD = $9192;
+ GL_QUERY_BUFFER_BINDING_AMD = $9193;
+ GL_QUERY_RESULT_NO_WAIT_AMD = $9194;
+
+ // GL_FfdMaskSGIX
+ GL_TEXTURE_DEFORMATION_BIT_SGIX = $00000001;
+ GL_GEOMETRY_DEFORMATION_BIT_SGIX = $00000002;
+
+ // GL_HP_convolution_border_modes
+ GL_IGNORE_BORDER_HP = $8150;
+ GL_CONSTANT_BORDER_HP = $8151;
+ GL_REPLICATE_BORDER_HP = $8153;
+ GL_CONVOLUTION_BORDER_COLOR_HP = $8154;
+
+ // GL_HP_image_transform
+ GL_IMAGE_SCALE_X_HP = $8155;
+ GL_IMAGE_SCALE_Y_HP = $8156;
+ GL_IMAGE_TRANSLATE_X_HP = $8157;
+ GL_IMAGE_TRANSLATE_Y_HP = $8158;
+ GL_IMAGE_ROTATE_ANGLE_HP = $8159;
+ GL_IMAGE_ROTATE_ORIGIN_X_HP = $815A;
+ GL_IMAGE_ROTATE_ORIGIN_Y_HP = $815B;
+ GL_IMAGE_MAG_FILTER_HP = $815C;
+ GL_IMAGE_MIN_FILTER_HP = $815D;
+ GL_IMAGE_CUBIC_WEIGHT_HP = $815E;
+ GL_CUBIC_HP = $815F;
+ GL_AVERAGE_HP = $8160;
+ GL_IMAGE_TRANSFORM_2D_HP = $8161;
+ GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = $8162;
+ GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = $8163;
+
+ // GL_HP_occlusion_test
+ GL_OCCLUSION_TEST_HP = $8165;
+ GL_OCCLUSION_TEST_RESULT_HP = $8166;
+
+ // GL_HP_texture_lighting
+ GL_TEXTURE_LIGHTING_MODE_HP = $8167;
+ GL_TEXTURE_POST_SPECULAR_HP = $8168;
+ GL_TEXTURE_PRE_SPECULAR_HP = $8169;
+
+ // GL_IBM_cull_vertex
+ GL_CULL_VERTEX_IBM = 103050;
+
+ // GL_IBM_rasterpos_clip
+ GL_RASTER_POSITION_UNCLIPPED_IBM = $19262;
+
+ // GL_IBM_texture_mirrored_repeat
+ GL_MIRRORED_REPEAT_IBM = $8370;
+
+ // GL_IBM_vertex_array_lists
+ GL_VERTEX_ARRAY_LIST_IBM = 103070;
+ GL_NORMAL_ARRAY_LIST_IBM = 103071;
+ GL_COLOR_ARRAY_LIST_IBM = 103072;
+ GL_INDEX_ARRAY_LIST_IBM = 103073;
+ GL_TEXTURE_COORD_ARRAY_LIST_IBM = 103074;
+ GL_EDGE_FLAG_ARRAY_LIST_IBM = 103075;
+ GL_FOG_COORDINATE_ARRAY_LIST_IBM = 103076;
+ GL_SECONDARY_COLOR_ARRAY_LIST_IBM = 103077;
+ GL_VERTEX_ARRAY_LIST_STRIDE_IBM = 103080;
+ GL_NORMAL_ARRAY_LIST_STRIDE_IBM = 103081;
+ GL_COLOR_ARRAY_LIST_STRIDE_IBM = 103082;
+ GL_INDEX_ARRAY_LIST_STRIDE_IBM = 103083;
+ GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = 103084;
+ GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = 103085;
+ GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = 103086;
+ GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = 103087;
+
+ // GL_INGR_color_clamp
+ GL_RED_MIN_CLAMP_INGR = $8560;
+ GL_GREEN_MIN_CLAMP_INGR = $8561;
+ GL_BLUE_MIN_CLAMP_INGR = $8562;
+ GL_ALPHA_MIN_CLAMP_INGR = $8563;
+ GL_RED_MAX_CLAMP_INGR = $8564;
+ GL_GREEN_MAX_CLAMP_INGR = $8565;
+ GL_BLUE_MAX_CLAMP_INGR = $8566;
+ GL_ALPHA_MAX_CLAMP_INGR = $8567;
+
+ // GL_INGR_interlace_read
+ GL_INTERLACE_READ_INGR = $8568;
+
+ // GL_INTEL_parallel_arrays
+ GL_PARALLEL_ARRAYS_INTEL = $83F4;
+ GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL = $83F5;
+ GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL = $83F6;
+ GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL = $83F7;
+ GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL = $83F8;
+
+ // GL_NV_copy_depth_to_color
+ GL_DEPTH_STENCIL_TO_RGBA_NV = $886E;
+ GL_DEPTH_STENCIL_TO_BGRA_NV = $886F;
+
+ // GL_NV_depth_clamp
+ GL_DEPTH_CLAMP_NV = $864F;
+
+ // GL_NV_evaluators
+ GL_EVAL_2D_NV = $86C0;
+ GL_EVAL_TRIANGULAR_2D_NV = $86C1;
+ GL_MAP_TESSELLATION_NV = $86C2;
+ GL_MAP_ATTRIB_U_ORDER_NV = $86C3;
+ GL_MAP_ATTRIB_V_ORDER_NV = $86C4;
+ GL_EVAL_FRACTIONAL_TESSELLATION_NV = $86C5;
+ GL_EVAL_VERTEX_ATTRIB0_NV = $86C6;
+ GL_EVAL_VERTEX_ATTRIB1_NV = $86C7;
+ GL_EVAL_VERTEX_ATTRIB2_NV = $86C8;
+ GL_EVAL_VERTEX_ATTRIB3_NV = $86C9;
+ GL_EVAL_VERTEX_ATTRIB4_NV = $86CA;
+ GL_EVAL_VERTEX_ATTRIB5_NV = $86CB;
+ GL_EVAL_VERTEX_ATTRIB6_NV = $86CC;
+ GL_EVAL_VERTEX_ATTRIB7_NV = $86CD;
+ GL_EVAL_VERTEX_ATTRIB8_NV = $86CE;
+ GL_EVAL_VERTEX_ATTRIB9_NV = $86CF;
+ GL_EVAL_VERTEX_ATTRIB10_NV = $86D0;
+ GL_EVAL_VERTEX_ATTRIB11_NV = $86D1;
+ GL_EVAL_VERTEX_ATTRIB12_NV = $86D2;
+ GL_EVAL_VERTEX_ATTRIB13_NV = $86D3;
+ GL_EVAL_VERTEX_ATTRIB14_NV = $86D4;
+ GL_EVAL_VERTEX_ATTRIB15_NV = $86D5;
+ GL_MAX_MAP_TESSELLATION_NV = $86D6;
+ GL_MAX_RATIONAL_EVAL_ORDER_NV = $86D7;
+
+ // GL_NV_fence
+ GL_ALL_COMPLETED_NV = $84F2;
+ GL_FENCE_STATUS_NV = $84F3;
+ GL_FENCE_CONDITION_NV = $84F4;
+
+ // GL_NV_float_buffer
+ GL_FLOAT_R_NV = $8880;
+ GL_FLOAT_RG_NV = $8881;
+ GL_FLOAT_RGB_NV = $8882;
+ GL_FLOAT_RGBA_NV = $8883;
+ GL_FLOAT_R16_NV = $8884;
+ GL_FLOAT_R32_NV = $8885;
+ GL_FLOAT_RG16_NV = $8886;
+ GL_FLOAT_RG32_NV = $8887;
+ GL_FLOAT_RGB16_NV = $8888;
+ GL_FLOAT_RGB32_NV = $8889;
+ GL_FLOAT_RGBA16_NV = $888A;
+ GL_FLOAT_RGBA32_NV = $888B;
+ GL_TEXTURE_FLOAT_COMPONENTS_NV = $888C;
+ GL_FLOAT_CLEAR_COLOR_VALUE_NV = $888D;
+ GL_FLOAT_RGBA_MODE_NV = $888E;
+
+ // GL_NV_fog_distance
+ GL_FOG_DISTANCE_MODE_NV = $855A;
+ GL_EYE_RADIAL_NV = $855B;
+ GL_EYE_PLANE_ABSOLUTE_NV = $855C;
+
+ // GL_NV_fragment_program
+ GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = $8868;
+ GL_FRAGMENT_PROGRAM_NV = $8870;
+ GL_MAX_TEXTURE_COORDS_NV = $8871;
+ GL_MAX_TEXTURE_IMAGE_UNITS_NV = $8872;
+ GL_FRAGMENT_PROGRAM_BINDING_NV = $8873;
+ GL_PROGRAM_ERROR_STRING_NV = $8874;
+
+ // GL_NV_half_float
+ GL_HALF_FLOAT_NV = $140B;
+
+ // GL_NV_light_max_exponent
+ GL_MAX_SHININESS_NV = $8504;
+ GL_MAX_SPOT_EXPONENT_NV = $8505;
+
+ // GL_NV_multisample_filter_hint
+ GL_MULTISAMPLE_FILTER_HINT_NV = $8534;
+
+ // GL_NV_occlusion_query
+ GL_PIXEL_COUNTER_BITS_NV = $8864;
+ GL_CURRENT_OCCLUSION_QUERY_ID_NV = $8865;
+ GL_PIXEL_COUNT_NV = $8866;
+ GL_PIXEL_COUNT_AVAILABLE_NV = $8867;
+
+ // GL_NV_packed_depth_stencil
+ GL_DEPTH_STENCIL_NV = $84F9;
+ GL_UNSIGNED_INT_24_8_NV = $84FA;
+
+ // GL_NV_pixel_data_range
+ GL_WRITE_PIXEL_DATA_RANGE_NV = $8878;
+ GL_READ_PIXEL_DATA_RANGE_NV = $8879;
+ GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = $887A;
+ GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = $887B;
+ GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = $887C;
+ GL_READ_PIXEL_DATA_RANGE_POINTER_NV = $887D;
+
+ // GL_NV_point_sprite
+ GL_POINT_SPRITE_NV = $8861;
+ GL_COORD_REPLACE_NV = $8862;
+ GL_POINT_SPRITE_R_MODE_NV = $8863;
+
+ // GL_NV_primitive_restart
+ GL_PRIMITIVE_RESTART_NV = $8558;
+ GL_PRIMITIVE_RESTART_INDEX_NV = $8559;
+
+ // GL_NV_register_combiners
+ GL_REGISTER_COMBINERS_NV = $8522;
+ GL_VARIABLE_A_NV = $8523;
+ GL_VARIABLE_B_NV = $8524;
+ GL_VARIABLE_C_NV = $8525;
+ GL_VARIABLE_D_NV = $8526;
+ GL_VARIABLE_E_NV = $8527;
+ GL_VARIABLE_F_NV = $8528;
+ GL_VARIABLE_G_NV = $8529;
+ GL_CONSTANT_COLOR0_NV = $852A;
+ GL_CONSTANT_COLOR1_NV = $852B;
+ GL_PRIMARY_COLOR_NV = $852C;
+ GL_SECONDARY_COLOR_NV = $852D;
+ GL_SPARE0_NV = $852E;
+ GL_SPARE1_NV = $852F;
+ GL_DISCARD_NV = $8530;
+ GL_E_TIMES_F_NV = $8531;
+ GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532;
+ GL_UNSIGNED_IDENTITY_NV = $8536;
+ GL_UNSIGNED_INVERT_NV = $8537;
+ GL_EXPAND_NORMAL_NV = $8538;
+ GL_EXPAND_NEGATE_NV = $8539;
+ GL_HALF_BIAS_NORMAL_NV = $853A;
+ GL_HALF_BIAS_NEGATE_NV = $853B;
+ GL_SIGNED_IDENTITY_NV = $853C;
+ GL_SIGNED_NEGATE_NV = $853D;
+ GL_SCALE_BY_TWO_NV = $853E;
+ GL_SCALE_BY_FOUR_NV = $853F;
+ GL_SCALE_BY_ONE_HALF_NV = $8540;
+ GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541;
+ GL_COMBINER_INPUT_NV = $8542;
+ GL_COMBINER_MAPPING_NV = $8543;
+ GL_COMBINER_COMPONENT_USAGE_NV = $8544;
+ GL_COMBINER_AB_DOT_PRODUCT_NV = $8545;
+ GL_COMBINER_CD_DOT_PRODUCT_NV = $8546;
+ GL_COMBINER_MUX_SUM_NV = $8547;
+ GL_COMBINER_SCALE_NV = $8548;
+ GL_COMBINER_BIAS_NV = $8549;
+ GL_COMBINER_AB_OUTPUT_NV = $854A;
+ GL_COMBINER_CD_OUTPUT_NV = $854B;
+ GL_COMBINER_SUM_OUTPUT_NV = $854C;
+ GL_MAX_GENERAL_COMBINERS_NV = $854D;
+ GL_NUM_GENERAL_COMBINERS_NV = $854E;
+ GL_COLOR_SUM_CLAMP_NV = $854F;
+ GL_COMBINER0_NV = $8550;
+ GL_COMBINER1_NV = $8551;
+ GL_COMBINER2_NV = $8552;
+ GL_COMBINER3_NV = $8553;
+ GL_COMBINER4_NV = $8554;
+ GL_COMBINER5_NV = $8555;
+ GL_COMBINER6_NV = $8556;
+ GL_COMBINER7_NV = $8557;
+
+ // GL_NV_register_combiners2
+ GL_PER_STAGE_CONSTANTS_NV = $8535;
+
+ // GL_NV_texgen_emboss
+ GL_EMBOSS_LIGHT_NV = $855D;
+ GL_EMBOSS_CONSTANT_NV = $855E;
+ GL_EMBOSS_MAP_NV = $855F;
+
+ // GL_NV_texgen_reflection
+ GL_NORMAL_MAP_NV = $8511;
+ GL_REFLECTION_MAP_NV = $8512;
+
+ // GL_NV_texture_env_combine4
+ GL_COMBINE4_NV = $8503;
+ GL_SOURCE3_RGB_NV = $8583;
+ GL_SOURCE3_ALPHA_NV = $858B;
+ GL_OPERAND3_RGB_NV = $8593;
+ GL_OPERAND3_ALPHA_NV = $859B;
+
+ // GL_NV_texture_expand_normal
+ GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = $888F;
+
+ // GL_NV_texture_rectangle
+ GL_TEXTURE_RECTANGLE_NV = $84F5;
+ GL_TEXTURE_BINDING_RECTANGLE_NV = $84F6;
+ GL_PROXY_TEXTURE_RECTANGLE_NV = $84F7;
+ GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = $84F8;
+
+ // GL_NV_texture_shader
+ GL_OFFSET_TEXTURE_RECTANGLE_NV = $864C;
+ GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = $864D;
+ GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = $864E;
+ GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = $86D9;
+ GL_UNSIGNED_INT_S8_S8_8_8_NV = $86DA;
+ GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = $86DB;
+ GL_DSDT_MAG_INTENSITY_NV = $86DC;
+ GL_SHADER_CONSISTENT_NV = $86DD;
+ GL_TEXTURE_SHADER_NV = $86DE;
+ GL_SHADER_OPERATION_NV = $86DF;
+ GL_CULL_MODES_NV = $86E0;
+ GL_OFFSET_TEXTURE_MATRIX_NV = $86E1;
+ GL_OFFSET_TEXTURE_SCALE_NV = $86E2;
+ GL_OFFSET_TEXTURE_BIAS_NV = $86E3;
+ GL_OFFSET_TEXTURE_2D_MATRIX_NV = GL_OFFSET_TEXTURE_MATRIX_NV;
+ GL_OFFSET_TEXTURE_2D_SCALE_NV = GL_OFFSET_TEXTURE_SCALE_NV;
+ GL_OFFSET_TEXTURE_2D_BIAS_NV = GL_OFFSET_TEXTURE_BIAS_NV;
+ GL_PREVIOUS_TEXTURE_INPUT_NV = $86E4;
+ GL_CONST_EYE_NV = $86E5;
+ GL_PASS_THROUGH_NV = $86E6;
+ GL_CULL_FRAGMENT_NV = $86E7;
+ GL_OFFSET_TEXTURE_2D_NV = $86E8;
+ GL_DEPENDENT_AR_TEXTURE_2D_NV = $86E9;
+ GL_DEPENDENT_GB_TEXTURE_2D_NV = $86EA;
+ GL_DOT_PRODUCT_NV = $86EC;
+ GL_DOT_PRODUCT_DEPTH_REPLACE_NV = $86ED;
+ GL_DOT_PRODUCT_TEXTURE_2D_NV = $86EE;
+ GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = $86F0;
+ GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = $86F1;
+ GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = $86F2;
+ GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = $86F3;
+ GL_HILO_NV = $86F4;
+ GL_DSDT_NV = $86F5;
+ GL_DSDT_MAG_NV = $86F6;
+ GL_DSDT_MAG_VIB_NV = $86F7;
+ GL_HILO16_NV = $86F8;
+ GL_SIGNED_HILO_NV = $86F9;
+ GL_SIGNED_HILO16_NV = $86FA;
+ GL_SIGNED_RGBA_NV = $86FB;
+ GL_SIGNED_RGBA8_NV = $86FC;
+ GL_SIGNED_RGB_NV = $86FE;
+ GL_SIGNED_RGB8_NV = $86FF;
+ GL_SIGNED_LUMINANCE_NV = $8701;
+ GL_SIGNED_LUMINANCE8_NV = $8702;
+ GL_SIGNED_LUMINANCE_ALPHA_NV = $8703;
+ GL_SIGNED_LUMINANCE8_ALPHA8_NV = $8704;
+ GL_SIGNED_ALPHA_NV = $8705;
+ GL_SIGNED_ALPHA8_NV = $8706;
+ GL_SIGNED_INTENSITY_NV = $8707;
+ GL_SIGNED_INTENSITY8_NV = $8708;
+ GL_DSDT8_NV = $8709;
+ GL_DSDT8_MAG8_NV = $870A;
+ GL_DSDT8_MAG8_INTENSITY8_NV = $870B;
+ GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = $870C;
+ GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = $870D;
+ GL_HI_SCALE_NV = $870E;
+ GL_LO_SCALE_NV = $870F;
+ GL_DS_SCALE_NV = $8710;
+ GL_DT_SCALE_NV = $8711;
+ GL_MAGNITUDE_SCALE_NV = $8712;
+ GL_VIBRANCE_SCALE_NV = $8713;
+ GL_HI_BIAS_NV = $8714;
+ GL_LO_BIAS_NV = $8715;
+ GL_DS_BIAS_NV = $8716;
+ GL_DT_BIAS_NV = $8717;
+ GL_MAGNITUDE_BIAS_NV = $8718;
+ GL_VIBRANCE_BIAS_NV = $8719;
+ GL_TEXTURE_BORDER_VALUES_NV = $871A;
+ GL_TEXTURE_HI_SIZE_NV = $871B;
+ GL_TEXTURE_LO_SIZE_NV = $871C;
+ GL_TEXTURE_DS_SIZE_NV = $871D;
+ GL_TEXTURE_DT_SIZE_NV = $871E;
+ GL_TEXTURE_MAG_SIZE_NV = $871F;
+
+ // GL_NV_texture_shader2
+ GL_DOT_PRODUCT_TEXTURE_3D_NV = $86EF;
+
+ // GL_NV_texture_shader3
+ GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = $8850;
+ GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = $8851;
+ GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8852;
+ GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = $8853;
+ GL_OFFSET_HILO_TEXTURE_2D_NV = $8854;
+ GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = $8855;
+ GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = $8856;
+ GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8857;
+ GL_DEPENDENT_HILO_TEXTURE_2D_NV = $8858;
+ GL_DEPENDENT_RGB_TEXTURE_3D_NV = $8859;
+ GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = $885A;
+ GL_DOT_PRODUCT_PASS_THROUGH_NV = $885B;
+ GL_DOT_PRODUCT_TEXTURE_1D_NV = $885C;
+ GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = $885D;
+ GL_HILO8_NV = $885E;
+ GL_SIGNED_HILO8_NV = $885F;
+ GL_FORCE_BLUE_TO_ONE_NV = $8860;
+
+ // GL_NV_vertex_array_range
+ GL_VERTEX_ARRAY_RANGE_NV = $851D;
+ GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E;
+ GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F;
+ GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520;
+ GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521;
+
+ // GL_NV_vertex_array_range2
+ GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = $8533;
+
+ // GL_NV_vertex_program
+ GL_VERTEX_PROGRAM_NV = $8620;
+ GL_VERTEX_STATE_PROGRAM_NV = $8621;
+ GL_ATTRIB_ARRAY_SIZE_NV = $8623;
+ GL_ATTRIB_ARRAY_STRIDE_NV = $8624;
+ GL_ATTRIB_ARRAY_TYPE_NV = $8625;
+ GL_CURRENT_ATTRIB_NV = $8626;
+ GL_PROGRAM_LENGTH_NV = $8627;
+ GL_PROGRAM_STRING_NV = $8628;
+ GL_MODELVIEW_PROJECTION_NV = $8629;
+ GL_IDENTITY_NV = $862A;
+ GL_INVERSE_NV = $862B;
+ GL_TRANSPOSE_NV = $862C;
+ GL_INVERSE_TRANSPOSE_NV = $862D;
+ GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E;
+ GL_MAX_TRACK_MATRICES_NV = $862F;
+ GL_MATRIX0_NV = $8630;
+ GL_MATRIX1_NV = $8631;
+ GL_MATRIX2_NV = $8632;
+ GL_MATRIX3_NV = $8633;
+ GL_MATRIX4_NV = $8634;
+ GL_MATRIX5_NV = $8635;
+ GL_MATRIX6_NV = $8636;
+ GL_MATRIX7_NV = $8637;
+ GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640;
+ GL_CURRENT_MATRIX_NV = $8641;
+ GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642;
+ GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643;
+ GL_PROGRAM_PARAMETER_NV = $8644;
+ GL_ATTRIB_ARRAY_POINTER_NV = $8645;
+ GL_PROGRAM_TARGET_NV = $8646;
+ GL_PROGRAM_RESIDENT_NV = $8647;
+ GL_TRACK_MATRIX_NV = $8648;
+ GL_TRACK_MATRIX_TRANSFORM_NV = $8649;
+ GL_VERTEX_PROGRAM_BINDING_NV = $864A;
+ GL_PROGRAM_ERROR_POSITION_NV = $864B;
+ GL_VERTEX_ATTRIB_ARRAY0_NV = $8650;
+ GL_VERTEX_ATTRIB_ARRAY1_NV = $8651;
+ GL_VERTEX_ATTRIB_ARRAY2_NV = $8652;
+ GL_VERTEX_ATTRIB_ARRAY3_NV = $8653;
+ GL_VERTEX_ATTRIB_ARRAY4_NV = $8654;
+ GL_VERTEX_ATTRIB_ARRAY5_NV = $8655;
+ GL_VERTEX_ATTRIB_ARRAY6_NV = $8656;
+ GL_VERTEX_ATTRIB_ARRAY7_NV = $8657;
+ GL_VERTEX_ATTRIB_ARRAY8_NV = $8658;
+ GL_VERTEX_ATTRIB_ARRAY9_NV = $8659;
+ GL_VERTEX_ATTRIB_ARRAY10_NV = $865A;
+ GL_VERTEX_ATTRIB_ARRAY11_NV = $865B;
+ GL_VERTEX_ATTRIB_ARRAY12_NV = $865C;
+ GL_VERTEX_ATTRIB_ARRAY13_NV = $865D;
+ GL_VERTEX_ATTRIB_ARRAY14_NV = $865E;
+ GL_VERTEX_ATTRIB_ARRAY15_NV = $865F;
+ GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660;
+ GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661;
+ GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662;
+ GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663;
+ GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664;
+ GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665;
+ GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666;
+ GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667;
+ GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668;
+ GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669;
+ GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A;
+ GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B;
+ GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C;
+ GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D;
+ GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E;
+ GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F;
+ GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670;
+ GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671;
+ GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672;
+ GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673;
+ GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674;
+ GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675;
+ GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676;
+ GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677;
+ GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678;
+ GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679;
+ GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A;
+ GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B;
+ GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C;
+ GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D;
+ GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E;
+ GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F;
+
+ // GL_NV_fragment_program2 and GL_NV_vertex_program2_option
+ GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = $88F4;
+ GL_MAX_PROGRAM_CALL_DEPTH_NV = $88F5;
+
+ // GL_NV_fragment_program2
+ GL_MAX_PROGRAM_IF_DEPTH_NV = $88F6;
+ GL_MAX_PROGRAM_LOOP_DEPTH_NV = $88F7;
+ GL_MAX_PROGRAM_LOOP_COUNT_NV = $88F8;
+
+ // GL_NV_vertex_program3
+ MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C;
+
+ // GL_NV_depth_buffer_float
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV = $8DAD;
+ GL_DEPTH_BUFFER_FLOAT_MODE_NV = $8DAF;
+
+ // GL_NV_framebuffer_multisample_coverage
+ GL_RENDERBUFFER_COVERAGE_SAMPLES_NV = $8CAB;
+ GL_RENDERBUFFER_COLOR_SAMPLES_NV = $8E10;
+
+ // GL_NV_geometry_program4
+ GL_GEOMETRY_PROGRAM_NV = $8C26;
+ GL_MAX_PROGRAM_OUTPUT_VERTICES_NV = $8C27;
+ GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV = $8C28;
+
+ // GL_NV_gpu_program4
+ GL_PROGRAM_ATTRIB_COMPONENTS_NV = $8906;
+ GL_PROGRAM_RESULT_COMPONENTS_NV = $8907;
+ GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV = $8908;
+ GL_MAX_PROGRAM_RESULT_COMPONENTS_NV = $8909;
+ GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV = $8DA5;
+ GL_MAX_PROGRAM_GENERIC_RESULTS_NV = $8DA6;
+
+ // GL_NV_parameter_buffer_object
+ GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV = $8DA0;
+ GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV = $8DA1;
+ GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV = $8DA2;
+ GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV = $8DA3;
+ GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV = $8DA4;
+
+ // GL_NV_transform_feedback
+ GL_TRANSFORM_FEEDBACK_BUFFER_NV = $8C8E;
+ GL_TRANSFORM_FEEDBACK_BUFFER_START_NV = $8C84;
+ GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV = $8C85;
+ GL_TRANSFORM_FEEDBACK_RECORD_NV = $8C86;
+ GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV = $8C8F;
+ GL_INTERLEAVED_ATTRIBS_NV = $8C8C;
+ GL_SEPARATE_ATTRIBS_NV = $8C8D;
+ GL_PRIMITIVES_GENERATED_NV = $8C87;
+ GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV = $8C88;
+ GL_RASTERIZER_DISCARD_NV = $8C89;
+ GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV = $8C8A;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV = $8C8B;
+ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV = $8C80;
+ GL_TRANSFORM_FEEDBACK_ATTRIBS_NV = $8C7E;
+ GL_ACTIVE_VARYINGS_NV = $8C81;
+ GL_ACTIVE_VARYING_MAX_LENGTH_NV = $8C82;
+ GL_TRANSFORM_FEEDBACK_VARYINGS_NV = $8C83;
+ GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV = $8C7F;
+ GL_BACK_PRIMARY_COLOR_NV = $8C77;
+ GL_BACK_SECONDARY_COLOR_NV = $8C78;
+ GL_TEXTURE_COORD_NV = $8C79;
+ GL_CLIP_DISTANCE_NV = $8C7A;
+ GL_VERTEX_ID_NV = $8C7B;
+ GL_PRIMITIVE_ID_NV = $8C7C;
+ GL_GENERIC_ATTRIB_NV = $8C7D;
+ GL_LAYER_NV = $8DAA;
+ GL_NEXT_BUFFER_NV = -2;
+ GL_SKIP_COMPONENTS4_NV = -3;
+ GL_SKIP_COMPONENTS3_NV = -4;
+ GL_SKIP_COMPONENTS2_NV = -5;
+ GL_SKIP_COMPONENTS1_NV = -6;
+
+ // GL_NV_conditional_render
+ GL_QUERY_WAIT_NV = $8E13;
+ GL_QUERY_NO_WAIT_NV = $8E14;
+ GL_QUERY_BY_REGION_WAIT_NV = $8E15;
+ GL_QUERY_BY_REGION_NO_WAIT_NV = $8E16;
+
+ // GL_NV_conservative_raster
+ GL_CONSERVATIVE_RASTERIZATION_NV = $9346;
+ GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV = $9347;
+ GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV = $9348;
+ GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV = $9349;
+
+ // GL_NV_conservative_raster_dilate
+ GL_CONSERVATIVE_RASTER_DILATE_NV = $9379;
+ GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV = $937A;
+ GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV = $937B;
+
+ // GL_NV_present_video
+ GL_FRAME_NV = $8E26;
+ GL_FIELDS_NV = $8E27;
+ GL_CURRENT_TIME_NV = $8E28;
+ GL_NUM_FILL_STREAMS_NV = $8E29;
+ GL_PRESENT_TIME_NV = $8E2A;
+ GL_PRESENT_DURATION_NV = $8E2B;
+
+ // GL_NV_explicit_multisample
+ GL_SAMPLE_POSITION_NV = $8E50;
+ GL_SAMPLE_MASK_NV = $8E51;
+ GL_SAMPLE_MASK_VALUE_NV = $8E52;
+ GL_TEXTURE_BINDING_RENDERBUFFER_NV = $8E53;
+ GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV = $8E54;
+ GL_TEXTURE_RENDERBUFFER_NV = $8E55;
+ GL_SAMPLER_RENDERBUFFER_NV = $8E56;
+ GL_INT_SAMPLER_RENDERBUFFER_NV = $8E57;
+ GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV = $8E58;
+ GL_MAX_SAMPLE_MASK_WORDS_NV = $8E59;
+
+ // GL_NV_transform_feedback2
+ GL_TRANSFORM_FEEDBACK_NV = $8E22;
+ GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV = $8E23;
+ GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV = $8E24;
+ GL_TRANSFORM_FEEDBACK_BINDING_NV = $8E25;
+
+ // GL_NV_video_capture
+ GL_VIDEO_BUFFER_NV = $9020;
+ GL_VIDEO_BUFFER_BINDING_NV = $9021;
+ GL_FIELD_UPPER_NV = $9022;
+ GL_FIELD_LOWER_NV = $9023;
+ GL_NUM_VIDEO_CAPTURE_STREAMS_NV = $9024;
+ GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV = $9025;
+ GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV = $9026;
+ GL_LAST_VIDEO_CAPTURE_STATUS_NV = $9027;
+ GL_VIDEO_BUFFER_PITCH_NV = $9028;
+ GL_VIDEO_COLOR_CONVERSION_MATRIX_NV = $9029;
+ GL_VIDEO_COLOR_CONVERSION_MAX_NV = $902A;
+ GL_VIDEO_COLOR_CONVERSION_MIN_NV = $902B;
+ GL_VIDEO_COLOR_CONVERSION_OFFSET_NV = $902C;
+ GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV = $902D;
+ GL_PARTIAL_SUCCESS_NV = $902E;
+ GL_SUCCESS_NV = $902F;
+ GL_FAILURE_NV = $9030;
+ GL_YCBYCR8_422_NV = $9031;
+ GL_YCBAYCR8A_4224_NV = $9032;
+ GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV = $9033;
+ GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV = $9034;
+ GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV = $9035;
+ GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV = $9036;
+ GL_Z4Y12Z4CB12Z4CR12_444_NV = $9037;
+ GL_VIDEO_CAPTURE_FRAME_WIDTH_NV = $9038;
+ GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV = $9039;
+ GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV = $903A;
+ GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV = $903B;
+ GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV = $903C;
+
+ // GL_NV_shader_buffer_load
+ GL_BUFFER_GPU_ADDRESS_NV = $8F1D;
+ GL_GPU_ADDRESS_NV = $8F34;
+ GL_MAX_SHADER_BUFFER_ADDRESS_NV = $8F35;
+
+ // GL_NV_vertex_buffer_unified_memory
+ GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV = $8F1E;
+ GL_ELEMENT_ARRAY_UNIFIED_NV = $8F1F;
+ GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV = $8F20;
+ GL_VERTEX_ARRAY_ADDRESS_NV = $8F21;
+ GL_NORMAL_ARRAY_ADDRESS_NV = $8F22;
+ GL_COLOR_ARRAY_ADDRESS_NV = $8F23;
+ GL_INDEX_ARRAY_ADDRESS_NV = $8F24;
+ GL_TEXTURE_COORD_ARRAY_ADDRESS_NV = $8F25;
+ GL_EDGE_FLAG_ARRAY_ADDRESS_NV = $8F26;
+ GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV = $8F27;
+ GL_FOG_COORD_ARRAY_ADDRESS_NV = $8F28;
+ GL_ELEMENT_ARRAY_ADDRESS_NV = $8F29;
+ GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV = $8F2A;
+ GL_VERTEX_ARRAY_LENGTH_NV = $8F2B;
+ GL_NORMAL_ARRAY_LENGTH_NV = $8F2C;
+ GL_COLOR_ARRAY_LENGTH_NV = $8F2D;
+ GL_INDEX_ARRAY_LENGTH_NV = $8F2E;
+ GL_TEXTURE_COORD_ARRAY_LENGTH_NV = $8F2F;
+ GL_EDGE_FLAG_ARRAY_LENGTH_NV = $8F30;
+ GL_SECONDARY_COLOR_ARRAY_LENGTH_NV = $8F31;
+ GL_FOG_COORD_ARRAY_LENGTH_NV = $8F32;
+ GL_ELEMENT_ARRAY_LENGTH_NV = $8F33;
+ GL_DRAW_INDIRECT_UNIFIED_NV = $8F40;
+ GL_DRAW_INDIRECT_ADDRESS_NV = $8F41;
+ GL_DRAW_INDIRECT_LENGTH_NV = $8F42;
+
+ // GL_NV_gpu_program5
+ GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV = $8E5A;
+ GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV = $8E5B;
+ GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV = $8E5C;
+ GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV = $8E5D;
+ GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV = $8E5E;
+ GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV = $8E5F;
+ GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV = $8F44;
+ GL_MAX_PROGRAM_SUBROUTINE_NUM_NV = $8F45;
+
+ // GL_NV_gpu_shader5
+ GL_INT64_NV = $140E;
+ GL_UNSIGNED_INT64_NV = $140F;
+ GL_INT8_NV = $8FE0;
+ GL_INT8_VEC2_NV = $8FE1;
+ GL_INT8_VEC3_NV = $8FE2;
+ GL_INT8_VEC4_NV = $8FE3;
+ GL_INT16_NV = $8FE4;
+ GL_INT16_VEC2_NV = $8FE5;
+ GL_INT16_VEC3_NV = $8FE6;
+ GL_INT16_VEC4_NV = $8FE7;
+ GL_INT64_VEC2_NV = $8FE9;
+ GL_INT64_VEC3_NV = $8FEA;
+ GL_INT64_VEC4_NV = $8FEB;
+ GL_UNSIGNED_INT8_NV = $8FEC;
+ GL_UNSIGNED_INT8_VEC2_NV = $8FED;
+ GL_UNSIGNED_INT8_VEC3_NV = $8FEE;
+ GL_UNSIGNED_INT8_VEC4_NV = $8FEF;
+ GL_UNSIGNED_INT16_NV = $8FF0;
+ GL_UNSIGNED_INT16_VEC2_NV = $8FF1;
+ GL_UNSIGNED_INT16_VEC3_NV = $8FF2;
+ GL_UNSIGNED_INT16_VEC4_NV = $8FF3;
+ GL_UNSIGNED_INT64_VEC2_NV = $8FF5;
+ GL_UNSIGNED_INT64_VEC3_NV = $8FF6;
+ GL_UNSIGNED_INT64_VEC4_NV = $8FF7;
+ GL_FLOAT16_NV = $8FF8;
+ GL_FLOAT16_VEC2_NV = $8FF9;
+ GL_FLOAT16_VEC3_NV = $8FFA;
+ GL_FLOAT16_VEC4_NV = $8FFB;
+ { reuse GL_PATCHES }
+
+ // GL_NV_shader_buffer_store
+ GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV = $00000010;
+ { reuse GL_READ_WRITE }
+ { reuse GL_WRITE_ONLY }
+
+ // GL_NV_tessellation_program5
+ GL_MAX_PROGRAM_PATCH_ATTRIBS_NV = $86D8;
+ GL_TESS_CONTROL_PROGRAM_NV = $891E;
+ GL_TESS_EVALUATION_PROGRAM_NV = $891F;
+ GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV = $8C74;
+ GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV = $8C75;
+
+ // GL_NV_vertex_attrib_integer_64bit
+ { reuse GL_INT64_NV }
+ { reuse GL_UNSIGNED_INT64_NV }
+
+ // GL_NV_multisample_coverage
+ GL_COVERAGE_SAMPLES_NV = $80A9;
+ GL_COLOR_SAMPLES_NV = $8E20;
+
+ // GL_NV_vdpau_interop
+ GL_SURFACE_STATE_NV = $86EB;
+ GL_SURFACE_REGISTERED_NV = $86FD;
+ GL_SURFACE_MAPPED_NV = $8700;
+ GL_WRITE_DISCARD_NV = $88BE;
+
+ // GL_OML_interlace
+ GL_INTERLACE_OML = $8980;
+ GL_INTERLACE_READ_OML = $8981;
+
+ // GL_OML_resample
+ GL_PACK_RESAMPLE_OML = $8984;
+ GL_UNPACK_RESAMPLE_OML = $8985;
+ GL_RESAMPLE_REPLICATE_OML = $8986;
+ GL_RESAMPLE_ZERO_FILL_OML = $8987;
+ GL_RESAMPLE_AVERAGE_OML = $8988;
+ GL_RESAMPLE_DECIMATE_OML = $8989;
+
+ // GL_OML_subsample
+ GL_FORMAT_SUBSAMPLE_24_24_OML = $8982;
+ GL_FORMAT_SUBSAMPLE_244_244_OML = $8983;
+
+ // GL_OVR_multiview
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = $9630;
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = $9632;
+ GL_MAX_VIEWS_OVR = $9631;
+ GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = $9633;
+
+ // GL_PGI_misc_hints
+ GL_PREFER_DOUBLEBUFFER_HINT_PGI = $1A1F8;
+ GL_CONSERVE_MEMORY_HINT_PGI = $1A1FD;
+ GL_RECLAIM_MEMORY_HINT_PGI = $1A1FE;
+ GL_NATIVE_GRAPHICS_HANDLE_PGI = $1A202;
+ GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI = $1A203;
+ GL_NATIVE_GRAPHICS_END_HINT_PGI = $1A204;
+ GL_ALWAYS_FAST_HINT_PGI = $1A20C;
+ GL_ALWAYS_SOFT_HINT_PGI = $1A20D;
+ GL_ALLOW_DRAW_OBJ_HINT_PGI = $1A20E;
+ GL_ALLOW_DRAW_WIN_HINT_PGI = $1A20F;
+ GL_ALLOW_DRAW_FRG_HINT_PGI = $1A210;
+ GL_ALLOW_DRAW_MEM_HINT_PGI = $1A211;
+ GL_STRICT_DEPTHFUNC_HINT_PGI = $1A216;
+ GL_STRICT_LIGHTING_HINT_PGI = $1A217;
+ GL_STRICT_SCISSOR_HINT_PGI = $1A218;
+ GL_FULL_STIPPLE_HINT_PGI = $1A219;
+ GL_CLIP_NEAR_HINT_PGI = $1A220;
+ GL_CLIP_FAR_HINT_PGI = $1A221;
+ GL_WIDE_LINE_HINT_PGI = $1A222;
+ GL_BACK_NORMALS_HINT_PGI = $1A223;
+
+ // GL_PGI_vertex_hints
+ GL_VERTEX_DATA_HINT_PGI = $1A22A;
+ GL_VERTEX_CONSISTENT_HINT_PGI = $1A22B;
+ GL_MATERIAL_SIDE_HINT_PGI = $1A22C;
+ GL_MAX_VERTEX_HINT_PGI = $1A22D;
+ GL_COLOR3_BIT_PGI = $00010000;
+ GL_COLOR4_BIT_PGI = $00020000;
+ GL_EDGEFLAG_BIT_PGI = $00040000;
+ GL_INDEX_BIT_PGI = $00080000;
+ GL_MAT_AMBIENT_BIT_PGI = $00100000;
+ GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI = $00200000;
+ GL_MAT_DIFFUSE_BIT_PGI = $00400000;
+ GL_MAT_EMISSION_BIT_PGI = $00800000;
+ GL_MAT_COLOR_INDEXES_BIT_PGI = $01000000;
+ GL_MAT_SHININESS_BIT_PGI = $02000000;
+ GL_MAT_SPECULAR_BIT_PGI = $04000000;
+ GL_NORMAL_BIT_PGI = $08000000;
+ GL_TEXCOORD1_BIT_PGI = $10000000;
+ GL_TEXCOORD2_BIT_PGI = $20000000;
+ GL_TEXCOORD3_BIT_PGI = $40000000;
+ GL_TEXCOORD4_BIT_PGI = $80000000;
+ GL_VERTEX23_BIT_PGI = $00000004;
+ GL_VERTEX4_BIT_PGI = $00000008;
+
+ // GL_REND_screen_coordinates
+ GL_SCREEN_COORDINATES_REND = $8490;
+ GL_INVERTED_SCREEN_W_REND = $8491;
+
+ // GL_S3_s3tc
+ GL_RGB_S3TC = $83A0;
+ GL_RGB4_S3TC = $83A1;
+ GL_RGBA_S3TC = $83A2;
+ GL_RGBA4_S3TC = $83A3;
+
+ // GL_SGIS_detail_texture
+ GL_DETAIL_TEXTURE_2D_SGIS = $8095;
+ GL_DETAIL_TEXTURE_2D_BINDING_SGIS = $8096;
+ GL_LINEAR_DETAIL_SGIS = $8097;
+ GL_LINEAR_DETAIL_ALPHA_SGIS = $8098;
+ GL_LINEAR_DETAIL_COLOR_SGIS = $8099;
+ GL_DETAIL_TEXTURE_LEVEL_SGIS = $809A;
+ GL_DETAIL_TEXTURE_MODE_SGIS = $809B;
+ GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS = $809C;
+
+ // GL_SGIS_fog_function
+ GL_FOG_FUNC_SGIS = $812A;
+ GL_FOG_FUNC_POINTS_SGIS = $812B;
+ GL_MAX_FOG_FUNC_POINTS_SGIS = $812C;
+
+ // GL_SGIS_generate_mipmap
+ GL_GENERATE_MIPMAP_SGIS = $8191;
+ GL_GENERATE_MIPMAP_HINT_SGIS = $8192;
+
+ // GL_SGIS_multisample
+ GL_MULTISAMPLE_SGIS = $809D;
+ GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E;
+ GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F;
+ GL_SAMPLE_MASK_SGIS = $80A0;
+ GL_1PASS_SGIS = $80A1;
+ GL_2PASS_0_SGIS = $80A2;
+ GL_2PASS_1_SGIS = $80A3;
+ GL_4PASS_0_SGIS = $80A4;
+ GL_4PASS_1_SGIS = $80A5;
+ GL_4PASS_2_SGIS = $80A6;
+ GL_4PASS_3_SGIS = $80A7;
+ GL_SAMPLE_BUFFERS_SGIS = $80A8;
+ GL_SAMPLES_SGIS = $80A9;
+ GL_SAMPLE_MASK_VALUE_SGIS = $80AA;
+ GL_SAMPLE_MASK_INVERT_SGIS = $80AB;
+ GL_SAMPLE_PATTERN_SGIS = $80AC;
+
+ // GL_SGIS_pixel_texture
+ GL_PIXEL_TEXTURE_SGIS = $8353;
+ GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354;
+ GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355;
+ GL_PIXEL_GROUP_COLOR_SGIS = $8356;
+
+ // GL_SGIS_point_line_texgen
+ GL_EYE_DISTANCE_TO_POINT_SGIS = $81F0;
+ GL_OBJECT_DISTANCE_TO_POINT_SGIS = $81F1;
+ GL_EYE_DISTANCE_TO_LINE_SGIS = $81F2;
+ GL_OBJECT_DISTANCE_TO_LINE_SGIS = $81F3;
+ GL_EYE_POINT_SGIS = $81F4;
+ GL_OBJECT_POINT_SGIS = $81F5;
+ GL_EYE_LINE_SGIS = $81F6;
+ GL_OBJECT_LINE_SGIS = $81F7;
+
+ // GL_SGIS_point_parameters
+ GL_POINT_SIZE_MIN_SGIS = $8126;
+ GL_POINT_SIZE_MAX_SGIS = $8127;
+ GL_POINT_FADE_THRESHOLD_SIZE_SGIS = $8128;
+ GL_DISTANCE_ATTENUATION_SGIS = $8129;
+
+ // GL_SGIS_sharpen_texture
+ GL_LINEAR_SHARPEN_SGIS = $80AD;
+ GL_LINEAR_SHARPEN_ALPHA_SGIS = $80AE;
+ GL_LINEAR_SHARPEN_COLOR_SGIS = $80AF;
+ GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS = $80B0;
+
+ // GL_SGIS_texture4D
+ GL_PACK_SKIP_VOLUMES_SGIS = $8130;
+ GL_PACK_IMAGE_DEPTH_SGIS = $8131;
+ GL_UNPACK_SKIP_VOLUMES_SGIS = $8132;
+ GL_UNPACK_IMAGE_DEPTH_SGIS = $8133;
+ GL_TEXTURE_4D_SGIS = $8134;
+ GL_PROXY_TEXTURE_4D_SGIS = $8135;
+ GL_TEXTURE_4DSIZE_SGIS = $8136;
+ GL_TEXTURE_WRAP_Q_SGIS = $8137;
+ GL_MAX_4D_TEXTURE_SIZE_SGIS = $8138;
+ GL_TEXTURE_4D_BINDING_SGIS = $814F;
+
+ // GL_SGIS_texture_color_mask
+ GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF;
+
+ // GL_SGIS_texture_edge_clamp
+ GL_CLAMP_TO_EDGE_SGIS = $812F;
+
+ // GL_SGIS_texture_filter4
+ GL_FILTER4_SGIS = $8146;
+ GL_TEXTURE_FILTER4_SIZE_SGIS = $8147;
+
+ // GL_SGIS_texture_lod
+ GL_TEXTURE_MIN_LOD_SGIS = $813A;
+ GL_TEXTURE_MAX_LOD_SGIS = $813B;
+ GL_TEXTURE_BASE_LEVEL_SGIS = $813C;
+ GL_TEXTURE_MAX_LEVEL_SGIS = $813D;
+
+ // GL_SGIS_texture_select
+ GL_DUAL_ALPHA4_SGIS = $8110;
+ GL_DUAL_ALPHA8_SGIS = $8111;
+ GL_DUAL_ALPHA12_SGIS = $8112;
+ GL_DUAL_ALPHA16_SGIS = $8113;
+ GL_DUAL_LUMINANCE4_SGIS = $8114;
+ GL_DUAL_LUMINANCE8_SGIS = $8115;
+ GL_DUAL_LUMINANCE12_SGIS = $8116;
+ GL_DUAL_LUMINANCE16_SGIS = $8117;
+ GL_DUAL_INTENSITY4_SGIS = $8118;
+ GL_DUAL_INTENSITY8_SGIS = $8119;
+ GL_DUAL_INTENSITY12_SGIS = $811A;
+ GL_DUAL_INTENSITY16_SGIS = $811B;
+ GL_DUAL_LUMINANCE_ALPHA4_SGIS = $811C;
+ GL_DUAL_LUMINANCE_ALPHA8_SGIS = $811D;
+ GL_QUAD_ALPHA4_SGIS = $811E;
+ GL_QUAD_ALPHA8_SGIS = $811F;
+ GL_QUAD_LUMINANCE4_SGIS = $8120;
+ GL_QUAD_LUMINANCE8_SGIS = $8121;
+ GL_QUAD_INTENSITY4_SGIS = $8122;
+ GL_QUAD_INTENSITY8_SGIS = $8123;
+ GL_DUAL_TEXTURE_SELECT_SGIS = $8124;
+ GL_QUAD_TEXTURE_SELECT_SGIS = $8125;
+
+ // GL_SGIX_async
+ GL_ASYNC_MARKER_SGIX = $8329;
+
+ // GL_SGIX_async_histogram
+ GL_ASYNC_HISTOGRAM_SGIX = $832C;
+ GL_MAX_ASYNC_HISTOGRAM_SGIX = $832D;
+
+ // GL_SGIX_async_pixel
+ GL_ASYNC_TEX_IMAGE_SGIX = $835C;
+ GL_ASYNC_DRAW_PIXELS_SGIX = $835D;
+ GL_ASYNC_READ_PIXELS_SGIX = $835E;
+ GL_MAX_ASYNC_TEX_IMAGE_SGIX = $835F;
+ GL_MAX_ASYNC_DRAW_PIXELS_SGIX = $8360;
+ GL_MAX_ASYNC_READ_PIXELS_SGIX = $8361;
+
+ // GL_SGIX_blend_alpha_minmax
+ GL_ALPHA_MIN_SGIX = $8320;
+ GL_ALPHA_MAX_SGIX = $8321;
+
+ // GL_SGIX_calligraphic_fragment
+ GL_CALLIGRAPHIC_FRAGMENT_SGIX = $8183;
+
+ // GL_SGIX_clipmap
+ GL_LINEAR_CLIPMAP_LINEAR_SGIX = $8170;
+ GL_TEXTURE_CLIPMAP_CENTER_SGIX = $8171;
+ GL_TEXTURE_CLIPMAP_FRAME_SGIX = $8172;
+ GL_TEXTURE_CLIPMAP_OFFSET_SGIX = $8173;
+ GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX = $8174;
+ GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX = $8175;
+ GL_TEXTURE_CLIPMAP_DEPTH_SGIX = $8176;
+ GL_MAX_CLIPMAP_DEPTH_SGIX = $8177;
+ GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX = $8178;
+ GL_NEAREST_CLIPMAP_NEAREST_SGIX = $844D;
+ GL_NEAREST_CLIPMAP_LINEAR_SGIX = $844E;
+ GL_LINEAR_CLIPMAP_NEAREST_SGIX = $844F;
+
+ // GL_SGIX_convolution_accuracy
+ GL_CONVOLUTION_HINT_SGIX = $8316;
+
+ // GL_SGIX_depth_texture
+ GL_DEPTH_COMPONENT16_SGIX = $81A5;
+ GL_DEPTH_COMPONENT24_SGIX = $81A6;
+ GL_DEPTH_COMPONENT32_SGIX = $81A7;
+
+ // GL_SGIX_fog_offset
+ GL_FOG_OFFSET_SGIX = $8198;
+ GL_FOG_OFFSET_VALUE_SGIX = $8199;
+
+ // GL_SGIX_fog_scale
+ GL_FOG_SCALE_SGIX = $81FC;
+ GL_FOG_SCALE_VALUE_SGIX = $81FD;
+
+ // GL_SGIX_fragment_lighting
+ GL_FRAGMENT_LIGHTING_SGIX = $8400;
+ GL_FRAGMENT_COLOR_MATERIAL_SGIX = $8401;
+ GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX = $8402;
+ GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX = $8403;
+ GL_MAX_FRAGMENT_LIGHTS_SGIX = $8404;
+ GL_MAX_ACTIVE_LIGHTS_SGIX = $8405;
+ GL_CURRENT_RASTER_NORMAL_SGIX = $8406;
+ GL_LIGHT_ENV_MODE_SGIX = $8407;
+ GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX = $8408;
+ GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX = $8409;
+ GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX = $840A;
+ GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX = $840B;
+ GL_FRAGMENT_LIGHT0_SGIX = $840C;
+ GL_FRAGMENT_LIGHT1_SGIX = $840D;
+ GL_FRAGMENT_LIGHT2_SGIX = $840E;
+ GL_FRAGMENT_LIGHT3_SGIX = $840F;
+ GL_FRAGMENT_LIGHT4_SGIX = $8410;
+ GL_FRAGMENT_LIGHT5_SGIX = $8411;
+ GL_FRAGMENT_LIGHT6_SGIX = $8412;
+ GL_FRAGMENT_LIGHT7_SGIX = $8413;
+
+ // GL_SGIX_framezoom
+ GL_FRAMEZOOM_SGIX = $818B;
+ GL_FRAMEZOOM_FACTOR_SGIX = $818C;
+ GL_MAX_FRAMEZOOM_FACTOR_SGIX = $818D;
+
+ // GL_SGIX_impact_pixel_texture
+ GL_PIXEL_TEX_GEN_Q_CEILING_SGIX = $8184;
+ GL_PIXEL_TEX_GEN_Q_ROUND_SGIX = $8185;
+ GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX = $8186;
+ GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX = $8187;
+ GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX = $8188;
+ GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX = $8189;
+ GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX = $818A;
+
+ // GL_SGIX_instruments
+ GL_INSTRUMENT_BUFFER_POINTER_SGIX = $8180;
+ GL_INSTRUMENT_MEASUREMENTS_SGIX = $8181;
+
+ // GL_SGIX_interlace
+ GL_INTERLACE_SGIX = $8094;
+
+ // GL_SGIX_ir_instrument1
+ GL_IR_INSTRUMENT1_SGIX = $817F;
+
+ // GL_SGIX_list_priority
+ GL_LIST_PRIORITY_SGIX = $8182;
+
+ // GL_SGIX_pixel_texture
+ GL_PIXEL_TEX_GEN_SGIX = $8139;
+ GL_PIXEL_TEX_GEN_MODE_SGIX = $832B;
+
+ // GL_SGIX_pixel_tiles
+ GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX = $813E;
+ GL_PIXEL_TILE_CACHE_INCREMENT_SGIX = $813F;
+ GL_PIXEL_TILE_WIDTH_SGIX = $8140;
+ GL_PIXEL_TILE_HEIGHT_SGIX = $8141;
+ GL_PIXEL_TILE_GRID_WIDTH_SGIX = $8142;
+ GL_PIXEL_TILE_GRID_HEIGHT_SGIX = $8143;
+ GL_PIXEL_TILE_GRID_DEPTH_SGIX = $8144;
+ GL_PIXEL_TILE_CACHE_SIZE_SGIX = $8145;
+
+ // GL_SGIX_polynomial_ffd
+ GL_GEOMETRY_DEFORMATION_SGIX = $8194;
+ GL_TEXTURE_DEFORMATION_SGIX = $8195;
+ GL_DEFORMATIONS_MASK_SGIX = $8196;
+ GL_MAX_DEFORMATION_ORDER_SGIX = $8197;
+
+ // GL_SGIX_reference_plane
+ GL_REFERENCE_PLANE_SGIX = $817D;
+ GL_REFERENCE_PLANE_EQUATION_SGIX = $817E;
+
+ // GL_SGIX_resample
+ GL_PACK_RESAMPLE_SGIX = $842C;
+ GL_UNPACK_RESAMPLE_SGIX = $842D;
+ GL_RESAMPLE_REPLICATE_SGIX = $842E;
+ GL_RESAMPLE_ZERO_FILL_SGIX = $842F;
+ GL_RESAMPLE_DECIMATE_SGIX = $8430;
+
+ // GL_SGIX_scalebias_hint
+ GL_SCALEBIAS_HINT_SGIX = $8322;
+
+ // GL_SGIX_shadow
+ GL_TEXTURE_COMPARE_SGIX = $819A;
+ GL_TEXTURE_COMPARE_OPERATOR_SGIX = $819B;
+ GL_TEXTURE_LEQUAL_R_SGIX = $819C;
+ GL_TEXTURE_GEQUAL_R_SGIX = $819D;
+
+ // GL_SGIX_shadow_ambient
+ GL_SHADOW_AMBIENT_SGIX = $80BF;
+
+ // GL_SGIX_sprite
+ GL_SPRITE_SGIX = $8148;
+ GL_SPRITE_MODE_SGIX = $8149;
+ GL_SPRITE_AXIS_SGIX = $814A;
+ GL_SPRITE_TRANSLATION_SGIX = $814B;
+ GL_SPRITE_AXIAL_SGIX = $814C;
+ GL_SPRITE_OBJECT_ALIGNED_SGIX = $814D;
+ GL_SPRITE_EYE_ALIGNED_SGIX = $814E;
+
+ // GL_SGIX_subsample
+ GL_PACK_SUBSAMPLE_RATE_SGIX = $85A0;
+ GL_UNPACK_SUBSAMPLE_RATE_SGIX = $85A1;
+ GL_PIXEL_SUBSAMPLE_4444_SGIX = $85A2;
+ GL_PIXEL_SUBSAMPLE_2424_SGIX = $85A3;
+ GL_PIXEL_SUBSAMPLE_4242_SGIX = $85A4;
+
+ // GL_SGIX_texture_add_env
+ GL_TEXTURE_ENV_BIAS_SGIX = $80BE;
+
+ // GL_SGIX_texture_coordinate_clamp
+ GL_TEXTURE_MAX_CLAMP_S_SGIX = $8369;
+ GL_TEXTURE_MAX_CLAMP_T_SGIX = $836A;
+ GL_TEXTURE_MAX_CLAMP_R_SGIX = $836B;
+
+ // GL_SGIX_texture_lod_bias
+ GL_TEXTURE_LOD_BIAS_S_SGIX = $818E;
+ GL_TEXTURE_LOD_BIAS_T_SGIX = $818F;
+ GL_TEXTURE_LOD_BIAS_R_SGIX = $8190;
+
+ // GL_SGIX_texture_multi_buffer
+ GL_TEXTURE_MULTI_BUFFER_HINT_SGIX = $812E;
+
+ // GL_SGIX_texture_scale_bias
+ GL_POST_TEXTURE_FILTER_BIAS_SGIX = $8179;
+ GL_POST_TEXTURE_FILTER_SCALE_SGIX = $817A;
+ GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX = $817B;
+ GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX = $817C;
+
+ // GL_SGIX_vertex_preclip
+ GL_VERTEX_PRECLIP_SGIX = $83EE;
+ GL_VERTEX_PRECLIP_HINT_SGIX = $83EF;
+
+ // GL_SGIX_ycrcb
+ GL_YCRCB_422_SGIX = $81BB;
+ GL_YCRCB_444_SGIX = $81BC;
+
+ // GL_SGIX_ycrcba
+ GL_YCRCB_SGIX = $8318;
+ GL_YCRCBA_SGIX = $8319;
+
+ // GL_SGI_color_matrix
+ GL_COLOR_MATRIX_SGI = $80B1;
+ GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2;
+ GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3;
+ GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4;
+ GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5;
+ GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6;
+ GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7;
+ GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8;
+ GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9;
+ GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA;
+ GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB;
+
+ // GL_SGI_color_table
+ GL_COLOR_TABLE_SGI = $80D0;
+ GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1;
+ GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2;
+ GL_PROXY_COLOR_TABLE_SGI = $80D3;
+ GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4;
+ GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5;
+ GL_COLOR_TABLE_SCALE_SGI = $80D6;
+ GL_COLOR_TABLE_BIAS_SGI = $80D7;
+ GL_COLOR_TABLE_FORMAT_SGI = $80D8;
+ GL_COLOR_TABLE_WIDTH_SGI = $80D9;
+ GL_COLOR_TABLE_RED_SIZE_SGI = $80DA;
+ GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB;
+ GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC;
+ GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD;
+ GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE;
+ GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF;
+
+ // GL_SGI_depth_pass_instrument
+ GL_DEPTH_PASS_INSTRUMENT_SGIX = $8310;
+ GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX = $8311;
+ GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX = $8312;
+
+ // GL_SGI_texture_color_table
+ GL_TEXTURE_COLOR_TABLE_SGI = $80BC;
+ GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD;
+
+ // GL_SUNX_constant_data
+ GL_UNPACK_CONSTANT_DATA_SUNX = $81D5;
+ GL_TEXTURE_CONSTANT_DATA_SUNX = $81D6;
+
+ // GL_SUN_convolution_border_modes
+ GL_WRAP_BORDER_SUN = $81D4;
+
+ // GL_SUN_global_alpha
+ GL_GLOBAL_ALPHA_SUN = $81D9;
+ GL_GLOBAL_ALPHA_FACTOR_SUN = $81DA;
+
+ // GL_SUN_mesh_array
+ GL_QUAD_MESH_SUN = $8614;
+ GL_TRIANGLE_MESH_SUN = $8615;
+
+ // GL_SUN_slice_accum
+ GL_SLICE_ACCUM_SUN = $85CC;
+
+ // GL_SUN_triangle_list
+ GL_RESTART_SUN = $0001;
+ GL_REPLACE_MIDDLE_SUN = $0002;
+ GL_REPLACE_OLDEST_SUN = $0003;
+ GL_TRIANGLE_LIST_SUN = $81D7;
+ GL_REPLACEMENT_CODE_SUN = $81D8;
+ GL_REPLACEMENT_CODE_ARRAY_SUN = $85C0;
+ GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN = $85C1;
+ GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN = $85C2;
+ GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN = $85C3;
+ GL_R1UI_V3F_SUN = $85C4;
+ GL_R1UI_C4UB_V3F_SUN = $85C5;
+ GL_R1UI_C3F_V3F_SUN = $85C6;
+ GL_R1UI_N3F_V3F_SUN = $85C7;
+ GL_R1UI_C4F_N3F_V3F_SUN = $85C8;
+ GL_R1UI_T2F_V3F_SUN = $85C9;
+ GL_R1UI_T2F_N3F_V3F_SUN = $85CA;
+ GL_R1UI_T2F_C4F_N3F_V3F_SUN = $85CB;
+
+ // GL_WIN_phong_shading
+ GL_PHONG_WIN = $80EA;
+ GL_PHONG_HINT_WIN = $80EB;
+
+ // GL_WIN_specular_fog
+ GL_FOG_SPECULAR_TEXTURE_WIN = $80EC;
+
+ // GL_ARB_vertex_shader
+ GL_VERTEX_SHADER_ARB = $8B31;
+ GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = $8B4A;
+ GL_MAX_VARYING_FLOATS_ARB = $8B4B;
+ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C;
+ GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = $8B4D;
+ GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = $8B89;
+ GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = $8B8A;
+
+ // GL_KHR_blend_equation_advanced
+ GL_MULTIPLY_KHR = $9294;
+ GL_SCREEN_KHR = $9295;
+ GL_OVERLAY_KHR = $9296;
+ GL_DARKEN_KHR = $9297;
+ GL_LIGHTEN_KHR = $9298;
+ GL_COLORDODGE_KHR = $9299;
+ GL_COLORBURN_KHR = $929A;
+ GL_HARDLIGHT_KHR = $929B;
+ GL_SOFTLIGHT_KHR = $929C;
+ GL_DIFFERENCE_KHR = $929E;
+ GL_EXCLUSION_KHR = $92A0;
+ GL_HSL_HUE_KHR = $92AD;
+ GL_HSL_SATURATION_KHR = $92AE;
+ GL_HSL_COLOR_KHR = $92AF;
+ GL_HSL_LUMINOSITY_KHR = $92B0;
+
+ // GL_KHR_blend_equation_advanced_coherent
+ GL_BLEND_ADVANCED_COHERENT_KHR = $9285;
+
+ // GL_KHR_robustness
+ GL_CONTEXT_ROBUST_ACCESS = $90F3;
+
+ // GL_KHR_no_error
+ GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR = $00000008;
+
+ // GL_ARB_fragment_shader
+ GL_FRAGMENT_SHADER_ARB = $8B30;
+ GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = $8B49; // 1.4
+ GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB = $8B8B; // 1.4
+
+ // GL_ARB_occlusion_query
+ GL_SAMPLES_PASSED_ARB = $8914;
+ GL_QUERY_COUNTER_BITS_ARB = $8864;
+ GL_CURRENT_QUERY_ARB = $8865;
+ GL_QUERY_RESULT_ARB = $8866;
+ GL_QUERY_RESULT_AVAILABLE_ARB = $8867;
+
+ // GL_ARB_pipeline_statistics_query
+ GL_VERTICES_SUBMITTED_ARB = $82EE;
+ GL_PRIMITIVES_SUBMITTED_ARB = $82EF;
+ GL_VERTEX_SHADER_INVOCATIONS_ARB = $82F0;
+ GL_TESS_CONTROL_SHADER_PATCHES_ARB = $82F1;
+ GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB = $82F2;
+ GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB = $82F3;
+ GL_FRAGMENT_SHADER_INVOCATIONS_ARB = $82F4;
+ GL_COMPUTE_SHADER_INVOCATIONS_ARB = $82F5;
+ GL_CLIPPING_INPUT_PRIMITIVES_ARB = $82F6;
+ GL_CLIPPING_OUTPUT_PRIMITIVES_ARB = $82F7;
+
+ // GL_ARB_point_sprite
+ GL_POINT_SPRITE_ARB = $8861;
+ GL_COORD_REPLACE_ARB = $8862;
+
+ // GL_ARB_shading_language_100
+ GL_SHADING_LANGUAGE_VERSION_ARB = $8B8C; // 1.4
+
+ // GL_ARB_shader_objects
+ GL_PROGRAM_OBJECT_ARB = $8B40;
+
+ GL_OBJECT_TYPE_ARB = $8B4E;
+ GL_OBJECT_SUBTYPE_ARB = $8B4F;
+ GL_OBJECT_DELETE_STATUS_ARB = $8B80;
+ GL_OBJECT_COMPILE_STATUS_ARB = $8B81;
+ GL_OBJECT_LINK_STATUS_ARB = $8B82;
+ GL_OBJECT_VALIDATE_STATUS_ARB = $8B83;
+ GL_OBJECT_INFO_LOG_LENGTH_ARB = $8B84;
+ GL_OBJECT_ATTACHED_OBJECTS_ARB = $8B85;
+ GL_OBJECT_ACTIVE_UNIFORMS_ARB = $8B86;
+ GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = $8B87;
+ GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = $8B88;
+
+ GL_SHADER_OBJECT_ARB = $8B48;
+
+ GL_FLOAT_VEC2_ARB = $8B50;
+ GL_FLOAT_VEC3_ARB = $8B51;
+ GL_FLOAT_VEC4_ARB = $8B52;
+ GL_INT_VEC2_ARB = $8B53;
+ GL_INT_VEC3_ARB = $8B54;
+ GL_INT_VEC4_ARB = $8B55;
+ GL_BOOL_ARB = $8B56;
+ GL_BOOL_VEC2_ARB = $8B57;
+ GL_BOOL_VEC3_ARB = $8B58;
+ GL_BOOL_VEC4_ARB = $8B59;
+ GL_FLOAT_MAT2_ARB = $8B5A;
+ GL_FLOAT_MAT3_ARB = $8B5B;
+ GL_FLOAT_MAT4_ARB = $8B5C;
+ GL_SAMPLER_1D_ARB = $8B5D;
+ GL_SAMPLER_2D_ARB = $8B5E;
+ GL_SAMPLER_3D_ARB = $8B5F;
+ GL_SAMPLER_CUBE_ARB = $8B60;
+ GL_SAMPLER_1D_SHADOW_ARB = $8B61;
+ GL_SAMPLER_2D_SHADOW_ARB = $8B62;
+ GL_SAMPLER_2D_RECT_ARB = $8B63;
+ GL_SAMPLER_2D_RECT_SHADOW_ARB = $8B64;
+
+ // WGL_3DFX_multisample
+ WGL_SAMPLE_BUFFERS_3DFX = $2060;
+ WGL_SAMPLES_3DFX = $2061;
+
+ // WGL_ARB_buffer_region
+ WGL_FRONT_COLOR_BUFFER_BIT_ARB = $00000001;
+ WGL_BACK_COLOR_BUFFER_BIT_ARB = $00000002;
+ WGL_DEPTH_BUFFER_BIT_ARB = $00000004;
+ WGL_STENCIL_BUFFER_BIT_ARB = $00000008;
+
+ // WGL_ARB_context_flush_control
+ WGL_CONTEXT_RELEASE_BEHAVIOR_ARB = $2097;
+ WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB = 0;
+ WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = $2098;
+
+ // WGL_ARB_make_current_read
+ ERROR_INVALID_PIXEL_TYPE_ARB = $2043;
+ ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = $2054;
+
+ // WGL_ARB_multisample
+ WGL_SAMPLE_BUFFERS_ARB = $2041;
+ WGL_SAMPLES_ARB = $2042;
+
+ // WGL_ARB_pbuffer
+ WGL_DRAW_TO_PBUFFER_ARB = $202D;
+ WGL_MAX_PBUFFER_PIXELS_ARB = $202E;
+ WGL_MAX_PBUFFER_WIDTH_ARB = $202F;
+ WGL_MAX_PBUFFER_HEIGHT_ARB = $2030;
+ WGL_PBUFFER_LARGEST_ARB = $2033;
+ WGL_PBUFFER_WIDTH_ARB = $2034;
+ WGL_PBUFFER_HEIGHT_ARB = $2035;
+ WGL_PBUFFER_LOST_ARB = $2036;
+
+ // WGL_ARB_pixel_format
+ WGL_NUMBER_PIXEL_FORMATS_ARB = $2000;
+ WGL_DRAW_TO_WINDOW_ARB = $2001;
+ WGL_DRAW_TO_BITMAP_ARB = $2002;
+ WGL_ACCELERATION_ARB = $2003;
+ WGL_NEED_PALETTE_ARB = $2004;
+ WGL_NEED_SYSTEM_PALETTE_ARB = $2005;
+ WGL_SWAP_LAYER_BUFFERS_ARB = $2006;
+ WGL_SWAP_METHOD_ARB = $2007;
+ WGL_NUMBER_OVERLAYS_ARB = $2008;
+ WGL_NUMBER_UNDERLAYS_ARB = $2009;
+ WGL_TRANSPARENT_ARB = $200A;
+ WGL_TRANSPARENT_RED_VALUE_ARB = $2037;
+ WGL_TRANSPARENT_GREEN_VALUE_ARB = $2038;
+ WGL_TRANSPARENT_BLUE_VALUE_ARB = $2039;
+ WGL_TRANSPARENT_ALPHA_VALUE_ARB = $203A;
+ WGL_TRANSPARENT_INDEX_VALUE_ARB = $203B;
+ WGL_SHARE_DEPTH_ARB = $200C;
+ WGL_SHARE_STENCIL_ARB = $200D;
+ WGL_SHARE_ACCUM_ARB = $200E;
+ WGL_SUPPORT_GDI_ARB = $200F;
+ WGL_SUPPORT_OPENGL_ARB = $2010;
+ WGL_DOUBLE_BUFFER_ARB = $2011;
+ WGL_STEREO_ARB = $2012;
+ WGL_PIXEL_TYPE_ARB = $2013;
+ WGL_COLOR_BITS_ARB = $2014;
+ WGL_RED_BITS_ARB = $2015;
+ WGL_RED_SHIFT_ARB = $2016;
+ WGL_GREEN_BITS_ARB = $2017;
+ WGL_GREEN_SHIFT_ARB = $2018;
+ WGL_BLUE_BITS_ARB = $2019;
+ WGL_BLUE_SHIFT_ARB = $201A;
+ WGL_ALPHA_BITS_ARB = $201B;
+ WGL_ALPHA_SHIFT_ARB = $201C;
+ WGL_ACCUM_BITS_ARB = $201D;
+ WGL_ACCUM_RED_BITS_ARB = $201E;
+ WGL_ACCUM_GREEN_BITS_ARB = $201F;
+ WGL_ACCUM_BLUE_BITS_ARB = $2020;
+ WGL_ACCUM_ALPHA_BITS_ARB = $2021;
+ WGL_DEPTH_BITS_ARB = $2022;
+ WGL_STENCIL_BITS_ARB = $2023;
+ WGL_AUX_BUFFERS_ARB = $2024;
+ WGL_NO_ACCELERATION_ARB = $2025;
+ WGL_GENERIC_ACCELERATION_ARB = $2026;
+ WGL_FULL_ACCELERATION_ARB = $2027;
+ WGL_SWAP_EXCHANGE_ARB = $2028;
+ WGL_SWAP_COPY_ARB = $2029;
+ WGL_SWAP_UNDEFINED_ARB = $202A;
+ WGL_TYPE_RGBA_ARB = $202B;
+ WGL_TYPE_COLORINDEX_ARB = $202C;
+
+ // WGL_ARB_pixel_format_float
+ WGL_RGBA_FLOAT_MODE_ARB = $8820;
+ WGL_CLAMP_VERTEX_COLOR_ARB = $891A;
+ WGL_CLAMP_FRAGMENT_COLOR_ARB = $891B;
+ WGL_CLAMP_READ_COLOR_ARB = $891C;
+ WGL_FIXED_ONLY_ARB = $891D;
+
+ // WGL_ARB_render_texture
+ WGL_BIND_TO_TEXTURE_RGB_ARB = $2070;
+ WGL_BIND_TO_TEXTURE_RGBA_ARB = $2071;
+ WGL_TEXTURE_FORMAT_ARB = $2072;
+ WGL_TEXTURE_TARGET_ARB = $2073;
+ WGL_MIPMAP_TEXTURE_ARB = $2074;
+ WGL_TEXTURE_RGB_ARB = $2075;
+ WGL_TEXTURE_RGBA_ARB = $2076;
+ WGL_NO_TEXTURE_ARB = $2077;
+ WGL_TEXTURE_CUBE_MAP_ARB = $2078;
+ WGL_TEXTURE_1D_ARB = $2079;
+ WGL_TEXTURE_2D_ARB = $207A;
+ WGL_MIPMAP_LEVEL_ARB = $207B;
+ WGL_CUBE_MAP_FACE_ARB = $207C;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $207D;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $207E;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $207F;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $2080;
+ WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $2081;
+ WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $2082;
+ WGL_FRONT_LEFT_ARB = $2083;
+ WGL_FRONT_RIGHT_ARB = $2084;
+ WGL_BACK_LEFT_ARB = $2085;
+ WGL_BACK_RIGHT_ARB = $2086;
+ WGL_AUX0_ARB = $2087;
+ WGL_AUX1_ARB = $2088;
+ WGL_AUX2_ARB = $2089;
+ WGL_AUX3_ARB = $208A;
+ WGL_AUX4_ARB = $208B;
+ WGL_AUX5_ARB = $208C;
+ WGL_AUX6_ARB = $208D;
+ WGL_AUX7_ARB = $208E;
+ WGL_AUX8_ARB = $208F;
+ WGL_AUX9_ARB = $2090;
+
+ // WGL_ARB_robustness_application_isolation
+ WGL_CONTEXT_RESET_ISOLATION_BIT_ARB = $00000008;
+
+ // WGL_ARB_create_context
+ WGL_CONTEXT_DEBUG_BIT_ARB = $00000001;
+ WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = $00000002;
+ WGL_CONTEXT_MAJOR_VERSION_ARB = $2091;
+ WGL_CONTEXT_MINOR_VERSION_ARB = $2092;
+ WGL_CONTEXT_LAYER_PLANE_ARB = $2093;
+ WGL_CONTEXT_FLAGS_ARB = $2094;
+ ERROR_INVALID_VERSION_ARB = $2095;
+
+ // WGL_ARB_create_context_profile
+ WGL_CONTEXT_PROFILE_MASK_ARB = $9126;
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB = $00000001;
+ WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = $00000002;
+ ERROR_INVALID_PROFILE_ARB = $2096;
+
+ // WGL_ARB_framebuffer_sRGB
+ WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB = $20A9;
+
+ // WGL_ARB_create_context_robustness
+ WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB = $00000004;
+ WGL_LOSE_CONTEXT_ON_RESET_ARB = $8252;
+ WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = $8256;
+ WGL_NO_RESET_NOTIFICATION_ARB = $8261;
+
+ // WGL_ATI_pixel_format_float
+ WGL_TYPE_RGBA_FLOAT_ATI = $21A0;
+ GL_TYPE_RGBA_FLOAT_ATI = $8820;
+ GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = $8835;
+
+ // WGL_AMD_gpu_association
+ WGL_GPU_VENDOR_AMD = $1F00;
+ WGL_GPU_RENDERER_STRING_AMD = $1F01;
+ WGL_GPU_OPENGL_VERSION_STRING_AMD = $1F02;
+ WGL_GPU_FASTEST_TARGET_GPUS_AMD = $21A2;
+ WGL_GPU_RAM_AMD = $21A3;
+ WGL_GPU_CLOCK_AMD = $21A4;
+ WGL_GPU_NUM_PIPES_AMD = $21A5;
+ WGL_GPU_NUM_SIMD_AMD = $21A6;
+ WGL_GPU_NUM_RB_AMD = $21A7;
+ WGL_GPU_NUM_SPI_AMD = $21A8;
+
+ // WGL_EXT_depth_float
+ WGL_DEPTH_FLOAT_EXT = $2040;
+
+ // WGL_EXT_make_current_read
+ ERROR_INVALID_PIXEL_TYPE_EXT = $2043;
+
+ // WGL_EXT_multisample
+ WGL_SAMPLE_BUFFERS_EXT = $2041;
+ WGL_SAMPLES_EXT = $2042;
+
+ // WGL_EXT_pbuffer
+ WGL_DRAW_TO_PBUFFER_EXT = $202D;
+ WGL_MAX_PBUFFER_PIXELS_EXT = $202E;
+ WGL_MAX_PBUFFER_WIDTH_EXT = $202F;
+ WGL_MAX_PBUFFER_HEIGHT_EXT = $2030;
+ WGL_OPTIMAL_PBUFFER_WIDTH_EXT = $2031;
+ WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = $2032;
+ WGL_PBUFFER_LARGEST_EXT = $2033;
+ WGL_PBUFFER_WIDTH_EXT = $2034;
+ WGL_PBUFFER_HEIGHT_EXT = $2035;
+
+ // WGL_EXT_pixel_format
+ WGL_NUMBER_PIXEL_FORMATS_EXT = $2000;
+ WGL_DRAW_TO_WINDOW_EXT = $2001;
+ WGL_DRAW_TO_BITMAP_EXT = $2002;
+ WGL_ACCELERATION_EXT = $2003;
+ WGL_NEED_PALETTE_EXT = $2004;
+ WGL_NEED_SYSTEM_PALETTE_EXT = $2005;
+ WGL_SWAP_LAYER_BUFFERS_EXT = $2006;
+ WGL_SWAP_METHOD_EXT = $2007;
+ WGL_NUMBER_OVERLAYS_EXT = $2008;
+ WGL_NUMBER_UNDERLAYS_EXT = $2009;
+ WGL_TRANSPARENT_EXT = $200A;
+ WGL_TRANSPARENT_VALUE_EXT = $200B;
+ WGL_SHARE_DEPTH_EXT = $200C;
+ WGL_SHARE_STENCIL_EXT = $200D;
+ WGL_SHARE_ACCUM_EXT = $200E;
+ WGL_SUPPORT_GDI_EXT = $200F;
+ WGL_SUPPORT_OPENGL_EXT = $2010;
+ WGL_DOUBLE_BUFFER_EXT = $2011;
+ WGL_STEREO_EXT = $2012;
+ WGL_PIXEL_TYPE_EXT = $2013;
+ WGL_COLOR_BITS_EXT = $2014;
+ WGL_RED_BITS_EXT = $2015;
+ WGL_RED_SHIFT_EXT = $2016;
+ WGL_GREEN_BITS_EXT = $2017;
+ WGL_GREEN_SHIFT_EXT = $2018;
+ WGL_BLUE_BITS_EXT = $2019;
+ WGL_BLUE_SHIFT_EXT = $201A;
+ WGL_ALPHA_BITS_EXT = $201B;
+ WGL_ALPHA_SHIFT_EXT = $201C;
+ WGL_ACCUM_BITS_EXT = $201D;
+ WGL_ACCUM_RED_BITS_EXT = $201E;
+ WGL_ACCUM_GREEN_BITS_EXT = $201F;
+ WGL_ACCUM_BLUE_BITS_EXT = $2020;
+ WGL_ACCUM_ALPHA_BITS_EXT = $2021;
+ WGL_DEPTH_BITS_EXT = $2022;
+ WGL_STENCIL_BITS_EXT = $2023;
+ WGL_AUX_BUFFERS_EXT = $2024;
+ WGL_NO_ACCELERATION_EXT = $2025;
+ WGL_GENERIC_ACCELERATION_EXT = $2026;
+ WGL_FULL_ACCELERATION_EXT = $2027;
+ WGL_SWAP_EXCHANGE_EXT = $2028;
+ WGL_SWAP_COPY_EXT = $2029;
+ WGL_SWAP_UNDEFINED_EXT = $202A;
+ WGL_TYPE_RGBA_EXT = $202B;
+ WGL_TYPE_COLORINDEX_EXT = $202C;
+
+ // WGL_I3D_digital_video_control
+ WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = $2050;
+ WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = $2051;
+ WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = $2052;
+ WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = $2053;
+
+ // WGL_I3D_gamma
+ WGL_GAMMA_TABLE_SIZE_I3D = $204E;
+ WGL_GAMMA_EXCLUDE_DESKTOP_I3D = $204F;
+
+ // WGL_I3D_genlock
+ WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = $2044;
+ WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D = $2045;
+ WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D = $2046;
+ WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D = $2047;
+ WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = $2048;
+ WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = $2049;
+ WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = $204A;
+ WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = $204B;
+ WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = $204C;
+
+ // WGL_I3D_image_buffer
+ WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = $00000001;
+ WGL_IMAGE_BUFFER_LOCK_I3D = $00000002;
+
+ // WGL_NV_float_buffer
+ WGL_FLOAT_COMPONENTS_NV = $20B0;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = $20B1;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = $20B2;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = $20B3;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = $20B4;
+ WGL_TEXTURE_FLOAT_R_NV = $20B5;
+ WGL_TEXTURE_FLOAT_RG_NV = $20B6;
+ WGL_TEXTURE_FLOAT_RGB_NV = $20B7;
+ WGL_TEXTURE_FLOAT_RGBA_NV = $20B8;
+
+ // WGL_NV_render_depth_texture
+ WGL_BIND_TO_TEXTURE_DEPTH_NV = $20A3;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = $20A4;
+ WGL_DEPTH_TEXTURE_FORMAT_NV = $20A5;
+ WGL_TEXTURE_DEPTH_COMPONENT_NV = $20A6;
+ WGL_DEPTH_COMPONENT_NV = $20A7;
+
+ // WGL_NV_render_texture_rectangle
+ WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = $20A0;
+ WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = $20A1;
+ WGL_TEXTURE_RECTANGLE_NV = $20A2;
+
+ // WGL_NV_present_video
+ WGL_NUM_VIDEO_SLOTS_NV = $20F0;
+
+ // WGL_NV_video_output
+ WGL_BIND_TO_VIDEO_RGB_NV = $20C0;
+ WGL_BIND_TO_VIDEO_RGBA_NV = $20C1;
+ WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV = $20C2;
+ WGL_VIDEO_OUT_COLOR_NV = $20C3;
+ WGL_VIDEO_OUT_ALPHA_NV = $20C4;
+ WGL_VIDEO_OUT_DEPTH_NV = $20C5;
+ WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV = $20C6;
+ WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV = $20C7;
+ WGL_VIDEO_OUT_FRAME = $20C8;
+ WGL_VIDEO_OUT_FIELD_1 = $20C9;
+ WGL_VIDEO_OUT_FIELD_2 = $20CA;
+ WGL_VIDEO_OUT_STACKED_FIELDS_1_2 = $20CB;
+ WGL_VIDEO_OUT_STACKED_FIELDS_2_1 = $20CC;
+
+ // WGL_NV_gpu_affinity
+ WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV = $20D0;
+ WGL_ERROR_MISSING_AFFINITY_MASK_NV = $20D1;
+
+ // WGL_NV_video_capture
+ WGL_UNIQUE_ID_NV = $20CE;
+ WGL_NUM_VIDEO_CAPTURE_SLOTS_NV = $20CF;
+
+ // WGL_NV_multisample_coverage
+ WGL_COVERAGE_SAMPLES_NV = $2042;
+ WGL_COLOR_SAMPLES_NV = $20B9;
+
+ // WGL_EXT_create_context_es2_profile
+ WGL_CONTEXT_ES2_PROFILE_BIT_EXT = $00000004;
+
+ // WGL_NV_DX_interop
+ WGL_ACCESS_READ_ONLY_NV = $00000000;
+ WGL_ACCESS_READ_WRITE_NV = $00000001;
+ WGL_ACCESS_WRITE_DISCARD_NV = $00000002;
+
+ // WIN_draw_range_elements
+ GL_MAX_ELEMENTS_VERTICES_WIN = $80E8;
+ GL_MAX_ELEMENTS_INDICES_WIN = $80E9;
+
+ // GLX 1.1 and later:
+ GLX_VENDOR = 1;
+ GLX_VERSION = 2;
+ GLX_EXTENSIONS = 3;
+
+ GLX_USE_GL = 1;
+ GLX_BUFFER_SIZE = 2;
+ GLX_LEVEL = 3;
+ GLX_RGBA = 4;
+ GLX_DOUBLEBUFFER = 5;
+ GLX_STEREO = 6;
+ GLX_AUX_BUFFERS = 7;
+ GLX_RED_SIZE = 8;
+ GLX_GREEN_SIZE = 9;
+ GLX_BLUE_SIZE = 10;
+ GLX_ALPHA_SIZE = 11;
+ GLX_DEPTH_SIZE = 12;
+ GLX_STENCIL_SIZE = 13;
+ GLX_ACCUM_RED_SIZE = 14;
+ GLX_ACCUM_GREEN_SIZE = 15;
+ GLX_ACCUM_BLUE_SIZE = 16;
+ GLX_ACCUM_ALPHA_SIZE = 17;
+
+ // GLX_VERSION_1_3
+ GLX_WINDOW_BIT = $00000001;
+ GLX_PIXMAP_BIT = $00000002;
+ GLX_PBUFFER_BIT = $00000004;
+ GLX_RGBA_BIT = $00000001;
+ GLX_COLOR_INDEX_BIT = $00000002;
+ GLX_PBUFFER_CLOBBER_MASK = $08000000;
+ GLX_FRONT_LEFT_BUFFER_BIT = $00000001;
+ GLX_FRONT_RIGHT_BUFFER_BIT = $00000002;
+ GLX_BACK_LEFT_BUFFER_BIT = $00000004;
+ GLX_BACK_RIGHT_BUFFER_BIT = $00000008;
+ GLX_AUX_BUFFERS_BIT = $00000010;
+ GLX_DEPTH_BUFFER_BIT = $00000020;
+ GLX_STENCIL_BUFFER_BIT = $00000040;
+ GLX_ACCUM_BUFFER_BIT = $00000080;
+ GLX_CONFIG_CAVEAT = $20;
+ GLX_X_VISUAL_TYPE = $22;
+ GLX_TRANSPARENT_TYPE = $23;
+ GLX_TRANSPARENT_INDEX_VALUE = $24;
+ GLX_TRANSPARENT_RED_VALUE = $25;
+ GLX_TRANSPARENT_GREEN_VALUE = $26;
+ GLX_TRANSPARENT_BLUE_VALUE = $27;
+ GLX_TRANSPARENT_ALPHA_VALUE = $28;
+ GLX_DONT_CARE = $FFFFFFFF;
+ GLX_NONE = $8000;
+ GLX_SLOW_CONFIG = $8001;
+ GLX_TRUE_COLOR = $8002;
+ GLX_DIRECT_COLOR = $8003;
+ GLX_PSEUDO_COLOR = $8004;
+ GLX_STATIC_COLOR = $8005;
+ GLX_GRAY_SCALE = $8006;
+ GLX_STATIC_GRAY = $8007;
+ GLX_TRANSPARENT_RGB = $8008;
+ GLX_TRANSPARENT_INDEX = $8009;
+ GLX_VISUAL_ID = $800B;
+ GLX_SCREEN = $800C;
+ GLX_NON_CONFORMANT_CONFIG = $800D;
+ GLX_DRAWABLE_TYPE = $8010;
+ GLX_RENDER_TYPE = $8011;
+ GLX_X_RENDERABLE = $8012;
+ GLX_FBCONFIG_ID = $8013;
+ GLX_RGBA_TYPE = $8014;
+ GLX_COLOR_INDEX_TYPE = $8015;
+ GLX_MAX_PBUFFER_WIDTH = $8016;
+ GLX_MAX_PBUFFER_HEIGHT = $8017;
+ GLX_MAX_PBUFFER_PIXELS = $8018;
+ GLX_PRESERVED_CONTENTS = $801B;
+ GLX_LARGEST_PBUFFER = $801C;
+ GLX_WIDTH = $801D;
+ GLX_HEIGHT = $801E;
+ GLX_EVENT_MASK = $801F;
+ GLX_DAMAGED = $8020;
+ GLX_SAVED = $8021;
+ GLX_WINDOW = $8022;
+ GLX_PBUFFER = $8023;
+ GLX_PBUFFER_HEIGHT = $8040;
+ GLX_PBUFFER_WIDTH = $8041;
+
+ // GLX_VERSION_1_4
+ GLX_SAMPLE_BUFFERS = 100000;
+ GLX_SAMPLES = 100001;
+
+ // GLX_ARB_multisample
+ GLX_SAMPLE_BUFFERS_ARB = 100000;
+ GLX_SAMPLES_ARB = 100001;
+
+ // GLX_ARB_robustness_application_isolation
+ GLX_CONTEXT_RESET_ISOLATION_BIT_ARB = $00000008;
+
+ // GLX_ARB_fbconfig_float
+ GLX_RGBA_FLOAT_TYPE_ARB = $20B9;
+ GLX_RGBA_FLOAT_BIT_ARB = $00000004;
+
+ // GLX_ARB_context_flush_control
+ GLX_CONTEXT_RELEASE_BEHAVIOR_ARB = $2097;
+ GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB = 0;
+ GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = $2098;
+
+ // GLX_ARB_create_context
+ GLX_CONTEXT_DEBUG_BIT_ARB = $00000001;
+ GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = $00000002;
+ GLX_CONTEXT_MAJOR_VERSION_ARB = $2091;
+ GLX_CONTEXT_MINOR_VERSION_ARB = $2092;
+ GLX_CONTEXT_FLAGS_ARB = $2094;
+
+ // GLX_ARB_create_context_profile
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB = $00000001;
+ GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = $00000002;
+ GLX_CONTEXT_PROFILE_MASK_ARB = $9126;
+
+ // GLX_ARB_vertex_buffer_object
+ GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB = $2095;
+
+ // GLX_ARB_framebuffer_sRGB
+ GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB = $20B2;
+
+ // GLX_ARB_create_context_robustness
+ GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB = $00000004;
+ GLX_LOSE_CONTEXT_ON_RESET_ARB = $8252;
+ GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = $8256;
+ GLX_NO_RESET_NOTIFICATION_ARB = $8261;
+
+ // GLX_EXT_visual_info
+ GLX_X_VISUAL_TYPE_EXT = $22;
+ GLX_TRANSPARENT_TYPE_EXT = $23;
+ GLX_TRANSPARENT_INDEX_VALUE_EXT = $24;
+ GLX_TRANSPARENT_RED_VALUE_EXT = $25;
+ GLX_TRANSPARENT_GREEN_VALUE_EXT = $26;
+ GLX_TRANSPARENT_BLUE_VALUE_EXT = $27;
+ GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28;
+ GLX_NONE_EXT = $8000;
+ GLX_TRUE_COLOR_EXT = $8002;
+ GLX_DIRECT_COLOR_EXT = $8003;
+ GLX_PSEUDO_COLOR_EXT = $8004;
+ GLX_STATIC_COLOR_EXT = $8005;
+ GLX_GRAY_SCALE_EXT = $8006;
+ GLX_STATIC_GRAY_EXT = $8007;
+ GLX_TRANSPARENT_RGB_EXT = $8008;
+ GLX_TRANSPARENT_INDEX_EXT = $8009;
+
+ // GLX_EXT_visual_rating
+ GLX_VISUAL_CAVEAT_EXT = $20;
+ GLX_SLOW_VISUAL_EXT = $8001;
+ GLX_NON_CONFORMANT_VISUAL_EXT = $800D;
+ (* reuse GLX_NONE_EXT *)
+
+ // GLX_EXT_import_context
+ GLX_SHARE_CONTEXT_EXT = $800A;
+ GLX_VISUAL_ID_EXT = $800B;
+ GLX_SCREEN_EXT = $800C;
+
+ // GLX_EXT_fbconfig_packed_float
+// GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT = $20B1;
+// GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT = $00000008;
+
+ // GLX_EXT_framebuffer_sRGB
+// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT = $20B2;
+
+ // GLX_EXT_texture_from_pixmap
+ GLX_TEXTURE_1D_BIT_EXT = $00000001;
+ GLX_TEXTURE_2D_BIT_EXT = $00000002;
+ GLX_TEXTURE_RECTANGLE_BIT_EXT = $00000004;
+ GLX_BIND_TO_TEXTURE_RGB_EXT = $20D0;
+ GLX_BIND_TO_TEXTURE_RGBA_EXT = $20D1;
+ GLX_BIND_TO_MIPMAP_TEXTURE_EXT = $20D2;
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT = $20D3;
+ GLX_Y_INVERTED_EXT = $20D4;
+ GLX_TEXTURE_FORMAT_EXT = $20D5;
+ GLX_TEXTURE_TARGET_EXT = $20D6;
+ GLX_MIPMAP_TEXTURE_EXT = $20D7;
+ GLX_TEXTURE_FORMAT_NONE_EXT = $20D8;
+ GLX_TEXTURE_FORMAT_RGB_EXT = $20D9;
+ GLX_TEXTURE_FORMAT_RGBA_EXT = $20DA;
+ GLX_TEXTURE_1D_EXT = $20DB;
+ GLX_TEXTURE_2D_EXT = $20DC;
+ GLX_TEXTURE_RECTANGLE_EXT = $20DD;
+ GLX_FRONT_LEFT_EXT = $20DE;
+ GLX_FRONT_RIGHT_EXT = $20DF;
+ GLX_BACK_LEFT_EXT = $20E0;
+ GLX_BACK_RIGHT_EXT = $20E1;
+ GLX_FRONT_EXT = GLX_FRONT_LEFT_EXT;
+ GLX_BACK_EXT = GLX_BACK_LEFT_EXT;
+ GLX_AUX0_EXT = $20E2;
+ GLX_AUX1_EXT = $20E3;
+ GLX_AUX2_EXT = $20E4;
+ GLX_AUX3_EXT = $20E5;
+ GLX_AUX4_EXT = $20E6;
+ GLX_AUX5_EXT = $20E7;
+ GLX_AUX6_EXT = $20E8;
+ GLX_AUX7_EXT = $20E9;
+ GLX_AUX8_EXT = $20EA;
+ GLX_AUX9_EXT = $20EB;
+
+ // GLX_EXT_swap_control
+ GLX_SWAP_INTERVAL_EXT = $20F1;
+ GLX_MAX_SWAP_INTERVAL_EXT = $20F2;
+
+ // GLX_EXT_create_context_es2_profile
+ GLX_CONTEXT_ES2_PROFILE_BIT_EXT = $00000004;
+
+ // GL_EXT_Late_Swaps
+ GLX_LATE_SWAPS_TEAR_EXT = $20F3;
+
+ // GLU
+ GLU_INVALID_ENUM = 100900;
+ GLU_INVALID_VALUE = 100901;
+ GLU_OUT_OF_MEMORY = 100902;
+ GLU_INCOMPATIBLE_GL_VERSION = 100903;
+ GLU_VERSION = 100800;
+ GLU_EXTENSIONS = 100801;
+ GLU_TRUE: ByteBool = True;
+ GLU_FALSE: ByteBool = False;
+ GLU_SMOOTH = 100000;
+ GLU_FLAT = 100001;
+ GLU_NONE = 100002;
+ GLU_POINT = 100010;
+ GLU_LINE = 100011;
+ GLU_FILL = 100012;
+ GLU_SILHOUETTE = 100013;
+ GLU_OUTSIDE = 100020;
+ GLU_INSIDE = 100021;
+ GLU_TESS_MAX_COORD = 1.0E150;
+ GLU_TESS_WINDING_RULE = 100140;
+ GLU_TESS_BOUNDARY_ONLY = 100141;
+ GLU_TESS_TOLERANCE = 100142;
+ GLU_TESS_WINDING_ODD = 100130;
+ GLU_TESS_WINDING_NONZERO = 100131;
+ GLU_TESS_WINDING_POSITIVE = 100132;
+ GLU_TESS_WINDING_NEGATIVE = 100133;
+ GLU_TESS_WINDING_ABS_GEQ_TWO = 100134;
+ GLU_TESS_BEGIN = 100100; // TGLUTessBeginProc
+ GLU_TESS_VERTEX = 100101; // TGLUTessVertexProc
+ GLU_TESS_END = 100102; // TGLUTessEndProc
+ GLU_TESS_ERROR = 100103; // TGLUTessErrorProc
+ GLU_TESS_EDGE_FLAG = 100104; // TGLUTessEdgeFlagProc
+ GLU_TESS_COMBINE = 100105; // TGLUTessCombineProc
+ GLU_TESS_BEGIN_DATA = 100106; // TGLUTessBeginDataProc
+ GLU_TESS_VERTEX_DATA = 100107; // TGLUTessVertexDataProc
+ GLU_TESS_END_DATA = 100108; // TGLUTessEndDataProc
+ GLU_TESS_ERROR_DATA = 100109; // TGLUTessErrorDataProc
+ GLU_TESS_EDGE_FLAG_DATA = 100110; // TGLUTessEdgeFlagDataProc
+ GLU_TESS_COMBINE_DATA = 100111; // TGLUTessCombineDataProc
+ GLU_TESS_ERROR1 = 100151;
+ GLU_TESS_ERROR2 = 100152;
+ GLU_TESS_ERROR3 = 100153;
+ GLU_TESS_ERROR4 = 100154;
+ GLU_TESS_ERROR5 = 100155;
+ GLU_TESS_ERROR6 = 100156;
+ GLU_TESS_ERROR7 = 100157;
+ GLU_TESS_ERROR8 = 100158;
+ GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1;
+ GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2;
+ GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3;
+ GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4;
+ GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5;
+ GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6;
+ GLU_AUTO_LOAD_MATRIX = 100200;
+ GLU_CULLING = 100201;
+ GLU_SAMPLING_TOLERANCE = 100203;
+ GLU_DISPLAY_MODE = 100204;
+ GLU_PARAMETRIC_TOLERANCE = 100202;
+ GLU_SAMPLING_METHOD = 100205;
+ GLU_U_STEP = 100206;
+ GLU_V_STEP = 100207;
+ GLU_PATH_LENGTH = 100215;
+ GLU_PARAMETRIC_ERROR = 100216;
+ GLU_DOMAIN_DISTANCE = 100217;
+ GLU_MAP1_TRIM_2 = 100210;
+ GLU_MAP1_TRIM_3 = 100211;
+ GLU_OUTLINE_POLYGON = 100240;
+ GLU_OUTLINE_PATCH = 100241;
+ GLU_NURBS_ERROR1 = 100251;
+ GLU_NURBS_ERROR2 = 100252;
+ GLU_NURBS_ERROR3 = 100253;
+ GLU_NURBS_ERROR4 = 100254;
+ GLU_NURBS_ERROR5 = 100255;
+ GLU_NURBS_ERROR6 = 100256;
+ GLU_NURBS_ERROR7 = 100257;
+ GLU_NURBS_ERROR8 = 100258;
+ GLU_NURBS_ERROR9 = 100259;
+ GLU_NURBS_ERROR10 = 100260;
+ GLU_NURBS_ERROR11 = 100261;
+ GLU_NURBS_ERROR12 = 100262;
+ GLU_NURBS_ERROR13 = 100263;
+ GLU_NURBS_ERROR14 = 100264;
+ GLU_NURBS_ERROR15 = 100265;
+ GLU_NURBS_ERROR16 = 100266;
+ GLU_NURBS_ERROR17 = 100267;
+ GLU_NURBS_ERROR18 = 100268;
+ GLU_NURBS_ERROR19 = 100269;
+ GLU_NURBS_ERROR20 = 100270;
+ GLU_NURBS_ERROR21 = 100271;
+ GLU_NURBS_ERROR22 = 100272;
+ GLU_NURBS_ERROR23 = 100273;
+ GLU_NURBS_ERROR24 = 100274;
+ GLU_NURBS_ERROR25 = 100275;
+ GLU_NURBS_ERROR26 = 100276;
+ GLU_NURBS_ERROR27 = 100277;
+ GLU_NURBS_ERROR28 = 100278;
+ GLU_NURBS_ERROR29 = 100279;
+ GLU_NURBS_ERROR30 = 100280;
+ GLU_NURBS_ERROR31 = 100281;
+ GLU_NURBS_ERROR32 = 100282;
+ GLU_NURBS_ERROR33 = 100283;
+ GLU_NURBS_ERROR34 = 100284;
+ GLU_NURBS_ERROR35 = 100285;
+ GLU_NURBS_ERROR36 = 100286;
+ GLU_NURBS_ERROR37 = 100287;
+ GLU_CW = 100120;
+ GLU_CCW = 100121;
+ GLU_INTERIOR = 100122;
+ GLU_EXTERIOR = 100123;
+ GLU_UNKNOWN = 100124;
+ GLU_BEGIN = GLU_TESS_BEGIN;
+ GLU_VERTEX = GLU_TESS_VERTEX;
+ GLU_END = GLU_TESS_END;
+ GLU_ERROR = GLU_TESS_ERROR;
+ GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG;
+
+type
+ // GL_VERSION_1_0
+ TglCullFace = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFrontFace = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglHint = procedure(target: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLineWidth = procedure(width: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointSize = procedure(size: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPolygonMode = procedure(face: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScissor = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterf = procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawBuffer = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClear = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearColor = procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearStencil = procedure(s: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearDepth = procedure(depth: GLclampd); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilMask = procedure(mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorMask = procedure(red: GLboolean; green: GLboolean; blue: GLboolean; alpha: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthMask = procedure(flag: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisable = procedure(cap: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnable = procedure(cap: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinish = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlush = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFunc = procedure(sfactor: GLenum; dfactor: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLogicOp = procedure(opcode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilFunc = procedure(func: GLenum; ref: GLint; mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilOp = procedure(fail: GLenum; zfail: GLenum; zpass: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthFunc = procedure(func: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelStoref = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReadBuffer = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBooleanv = procedure(pname: GLenum; params: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDoublev = procedure(pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetError = function(): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFloatv = procedure(pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsEnabled = function(cap: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthRange = procedure(zNear: GLclampd; zFar: GLclampd); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglViewport = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_1_1
+ TglDrawArrays = procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElements = procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPointerv = procedure(pname: GLenum; params: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPolygonOffset = procedure(factor: GLfloat; units: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexImage1D = procedure(target: GLenum; level: GLint; internalFormat: GLenum; x: GLint; y: GLint; width: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexImage2D = procedure(target: GLenum; level: GLint; internalFormat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage1D = procedure(target: GLenum; level: GLint; xoffset: GLint; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage2D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage1D = procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage2D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+{$ifdef DGL_DEPRECATED}
+ TglAccum = procedure(op: GLenum; value: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAlphaFunc = procedure(func: GLenum; ref: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglArrayElement = procedure(i: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBegin = procedure(mode: GLenum); {$IFNDEF CLR}{$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}{$ENDIF}
+ TglBitmap = procedure(width: GLsizei; height: GLsizei; xorig: GLfloat; yorig: GLfloat; xmove: GLfloat; ymove: GLfloat; const bitmap: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCallList = procedure(list: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCallLists = procedure(n: GLsizei; _type: GLenum; const lists: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearAccum = procedure(red: GLfloat; green: GLfloat; blue: GLfloat; alpha: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearIndex = procedure(c: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClipPlane = procedure(plane: GLenum; const equation: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3b = procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3bv = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3d = procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3f = procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3i = procedure(red: GLint; green: GLint; blue: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3s = procedure(red: GLshort; green: GLshort; blue: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3ub = procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3ubv = procedure(const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3ui = procedure(red: GLuint; green: GLuint; blue: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3uiv = procedure(const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3us = procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3usv = procedure(const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4b = procedure(red: GLbyte; green: GLbyte; blue: GLbyte; alpha: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4bv = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4d = procedure(red: GLdouble; green: GLdouble; blue: GLdouble; alpha: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4f = procedure(red: GLfloat; green: GLfloat; blue: GLfloat; alpha: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4i = procedure(red: GLint; green: GLint; blue: GLint; alpha: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4s = procedure(red: GLshort; green: GLshort; blue: GLshort; alpha: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ub = procedure(red: GLubyte; green: GLubyte; blue: GLubyte; alpha: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ubv = procedure(const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ui = procedure(red: GLuint; green: GLuint; blue: GLuint; alpha: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4uiv = procedure(const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4us = procedure(red: GLushort; green: GLushort; blue: GLushort; alpha: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4usv = procedure(const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorMaterial = procedure(face: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorPointer = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; _type: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteLists = procedure(list: GLuint; range: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableClientState = procedure(_array: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawPixels = procedure(width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlag = procedure(flag: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlagPointer = procedure(stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlagv = procedure(const flag: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableClientState = procedure(_array: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnd = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndList = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord1d = procedure(u: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord1dv = procedure(const u: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord1f = procedure(u: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord1fv = procedure(const u: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord2d = procedure(u: GLdouble; v: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord2dv = procedure(const u: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord2f = procedure(u: GLfloat; v: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalCoord2fv = procedure(const u: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalMesh1 = procedure(mode: GLenum; i1: GLint; i2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalMesh2 = procedure(mode: GLenum; i1: GLint; i2: GLint; j1: GLint; j2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalPoint1 = procedure(i: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalPoint2 = procedure(i: GLint; j: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFeedbackBuffer = procedure(size: GLsizei; _type: GLenum; buffer: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogf = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogfv = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogi = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogiv = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFrustum = procedure(left: GLdouble; right: GLdouble; bottom: GLdouble; top: GLdouble; zNear: GLdouble; zFar: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenLists = function(range: GLsizei): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetClipPlane = procedure(plane: GLenum; equation: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetLightfv = procedure(light: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetLightiv = procedure(light: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapdv = procedure(target: GLenum; query: GLenum; v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapfv = procedure(target: GLenum; query: GLenum; v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapiv = procedure(target: GLenum; query: GLenum; v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMaterialfv = procedure(face: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMaterialiv = procedure(face: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPixelMapfv = procedure(map: GLenum; values: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPixelMapuiv = procedure(map: GLenum; values: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPixelMapusv = procedure(map: GLenum; values: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPolygonStipple = procedure(mask: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexEnvfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexEnviv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexGendv = procedure(coord: GLenum; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexGenfv = procedure(coord: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexGeniv = procedure(coord: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexMask = procedure(mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexPointer = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexd = procedure(c: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexdv = procedure(const c: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexf = procedure(c: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexfv = procedure(const c: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexi = procedure(c: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexiv = procedure(const c: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexs = procedure(c: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexsv = procedure(const c: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexub = procedure(c: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexubv = procedure(const c: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInitNames = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInterleavedArrays = procedure(format: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsList = function(list: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTexture = function(texture: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightModelf = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightModelfv = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightModeli = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightModeliv = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightf = procedure(light: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightfv = procedure(light: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLighti = procedure(light: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightiv = procedure(light: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLineStipple = procedure(factor: GLint; pattern: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglListBase = procedure(base: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadIdentity = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadMatrixd = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadMatrixf = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadName = procedure(name: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMap1d = procedure(target: GLenum; u1: GLdouble; u2: GLdouble; stride: GLint; order: GLint; const points: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMap1f = procedure(target: GLenum; u1: GLfloat; u2: GLfloat; stride: GLint; order: GLint; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMap2d = procedure(target: GLenum; u1: GLdouble; u2: GLdouble; ustride: GLint; uorder: GLint; v1: GLdouble; v2: GLdouble; vstride: GLint; vorder: GLint; const points: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMap2f = procedure(target: GLenum; u1: GLfloat; u2: GLfloat; ustride: GLint; uorder: GLint; v1: GLfloat; v2: GLfloat; vstride: GLint; vorder: GLint; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapGrid1d = procedure(un: GLint; u1: GLdouble; u2: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapGrid1f = procedure(un: GLint; u1: GLfloat; u2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapGrid2d = procedure(un: GLint; u1: GLdouble; u2: GLdouble; vn: GLint; v1: GLdouble; v2: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapGrid2f = procedure(un: GLint; u1: GLfloat; u2: GLfloat; vn: GLint; v1: GLfloat; v2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMaterialf = procedure(face: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMaterialfv = procedure(face: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMateriali = procedure(face: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMaterialiv = procedure(face: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixMode = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultMatrixd = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultMatrixf = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNewList = procedure(list: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3b = procedure(nx: GLbyte; ny: GLbyte; nz: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3bv = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3d = procedure(nx: GLdouble; ny: GLdouble; nz: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3f = procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3i = procedure(nx: GLint; ny: GLint; nz: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3s = procedure(nx: GLshort; ny: GLshort; nz: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalPointer = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglOrtho = procedure(left: GLdouble; right: GLdouble; bottom: GLdouble; top: GLdouble; zNear: GLdouble; zFar: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPassThrough = procedure(token: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelMapfv = procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelMapuiv = procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelMapusv = procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTransferf = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTransferi = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelZoom = procedure(xfactor: GLfloat; yfactor: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPolygonStipple = procedure(const mask: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPopAttrib = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPopClientAttrib = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPopMatrix = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPopName = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPrioritizeTextures = procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushAttrib = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushClientAttrib = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushMatrix = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushName = procedure(name: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2d = procedure(x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2f = procedure(x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2i = procedure(x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2s = procedure(x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos2sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3d = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3f = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3i = procedure(x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3s = procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4d = procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4f = procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4i = procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4s = procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRasterPos4sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectd = procedure(x1: GLdouble; y1: GLdouble; x2: GLdouble; y2: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectdv = procedure(const v1: PGLdouble; const v2: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectf = procedure(x1: GLfloat; y1: GLfloat; x2: GLfloat; y2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectfv = procedure(const v1: PGLfloat; const v2: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRecti = procedure(x1: GLint; y1: GLint; x2: GLint; y2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectiv = procedure(const v1: PGLint; const v2: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRects = procedure(x1: GLshort; y1: GLshort; x2: GLshort; y2: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRectsv = procedure(const v1: PGLshort; const v2: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRenderMode = function(mode: GLenum): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRotated = procedure(angle: GLdouble; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRotatef = procedure(angle: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScaled = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScalef = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSelectBuffer = procedure(size: GLsizei; buffer: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShadeModel = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1d = procedure(s: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1f = procedure(s: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1i = procedure(s: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1s = procedure(s: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2d = procedure(s: GLdouble; t: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2f = procedure(s: GLfloat; t: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2i = procedure(s: GLint; t: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2s = procedure(s: GLshort; t: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3d = procedure(s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3f = procedure(s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3i = procedure(s: GLint; t: GLint; r: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3s = procedure(s: GLshort; t: GLshort; r: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4d = procedure(s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4f = procedure(s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4i = procedure(s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4s = procedure(s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordPointer = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexEnvf = procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexEnvfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexEnvi = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexEnviv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGend = procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGendv = procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGenf = procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGenfv = procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexGeniv = procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+
+ TglTranslated = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTranslatef = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2d = procedure(x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2f = procedure(x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2i = procedure(x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2s = procedure(x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3d = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3f = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3i = procedure(x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3s = procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4d = procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4f = procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4i = procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4s = procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexPointer = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$endif}
+
+ // GL_VERSION_1_2
+ TglBlendColor = procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquation = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawRangeElements = procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexImage3D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage3D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage3D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$ifdef DGL_DEPRECATED}
+ TglColorTable = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorTableParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorTableParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyColorTable = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTable = procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorSubTable = procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyColorSubTable = procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionFilter1D = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionFilter2D = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameterf = procedure(target: GLenum; pname: GLenum; params: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameteri = procedure(target: GLenum; pname: GLenum; params: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyConvolutionFilter1D = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyConvolutionFilter2D = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionFilter = procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSeparableFilter = procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSeparableFilter2D = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHistogram = procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHistogramParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHistogramParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmax = procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmaxParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmaxParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglHistogram = procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMinmax = procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResetHistogram = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResetMinmax = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$endif}
+
+ // GL_VERSION_1_3
+ TglActiveTexture = procedure(texture: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSampleCoverage = procedure(value: GLclampf; invert: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexImage3D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage3D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage2D = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage1D = procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$ifdef DGL_DEPRECATED}
+ TglClientActiveTexture = procedure(texture: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1d = procedure(target: GLenum; s: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1dv = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1f = procedure(target: GLenum; s: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1fv = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1i = procedure(target: GLenum; s: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1iv = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1s = procedure(target: GLenum; s: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1sv = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2d = procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2dv = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2f = procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2fv = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2i = procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2iv = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2s = procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2sv = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3d = procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3dv = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3f = procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3fv = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3i = procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3iv = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3s = procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3sv = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4d = procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4dv = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4f = procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4fv = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4i = procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4iv = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4s = procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4sv = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadTransposeMatrixf = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadTransposeMatrixd = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultTransposeMatrixf = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultTransposeMatrixd = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$endif}
+
+ // GL_VERSION_1_4
+ TglBlendFuncSeparate = procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawArrays = procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElements = procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterf = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterfv = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameteri = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameteriv = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$ifdef DGL_DEPRECATED}
+ TglFogCoordf = procedure(coord: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordfv = procedure(const coord: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordd = procedure(coord: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoorddv = procedure(const coord: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordPointer = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3b = procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3bv = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3d = procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3f = procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3i = procedure(red: GLint; green: GLint; blue: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3s = procedure(red: GLshort; green: GLshort; blue: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ub = procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ubv = procedure(const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ui = procedure(red: GLuint; green: GLuint; blue: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3uiv = procedure(const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3us = procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3usv = procedure(const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorPointer = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2d = procedure(x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2f = procedure(x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2i = procedure(x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2s = procedure(x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3d = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3dv = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3f = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3fv = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3i = procedure(x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3iv = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3s = procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3sv = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+{$endif}
+
+ // GL_VERSION_1_5
+ TglGenQueries = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteQueries = procedure(n: GLsizei; const ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsQuery = function(id: GLuint): boolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginQuery = procedure(target: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndQuery = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryiv = procedure(target, pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectiv = procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectuiv = procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBuffer = procedure(target: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteBuffers = procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenBuffers = procedure(n: GLsizei; buffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsBuffer = function(buffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBufferData = procedure(target: GLenum; size: GLsizeiptr; const data: PGLvoid; usage: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBufferSubData = procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferSubData = procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapBuffer = function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnmapBuffer = function(target: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferPointerv = procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_2_0
+ TglBlendEquationSeparate = procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawBuffers = procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilOpSeparate = procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilFuncSeparate = procedure(face: GLenum; func: GLenum; ref: GLint; mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilMaskSeparate = procedure(face: GLenum; mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAttachShader = procedure(programObj, shaderObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindAttribLocation = procedure(programObj: GLhandle; index: GLuint; name: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompileShader = procedure(shaderObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateProgram = function: GLhandle; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateShader = function(shaderType: GLenum): GLhandle; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteProgram = procedure(programObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteShader = procedure(shaderObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDetachShader = procedure(programObj, shaderObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableVertexAttribArray = procedure(index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableVertexAttribArray = procedure(index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveAttrib = procedure(programObj: GLhandle; index: GLuint; maxlength: GLsizei; var length: GLint; var size: GLint; var _type: GLenum; name: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniform = procedure(programObj: GLhandle; index: GLuint; maxLength: GLsizei; var length: GLsizei; var size: GLint; var _type: GLenum; name: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetAttachedShaders = procedure(programObj: GLhandle; MaxCount: GLsizei; var Count: GLint; shaders: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetAttribLocation = function(programObj: GLhandle; char: PGLChar): glint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramiv = procedure(programObj: GLhandle; pname: GLenum; params: PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramInfoLog = procedure(programObj: GLHandle; maxLength: glsizei; length: PGLSizei; infoLog: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetShaderiv = procedure(shaderObj: GLhandle; pname: GLenum; params: PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetShaderInfoLog = procedure(shaderObj: GLHandle; maxLength: glsizei; length: PGLSizei; infoLog: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetShaderSource = procedure(shaderObj: GLhandle; maxlength: GLsizei; var length: GLsizei; source: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformLocation = function(programObj: GLhandle; const char: PGLChar): glint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformfv = procedure(programObj: GLhandle; location: GLint; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformiv = procedure(programObj: GLhandle; location: GLint; params: PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribfv = procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribiv = procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribPointerv = procedure(index: GLuint; pname: GLenum; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsProgram = function(programObj: GLhandle) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsShader = function(shaderObj: GLhandle) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLinkProgram = procedure(programObj: GLHandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderSource = procedure(shaderObj: GLHandle; count: glsizei; const _string: PPGLChar; lengths: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUseProgram = procedure(programObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1f = procedure(location: GLint; v0: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2f = procedure(location: GLint; v0, v1: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3f = procedure(location: GLint; v0, v1, v2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4f = procedure(location: GLint; v0, v1, v2, v3: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1i = procedure(location: GLint; v0: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2i = procedure(location: GLint; v0, v1: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3i = procedure(location: GLint; v0, v1, v2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4i = procedure(location: GLint; v0, v1, v2, v3: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1fv = procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2fv = procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3fv = procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4fv = procedure(location: GLint; count: GLsizei; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1iv = procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2iv = procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3iv = procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4iv = procedure(location: GLint; count: GLsizei; value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglValidateProgram = procedure(programObj: GLhandle); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1d = procedure(index: GLuint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1f = procedure(index: GLuint; x: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1fv = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1s = procedure(index: GLuint; x: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1sv = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2d = procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2f = procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2fv = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2s = procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2sv = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3d = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3f = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3fv = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3s = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3sv = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nbv = procedure(index: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Niv = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nsv = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nub = procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nubv = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nuiv = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4Nusv = procedure(index: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4bv = procedure(index: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4d = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4f = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4fv = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4iv = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4s = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4sv = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4ubv = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4uiv = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4usv = procedure(index: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribPointer = procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_2_1
+ TglUniformMatrix2x3fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3x2fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2x4fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4x2fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3x4fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4x3fv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_3_0
+ { OpenGL 3.0 also reuses entry points from these extensions: }
+ { ARB_framebuffer_object }
+ { ARB_map_buffer_range }
+ { ARB_vertex_array_object }
+ TglColorMaski = procedure(index_: GLuint; r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBooleani_v = procedure(target: GLenum; index_: GLuint; data: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetIntegeri_v = procedure(target: GLenum; index_: GLuint; data: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnablei = procedure(target: GLenum; index_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisablei = procedure(target: GLenum; index_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsEnabledi = function(target: GLenum; index_: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginTransformFeedback = procedure(primitiveMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndTransformFeedback = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferRange = procedure(target: GLenum; index_: GLuint; buffer: GLuint; offset: GLintptr; size: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferBase = procedure(target: GLenum; index_: GLuint; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackVaryings = procedure(program_: GLuint; count: GLsizei; const varyings: PPGLchar; bufferMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbackVarying = procedure(program_: GLuint; index_: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLsizei; type_: PGLsizei; name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClampColor = procedure(targe: GLenum; clamp: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginConditionalRender = procedure(id: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndConditionalRender = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribIPointer = procedure(index_: GLuint; size: GLint; type_: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribIiv = procedure(index_: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribIuiv = procedure(index_: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1i = procedure(index_: GLuint; x: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2i = procedure(index_: GLuint; x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3i = procedure(index_: GLuint; x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4i = procedure(index_: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1ui = procedure(index_: GLuint; x: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2ui = procedure(index_: GLuint; x: GLuint; y: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3ui = procedure(index_: GLuint; x: GLuint; y: GLuint; z: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4ui = procedure(index_: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1iv = procedure(index_: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2iv = procedure(index_: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3iv = procedure(index_: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4iv = procedure(index_: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1uiv = procedure(index_: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2uiv = procedure(index_: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3uiv = procedure(index_: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4uiv = procedure(index_: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4bv = procedure(index_: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4sv = procedure(index_: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4ubv = procedure(index_: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4usv = procedure(index_: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformuiv = procedure(program_: GLuint; location: GLint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindFragDataLocation = procedure(program_: GLuint; color: GLuint; const name: PGLChar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragDataLocation = function(program_: GLuint; const name: PGLChar): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ui = procedure(location: GLint; v0: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ui = procedure(location: GLint; v0: GLuint; v1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ui = procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ui = procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1uiv = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2uiv = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3uiv = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4uiv = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterIiv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterIuiv = procedure(target: GLenum; pname: GLenum; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterIiv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterIuiv = procedure(target: GLenum; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearBufferiv = procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearBufferuiv = procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearBufferfv = procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearBufferfi = procedure(buffer: GLenum; drawbuffer: GLint; depth: GLfloat; stencil: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetStringi = function(name: GLenum; index: GLuint): PGLubyte; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_2_1
+ TglEnableVertexArrayEXT = procedure(vaobj: GLuint; array_: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableVertexArrayAttribEXT = procedure(vaobj: GLuint; index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribOffsetEXT = procedure(vaobj: GLuint; buffer: GLuint; index: GLuint; size: GLint; type_: GLenum; normalized: GLboolean; stride: GLsizei; offset: GLintptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_3_1
+ { OpenGL 3.1 also reuses entry points from these extensions: }
+ { ARB_copy_buffer }
+ { ARB_uniform_buffer_object }
+ TglDrawArraysInstanced = procedure(mode: GLenum; first: GLint; count: GLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstanced = procedure(mode: GLenum; count: GLsizei; type_: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexBuffer = procedure(target: GLenum; internalformat: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPrimitiveRestartIndex = procedure(index_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_3_2
+ { OpenGL 3.2 also reuses entry points from these extensions: }
+ { ARB_draw_elements_base_vertex }
+ { ARB_provoking_vertex }
+ { ARB_sync }
+ { ARB_texture_multisample }
+ TglGetInteger64i_v = procedure(target: GLenum; index_: GLuint; data: PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferParameteri64v = procedure(target: GLenum; pname: GLenum; params: PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+// TglFramebufferTextureFace = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; face: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_3_3
+ { OpenGL 3.3 also reuses entry points from these extensions: }
+ { ARB_blend_func_extended }
+ { ARB_sampler_objects }
+ { ARB_explicit_attrib_location, but it has none }
+ { ARB_occlusion_query2 (no entry points) }
+ { ARB_shader_bit_encoding (no entry points) }
+ { ARB_texture_rgb10_a2ui (no entry points) }
+ { ARB_texture_swizzle (no entry points) }
+ { ARB_timer_query }
+ { ARB_vertex_type_2_10_10_10_rev }
+ TglVertexAttribDivisor = procedure(index: GLuint; divisor: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_4_0
+ { OpenGL 4.0 also reuses entry points from these extensions: }
+ { ARB_texture_query_lod (no entry points) }
+ { ARB_draw_indirect }
+ { ARB_gpu_shader5 (no entry points) }
+ { ARB_gpu_shader_fp64 }
+ { ARB_shader_subroutine }
+ { ARB_tessellation_shader }
+ { ARB_texture_buffer_object_rgb32 (no entry points) }
+ { ARB_texture_cube_map_array (no entry points) }
+ { ARB_texture_gather (no entry points) }
+ { ARB_transform_feedback2 }
+ { ARB_transform_feedback3 }
+ TglMinSampleShading = procedure(value: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquationi = procedure(buf: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquationSeparatei = procedure(buf: GLuint; modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFunci = procedure(buf: GLuint; src: GLenum; dst: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFuncSeparatei = procedure(buf: GLuint; srcRGB: GLenum; dstRGB: GLenum; srcAlpha: GLenum; dstAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_VERSION_4_1
+ { OpenGL 4.1 also reuses entry points from these extensions: }
+ { ARB_ES2_compatibility }
+ { ARB_get_program_binary }
+ { ARB_separate_shader_objects }
+ { ARB_shader_precision (no entry points) }
+ { ARB_vertex_attrib_64bit }
+ { ARB_viewport_array }
+
+ // GL_3DFX_tbuffer
+ TglTbufferMask3DFX = procedure(mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_element_array
+ TglElementPointerAPPLE = procedure(_type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementArrayAPPLE = procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawRangeElementArrayAPPLE = procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElementArrayAPPLE = procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawRangeElementArrayAPPLE = procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_fence
+ TglGenFencesAPPLE = procedure(n: GLsizei; fences: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteFencesAPPLE = procedure(n: GLsizei; const fences: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSetFenceAPPLE = procedure(fence: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsFenceAPPLE = function(fence: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTestFenceAPPLE = function(fence: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinishFenceAPPLE = procedure(fence: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTestObjectAPPLE = function(_object: GLenum; name: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinishObjectAPPLE = procedure(_object: GLenum; name: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_vertex_array_object
+ TglBindVertexArrayAPPLE = procedure(_array: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteVertexArraysAPPLE = procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenVertexArraysAPPLE = procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsVertexArrayAPPLE = function(_array: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_vertex_array_range
+ TglVertexArrayRangeAPPLE = procedure(length: GLsizei; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlushVertexArrayRangeAPPLE = procedure(length: GLsizei; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayParameteriAPPLE = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_texture_range
+ TglTextureRangeAPPLE = procedure(target: GLenum; length: GLsizei; const Pointer_: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterPointervAPPLE = procedure(target: GLenum; pname: GLenum; params: PPGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_vertex_program_evaluators
+ TglEnableVertexAttribAPPLE = procedure(index_: GLuint; pname: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableVertexAttribAPPLE = procedure(index_: GLuint; pname: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsVertexAttribEnabledAPPLE = function(index_: GLuint; pname: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapVertexAttrib1dAPPLE = procedure(index_: GLuint; size: GLuint; u1: GLdouble; u2: GLdouble; stride: GLint; order: GLint; const points: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapVertexAttrib1fAPPLE = procedure(index_: GLuint; size: GLuint; u1: GLfloat; u2: GLfloat; stride: GLint; order: GLint; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapVertexAttrib2dAPPLE = procedure(index_: GLuint; size: GLuint; u1: GLdouble; u2: GLdouble; ustride: GLint; uorder: GLint; v1: GLdouble; v2: GLdouble; vstride: GLint; vorder: GLint; const points: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapVertexAttrib2fAPPLE = procedure(index_: GLuint; size: GLuint; u1: GLfloat; u2: GLfloat; ustride: GLint; order: GLint; v1: GLfloat; v2: GLfloat; vstride: GLint; vorder: GLint; const points: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_APPLE_object_purgeable
+ TglObjectPurgeableAPPLE = function(objectType: GLenum; name: GLuint; option: GLenum): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglObjectUnpurgeableAPPLE = function(objectType: GLenum; name: GLuint; option: GLenum): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectParameterivAPPLE = procedure(objectType: GLenum; name: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_matrix_palette
+ TglCurrentPaletteMatrixARB = procedure(index: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixIndexubvARB = procedure(size: GLint; const indices: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixIndexusvARB = procedure(size: GLint; const indices: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixIndexuivARB = procedure(size: GLint; const indices: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixIndexPointerARB = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_multisample
+ TglSampleCoverageARB = procedure(value: GLclampf; invert: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_multitexture
+ TglActiveTextureARB = procedure(texture: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClientActiveTextureARB = procedure(texture: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1dARB = procedure(target: GLenum; s: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1dvARB = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1fARB = procedure(target: GLenum; s: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1fvARB = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1iARB = procedure(target: GLenum; s: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1ivARB = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1sARB = procedure(target: GLenum; s: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1svARB = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2dARB = procedure(target: GLenum; s: GLdouble; t: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2dvARB = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2fARB = procedure(target: GLenum; s: GLfloat; t: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2fvARB = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2iARB = procedure(target: GLenum; s: GLint; t: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2ivARB = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2sARB = procedure(target: GLenum; s: GLshort; t: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2svARB = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3dARB = procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3dvARB = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3fARB = procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3fvARB = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3iARB = procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3ivARB = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3sARB = procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3svARB = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4dARB = procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4dvARB = procedure(target: GLenum; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4fARB = procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4fvARB = procedure(target: GLenum; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4iARB = procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4ivARB = procedure(target: GLenum; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4sARB = procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4svARB = procedure(target: GLenum; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_point_parameters
+ TglPointParameterfARB = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterfvARB = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_compression
+ TglCompressedTexImage3DARB = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexImage2DARB = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexImage1DARB = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage3DARB = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage2DARB = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTexSubImage1DARB = procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedTexImageARB = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_transpose_matrix
+ TglLoadTransposeMatrixfARB = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadTransposeMatrixdARB = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultTransposeMatrixfARB = procedure(const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultTransposeMatrixdARB = procedure(const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_blend
+ TglWeightbvARB = procedure(size: GLint; const weights: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightsvARB = procedure(size: GLint; const weights: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightivARB = procedure(size: GLint; const weights: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightfvARB = procedure(size: GLint; const weights: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightdvARB = procedure(size: GLint; const weights: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightubvARB = procedure(size: GLint; const weights: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightusvARB = procedure(size: GLint; const weights: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightuivARB = procedure(size: GLint; const weights: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightPointerARB = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexBlendARB = procedure(count: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_buffer_object
+ TglBindBufferARB = procedure(target: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteBuffersARB = procedure(n: GLsizei; const buffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenBuffersARB = procedure(n: GLsizei; buffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsBufferARB = function(buffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBufferDataARB = procedure(target: GLenum; size: GLsizeiptrARB; const data: PGLvoid; usage: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBufferSubDataARB = procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferSubDataARB = procedure(target: GLenum; offset: GLintptrARB; size: GLsizeiptrARB; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapBufferARB = function(target: GLenum; access: GLenum): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnmapBufferARB = function(target: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferParameterivARB = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferPointervARB = procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_program
+ TglVertexAttrib1dARB = procedure(index: GLuint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1dvARB = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1fARB = procedure(index: GLuint; x: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1fvARB = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1sARB = procedure(index: GLuint; x: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1svARB = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2dARB = procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2dvARB = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2fARB = procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2fvARB = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2sARB = procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2svARB = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3dARB = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3dvARB = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3fARB = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3fvARB = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3sARB = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3svARB = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NbvARB = procedure(index: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NivARB = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NsvARB = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NubARB = procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NubvARB = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NuivARB = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4NusvARB = procedure(index: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4bvARB = procedure(index: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4dARB = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4dvARB = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4fARB = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4fvARB = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4ivARB = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4sARB = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4svARB = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4ubvARB = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4uivARB = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4usvARB = procedure(index: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribPointerARB = procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableVertexAttribArrayARB = procedure(index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableVertexAttribArrayARB = procedure(index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramStringARB = procedure(target: GLenum; format: GLenum; len: GLsizei; const _string: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindProgramARB = procedure(target: GLenum; _program: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteProgramsARB = procedure(n: GLsizei; const programs: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenProgramsARB = procedure(n: GLsizei; programs: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameter4dARB = procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameter4dvARB = procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameter4fARB = procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameter4fvARB = procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameter4dARB = procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameter4dvARB = procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameter4fARB = procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameter4fvARB = procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramEnvParameterdvARB = procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramEnvParameterfvARB = procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramLocalParameterdvARB = procedure(target: GLenum; index: GLuint; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramLocalParameterfvARB = procedure(target: GLenum; index: GLuint; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramivARB = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramStringARB = procedure(target: GLenum; pname: GLenum; _string: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribdvARB = procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribfvARB = procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribivARB = procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribPointervARB = procedure(index: GLuint; pname: GLenum; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsProgramARB = function(_program: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_window_pos
+ TglWindowPos2dARB = procedure(x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2dvARB = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2fARB = procedure(x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2fvARB = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2iARB = procedure(x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2ivARB = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2sARB = procedure(x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2svARB = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3dARB = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3dvARB = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3fARB = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3fvARB = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3iARB = procedure(x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3ivARB = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3sARB = procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3svARB = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_draw_buffers
+ TglDrawBuffersARB = procedure(n: GLsizei; bufs: PGLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_color_buffer_float
+ TglClampColorARB = procedure(target: GLenum; clamp: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_shader
+ TglGetActiveAttribARB = procedure(programobj: GLhandleARB; index: GLuint; maxLength: GLsizei; var length: GLsizei; var size: GLint; var _type: GLenum; name: PGLcharARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetAttribLocationARB = function(programObj: GLhandleARB; const char: PGLcharARB): glint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindAttribLocationARB = procedure(programObj: GLhandleARB; index: GLuint; const name: PGLcharARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_shader_objects
+ TglDeleteObjectARB = procedure(Obj: GLHandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHandleARB = function(pname: GlEnum): GLHandleARB; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDetachObjectARB = procedure(container, attached: GLHandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateShaderObjectARB = function(shaderType: glenum): GLHandleARB; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderSourceARB = procedure(shaderObj: GLHandleARB; count: glsizei; const _string: PPGLCharARB; lengths: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompileShaderARB = procedure(shaderObj: GLHandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateProgramObjectARB = function: GLHandleARB; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAttachObjectARB = procedure(programObj, shaderObj: GLhandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLinkProgramARB = procedure(programObj: GLHandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUseProgramObjectARB = procedure(programObj: GLHandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglValidateProgramARB = procedure(programObj: GLhandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1fARB = procedure(location: glint; v0: glfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2fARB = procedure(location: glint; v0, v1: glfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3fARB = procedure(location: glint; v0, v1, v2: glfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4fARB = procedure(location: glint; v0, v1, v2, v3: glfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1iARB = procedure(location: glint; v0: glint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2iARB = procedure(location: glint; v0, v1: glint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3iARB = procedure(location: glint; v0, v1, v2: glint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4iARB = procedure(location: glint; v0, v1, v2, v3: glint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1fvARB = procedure(location: glint; count: GLsizei; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2fvARB = procedure(location: glint; count: GLsizei; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3fvARB = procedure(location: glint; count: GLsizei; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4fvARB = procedure(location: glint; count: GLsizei; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ivARB = procedure(location: glint; count: GLsizei; value: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ivARB = procedure(location: glint; count: GLsizei; value: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ivARB = procedure(location: glint; count: GLsizei; value: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ivARB = procedure(location: glint; count: GLsizei; value: pglint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2fvARB = procedure(location: glint; count: glsizei; transpose: glboolean; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3fvARB = procedure(location: glint; count: glsizei; transpose: glboolean; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4fvARB = procedure(location: glint; count: glsizei; transpose: glboolean; value: pglfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectParameterfvARB = procedure(Obj: GLHandleARB; pname: GLEnum; params: PGLFloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectParameterivARB = procedure(Obj: GLHandleARB; pname: GLEnum; params: PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetInfoLogARB = procedure(shaderObj: GLHandleARB; maxLength: glsizei; var length: glint; infoLog: PGLcharARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetAttachedObjectsARB = procedure(programobj: GLhandleARB; maxCount: GLsizei; var count: GLsizei; objects: PGLhandleARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformLocationARB = function(programObj: GLhandleARB; const char: PGLcharARB): glint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniformARB = procedure(programobj: GLhandleARB; index: GLuint; maxLength: GLsizei; var length: GLsizei; var size: GLint; var _type: GLenum; name: PGLcharARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformfvARB = procedure(programObj: GLhandleARB; location: GLint; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformivARB = procedure(programObj: GLhandleARB; location: GLint; params: PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetShaderSourceARB = procedure(shader: GLhandleARB; maxLength: GLsizei; var length: GLsizei; source: PGLcharARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_Occlusion_Query
+ TglGenQueriesARB = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteQueriesARB = procedure(n: GLsizei; const ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsQueryARB = function(id: GLuint): boolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginQueryARB = procedure(target: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndQueryARB = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryivARB = procedure(target, pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectivARB = procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectuivARB = procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_draw_instanced
+ TglDrawArraysInstancedARB = procedure(mode: GLenum; first: GLint; count: GLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstancedARB = procedure(mode: GLenum; count: GLsizei; type_: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_framebuffer_object
+ TglIsRenderbuffer = function(renderbuffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindRenderbuffer = procedure(target: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteRenderbuffers = procedure(n: GLsizei; const renderbuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenRenderbuffers = procedure(n: GLsizei; renderbuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRenderbufferStorage = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetRenderbufferParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsFramebuffer = function(framebuffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindFramebuffer = procedure(target: GLenum; framebuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteFramebuffers = procedure(n: GLsizei; const framebuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenFramebuffers = procedure(n: GLsizei; framebuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCheckFramebufferStatus = function(target: GLenum): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture1D = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture2D = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture3D = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferRenderbuffer = procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFramebufferAttachmentParameteriv = procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenerateMipmap = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlitFramebuffer = procedure(srcX0: GLint; srcY0: GLint; srcX1: GLint; srcY1: GLint; dstX0: GLint; dstY0: GLint; dstX1: GLint; dstY1: GLint; mask: GLbitfield; filter: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRenderbufferStorageMultisample = procedure(target: GLenum; samples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTextureLayer = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_geometry_shader4
+ TglProgramParameteriARB = procedure(program_: GLuint; pname: GLenum; value: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTextureARB = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTextureLayerARB = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTextureFaceARB = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; face: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_gl_spirv
+ TglSpecializeShaderARB = procedure(shader : GLuint; const pEntryPoint : PGLChar; numSpecializationConstants : GLuint; const pConstantIndex : PGLUint; const pConstantValue : PGLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_instanced_arrays
+ TglVertexAttribDivisorARB = procedure(index_: GLuint; divisor: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_map_buffer_range
+ TglMapBufferRange = function(target: GLenum; offset: GLintptr; length: GLsizeiptr; access: GLbitfield): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlushMappedBufferRange = procedure(target: GLenum; offset: GLintptr; length: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_parallel_shader_compile
+ TglMaxShaderCompilerThreadsARB = procedure(count : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_buffer_object
+ TglTexBufferARB = procedure(target: GLenum; internalformat: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_array_object
+ TglBindVertexArray = procedure(array_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteVertexArrays = procedure(n: GLsizei; const arrays: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenVertexArrays = procedure(n: GLsizei; arrays: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsVertexArray = function(array_: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_uniform_buffer_object
+ TglGetUniformIndices = procedure(program_: GLuint; uniformCount: GLsizei; const uniformNames: PPGLchar; uniformIndices: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniformsiv = procedure(program_: GLuint; uniformCount: GLsizei; const uniformIndices: PGLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniformName = procedure(program_: GLuint; uniformIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformName: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformBlockIndex = function(program_: GLuint; const uniformBlockName: PGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniformBlockiv = procedure(program_: GLuint; uniformBlockIndex: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveUniformBlockName = procedure(program_: GLuint; uniformBlockIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformBlockName: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformBlockBinding = procedure(program_: GLuint; uniformBlockIndex: GLuint; uniformBlockBinding: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_copy_buffer
+ TglCopyBufferSubData = procedure(readTarget: GLenum; writeTarget: GLenum; readOffset: GLintptr; writeOffset: GLintptr; size: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_draw_elements_base_vertex
+ TglDrawElementsBaseVertex = procedure(mode: GLenum; count: GLsizei; type_: GLenum; const indices: PGLvoid; basevertex: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawRangeElementsBaseVertex = procedure(mode: GLenum; start: GLuint; end_: GLuint; count: GLsizei; type_: GLenum; const indices: PGLvoid; basevertex: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstancedBaseVertex = procedure(mode: GLenum; count: GLsizei; type_: GLenum; const indices: PGLvoid; primcount: GLsizei; basevertex: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElementsBaseVertex = procedure(mode: GLenum; const count: PGLsizei; type_: GLenum; const indices: PPGLvoid; primcount: GLsizei; const basevertex: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_provoking_vertex
+ TglProvokingVertex = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_sync
+ TglFenceSync = function(condition: GLenum; flags: GLbitfield): GLsync; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsSync = function(sync: GLsync): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteSync = procedure(sync: GLsync); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClientWaitSync = function(sync: GLsync; flags: GLbitfield; timeout: GLuint64): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWaitSync = procedure(sync: GLsync; flags: GLbitfield; timeout: GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetInteger64v = procedure(pname: GLenum; params: PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSynciv = procedure(sync: GLsync; pname: GLenum; butSize: GLsizei; length: PGLsizei; values: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_multisample
+ TglTexImage2DMultisample = procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; fixedsamplelocations: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexImage3DMultisample = procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; fixedsamplelocations: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultisamplefv = procedure(pname: GLenum; index_: GLuint; val: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSampleMaski = procedure(index_: GLuint; mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_draw_buffers_blend
+ TglBlendEquationiARB = procedure(buf: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquationSeparateiARB = procedure(buf: GLuint; modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFunciARB = procedure(buf: GLuint; src: GLenum; dst: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFuncSeparateiARB = procedure(buf: GLuint; srcRGB: GLenum; dstRGB: GLenum; srcAlpha: GLenum; dstAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_sample_shading
+ TglMinSampleShadingARB = procedure(value: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_sample_locations
+ TglFramebufferSampleLocationsfvARB = procedure(target : GLenum; start : GLuint; count : GLsizei; const v : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferSampleLocationsfvARB = procedure(framebuffer : GLuint; start : GLuint; count : GLsizei; const v : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvaluateDepthValuesARB = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_shading_language_include
+ TglNamedStringARB = procedure(type_: GLenum; namelen: GLint; const name: PGLchar; stringlen: GLint; const string_: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteNamedStringARB = procedure(namelen: GLint; const name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompileShaderIncludeARB = procedure (shader: GLuint; count: GLsizei; const path: PPGLchar; const length: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsNamedStringARB = function(namelen: GLint; const name: PGLchar): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedStringARB = procedure(namelen: GLint; const name: PGLchar; bufSize: GLsizei; stringlen: GLint; string_: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedStringivARB = procedure(namelen: GLint; const name: PGLchar; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_blend_func_extended
+ TglBindFragDataLocationIndexed = procedure(program_: GLuint; colorNumber: GLuint; index: GLuint; const name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragDataIndex = function(program_: GLuint; const name: PGLchar): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_sampler_objects
+ TglGenSamplers = procedure(count: GLsizei; samplers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteSamplers = procedure(count: GLsizei; const samplers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsSampler = function(sampler: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindSampler = procedure(unit_: GLuint; sampler: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameteri = procedure(sampler: GLuint; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameteriv = procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameterf = procedure(sampler: GLuint; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameterfv = procedure(sampler: GLuint; pname: GLenum; const param: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameterIiv = procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplerParameterIuiv = procedure(sampler: GLuint; pname: GLenum; const param: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSamplerParameteriv = procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSamplerParameterIiv = procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSamplerParameterfv = procedure(sampler: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSamplerParameterIuiv = procedure(sampler: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_timer_query
+ TglQueryCounter = procedure(id: GLuint; target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjecti64v = procedure(id: GLuint; pname: GLenum; params: PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectui64v = procedure(id: GLuint; pname: GLenum; params: PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_type_2_10_10_10_rev
+ TglVertexP2ui = procedure(type_: GLenum; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexP2uiv = procedure(type_: GLenum; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexP3ui = procedure(type_: GLenum; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexP3uiv = procedure(type_: GLenum; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexP4ui = procedure(type_: GLenum; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexP4uiv = procedure(type_: GLenum; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP1ui = procedure(type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP1uiv = procedure(type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP2ui = procedure(type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP2uiv = procedure(type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP3ui = procedure(type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP3uiv = procedure(type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP4ui = procedure(type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordP4uiv = procedure(type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP1ui = procedure(texture: GLenum; type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP1uiv = procedure(texture: GLenum; type_: GLenum; const coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP2ui = procedure(texture: GLenum; type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP2uiv = procedure(texture: GLenum; type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP3ui = procedure(texture: GLenum; type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP3uiv = procedure(texture: GLenum; type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP4ui = procedure(texture: GLenum; type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordP4uiv = procedure(texture: GLenum; type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalP3ui = procedure(type_: GLenum; coords: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalP3uiv = procedure(type_: GLenum; const coords: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorP3ui = procedure(type_: GLenum; color: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorP3uiv = procedure(type_: GLenum; const color: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorP4ui = procedure(type_: GLenum; color: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorP4uiv = procedure(type_: GLenum; const color: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorP3ui = procedure(type_: GLenum; color: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorP3uiv = procedure(type_: GLenum; const color: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP1ui = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP1uiv = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP2ui = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP2uiv = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP3ui = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP3uiv = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP4ui = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; value: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribP4uiv = procedure(index: GLuint; type_: GLenum; normalized: GLboolean; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_draw_indirect
+ TglDrawArraysIndirect = procedure(mode: GLenum; const indirect: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsIndirect = procedure(mode: GLenum; type_: GLenum; const indirect: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_gpu_shader_fp64
+ TglUniform1d = procedure(location: GLint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2d = procedure(location: GLint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3d = procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4d = procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1dv = procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2dv = procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3dv = procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4dv = procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2x3dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix2x4dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3x2dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix3x4dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4x2dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformMatrix4x3dv = procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformdv = procedure(program_: GLuint; location: GLint; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_gpu_shader_int64
+ TglUniform1i64ARB = procedure(location : GLint; x : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2i64ARB = procedure(location : GLint; x : GLint64; y : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3i64ARB = procedure(location : GLint; x : GLint64; y : GLint64; z : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4i64ARB = procedure(location : GLint; x : GLint64; y : GLint64; z : GLint64; w : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1i64vARB = procedure(location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2i64vARB = procedure(location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3i64vARB = procedure(location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4i64vARB = procedure(location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ui64ARB = procedure(location : GLint; x : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ui64ARB = procedure(location : GLint; x : GLuint64; y : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ui64ARB = procedure(location : GLint; x : GLuint64; y : GLuint64; z : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ui64ARB = procedure(location : GLint; x : GLuint64; y : GLuint64; z : GLuint64; w : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ui64vARB = procedure(location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ui64vARB = procedure(location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ui64vARB = procedure(location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ui64vARB = procedure(location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformi64vARB = procedure(program_ : GLuint; location : GLint; params : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformui64vARB = procedure(program_ : GLuint; location : GLint; params : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformi64vARB = procedure(program_ : GLuint; location : GLint; bufSize : GLsizei; params : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformui64vARB = procedure(program_ : GLuint; location : GLint; bufSize : GLsizei; params : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1i64ARB = procedure(program_ : GLuint; location : GLint; x : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2i64ARB = procedure(program_ : GLuint; location : GLint; x : GLint64; y : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3i64ARB = procedure(program_ : GLuint; location : GLint; x : GLint64; y : GLint64; z : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4i64ARB = procedure(program_ : GLuint; location : GLint; x : GLint64; y : GLint64; z : GLint64; w : GLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1i64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2i64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3i64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4i64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ui64ARB = procedure(program_ : GLuint; location : GLint; x : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ui64ARB = procedure(program_ : GLuint; location : GLint; x : GLuint64; y : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ui64ARB = procedure(program_ : GLuint; location : GLint; x : GLuint64; y : GLuint64; z : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ui64ARB = procedure(program_ : GLuint; location : GLint; x : GLuint64; y : GLuint64; z : GLuint64; w : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ui64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ui64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ui64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ui64vARB = procedure(program_ : GLuint; location : GLint; count : GLsizei; const value : PGLuint64 ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_shader_subroutine
+ TglGetSubroutineUniformLocation = function(program_: GLuint; shadertype: GLenum; const name: PGLchar): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSubroutineIndex = function(program_: GLuint; shadertype: GLenum; const name: PGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveSubroutineUniformiv = procedure(program_: GLuint; shadertype: GLenum; index: GLuint; pname: GLenum; values: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveSubroutineUniformName = procedure(program_: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveSubroutineName = procedure(program_: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformSubroutinesuiv = procedure(shadertype: GLenum; count: GLsizei; const indices: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformSubroutineuiv = procedure(shadertype: GLenum; location: GLint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramStageiv = procedure(program_: GLuint; shadertype: GLenum; pname: GLenum; values: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_tessellation_shader
+ TglPatchParameteri = procedure(pname: GLenum; value: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPatchParameterfv = procedure(pname: GLenum; const values: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_transform_feedback2
+ TglBindTransformFeedback = procedure(target: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteTransformFeedbacks = procedure(n: GLsizei; const ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenTransformFeedbacks = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTransformFeedback = function(id: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPauseTransformFeedback = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResumeTransformFeedback = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawTransformFeedback = procedure(mode: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_transform_feedback3
+ TglDrawTransformFeedbackStream = procedure(mode: GLenum; id: GLuint; stream: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginQueryIndexed = procedure(target: GLenum; index: GLuint; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndQueryIndexed = procedure(target: GLenum; index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryIndexediv = procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_ES2_compatibility
+ TglReleaseShaderCompiler = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderBinary = procedure(count: GLsizei; const shaders: PGLuint; binaryformat: GLenum; const binary: PGLvoid; length: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetShaderPrecisionFormat = procedure(shadertype: GLenum; precisiontype: GLenum; range: PGLint; precision: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthRangef = procedure(n: GLclampf; f: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearDepthf = procedure(d: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_get_program_binary
+ TglGetProgramBinary = procedure(program_: GLuint; bufSize: GLsizei; length: PGLsizei; binaryFormat: PGLenum; binary: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramBinary = procedure(program_: GLuint; binaryFormat: GLenum; const binary: PGLvoid; length: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameteri = procedure(program_: GLuint; pname: GLenum; value: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_separate_shader_objects
+ TglUseProgramStages = procedure(pipeline: GLuint; stages: GLbitfield; program_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglActiveShaderProgram = procedure(pipeline: GLuint; program_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateShaderProgramv = function(type_: GLenum; count: GLsizei; const strings: PPGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindProgramPipeline = procedure(pipeline: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteProgramPipelines = procedure(n: GLsizei; const pipelines: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenProgramPipelines = procedure(n: GLsizei; pipelines: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsProgramPipeline = function(pipeline: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramPipelineiv = procedure(pipeline: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1i = procedure(program_: GLuint; location: GLint; v0: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1iv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1f = procedure(program_: GLuint; location: GLint; v0: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1fv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1d = procedure(program_: GLuint; location: GLint; v0: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1dv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ui = procedure(program_: GLuint; location: GLint; v0: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1uiv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2i = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2iv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2f = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2fv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2d = procedure(program_: GLuint; location: GLint; v0: GLdouble; v1: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2dv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ui = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2uiv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3i = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3iv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3f = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3fv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3d = procedure(program_: GLuint; location: GLint; v0: GLdouble; v1: GLdouble; v2: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3dv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ui = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3uiv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4i = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4iv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4f = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4fv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4d = procedure(program_: GLuint; location: GLint; v0: GLdouble; v1: GLdouble; v2: GLdouble; v3: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4dv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ui = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4uiv = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x3fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x2fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x4fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x2fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x4fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x3fv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x3dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x2dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x4dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x2dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x4dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x3dv = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglValidateProgramPipeline = procedure(pipeline: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramPipelineInfoLog = procedure(pipeline: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_attrib_64bit
+ TglVertexAttribL1d = procedure(index: GLuint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2d = procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3d = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4d = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4dv = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribLPointer = procedure(index: GLuint; size: GLint; type_: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribLdv = procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_viewport_array
+ TglViewportArrayv = procedure(first: GLuint; count: GLsizei; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglViewportIndexedf = procedure(index: GLuint; x: GLfloat; y: GLfloat; w: GLfloat; h: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglViewportIndexedfv = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScissorArrayv = procedure(first: GLuint; count: GLsizei; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScissorIndexed = procedure(index: GLuint; left: GLint; bottom: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglScissorIndexedv = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthRangeArrayv = procedure(first: GLuint; count: GLsizei; const v: PGLclampd); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthRangeIndexed = procedure(index: GLuint; n: GLclampd; f: GLclampd); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFloati_v = procedure(target: GLenum; index: GLuint; data: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDoublei_v = procedure(target: GLenum; index: GLuint; data: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL 4.2
+
+ // GL_ARB_base_instance
+ TglDrawArraysInstancedBaseInstance = procedure(mode : GLenum; first : GLint; count :GLsizei; primcount : GLsizei; baseinstance : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstancedBaseInstance = procedure(mode : GLEnum; count : GLsizei; _type : GLenum; const indices : PGLVoid; primcount : GLsizei; baseinstance : GLUInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstancedBaseVertexBaseInstance = procedure(mode : GLEnum; count : GLsizei; _type : GLenum; const indices : PGLVoid; primcount :GLsizei; basevertex : GLint; baseinstance : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_transform_feedback_instanced
+ TglDrawTransformFeedbackInstanced = procedure(mode : GLenum; id : GLuint; primcount : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawTransformFeedbackStreamInstanced = procedure(mode : GLenum; id : GLUInt; stream : GLUint; primcount : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_internalformat_query
+ TglGetInternalformativ = procedure(target : GLenum; internalformat : GLenum; pname : GLenum; bufSize : GLsizei; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_shader_atomic_counters
+ TglGetActiveAtomicCounterBufferiv = procedure(_program : GLuint; bufferIndex : GLuint; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ /// GL_ARB_shader_image_load_store
+ TglBindImageTexture = procedure(_unit : GLuint; texture : GLuint; level :GLint; layered : GLboolean; layer : GLint; access : GLenum; format : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMemoryBarrier = procedure(barriers : GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_storage
+ TglTexStorage1D = procedure(target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexStorage2D = procedure(target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexStorage3D = procedure(target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage1DEXT = procedure(texture : GLuint; target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage2DEXT = procedure(texture : GLuint; target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage3DEXT = procedure(texture : GLuint; target : GLenum; levels :GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+
+ // GL 4.3
+
+ // GL_KHR_debug
+ TglDebugMessageControl = procedure(source : GLenum; type_ : GLenum; severity : TGLenum; count : GLsizei; const ids : PGLUInt; enabled : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageInsert = procedure(source : GLenum; type_ : GLenum; id : GLuint; sverity : GLenum; length : GLsizei; const buf : PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageCallback = procedure(callback : TGLDEBUGPROC; const userParam : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDebugMessageLog = function(count : GLuint; bufsize : GLsizei; sources : PGLenum; types : PGLenum; ids : PGLuint; sverities : PGLenum; lengths : PGLSizei; messagelog : PGLchar) : GLUInt; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushDebugGroup = procedure(source : GLenum; id : GLuint; length : GLsizei; const message_ : PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPopDebugGroup = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglObjectLabel = procedure(identifier : GLenum; name : GLuint; length : GLsizei; const label_ : PGLCHar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectLabel = procedure(identifier : GLenum; name : GLuint; bufsize : GLsizei; length : PGLsizei; label_ : PGLCHar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglObjectPtrLabel = procedure(const ptr : Pointer; length : GLsizei; const label_ : PGLCHar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectPtrLabel = procedure(const ptr : Pointer; bufSize : GLsizei; length : PGLsizei; label_ : PGLCHar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_clear_buffer_object
+ TglClearBufferData = procedure(target : GLenum; internalformat : GLenum; format : GLEnum; type_ : GLEnum; const data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearBufferSubData = procedure(target : GLenum; internalformat : GLenum; offset : GLintptr; size : GLsizeiptr; format : GLenum; type_ : GLenum; const data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedBufferDataEXT = procedure(buffer : GLuint; internalformat : GLenum; format : GLEnum; type_ : GLEnum; const data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedBufferSubDataEXT = procedure(buffer : GLuint; internalformat : GLenum; format : GLenum; type_ : GLenum; offset : GLsizeiptr; size : GLsizeiptr; const data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_compute_shader
+ TglDispatchCompute = procedure(num_groups_x : GLuint; num_groups_y : GLuint; num_groups_z : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDispatchComputeIndirect = procedure(indirect : GLintptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_copy_image
+ TglCopyImageSubData = procedure(srcName : GLUInt; srcTarget : GLenum; srcLevel : GLint; srcX : GLint; srcY : GLint; srcZ : GLint; dstName : GLUInt; dstTarget : GLEnum; dstLevel : GLInt; dstX : GLInt; dstY : GLint; dstZ : GLint; srcWidth : GLsizei; srcHeight : GLsizei; srcDepth : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_debug_group
+ // ARB_debug_group reuses entry points from KHR_debug
+
+ // GL_ARB_debug_label
+ // ARB_debug_label reuses entry points from KHR_debug
+
+ // GL_ARB_debug_output2
+
+ // GL_ARB_ES3_2_compatibility
+ TglPrimitiveBoundingBoxARB = procedure(minX : GLfloat; minY : GLfloat; minZ : GLfloat; minW : GLfloat; maxX : GLfloat; maxY : GLfloat; maxZ : GLfloat; maxW : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_ES3_compatibility
+
+ // GL_ARB_explicit_uniform_location
+
+ // GL_ARB_fragment_layer_viewport
+
+ // GL_ARB_framebuffer_no_attachments
+ TglFramebufferParameteri = procedure(target : GLenum; pname : GLenum; param : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFramebufferParameteriv = procedure(target : GLenum; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferParameteriEXT = procedure(framebuffer : GLUInt; pname : GLenum; param : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedFramebufferParameterivEXT = procedure(framebuffer : GLUInt; pname : GLenum; param : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_internalformat_query2
+ TglGetInternalformati64v = procedure(target : GLenum; internalformat : GLenum; pname : GLenum; bufSize : GLsizei; params : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_invalidate_subdata
+ TglInvalidateTexSubImage = procedure(texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateTexImage = procedure(texture : GLuint; level : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateBufferSubData = procedure(buffer : GLuint; offset : GLintptr; length : GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateBufferData = procedure(buffer : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateFramebuffer = procedure(target : GLenum; numAttachments : GLsizei; const attachments : PGLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateSubFramebuffer = procedure(target : GLenum; numAttachments : GLsizei; const attachments : PGLenum; x : GLint; y : GLint; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_multi_draw_indirect
+ TglMultiDrawArraysIndirect = procedure(mode : GLenum; const indirect : Pointer; drawcount : GLsizei; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElementsIndirect = procedure(mode : GLenum; type_ : GLenum; const indirect : Pointer; drawcount : GLsizei; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_program_interface_query
+ TglGetProgramInterfaceiv = procedure(program_ : GLUInt;programInterface : GLenum; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramResourceIndex = function(program_ : GLUInt;programInterface : GLenum; const name : PGLchar) : GLUInt; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramResourceName = procedure(program_ : GLUInt;programInterface : GLenum; index : GLuint; bufSize : GLsizei; length : PGLsizei; name : PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramResourceiv = procedure(program_ : GLUInt;programInterface : GLenum; index : GLuint; propCount : GLsizei; const props : PGLenum; bufSize : GLsizei; length : PGLsizei; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramResourceLocation = function(program_ : GLUInt;programInterface : GLenum; const name : PGLchar) : GLInt; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramResourceLocationIndex = function(program_ : GLUInt;programInterface : GLenum; const name : PGLchar) : GLInt; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_robust_buffer_access_behavior
+
+ // GL_ARB_shader_image_size
+
+ // GL_ARB_shader_storage_buffer_object
+ TglShaderStorageBlockBinding = procedure(program_ : GLuint; storageBlockIndex : GLuint; storageBlockBinding : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_stencil_texturing
+
+ // GL_ARB_texture_buffer_range
+ TglTexBufferRange = procedure(target : GLenum; internalformat : GLenum; buffer : GLuint; offset :GLintptr; size : GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureBufferRangeEXT = procedure(texture : GLuint; target : GLenum; internalformat : GLenum; buffer : GLuint; offset : GLintptr; size : GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_query_levels
+
+ // GL_ARB_texture_storage_multisample
+ TglTexStorage2DMultisample = procedure(target : GLenum; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexStorage3DMultisample = procedure(target : GLenum; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage2DMultisampleEXT = procedure(texture : GLuint; target : GLenum; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage3DMultisampleEXT = procedure(texture : GLuint; target : GLenum; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL 4.4
+
+ TglBufferStorage = procedure(target : GLenum; size : GLsizeiptr; const data : pointer; flags : GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearTexImage = procedure(texture : GLuint; level : GLint; format : GLenum; _type : GLenum; const data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearTexSubImage = procedure(texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei; format : GLenum; _type : GLenum; const Data : Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBuffersBase = procedure(target : GLenum; first : GLuint; count : GLsizei; const buffers : PGLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBuffersRange = procedure(target : GLenum; first : GLuint; count : GLsizei; const buffers : PGLuint; const offsets : GLintptr; const sizes : GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTextures = procedure(first : GLuint; count : GLsizei; const textures : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindSamplers = procedure(first : GLuint; count : GLsizei; const samplers : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindImageTextures = procedure(first : GLuint; count : GLsizei; const textures : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindVertexBuffers = procedure(first : GLuint; count : GLsizei; const buffers : GLuint; const offsets : GLintptr; const strides : PGLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexPageCommitmentARB = procedure(target : glenum; level : glint; xoffset : glint; yoffset : glint; zoffset : glint; width : glsizei; height : glsizei; depth : glsizei; resident : glboolean); {$IFDEF DGL_WIN} stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL 4.5
+ TglClipControl = procedure(origin : GLenum; depth : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateTransformFeedbacks = procedure(n : GLsizei; ids : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackBufferBase = procedure (xfb : GLuint; index : GLuint; buffer : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackBufferRange = procedure (xfb : GLuint; index : GLuint; buffer : GLuint; offset : GLintptr; size : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbackiv = procedure (xfb : GLuint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbacki_v = procedure (xfb : GLuint; pname : GLenum; index : GLuint; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbacki64_v = procedure (xfb : GLuint; pname : GLenum; index : GLuint; param : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateBuffers = procedure (n : GLsizei; buffers : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferStorage = procedure (buffer : GLuint; size : GLsizei; const data : PGLVoid; flags : GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferData = procedure (buffer : GLuint; size : GLsizei; const data : PGLVoid; usage : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferSubData = procedure (buffer : GLuint; offset : GLintptr; size : GLsizei; data : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyNamedBufferSubData = procedure (readBuffer : GLuint; writeBuffer : GLuint; readOffset : GLintptr; writeOffset : GLintptr; size : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedBufferData = procedure (buffer : GLuint; internalformat : GLenum; format : GLenum; _type : GLenum; data : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedBufferSubData = procedure (buffer : GLuint; internalformat : GLenum; offset : GLintptr; size : GLsizei; format : GLenum; _type : GLenum; data : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapNamedBuffer = function(buffer : GLuint; access : GLenum) : PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapNamedBufferRange = function(buffer : GLuint; offset : GLintptr; length : GLsizei; access : GLbitfield) : PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnmapNamedBuffer = function(buffer : GLuint) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlushMappedNamedBufferRange = procedure (buffer : GLuint; offset : GLintptr; length : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferParameteriv = procedure (buffer : GLuint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferParameteri64v = procedure (buffer : GLuint; pname : GLenum; param : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferPointerv = procedure (buffer : GLuint; pname : GLenum; params : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferSubData = procedure (buffer : GLuint; offset : GLintptr; size : GLsizei; data : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateFramebuffers = procedure (n : GLsizei; framebuffers : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferRenderbuffer = procedure (framebuffer : GLuint; attachment : GLenum ; renderbuffertarget : GLEnum; renderbuffer : GLUInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferParameteri = procedure (framebuffer : GLuint; pname : GLenum; param : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTexture = procedure (framebuffer : GLuint; attachment : GLenum; texture : GLuint; level : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTextureLayer = procedure (framebuffer : GLuint; attachment : GLenum; texture : GLuint; level : GLint; layer : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferDrawBuffer = procedure (framebuffer : GLuint; buf : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferDrawBuffers = procedure (framebuffer : GLuint; n : GLsizei; bufs : PGLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferReadBuffer = procedure (framebuffer : GLuint; src : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateNamedFramebufferData = procedure (framebuffer : GLuint; numAttachments : GLSizei; attachments : PGLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInvalidateNamedFramebufferSubData = procedure (framebuffer : GLuint; numAttachments : GLSizei; attachments : PGLEnum; x : GLint; y : GLint; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedFramebufferiv = procedure (framebuffer : GLuint; buffer : GLenum; drawbuffer : GLint; value : PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedFramebufferuiv = procedure (framebuffer : GLuint; buffer : GLenum; drawbuffer : GLint; value : PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedFramebufferfv = procedure (framebuffer : GLuint; buffer : GLenum; drawbuffer : GLint; value : PGLFloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearNamedFramebufferfi = procedure (framebuffer : GLuint; buffer : GLenum; const depth : GLfloat; stencil : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlitNamedFramebuffer = procedure (readFramebuffer : GLuint; drawFramebuffer : GLuint; srcX0 : GLint; srcY0 : GLint; srcX1 : GLint; srcY1 : GLint; dstX0 : GLint; dstY0 : GLint; dstX1 : GLint; dstY1 : GLint ; mask : GLbitfield; filter : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCheckNamedFramebufferStatus = function(framebuffer : GLuint; target : GLenum) : GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedFramebufferParameteriv = procedure (framebuffer : GLuint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedFramebufferAttachmentParameteriv = procedure (framebuffer : GLuint; attachment : GLenum; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateRenderbuffers = procedure (n : GLsizei; renderbuffers : PGLUInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedRenderbufferStorage = procedure (renderbuffer : GLUInt; internalformat : GLenum ; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedRenderbufferStorageMultisample = procedure (renderbuffer : GLUInt; samples : GLSizei; internalformat : GLenum ; width : GLSizei; height : GLSizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedRenderbufferParameteriv = procedure (renderbuffer : GLUInt; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateTextures = procedure (target : GLenum ; n : GLsizei; textures : PGLUInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureBuffer = procedure (texture : GLuint; internalformat : GLenum; buffer : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureBufferRange = procedure (texture : GLuint; internalformat : GLenum; buffer : GLuint; offset : GLintptr; size : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage1D = procedure (texture : GLuint; levels : GLsizei; internalformat : GLenum; width : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage2D = procedure (texture : GLuint; levels : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage3D = procedure (texture : GLuint; levels : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage2DMultisample = procedure (texture : GLuint; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureStorage3DMultisample = procedure (texture : GLuint; samples : GLsizei; internalformat : GLenum; width : GLsizei; height : GLsizei; depth : GLsizei; fixedsamplelocations : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage1D = procedure (texture : GLuint; level : GLint; xoffset : GLint; width : GLsizei; format : GLenum; _type : GLenum; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage2D = procedure (texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; width : GLsizei; height : GLsizei; format : GLenum; _type : GLenum; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage3D = procedure (texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei; format : GLenum; _type : GLenum; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage1D = procedure (texture : GLuint; level : GLint; xoffset : GLint; width : GLsizei; format : GLenum; imageSize : GLsizei; data : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage2D = procedure (texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; width : GLsizei; height : GLsizei; format : GLenum; mageSize : GLsizei; data : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage3D = procedure (texture : GLuint; level : GLint; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei; format : GLenum; imageSize : GLsizei; data : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage1D = procedure (texture : GLuint; level : GLint ; xoffset : GLint; x : GLint; y : GLint; width : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage2D = procedure (texture : GLuint; level : GLint ; xoffset : GLint; yoffset : GLint; x : GLint; y : GLint; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage3D = procedure (texture : GLuint; level : GLint ; xoffset : GLint; yoffset : GLint; zoffset : GLint; x : GLint; y : GLint; width : GLsizei; height : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterf = procedure (texture : GLuint; pname : GLenum; param : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterfv = procedure (texture : GLuint; pname : GLenum; const param : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameteri = procedure (texture : GLuint; pname : GLenum; param : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterIiv = procedure (texture : GLuint; pname : GLenum; const params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterIuiv = procedure (texture : GLuint; pname : GLenum; const params : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameteriv = procedure (texture : GLuint; pname : GLenum; const param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenerateTextureMipmap = procedure(texture : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTextureUnit = procedure (_unit : GLuint; texture : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureImage = procedure (texture : GLuint; level : GLint ; format : GLenum; _type : GLenum; bufSize : GLsizei; pixels : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedTextureImage = procedure (texture : GLuint; level : GLint; bufSize : GLSizei; pixels : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureLevelParameterfv = procedure (texture : GLuint; level : GLint; pname : GLenum; params : PGLFloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureLevelParameteriv = procedure (texture : GLuint; level : GLint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterfv = procedure (texture : GLuint; pname : GLenum; params : PGLFloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterIiv = procedure (texture : GLuint; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterIuiv = procedure (texture : GLuint; pname : GLenum; params : PGLInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameteriv = procedure (texture : GLuint; pname : GLenum; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateVertexArrays = procedure (n : GLsizei; arrays : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableVertexArrayAttrib = procedure (vaobj : GLuint; index : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableVertexArrayAttrib = procedure (vaobj : GLuint; index : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayElementBuffer = procedure (vaobj : GLuint; buffer : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexBuffer = procedure (vaobj : GLuint; bindingindex : GLuint; buffer : GLuint; offset : GLintptr; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexBuffers = procedure (vaobj : GLuint; first : GLuint; count : GLsizei; const buffers : PGLuint; const offsets : PGLintptr; const strides : PGLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayAttribBinding = procedure (vaobj : GLuint; attribindex : GLuint; bindingindex : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayAttribFormat = procedure(vaobj : GLuint; attribindex : GLuint; size : GLint; _type : GLenum; normalized : GLboolean; relativeoffset : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayAttribIFormat = procedure (vaobj : GLuint; attribindex : GLuint; size : GLint; _type : GLenum; relativeoffset : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayAttribLFormat = procedure (vaobj : GLuint; attribindex : GLuint; size : GLint; _type : GLenum; relativeoffset : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayBindingDivisor = procedure (vaobj : GLuint; bindingindex : GLuint; divisor : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexArrayiv = procedure (vaobj : GLuint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexArrayIndexediv = procedure (vaobj : GLuint; index : GLuint; pname : GLenum; param : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexArrayIndexed64iv = procedure (vaobj : GLuint; index : GLuint; pname : GLenum; param : PGLint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateSamplers = procedure (n : GLsizei; samplers : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateProgramPipelines = procedure (n : GLsizei; pipelines : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateQueries = procedure (target : GLenum; n : GLsizei; ids : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMemoryBarrierByRegion = procedure (barriers : GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureSubImage = procedure (texture : GLuint; level : GLint ; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei; format : GLenum; _type : GLenum; bufSize : GLsizei; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedTextureSubImage = procedure (texture : GLuint; level : GLint ; xoffset : GLint; yoffset : GLint; zoffset : GLint; width : GLsizei; height : GLsizei; depth : GLsizei; bufSize : GLsizei; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetGraphicsResetStatus = function : GLEnum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnCompressedTexImage = procedure (target : GLenum; lod : GLint; bufSize : GLsizei; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnTexImage = procedure (target : GLenum; level : GLint; format : GLenum; _type : GLenum; bufSize : GLSizei; pixels : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformdv = procedure (_program : GLuint; location : GLint; bufSize : GLsizei; params : PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformfv = procedure (_program : GLuint; location : GLint; bufSize : GLsizei; params : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformiv = procedure (_program : GLuint; location : GLint; bufSize : GLsizei; params : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformuiv = procedure (_program : GLuint; location : GLint; bufSize : GLsizei; params : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReadnPixels = procedure (x : GLint; y : GLint; width : GLsizei; height : GLsizei; format : GLenum; _type : GLenum; bufSize : GLsizei; data : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapdv = procedure (target : GLenum; query : GLenum; bufSize : GLsizei; v : PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapfv = procedure (target : GLenum; query : GLenum; bufSize : GLsizei; v : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapiv = procedure (target : GLenum; query : GLenum; bufSize : GLsizei; v : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapfv = procedure (map : GLenum; bufSize : GLsizei; values : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapuiv = procedure (map : GLenum; bufSize : GLsizei; values : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapusv = procedure (map : GLenum; bufSize : GLsizei; values : PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPolygonStipple = procedure (bufSize : GLsizei; pattern : PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnColorTable = procedure (target : GLenum; format : GLenum; _type : GLenum; bufSize : GLsizei; table : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnConvolutionFilter = procedure (target : GLenum; format : GLenum; _type : GLenum; bufSize : GLsizei; image : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnSeparableFilter = procedure (target : GLenum; format : GLenum; _type : GLenum; rowBufSize : GLsizei; row : PGLvoid; columnBufSize : GLsizei; column : PGLvoid; span : PGLVoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnHistogram = procedure (target : GLenum; reset : GLboolean; format : GLenum; _type : GLenum; bufSize : GLsizei; values : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMinmax = procedure (target : GLenum; reset : GLboolean; format : GLenum; _type : GLenum; bufSize : GLsizei; values : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureBarrier = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL 4.6
+ TglSpecializeShader = procedure(shader : GLuint; const pEntryPoint : PGLchar; numSpecializationConstants : GLuint; const pConstantIndex : PGLuint; const pConstantValue : PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawArraysIndirectCount = procedure(mode : GLenum; const indirect : PGLVoid; drawcount : GLintptr; maxdrawcount : GLsizei; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElementsIndirectCount = procedure(mode : GLenum; _type : GLenum; const indirect : PGLvoid; drawcount : GLintptr; maxdrawcount : GLsizei; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPolygonOffsetClamp = procedure(factor : GLfloat; units : GLfloat; clamp : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_sparse_buffer
+ TglBufferPageCommitmentARB = procedure (target : GLenum; offset : GLintptr; size : GLsizei; commit : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferPageCommitmentEXT = procedure (buffer : GLuint; offset : GLintptr; size : GLsizei; commit : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferPageCommitmentARB = procedure (buffer : GLuint; offset : GLintptr; size : GLsizei; commit : GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_KHR_blend_equation_advanced
+ TglBlendBarrierKHR = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_texture_view
+ TglTextureView = procedure(texture : GLuint; target : GLenum; origtexture : GLuint; internalformat : GLenum; minlevel : GLuint; numlevels : GLuint; minlayer : GLuint; numlayers : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_vertex_attrib_binding
+ TglBindVertexBuffer = procedure(bindingindex : GLuint; buffer : GLuint; offset : GLintptr; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribFormat = procedure(attribindex : GLuint; size : GLInt; type_ : GLEnum; normalized : GLboolean; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribIFormat = procedure(attribindex : GLuint; size : GLInt; type_ : GLEnum; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribLFormat = procedure(attribindex : GLuint; size : GLInt; type_ : GLEnum; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribBinding = procedure(attribindex : GLuint; bindingindex : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexBindingDivisor = procedure(bindingindex : GLuint; divisor : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayBindVertexBufferEXT = procedure(vaobj : GLuint; bindingindex : GLuint; buffer : GLuint; offset : GLintptr; stride : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribFormatEXT = procedure(vaobj : GLuint; attribindex : GLuint; size : GLInt; type_ : GLEnum; normalized : GLboolean; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribIFormatEXT = procedure(vaobj : GLuint; attribindex : GLuint; size : GLInt; type_ : GLEnum; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribLFormatEXT = procedure(vaobj : GLuint; attribindex : GLuint; size : GLInt; type_ : GLEnum; relativeoffset : GLUint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribBindingEXT = procedure(vaobj : GLuint; attribindex : GLuint; bindingindex : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexBindingDivisorEXT = procedure(vaobj : GLuint; bindingindex : GLuint; divisor : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_robustness_isolation
+
+ //
+
+ // GL_ARB_cl_event
+ TglCreateSyncFromCLeventARB = function(context: p_cl_context; event: p_cl_event; flags: GLbitfield): GLsync; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_debug_output
+ TglDebugMessageControlARB = procedure(source: GLenum; type_: GLenum; severity: GLenum; count: GLsizei; const ids: PGLuint; enabled: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageInsertARB = procedure(source: GLenum; type_: GLenum; id: GLuint; severity: GLenum; length: GLsizei; const buf: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageCallbackARB = procedure(callback: TglDebugProcARB; const userParam: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDebugMessageLogARB = function(count: GLuint; bufsize: GLsizei; sources: PGLenum; types: PGLenum; ids: PGLuint; severities: PGLenum; lengths: PGLsizei; messageLog: PGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_robustness
+ TglGetGraphicsResetStatusARB = function(): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapdvARB = procedure(target: GLenum; query: GLenum; bufSize: GLsizei; v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapfvARB = procedure(target: GLenum; query: GLenum; bufSize: GLsizei; v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMapivARB = procedure(target: GLenum; query: GLenum; bufSize: GLsizei; v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapfvARB = procedure(map: GLenum; bufSize: GLsizei; values: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapuivARB = procedure(map: GLenum; bufSize: GLsizei; values: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPixelMapusvARB = procedure(map: GLenum; bufSize: GLsizei; values: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnPolygonStippleARB = procedure(bufSize: GLsizei; pattern: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnColorTableARB = procedure(target: GLenum; format: GLenum; type_: GLenum; bufSize: GLsizei; table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnConvolutionFilterARB = procedure(target: GLenum; format: GLenum; type_: GLenum; bufSize: GLsizei; image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnSeparableFilterARB = procedure(target: GLenum; format: GLenum; type_: GLenum; rowBufSize: GLsizei; row: PGLvoid; columnBufSize: GLsizei; column: PGLvoid; span: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnHistogramARB = procedure(target: GLenum; reset: GLboolean; format: GLenum; type_: GLenum; bufSize: GLsizei; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnMinmaxARB = procedure(target: GLenum; reset: GLboolean; format: GLenum; type_: GLenum; bufSize: GLsizei; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnTexImageARB = procedure(target: GLenum; level: GLint; format: GLenum; type_: GLenum; bufSize: GLsizei; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReadnPixelsARB = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; type_: GLenum; bufSize: GLsizei; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnCompressedTexImageARB = procedure(target: GLenum; lod: GLint; bufSize: GLsizei; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformfvARB = procedure(program_: GLuint; location: GLint; bufSize: GLsizei; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformivARB = procedure(program_: GLuint; location: GLint; bufSize: GLsizei; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformuivARB = procedure(program_: GLuint; location: GLint; bufSize: GLsizei; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetnUniformdvARB = procedure(program_: GLuint; location: GLint; bufSize: GLsizei; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_draw_buffers
+ TglDrawBuffersATI = procedure(n: GLsizei; const bufs: PGLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_element_array
+ TglElementPointerATI = procedure(_type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementArrayATI = procedure(mode: GLenum; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawRangeElementArrayATI = procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_envmap_bumpmap
+ TglTexBumpParameterivATI = procedure(pname: GLenum; const param: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexBumpParameterfvATI = procedure(pname: GLenum; const param: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexBumpParameterivATI = procedure(pname: GLenum; param: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexBumpParameterfvATI = procedure(pname: GLenum; param: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_fragment_shader
+ TglGenFragmentShadersATI = function(range: GLuint): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindFragmentShaderATI = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteFragmentShaderATI = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginFragmentShaderATI = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndFragmentShaderATI = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPassTexCoordATI = procedure(dst: GLuint; coord: GLuint; swizzle: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSampleMapATI = procedure(dst: GLuint; interp: GLuint; swizzle: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorFragmentOp1ATI = procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorFragmentOp2ATI = procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorFragmentOp3ATI = procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAlphaFragmentOp1ATI = procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAlphaFragmentOp2ATI = procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglAlphaFragmentOp3ATI = procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSetFragmentShaderConstantATI = procedure(dst: GLuint; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_map_object_buffer
+ TglMapObjectBufferATI = function(buffer: GLuint): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnmapObjectBufferATI = procedure(buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_pn_triangles
+ TglPNTrianglesiATI = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPNTrianglesfATI = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_separate_stencil
+ TglStencilOpSeparateATI = procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilFuncSeparateATI = procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_vertex_array_object
+ TglNewObjectBufferATI = function(size: GLsizei; const _pointer: PGLvoid; usage: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsObjectBufferATI = function(buffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUpdateObjectBufferATI = procedure(buffer: GLuint; offset: GLuint; size: GLsizei; const _pointer: PGLvoid; preserve: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectBufferfvATI = procedure(buffer: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetObjectBufferivATI = procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFreeObjectBufferATI = procedure(buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglArrayObjectATI = procedure(_array: GLenum; size: GLint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetArrayObjectfvATI = procedure(_array: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetArrayObjectivATI = procedure(_array: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantArrayObjectATI = procedure(id: GLuint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantArrayObjectfvATI = procedure(id: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantArrayObjectivATI = procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_vertex_attrib_array_object
+ TglVertexAttribArrayObjectATI = procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; buffer: GLuint; offset: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribArrayObjectfvATI = procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribArrayObjectivATI = procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ATI_vertex_streams
+ TglVertexStream1sATI = procedure(stream: GLenum; x: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1svATI = procedure(stream: GLenum; const coords: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1iATI = procedure(stream: GLenum; x: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1ivATI = procedure(stream: GLenum; const coords: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1fATI = procedure(stream: GLenum; x: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1fvATI = procedure(stream: GLenum; const coords: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1dATI = procedure(stream: GLenum; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream1dvATI = procedure(stream: GLenum; const coords: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2sATI = procedure(stream: GLenum; x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2svATI = procedure(stream: GLenum; const coords: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2iATI = procedure(stream: GLenum; x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2ivATI = procedure(stream: GLenum; const coords: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2fATI = procedure(stream: GLenum; x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2fvATI = procedure(stream: GLenum; const coords: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2dATI = procedure(stream: GLenum; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream2dvATI = procedure(stream: GLenum; const coords: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3sATI = procedure(stream: GLenum; x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3svATI = procedure(stream: GLenum; const coords: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3iATI = procedure(stream: GLenum; x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3ivATI = procedure(stream: GLenum; const coords: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3fATI = procedure(stream: GLenum; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3fvATI = procedure(stream: GLenum; const coords: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3dATI = procedure(stream: GLenum; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream3dvATI = procedure(stream: GLenum; const coords: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4sATI = procedure(stream: GLenum; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4svATI = procedure(stream: GLenum; const coords: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4iATI = procedure(stream: GLenum; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4ivATI = procedure(stream: GLenum; const coords: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4fATI = procedure(stream: GLenum; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4fvATI = procedure(stream: GLenum; const coords: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4dATI = procedure(stream: GLenum; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexStream4dvATI = procedure(stream: GLenum; const coords: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3bATI = procedure(stream: GLenum; nx: GLbyte; ny: GLbyte; nz: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3bvATI = procedure(stream: GLenum; const coords: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3sATI = procedure(stream: GLenum; nx: GLshort; ny: GLshort; nz: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3svATI = procedure(stream: GLenum; const coords: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3iATI = procedure(stream: GLenum; nx: GLint; ny: GLint; nz: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3ivATI = procedure(stream: GLenum; const coords: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3fATI = procedure(stream: GLenum; nx: GLfloat; ny: GLfloat; nz: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3fvATI = procedure(stream: GLenum; const coords: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3dATI = procedure(stream: GLenum; nx: GLdouble; ny: GLdouble; nz: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalStream3dvATI = procedure(stream: GLenum; const coords: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClientActiveVertexStreamATI = procedure(stream: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexBlendEnviATI = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexBlendEnvfATI = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_performance_monitor
+ TglGetPerfMonitorGroupsAMD = procedure(numGroups: PGLint; groupsSize: GLsizei; groups: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPerfMonitorCountersAMD = procedure(group: GLuint; numCounters: PGLint; maxActiveCouters: PGLint; counterSize: GLsizei; counters: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPerfMonitorGroupStringAMD = procedure(group: GLuint; bufSize: GLsizei; length: PGLsizei; groupString: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPerfMonitorCounterStringAMD = procedure(group: GLuint; counter: GLuint; bufSize: GLsizei; length: PGLsizei; counterString: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPerfMonitorCounterInfoAMD = procedure(group: GLuint; counter: GLuint; pname: GLenum; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenPerfMonitorsAMD = procedure(n: GLsizei; monitors: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeletePerfMonitorsAMD = procedure(n: GLsizei; monitors: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSelectPerfMonitorCountersAMD = procedure(monitor: GLuint; enable: GLboolean; group: GLuint; numCounters: GLint; counterList: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginPerfMonitorAMD = procedure(monitor: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndPerfMonitorAMD = procedure(monitor: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPerfMonitorCounterDataAMD = procedure(monitor: GLuint; pname: GLenum; dataSize: GLsizei; data: PGLuint; bytesWritten: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_vertex_shader_tesselator
+ TglTessellationFactorAMD = procedure(factor: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTessellationModeAMD = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_draw_buffers_blend
+ TglBlendFuncIndexedAMD = procedure(buf: GLuint; src: GLenum; dst: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendFuncSeparateIndexedAMD = procedure(buf: GLuint; srcRGB: GLenum; dstRGB: GLenum; srcAlpha: GLenum; dstAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquationIndexedAMD = procedure(buf: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBlendEquationSeparateIndexedAMD = procedure(buf: GLuint; modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_name_gen_delete
+ TglGenNamesAMD = procedure(identifier: GLenum; num: GLuint; names: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteNamesAMD = procedure(identifier: GLenum; num: GLuint; const names: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsNameAMD = function(identifier: GLenum; name: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_debug_output
+ TglDebugMessageEnableAMD = procedure(category: GLenum; severity: GLenum; count: GLsizei; const ids: PGLuint; enabled: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageInsertAMD = procedure(category: GLenum; severity: GLenum; id: GLuint; length: GLsizei; const buf: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDebugMessageCallbackAMD = procedure(callback: TGLDebugProcAMD; userParam: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDebugMessageLogAMD = function(count: GLuint; bufsize: GLsizei; categories: PGLenum; severities: PGLuint; ids: PGLuint; lengths: PGLsizei; message: PGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_blend_color
+ TglBlendColorEXT = procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_blend_func_separate
+ TglBlendFuncSeparateEXT = procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_blend_minmax
+ TglBlendEquationEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_color_subtable
+ TglColorSubTableEXT = procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyColorSubTableEXT = procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_compiled_vertex_array
+ TglLockArraysEXT = procedure(first: GLint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnlockArraysEXT = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_convolution
+ TglConvolutionFilter1DEXT = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionFilter2DEXT = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameterfEXT = procedure(target: GLenum; pname: GLenum; params: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameterfvEXT = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameteriEXT = procedure(target: GLenum; pname: GLenum; params: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglConvolutionParameterivEXT = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyConvolutionFilter1DEXT = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyConvolutionFilter2DEXT = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionFilterEXT = procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionParameterfvEXT = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetConvolutionParameterivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSeparableFilterEXT = procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSeparableFilter2DEXT = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_coordinate_frame
+ TglTangent3bEXT = procedure(tx: GLbyte; ty: GLbyte; tz: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3bvEXT = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3dEXT = procedure(tx: GLdouble; ty: GLdouble; tz: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3dvEXT = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3fEXT = procedure(tx: GLfloat; ty: GLfloat; tz: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3fvEXT = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3iEXT = procedure(tx: GLint; ty: GLint; tz: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3ivEXT = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3sEXT = procedure(tx: GLshort; ty: GLshort; tz: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangent3svEXT = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3bEXT = procedure(bx: GLbyte; by: GLbyte; bz: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3bvEXT = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3dEXT = procedure(bx: GLdouble; by: GLdouble; bz: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3dvEXT = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3fEXT = procedure(bx: GLfloat; by: GLfloat; bz: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3fvEXT = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3iEXT = procedure(bx: GLint; by: GLint; bz: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3ivEXT = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3sEXT = procedure(bx: GLshort; by: GLshort; bz: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormal3svEXT = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTangentPointerEXT = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBinormalPointerEXT = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_copy_texture
+ TglCopyTexImage1DEXT = procedure(target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexImage2DEXT = procedure(target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage1DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage2DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTexSubImage3DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_cull_vertex
+ TglCullParameterdvEXT = procedure(pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCullParameterfvEXT = procedure(pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_draw_range_elements
+ TglDrawRangeElementsEXT = procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_fog_coord
+ TglFogCoordfEXT = procedure(coord: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordfvEXT = procedure(const coord: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoorddEXT = procedure(coord: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoorddvEXT = procedure(const coord: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordPointerEXT = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_framebuffer_object
+ TglIsRenderbufferEXT = function(renderbuffer: GLuint): Boolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindRenderbufferEXT = procedure(target: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteRenderbuffersEXT = procedure(n: GLsizei; const renderbuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenRenderbuffersEXT = procedure(n: GLsizei; renderbuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRenderbufferStorageEXT = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetRenderbufferParameterivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsFramebufferEXT = function(framebuffer: GLuint): Boolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindFramebufferEXT = procedure(target: GLenum; framebuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteFramebuffersEXT = procedure(n: GLsizei; const framebuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenFramebuffersEXT = procedure(n: GLsizei; framebuffers: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCheckFramebufferStatusEXT = function(target: GLenum): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture1DEXT = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture2DEXT = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTexture3DEXT = procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferRenderbufferEXT = procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFramebufferAttachmentParameterivEXT = procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenerateMipmapEXT = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_histogram
+ TglGetHistogramEXT = procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHistogramParameterfvEXT = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetHistogramParameterivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmaxEXT = procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmaxParameterfvEXT = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMinmaxParameterivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglHistogramEXT = procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMinmaxEXT = procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResetHistogramEXT = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResetMinmaxEXT = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_index_func
+ TglIndexFuncEXT = procedure(func: GLenum; ref: GLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_index_material
+ TglIndexMaterialEXT = procedure(face: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_light_texture
+ TglApplyTextureEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureLightEXT = procedure(pname: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureMaterialEXT = procedure(face: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_multi_draw_arrays
+ TglMultiDrawArraysEXT = procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiDrawElementsEXT = procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_multisample
+ TglSampleMaskEXT = procedure(value: GLclampf; invert: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplePatternEXT = procedure(pattern: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_paletted_texture
+ TglColorTableEXT = procedure(target: GLenum; internalFormat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableEXT = procedure(target: GLenum; format: GLenum; _type: GLenum; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameterivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameterfvEXT = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_pixel_transform
+ TglPixelTransformParameteriEXT = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTransformParameterfEXT = procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTransformParameterivEXT = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTransformParameterfvEXT = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_point_parameters
+ TglPointParameterfEXT = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterfvEXT = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_polygon_offset
+ TglPolygonOffsetEXT = procedure(factor: GLfloat; bias: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_secondary_color
+ TglSecondaryColor3bEXT = procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3bvEXT = procedure(const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3dEXT = procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3dvEXT = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3fEXT = procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3fvEXT = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3iEXT = procedure(red: GLint; green: GLint; blue: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ivEXT = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3sEXT = procedure(red: GLshort; green: GLshort; blue: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3svEXT = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ubEXT = procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3ubvEXT = procedure(const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3uiEXT = procedure(red: GLuint; green: GLuint; blue: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3uivEXT = procedure(const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3usEXT = procedure(red: GLushort; green: GLushort; blue: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3usvEXT = procedure(const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorPointerEXT = procedure(size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_stencil_two_side
+ TglActiveStencilFaceEXT = procedure(face: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_subtexture
+ TglTexSubImage1DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage2DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_texture3D
+ TglTexImage3DEXT = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage3DEXT = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_texture_object
+ TglAreTexturesResidentEXT = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTextureEXT = procedure(target: GLenum; texture: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteTexturesEXT = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenTexturesEXT = procedure(n: GLsizei; textures: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTextureEXT = function(texture: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPrioritizeTexturesEXT = procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_texture_perturb_normal
+ TglTextureNormalEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_vertex_array
+ TglArrayElementEXT = procedure(i: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorPointerEXT = procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawArraysEXT = procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlagPointerEXT = procedure(stride: GLsizei; count: GLsizei; const _pointer: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPointervEXT = procedure(pname: GLenum; params: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexPointerEXT = procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalPointerEXT = procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordPointerEXT = procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexPointerEXT = procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_vertex_shader
+ TglBeginVertexShaderEXT = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndVertexShaderEXT = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindVertexShaderEXT = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenVertexShadersEXT = function(range: GLuint): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteVertexShaderEXT = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderOp1EXT = procedure(op: GLenum; res: GLuint; arg1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderOp2EXT = procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglShaderOp3EXT = procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint; arg3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSwizzleEXT = procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWriteMaskEXT = procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInsertComponentEXT = procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglExtractComponentEXT = procedure(res: GLuint; src: GLuint; num: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenSymbolsEXT = function(datatype: GLenum; storagetype: GLenum; range: GLenum; components: GLuint): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSetInvariantEXT = procedure(id: GLuint; _type: GLenum; const addr: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSetLocalConstantEXT = procedure(id: GLuint; _type: GLenum; const addr: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantbvEXT = procedure(id: GLuint; const addr: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantsvEXT = procedure(id: GLuint; const addr: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantivEXT = procedure(id: GLuint; const addr: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantfvEXT = procedure(id: GLuint; const addr: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantdvEXT = procedure(id: GLuint; const addr: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantubvEXT = procedure(id: GLuint; const addr: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantusvEXT = procedure(id: GLuint; const addr: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantuivEXT = procedure(id: GLuint; const addr: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVariantPointerEXT = procedure(id: GLuint; _type: GLenum; stride: GLuint; const addr: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableVariantClientStateEXT = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableVariantClientStateEXT = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindLightParameterEXT = function(light: GLenum; value: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindMaterialParameterEXT = function(face: GLenum; value: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTexGenParameterEXT = function(_unit: GLenum; coord: GLenum; value: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindTextureUnitParameterEXT = function(_unit: GLenum; value: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindParameterEXT = function(value: GLenum): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsVariantEnabledEXT = function(id: GLuint; cap: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantBooleanvEXT = procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantIntegervEXT = procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantFloatvEXT = procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVariantPointervEXT = procedure(id: GLuint; value: GLenum; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetInvariantBooleanvEXT = procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetInvariantIntegervEXT = procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetInvariantFloatvEXT = procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetLocalConstantBooleanvEXT = procedure(id: GLuint; value: GLenum; data: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetLocalConstantIntegervEXT = procedure(id: GLuint; value: GLenum; data: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetLocalConstantFloatvEXT = procedure(id: GLuint; value: GLenum; data: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_vertex_weighting
+ TglVertexWeightfEXT = procedure(weight: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexWeightfvEXT = procedure(const weight: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexWeightPointerEXT = procedure(size: GLsizei; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_stencil_clear_tag
+ TglStencilClearTagEXT = procedure(stencilTagBits: GLsizei; stencilClearTag: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_framebuffer_blit
+ TglBlitFramebufferEXT = procedure(srcX0: GLint; srcY0: GLint; srcX1: GLint; srcY1: GLint; dstX0: GLint; dstY0: GLint; dstX1: GLint; dstY1: GLint; mask: GLbitfield; filter: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_framebuffer_multisample
+ TglRenderbufferStorageMultisampleEXT = procedure(target: GLenum; samples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_timer_query
+ TglGetQueryObjecti64vEXT = procedure(id: GLuint; pname: GLenum; params: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetQueryObjectui64vEXT = procedure(id: GLuint; pname: GLenum; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_gpu_program_parameters
+ TglProgramEnvParameters4fvEXT = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameters4fvEXT = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_bindable_uniform
+ TglUniformBufferEXT = procedure(_program: GLuint; location: GLint; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformBufferSizeEXT = function(_program: GLuint; location: GLint): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformOffsetEXT = function(_program: GLuint; location: GLint): GLintptr; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_draw_buffers2
+ TglColorMaskIndexedEXT = procedure(buf: GLuint; r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBooleanIndexedvEXT = procedure(value: GLenum; index: GLuint; data: PGLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetIntegerIndexedvEXT = procedure(value: GLenum; index: GLuint; data: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableIndexedEXT = procedure(target: GLenum; index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableIndexedEXT = procedure(target: GLenum; index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsEnabledIndexedEXT = function(target: GLenum; index: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_draw_instanced
+ TglDrawArraysInstancedEXT = procedure(mode: GLenum; first: GLint; count: GLsizei; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawElementsInstancedEXT = procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: Pointer; primcount: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_geometry_shader4
+ TglProgramParameteriEXT = procedure (_program: GLuint; pname: GLenum; value: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferTextureEXT = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ TglFramebufferTextureFaceEXT = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; face: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_gpu_shader4
+ TglVertexAttribI1iEXT = procedure(index: GLuint; x: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2iEXT = procedure(index: GLuint; x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3iEXT = procedure(index: GLuint; x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4iEXT = procedure(index: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1uiEXT = procedure(index: GLuint; x: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2uiEXT = procedure(index: GLuint; x: GLuint; y: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3uiEXT = procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4uiEXT = procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1ivEXT = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2ivEXT = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3ivEXT = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4ivEXT = procedure(index: GLuint; const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI1uivEXT = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI2uivEXT = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI3uivEXT = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4uivEXT = procedure(index: GLuint; const v: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4bvEXT = procedure(index: GLuint; const v: PGLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4svEXT = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4ubvEXT = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribI4usvEXT = procedure(index: GLuint; const v: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribIPointerEXT = procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const _pointer: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribIivEXT = procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribIuivEXT = procedure(index: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1uiEXT = procedure(location: GLint; v0: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2uiEXT = procedure(location: GLint; v0: GLuint; v1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3uiEXT = procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4uiEXT = procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1uivEXT = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2uivEXT = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3uivEXT = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4uivEXT = procedure(location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformuivEXT = procedure(_program: GLuint; location: GLint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindFragDataLocationEXT = procedure(_program: GLuint; colorNumber: GLuint; const name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragDataLocationEXT = function(_program: GLuint; const name: PGLchar): GLint;
+
+ // GL_EXT_texture_array
+ TglFramebufferTextureLayerEXT = procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_texture_buffer_object
+ TglTexBufferEXT = procedure(target: GLenum; internalformat: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_texture_integer
+ TglClearColorIiEXT = procedure(r: GLint; g: GLint; b: GLint; a: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearColorIuiEXT = procedure(r: GLuint; g: GLuint; b: GLuint; a: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterIivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexParameterIuivEXT = procedure(target: GLenum; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterIivEXT = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTexParameterIiuvEXT = procedure(target: GLenum; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_HP_image_transform
+ TglImageTransformParameteriHP = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglImageTransformParameterfHP = procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglImageTransformParameterivHP = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglImageTransformParameterfvHP = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetImageTransformParameterivHP = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetImageTransformParameterfvHP = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_depth_bounds_test
+ TglDepthBoundsEXT = procedure(zmin: GLclampd; zmax: GLclampd); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_blend_equation_separate
+ TglBlendEquationSeparateEXT = procedure(modeRGB: GLenum; modeAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_transform_feedback
+ TglBeginTransformFeedbackEXT = procedure(primitiveMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndTransformFeedbackEXT = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferRangeEXT = procedure(target: GLenum; index_: GLuint; buffer: GLuint; offset: GLintptr; size: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferOffsetEXT = procedure(target: GLenum; index_: GLuint; buffer: GLuint; offset: GLintptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferBaseEXT = procedure(target: GLenum; index_: GLuint; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackVaryingsEXT = procedure(program_: GLuint; count: GLsizei; const locations: PGLint; bufferMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbackVaryingEXT = procedure(program_: GLuint; index_: GLuint; location: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_direct_state_access
+ TglClientAttribDefaultEXT = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPushClientAttribDefaultEXT = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixLoadfEXT = procedure(mode: GLenum; const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixLoaddEXT = procedure(mode: GLenum; const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixMultfEXT = procedure(mode: GLenum; const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixMultdEXT = procedure(mode: GLenum; const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixLoadIdentityEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixRotatefEXT = procedure(mode: GLenum; angle: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixRotatedEXT = procedure(mode: GLenum; angle: GLdouble; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixScalefEXT = procedure(mode: GLenum; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixScaledEXT = procedure(mode: GLenum; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixTranslatefEXT = procedure(mode: GLenum; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixTranslatedEXT = procedure(mode: GLenum; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixFrustumEXT = procedure(mode: GLenum; left: GLdouble; right: GLdouble; bottom: GLdouble; top: GLdouble; zNear: GLdouble; zFar: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixOrthoEXT = procedure(mode: GLenum; left: GLdouble; right: GLdouble; bottom: GLdouble; top: GLdouble; zNear: GLdouble; zFar: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixPopEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixPushEXT = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixLoadTransposefEXT = procedure(mode: GLenum; const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixLoadTransposedEXT = procedure(mode: GLenum; const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixMultTransposefEXT = procedure(mode: GLenum; const m: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMatrixMultTransposedEXT = procedure(mode: GLenum; const m: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterfEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterfvEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameteriEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureImageEXT = procedure(texture: GLuint; target: GLenum; level: GLint; format: GLenum; type_: GLenum; pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterfvEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureLevelParameterfvEXT = procedure(texture: GLuint; target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureLevelParameterivEXT = procedure(texture: GLuint; target: GLenum; level: GLint; pname: GLenum; params: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureImage3DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureSubImage3DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyTextureSubImage3DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameterfEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameterfvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameteriEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameterivEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexSubImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexSubImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyMultiTexImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyMultiTexImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei; border: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyMultiTexSubImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyMultiTexSubImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexImageEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; format: GLenum; type_: GLenum; pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexParameterfvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexParameterivEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexLevelParameterfvEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexLevelParameterivEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexImage3DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; type_: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexSubImage3DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; type_: GLenum; const pixels:PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyMultiTexSubImage3DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindMultiTextureEXT = procedure(texunit: GLenum; target: GLenum; texture: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEnableClientStateIndexedEXT = procedure(array_: GLenum; index_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDisableClientStateIndexedEXT = procedure(array_: GLenum; index_: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoordPointerEXT = procedure(texunit: GLenum; size: GLint; type_: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexEnvfEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexEnvfvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexEnviEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexEnvivEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGendEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGendvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGenfEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGenfvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGeniEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexGenivEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexEnvfvEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexEnvivEXT = procedure(texunit: GLenum; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexGendvEXT = procedure(texunit: GLenum; coord: GLenum; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexGenfvEXT = procedure(texunit: GLenum; coord: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexGenivEXT = procedure(texunit: GLenum; coord: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFloatIndexedvEXT = procedure(target: GLenum; index_: GLuint; data: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDoubleIndexedvEXT = procedure(target: GLenum; index_: GLuint; data: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPointerIndexedvEXT = procedure(target: GLenum; index_: GLuint; data: PPGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureImage3DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage3DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage2DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedTextureSubImage1DEXT = procedure(texture: GLuint; target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedTextureImageEXT = procedure(texture: GLuint; target: GLenum; lod: GLint; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexImage3DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexSubImage3DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexSubImage2DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCompressedMultiTexSubImage1DEXT = procedure(texunit: GLenum; target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const bits: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCompressedMultiTexImageEXT = procedure(texunit: GLenum; target: GLenum; lod: GLint; img: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramStringEXT = procedure(program_: GLuint; target: GLenum; format: GLenum; len: GLsizei; const string_: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameter4dEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameter4dvEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameter4fEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameter4fvEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramLocalParameterdvEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramLocalParameterfvEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramivEXT = procedure(program_: GLuint; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramStringEXT = procedure(program_: GLuint; target: GLenum; pname: GLenum; string_: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameters4fvEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; count: GLsizei; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameterI4iEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameterI4ivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParametersI4ivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; count: GLsizei; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameterI4uiEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParameterI4uivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedProgramLocalParametersI4uivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; count: GLsizei; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramLocalParameterIivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedProgramLocalParameterIuivEXT = procedure(program_: GLuint; target: GLenum; index_: GLuint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterIivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureParameterIuivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterIivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureParameterIuivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameterIivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexParameterIuivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexParameterIivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMultiTexParameterIuivEXT = procedure(texture: GLuint; target: GLenum; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1fEXT = procedure(program_: GLuint; location: GLint; v0: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2fEXT = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3fEXT = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4fEXT = procedure(program_: GLuint; location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1iEXT = procedure(program_: GLuint; location: GLint; v0: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2iEXT = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3iEXT = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint; v2: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4iEXT = procedure(program_: GLuint; location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x3fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x2fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x4fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x2fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x4fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x3fvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1uiEXT = procedure(program_: GLuint; location: GLint; v0: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2uiEXT = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3uiEXT = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4uiEXT = procedure(program_: GLuint; location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1uivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2uivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3uivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4uivEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferDataEXT = procedure(buffer: GLuint; size: GLsizei; const data: PGLvoid; usage: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedBufferSubDataEXT = procedure(buffer: GLuint; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapNamedBufferEXT = function(buffer: GLuint; access: GLenum): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUnmapNamedBufferEXT = function(buffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapNamedBufferRangeEXT = function(buffer: GLuint; offset: GLintptr; length: GLsizeiptr; access: GLbitfield): PGLvoid; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlushMappedNamedBufferRangeEXT = procedure(buffer: GLuint; offset: GLintptr; length: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedCopyBufferSubDataEXT = procedure(readBuffer: GLuint; writeBuffer: GLuint; readOffset: GLintptr; writeOffset: GLintptr; size: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferParameterivEXT = procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferPointervEXT = procedure(buffer: GLuint; pname: GLenum; params: PPGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferSubDataEXT = procedure(buffer: GLuint; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureBufferEXT = procedure(texture: GLuint; target: GLenum; internalformat: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexBufferEXT = procedure(texunit: GLenum; target: GLenum; interformat: GLenum; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedRenderbufferStorageEXT = procedure(renderbuffer: GLuint; interformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedRenderbufferParameterivEXT = procedure(renderbuffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCheckNamedFramebufferStatusEXT = function(framebuffer: GLuint; target: GLenum): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTexture1DEXT = procedure(framebuffer: GLuint; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTexture2DEXT = procedure(framebuffer: GLuint; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTexture3DEXT = procedure(framebuffer: GLuint; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferRenderbufferEXT = procedure(framebuffer: GLuint; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedFramebufferAttachmentParameterivEXT = procedure(framebuffer: GLuint; attachment: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenerateTextureMipmapEXT = procedure(texture: GLuint; target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenerateMultiTexMipmapEXT = procedure(texunit: GLenum; target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferDrawBufferEXT = procedure(framebuffer: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferDrawBuffersEXT = procedure(framebuffer: GLuint; n: GLsizei; const bufs: PGLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFramebufferReadBufferEXT = procedure(framebuffer: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFramebufferParameterivEXT = procedure(framebuffer: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedRenderbufferStorageMultisampleEXT = procedure(renderbuffer: GLuint; samples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedRenderbufferStorageMultisampleCoverageEXT = procedure(renderbuffer: GLuint; coverageSamples: GLsizei; colorSamples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTextureEXT = procedure(framebuffer: GLuint; attachment: GLenum; texture: GLuint; level: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTextureLayerEXT = procedure(framebuffer: GLuint; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNamedFramebufferTextureFaceEXT = procedure(framebuffer: GLuint; attachment: GLenum; texture: GLuint; level: GLint; face: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTextureRenderbufferEXT = procedure(texture: GLuint; target: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexRenderbufferEXT = procedure(texunit: GLenum; target: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1dEXT = procedure(program_: GLuint; location: GLint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2dEXT = procedure(program_: GLuint; location: GLint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3dEXT = procedure(program_: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4dEXT = procedure(program_: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x3dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix2x4dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x2dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix3x4dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x2dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformMatrix4x3dvEXT = procedure(program_: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_separate_shader_objects
+ TglUseShaderProgramEXT = procedure(_type: GLenum; _program: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglActiveProgramEXT = procedure(_program: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCreateShaderProgramEXT = function(_type: GLenum; const _string: PGLchar): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_shader_image_load_store
+ TglBindImageTextureEXT = procedure(index: GLuint; texture: GLuint; level: GLint; layered: GLboolean; layer: GLint; access: GLenum; format: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMemoryBarrierEXT = procedure(barriers: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_EXT_vertex_attrib_64bit
+ TglVertexAttribL1dEXT = procedure(index: GLuint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2dEXT = procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3dEXT = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4dEXT = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1dvEXT = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2dvEXT = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3dvEXT = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4dvEXT = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribLPointerEXT = procedure(index: GLuint; size: GLint; type_: GLenum; stride: GLsizei; const pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribLdvEXT = procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayVertexAttribLOffsetEXT = procedure(vaobj: GLuint; buffer: GLuint; index: GLuint; size: GLint; type_: GLenum; stride: GLsizei; offset: GLintptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_IBM_multimode_draw_arrays
+ TglMultiModeDrawArraysIBM = procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei; modestride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiModeDrawElementsIBM = procedure(const mode: PGLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; modestride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_IBM_vertex_array_lists
+ TglColorPointerListIBM = procedure(size: GLint; _type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorPointerListIBM = procedure(size: GLint; _type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlagPointerListIBM = procedure(stride: GLint; const _pointer: PGLboolean; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordPointerListIBM = procedure(_type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexPointerListIBM = procedure(_type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalPointerListIBM = procedure(_type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordPointerListIBM = procedure(size: GLint; _type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexPointerListIBM = procedure(size: GLint; _type: GLenum; stride: GLint; const _pointer: PGLvoid; ptrstride: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_INGR_blend_func_separate
+ TglBlendFuncSeparateINGR = procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_INTEL_framebuffer_CMAA
+ TglApplyFramebufferAttachmentCMAAINTEL = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_INTEL_parallel_arrays
+ TglVertexPointervINTEL = procedure(size: GLint; _type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalPointervINTEL = procedure(_type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorPointervINTEL = procedure(size: GLint; _type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordPointervINTEL = procedure(size: GLint; _type: GLenum; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_MESA_resize_buffers
+ TglResizeBuffersMESA = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_MESA_window_pos
+ TglWindowPos2dMESA = procedure(x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2dvMESA = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2fMESA = procedure(x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2fvMESA = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2iMESA = procedure(x: GLint; y: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2ivMESA = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2sMESA = procedure(x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos2svMESA = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3dMESA = procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3dvMESA = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3fMESA = procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3fvMESA = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3iMESA = procedure(x: GLint; y: GLint; z: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3ivMESA = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3sMESA = procedure(x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos3svMESA = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4dMESA = procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4dvMESA = procedure(const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4fMESA = procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4fvMESA = procedure(const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4iMESA = procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4ivMESA = procedure(const v: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4sMESA = procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWindowPos4svMESA = procedure(const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_evaluators
+ TglMapControlPointsNV = procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; uorder: GLint; vorder: GLint; _packed: GLboolean; const points: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapParameterivNV = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMapParameterfvNV = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapControlPointsNV = procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; _packed: GLboolean; points: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapParameterivNV = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapParameterfvNV = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapAttribParameterivNV = procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetMapAttribParameterfvNV = procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEvalMapsNV = procedure(target: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_fence
+ TglDeleteFencesNV = procedure(n: GLsizei; const fences: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenFencesNV = procedure(n: GLsizei; fences: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsFenceNV = function(fence: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTestFenceNV = function(fence: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFenceivNV = procedure(fence: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinishFenceNV = procedure(fence: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSetFenceNV = procedure(fence: GLuint; condition: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_fragment_program
+ TglProgramNamedParameter4fNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramNamedParameter4dNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramNamedParameter4fvNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramNamedParameter4dvNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramNamedParameterfvNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramNamedParameterdvNV = procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_half_float
+ TglVertex2hNV = procedure(x: GLhalfNV; y: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex2hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3hNV = procedure(x: GLhalfNV; y: GLhalfNV; z: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex3hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4hNV = procedure(x: GLhalfNV; y: GLhalfNV; z: GLhalfNV; w: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertex4hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3hNV = procedure(nx: GLhalfNV; ny: GLhalfNV; nz: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3hNV = procedure(red: GLhalfNV; green: GLhalfNV; blue: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4hNV = procedure(red: GLhalfNV; green: GLhalfNV; blue: GLhalfNV; alpha: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1hNV = procedure(s: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord1hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2hNV = procedure(s: GLhalfNV; t: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3hNV = procedure(s: GLhalfNV; t: GLhalfNV; r: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord3hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4hNV = procedure(s: GLhalfNV; t: GLhalfNV; r: GLhalfNV; q: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1hNV = procedure(target: GLenum; s: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord1hvNV = procedure(target: GLenum; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2hNV = procedure(target: GLenum; s: GLhalfNV; t: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord2hvNV = procedure(target: GLenum; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3hNV = procedure(target: GLenum; s: GLhalfNV; t: GLhalfNV; r: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord3hvNV = procedure(target: GLenum; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4hNV = procedure(target: GLenum; s: GLhalfNV; t: GLhalfNV; r: GLhalfNV; q: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMultiTexCoord4hvNV = procedure(target: GLenum; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordhNV = procedure(fog: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordhvNV = procedure(const fog: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3hNV = procedure(red: GLhalfNV; green: GLhalfNV; blue: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColor3hvNV = procedure(const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexWeighthNV = procedure(weight: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexWeighthvNV = procedure(const weight: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1hNV = procedure(index: GLuint; x: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1hvNV = procedure(index: GLuint; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2hNV = procedure(index: GLuint; x: GLhalfNV; y: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2hvNV = procedure(index: GLuint; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3hNV = procedure(index: GLuint; x: GLhalfNV; y: GLhalfNV; z: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3hvNV = procedure(index: GLuint; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4hNV = procedure(index: GLuint; x: GLhalfNV; y: GLhalfNV; z: GLhalfNV; w: GLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4hvNV = procedure(index: GLuint; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs1hvNV = procedure(index: GLuint; n: GLsizei; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs2hvNV = procedure(index: GLuint; n: GLsizei; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs3hvNV = procedure(index: GLuint; n: GLsizei; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs4hvNV = procedure(index: GLuint; n: GLsizei; const v: PGLhalfNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_occlusion_query
+ TglGenOcclusionQueriesNV = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteOcclusionQueriesNV = procedure(n: GLsizei; const ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsOcclusionQueryNV = function(id: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBeginOcclusionQueryNV = procedure(id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndOcclusionQueryNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetOcclusionQueryivNV = procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetOcclusionQueryuivNV = procedure(id: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_pixel_data_range
+ TglPixelDataRangeNV = procedure(target: GLenum; length: GLsizei; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFlushPixelDataRangeNV = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_point_sprite
+ TglPointParameteriNV = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterivNV = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_primitive_restart
+ TglPrimitiveRestartNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPrimitiveRestartIndexNV = procedure(index: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_register_combiners
+ TglCombinerParameterfvNV = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCombinerParameterfNV = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCombinerParameterivNV = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCombinerParameteriNV = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCombinerInputNV = procedure(stage: GLenum; portion: GLenum; variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCombinerOutputNV = procedure(stage: GLenum; portion: GLenum; abOutput: GLenum; cdOutput: GLenum; sumOutput: GLenum; scale: GLenum; bias: GLenum; abDotProduct: GLboolean; cdDotProduct: GLboolean; muxSum: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinalCombinerInputNV = procedure(variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCombinerInputParameterfvNV = procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCombinerInputParameterivNV = procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCombinerOutputParameterfvNV = procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCombinerOutputParameterivNV = procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFinalCombinerInputParameterfvNV = procedure(variable: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFinalCombinerInputParameterivNV = procedure(variable: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_register_combiners2
+ TglCombinerStageParameterfvNV = procedure(stage: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetCombinerStageParameterfvNV = procedure(stage: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vertex_array_range
+ TglFlushVertexArrayRangeNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexArrayRangeNV = procedure(length: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vertex_program
+ TglAreProgramsResidentNV = function(n: GLsizei; const programs: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindProgramNV = procedure(target: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteProgramsNV = procedure(n: GLsizei; const programs: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglExecuteProgramNV = procedure(target: GLenum; id: GLuint; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenProgramsNV = procedure(n: GLsizei; programs: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramParameterdvNV = procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramParameterfvNV = procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramivNV = procedure(id: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramStringNV = procedure(id: GLuint; pname: GLenum; _program: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTrackMatrixivNV = procedure(target: GLenum; address: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribdvNV = procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribfvNV = procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribivNV = procedure(index: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribPointervNV = procedure(index: GLuint; pname: GLenum; _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsProgramNV = function(id: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadProgramNV = procedure(target: GLenum; id: GLuint; len: GLsizei; const _program: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameter4dNV = procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameter4dvNV = procedure(target: GLenum; index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameter4fNV = procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameter4fvNV = procedure(target: GLenum; index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameters4dvNV = procedure(target: GLenum; index: GLuint; count: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramParameters4fvNV = procedure(target: GLenum; index: GLuint; count: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglRequestResidentProgramsNV = procedure(n: GLsizei; const programs: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTrackMatrixNV = procedure(target: GLenum; address: GLuint; matrix: GLenum; transform: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribPointerNV = procedure(index: GLuint; fsize: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1dNV = procedure(index: GLuint; x: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1dvNV = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1fNV = procedure(index: GLuint; x: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1fvNV = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1sNV = procedure(index: GLuint; x: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib1svNV = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2dNV = procedure(index: GLuint; x: GLdouble; y: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2dvNV = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2fNV = procedure(index: GLuint; x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2fvNV = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2sNV = procedure(index: GLuint; x: GLshort; y: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib2svNV = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3dNV = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3dvNV = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3fNV = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3fvNV = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3sNV = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib3svNV = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4dNV = procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4dvNV = procedure(index: GLuint; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4fNV = procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4fvNV = procedure(index: GLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4sNV = procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4svNV = procedure(index: GLuint; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4ubNV = procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttrib4ubvNV = procedure(index: GLuint; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs1dvNV = procedure(index: GLuint; count: GLsizei; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs1fvNV = procedure(index: GLuint; count: GLsizei; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs1svNV = procedure(index: GLuint; count: GLsizei; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs2dvNV = procedure(index: GLuint; count: GLsizei; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs2fvNV = procedure(index: GLuint; count: GLsizei; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs2svNV = procedure(index: GLuint; count: GLsizei; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs3dvNV = procedure(index: GLuint; count: GLsizei; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs3fvNV = procedure(index: GLuint; count: GLsizei; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs3svNV = procedure(index: GLuint; count: GLsizei; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs4dvNV = procedure(index: GLuint; count: GLsizei; const v: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs4fvNV = procedure(index: GLuint; count: GLsizei; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs4svNV = procedure(index: GLuint; count: GLsizei; const v: PGLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribs4ubvNV = procedure(index: GLuint; count: GLsizei; const v: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_depth_buffer_float
+ TglDepthRangedNV = procedure(n: GLdouble; f: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglClearDepthdNV = procedure(d: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDepthBoundsdNV = procedure(zmin: GLdouble; zmax: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_framebuffer_multisample_coverage
+ TglRenderbufferStorageMultsampleCoverageNV = procedure(target: GLenum; coverageSamples: GLsizei; colorSamples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_geometry_program4
+ TglProgramVertexLimitNV = procedure(target: GLenum; limit: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_gpu_program4
+ TglProgramLocalParameterI4iNV = procedure(target: GLenum; index: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameterI4ivNV = procedure(target: GLenum; index: GLuint; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParametersI4ivNV = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameterI4uiNV = procedure(target: GLenum; index: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParameterI4uivNV = procedure(target: GLenum; index: GLuint; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramLocalParametersI4uivNV = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameterI4iNV = procedure(target: GLenum; index: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameterI4ivNV = procedure(target: GLenum; index: GLuint; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParametersI4ivNV = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameterI4uiNV = procedure(target: GLenum; index: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParameterI4uivNV = procedure(target: GLenum; index: GLuint; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramEnvParametersI4uivNV = procedure(target: GLenum; index: GLuint; count: GLsizei; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramLocalParameterIivNV = procedure(target: GLenum; index: GLuint; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramLocalParameterIuivNV = procedure(target: GLenum; index: GLuint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramEnvParameterIivNV = procedure(target: GLenum; index: GLuint; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramEnvParameterIuivNV = procedure(target: GLenum; index: GLuint; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_parameter_buffer_object
+ TglProgramBufferParametersfvNV = procedure(target: GLenum; buffer: GLuint; index: GLuint; count: GLsizei; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramBufferParametersIivNV = procedure(target: GLenum; buffer: GLuint; index: GLuint; count: GLsizei; const params: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramBufferParametersIuivNV = procedure(target: GLenum; buffer: GLuint; index: GLuint; count: GLuint; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_transform_feedback
+ TglBeginTransformFeedbackNV = procedure(primitiveMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndTransformFeedbackNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackAttribsNV = procedure(count: GLsizei; const attribs: GLint; bufferMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferRangeNV = procedure(target: GLenum; index: GLuint; buffer: GLuint; offset: GLintptr; size: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferOffsetNV = procedure(target: GLenum; index: GLuint; buffer: GLuint; offset: GLintptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindBufferBaseNV = procedure(target: GLenum; index: GLuint; buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackVaryingsNV = procedure(program_: GLuint; count: GLsizei; const locations: PGLint; bufferMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglActiveVaryingNV = procedure(program_: GLuint; const name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVaryingLocationNV = function(program_: GLuint; const name: PGLchar): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetActiveVaryingNV = procedure(program_: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLsizei; _type: PGLenum; name: PGLchar); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTransformFeedbackVaryingNV = procedure(program_: GLuint; index: GLuint; location: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformFeedbackStreamAttribsNV = procedure(count: GLsizei; const attribs: PGLint; nbuffers: GLsizei; const bufstreams: PGLint; bufferMode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_conditional_render
+ TglBeginConditionalRenderNV = procedure(id: GLuint; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndConditionalRenderNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_conservative_raster
+ TglSubpixelPrecisionBiasNV = procedure(xbits : GLuint; ybits : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_conservative_raster_dilate
+ TglConservativeRasterParameterfNV = procedure(pname : GLenum; value : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_present_video
+ TglPresentFrameKeyedNV = procedure(video_slot: GLuint; minPresentTime: GLuint64EXT; beginPresentTimeId: GLuint; presentDuratioId: GLuint; type_: GLenum; target0: GLenum; fill0: GLuint; key0: GLuint; target1: GLenum; fill1: GLuint; key1: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPresentFrameDualFillNV = procedure(video_slot: GLuint; minPresentTime: GLuint64EXT; beginPresentTimeId: GLuint; presentDurationId: GLuint; type_: GLenum; target0: GLenum; fill0: GLuint; target1: GLenum; fill1: GLuint; target2: GLenum; fill2: GLuint; target3: GLenum; fill3: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoivNV = procedure(video_slot: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideouivNV = procedure(video_slot: GLuint; pname: GLenum; params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoi64vNV = procedure(video_slot: GLuint; pname: GLenum; params: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoui64vNV = procedure(video_slot: GLuint; pname: GLenum; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+// TglVideoParameterivNV = procedure(video_slot: GLuint; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_explicit_multisample
+ TglGetMultisamplefvNV = procedure (pname: GLenum; index: GLuint; val: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSampleMaskIndexedNV = procedure (index: GLuint; mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexRenderbufferNV = procedure (target: GLenum; renderbuffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_transform_feedback2
+ TglBindTransformFeedbackNV = procedure(target: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteTransformFeedbacksNV = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenTransformFeedbacksNV = procedure(n: GLsizei; ids: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTransformFeedbackNV = function (id: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPauseTransformFeedbackNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglResumeTransformFeedbackNV = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDrawTransformFeedbackNV = procedure(mode: GLenum; id: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_video_capture
+ TglBeginVideoCaptureNV = procedure(video_capture_slot: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindVideoCaptureStreamBufferNV = procedure(video_capture_slot: GLuint; stream: GLuint; frame_region: GLenum; offset: GLintptrARB); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglBindVideoCaptureStreamTextureNV = procedure(video_capture_slot: GLuint; stream: GLuint; frame_region: GLenum; target: GLenum; texture: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEndVideoCaptureNV = procedure(video_capture_slot: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoCaptureivNV = procedure(video_capture_slot: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoCaptureStreamivNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoCaptureStreamfvNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVideoCaptureStreamdvNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVideoCaptureNV = function(video_capture_slot: GLuint; sequence_num: PGLuint; capture_time: PGLuint64EXT): GLenum; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVideoCaptureStreamParameterivNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVideoCaptureStreamParameterfvNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVideoCaptureStreamParameterdvNV = procedure(video_capture_slot: GLuint; stream: GLuint; pname: GLenum; const params: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_copy_image
+ TglCopyImageSubDataNV = procedure(srcName: GLuint; srcTarget: GLenum; srcLevel: GLint; srcX: GLint; srcY: GLint; srcZ: GLint; dstName: GLuint; dstTarget: GLenum; dstLevel: GLint; dstX: GLint; dstY: GLint; dstZ: GLint; width: GLsizei; height: GLsizei; depth: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_shader_buffer_load
+ TglMakeBufferResidentNV = procedure(target: GLenum; access: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeBufferNonResidentNV = procedure(target: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsBufferResidentNV = function(target: GLenum): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeNamedBufferResidentNV = procedure(buffer: GLuint; access: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeNamedBufferNonResidentNV = procedure(buffer: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsNamedBufferResidentNV = function(buffer: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetBufferParameterui64vNV = procedure(target: GLenum; pname: GLenum; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetNamedBufferParameterui64vNV = procedure(buffer: GLuint; pname: GLenum; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetIntegerui64vNV = procedure(value: GLenum; result: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformui64NV = procedure(location: GLint; value: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformui64vNV = procedure(location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformui64vNV = procedure(_program: GLuint; location: GLint; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformui64NV = procedure(_program: GLuint; location: GLint; value: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformui64vNV = procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vertex_buffer_unified_memory
+ TglBufferAddressRangeNV = procedure(pname: GLenum; index: GLuint; adress: GLuint64EXT; length: GLsizeiptr); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexFormatNV = procedure(size: GLint; _type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormalFormatNV = procedure(_type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorFormatNV = procedure(size: GLint; _type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIndexFormatNV = procedure(_type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoordFormatNV = procedure(size: GLint; _type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglEdgeFlagFormatNV = procedure(stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSecondaryColorFormatNV = procedure(size: GLint; _type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFogCoordFormatNV = procedure(_type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribFormatNV = procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribIFormatNV = procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetIntegerui64i_vNV = procedure(value: GLenum; index: GLuint; Result: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_gpu_program5
+ TglProgramSubroutineParametersuivNV = procedure(target: GLenum; count: GLsizei; const params: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetProgramSubroutineParameteruivNV = procedure(target: GLenum; index: GLuint; param: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_gpu_shader5
+ TglUniform1i64NV = procedure(location: GLint; x: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2i64NV = procedure(location: GLint; x: GLint64EXT; y: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3i64NV = procedure(location: GLint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4i64NV = procedure(location: GLint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT; w: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1i64vNV = procedure(location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2i64vNV = procedure(location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3i64vNV = procedure(location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4i64vNV = procedure(location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ui64NV = procedure(location: GLint; x: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ui64NV = procedure(location: GLint; x: GLuint64EXT; y: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ui64NV = procedure(location: GLint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ui64NV = procedure(location: GLint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT; w: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform1ui64vNV = procedure(location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform2ui64vNV = procedure(location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform3ui64vNV = procedure(location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniform4ui64vNV = procedure(location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetUniformi64vNV = procedure(program_: GLuint; location: GLint; params: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1i64NV = procedure(program_: GLuint; location: GLint; x: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2i64NV = procedure(program_: GLuint; location: GLint; x: GLint64EXT; y: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3i64NV = procedure(program_: GLuint; location: GLint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4i64NV = procedure(program_: GLuint; location: GLint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT; w: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1i64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2i64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3i64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4i64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ui64NV = procedure(program_: GLuint; location: GLint; x: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ui64NV = procedure(program_: GLuint; location: GLint; x: GLuint64EXT; y: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ui64NV = procedure(program_: GLuint; location: GLint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ui64NV = procedure(program_: GLuint; location: GLint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT; w: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform1ui64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform2ui64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform3ui64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniform4ui64vNV = procedure(program_: GLuint; location: GLint; count: GLsizei; const value: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vertex_attrib_integer_64bit
+ TglVertexAttribL1i64NV = procedure(index: GLuint; x: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2i64NV = procedure(index: GLuint; x: GLint64EXT; y: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3i64NV = procedure(index: GLuint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4i64NV = procedure(index: GLuint; x: GLint64EXT; y: GLint64EXT; z: GLint64EXT; w: GLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1i64vNV = procedure(index: GLuint; const v: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2i64vNV = procedure(index: GLuint; const v: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3i64vNV = procedure(index: GLuint; const v: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4i64vNV = procedure(index: GLuint; const v: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1ui64NV = procedure(index: GLuint; x: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2ui64NV = procedure(index: GLuint; x: GLuint64EXT; y: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3ui64NV = procedure(index: GLuint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4ui64NV = procedure(index: GLuint; x: GLuint64EXT; y: GLuint64EXT; z: GLuint64EXT; w: GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1ui64vNV = procedure(index: GLuint; const v: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL2ui64vNV = procedure(index: GLuint; const v: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL3ui64vNV = procedure(index: GLuint; const v: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL4ui64vNV = procedure(index: GLuint; const v: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribLi64vNV = procedure(index: GLuint; pname: GLenum; params: PGLint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribLui64vNV = procedure(index: GLuint; pname: GLenum; params: PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribLFormatNV = procedure(index: GLuint; size: GLint; type_: GLenum; stride: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_vdpau_interop
+ TglVDPAUInitNV = procedure(const vdpDevice: PGLvoid; const getProcAddress: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUFiniNV = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAURegisterVideoSurfaceNV = function(vdpSurface: PGLvoid; target: GLenum; numTextureNames: GLsizei; const textureNames: PGLuint): GLvdpauSurfaceNV; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAURegisterOutputSurfaceNV = function(vdpSurface: PGLvoid; target: GLenum; numTextureNames: GLsizei; const textureNames: PGLuint): GLvdpauSurfaceNV; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUIsSurfaceNV = procedure(surface: GLvdpauSurfaceNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUUnregisterSurfaceNV = procedure(surface: GLvdpauSurfaceNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUGetSurfaceivNV = procedure(surface: GLvdpauSurfaceNV; pname: GLenum; bufSize: GLsizei; length: PGLsizei; values: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUSurfaceAccessNV = procedure(surface: GLvdpauSurfaceNV; access: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUMapSurfacesNV = procedure(numSurfaces: GLsizei; const surfaces: PGLvdpauSurfaceNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVDPAUUnmapSurfacesNV = procedure(numSurface: GLsizei; const surfaces: PGLvdpauSurfaceNV); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_texture_barrier
+ TglTextureBarrierNV = procedure; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // (4.3)
+ // GL_NV_path_rendering
+ TglGenPathsNV = function(range : GLsizei) : GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeletePathsNV = procedure(path : GLUInt; range : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsPathNV = function(path : GLUInt) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathCommandsNV = procedure(path : GLUInt; numCommands : GLsizei; const commands : PGLubyte; numCoords : GLsizei; coordType : GLenum; const coords : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathCoordsNV = procedure(path : GLUInt; numCoords : GLSizei; coordType : GLenum; const coords : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathSubCommandsNV = procedure(path : GLUInt; commandStart : GLsizei; commandsToDelete : GLsizei; numCommands : GLsizei; const commands : PGLubyte; numCoords : GLSizei; coordType : GLenum; const coords : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathSubCoordsNV = procedure(path : GLUInt; coordStart : GLsizei; numCoords : GLSizei; coordType : GLenum; const coords : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathStringNV = procedure(path : GLUInt; format : GLenum; length : GLsizei; const pathString : PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathGlyphsNV = procedure(firstPathName : GLuint; fontTarget : GLenum; const fontName : PGLvoid; fontStyle : GLbitfield; numGlyphs : GLsizei; type_ : GLenum; const charcodes : PGLvoid; handleMissingGlyphs : GLenum; pathParameterTemplate : GLUInt; emScale : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathGlyphRangeNV = procedure(firstPathName : GLuint; fontTarget : GLenum; const fontName : PGLvoid; fontStyle : GLbitfield; firstGlyph : GLuint; numGlyphs : GLsizei; handleMissingGlyphs : GLenum; pathParameterTemplate : GLUInt; emScale : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglWeightPathsNV = procedure(resultPath : GLUInt; numPaths : GLSizei; const paths : PGLuint; const weights : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyPathNV = procedure(resultPath : GLUInt; srcPath : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInterpolatePathsNV = procedure(resultPath : GLUInt; pathA : GLUInt; pathB : GLUInt; weight : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTransformPathNV = procedure(resultPath : GLUInt; srcPath : GLuint; transformType : GLenum; const transformValues : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathParameterivNV = procedure(path : GLUInt; pname : GLEnum; const value : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathParameteriNV = procedure(path : GLUInt; pname : GLEnum; value : GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathParameterfvNV = procedure(path : GLUInt; pname : GLEnum; const value : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathParameterfNV = procedure(path : GLUInt; pname : GLEnum; value : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathDashArrayNV = procedure(path : GLUInt; dashCount : GLsizei; const dashArray : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathStencilFuncNV = procedure(func : GLenum; ref : GLint; mask : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathStencilDepthOffsetNV = procedure(factor : GLfloat; units : GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilFillPathNV = procedure(path : GLUInt; fillMode : GLenum; mask : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilStrokePathNV = procedure(path : GLUInt; reference : GLint; mask : GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilFillPathInstancedNV = procedure(numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; fillMode : GLenum; mask : GLuint; transformType : GLenum; const transformValues : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStencilStrokePathInstancedNV = procedure(numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; reference : GLint; mask : GLuint; transformType : GLenum; const transformValues : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathCoverDepthFuncNV = procedure(func : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathColorGenNV = procedure(color : GLenum; genMode : GLenum; colorFormat : GLenum; const coeffs : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathTexGenNV = procedure(texCoordSet : GLenum; genMode : GLenum; components : GLint; const coeffs : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPathFogGenNV = procedure(genMode : GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCoverFillPathNV = procedure(path : GLUInt; coverMode : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCoverStrokePathNV = procedure(path : GLUInt; coverMode : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCoverFillPathInstancedNV = procedure(numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; coverMode : GLenum; transformType : GLenum; const transformValues : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCoverStrokePathInstancedNV = procedure(numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; coverMode : GLenum; transformType : GLenum; const transformValues : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathParameterivNV = procedure(path : GLUInt; pname : GLEnum; value : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathParameterfvNV = procedure(path : GLUInt; pname : GLEnum; value : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathCommandsNV = procedure(path : GLUInt; commands : PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathCoordsNV = procedure(path : GLUInt; coords : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathDashArrayNV = procedure(path : GLUInt; dashArray : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathMetricsNV = procedure(metricQueryMask : GLbitfield; numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; stride : GLsizei; metrics : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathMetricRangeNV = procedure(metricQueryMask : GLbitfield; firstPathName : GLuint; numPaths : GLSizei; stride : GLsizei; metrics : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathSpacingNV = procedure(pathListMode : GLenum; numPaths : GLSizei; pathNameType : GLenum; const paths : PGLvoid; pathBase : GLUInt; advanceScale : GLfloat; kerningScale : GLfloat; transformType : GLenum; returnedSpacing : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathColorGenivNV = procedure(color : GLenum; pname : GLEnum; value : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathColorGenfvNV = procedure(color : GLenum; pname : GLEnum; value : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathTexGenivNV = procedure(texCoordSet : GLenum; pname : GLEnum; value : PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathTexGenfvNV = procedure(texCoordSet : GLenum; pname : GLEnum; value : PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsPointInFillPathNV = function(path : GLUInt; mask : GLuint; x : GLfloat; y : GLfloat) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsPointInStrokePathNV = function (path : GLUInt; x : GLfloat; y : GLfloat) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPathLengthNV = function(path : GLUInt; startSegment : GLsizei; numSegments : GLsizei) : GLfloat; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointAlongPathNV = function(path : GLUInt; startSegment : GLsizei; numSegments : GLsizei; distance : GLfloat; x : PGLfloat; y : PGLfloat; tangentX : PGLfloat; tangentY : PGLfloat) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_pinned_memory
+
+ // GL_AMD_stencil_operation_extended
+ TglStencilOpValueAMD = procedure(face : GLEnum; value : GLUInt); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_AMD_vertex_shader_viewport_index
+
+ // GL_AMD_vertex_shader_layer
+
+ // GL_NV_bindless_texture
+ TglGetTextureHandleNV = function(texture : GLuint ) : GLuint64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureSamplerHandleNV = function(texture : GLuint; sampler : GLuint) : GLuint64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeTextureHandleResidentNV = procedure(handle : GLUint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeTextureHandleNonResidentNV = procedure(handle : GLUint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetImageHandleNV = function(texture : GLuint; level : GLint; layered : GLboolean; layer : GLint; format : GLenum) : GLUInt64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeImageHandleResidentNV = procedure(handle : GLUint64; access : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeImageHandleNonResidentNV = procedure(handle : GLUint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformHandleui64NV = procedure(location : GLint; value : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformHandleui64vNV = procedure(location : GLint; cowunt : GLsizei; const value : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformHandleui64NV = procedure(program_ : GLuint; location : GLint; value : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformHandleui64vNV = procedure(program_ : GLuint; location : GLint; count : GLsizei; const values : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTextureHandleResidentNV = function(handle : GLUint64) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsImageHandleResidentNV = function(handle : GLUint64) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_ARB_bindless_texture
+
+ TglGetTextureHandleARB = function (texture : GLuint) : GLUInt64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetTextureSamplerHandleARB = function (texture : GLuint; sampler : GLuint) : GLUInt64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeTextureHandleResidentARB = procedure (handle : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeTextureHandleNonResidentARB = procedure (handle : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetImageHandleARB = function (texture : GLuint; level : GLint; layered : GLboolean; layer : GLint; format : GLenum) : GLuint64; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeImageHandleResidentARB = procedure (handle : GLuint64; access : GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglMakeImageHandleNonResidentARB = procedure (handle : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformHandleui64ARB = procedure (location : GLint; value : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglUniformHandleui64vARB = procedure (location : GLint; count : GLsizei; const value : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformHandleui64ARB = procedure (program_ : GLuint; location : GLint; value : GLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglProgramUniformHandleui64vARB = procedure (program_ : GLuint; location : GLint; count : GLsizei; const values : PGLuint64); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsTextureHandleResidentARB = function (handle : GLuint64) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsImageHandleResidentARB = function (handle : GLuint64) : GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1ui64ARB = procedure (index : GLuint; x : GLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglVertexAttribL1ui64vARB = procedure (index : GLuint; const v : PGLuint64EXT); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetVertexAttribLui64vARB = procedure (index : GLuint; pname : GLenum; params : PGLuint64EXT ); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_NV_shader_atomic_float
+
+ // GL_AMD_query_buffer_object
+
+ // GL_OVR_multiview
+ TglFramebufferTextureMultiviewOVR = procedure(target : GLenum; attachment : GLenum; texture : GLuint; level : GLint; baseViewIndex : GLint; numViews : GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_PGI_misc_hints
+ TglHintPGI = procedure(target: GLenum; mode: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_detail_texture
+ TglDetailTexFuncSGIS = procedure(target: GLenum; n: GLsizei; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetDetailTexFuncSGIS = procedure(target: GLenum; points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_fog_function
+ TglFogFuncSGIS = procedure(n: GLsizei; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFogFuncSGIS = procedure(points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_multisample
+ TglSampleMaskSGIS = procedure(value: GLclampf; invert: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSamplePatternSGIS = procedure(pattern: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_pixel_texture
+ TglPixelTexGenParameteriSGIS = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTexGenParameterivSGIS = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTexGenParameterfSGIS = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPixelTexGenParameterfvSGIS = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPixelTexGenParameterivSGIS = procedure(pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetPixelTexGenParameterfvSGIS = procedure(pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_point_parameters
+ TglPointParameterfSGIS = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPointParameterfvSGIS = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_sharpen_texture
+ TglSharpenTexFuncSGIS = procedure(target: GLenum; n: GLsizei; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetSharpenTexFuncSGIS = procedure(target: GLenum; points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_texture4D
+ TglTexImage4DSGIS = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; size4d: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexSubImage4DSGIS = procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; woffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; size4d: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_texture_color_mask
+ TglTextureColorMaskSGIS = procedure(red: GLboolean; green: GLboolean; blue: GLboolean; alpha: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIS_texture_filter4
+ TglGetTexFilterFuncSGIS = procedure(target: GLenum; filter: GLenum; weights: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexFilterFuncSGIS = procedure(target: GLenum; filter: GLenum; n: GLsizei; const weights: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_async
+ TglAsyncMarkerSGIX = procedure(marker: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFinishAsyncSGIX = function(markerp: PGLuint): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPollAsyncSGIX = function(markerp: PGLuint): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGenAsyncMarkersSGIX = function(range: GLsizei): GLuint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeleteAsyncMarkersSGIX = procedure(marker: GLuint; range: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglIsAsyncMarkerSGIX = function(marker: GLuint): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_flush_raster
+ TglFlushRasterSGIX = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_fragment_lighting
+ TglFragmentColorMaterialSGIX = procedure(face: GLenum; mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightfSGIX = procedure(light: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightfvSGIX = procedure(light: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightiSGIX = procedure(light: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightivSGIX = procedure(light: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightModelfSGIX = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightModelfvSGIX = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightModeliSGIX = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentLightModelivSGIX = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentMaterialfSGIX = procedure(face: GLenum; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentMaterialfvSGIX = procedure(face: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentMaterialiSGIX = procedure(face: GLenum; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglFragmentMaterialivSGIX = procedure(face: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragmentLightfvSGIX = procedure(light: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragmentLightivSGIX = procedure(light: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragmentMaterialfvSGIX = procedure(face: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetFragmentMaterialivSGIX = procedure(face: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLightEnviSGIX = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_framezoom
+ TglFrameZoomSGIX = procedure(factor: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_igloo_interface
+ TglIglooInterfaceSGIX = procedure(pname: GLenum; const params: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_instruments
+ TglGetInstrumentsSGIX = function(): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglInstrumentsBufferSGIX = procedure(size: GLsizei; buffer: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglPollInstrumentsSGIX = function(marker_p: PGLint): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReadInstrumentsSGIX = procedure(marker: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStartInstrumentsSGIX = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglStopInstrumentsSGIX = procedure(marker: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_list_priority
+ TglGetListParameterfvSGIX = procedure(list: GLuint; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetListParameterivSGIX = procedure(list: GLuint; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglListParameterfSGIX = procedure(list: GLuint; pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglListParameterfvSGIX = procedure(list: GLuint; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglListParameteriSGIX = procedure(list: GLuint; pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglListParameterivSGIX = procedure(list: GLuint; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_pixel_texture
+ TglPixelTexGenSGIX = procedure(mode: GLenum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_polynomial_ffd
+ TglDeformationMap3dSGIX = procedure(target: GLenum; u1: GLdouble; u2: GLdouble; ustride: GLint; uorder: GLint; v1: GLdouble; v2: GLdouble; vstride: GLint; vorder: GLint; w1: GLdouble; w2: GLdouble; wstride: GLint; worder: GLint; const points: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeformationMap3fSGIX = procedure(target: GLenum; u1: GLfloat; u2: GLfloat; ustride: GLint; uorder: GLint; v1: GLfloat; v2: GLfloat; vstride: GLint; vorder: GLint; w1: GLfloat; w2: GLfloat; wstride: GLint; worder: GLint; const points: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglDeformSGIX = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglLoadIdentityDeformationMapSGIX = procedure(mask: GLbitfield); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_reference_plane
+ TglReferencePlaneSGIX = procedure(const equation: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_sprite
+ TglSpriteParameterfSGIX = procedure(pname: GLenum; param: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSpriteParameterfvSGIX = procedure(pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSpriteParameteriSGIX = procedure(pname: GLenum; param: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglSpriteParameterivSGIX = procedure(pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGIX_tag_sample_buffer
+ TglTagSampleBufferSGIX = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SGI_color_table
+ TglColorTableSGI = procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorTableParameterfvSGI = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColorTableParameterivSGI = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglCopyColorTableSGI = procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableSGI = procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameterfvSGI = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGetColorTableParameterivSGI = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SUNX_constant_data
+ TglFinishTextureSUNX = procedure(); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SUN_global_alpha
+ TglGlobalAlphaFactorbSUN = procedure(factor: GLbyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactorsSUN = procedure(factor: GLshort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactoriSUN = procedure(factor: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactorfSUN = procedure(factor: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactordSUN = procedure(factor: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactorubSUN = procedure(factor: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactorusSUN = procedure(factor: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglGlobalAlphaFactoruiSUN = procedure(factor: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SUN_mesh_array
+ TglDrawMeshArraysSUN = procedure(mode: GLenum; first: GLint; count: GLsizei; width: GLsizei); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SUN_triangle_list
+ TglReplacementCodeuiSUN = procedure(code: GLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeusSUN = procedure(code: GLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeubSUN = procedure(code: GLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuivSUN = procedure(const code: PGLuint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeusvSUN = procedure(const code: PGLushort); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeubvSUN = procedure(const code: PGLubyte); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodePointerSUN = procedure(_type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // GL_SUN_vertex
+ TglColor4ubVertex2fSUN = procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ubVertex2fvSUN = procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ubVertex3fSUN = procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4ubVertex3fvSUN = procedure(const c: PGLubyte; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3fVertex3fSUN = procedure(r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor3fVertex3fvSUN = procedure(const c: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3fVertex3fSUN = procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglNormal3fVertex3fvSUN = procedure(const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4fNormal3fVertex3fSUN = procedure(r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglColor4fNormal3fVertex3fvSUN = procedure(const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fVertex3fSUN = procedure(s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fVertex3fvSUN = procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4fVertex4fSUN = procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4fVertex4fvSUN = procedure(const tc: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor4ubVertex3fSUN = procedure(s: GLfloat; t: GLfloat; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor4ubVertex3fvSUN = procedure(const tc: PGLfloat; const c: PGLubyte; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor3fVertex3fSUN = procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor3fVertex3fvSUN = procedure(const tc: PGLfloat; const c: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fNormal3fVertex3fSUN = procedure(s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fNormal3fVertex3fvSUN = procedure(const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor4fNormal3fVertex3fSUN = procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord2fColor4fNormal3fVertex3fvSUN = procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4fColor4fNormal3fVertex4fSUN = procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglTexCoord4fColor4fNormal3fVertex4fvSUN = procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiVertex3fSUN = procedure(rc: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiVertex3fvSUN = procedure(const rc: PGLuint; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor4ubVertex3fSUN = procedure(rc: GLuint; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor4ubVertex3fvSUN = procedure(const rc: PGLuint; const c: PGLubyte; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor3fVertex3fSUN = procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor3fVertex3fvSUN = procedure(const rc: PGLuint; const c: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiNormal3fVertex3fSUN = procedure(rc: GLuint; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiNormal3fVertex3fvSUN = procedure(const rc: PGLuint; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor4fNormal3fVertex3fSUN = procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiColor4fNormal3fVertex3fvSUN = procedure(const rc: PGLuint; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fVertex3fSUN = procedure(rc: GLuint; s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fVertex3fvSUN = procedure(const rc: PGLuint; const tc: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = procedure(rc: GLuint; s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = procedure(const rc: PGLuint; const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = procedure(rc: GLuint; s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = procedure(const rc: PGLuint; const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+ // window support functions
+{$IFDEF DGL_WIN}
+ TwglGetProcAddress = function(ProcName: PAnsiChar): Pointer; stdcall;
+ TwglCopyContext = function(p1: HGLRC; p2: HGLRC; p3: Cardinal): BOOL; stdcall;
+ TwglCreateContext = function(DC: HDC): HGLRC; stdcall;
+ TwglCreateLayerContext = function(p1: HDC; p2: Integer): HGLRC; stdcall;
+ TwglDeleteContext = function(p1: HGLRC): BOOL; stdcall;
+ TwglDescribeLayerPlane = function(p1: HDC; p2, p3: Integer; p4: Cardinal; p5: PLayerPlaneDescriptor): BOOL; stdcall;
+ TwglGetCurrentContext = function: HGLRC; stdcall;
+ TwglGetCurrentDC = function: HDC; stdcall;
+ TwglGetLayerPaletteEntries = function(p1: HDC; p2, p3, p4: Integer; var pcr): Integer; stdcall;
+ TwglMakeCurrent = function(DC: HDC; p2: HGLRC): BOOL; stdcall;
+ TwglRealizeLayerPalette = function(p1: HDC; p2: Integer; p3: BOOL): BOOL; stdcall;
+ TwglSetLayerPaletteEntries = function(p1: HDC; p2, p3, p4: Integer; var pcr): Integer; stdcall;
+ TwglShareLists = function(p1, p2: HGLRC): BOOL; stdcall;
+ TwglSwapLayerBuffers = function(p1: HDC; p2: Cardinal): BOOL; stdcall;
+ TwglSwapMultipleBuffers = function(p1: UINT; const p2: PWGLSWAP): DWORD; stdcall;
+ TwglUseFontBitmapsA = function(DC: HDC; p2, p3, p4: DWORD): BOOL; stdcall;
+ TwglUseFontBitmapsW = function(DC: HDC; p2, p3, p4: DWORD): BOOL; stdcall;
+ TwglUseFontBitmaps = function(DC: HDC; p2, p3, p4: DWORD): BOOL; stdcall;
+
+ TwglUseFontOutlinesA = function(p1: HDC; p2, p3, p4: DWORD; p5, p6: Single; p7: Integer; p8: PGlyphMetricsFloat): BOOL; stdcall;
+ TwglUseFontOutlinesW = function(p1: HDC; p2, p3, p4: DWORD; p5, p6: Single; p7: Integer; p8: PGlyphMetricsFloat): BOOL; stdcall;
+ TwglUseFontOutlines = function(p1: HDC; p2, p3, p4: DWORD; p5, p6: Single; p7: Integer; p8: PGlyphMetricsFloat): BOOL; stdcall;
+
+
+ // WGL_ARB_buffer_region
+ TwglCreateBufferRegionARB = function(hDC: HDC; iLayerPlane: GLint; uType: GLuint): THandle; stdcall;
+ TwglDeleteBufferRegionARB = procedure(hRegion: THandle); stdcall;
+ TwglSaveBufferRegionARB = function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint): Boolean; stdcall;
+ TwglRestoreBufferRegionARB = function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint; xSrc: GLint; ySrc: GLint): Boolean; stdcall;
+
+ // WGL_ARB_extensions_string
+ TwglGetExtensionsStringARB = function(hdc: HDC): PAnsiChar; stdcall;
+
+ // WGL_ARB_make_current_read
+ TwglMakeContextCurrentARB = function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): Boolean; stdcall;
+ TwglGetCurrentReadDCARB = function(): HDC; stdcall;
+
+ // WGL_ARB_pbuffer
+ TwglCreatePbufferARB = function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): HPBUFFERARB; stdcall;
+ TwglGetPbufferDCARB = function(hPbuffer: HPBUFFERARB): HDC; stdcall;
+ TwglReleasePbufferDCARB = function(hPbuffer: HPBUFFERARB; hDC: HDC): GLint; stdcall;
+ TwglDestroyPbufferARB = function(hPbuffer: HPBUFFERARB): Boolean; stdcall;
+ TwglQueryPbufferARB = function(hPbuffer: HPBUFFERARB; iAttribute: GLint; piValue: PGLint): Boolean; stdcall;
+
+ // WGL_ARB_pixel_format
+ TwglGetPixelFormatAttribivARB = function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): Boolean; stdcall;
+ TwglGetPixelFormatAttribfvARB = function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; pfValues: PGLfloat): Boolean; stdcall;
+ TwglChoosePixelFormatARB = function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; stdcall;
+
+ // WGL_ARB_color_buffer_float
+ TwglClampColorARB = procedure(target: GLenum; clamp: GLenum); stdcall;
+
+ // WGL_ARB_render_texture
+ TwglBindTexImageARB = function(hPbuffer: HPBUFFERARB; iBuffer: GLint): Boolean; stdcall;
+ TwglReleaseTexImageARB = function(hPbuffer: HPBUFFERARB; iBuffer: GLint): Boolean; stdcall;
+ TwglSetPbufferAttribARB = function(hPbuffer: HPBUFFERARB; const piAttribList: PGLint): Boolean; stdcall;
+
+ // WGL_ARB_create_context
+ TwglCreateContextAttribsARB = function(hDC: HDC; hShareContext: HGLRC; const attribList: PGLint): HGLRC; stdcall;
+
+ // WGL_AMD_gpu_association
+ TwglGetGPUIDsAMD = function(maxCount: Cardinal; ids: PCardinal): Cardinal; stdcall;
+ TwglGetGPUInfoAMD = function(id: Cardinal; property_: Integer; dataType: GLenum; size: Cardinal; data: Pointer): Integer; stdcall;
+ TwglGetContextGPUIDAMD = function(hglrc: HGLRC): Cardinal; stdcall;
+ TwglCreateAssociatedContextAMD = function(id: Cardinal): HGLRC; stdcall;
+ TwglCreateAssociatedContextAttribsAMD = function(id: Cardinal; hShareContext: HGLRC; const attribList: PInteger): HGLRC; stdcall;
+ TwglDeleteAssociatedContextAMD = function(hglrc: HGLRC): Boolean; stdcall;
+ TwglMakeAssociatedContextCurrentAMD = function(hglrc: HGLRC): Boolean; stdcall;
+ TwglGetCurrentAssociatedContextAMD = function(): HGLRC; stdcall;
+ TwglBlitContextFramebufferAMD = procedure(dstCtx: HGLRC; srcX0: GLint; srcY0: GLint; srcX1: GLint; srcY1: GLint; dstX0: GLint; dstY0: GLint; dstX1: GLint; dstY1: GLint; mask: GLbitfield; filter: GLenum); stdcall;
+
+ // WGL_EXT_display_color_table
+ TwglCreateDisplayColorTableEXT = function(id: GLushort): GLboolean; stdcall;
+ TwglLoadDisplayColorTableEXT = function(const table: PGLushort; length: GLuint): GLboolean; stdcall;
+ TwglBindDisplayColorTableEXT = function(id: GLushort): GLboolean; stdcall;
+ TwglDestroyDisplayColorTableEXT = procedure(id: GLushort); stdcall;
+
+ // WGL_EXT_extensions_string
+ TwglGetExtensionsStringEXT = function(): PAnsiChar; stdcall;
+
+ // WGL_EXT_make_current_read
+ TwglMakeContextCurrentEXT = function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): Boolean; stdcall;
+ TwglGetCurrentReadDCEXT = function(): HDC; stdcall;
+
+ // WGL_EXT_pbuffer
+ TwglCreatePbufferEXT = function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): HPBUFFEREXT; stdcall;
+ TwglGetPbufferDCEXT = function(hPbuffer: HPBUFFEREXT): HDC; stdcall;
+ TwglReleasePbufferDCEXT = function(hPbuffer: HPBUFFEREXT; hDC: HDC): GLint; stdcall;
+ TwglDestroyPbufferEXT = function(hPbuffer: HPBUFFEREXT): Boolean; stdcall;
+ TwglQueryPbufferEXT = function(hPbuffer: HPBUFFEREXT; iAttribute: GLint; piValue: PGLint): Boolean; stdcall;
+
+ // WGL_EXT_pixel_format
+ TwglGetPixelFormatAttribivEXT = function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; piValues: PGLint): Boolean; stdcall;
+ TwglGetPixelFormatAttribfvEXT = function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; pfValues: PGLfloat): Boolean; stdcall;
+ TwglChoosePixelFormatEXT = function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): Boolean; stdcall;
+
+ // WGL_EXT_swap_control
+ TwglSwapIntervalEXT = function(interval: GLint): Boolean; stdcall;
+ TwglGetSwapIntervalEXT = function(): GLint; stdcall;
+
+ // WGL_I3D_digital_video_control
+ TwglGetDigitalVideoParametersI3D = function(hDC: HDC; iAttribute: GLint; piValue: PGLint): Boolean; stdcall;
+ TwglSetDigitalVideoParametersI3D = function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): Boolean; stdcall;
+
+ // WGL_I3D_gamma
+ TwglGetGammaTableParametersI3D = function(hDC: HDC; iAttribute: GLint; piValue: PGLint): Boolean; stdcall;
+ TwglSetGammaTableParametersI3D = function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): Boolean; stdcall;
+ TwglGetGammaTableI3D = function(hDC: HDC; iEntries: GLint; puRed: PGLushort; puGreen: PGLushort; puBlue: PGLushort): Boolean; stdcall;
+ TwglSetGammaTableI3D = function(hDC: HDC; iEntries: GLint; const puRed: PGLushort; const puGreen: PGLushort; const puBlue: PGLushort): Boolean; stdcall;
+
+ // WGL_I3D_genlock
+ TwglEnableGenlockI3D = function(hDC: HDC): Boolean; stdcall;
+ TwglDisableGenlockI3D = function(hDC: HDC): Boolean; stdcall;
+ TwglIsEnabledGenlockI3D = function(hDC: HDC; pFlag: Boolean): Boolean; stdcall;
+ TwglGenlockSourceI3D = function(hDC: HDC; uSource: GLuint): Boolean; stdcall;
+ TwglGetGenlockSourceI3D = function(hDC: HDC; uSource: PGLuint): Boolean; stdcall;
+ TwglGenlockSourceEdgeI3D = function(hDC: HDC; uEdge: GLuint): Boolean; stdcall;
+ TwglGetGenlockSourceEdgeI3D = function(hDC: HDC; uEdge: PGLuint): Boolean; stdcall;
+ TwglGenlockSampleRateI3D = function(hDC: HDC; uRate: GLuint): Boolean; stdcall;
+ TwglGetGenlockSampleRateI3D = function(hDC: HDC; uRate: PGLuint): Boolean; stdcall;
+ TwglGenlockSourceDelayI3D = function(hDC: HDC; uDelay: GLuint): Boolean; stdcall;
+ TwglGetGenlockSourceDelayI3D = function(hDC: HDC; uDelay: PGLuint): Boolean; stdcall;
+ TwglQueryGenlockMaxSourceDelayI3D = function(hDC: HDC; uMaxLineDelay: PGLuint; uMaxPixelDelay: PGLuint): Boolean; stdcall;
+
+ // WGL_I3D_image_buffer
+ TwglCreateImageBufferI3D = function(hDC: HDC; dwSize: GLuint; uFlags: GLuint): GLvoid; stdcall;
+ TwglDestroyImageBufferI3D = function(hDC: HDC; pAddress: GLvoid): Boolean; stdcall;
+ TwglAssociateImageBufferEventsI3D = function(hDC: HDC; const pEvent: THandle; const pAddress: PGLvoid; const pSize: PGLuint; count: GLuint): Boolean; stdcall;
+ TwglReleaseImageBufferEventsI3D = function(hDC: HDC; const pAddress: PGLvoid; count: GLuint): Boolean; stdcall;
+
+ // WGL_I3D_swap_frame_lock
+ TwglEnableFrameLockI3D = function(): Boolean; stdcall;
+ TwglDisableFrameLockI3D = function(): Boolean; stdcall;
+ TwglIsEnabledFrameLockI3D = function(pFlag: Boolean): Boolean; stdcall;
+ TwglQueryFrameLockMasterI3D = function(pFlag: Boolean): Boolean; stdcall;
+
+ // WGL_I3D_swap_frame_usage
+ TwglGetFrameUsageI3D = function(pUsage: PGLfloat): Boolean; stdcall;
+ TwglBeginFrameTrackingI3D = function(): Boolean; stdcall;
+ TwglEndFrameTrackingI3D = function(): Boolean; stdcall;
+ TwglQueryFrameTrackingI3D = function(pFrameCount: PGLuint; pMissedFrames: PGLuint; pLastMissedUsage: PGLfloat): Boolean; stdcall;
+
+ // WGL_NV_vertex_array_range
+ TwglAllocateMemoryNV = procedure(size: GLsizei; readfreq: GLfloat; writefreq: GLfloat; priority: GLfloat); stdcall;
+ TwglFreeMemoryNV = procedure(_pointer: Pointer); stdcall;
+
+ // WGL_NV_present_video
+ TwglEnumerateVideoDevicesNV = function(hdc: HDC; phDeviceList: PHVIDEOOUTPUTDEVICENV): Integer; stdcall;
+ TwglBindVideoDeviceNV = function(hd: HDC; uVideoSlot: Cardinal; hVideoDevice: HVIDEOOUTPUTDEVICENV; piAttribList: PInteger): Boolean; stdcall;
+ TwglQueryCurrentContextNV = function(iAttribute: Integer; piValue: PInteger): Boolean; stdcall;
+
+ // WGL_NV_video_output
+ TwglGetVideoDeviceNV = function(hDC: HDC; numDevices: Integer; hVideoDevice: PHPVIDEODEV): Boolean; stdcall;
+ TwglReleaseVideoDeviceNV = function(hVideoDevice: HPVIDEODEV): Boolean; stdcall;
+ TwglBindVideoImageNV = function(hVideoDevice: HPVIDEODEV; hPbuffer: HPBUFFERARB; iVideoBuffer: Integer): Boolean; stdcall;
+ TwglReleaseVideoImageNV = function(hPbuffer: HPBUFFERARB; iVideoBuffer: Integer): Boolean; stdcall;
+ TwglSendPbufferToVideoNV = function(hPbuffer: HPBUFFERARB; iBufferType: Integer; pulCounterPbuffer: PCardinal; bBlock: Boolean): Boolean; stdcall;
+ TwglGetVideoInfoNV = function(hpVideoDevice: HPVIDEODEV; pulCounterOutputPbuffer: PCardinal; pulCounterOutputVideo: PCardinal): Boolean; stdcall;
+
+ // WGL_NV_swap_group
+ TwglJoinSwapGroupNV = function(hDC: HDC; group: GLuint): Boolean; stdcall;
+ TwglBindSwapBarrierNV = function(group: GLuint; barrier: GLuint): Boolean; stdcall;
+ TwglQuerySwapGroupNV = function(hDC: HDC; group: PGLuint; barrier: PGLuint): Boolean; stdcall;
+ TwglQueryMaxSwapGroupsNV = function(hDC: HDC; mxGroups: PGLuint; maxBarriers: PGLuint): Boolean; stdcall;
+ TwglQueryFrameCountNV = function(hDC: HDC; count: PGLuint): Boolean; stdcall;
+ TwglResetFrameCountNV = function(hDC: HDC): Boolean; stdcall;
+
+ // WGL_NV_gpu_affinity
+ TwglEnumGpusNV = function(iGpuIndex: Cardinal; phGpu: PHGPUNV): Boolean; stdcall;
+ TwglEnumGpuDevicesNV = function(hGpu: HGPUNV; iDeviceIndex: Cardinal; lpGpuDevice: PGPU_DEVICE): Boolean; stdcall;
+ TwglCreateAffinityDCNV = function(const phGpuList: PHGPUNV): HDC; stdcall;
+ TwglEnumGpusFromAffinityDCNV = function(hAffinityDC: HDC; iGpuIndex: Cardinal; hGpu: PHGPUNV): Boolean; stdcall;
+ TwglDeleteDCNV = function(hDC: HDC): Boolean; stdcall;
+
+ // WGL_NV_video_capture
+ TwglBindVideoCaptureDeviceNV = function(uVideoSlot: Cardinal; hDevice: HVIDEOINPUTDEVICENV): Boolean; stdcall;
+ TwglEnumerateVideoCaptureDevicesNV = function(hDc: HDC; phDeviceList: PHVIDEOINPUTDEVICENV): Cardinal; stdcall;
+ TwglLockVideoCaptureDeviceNV = function(hDc: HDC; hDevice: HVIDEOINPUTDEVICENV): Boolean; stdcall;
+ TwglQueryVideoCaptureDeviceNV = function(hDc: HDC; hDevice: HVIDEOINPUTDEVICENV; iAttribute: Integer; piValue: PInteger): Boolean; stdcall;
+ TwglReleaseVideoCaptureDeviceNV = function(hDc: HDC; hDevice: HVIDEOINPUTDEVICENV): Boolean; stdcall;
+
+ // WGL_NV_copy_image
+ TwglCopyImageSubDataNV = function(hSrcRc: HGLRC; srcName: GLuint; srcTarget: GLenum; srcLevel: GLint; srcX: GLint; srcY: GLint; srcZ: GLint; hDstRC: HGLRC; dstName: GLuint; dstTarget: GLenum; dstLevel: GLint; dstX: GLint; dstY: GLint; dstZ: GLint; width: GLsizei; height: GLsizei; depth: GLsizei): Boolean; stdcall;
+
+ // WGL_NV_DX_interop
+ TwglDXSetResourceShareHandleNV = function(dxObject : PGLVoid; hareHandle : Cardinal) : Boolean; stdcall;
+ TwglDXOpenDeviceNV = function(dxDevice : PGLVoid) : Cardinal; stdcall;
+ TwglDXCloseDeviceNV = function(hDevice : Cardinal) : Boolean; stdcall;
+ TwglDXRegisterObjectNV = function(hDevice : Cardinal; dxObject : PGLVoid; name : GLUInt; _type : TGLEnum; access : TGLenum) : Cardinal; stdcall;
+ TwglDXUnregisterObjectNV = function(hDevice : Cardinal; hObject : Cardinal) : Boolean; stdcall;
+ TwglDXObjectAccessNV = function(hObject : Cardinal; access : GLenum) : Boolean; stdcall;
+ TwglDXLockObjectsNV = function(hDevice : Cardinal; count : GLint; hObjects : PCardinal) : Boolean; stdcall;
+ TwglDXUnlockObjectsNV = function (hDevice : Cardinal; count : GLint; hObjects : PCardinal) : Boolean; stdcall;
+
+ // WGL_OML_sync_control
+ TwglGetSyncValuesOML = function(hdc: HDC; ust: PGLint64; msc: PGLint64; sbc: PGLint64): Boolean; stdcall;
+ TwglGetMscRateOML = function(hdc: HDC; numerator: PGLint; denominator: PGLint): Boolean; stdcall;
+ TwglSwapBuffersMscOML = function(hdc: HDC; target_msc: GLint64; divisor: GLint64; remainder: GLint64): GLint64; stdcall;
+ TwglSwapLayerBuffersMscOML = function(hdc: HDC; fuPlanes: GLint; target_msc: GLint64; divisor: GLint64; remainder: GLint64): GLint64; stdcall;
+ TwglWaitForMscOML = function(hdc: HDC; target_msc: GLint64; divisor: GLint64; remainder: GLint64; ust: PGLint64; msc: PGLint64; sbc: PGLint64): Boolean; stdcall;
+ TwglWaitForSbcOML = function(hdc: HDC; target_sbc: GLint64; ust: PGLint64; msc: PGLint64; sbc: PGLint64): Boolean; stdcall;
+
+ // WGL_3DL_stereo_control
+ TwglSetStereoEmitterState3DL = function(hDC: HDC; uState: UINT): Boolean; stdcall;
+
+ // WIN_draw_range_elements
+ TglDrawRangeElementsWIN = procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); stdcall;
+
+ // WIN_swap_hint
+ TglAddSwapHintRectWIN = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei); stdcall;
+{$ENDIF}
+
+{$IFDEF DGL_LINUX}
+ TglXChooseVisual = function(dpy: PDisplay; screen: GLint; attribList: PGLint): PXVisualInfo; cdecl;
+ TglXCopyContext = procedure(dpy: PDisplay; src: GLXContext; dst: GLXContext; mask: GLuint); cdecl;
+ TglXCreateContext = function(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: GLboolean): GLXContext; cdecl;
+ TglXCreateGLXPixmap = function(dpy: PDisplay; vis: PXVisualInfo; pixmap: Pixmap): GLXPixmap cdecl;
+ TglXDestroyContext = procedure(dpy: PDisplay; ctx: GLXContext); cdecl;
+ TglXDestroyGLXPixmap = procedure(dpy : PDisplay; pix: GLXPixmap); cdecl;
+ TglXGetConfig = function(dpy : PDisplay; vis: PXVisualInfo; attrib: GLint; value: PGLint): GLint; cdecl;
+ TglXGetCurrentContext = function: GLXContext cdecl;
+ TglXGetCurrentDrawable = function: GLXDrawable cdecl;
+ TglXIsDirect = function(dpy: PDisplay; ctx: GLXContext): glboolean; cdecl;
+ TglXMakeCurrent = function(dpy: PDisplay; drawable: GLXDrawable; ctx: GLXContext): GLboolean cdecl;
+ TglXQueryExtension = function(dpy: PDisplay; errorBase: PGLint; eventBase: PGLint): GLboolean; cdecl;
+ TglXQueryVersion = function(dpy: PDisplay; major: PGLint; minor: PGLint): GLboolean cdecl;
+ TglXSwapBuffers = procedure(dpy: PDisplay; drawable: GLXDrawable); cdecl;
+ TglXUseXFont = procedure(font: Font; first: GLint; count: GLint; listBase: GLint); cdecl;
+ TglXWaitGL = procedure; cdecl;
+ TglXWaitX = procedure; cdecl;
+
+ TglXGetClientString = function(dpy: PDisplay; name: GLint): PGLchar; cdecl;
+ TglXQueryServerString = function(dpy: PDisplay; screen: GLint; name: GLint): PGLchar; cdecl;
+ TglXQueryExtensionsString = function(dpy: PDisplay; screen: GLint): PGLchar; cdecl;
+
+ // GLX_VERSION_1_3
+ TglXGetFBConfigs = function(dpy: PDisplay; screen: GLint; nelements: PGLint): GLXFBConfig; cdecl;
+ TglXChooseFBConfig = function(dpy: PDisplay; screen: GLint; attrib_list: PGLint; nelements: PGLint): GLXFBConfig; cdecl;
+ TglXGetFBConfigAttrib = function(dpy: PDisplay; config: GLXFBConfig; attribute: GLint; value: PGLint): glint; cdecl;
+ TglXGetVisualFromFBConfig = function(dpy: PDisplay; config: GLXFBConfig) : PXVisualInfo; cdecl;
+ TglXCreateWindow = function(dpy: PDisplay; config: GLXFBConfig; win: Window; attrib_list: PGLint): GLXWindow; cdecl;
+ TglXDestroyWindow = procedure(dpy: PDisplay; win: GLXWindow); cdecl;
+ TglXCreatePixmap = function(dpy: PDisplay; config: GLXFBConfig; pixmap: Pixmap; attrib_list: PGLint): GLXPixmap; cdecl;
+
+ TglXDestroyPixmap = procedure(dpy: PDisplay; pixmap: GLXPixmap); cdecl;
+ TglXCreatePbuffer = function(dpy: PDisplay; config: GLXFBConfig; attrib_list: PGLint): GLXPbuffer; cdecl;
+ TglXDestroyPbuffer = procedure(dpy: PDisplay; pbuf: GLXPbuffer); cdecl;
+ TglXQueryDrawable = procedure(dpy: PDisplay; draw: GLXDrawable; attribute: GLint; value: PGLuint); cdecl;
+ TglXCreateNewContext = function(dpy: PDisplay; config: GLXFBConfig; render_type: GLint; share_list: GLXContext; direct: GLboolean): GLXContext cdecl;
+ TglXMakeContextCurrent = function(display: PDisplay; draw: GLXDrawable; read_: GLXDrawable; ctx: GLXContext): GLboolean; cdecl;
+ TglXGetCurrentReadDrawable = function: GLXDrawable; cdecl;
+ TglXGetCurreentDisplay = function: PDisplay;
+
+ TglXQueryContext = function(dpy: PDisplay; ctx: GLXContext; attribute: GLint; value: PGLint): GLint; cdecl;
+ TglXSelectEvent = procedure(dpy: PDisplay; draw: GLXDrawable; event_mask: GLuint); cdecl;
+ TglXGetSelectedEvent = procedure(dpy: PDisplay; draw: GLXDrawable; event_mask: PGLuint); cdecl;
+
+ // GLX_VERSION_1_4
+ TglXGetProcAddress = function(const name: PAnsiChar): pointer; cdecl;
+
+ // GLX_ARB_get_proc_address
+ TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
+
+ // GLX_ARB_create_context
+ TglXCreateContextAttribsARB = function(dpy: PDisplay; config: GLXFBConfig; share_context: GLXContext; direct: GLboolean; const attrib_list: PGLint): GLXContext; cdecl;
+
+ // GLX_EXT_import_context
+ TglXGetCurrentDisplayEXT = function: PDisplay; cdecl;
+ TglXQueryContextInfoEXT = function(dpy: PDisplay; context: GLXContext; attribute: GLint; value: PGLint): GLint; cdecl;
+ TglXGetContextIDEXT = function(const context: GLXContext): GLXContextID; cdecl;
+ TglXImportContextEXT = function(dpy: PDisplay; contextID: GLXContextID): GLXContext; cdecl;
+ TglXFreeContextEXT = procedure(dpy: PDisplay; context: GLXContext); cdecl;
+
+ // GLX_EXT_texture_from_pixmap
+ TglXBindTexImageEXT = procedure(dpy: PDisplay; drawable: GLXDrawable; buffer: GLint; const attrib_list: PGLint); cdecl;
+ TglXReleaseTexImageEXT = procedure(dpy: PDisplay; drawable: GLXDrawable; buffer: GLint); cdecl;
+
+ TglXSwapIntervalEXT = procedure (dpy : PDisplay; drawable : GLXDrawable; interval : GLint); cdecl;
+{$ENDIF}
+
+ // GL utility functions and procedures
+ TgluErrorString = function(errCode: GLEnum): PAnsiChar; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluGetString = function(name: GLEnum): PAnsiChar; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluOrtho2D = procedure(left, right, bottom, top: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluPerspective = procedure(fovy, aspect, zNear, zFar: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluPickMatrix = procedure(x, y, width, height: GLdouble; const viewport: TVector4i); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluLookAt = procedure(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluProject = function(objx, objy, objz: GLdouble; const modelMatrix: TGLMatrixd4; const projMatrix: TGLMatrixd4; const viewport: TVector4i; winx, winy, winz: PGLdouble): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluUnProject = function(winx, winy, winz: GLdouble; const modelMatrix: TGLMatrixd4; const projMatrix: TGLMatrixd4; const viewport: TVector4i; objx, objy, objz: PGLdouble): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluScaleImage = function(format: GLEnum; widthin, heightin: GLint; typein: GLEnum; datain: Pointer; widthout, heightout: GLint; typeout: GLEnum; const dataout: Pointer): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNewQuadric = function: PGLUquadric; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluDeleteQuadric = procedure(state: PGLUquadric); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluQuadricNormals = procedure(quadObject: PGLUquadric; normals: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluQuadricTexture = procedure(quadObject: PGLUquadric; textureCoords: GLboolean); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluQuadricOrientation = procedure(quadObject: PGLUquadric; orientation: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluQuadricDrawStyle = procedure(quadObject: PGLUquadric; drawStyle: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluCylinder = procedure(quadObject: PGLUquadric; baseRadius, topRadius, height: GLdouble; slices, stacks: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluDisk = procedure(quadObject: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluPartialDisk = procedure(quadObject: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint; startAngle, sweepAngle: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluSphere = procedure(quadObject: PGLUquadric; radius: GLdouble; slices, stacks: GLint); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluQuadricCallback = procedure(quadObject: PGLUquadric; which: GLEnum; fn: TGLUQuadricErrorProc); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNewTess = function: PGLUtesselator; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluDeleteTess = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessBeginPolygon = procedure(tess: PGLUtesselator; polygon_data: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessBeginContour = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessVertex = procedure(tess: PGLUtesselator; const coords: TGLArrayd3; data: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessEndContour = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessEndPolygon = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessProperty = procedure(tess: PGLUtesselator; which: GLEnum; value: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessNormal = procedure(tess: PGLUtesselator; x, y, z: GLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluTessCallback = procedure(tess: PGLUtesselator; which: GLEnum; fn: Pointer); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluGetTessProperty = procedure(tess: PGLUtesselator; which: GLEnum; value: PGLdouble); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNewNurbsRenderer = function: PGLUnurbs; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluDeleteNurbsRenderer = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBeginSurface = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBeginCurve = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluEndCurve = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluEndSurface = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBeginTrim = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluEndTrim = procedure(nobj: PGLUnurbs); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluPwlCurve = procedure(nobj: PGLUnurbs; count: GLint; points: PGLfloat; stride: GLint; atype: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNurbsCurve = procedure(nobj: PGLUnurbs; nknots: GLint; knot: PGLfloat; stride: GLint; ctlarray: PGLfloat; order: GLint; atype: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNurbsSurface = procedure(nobj: PGLUnurbs; sknot_count: GLint; sknot: PGLfloat; tknot_count: GLint; tknot: PGLfloat; s_stride, t_stride: GLint; ctlarray: PGLfloat; sorder, torder: GLint; atype: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluLoadSamplingMatrices = procedure(nobj: PGLUnurbs; const modelMatrix, projMatrix: TGLMatrixf4; const viewport: TVector4i); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNurbsProperty = procedure(nobj: PGLUnurbs; aproperty: GLEnum; value: GLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluGetNurbsProperty = procedure(nobj: PGLUnurbs; aproperty: GLEnum; value: PGLfloat); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNurbsCallback = procedure(nobj: PGLUnurbs; which: GLEnum; fn: TGLUNurbsErrorProc); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluBeginPolygon = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluNextContour = procedure(tess: PGLUtesselator; atype: GLEnum); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+ TgluEndPolygon = procedure(tess: PGLUtesselator); {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
+
+var
+ // GL_VERSION_1_0
+ glCullFace: TglCullFace;
+ glFrontFace: TglFrontFace;
+ glHint: TglHint;
+ glLineWidth: TglLineWidth;
+ glPointSize: TglPointSize;
+ glPolygonMode: TglPolygonMode;
+ glScissor: TglScissor;
+ glTexParameterf: TglTexParameterf;
+ glTexParameterfv: TglTexParameterfv;
+ glTexParameteri: TglTexParameteri;
+ glTexParameteriv: TglTexParameteriv;
+ glTexImage1D: TglTexImage1D;
+ glTexImage2D: TglTexImage2D;
+ glDrawBuffer: TglDrawBuffer;
+ glClear: TglClear;
+ glClearColor: TglClearColor;
+ glClearStencil: TglClearStencil;
+ glClearDepth: TglClearDepth;
+ glStencilMask: TglStencilMask;
+ glColorMask: TglColorMask;
+ glDepthMask: TglDepthMask;
+ glDisable: TglDisable;
+ glEnable: TglEnable;
+ glFinish: TglFinish;
+ glFlush: TglFlush;
+ glBlendFunc: TglBlendFunc;
+ glLogicOp: TglLogicOp;
+ glStencilFunc: TglStencilFunc;
+ glStencilOp: TglStencilOp;
+ glDepthFunc: TglDepthFunc;
+ glPixelStoref: TglPixelStoref;
+ glPixelStorei: TglPixelStorei;
+ glReadBuffer: TglReadBuffer;
+ glReadPixels: TglReadPixels;
+ glGetBooleanv: TglGetBooleanv;
+ glGetDoublev: TglGetDoublev;
+ glGetError: TglGetError;
+ glGetFloatv: TglGetFloatv;
+ glGetIntegerv: TglGetIntegerv;
+ glGetString: TglGetString;
+ glGetTexImage: TglGetTexImage;
+ glGetTexParameteriv: TglGetTexParameteriv;
+ glGetTexParameterfv: TglGetTexParameterfv;
+ glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
+ glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
+ glIsEnabled: TglIsEnabled;
+ glDepthRange: TglDepthRange;
+ glViewport: TglViewport;
+
+ // GL_VERSION_1_1
+ glDrawArrays: TglDrawArrays;
+ glDrawElements: TglDrawElements;
+ glGetPointerv: TglGetPointerv;
+ glPolygonOffset: TglPolygonOffset;
+ glCopyTexImage1D: TglCopyTexImage1D;
+ glCopyTexImage2D: TglCopyTexImage2D;
+ glCopyTexSubImage1D: TglCopyTexSubImage1D;
+ glCopyTexSubImage2D: TglCopyTexSubImage2D;
+ glTexSubImage1D: TglTexSubImage1D;
+ glTexSubImage2D: TglTexSubImage2D;
+ glBindTexture: TglBindTexture;
+ glDeleteTextures: TglDeleteTextures;
+ glGenTextures: TglGenTextures;
+{$ifdef DGL_DEPRECATED}
+ glAccum: TglAccum;
+ glAlphaFunc: TglAlphaFunc;
+ glAreTexturesResident: TglAreTexturesResident;
+ glArrayElement: TglArrayElement;
+ glBegin: TglBegin;
+ glBitmap: TglBitmap;
+ glCallList: TglCallList;
+ glCallLists: TglCallLists;
+ glClearAccum: TglClearAccum;
+ glClearIndex: TglClearIndex;
+ glClipPlane: TglClipPlane;
+ glColor3b: TglColor3b;
+ glColor3bv: TglColor3bv;
+ glColor3d: TglColor3d;
+ glColor3dv: TglColor3dv;
+ glColor3f: TglColor3f;
+ glColor3fv: TglColor3fv;
+ glColor3i: TglColor3i;
+ glColor3iv: TglColor3iv;
+ glColor3s: TglColor3s;
+ glColor3sv: TglColor3sv;
+ glColor3ub: TglColor3ub;
+ glColor3ubv: TglColor3ubv;
+ glColor3ui: TglColor3ui;
+ glColor3uiv: TglColor3uiv;
+ glColor3us: TglColor3us;
+ glColor3usv: TglColor3usv;
+ glColor4b: TglColor4b;
+ glColor4bv: TglColor4bv;
+ glColor4d: TglColor4d;
+ glColor4dv: TglColor4dv;
+ glColor4f: TglColor4f;
+ glColor4fv: TglColor4fv;
+ glColor4i: TglColor4i;
+ glColor4iv: TglColor4iv;
+ glColor4s: TglColor4s;
+ glColor4sv: TglColor4sv;
+ glColor4ub: TglColor4ub;
+ glColor4ubv: TglColor4ubv;
+ glColor4ui: TglColor4ui;
+ glColor4uiv: TglColor4uiv;
+ glColor4us: TglColor4us;
+ glColor4usv: TglColor4usv;
+ glColorMaterial: TglColorMaterial;
+ glColorPointer: TglColorPointer;
+ glCopyPixels: TglCopyPixels;
+ glDeleteLists: TglDeleteLists;
+ glDisableClientState: TglDisableClientState;
+ glDrawPixels: TglDrawPixels;
+ glEdgeFlag: TglEdgeFlag;
+ glEdgeFlagPointer: TglEdgeFlagPointer;
+ glEdgeFlagv: TglEdgeFlagv;
+ glEnableClientState: TglEnableClientState;
+ glEnd: TglEnd;
+ glEndList: TglEndList;
+ glEvalCoord1d: TglEvalCoord1d;
+ glEvalCoord1dv: TglEvalCoord1dv;
+ glEvalCoord1f: TglEvalCoord1f;
+ glEvalCoord1fv: TglEvalCoord1fv;
+ glEvalCoord2d: TglEvalCoord2d;
+ glEvalCoord2dv: TglEvalCoord2dv;
+ glEvalCoord2f: TglEvalCoord2f;
+ glEvalCoord2fv: TglEvalCoord2fv;
+ glEvalMesh1: TglEvalMesh1;
+ glEvalMesh2: TglEvalMesh2;
+ glEvalPoint1: TglEvalPoint1;
+ glEvalPoint2: TglEvalPoint2;
+ glFeedbackBuffer: TglFeedbackBuffer;
+ glFogf: TglFogf;
+ glFogfv: TglFogfv;
+ glFogi: TglFogi;
+ glFogiv: TglFogiv;
+ glFrustum: TglFrustum;
+ glGenLists: TglGenLists;
+ glGetClipPlane: TglGetClipPlane;
+ glGetLightfv: TglGetLightfv;
+ glGetLightiv: TglGetLightiv;
+ glGetMapdv: TglGetMapdv;
+ glGetMapfv: TglGetMapfv;
+ glGetMapiv: TglGetMapiv;
+ glGetMaterialfv: TglGetMaterialfv;
+ glGetMaterialiv: TglGetMaterialiv;
+ glGetPixelMapfv: TglGetPixelMapfv;
+ glGetPixelMapuiv: TglGetPixelMapuiv;
+ glGetPixelMapusv: TglGetPixelMapusv;
+ glGetPolygonStipple: TglGetPolygonStipple;
+ glGetTexEnvfv: TglGetTexEnvfv;
+ glGetTexEnviv: TglGetTexEnviv;
+ glGetTexGendv: TglGetTexGendv;
+ glGetTexGenfv: TglGetTexGenfv;
+ glGetTexGeniv: TglGetTexGeniv;
+ glIndexMask: TglIndexMask;
+ glIndexPointer: TglIndexPointer;
+ glIndexd: TglIndexd;
+ glIndexdv: TglIndexdv;
+ glIndexf: TglIndexf;
+ glIndexfv: TglIndexfv;
+ glIndexi: TglIndexi;
+ glIndexiv: TglIndexiv;
+ glIndexs: TglIndexs;
+ glIndexsv: TglIndexsv;
+ glIndexub: TglIndexub;
+ glIndexubv: TglIndexubv;
+ glInitNames: TglInitNames;
+ glInterleavedArrays: TglInterleavedArrays;
+ glIsList: TglIsList;
+ glIsTexture: TglIsTexture;
+ glLightModelf: TglLightModelf;
+ glLightModelfv: TglLightModelfv;
+ glLightModeli: TglLightModeli;
+ glLightModeliv: TglLightModeliv;
+ glLightf: TglLightf;
+ glLightfv: TglLightfv;
+ glLighti: TglLighti;
+ glLightiv: TglLightiv;
+ glLineStipple: TglLineStipple;
+ glListBase: TglListBase;
+ glLoadIdentity: TglLoadIdentity;
+ glLoadMatrixd: TglLoadMatrixd;
+ glLoadMatrixf: TglLoadMatrixf;
+ glLoadName: TglLoadName;
+ glMap1d: TglMap1d;
+ glMap1f: TglMap1f;
+ glMap2d: TglMap2d;
+ glMap2f: TglMap2f;
+ glMapGrid1d: TglMapGrid1d;
+ glMapGrid1f: TglMapGrid1f;
+ glMapGrid2d: TglMapGrid2d;
+ glMapGrid2f: TglMapGrid2f;
+ glMaterialf: TglMaterialf;
+ glMaterialfv: TglMaterialfv;
+ glMateriali: TglMateriali;
+ glMaterialiv: TglMaterialiv;
+ glMatrixMode: TglMatrixMode;
+ glMultMatrixd: TglMultMatrixd;
+ glMultMatrixf: TglMultMatrixf;
+ glNewList: TglNewList;
+ glNormal3b: TglNormal3b;
+ glNormal3bv: TglNormal3bv;
+ glNormal3d: TglNormal3d;
+ glNormal3dv: TglNormal3dv;
+ glNormal3f: TglNormal3f;
+ glNormal3fv: TglNormal3fv;
+ glNormal3i: TglNormal3i;
+ glNormal3iv: TglNormal3iv;
+ glNormal3s: TglNormal3s;
+ glNormal3sv: TglNormal3sv;
+ glNormalPointer: TglNormalPointer;
+ glOrtho: TglOrtho;
+ glPassThrough: TglPassThrough;
+ glPixelMapfv: TglPixelMapfv;
+ glPixelMapuiv: TglPixelMapuiv;
+ glPixelMapusv: TglPixelMapusv;
+ glPixelTransferf: TglPixelTransferf;
+ glPixelTransferi: TglPixelTransferi;
+ glPixelZoom: TglPixelZoom;
+ glPolygonStipple: TglPolygonStipple;
+ glPopAttrib: TglPopAttrib;
+ glPopClientAttrib: TglPopClientAttrib;
+ glPopMatrix: TglPopMatrix;
+ glPopName: TglPopName;
+ glPrioritizeTextures: TglPrioritizeTextures;
+ glPushAttrib: TglPushAttrib;
+ glPushClientAttrib: TglPushClientAttrib;
+ glPushMatrix: TglPushMatrix;
+ glPushName: TglPushName;
+ glRasterPos2d: TglRasterPos2d;
+ glRasterPos2dv: TglRasterPos2dv;
+ glRasterPos2f: TglRasterPos2f;
+ glRasterPos2fv: TglRasterPos2fv;
+ glRasterPos2i: TglRasterPos2i;
+ glRasterPos2iv: TglRasterPos2iv;
+ glRasterPos2s: TglRasterPos2s;
+ glRasterPos2sv: TglRasterPos2sv;
+ glRasterPos3d: TglRasterPos3d;
+ glRasterPos3dv: TglRasterPos3dv;
+ glRasterPos3f: TglRasterPos3f;
+ glRasterPos3fv: TglRasterPos3fv;
+ glRasterPos3i: TglRasterPos3i;
+ glRasterPos3iv: TglRasterPos3iv;
+ glRasterPos3s: TglRasterPos3s;
+ glRasterPos3sv: TglRasterPos3sv;
+ glRasterPos4d: TglRasterPos4d;
+ glRasterPos4dv: TglRasterPos4dv;
+ glRasterPos4f: TglRasterPos4f;
+ glRasterPos4fv: TglRasterPos4fv;
+ glRasterPos4i: TglRasterPos4i;
+ glRasterPos4iv: TglRasterPos4iv;
+ glRasterPos4s: TglRasterPos4s;
+ glRasterPos4sv: TglRasterPos4sv;
+ glRectd: TglRectd;
+ glRectdv: TglRectdv;
+ glRectf: TglRectf;
+ glRectfv: TglRectfv;
+ glRecti: TglRecti;
+ glRectiv: TglRectiv;
+ glRects: TglRects;
+ glRectsv: TglRectsv;
+ glRenderMode: TglRenderMode;
+ glRotated: TglRotated;
+ glRotatef: TglRotatef;
+ glScaled: TglScaled;
+ glScalef: TglScalef;
+ glSelectBuffer: TglSelectBuffer;
+ glShadeModel: TglShadeModel;
+ glTexCoord1d: TglTexCoord1d;
+ glTexCoord1dv: TglTexCoord1dv;
+ glTexCoord1f: TglTexCoord1f;
+ glTexCoord1fv: TglTexCoord1fv;
+ glTexCoord1i: TglTexCoord1i;
+ glTexCoord1iv: TglTexCoord1iv;
+ glTexCoord1s: TglTexCoord1s;
+ glTexCoord1sv: TglTexCoord1sv;
+ glTexCoord2d: TglTexCoord2d;
+ glTexCoord2dv: TglTexCoord2dv;
+ glTexCoord2f: TglTexCoord2f;
+ glTexCoord2fv: TglTexCoord2fv;
+ glTexCoord2i: TglTexCoord2i;
+ glTexCoord2iv: TglTexCoord2iv;
+ glTexCoord2s: TglTexCoord2s;
+ glTexCoord2sv: TglTexCoord2sv;
+ glTexCoord3d: TglTexCoord3d;
+ glTexCoord3dv: TglTexCoord3dv;
+ glTexCoord3f: TglTexCoord3f;
+ glTexCoord3fv: TglTexCoord3fv;
+ glTexCoord3i: TglTexCoord3i;
+ glTexCoord3iv: TglTexCoord3iv;
+ glTexCoord3s: TglTexCoord3s;
+ glTexCoord3sv: TglTexCoord3sv;
+ glTexCoord4d: TglTexCoord4d;
+ glTexCoord4dv: TglTexCoord4dv;
+ glTexCoord4f: TglTexCoord4f;
+ glTexCoord4fv: TglTexCoord4fv;
+ glTexCoord4i: TglTexCoord4i;
+ glTexCoord4iv: TglTexCoord4iv;
+ glTexCoord4s: TglTexCoord4s;
+ glTexCoord4sv: TglTexCoord4sv;
+ glTexCoordPointer: TglTexCoordPointer;
+ glTexEnvf: TglTexEnvf;
+ glTexEnvfv: TglTexEnvfv;
+ glTexEnvi: TglTexEnvi;
+ glTexEnviv: TglTexEnviv;
+ glTexGend: TglTexGend;
+ glTexGendv: TglTexGendv;
+ glTexGenf: TglTexGenf;
+ glTexGenfv: TglTexGenfv;
+ glTexGeni: TglTexGeni;
+ glTexGeniv: TglTexGeniv;
+ glTranslated: TglTranslated;
+ glTranslatef: TglTranslatef;
+ glVertex2d: TglVertex2d;
+ glVertex2dv: TglVertex2dv;
+ glVertex2f: TglVertex2f;
+ glVertex2fv: TglVertex2fv;
+ glVertex2i: TglVertex2i;
+ glVertex2iv: TglVertex2iv;
+ glVertex2s: TglVertex2s;
+ glVertex2sv: TglVertex2sv;
+ glVertex3d: TglVertex3d;
+ glVertex3dv: TglVertex3dv;
+ glVertex3f: TglVertex3f;
+ glVertex3fv: TglVertex3fv;
+ glVertex3i: TglVertex3i;
+ glVertex3iv: TglVertex3iv;
+ glVertex3s: TglVertex3s;
+ glVertex3sv: TglVertex3sv;
+ glVertex4d: TglVertex4d;
+ glVertex4dv: TglVertex4dv;
+ glVertex4f: TglVertex4f;
+ glVertex4fv: TglVertex4fv;
+ glVertex4i: TglVertex4i;
+ glVertex4iv: TglVertex4iv;
+ glVertex4s: TglVertex4s;
+ glVertex4sv: TglVertex4sv;
+ glVertexPointer: TglVertexPointer;
+{$endif}
+
+ // GL_VERSION_1_2
+ glBlendColor: TglBlendColor;
+ glBlendEquation: TglBlendEquation;
+ glDrawRangeElements: TglDrawRangeElements;
+ glTexImage3D: TglTexImage3D;
+ glTexSubImage3D: TglTexSubImage3D;
+ glCopyTexSubImage3D: TglCopyTexSubImage3D;
+{$ifdef DGL_DEPRECATED}
+ glColorTable: TglColorTable;
+ glColorTableParameterfv: TglColorTableParameterfv;
+ glColorTableParameteriv: TglColorTableParameteriv;
+ glCopyColorTable: TglCopyColorTable;
+ glGetColorTable: TglGetColorTable;
+ glGetColorTableParameterfv: TglGetColorTableParameterfv;
+ glGetColorTableParameteriv: TglGetColorTableParameteriv;
+ glColorSubTable: TglColorSubTable;
+ glCopyColorSubTable: TglCopyColorSubTable;
+ glConvolutionFilter1D: TglConvolutionFilter1D;
+ glConvolutionFilter2D: TglConvolutionFilter2D;
+ glConvolutionParameterf: TglConvolutionParameterf;
+ glConvolutionParameterfv: TglConvolutionParameterfv;
+ glConvolutionParameteri: TglConvolutionParameteri;
+ glConvolutionParameteriv: TglConvolutionParameteriv;
+ glCopyConvolutionFilter1D: TglCopyConvolutionFilter1D;
+ glCopyConvolutionFilter2D: TglCopyConvolutionFilter2D;
+ glGetConvolutionFilter: TglGetConvolutionFilter;
+ glGetConvolutionParameterfv: TglGetConvolutionParameterfv;
+ glGetConvolutionParameteriv: TglGetConvolutionParameteriv;
+ glGetSeparableFilter: TglGetSeparableFilter;
+ glSeparableFilter2D: TglSeparableFilter2D;
+ glGetHistogram: TglGetHistogram;
+ glGetHistogramParameterfv: TglGetHistogramParameterfv;
+ glGetHistogramParameteriv: TglGetHistogramParameteriv;
+ glGetMinmax: TglGetMinmax;
+ glGetMinmaxParameterfv: TglGetMinmaxParameterfv;
+ glGetMinmaxParameteriv: TglGetMinmaxParameteriv;
+ glHistogram: TglHistogram;
+ glMinmax: TglMinmax;
+ glResetHistogram: TglResetHistogram;
+ glResetMinmax: TglResetMinmax;
+{$endif}
+
+ // GL_VERSION_1_3
+ glActiveTexture: TglActiveTexture;
+ glSampleCoverage: TglSampleCoverage;
+ glCompressedTexImage3D: TglCompressedTexImage3D;
+ glCompressedTexImage2D: TglCompressedTexImage2D;
+ glCompressedTexImage1D: TglCompressedTexImage1D;
+ glCompressedTexSubImage3D: TglCompressedTexSubImage3D;
+ glCompressedTexSubImage2D: TglCompressedTexSubImage2D;
+ glCompressedTexSubImage1D: TglCompressedTexSubImage1D;
+ glGetCompressedTexImage: TglGetCompressedTexImage;
+{$ifdef DGL_DEPRECATED}
+ glClientActiveTexture: TglClientActiveTexture;
+ glMultiTexCoord1d: TglMultiTexCoord1d;
+ glMultiTexCoord1dv: TglMultiTexCoord1dv;
+ glMultiTexCoord1f: TglMultiTexCoord1f;
+ glMultiTexCoord1fv: TglMultiTexCoord1fv;
+ glMultiTexCoord1i: TglMultiTexCoord1i;
+ glMultiTexCoord1iv: TglMultiTexCoord1iv;
+ glMultiTexCoord1s: TglMultiTexCoord1s;
+ glMultiTexCoord1sv: TglMultiTexCoord1sv;
+ glMultiTexCoord2d: TglMultiTexCoord2d;
+ glMultiTexCoord2dv: TglMultiTexCoord2dv;
+ glMultiTexCoord2f: TglMultiTexCoord2f;
+ glMultiTexCoord2fv: TglMultiTexCoord2fv;
+ glMultiTexCoord2i: TglMultiTexCoord2i;
+ glMultiTexCoord2iv: TglMultiTexCoord2iv;
+ glMultiTexCoord2s: TglMultiTexCoord2s;
+ glMultiTexCoord2sv: TglMultiTexCoord2sv;
+ glMultiTexCoord3d: TglMultiTexCoord3d;
+ glMultiTexCoord3dv: TglMultiTexCoord3dv;
+ glMultiTexCoord3f: TglMultiTexCoord3f;
+ glMultiTexCoord3fv: TglMultiTexCoord3fv;
+ glMultiTexCoord3i: TglMultiTexCoord3i;
+ glMultiTexCoord3iv: TglMultiTexCoord3iv;
+ glMultiTexCoord3s: TglMultiTexCoord3s;
+ glMultiTexCoord3sv: TglMultiTexCoord3sv;
+ glMultiTexCoord4d: TglMultiTexCoord4d;
+ glMultiTexCoord4dv: TglMultiTexCoord4dv;
+ glMultiTexCoord4f: TglMultiTexCoord4f;
+ glMultiTexCoord4fv: TglMultiTexCoord4fv;
+ glMultiTexCoord4i: TglMultiTexCoord4i;
+ glMultiTexCoord4iv: TglMultiTexCoord4iv;
+ glMultiTexCoord4s: TglMultiTexCoord4s;
+ glMultiTexCoord4sv: TglMultiTexCoord4sv;
+ glLoadTransposeMatrixf: TglLoadTransposeMatrixf;
+ glLoadTransposeMatrixd: TglLoadTransposeMatrixd;
+ glMultTransposeMatrixf: TglMultTransposeMatrixf;
+ glMultTransposeMatrixd: TglMultTransposeMatrixd;
+{$endif}
+
+ // GL_VERSION_1_4
+ glBlendFuncSeparate: TglBlendFuncSeparate;
+ glMultiDrawArrays: TglMultiDrawArrays;
+ glMultiDrawElements: TglMultiDrawElements;
+ glPointParameterf: TglPointParameterf;
+ glPointParameterfv: TglPointParameterfv;
+ glPointParameteri: TglPointParameteri;
+ glPointParameteriv: TglPointParameteriv;
+{$ifdef DGL_DEPRECATED}
+ glFogCoordf: TglFogCoordf;
+ glFogCoordfv: TglFogCoordfv;
+ glFogCoordd: TglFogCoordd;
+ glFogCoorddv: TglFogCoorddv;
+ glFogCoordPointer: TglFogCoordPointer;
+ glSecondaryColor3b: TglSecondaryColor3b;
+ glSecondaryColor3bv: TglSecondaryColor3bv;
+ glSecondaryColor3d: TglSecondaryColor3d;
+ glSecondaryColor3dv: TglSecondaryColor3dv;
+ glSecondaryColor3f: TglSecondaryColor3f;
+ glSecondaryColor3fv: TglSecondaryColor3fv;
+ glSecondaryColor3i: TglSecondaryColor3i;
+ glSecondaryColor3iv: TglSecondaryColor3iv;
+ glSecondaryColor3s: TglSecondaryColor3s;
+ glSecondaryColor3sv: TglSecondaryColor3sv;
+ glSecondaryColor3ub: TglSecondaryColor3ub;
+ glSecondaryColor3ubv: TglSecondaryColor3ubv;
+ glSecondaryColor3ui: TglSecondaryColor3ui;
+ glSecondaryColor3uiv: TglSecondaryColor3uiv;
+ glSecondaryColor3us: TglSecondaryColor3us;
+ glSecondaryColor3usv: TglSecondaryColor3usv;
+ glSecondaryColorPointer: TglSecondaryColorPointer;
+ glWindowPos2d: TglWindowPos2d;
+ glWindowPos2dv: TglWindowPos2dv;
+ glWindowPos2f: TglWindowPos2f;
+ glWindowPos2fv: TglWindowPos2fv;
+ glWindowPos2i: TglWindowPos2i;
+ glWindowPos2iv: TglWindowPos2iv;
+ glWindowPos2s: TglWindowPos2s;
+ glWindowPos2sv: TglWindowPos2sv;
+ glWindowPos3d: TglWindowPos3d;
+ glWindowPos3dv: TglWindowPos3dv;
+ glWindowPos3f: TglWindowPos3f;
+ glWindowPos3fv: TglWindowPos3fv;
+ glWindowPos3i: TglWindowPos3i;
+ glWindowPos3iv: TglWindowPos3iv;
+ glWindowPos3s: TglWindowPos3s;
+ glWindowPos3sv: TglWindowPos3sv;
+{$endif}
+
+ // GL_VERSION_1_5
+ glGenQueries: TglGenQueries;
+ glDeleteQueries: TglDeleteQueries;
+ glIsQuery: TglIsQuery;
+ glBeginQuery: TglBeginQuery;
+ glEndQuery: TglEndQuery;
+ glGetQueryiv: TglGetQueryiv;
+ glGetQueryObjectiv: TglGetQueryObjectiv;
+ glGetQueryObjectuiv: TglGetQueryObjectuiv;
+ glBindBuffer: TglBindBuffer;
+ glDeleteBuffers: TglDeleteBuffers;
+ glGenBuffers: TglGenBuffers;
+ glIsBuffer: TglIsBuffer;
+ glBufferData: TglBufferData;
+ glBufferSubData: TglBufferSubData;
+ glGetBufferSubData: TglGetBufferSubData;
+ glMapBuffer: TglMapBuffer;
+ glUnmapBuffer: TglUnmapBuffer;
+ glGetBufferParameteriv: TglGetBufferParameteriv;
+ glGetBufferPointerv: TglGetBufferPointerv;
+
+ // GL_VERSION_2_0
+ glBlendEquationSeparate: TglBlendEquationSeparate;
+ glDrawBuffers: TglDrawBuffers;
+ glStencilOpSeparate: TglStencilOpSeparate;
+ glStencilFuncSeparate: TglStencilFuncSeparate;
+ glStencilMaskSeparate: TglStencilMaskSeparate;
+ glAttachShader: TglAttachShader;
+ glBindAttribLocation: TglBindAttribLocation;
+ glCompileShader: TglCompileShader;
+ glCreateProgram: TglCreateProgram;
+ glCreateShader: TglCreateShader;
+ glDeleteProgram: TglDeleteProgram;
+ glDeleteShader: TglDeleteShader;
+ glDetachShader: TglDetachShader;
+ glDisableVertexAttribArray: TglDisableVertexAttribArray;
+ glEnableVertexAttribArray: TglEnableVertexAttribArray;
+ glGetActiveAttrib: TglGetActiveAttrib;
+ glGetActiveUniform: TglGetActiveUniform;
+ glGetAttachedShaders: TglGetAttachedShaders;
+ glGetAttribLocation: TglGetAttribLocation;
+ glGetProgramiv: TglGetProgramiv;
+ glGetProgramInfoLog: TglGetProgramInfoLog;
+ glGetShaderiv: TglGetShaderiv;
+ glGetShaderInfoLog: TglGetShaderInfoLog;
+ glGetShaderSource: TglGetShaderSource;
+ glGetUniformLocation: TglGetUniformLocation;
+ glGetUniformfv: TglGetUniformfv;
+ glGetUniformiv: TglGetUniformiv;
+ glGetVertexAttribfv: TglGetVertexAttribfv;
+ glGetVertexAttribiv: TglGetVertexAttribiv;
+ glGetVertexAttribPointerv: TglGetVertexAttribPointerv;
+ glIsProgram: TglIsProgram;
+ glIsShader: TglIsShader;
+ glLinkProgram: TglLinkProgram;
+ glShaderSource: TglShaderSource;
+ glUseProgram: TglUseProgram;
+ glUniform1f: TglUniform1f;
+ glUniform2f: TglUniform2f;
+ glUniform3f: TglUniform3f;
+ glUniform4f: TglUniform4f;
+ glUniform1i: TglUniform1i;
+ glUniform2i: TglUniform2i;
+ glUniform3i: TglUniform3i;
+ glUniform4i: TglUniform4i;
+ glUniform1fv: TglUniform1fv;
+ glUniform2fv: TglUniform2fv;
+ glUniform3fv: TglUniform3fv;
+ glUniform4fv: TglUniform4fv;
+ glUniform1iv: TglUniform1iv;
+ glUniform2iv: TglUniform2iv;
+ glUniform3iv: TglUniform3iv;
+ glUniform4iv: TglUniform4iv;
+ glUniformMatrix2fv: TglUniformMatrix2fv;
+ glUniformMatrix3fv: TglUniformMatrix3fv;
+ glUniformMatrix4fv: TglUniformMatrix4fv;
+ glValidateProgram: TglValidateProgram;
+ glVertexAttrib1d: TglVertexAttrib1d;
+ glVertexAttrib1dv: TglVertexAttrib1dv;
+ glVertexAttrib1f: TglVertexAttrib1f;
+ glVertexAttrib1fv: TglVertexAttrib1fv;
+ glVertexAttrib1s: TglVertexAttrib1s;
+ glVertexAttrib1sv: TglVertexAttrib1sv;
+ glVertexAttrib2d: TglVertexAttrib2d;
+ glVertexAttrib2dv: TglVertexAttrib2dv;
+ glVertexAttrib2f: TglVertexAttrib2f;
+ glVertexAttrib2fv: TglVertexAttrib2fv;
+ glVertexAttrib2s: TglVertexAttrib2s;
+ glVertexAttrib2sv: TglVertexAttrib2sv;
+ glVertexAttrib3d: TglVertexAttrib3d;
+ glVertexAttrib3dv: TglVertexAttrib3dv;
+ glVertexAttrib3f: TglVertexAttrib3f;
+ glVertexAttrib3fv: TglVertexAttrib3fv;
+ glVertexAttrib3s: TglVertexAttrib3s;
+ glVertexAttrib3sv: TglVertexAttrib3sv;
+ glVertexAttrib4Nbv: TglVertexAttrib4Nbv;
+ glVertexAttrib4Niv: TglVertexAttrib4Niv;
+ glVertexAttrib4Nsv: TglVertexAttrib4Nsv;
+ glVertexAttrib4Nub: TglVertexAttrib4Nub;
+ glVertexAttrib4Nubv: TglVertexAttrib4Nubv;
+ glVertexAttrib4Nuiv: TglVertexAttrib4Nuiv;
+ glVertexAttrib4Nusv: TglVertexAttrib4Nusv;
+ glVertexAttrib4bv: TglVertexAttrib4bv;
+ glVertexAttrib4d: TglVertexAttrib4d;
+ glVertexAttrib4dv: TglVertexAttrib4dv;
+ glVertexAttrib4f: TglVertexAttrib4f;
+ glVertexAttrib4fv: TglVertexAttrib4fv;
+ glVertexAttrib4iv: TglVertexAttrib4iv;
+ glVertexAttrib4s: TglVertexAttrib4s;
+ glVertexAttrib4sv: TglVertexAttrib4sv;
+ glVertexAttrib4ubv: TglVertexAttrib4ubv;
+ glVertexAttrib4uiv: TglVertexAttrib4uiv;
+ glVertexAttrib4usv: TglVertexAttrib4usv;
+ glVertexAttribPointer: TglVertexAttribPointer;
+
+ // GL_VERSION_2_1
+ glUniformMatrix2x3fv: TglUniformMatrix2x3fv;
+ glUniformMatrix3x2fv: TglUniformMatrix3x2fv;
+ glUniformMatrix2x4fv: TglUniformMatrix2x4fv;
+ glUniformMatrix4x2fv: TglUniformMatrix4x2fv;
+ glUniformMatrix3x4fv: TglUniformMatrix3x4fv;
+ glUniformMatrix4x3fv: TglUniformMatrix4x3fv;
+
+ // GL_VERSION_3_0
+ glColorMaski: TglColorMaski;
+ glGetBooleani_v: TglGetBooleani_v;
+ glGetIntegeri_v: TglGetIntegeri_v;
+ glEnablei: TglEnablei;
+ glDisablei: TglDisablei;
+ glIsEnabledi: TglIsEnabledi;
+ glBeginTransformFeedback: TglBeginTransformFeedback;
+ glEndTransformFeedback: TglEndTransformFeedback;
+ glBindBufferRange: TglBindBufferRange;
+ glBindBufferBase: TglBindBufferBase;
+ glTransformFeedbackVaryings: TglTransformFeedbackVaryings;
+ glGetTransformFeedbackVarying: TglGetTransformFeedbackVarying;
+ glClampColor: TglClampColor;
+ glBeginConditionalRender: TglBeginConditionalRender;
+ glEndConditionalRender: TglEndConditionalRender;
+ glVertexAttribI1i: TglVertexAttribI1i;
+ glVertexAttribI2i: TglVertexAttribI2i;
+ glVertexAttribI3i: TglVertexAttribI3i;
+ glVertexAttribI4i: TglVertexAttribI4i;
+ glVertexAttribI1ui: TglVertexAttribI1ui;
+ glVertexAttribI2ui: TglVertexAttribI2ui;
+ glVertexAttribI3ui: TglVertexAttribI3ui;
+ glVertexAttribI4ui: TglVertexAttribI4ui;
+ glVertexAttribI1iv: TglVertexAttribI1iv;
+ glVertexAttribI2iv: TglVertexAttribI2iv;
+ glVertexAttribI3iv: TglVertexAttribI3iv;
+ glVertexAttribI4iv: TglVertexAttribI4iv;
+ glVertexAttribI1uiv: TglVertexAttribI1uiv;
+ glVertexAttribI2uiv: TglVertexAttribI2uiv;
+ glVertexAttribI3uiv: TglVertexAttribI3uiv;
+ glVertexAttribI4uiv: TglVertexAttribI4uiv;
+ glVertexAttribI4bv: TglVertexAttribI4bv;
+ glVertexAttribI4sv: TglVertexAttribI4sv;
+ glVertexAttribI4ubv: TglVertexAttribI4ubv;
+ glVertexAttribI4usv: TglVertexAttribI4usv;
+ glVertexAttribIPointer: TglVertexAttribIPointer;
+ glGetVertexAttribIiv: TglGetVertexAttribIiv;
+ glGetVertexAttribIuiv: TglGetVertexAttribIuiv;
+ glGetUniformuiv: TglGetUniformuiv;
+ glBindFragDataLocation: TglBindFragDataLocation;
+ glGetFragDataLocation: TglGetFragDataLocation;
+ glUniform1ui: TglUniform1ui;
+ glUniform2ui: TglUniform2ui;
+ glUniform3ui: TglUniform3ui;
+ glUniform4ui: TglUniform4ui;
+ glUniform1uiv: TglUniform1uiv;
+ glUniform2uiv: TglUniform2uiv;
+ glUniform3uiv: TglUniform3uiv;
+ glUniform4uiv: TglUniform4uiv;
+ glTexParameterIiv: TglTexParameterIiv;
+ glTexParameterIuiv: TglTexParameterIuiv;
+ glGetTexParameterIiv: TglGetTexParameterIiv;
+ glGetTexParameterIuiv: TglGetTexParameterIuiv;
+ glClearBufferiv: TglClearBufferiv;
+ glClearBufferuiv: TglClearBufferuiv;
+ glClearBufferfv: TglClearBufferfv;
+ glClearBufferfi: TglClearBufferfi;
+ glGetStringi: TglGetStringi;
+
+ // GL_VERSION_2_1
+ glEnableVertexArrayEXT : TglEnableVertexArrayEXT;
+ glEnableVertexArrayAttribEXT : TglEnableVertexArrayAttribEXT;
+ glVertexArrayVertexAttribOffsetEXT : TglVertexArrayVertexAttribOffsetEXT;
+
+ // GL_VERSION_3_1
+ glDrawArraysInstanced: TglDrawArraysInstanced;
+ glDrawElementsInstanced: TglDrawElementsInstanced;
+ glTexBuffer: TglTexBuffer;
+ glPrimitiveRestartIndex: TglPrimitiveRestartIndex;
+
+ // GL_VERSION_3_2
+ glGetInteger64i_v: TglGetInteger64i_v;
+ glGetBufferParameteri64v: TglGetBufferParameteri64v;
+ glFramebufferTexture: TglFramebufferTexture;
+
+ // GL_VERSION_3_3
+ glVertexAttribDivisor: TglVertexAttribDivisor;
+
+ // GL_VERSION_4_0
+ { OpenGL 4.0 also reuses entry points from these extensions: }
+ { ARB_texture_query_lod (no entry points) }
+ { ARB_draw_indirect }
+ { ARB_gpu_shader5 (no entry points) }
+ { ARB_gpu_shader_fp64 }
+ { ARB_shader_subroutine }
+ { ARB_tessellation_shader }
+ { ARB_texture_buffer_object_rgb32 (no entry points) }
+ { ARB_texture_cube_map_array (no entry points) }
+ { ARB_texture_gather (no entry points) }
+ { ARB_transform_feedback2 }
+ { ARB_transform_feedback3 }
+ glMinSampleShading: TglMinSampleShading;
+ glBlendEquationi: TglBlendEquationi;
+ glBlendEquationSeparatei: TglBlendEquationSeparatei;
+ glBlendFunci: TglBlendFunci;
+ glBlendFuncSeparatei: TglBlendFuncSeparatei;
+
+ // GL_3DFX_tbuffer
+ glTbufferMask3DFX: TglTbufferMask3DFX;
+
+ // GL_APPLE_element_array
+ glElementPointerAPPLE: TglElementPointerAPPLE;
+ glDrawElementArrayAPPLE: TglDrawElementArrayAPPLE;
+ glDrawRangeElementArrayAPPLE: TglDrawRangeElementArrayAPPLE;
+ glMultiDrawElementArrayAPPLE: TglMultiDrawElementArrayAPPLE;
+ glMultiDrawRangeElementArrayAPPLE: TglMultiDrawRangeElementArrayAPPLE;
+
+ // GL_APPLE_fence
+ glGenFencesAPPLE: TglGenFencesAPPLE;
+ glDeleteFencesAPPLE: TglDeleteFencesAPPLE;
+ glSetFenceAPPLE: TglSetFenceAPPLE;
+ glIsFenceAPPLE: TglIsFenceAPPLE;
+ glTestFenceAPPLE: TglTestFenceAPPLE;
+ glFinishFenceAPPLE: TglFinishFenceAPPLE;
+ glTestObjectAPPLE: TglTestObjectAPPLE;
+ glFinishObjectAPPLE: TglFinishObjectAPPLE;
+
+ // GL_APPLE_vertex_array_object
+ glBindVertexArrayAPPLE: TglBindVertexArrayAPPLE;
+ glDeleteVertexArraysAPPLE: TglDeleteVertexArraysAPPLE;
+ glGenVertexArraysAPPLE: TglGenVertexArraysAPPLE;
+ glIsVertexArrayAPPLE: TglIsVertexArrayAPPLE;
+
+ // GL_APPLE_vertex_array_range
+ glVertexArrayRangeAPPLE: TglVertexArrayRangeAPPLE;
+ glFlushVertexArrayRangeAPPLE: TglFlushVertexArrayRangeAPPLE;
+ glVertexArrayParameteriAPPLE: TglVertexArrayParameteriAPPLE;
+
+ // GL_APPLE_texture_range
+ glTextureRangeAPPLE: TglTextureRangeAPPLE;
+ glGetTexParameterPointervAPPLE: TglGetTexParameterPointervAPPLE;
+
+ // GL_APPLE_vertex_program_evaluators
+ glEnableVertexAttribAPPLE: TglEnableVertexAttribAPPLE;
+ glDisableVertexAttribAPPLE: TglDisableVertexAttribAPPLE;
+ glIsVertexAttribEnabledAPPLE: TglIsVertexAttribEnabledAPPLE;
+ glMapVertexAttrib1dAPPLE: TglMapVertexAttrib1dAPPLE;
+ glMapVertexAttrib1fAPPLE: TglMapVertexAttrib1fAPPLE;
+ glMapVertexAttrib2dAPPLE: TglMapVertexAttrib2dAPPLE;
+ glMapVertexAttrib2fAPPLE: TglMapVertexAttrib2fAPPLE;
+
+ // GL_APPLE_object_purgeable
+ glObjectPurgeableAPPLE: TglObjectPurgeableAPPLE;
+ glObjectUnpurgeableAPPLE: TglObjectUnpurgeableAPPLE;
+ glGetObjectParameterivAPPLE: TglGetObjectParameterivAPPLE;
+
+ // GL_ARB_matrix_palette
+ glCurrentPaletteMatrixARB: TglCurrentPaletteMatrixARB;
+ glMatrixIndexubvARB: TglMatrixIndexubvARB;
+ glMatrixIndexusvARB: TglMatrixIndexusvARB;
+ glMatrixIndexuivARB: TglMatrixIndexuivARB;
+ glMatrixIndexPointerARB: TglMatrixIndexPointerARB;
+
+ // GL_ARB_multisample
+ glSampleCoverageARB: TglSampleCoverageARB;
+
+ // GL_ARB_multitexture
+ glActiveTextureARB: TglActiveTextureARB;
+ glClientActiveTextureARB: TglClientActiveTextureARB;
+ glMultiTexCoord1dARB: TglMultiTexCoord1dARB;
+ glMultiTexCoord1dvARB: TglMultiTexCoord1dvARB;
+ glMultiTexCoord1fARB: TglMultiTexCoord1fARB;
+ glMultiTexCoord1fvARB: TglMultiTexCoord1fvARB;
+ glMultiTexCoord1iARB: TglMultiTexCoord1iARB;
+ glMultiTexCoord1ivARB: TglMultiTexCoord1ivARB;
+ glMultiTexCoord1sARB: TglMultiTexCoord1sARB;
+ glMultiTexCoord1svARB: TglMultiTexCoord1svARB;
+ glMultiTexCoord2dARB: TglMultiTexCoord2dARB;
+ glMultiTexCoord2dvARB: TglMultiTexCoord2dvARB;
+ glMultiTexCoord2fARB: TglMultiTexCoord2fARB;
+ glMultiTexCoord2fvARB: TglMultiTexCoord2fvARB;
+ glMultiTexCoord2iARB: TglMultiTexCoord2iARB;
+ glMultiTexCoord2ivARB: TglMultiTexCoord2ivARB;
+ glMultiTexCoord2sARB: TglMultiTexCoord2sARB;
+ glMultiTexCoord2svARB: TglMultiTexCoord2svARB;
+ glMultiTexCoord3dARB: TglMultiTexCoord3dARB;
+ glMultiTexCoord3dvARB: TglMultiTexCoord3dvARB;
+ glMultiTexCoord3fARB: TglMultiTexCoord3fARB;
+ glMultiTexCoord3fvARB: TglMultiTexCoord3fvARB;
+ glMultiTexCoord3iARB: TglMultiTexCoord3iARB;
+ glMultiTexCoord3ivARB: TglMultiTexCoord3ivARB;
+ glMultiTexCoord3sARB: TglMultiTexCoord3sARB;
+ glMultiTexCoord3svARB: TglMultiTexCoord3svARB;
+ glMultiTexCoord4dARB: TglMultiTexCoord4dARB;
+ glMultiTexCoord4dvARB: TglMultiTexCoord4dvARB;
+ glMultiTexCoord4fARB: TglMultiTexCoord4fARB;
+ glMultiTexCoord4fvARB: TglMultiTexCoord4fvARB;
+ glMultiTexCoord4iARB: TglMultiTexCoord4iARB;
+ glMultiTexCoord4ivARB: TglMultiTexCoord4ivARB;
+ glMultiTexCoord4sARB: TglMultiTexCoord4sARB;
+ glMultiTexCoord4svARB: TglMultiTexCoord4svARB;
+
+ // GL_ARB_point_parameters
+ glPointParameterfARB: TglPointParameterfARB;
+ glPointParameterfvARB: TglPointParameterfvARB;
+
+ // GL_ARB_texture_compression
+ glCompressedTexImage3DARB: TglCompressedTexImage3DARB;
+ glCompressedTexImage2DARB: TglCompressedTexImage2DARB;
+ glCompressedTexImage1DARB: TglCompressedTexImage1DARB;
+ glCompressedTexSubImage3DARB: TglCompressedTexSubImage3DARB;
+ glCompressedTexSubImage2DARB: TglCompressedTexSubImage2DARB;
+ glCompressedTexSubImage1DARB: TglCompressedTexSubImage1DARB;
+ glGetCompressedTexImageARB: TglGetCompressedTexImageARB;
+
+ // GL_ARB_transpose_matrix
+ glLoadTransposeMatrixfARB: TglLoadTransposeMatrixfARB;
+ glLoadTransposeMatrixdARB: TglLoadTransposeMatrixdARB;
+ glMultTransposeMatrixfARB: TglMultTransposeMatrixfARB;
+ glMultTransposeMatrixdARB: TglMultTransposeMatrixdARB;
+
+ // GL_ARB_vertex_blend
+ glWeightbvARB: TglWeightbvARB;
+ glWeightsvARB: TglWeightsvARB;
+ glWeightivARB: TglWeightivARB;
+ glWeightfvARB: TglWeightfvARB;
+ glWeightdvARB: TglWeightdvARB;
+ glWeightubvARB: TglWeightubvARB;
+ glWeightusvARB: TglWeightusvARB;
+ glWeightuivARB: TglWeightuivARB;
+ glWeightPointerARB: TglWeightPointerARB;
+ glVertexBlendARB: TglVertexBlendARB;
+
+ // GL_ARB_vertex_buffer_object
+ glBindBufferARB: TglBindBufferARB;
+ glDeleteBuffersARB: TglDeleteBuffersARB;
+ glGenBuffersARB: TglGenBuffersARB;
+ glIsBufferARB: TglIsBufferARB;
+ glBufferDataARB: TglBufferDataARB;
+ glBufferSubDataARB: TglBufferSubData;
+ glGetBufferSubDataARB: TglGetBufferSubDataARB;
+ glMapBufferARB: TglMapBufferARB;
+ glUnmapBufferARB: TglUnmapBufferARB;
+ glGetBufferParameterivARB: TglGetBufferParameterivARB;
+ glGetBufferPointervARB: TglGetBufferPointervARB;
+
+ // GL_ARB_vertex_program
+ glVertexAttrib1dARB: TglVertexAttrib1dARB;
+ glVertexAttrib1dvARB: TglVertexAttrib1dvARB;
+ glVertexAttrib1fARB: TglVertexAttrib1fARB;
+ glVertexAttrib1fvARB: TglVertexAttrib1fvARB;
+ glVertexAttrib1sARB: TglVertexAttrib1sARB;
+ glVertexAttrib1svARB: TglVertexAttrib1svARB;
+ glVertexAttrib2dARB: TglVertexAttrib2dARB;
+ glVertexAttrib2dvARB: TglVertexAttrib2dvARB;
+ glVertexAttrib2fARB: TglVertexAttrib2fARB;
+ glVertexAttrib2fvARB: TglVertexAttrib2fvARB;
+ glVertexAttrib2sARB: TglVertexAttrib2sARB;
+ glVertexAttrib2svARB: TglVertexAttrib2svARB;
+ glVertexAttrib3dARB: TglVertexAttrib3dARB;
+ glVertexAttrib3dvARB: TglVertexAttrib3dvARB;
+ glVertexAttrib3fARB: TglVertexAttrib3fARB;
+ glVertexAttrib3fvARB: TglVertexAttrib3fvARB;
+ glVertexAttrib3sARB: TglVertexAttrib3sARB;
+ glVertexAttrib3svARB: TglVertexAttrib3svARB;
+ glVertexAttrib4NbvARB: TglVertexAttrib4NbvARB;
+ glVertexAttrib4NivARB: TglVertexAttrib4NivARB;
+ glVertexAttrib4NsvARB: TglVertexAttrib4NsvARB;
+ glVertexAttrib4NubARB: TglVertexAttrib4NubARB;
+ glVertexAttrib4NubvARB: TglVertexAttrib4NubvARB;
+ glVertexAttrib4NuivARB: TglVertexAttrib4NuivARB;
+ glVertexAttrib4NusvARB: TglVertexAttrib4NusvARB;
+ glVertexAttrib4bvARB: TglVertexAttrib4bvARB;
+ glVertexAttrib4dARB: TglVertexAttrib4dARB;
+ glVertexAttrib4dvARB: TglVertexAttrib4dvARB;
+ glVertexAttrib4fARB: TglVertexAttrib4fARB;
+ glVertexAttrib4fvARB: TglVertexAttrib4fvARB;
+ glVertexAttrib4ivARB: TglVertexAttrib4ivARB;
+ glVertexAttrib4sARB: TglVertexAttrib4sARB;
+ glVertexAttrib4svARB: TglVertexAttrib4svARB;
+ glVertexAttrib4ubvARB: TglVertexAttrib4ubvARB;
+ glVertexAttrib4uivARB: TglVertexAttrib4uivARB;
+ glVertexAttrib4usvARB: TglVertexAttrib4usvARB;
+ glVertexAttribPointerARB: TglVertexAttribPointerARB;
+ glEnableVertexAttribArrayARB: TglEnableVertexAttribArrayARB;
+ glDisableVertexAttribArrayARB: TglDisableVertexAttribArrayARB;
+ glProgramStringARB: TglProgramStringARB;
+ glBindProgramARB: TglBindProgramARB;
+ glDeleteProgramsARB: TglDeleteProgramsARB;
+ glGenProgramsARB: TglGenProgramsARB;
+
+ glProgramEnvParameter4dARB: TglProgramEnvParameter4dARB;
+ glProgramEnvParameter4dvARB: TglProgramEnvParameter4dvARB;
+ glProgramEnvParameter4fARB: TglProgramEnvParameter4fARB;
+ glProgramEnvParameter4fvARB: TglProgramEnvParameter4fvARB;
+ glProgramLocalParameter4dARB: TglProgramLocalParameter4dARB;
+ glProgramLocalParameter4dvARB: TglProgramLocalParameter4dvARB;
+ glProgramLocalParameter4fARB: TglProgramLocalParameter4fARB;
+ glProgramLocalParameter4fvARB: TglProgramLocalParameter4fvARB;
+ glGetProgramEnvParameterdvARB: TglGetProgramEnvParameterdvARB;
+ glGetProgramEnvParameterfvARB: TglGetProgramEnvParameterfvARB;
+ glGetProgramLocalParameterdvARB: TglGetProgramLocalParameterdvARB;
+ glGetProgramLocalParameterfvARB: TglGetProgramLocalParameterfvARB;
+ glGetProgramivARB: TglGetProgramivARB;
+ glGetProgramStringARB: TglGetProgramStringARB;
+ glGetVertexAttribdvARB: TglGetVertexAttribdvARB;
+ glGetVertexAttribfvARB: TglGetVertexAttribfvARB;
+ glGetVertexAttribivARB: TglGetVertexAttribivARB;
+ glGetVertexAttribPointervARB: TglGetVertexAttribPointervARB;
+ glIsProgramARB: TglIsProgramARB;
+
+ // GL_ARB_window_pos
+ glWindowPos2dARB: TglWindowPos2dARB;
+ glWindowPos2dvARB: TglWindowPos2dvARB;
+ glWindowPos2fARB: TglWindowPos2fARB;
+ glWindowPos2fvARB: TglWindowPos2fvARB;
+ glWindowPos2iARB: TglWindowPos2iARB;
+ glWindowPos2ivARB: TglWindowPos2ivARB;
+ glWindowPos2sARB: TglWindowPos2sARB;
+ glWindowPos2svARB: TglWindowPos2svARB;
+ glWindowPos3dARB: TglWindowPos3dARB;
+ glWindowPos3dvARB: TglWindowPos3dvARB;
+ glWindowPos3fARB: TglWindowPos3fARB;
+ glWindowPos3fvARB: TglWindowPos3fvARB;
+ glWindowPos3iARB: TglWindowPos3iARB;
+ glWindowPos3ivARB: TglWindowPos3ivARB;
+ glWindowPos3sARB: TglWindowPos3sARB;
+ glWindowPos3svARB: TglWindowPos3svARB;
+
+ // GL_ARB_draw_buffers
+ glDrawBuffersARB: TglDrawBuffersARB;
+
+ // GL_ARB_color_buffer_float
+ glClampColorARB: TglClampColorARB;
+
+ // GL_ARB_vertex_shader
+ glGetActiveAttribARB: TglGetActiveAttribARB;
+ glGetAttribLocationARB: TglGetAttribLocationARB;
+ glBindAttribLocationARB: TglBindAttribLocationARB;
+
+ // GL_ARB_shader_objects
+ glDeleteObjectARB: TglDeleteObjectARB;
+ glGetHandleARB: TglGetHandleARB;
+ glDetachObjectARB: TglDetachObjectARB;
+ glCreateShaderObjectARB: TglCreateShaderObjectARB;
+ glShaderSourceARB: TglShaderSourceARB;
+ glCompileShaderARB: TglCompileShaderARB;
+ glCreateProgramObjectARB: TglCreateProgramObjectARB;
+ glAttachObjectARB: TglAttachObjectARB;
+ glLinkProgramARB: TglLinkProgramARB;
+ glUseProgramObjectARB: TglUseProgramObjectARB;
+ glValidateProgramARB: TglValidateProgramARB;
+ glUniform1fARB: TglUniform1fARB;
+ glUniform2fARB: TglUniform2fARB;
+ glUniform3fARB: TglUniform3fARB;
+ glUniform4fARB: TglUniform4fARB;
+ glUniform1iARB: TglUniform1iARB;
+ glUniform2iARB: TglUniform2iARB;
+ glUniform3iARB: TglUniform3iARB;
+ glUniform4iARB: TglUniform4iARB;
+ glUniform1fvARB: TglUniform1fvARB;
+ glUniform2fvARB: TglUniform2fvARB;
+ glUniform3fvARB: TglUniform3fvARB;
+ glUniform4fvARB: TglUniform4fvARB;
+ glUniform1ivARB: TglUniform1ivARB;
+ glUniform2ivARB: TglUniform2ivARB;
+ glUniform3ivARB: TglUniform3ivARB;
+ glUniform4ivARB: TglUniform4ivARB;
+ glUniformMatrix2fvARB: TglUniformMatrix2fvARB;
+ glUniformMatrix3fvARB: TglUniformMatrix3fvARB;
+ glUniformMatrix4fvARB: TglUniformMatrix4fvARB;
+ glGetObjectParameterfvARB: TglGetObjectParameterfvARB;
+ glGetObjectParameterivARB: TglGetObjectParameterivARB;
+ glGetInfoLogARB: TglGetInfoLogARB;
+ glGetAttachedObjectsARB: TglGetAttachedObjectsARB;
+ glGetUniformLocationARB: TglGetUniformLocationARB;
+ glGetActiveUniformARB: TglGetActiveUniformARB;
+ glGetUniformfvARB: TglGetUniformfvARB;
+ glGetUniformivARB: TglGetUniformivARB;
+ glGetShaderSourceARB: TglGetShaderSourceARB;
+
+ // GL_ARB_Occlusion_Query
+ glGenQueriesARB: TglGenQueriesARB;
+ glDeleteQueriesARB: TglDeleteQueriesARB;
+ glIsQueryARB: TglIsQueryARB;
+ glBeginQueryARB: TglBeginQueryARB;
+ glEndQueryARB: TglEndQueryARB;
+ glGetQueryivARB: TglGetQueryivARB;
+ glGetQueryObjectivARB: TglGetQueryObjectivARB;
+ glGetQueryObjectuivARB: TglGetQueryObjectuivARB;
+
+ // GL_ARB_draw_instanced
+ glDrawArraysInstancedARB: TglDrawArraysInstancedARB;
+ glDrawElementsInstancedARB: TglDrawElementsInstancedARB;
+
+ // GL_ARB_framebuffer_object
+ glIsRenderbuffer: TglIsRenderbuffer;
+ glBindRenderbuffer: TglBindRenderbuffer;
+ glDeleteRenderbuffers: TglDeleteRenderbuffers;
+ glGenRenderbuffers: TglGenRenderbuffers;
+ glRenderbufferStorage: TglRenderbufferStorage;
+ glGetRenderbufferParameteriv: TglGetRenderbufferParameteriv;
+ glIsFramebuffer: TglIsFramebuffer;
+ glBindFramebuffer: TglBindFramebuffer;
+ glDeleteFramebuffers: TglDeleteFramebuffers;
+ glGenFramebuffers: TglGenFramebuffers;
+ glCheckFramebufferStatus: TglCheckFramebufferStatus;
+ glFramebufferTexture1D: TglFramebufferTexture1D;
+ glFramebufferTexture2D: TglFramebufferTexture2D;
+ glFramebufferTexture3D: TglFramebufferTexture3D;
+ glFramebufferRenderbuffer: TglFramebufferRenderbuffer;
+ glGetFramebufferAttachmentParameteriv: TglGetFramebufferAttachmentParameteriv;
+ glGenerateMipmap: TglGenerateMipmap;
+ glBlitFramebuffer: TglBlitFramebuffer;
+ glRenderbufferStorageMultisample: TglRenderbufferStorageMultisample;
+ glFramebufferTextureLayer: TglFramebufferTextureLayer;
+
+ // GL_ARB_geometry_shader4
+ glProgramParameteriARB: TglProgramParameteriARB;
+ glFramebufferTextureARB: TglFramebufferTextureARB;
+ glFramebufferTextureLayerARB: TglFramebufferTextureLayerARB;
+ glFramebufferTextureFaceARB: TglFramebufferTextureFaceARB;
+
+ // GL_ARB_gl_spirv
+ glSpecializeShaderARB: TglSpecializeShaderARB;
+
+ // GL_ARB_instanced_arrays
+ glVertexAttribDivisorARB: TglVertexAttribDivisorARB;
+
+ // GL_ARB_map_buffer_range
+ glMapBufferRange: TglMapBufferRange;
+ glFlushMappedBufferRange: TglFlushMappedBufferRange;
+
+ // GL_ARB_texture_buffer_object
+ glTexBufferARB: TglTexBufferARB;
+
+ // GL_ARB_vertex_array_object
+ glBindVertexArray: TglBindVertexArray;
+ glDeleteVertexArrays: TglDeleteVertexArrays;
+ glGenVertexArrays: TglGenVertexArrays;
+ glIsVertexArray: TglIsVertexArray;
+
+ // GL_ARB_uniform_buffer_object
+ glGetUniformIndices: TglGetUniformIndices;
+ glGetActiveUniformsiv: TglGetActiveUniformsiv;
+ glGetActiveUniformName: TglGetActiveUniformName;
+ glGetUniformBlockIndex: TglGetUniformBlockIndex;
+ glGetActiveUniformBlockiv: TglGetActiveUniformBlockiv;
+ glGetActiveUniformBlockName: TglGetActiveUniformBlockName;
+ glUniformBlockBinding: TglUniformBlockBinding;
+
+ // GL_ARB_copy_buffer
+ glCopyBufferSubData: TglCopyBufferSubData;
+
+ // GL_ARB_draw_elements_base_vertex
+ glDrawElementsBaseVertex: TglDrawElementsBaseVertex;
+ glDrawRangeElementsBaseVertex: TglDrawRangeElementsBaseVertex;
+ glDrawElementsInstancedBaseVertex: TglDrawElementsInstancedBaseVertex;
+ glMultiDrawElementsBaseVertex: TglMultiDrawElementsBaseVertex;
+
+ // GL_ARB_provoking_vertex
+ glProvokingVertex: TglProvokingVertex;
+
+ // GL_ARB_sync
+ glFenceSync: TglFenceSync;
+ glIsSync: TglIsSync;
+ glDeleteSync: TglDeleteSync;
+ glClientWaitSync: TglClientWaitSync;
+ glWaitSync: TglWaitSync;
+ glGetInteger64v: TglGetInteger64v;
+ glGetSynciv: TglGetSynciv;
+
+ // GL_ARB_texture_multisample
+ glTexImage2DMultisample: TglTexImage2DMultisample;
+ glTexImage3DMultisample: TglTexImage3DMultisample;
+ glGetMultisamplefv: TglGetMultisamplefv;
+ glSampleMaski: TglSampleMaski;
+
+ // GL_ARB_draw_buffers_blend
+ glBlendEquationiARB: TglBlendEquationiARB;
+ glBlendEquationSeparateiARB: TglBlendEquationSeparateiARB;
+ glBlendFunciARB: TglBlendFunciARB;
+ glBlendFuncSeparateiARB: TglBlendFuncSeparateiARB;
+
+ // GL_ARB_sample_shading
+ glMinSampleShadingARB: TglMinSampleShadingARB;
+
+ // GL_ARB_sample_locations
+ glFramebufferSampleLocationsfvARB : TglFramebufferSampleLocationsfvARB;
+ glNamedFramebufferSampleLocationsfvARB : TglNamedFramebufferSampleLocationsfvARB;
+ glEvaluateDepthValuesARB : TglEvaluateDepthValuesARB;
+
+ // GL_ARB_shading_language_include
+ glNamedStringARB: TglNamedStringARB;
+ glDeleteNamedStringARB: TglDeleteNamedStringARB;
+ glCompileShaderIncludeARB: TglCompileShaderIncludeARB;
+ glIsNamedStringARB: TglIsNamedStringARB;
+ glGetNamedStringARB: TglGetNamedStringARB;
+ glGetNamedStringivARB: TglGetNamedStringivARB;
+
+ // GL_ARB_blend_func_extended
+ glBindFragDataLocationIndexed: TglBindFragDataLocationIndexed;
+ glGetFragDataIndex: TglGetFragDataIndex;
+
+ // GL_ARB_sampler_objects
+ glGenSamplers: TglGenSamplers;
+ glDeleteSamplers: TglDeleteSamplers;
+ glIsSampler: TglIsSampler;
+ glBindSampler: TglBindSampler;
+ glSamplerParameteri: TglSamplerParameteri;
+ glSamplerParameteriv: TglSamplerParameteriv;
+ glSamplerParameterf: TglSamplerParameterf;
+ glSamplerParameterfv: TglSamplerParameterfv;
+ glSamplerParameterIiv: TglSamplerParameterIiv;
+ glSamplerParameterIuiv: TglSamplerParameterIuiv;
+ glGetSamplerParameteriv: TglGetSamplerParameteriv;
+ glGetSamplerParameterIiv: TglGetSamplerParameterIiv;
+ glGetSamplerParameterfv: TglGetSamplerParameterfv;
+ glGetSamplerParameterIuiv: TglGetSamplerParameterIuiv;
+
+ // GL_ARB_timer_query
+ glQueryCounter: TglQueryCounter;
+ glGetQueryObjecti64v: TglGetQueryObjecti64v;
+ glGetQueryObjectui64v: TglGetQueryObjectui64v;
+
+ // GL_ARB_vertex_type_2_10_10_10_rev
+ glVertexP2ui: TglVertexP2ui;
+ glVertexP2uiv: TglVertexP2uiv;
+ glVertexP3ui: TglVertexP3ui;
+ glVertexP3uiv: TglVertexP3uiv;
+ glVertexP4ui: TglVertexP4ui;
+ glVertexP4uiv: TglVertexP4uiv;
+ glTexCoordP1ui: TglTexCoordP1ui;
+ glTexCoordP1uiv: TglTexCoordP1uiv;
+ glTexCoordP2ui: TglTexCoordP2ui;
+ glTexCoordP2uiv: TglTexCoordP2uiv;
+ glTexCoordP3ui: TglTexCoordP3ui;
+ glTexCoordP3uiv: TglTexCoordP3uiv;
+ glTexCoordP4ui: TglTexCoordP4ui;
+ glTexCoordP4uiv: TglTexCoordP4uiv;
+ glMultiTexCoordP1ui: TglMultiTexCoordP1ui;
+ glMultiTexCoordP1uiv: TglMultiTexCoordP1uiv;
+ glMultiTexCoordP2ui: TglMultiTexCoordP2ui;
+ glMultiTexCoordP2uiv: TglMultiTexCoordP2uiv;
+ glMultiTexCoordP3ui: TglMultiTexCoordP3ui;
+ glMultiTexCoordP3uiv: TglMultiTexCoordP3uiv;
+ glMultiTexCoordP4ui: TglMultiTexCoordP4ui;
+ glMultiTexCoordP4uiv: TglMultiTexCoordP4uiv;
+ glNormalP3ui: TglNormalP3ui;
+ glNormalP3uiv: TglNormalP3uiv;
+ glColorP3ui: TglColorP3ui;
+ glColorP3uiv: TglColorP3uiv;
+ glColorP4ui: TglColorP4ui;
+ glColorP4uiv: TglColorP4uiv;
+ glSecondaryColorP3ui: TglSecondaryColorP3ui;
+ glSecondaryColorP3uiv: TglSecondaryColorP3uiv;
+ glVertexAttribP1ui: TglVertexAttribP1ui;
+ glVertexAttribP1uiv: TglVertexAttribP1uiv;
+ glVertexAttribP2ui: TglVertexAttribP2ui;
+ glVertexAttribP2uiv: TglVertexAttribP2uiv;
+ glVertexAttribP3ui: TglVertexAttribP3ui;
+ glVertexAttribP3uiv: TglVertexAttribP3uiv;
+ glVertexAttribP4ui: TglVertexAttribP4ui;
+ glVertexAttribP4uiv: TglVertexAttribP4uiv;
+
+ // GL_ARB_draw_indirect
+ glDrawArraysIndirect: TglDrawArraysIndirect;
+ glDrawElementsIndirect: TglDrawElementsIndirect;
+
+ // GL_ARB_gpu_shader_fp64
+ glUniform1d: TglUniform1d;
+ glUniform2d: TglUniform2d;
+ glUniform3d: TglUniform3d;
+ glUniform4d: TglUniform4d;
+ glUniform1dv: TglUniform1dv;
+ glUniform2dv: TglUniform2dv;
+ glUniform3dv: TglUniform3dv;
+ glUniform4dv: TglUniform4dv;
+ glUniformMatrix2dv: TglUniformMatrix2dv;
+ glUniformMatrix3dv: TglUniformMatrix3dv;
+ glUniformMatrix4dv: TglUniformMatrix4dv;
+ glUniformMatrix2x3dv: TglUniformMatrix2x3dv;
+ glUniformMatrix2x4dv: TglUniformMatrix2x4dv;
+ glUniformMatrix3x2dv: TglUniformMatrix3x2dv;
+ glUniformMatrix3x4dv: TglUniformMatrix3x4dv;
+ glUniformMatrix4x2dv: TglUniformMatrix4x2dv;
+ glUniformMatrix4x3dv: TglUniformMatrix4x3dv;
+ glGetUniformdv: TglGetUniformdv;
+
+ // GL_ARB_gpu_shader_int64
+ glUniform1i64ARB : TglUniform1i64ARB;
+ glUniform2i64ARB : TglUniform2i64ARB;
+ glUniform3i64ARB : TglUniform3i64ARB;
+ glUniform4i64ARB : TglUniform4i64ARB;
+ glUniform1i64vARB : TglUniform1i64vARB;
+ glUniform2i64vARB : TglUniform2i64vARB;
+ glUniform3i64vARB : TglUniform3i64vARB;
+ glUniform4i64vARB : TglUniform4i64vARB;
+ glUniform1ui64ARB : TglUniform1ui64ARB;
+ glUniform2ui64ARB : TglUniform2ui64ARB;
+ glUniform3ui64ARB : TglUniform3ui64ARB;
+ glUniform4ui64ARB : TglUniform4ui64ARB;
+ glUniform1ui64vARB : TglUniform1ui64vARB;
+ glUniform2ui64vARB : TglUniform2ui64vARB;
+ glUniform3ui64vARB : TglUniform3ui64vARB;
+ glUniform4ui64vARB : TglUniform4ui64vARB;
+ glGetUniformi64vARB : TglGetUniformi64vARB;
+ glGetUniformui64vARB : TglGetUniformui64vARB;
+ glGetnUniformi64vARB : TglGetnUniformi64vARB;
+ glGetnUniformui64vARB : TglGetnUniformui64vARB;
+ glProgramUniform1i64ARB : TglProgramUniform1i64ARB;
+ glProgramUniform2i64ARB : TglProgramUniform2i64ARB;
+ glProgramUniform3i64ARB : TglProgramUniform3i64ARB;
+ glProgramUniform4i64ARB : TglProgramUniform4i64ARB;
+ glProgramUniform1i64vARB : TglProgramUniform1i64vARB;
+ glProgramUniform2i64vARB : TglProgramUniform2i64vARB;
+ glProgramUniform3i64vARB : TglProgramUniform3i64vARB;
+ glProgramUniform4i64vARB : TglProgramUniform4i64vARB;
+ glProgramUniform1ui64ARB : TglProgramUniform1ui64ARB;
+ glProgramUniform2ui64ARB : TglProgramUniform2ui64ARB;
+ glProgramUniform3ui64ARB : TglProgramUniform3ui64ARB;
+ glProgramUniform4ui64ARB : TglProgramUniform4ui64ARB ;
+ glProgramUniform1ui64vARB : TglProgramUniform1ui64vARB;
+ glProgramUniform2ui64vARB : TglProgramUniform2ui64vARB;
+ glProgramUniform3ui64vARB : TglProgramUniform3ui64vARB;
+ glProgramUniform4ui64vARB : TglProgramUniform4ui64vARB;
+
+ // GL_ARB_shader_subroutine
+ glGetSubroutineUniformLocation: TglGetSubroutineUniformLocation;
+ glGetSubroutineIndex: TglGetSubroutineIndex;
+ glGetActiveSubroutineUniformiv: TglGetActiveSubroutineUniformiv;
+ glGetActiveSubroutineUniformName: TglGetActiveSubroutineUniformName;
+ glGetActiveSubroutineName: TglGetActiveSubroutineName;
+ glUniformSubroutinesuiv: TglUniformSubroutinesuiv;
+ glGetUniformSubroutineuiv: TglGetUniformSubroutineuiv;
+ glGetProgramStageiv: TglGetProgramStageiv;
+
+ // GL_ARB_tessellation_shader
+ glPatchParameteri: TglPatchParameteri;
+ glPatchParameterfv: TglPatchParameterfv;
+
+ // GL_ARB_transform_feedback2
+ glBindTransformFeedback: TglBindTransformFeedback;
+ glDeleteTransformFeedbacks: TglDeleteTransformFeedbacks;
+ glGenTransformFeedbacks: TglGenTransformFeedbacks;
+ glIsTransformFeedback: TglIsTransformFeedback;
+ glPauseTransformFeedback: TglPauseTransformFeedback;
+ glResumeTransformFeedback: TglResumeTransformFeedback;
+ glDrawTransformFeedback: TglDrawTransformFeedback;
+
+ // GL_ARB_transform_feedback3
+ glDrawTransformFeedbackStream: TglDrawTransformFeedbackStream;
+ glBeginQueryIndexed: TglBeginQueryIndexed;
+ glEndQueryIndexed: TglEndQueryIndexed;
+ glGetQueryIndexediv: TglGetQueryIndexediv;
+
+ // GL_ARB_ES2_compatibility
+ glReleaseShaderCompiler: TglReleaseShaderCompiler;
+ glShaderBinary: TglShaderBinary;
+ glGetShaderPrecisionFormat: TglGetShaderPrecisionFormat;
+ glDepthRangef: TglDepthRangef;
+ glClearDepthf: TglClearDepthf;
+
+ // GL_ARB_ES3_2_compatibility
+ glPrimitiveBoundingBoxARB : TglPrimitiveBoundingBoxARB;
+
+ // GL_ARB_parallel_shader_compile
+ glMaxShaderCompilerThreadsARB : TglMaxShaderCompilerThreadsARB;
+
+ // GL_ARB_get_program_binary
+ glGetProgramBinary: TglGetProgramBinary;
+ glProgramBinary: TglProgramBinary;
+ glProgramParameteri: TglProgramParameteri;
+
+ // GL_ARB_separate_shader_objects
+ glUseProgramStages: TglUseProgramStages;
+ glActiveShaderProgram: TglActiveShaderProgram;
+ glCreateShaderProgramv: TglCreateShaderProgramv;
+ glBindProgramPipeline: TglBindProgramPipeline;
+ glDeleteProgramPipelines: TglDeleteProgramPipelines;
+ glGenProgramPipelines: TglGenProgramPipelines;
+ glIsProgramPipeline: TglIsProgramPipeline;
+ glGetProgramPipelineiv: TglGetProgramPipelineiv;
+ glProgramUniform1i: TglProgramUniform1i;
+ glProgramUniform1iv: TglProgramUniform1iv;
+ glProgramUniform1f: TglProgramUniform1f;
+ glProgramUniform1fv: TglProgramUniform1fv;
+ glProgramUniform1d: TglProgramUniform1d;
+ glProgramUniform1dv: TglProgramUniform1dv;
+ glProgramUniform1ui: TglProgramUniform1ui;
+ glProgramUniform1uiv: TglProgramUniform1uiv;
+ glProgramUniform2i: TglProgramUniform2i;
+ glProgramUniform2iv: TglProgramUniform2iv;
+ glProgramUniform2f: TglProgramUniform2f;
+ glProgramUniform2fv: TglProgramUniform2fv;
+ glProgramUniform2d: TglProgramUniform2d;
+ glProgramUniform2dv: TglProgramUniform2dv;
+ glProgramUniform2ui: TglProgramUniform2ui;
+ glProgramUniform2uiv: TglProgramUniform2uiv;
+ glProgramUniform3i: TglProgramUniform3i;
+ glProgramUniform3iv: TglProgramUniform3iv;
+ glProgramUniform3f: TglProgramUniform3f;
+ glProgramUniform3fv: TglProgramUniform3fv;
+ glProgramUniform3d: TglProgramUniform3d;
+ glProgramUniform3dv: TglProgramUniform3dv;
+ glProgramUniform3ui: TglProgramUniform3ui;
+ glProgramUniform3uiv: TglProgramUniform3uiv;
+ glProgramUniform4i: TglProgramUniform4i;
+ glProgramUniform4iv: TglProgramUniform4iv;
+ glProgramUniform4f: TglProgramUniform4f;
+ glProgramUniform4fv: TglProgramUniform4fv;
+ glProgramUniform4d: TglProgramUniform4d;
+ glProgramUniform4dv: TglProgramUniform4dv;
+ glProgramUniform4ui: TglProgramUniform4ui;
+ glProgramUniform4uiv: TglProgramUniform4uiv;
+ glProgramUniformMatrix2fv: TglProgramUniformMatrix2fv;
+ glProgramUniformMatrix3fv: TglProgramUniformMatrix3fv;
+ glProgramUniformMatrix4fv: TglProgramUniformMatrix4fv;
+ glProgramUniformMatrix2dv: TglProgramUniformMatrix2dv;
+ glProgramUniformMatrix3dv: TglProgramUniformMatrix3dv;
+ glProgramUniformMatrix4dv: TglProgramUniformMatrix4dv;
+ glProgramUniformMatrix2x3fv: TglProgramUniformMatrix2x3fv;
+ glProgramUniformMatrix3x2fv: TglProgramUniformMatrix3x2fv;
+ glProgramUniformMatrix2x4fv: TglProgramUniformMatrix2x4fv;
+ glProgramUniformMatrix4x2fv: TglProgramUniformMatrix4x2fv;
+ glProgramUniformMatrix3x4fv: TglProgramUniformMatrix3x4fv;
+ glProgramUniformMatrix4x3fv: TglProgramUniformMatrix4x3fv;
+ glProgramUniformMatrix2x3dv: TglProgramUniformMatrix2x3dv;
+ glProgramUniformMatrix3x2dv: TglProgramUniformMatrix3x2dv;
+ glProgramUniformMatrix2x4dv: TglProgramUniformMatrix2x4dv;
+ glProgramUniformMatrix4x2dv: TglProgramUniformMatrix4x2dv;
+ glProgramUniformMatrix3x4dv: TglProgramUniformMatrix3x4dv;
+ glProgramUniformMatrix4x3dv: TglProgramUniformMatrix4x3dv;
+ glValidateProgramPipeline: TglValidateProgramPipeline;
+ glGetProgramPipelineInfoLog: TglGetProgramPipelineInfoLog;
+
+ // GL_ARB_vertex_attrib_64bit
+ glVertexAttribL1d: TglVertexAttribL1d;
+ glVertexAttribL2d: TglVertexAttribL2d;
+ glVertexAttribL3d: TglVertexAttribL3d;
+ glVertexAttribL4d: TglVertexAttribL4d;
+ glVertexAttribL1dv: TglVertexAttribL1dv;
+ glVertexAttribL2dv: TglVertexAttribL2dv;
+ glVertexAttribL3dv: TglVertexAttribL3dv;
+ glVertexAttribL4dv: TglVertexAttribL4dv;
+ glVertexAttribLPointer: TglVertexAttribLPointer;
+ glGetVertexAttribLdv: TglGetVertexAttribLdv;
+
+ // GL_ARB_viewport_array
+ glViewportArrayv: TglViewportArrayv;
+ glViewportIndexedf: TglViewportIndexedf;
+ glViewportIndexedfv: TglViewportIndexedfv;
+ glScissorArrayv: TglScissorArrayv;
+ glScissorIndexed: TglScissorIndexed;
+ glScissorIndexedv: TglScissorIndexedv;
+ glDepthRangeArrayv: TglDepthRangeArrayv;
+ glDepthRangeIndexed: TglDepthRangeIndexed;
+ glGetFloati_v: TglGetFloati_v;
+ glGetDoublei_v: TglGetDoublei_v;
+
+ // GL 4.2
+
+ // GL_ARB_base_instance
+ glDrawArraysInstancedBaseInstance : TglDrawArraysInstancedBaseInstance;
+ glDrawElementsInstancedBaseInstance : TglDrawElementsInstancedBaseInstance;
+ glDrawElementsInstancedBaseVertexBaseInstance : TglDrawElementsInstancedBaseVertexBaseInstance;
+
+ // GL_ARB_transform_feedback_instanced
+ glDrawTransformFeedbackInstanced : TglDrawTransformFeedbackInstanced;
+ glDrawTransformFeedbackStreamInstanced : TglDrawTransformFeedbackStreamInstanced;
+
+ // GL_ARB_internalformat_query
+ glGetInternalformativ : TglGetInternalformativ;
+
+ // GL_ARB_shader_atomic_counters
+ glGetActiveAtomicCounterBufferiv : TglGetActiveAtomicCounterBufferiv;
+
+ /// GL_ARB_shader_image_load_store
+ glBindImageTexture : TglBindImageTexture;
+ glMemoryBarrier : TglMemoryBarrier;
+
+ // GL_ARB_texture_storage
+ glTexStorage1D : TglTexStorage1D;
+ glTexStorage2D : TglTexStorage2D;
+ glTexStorage3D : TglTexStorage3D;
+ glTextureStorage1DEXT : TglTextureStorage1DEXT;
+ glTextureStorage2DEXT : TglTextureStorage2DEXT;
+ glTextureStorage3DEXT : TglTextureStorage3DEXT;
+
+
+ // GL 4.3
+ // GL_KHR_debug
+ glDebugMessageControl : TglDebugMessageControl;
+ glDebugMessageInsert : TglDebugMessageInsert;
+ glDebugMessageCallback : TglDebugMessageCallback;
+ glGetDebugMessageLog : TglGetDebugMessageLog;
+ glPushDebugGroup : TglPushDebugGroup;
+ glPopDebugGroup : TglPopDebugGroup;
+ glObjectLabel : TglObjectLabel;
+ glGetObjectLabel : TglGetObjectLabel;
+ glObjectPtrLabel : TglObjectPtrLabel;
+ glGetObjectPtrLabel : TglGetObjectPtrLabel;
+ // GL_ARB_clear_buffer_object
+ glClearBufferData : TglClearBufferData;
+ glClearBufferSubData : TglClearBufferSubData;
+ glClearNamedBufferDataEXT : TglClearNamedBufferDataEXT;
+ glClearNamedBufferSubDataEXT : TglClearNamedBufferSubDataEXT;
+ // GL_ARB_compute_shader
+ glDispatchCompute : TglDispatchCompute;
+ glDispatchComputeIndirect : TglDispatchComputeIndirect;
+ // GL_ARB_copy_image
+ glCopyImageSubData : TglCopyImageSubData;
+ // GL_ARB_framebuffer_no_attachments
+ glFramebufferParameteri : TglFramebufferParameteri;
+ glGetFramebufferParameteriv : TglGetFramebufferParameteriv;
+ glNamedFramebufferParameteriEXT : TglNamedFramebufferParameteriEXT;
+ glGetNamedFramebufferParameterivEXT : TglGetNamedFramebufferParameterivEXT;
+ // GL_ARB_internalformat_query2
+ glGetInternalformati64v : TglGetInternalformati64v;
+ // GL_ARB_invalidate_subdata
+ glInvalidateTexSubImage : TglInvalidateTexSubImage;
+ glInvalidateTexImage : TglInvalidateTexImage;
+ glInvalidateBufferSubData : TglInvalidateBufferSubData;
+ glInvalidateBufferData : TglInvalidateBufferData;
+ glInvalidateFramebuffer : TglInvalidateFramebuffer;
+ glInvalidateSubFramebuffer : TglInvalidateSubFramebuffer;
+ // GL_ARB_multi_draw_indirect
+ glMultiDrawArraysIndirect : TglMultiDrawArraysIndirect;
+ glMultiDrawElementsIndirect : TglMultiDrawElementsIndirect;
+ // GL_ARB_program_interface_query
+ glGetProgramInterfaceiv : TglGetProgramInterfaceiv;
+ glGetProgramResourceIndex : TglGetProgramResourceIndex;
+ glGetProgramResourceName : TglGetProgramResourceName;
+ glGetProgramResourceiv : TglGetProgramResourceiv;
+ glGetProgramResourceLocation : TglGetProgramResourceLocation;
+ glGetProgramResourceLocationIndex : TglGetProgramResourceLocationIndex;
+ // GL_ARB_shader_storage_buffer_object
+ glShaderStorageBlockBinding : TglShaderStorageBlockBinding;
+ // GL_ARB_texture_buffer_range
+ glTexBufferRange : TglTexBufferRange;
+ glTextureBufferRangeEXT : TglTextureBufferRangeEXT;
+ // GL_ARB_texture_storage_multisample
+ glTexStorage2DMultisample : TglTexStorage2DMultisample;
+ glTexStorage3DMultisample : TglTexStorage3DMultisample;
+ glTextureStorage2DMultisampleEXT : TglTextureStorage2DMultisampleEXT;
+ glTextureStorage3DMultisampleEXT : TglTextureStorage3DMultisampleEXT;
+ // GL_ARB_texture_view
+ glTextureView : TglTextureView;
+ // GL_ARB_vertex_attrib_binding
+ glBindVertexBuffer : TglBindVertexBuffer;
+ glVertexAttribFormat : TglVertexAttribFormat;
+ glVertexAttribIFormat : TglVertexAttribIFormat;
+ glVertexAttribLFormat : TglVertexAttribLFormat;
+ glVertexAttribBinding : TglVertexAttribBinding;
+ glVertexBindingDivisor : TglVertexBindingDivisor;
+ glVertexArrayBindVertexBufferEXT : TglVertexArrayBindVertexBufferEXT;
+ glVertexArrayVertexAttribFormatEXT : TglVertexArrayVertexAttribFormatEXT;
+ glVertexArrayVertexAttribIFormatEXT : TglVertexArrayVertexAttribIFormatEXT;
+ glVertexArrayVertexAttribLFormatEXT : TglVertexArrayVertexAttribLFormatEXT;
+ glVertexArrayVertexAttribBindingEXT : TglVertexArrayVertexAttribBindingEXT;
+ glVertexArrayVertexBindingDivisorEXT : TglVertexArrayVertexBindingDivisorEXT;
+ // END GL 4.3
+
+
+ // GL 4.4
+ glBufferStorage : TglBufferStorage;
+ glClearTexImage : TglClearTexImage;
+ glClearTexSubImage : TglClearTexSubImage;
+ glBindBuffersBase : TglBindBuffersBase;
+ glBindBuffersRange : TglBindBuffersRange;
+ glBindTextures : TglBindTextures;
+ glBindSamplers : TglBindSamplers;
+ glBindImageTextures : TglBindImageTextures;
+ glBindVertexBuffers : TglBindVertexBuffers;
+ glTexPageCommitmentARB : TglTexPageCommitmentARB;
+
+ // GL 4.5
+ glClipControl : TglClipControl;
+ glCreateTransformFeedbacks : TglCreateTransformFeedbacks;
+ glTransformFeedbackBufferBase : TglTransformFeedbackBufferBase;
+ glTransformFeedbackBufferRange : TglTransformFeedbackBufferRange;
+ glGetTransformFeedbackiv : TglGetTransformFeedbackiv;
+ glGetTransformFeedbacki_v : TglGetTransformFeedbacki_v;
+ glGetTransformFeedbacki64_v : TglGetTransformFeedbacki64_v;
+ glCreateBuffers : TglCreateBuffers;
+ glNamedBufferStorage : TglNamedBufferStorage;
+ glNamedBufferData : TglNamedBufferData;
+ glNamedBufferSubData : TglNamedBufferSubData;
+ glCopyNamedBufferSubData : TglCopyNamedBufferSubData;
+ glClearNamedBufferData : TglClearNamedBufferData;
+ glClearNamedBufferSubData : TglClearNamedBufferSubData;
+ glMapNamedBuffer : TglMapNamedBuffer;
+ glMapNamedBufferRange : TglMapNamedBufferRange;
+ glUnmapNamedBuffer : TglUnmapNamedBuffer;
+ glFlushMappedNamedBufferRange : TglFlushMappedNamedBufferRange;
+ glGetNamedBufferParameteriv : TglGetNamedBufferParameteriv;
+ glGetNamedBufferParameteri64v : TglGetNamedBufferParameteri64v;
+ glGetNamedBufferPointerv : TglGetNamedBufferPointerv;
+ glGetNamedBufferSubData : TglGetNamedBufferSubData;
+ glCreateFramebuffers : TglCreateFramebuffers;
+ glNamedFramebufferRenderbuffer : TglNamedFramebufferRenderbuffer;
+ glNamedFramebufferParameteri : TglNamedFramebufferParameteri;
+ glNamedFramebufferTexture : TglNamedFramebufferTexture;
+ glNamedFramebufferTextureLayer : TglNamedFramebufferTextureLayer;
+ glNamedFramebufferDrawBuffer : TglNamedFramebufferDrawBuffer;
+ glNamedFramebufferDrawBuffers : TglNamedFramebufferDrawBuffers;
+ glNamedFramebufferReadBuffer : TglNamedFramebufferReadBuffer;
+ glInvalidateNamedFramebufferData : TglInvalidateNamedFramebufferData;
+ glInvalidateNamedFramebufferSubData : TglInvalidateNamedFramebufferSubData;
+ glClearNamedFramebufferiv : TglClearNamedFramebufferiv;
+ glClearNamedFramebufferuiv : TglClearNamedFramebufferuiv;
+ glClearNamedFramebufferfv : TglClearNamedFramebufferfv;
+ glClearNamedFramebufferfi : TglClearNamedFramebufferfi;
+ glBlitNamedFramebuffer : TglBlitNamedFramebuffer;
+ glCheckNamedFramebufferStatus : TglCheckNamedFramebufferStatus;
+ glGetNamedFramebufferParameteriv : TglGetNamedFramebufferParameteriv;
+ glGetNamedFramebufferAttachmentParameteriv : TglGetNamedFramebufferAttachmentParameteriv;
+ glCreateRenderbuffers : TglCreateRenderbuffers;
+ glNamedRenderbufferStorage : TglNamedRenderbufferStorage;
+ glNamedRenderbufferStorageMultisample : TglNamedRenderbufferStorageMultisample;
+ glGetNamedRenderbufferParameteriv : TglGetNamedRenderbufferParameteriv;
+ glCreateTextures : TglCreateTextures;
+ glTextureBuffer : TglTextureBuffer;
+ glTextureBufferRange : TglTextureBufferRange;
+ glTextureStorage1D : TglTextureStorage1D;
+ glTextureStorage2D : TglTextureStorage2D;
+ glTextureStorage3D : TglTextureStorage3D;
+ glTextureStorage2DMultisample : TglTextureStorage2DMultisample;
+ glTextureStorage3DMultisample : TglTextureStorage3DMultisample;
+ glTextureSubImage1D : TglTextureSubImage1D;
+ glTextureSubImage2D : TglTextureSubImage2D;
+ glTextureSubImage3D : TglTextureSubImage3D;
+ glCompressedTextureSubImage1D : TglCompressedTextureSubImage1D;
+ glCompressedTextureSubImage2D : TglCompressedTextureSubImage2D;
+ glCompressedTextureSubImage3D : TglCompressedTextureSubImage3D;
+ glCopyTextureSubImage1D : TglCopyTextureSubImage1D;
+ glCopyTextureSubImage2D : TglCopyTextureSubImage2D;
+ glCopyTextureSubImage3D : TglCopyTextureSubImage3D;
+ glTextureParameterf : TglTextureParameterf;
+ glTextureParameterfv : TglTextureParameterfv;
+ glTextureParameteri : TglTextureParameteri;
+ glTextureParameterIiv : TglTextureParameterIiv;
+ glTextureParameterIuiv : TglTextureParameterIuiv;
+ glTextureParameteriv : TglTextureParameteriv;
+ glGenerateTextureMipmap : TglGenerateTextureMipmap;
+ glBindTextureUnit : TglBindTextureUnit;
+ glGetTextureImage : TglGetTextureImage;
+ glGetCompressedTextureImage : TglGetCompressedTextureImage;
+ glGetTextureLevelParameterfv : TglGetTextureLevelParameterfv;
+ glGetTextureLevelParameteriv : TglGetTextureLevelParameteriv;
+ glGetTextureParameterfv : TglGetTextureParameterfv;
+ glGetTextureParameterIiv : TglGetTextureParameterIiv;
+ glGetTextureParameterIuiv : TglGetTextureParameterIuiv;
+ glGetTextureParameteriv : TglGetTextureParameteriv;
+ glCreateVertexArrays : TglCreateVertexArrays;
+ glDisableVertexArrayAttrib : TglDisableVertexArrayAttrib;
+ glEnableVertexArrayAttrib : TglEnableVertexArrayAttrib;
+ glVertexArrayElementBuffer : TglVertexArrayElementBuffer;
+ glVertexArrayVertexBuffer : TglVertexArrayVertexBuffer;
+ glVertexArrayVertexBuffers : TglVertexArrayVertexBuffers;
+ glVertexArrayAttribBinding : TglVertexArrayAttribBinding;
+ glVertexArrayAttribFormat : TglVertexArrayAttribFormat;
+ glVertexArrayAttribIFormat : TglVertexArrayAttribIFormat;
+ glVertexArrayAttribLFormat : TglVertexArrayAttribLFormat;
+ glVertexArrayBindingDivisor : TglVertexArrayBindingDivisor;
+ glGetVertexArrayiv : TglGetVertexArrayiv;
+ glGetVertexArrayIndexediv : TglGetVertexArrayIndexediv;
+ glGetVertexArrayIndexed64iv : TglGetVertexArrayIndexed64iv;
+ glCreateSamplers : TglCreateSamplers;
+ glCreateProgramPipelines : TglCreateProgramPipelines;
+ glCreateQueries : TglCreateQueries;
+ glMemoryBarrierByRegion : TglMemoryBarrierByRegion;
+ glGetTextureSubImage : TglGetTextureSubImage;
+ glGetCompressedTextureSubImage : TglGetCompressedTextureSubImage;
+ glGetGraphicsResetStatus : TglGetGraphicsResetStatus;
+ glGetnCompressedTexImage : TglGetnCompressedTexImage;
+ glGetnTexImage : TglGetnTexImage;
+ glGetnUniformdv : TglGetnUniformdv;
+ glGetnUniformfv : TglGetnUniformfv;
+ glGetnUniformiv : TglGetnUniformiv;
+ glGetnUniformuiv : TglGetnUniformuiv;
+ glReadnPixels : TglReadnPixels;
+ glGetnMapdv : TglGetnMapdv;
+ glGetnMapfv : TglGetnMapfv;
+ glGetnMapiv : TglGetnMapiv;
+ glGetnPixelMapfv : TglGetnPixelMapfv;
+ glGetnPixelMapuiv : TglGetnPixelMapuiv;
+ glGetnPixelMapusv : TglGetnPixelMapusv;
+ glGetnPolygonStipple : TglGetnPolygonStipple;
+ glGetnColorTable : TglGetnColorTable;
+ glGetnConvolutionFilter : TglGetnConvolutionFilter;
+ glGetnSeparableFilter : TglGetnSeparableFilter;
+ glGetnHistogram : TglGetnHistogram;
+ glGetnMinmax : TglGetnMinmax;
+ glTextureBarrier : TglTextureBarrier;
+
+ // 4.6
+ glSpecializeShader : TglSpecializeShader;
+ glMultiDrawArraysIndirectCount : TglMultiDrawArraysIndirectCount;
+ glMultiDrawElementsIndirectCount : TglMultiDrawElementsIndirectCount;
+ glPolygonOffsetClamp : TglPolygonOffsetClamp;
+
+ // GL_ARB_sparse_buffer
+ glBufferPageCommitmentARB : TglBufferPageCommitmentARB;
+ glNamedBufferPageCommitmentEXT : TglNamedBufferPageCommitmentEXT;
+ glNamedBufferPageCommitmentARB : TglNamedBufferPageCommitmentARB;
+
+ // GL_KHR_blend_equation_advanced
+ glBlendBarrierKHR : TglBlendBarrierKHR;
+
+ // GL_ARB_cl_event
+ glCreateSyncFromCLeventARB: TglCreateSyncFromCLeventARB;
+
+ // GL_ARB_debug_output
+ glDebugMessageControlARB: TglDebugMessageControlARB;
+ glDebugMessageInsertARB: TglDebugMessageInsertARB;
+ glDebugMessageCallbackARB: TglDebugMessageCallbackARB;
+ glGetDebugMessageLogARB: TglGetDebugMessageLogARB;
+
+ // GL_ARB_compute_variable_group_size
+ glDispatchComputeGroupSizeARB : TglDispatchComputeGroupSizeARB;
+
+ // GL_ARB_robustness
+ glGetGraphicsResetStatusARB: TglGetGraphicsResetStatusARB;
+ glGetnMapdvARB: TglGetnMapdvARB;
+ glGetnMapfvARB: TglGetnMapfvARB;
+ glGetnMapivARB: TglGetnMapivARB;
+ glGetnPixelMapfvARB: TglGetnPixelMapfvARB;
+ glGetnPixelMapuivARB: TglGetnPixelMapuivARB;
+ glGetnPixelMapusvARB: TglGetnPixelMapusvARB;
+ glGetnPolygonStippleARB: TglGetnPolygonStippleARB;
+ glGetnColorTableARB: TglGetnColorTableARB;
+ glGetnConvolutionFilterARB: TglGetnConvolutionFilterARB;
+ glGetnSeparableFilterARB: TglGetnSeparableFilterARB;
+ glGetnHistogramARB: TglGetnHistogramARB;
+ glGetnMinmaxARB: TglGetnMinmaxARB;
+ glGetnTexImageARB: TglGetnTexImageARB;
+ glReadnPixelsARB: TglReadnPixelsARB;
+ glGetnCompressedTexImageARB: TglGetnCompressedTexImageARB;
+ glGetnUniformfvARB: TglGetnUniformfvARB;
+ glGetnUniformivARB: TglGetnUniformivARB;
+ glGetnUniformuivARB: TglGetnUniformuivARB;
+ glGetnUniformdvARB: TglGetnUniformdvARB;
+
+ // GL_ATI_draw_buffers
+ glDrawBuffersATI: TglDrawBuffersATI;
+
+ // GL_ATI_element_array
+ glElementPointerATI: TglElementPointerATI;
+ glDrawElementArrayATI: TglDrawElementArrayATI;
+ glDrawRangeElementArrayATI: TglDrawRangeElementArrayATI;
+
+ // GL_ATI_envmap_bumpmap
+ glTexBumpParameterivATI: TglTexBumpParameterivATI;
+ glTexBumpParameterfvATI: TglTexBumpParameterfvATI;
+ glGetTexBumpParameterivATI: TglGetTexBumpParameterivATI;
+ glGetTexBumpParameterfvATI: TglGetTexBumpParameterfvATI;
+
+ // GL_ATI_fragment_shader
+ glGenFragmentShadersATI: TglGenFragmentShadersATI;
+ glBindFragmentShaderATI: TglBindFragmentShaderATI;
+ glDeleteFragmentShaderATI: TglDeleteFragmentShaderATI;
+ glBeginFragmentShaderATI: TglBeginFragmentShaderATI;
+ glEndFragmentShaderATI: TglEndFragmentShaderATI;
+ glPassTexCoordATI: TglPassTexCoordATI;
+ glSampleMapATI: TglSampleMapATI;
+ glColorFragmentOp1ATI: TglColorFragmentOp1ATI;
+ glColorFragmentOp2ATI: TglColorFragmentOp2ATI;
+ glColorFragmentOp3ATI: TglColorFragmentOp3ATI;
+ glAlphaFragmentOp1ATI: TglAlphaFragmentOp1ATI;
+ glAlphaFragmentOp2ATI: TglAlphaFragmentOp2ATI;
+ glAlphaFragmentOp3ATI: TglAlphaFragmentOp3ATI;
+ glSetFragmentShaderConstantATI: TglSetFragmentShaderConstantATI;
+
+ // GL_ATI_map_object_buffer
+ glMapObjectBufferATI: TglMapObjectBufferATI;
+ glUnmapObjectBufferATI: TglUnmapObjectBufferATI;
+
+ // GL_ATI_pn_triangles
+ glPNTrianglesiATI: TglPNTrianglesiATI;
+ glPNTrianglesfATI: TglPNTrianglesfATI;
+
+ // GL_ATI_separate_stencil
+ glStencilOpSeparateATI: TglStencilOpSeparateATI;
+ glStencilFuncSeparateATI: TglStencilFuncSeparateATI;
+
+ // GL_ATI_vertex_array_object
+ glNewObjectBufferATI: TglNewObjectBufferATI;
+ glIsObjectBufferATI: TglIsObjectBufferATI;
+ glUpdateObjectBufferATI: TglUpdateObjectBufferATI;
+ glGetObjectBufferfvATI: TglGetObjectBufferfvATI;
+ glGetObjectBufferivATI: TglGetObjectBufferivATI;
+ glFreeObjectBufferATI: TglFreeObjectBufferATI;
+ glArrayObjectATI: TglArrayObjectATI;
+ glGetArrayObjectfvATI: TglGetArrayObjectfvATI;
+ glGetArrayObjectivATI: TglGetArrayObjectivATI;
+ glVariantArrayObjectATI: TglVariantArrayObjectATI;
+ glGetVariantArrayObjectfvATI: TglGetVariantArrayObjectfvATI;
+ glGetVariantArrayObjectivATI: TglGetVariantArrayObjectivATI;
+ glVertexAttribArrayObjectATI: TglVertexAttribArrayObjectATI;
+ glGetVertexAttribArrayObjectfvATI: TglGetVertexAttribArrayObjectfvATI;
+ glGetVertexAttribArrayObjectivATI: TglGetVertexAttribArrayObjectivATI;
+
+ // GL_ATI_vertex_streams
+ glVertexStream1sATI: TglVertexStream1sATI;
+ glVertexStream1svATI: TglVertexStream1svATI;
+ glVertexStream1iATI: TglVertexStream1iATI;
+ glVertexStream1ivATI: TglVertexStream1ivATI;
+ glVertexStream1fATI: TglVertexStream1fATI;
+ glVertexStream1fvATI: TglVertexStream1fvATI;
+ glVertexStream1dATI: TglVertexStream1dATI;
+ glVertexStream1dvATI: TglVertexStream1dvATI;
+ glVertexStream2sATI: TglVertexStream2sATI;
+ glVertexStream2svATI: TglVertexStream2svATI;
+ glVertexStream2iATI: TglVertexStream2iATI;
+ glVertexStream2ivATI: TglVertexStream2ivATI;
+ glVertexStream2fATI: TglVertexStream2fATI;
+ glVertexStream2fvATI: TglVertexStream2fvATI;
+ glVertexStream2dATI: TglVertexStream2dATI;
+ glVertexStream2dvATI: TglVertexStream2dvATI;
+ glVertexStream3sATI: TglVertexStream3sATI;
+ glVertexStream3svATI: TglVertexStream3svATI;
+ glVertexStream3iATI: TglVertexStream3iATI;
+ glVertexStream3ivATI: TglVertexStream3ivATI;
+ glVertexStream3fATI: TglVertexStream3fATI;
+ glVertexStream3fvATI: TglVertexStream3fvATI;
+ glVertexStream3dATI: TglVertexStream3dATI;
+ glVertexStream3dvATI: TglVertexStream3dvATI;
+ glVertexStream4sATI: TglVertexStream4sATI;
+ glVertexStream4svATI: TglVertexStream4svATI;
+ glVertexStream4iATI: TglVertexStream4iATI;
+ glVertexStream4ivATI: TglVertexStream4ivATI;
+ glVertexStream4fATI: TglVertexStream4fATI;
+ glVertexStream4fvATI: TglVertexStream4fvATI;
+ glVertexStream4dATI: TglVertexStream4dATI;
+ glVertexStream4dvATI: TglVertexStream4dvATI;
+ glNormalStream3bATI: TglNormalStream3bATI;
+ glNormalStream3bvATI: TglNormalStream3bvATI;
+ glNormalStream3sATI: TglNormalStream3sATI;
+ glNormalStream3svATI: TglNormalStream3svATI;
+ glNormalStream3iATI: TglNormalStream3iATI;
+ glNormalStream3ivATI: TglNormalStream3ivATI;
+ glNormalStream3fATI: TglNormalStream3fATI;
+ glNormalStream3fvATI: TglNormalStream3fvATI;
+ glNormalStream3dATI: TglNormalStream3dATI;
+ glNormalStream3dvATI: TglNormalStream3dvATI;
+ glClientActiveVertexStreamATI: TglClientActiveVertexStreamATI;
+ glVertexBlendEnviATI: TglVertexBlendEnviATI;
+ glVertexBlendEnvfATI: TglVertexBlendEnvfATI;
+
+ // GL_AMD_performance_monitor
+ glGetPerfMonitorGroupsAMD: TglGetPerfMonitorGroupsAMD;
+ glGetPerfMonitorCountersAMD: TglGetPerfMonitorCountersAMD;
+ glGetPerfMonitorGroupStringAMD: TglGetPerfMonitorGroupStringAMD;
+ glGetPerfMonitorCounterStringAMD: TglGetPerfMonitorCounterStringAMD;
+ glGetPerfMonitorCounterInfoAMD: TglGetPerfMonitorCounterInfoAMD;
+ glGenPerfMonitorsAMD: TglGenPerfMonitorsAMD;
+ glDeletePerfMonitorsAMD: TglDeletePerfMonitorsAMD;
+ glSelectPerfMonitorCountersAMD: TglSelectPerfMonitorCountersAMD;
+ glBeginPerfMonitorAMD: TglBeginPerfMonitorAMD;
+ glEndPerfMonitorAMD: TglEndPerfMonitorAMD;
+ glGetPerfMonitorCounterDataAMD: TglGetPerfMonitorCounterDataAMD;
+
+ // GL_AMD_vertex_shader_tesselator
+ glTessellationFactorAMD: TglTessellationFactorAMD;
+ glTessellationModeAMD: TglTessellationModeAMD;
+
+ // GL_AMD_draw_buffers_blend
+ glBlendFuncIndexedAMD: TglBlendFuncIndexedAMD;
+ glBlendFuncSeparateIndexedAMD: TglBlendFuncSeparateIndexedAMD;
+ glBlendEquationIndexedAMD: TglBlendEquationIndexedAMD;
+ glBlendEquationSeparateIndexedAMD: TglBlendEquationSeparateIndexedAMD;
+
+ // GL_AMD_name_gen_delete
+ glGenNamesAMD: TglGenNamesAMD;
+ glDeleteNamesAMD: TglDeleteNamesAMD;
+ glIsNameAMD: TglIsNameAMD;
+
+ // GL_AMD_debug_output
+ glDebugMessageEnableAMD: TglDebugMessageEnableAMD;
+ glDebugMessageInsertAMD: TglDebugMessageInsertAMD;
+ glDebugMessageCallbackAMD: TglDebugMessageCallbackAMD;
+ glGetDebugMessageLogAMD: TglGetDebugMessageLogAMD;
+
+ // GL_EXT_blend_color
+ glBlendColorEXT: TglBlendColorEXT;
+
+ // GL_EXT_blend_func_separate
+ glBlendFuncSeparateEXT: TglBlendFuncSeparateEXT;
+
+ // GL_EXT_blend_minmax
+ glBlendEquationEXT: TglBlendEquationEXT;
+
+ // GL_EXT_color_subtable
+ glColorSubTableEXT: TglColorSubTableEXT;
+ glCopyColorSubTableEXT: TglCopyColorSubTableEXT;
+
+ // GL_EXT_compiled_vertex_array
+ glLockArraysEXT: TglLockArraysEXT;
+ glUnlockArraysEXT: TglUnlockArraysEXT;
+
+ // GL_EXT_convolution
+ glConvolutionFilter1DEXT: TglConvolutionFilter1DEXT;
+ glConvolutionFilter2DEXT: TglConvolutionFilter2DEXT;
+ glConvolutionParameterfEXT: TglConvolutionParameterfEXT;
+ glConvolutionParameterfvEXT: TglConvolutionParameterfvEXT;
+ glConvolutionParameteriEXT: TglConvolutionParameteriEXT;
+ glConvolutionParameterivEXT: TglConvolutionParameterivEXT;
+ glCopyConvolutionFilter1DEXT: TglCopyConvolutionFilter1DEXT;
+ glCopyConvolutionFilter2DEXT: TglCopyConvolutionFilter2DEXT;
+ glGetConvolutionFilterEXT: TglGetConvolutionFilterEXT;
+ glGetConvolutionParameterfvEXT: TglGetConvolutionParameterfvEXT;
+ glGetConvolutionParameterivEXT: TglGetConvolutionParameterivEXT;
+ glGetSeparableFilterEXT: TglGetSeparableFilterEXT;
+ glSeparableFilter2DEXT: TglSeparableFilter2DEXT;
+
+ // GL_EXT_coordinate_frame
+ glTangent3bEXT: TglTangent3bEXT;
+ glTangent3bvEXT: TglTangent3bvEXT;
+ glTangent3dEXT: TglTangent3dEXT;
+ glTangent3dvEXT: TglTangent3dvEXT;
+ glTangent3fEXT: TglTangent3fEXT;
+ glTangent3fvEXT: TglTangent3fvEXT;
+ glTangent3iEXT: TglTangent3iEXT;
+ glTangent3ivEXT: TglTangent3ivEXT;
+ glTangent3sEXT: TglTangent3sEXT;
+ glTangent3svEXT: TglTangent3svEXT;
+ glBinormal3bEXT: TglBinormal3bEXT;
+ glBinormal3bvEXT: TglBinormal3bvEXT;
+ glBinormal3dEXT: TglBinormal3dEXT;
+ glBinormal3dvEXT: TglBinormal3dvEXT;
+ glBinormal3fEXT: TglBinormal3fEXT;
+ glBinormal3fvEXT: TglBinormal3fvEXT;
+ glBinormal3iEXT: TglBinormal3iEXT;
+ glBinormal3ivEXT: TglBinormal3ivEXT;
+ glBinormal3sEXT: TglBinormal3sEXT;
+ glBinormal3svEXT: TglBinormal3svEXT;
+ glTangentPointerEXT: TglTangentPointerEXT;
+ glBinormalPointerEXT: TglBinormalPointerEXT;
+
+ // GL_EXT_copy_texture
+ glCopyTexImage1DEXT: TglCopyTexImage1DEXT;
+ glCopyTexImage2DEXT: TglCopyTexImage2DEXT;
+ glCopyTexSubImage1DEXT: TglCopyTexSubImage1DEXT;
+ glCopyTexSubImage2DEXT: TglCopyTexSubImage2DEXT;
+ glCopyTexSubImage3DEXT: TglCopyTexSubImage3DEXT;
+
+ // GL_EXT_cull_vertex
+ glCullParameterdvEXT: TglCullParameterdvEXT;
+ glCullParameterfvEXT: TglCullParameterfvEXT;
+
+ // GL_EXT_draw_range_elements
+ glDrawRangeElementsEXT: TglDrawRangeElementsEXT;
+
+ // GL_EXT_fog_coord
+ glFogCoordfEXT: TglFogCoordfEXT;
+ glFogCoordfvEXT: TglFogCoordfvEXT;
+ glFogCoorddEXT: TglFogCoorddEXT;
+ glFogCoorddvEXT: TglFogCoorddvEXT;
+ glFogCoordPointerEXT: TglFogCoordPointerEXT;
+
+ // GL_EXT_framebuffer_object
+ glIsRenderbufferEXT: TglIsRenderbufferEXT;
+ glBindRenderbufferEXT: TglBindRenderbufferEXT;
+ glDeleteRenderbuffersEXT: TglDeleteRenderbuffersEXT;
+ glGenRenderbuffersEXT: TglGenRenderbuffersEXT;
+ glRenderbufferStorageEXT: TglRenderbufferStorageEXT;
+ glGetRenderbufferParameterivEXT: TglGetRenderbufferParameterivEXT;
+ glIsFramebufferEXT: TglIsFramebufferEXT;
+ glBindFramebufferEXT: TglBindFramebufferEXT;
+ glDeleteFramebuffersEXT: TglDeleteFramebuffersEXT;
+ glGenFramebuffersEXT: TglGenFramebuffersEXT;
+ glCheckFramebufferStatusEXT: TglCheckFramebufferStatusEXT;
+ glFramebufferTexture1DEXT: TglFramebufferTexture1DEXT;
+ glFramebufferTexture2DEXT: TglFramebufferTexture2DEXT;
+ glFramebufferTexture3DEXT: TglFramebufferTexture3DEXT;
+ glFramebufferRenderbufferEXT: TglFramebufferRenderbufferEXT;
+ glGetFramebufferAttachmentParameterivEXT: TglGetFramebufferAttachmentParameterivEXT;
+ glGenerateMipmapEXT: TglGenerateMipmapEXT;
+
+ // GL_EXT_histogram
+ glGetHistogramEXT: TglGetHistogramEXT;
+ glGetHistogramParameterfvEXT: TglGetHistogramParameterfvEXT;
+ glGetHistogramParameterivEXT: TglGetHistogramParameterivEXT;
+ glGetMinmaxEXT: TglGetMinmaxEXT;
+ glGetMinmaxParameterfvEXT: TglGetMinmaxParameterfvEXT;
+ glGetMinmaxParameterivEXT: TglGetMinmaxParameterivEXT;
+ glHistogramEXT: TglHistogramEXT;
+ glMinmaxEXT: TglMinmaxEXT;
+ glResetHistogramEXT: TglResetHistogramEXT;
+ glResetMinmaxEXT: TglResetMinmaxEXT;
+
+ // GL_EXT_index_func
+ glIndexFuncEXT: TglIndexFuncEXT;
+
+ // GL_EXT_index_material
+ glIndexMaterialEXT: TglIndexMaterialEXT;
+
+ // GL_EXT_light_texture
+ glApplyTextureEXT: TglApplyTextureEXT;
+ glTextureLightEXT: TglTextureLightEXT;
+ glTextureMaterialEXT: TglTextureMaterialEXT;
+
+ // GL_EXT_multi_draw_arrays
+ glMultiDrawArraysEXT: TglMultiDrawArraysEXT;
+ glMultiDrawElementsEXT: TglMultiDrawElementsEXT;
+
+ // GL_EXT_multisample
+ glSampleMaskEXT: TglSampleMaskEXT;
+ glSamplePatternEXT: TglSamplePatternEXT;
+
+ // GL_EXT_paletted_texture
+ glColorTableEXT: TglColorTableEXT;
+ glGetColorTableEXT: TglGetColorTableEXT;
+ glGetColorTableParameterivEXT: TglGetColorTableParameterivEXT;
+ glGetColorTableParameterfvEXT: TglGetColorTableParameterfvEXT;
+
+ // GL_EXT_pixel_transform
+ glPixelTransformParameteriEXT: TglPixelTransformParameteriEXT;
+ glPixelTransformParameterfEXT: TglPixelTransformParameterfEXT;
+ glPixelTransformParameterivEXT: TglPixelTransformParameterivEXT;
+ glPixelTransformParameterfvEXT: TglPixelTransformParameterfvEXT;
+
+ // GL_EXT_point_parameters
+ glPointParameterfEXT: TglPointParameterfEXT;
+ glPointParameterfvEXT: TglPointParameterfvEXT;
+
+ // GL_EXT_polygon_offset
+ glPolygonOffsetEXT: TglPolygonOffsetEXT;
+
+ // GL_EXT_secondary_color
+ glSecondaryColor3bEXT: TglSecondaryColor3bEXT;
+ glSecondaryColor3bvEXT: TglSecondaryColor3bvEXT;
+ glSecondaryColor3dEXT: TglSecondaryColor3dEXT;
+ glSecondaryColor3dvEXT: TglSecondaryColor3dvEXT;
+ glSecondaryColor3fEXT: TglSecondaryColor3fEXT;
+ glSecondaryColor3fvEXT: TglSecondaryColor3fvEXT;
+ glSecondaryColor3iEXT: TglSecondaryColor3iEXT;
+ glSecondaryColor3ivEXT: TglSecondaryColor3ivEXT;
+ glSecondaryColor3sEXT: TglSecondaryColor3sEXT;
+ glSecondaryColor3svEXT: TglSecondaryColor3svEXT;
+ glSecondaryColor3ubEXT: TglSecondaryColor3ubEXT;
+ glSecondaryColor3ubvEXT: TglSecondaryColor3ubvEXT;
+ glSecondaryColor3uiEXT: TglSecondaryColor3uiEXT;
+ glSecondaryColor3uivEXT: TglSecondaryColor3uivEXT;
+ glSecondaryColor3usEXT: TglSecondaryColor3usEXT;
+ glSecondaryColor3usvEXT: TglSecondaryColor3usvEXT;
+ glSecondaryColorPointerEXT: TglSecondaryColorPointerEXT;
+
+ // GL_EXT_stencil_two_side
+ glActiveStencilFaceEXT: TglActiveStencilFaceEXT;
+
+ // GL_EXT_subtexture
+ glTexSubImage1DEXT: TglTexSubImage1DEXT;
+ glTexSubImage2DEXT: TglTexSubImage2DEXT;
+
+ // GL_EXT_texture3D
+ glTexImage3DEXT: TglTexImage3DEXT;
+ glTexSubImage3DEXT: TglTexSubImage3DEXT;
+
+ // GL_EXT_texture_object
+ glAreTexturesResidentEXT: TglAreTexturesResidentEXT;
+ glBindTextureEXT: TglBindTextureEXT;
+ glDeleteTexturesEXT: TglDeleteTexturesEXT;
+ glGenTexturesEXT: TglGenTexturesEXT;
+ glIsTextureEXT: TglIsTextureEXT;
+ glPrioritizeTexturesEXT: TglPrioritizeTexturesEXT;
+
+ // GL_EXT_texture_perturb_normal
+ glTextureNormalEXT: TglTextureNormalEXT;
+
+ // GL_EXT_vertex_array
+ glArrayElementEXT: TglArrayElementEXT;
+ glColorPointerEXT: TglColorPointerEXT;
+ glDrawArraysEXT: TglDrawArraysEXT;
+ glEdgeFlagPointerEXT: TglEdgeFlagPointerEXT;
+ glGetPointervEXT: TglGetPointervEXT;
+ glIndexPointerEXT: TglIndexPointerEXT;
+ glNormalPointerEXT: TglNormalPointerEXT;
+ glTexCoordPointerEXT: TglTexCoordPointerEXT;
+ glVertexPointerEXT: TglVertexPointerEXT;
+
+ // GL_EXT_vertex_shader
+ glBeginVertexShaderEXT: TglBeginVertexShaderEXT;
+ glEndVertexShaderEXT: TglEndVertexShaderEXT;
+ glBindVertexShaderEXT: TglBindVertexShaderEXT;
+ glGenVertexShadersEXT: TglGenVertexShadersEXT;
+ glDeleteVertexShaderEXT: TglDeleteVertexShaderEXT;
+ glShaderOp1EXT: TglShaderOp1EXT;
+ glShaderOp2EXT: TglShaderOp2EXT;
+ glShaderOp3EXT: TglShaderOp3EXT;
+ glSwizzleEXT: TglSwizzleEXT;
+ glWriteMaskEXT: TglWriteMaskEXT;
+ glInsertComponentEXT: TglInsertComponentEXT;
+ glExtractComponentEXT: TglExtractComponentEXT;
+ glGenSymbolsEXT: TglGenSymbolsEXT;
+ glSetInvariantEXT: TglSetInvariantEXT;
+ glSetLocalConstantEXT: TglSetLocalConstantEXT;
+ glVariantbvEXT: TglVariantbvEXT;
+ glVariantsvEXT: TglVariantsvEXT;
+ glVariantivEXT: TglVariantivEXT;
+ glVariantfvEXT: TglVariantfvEXT;
+ glVariantdvEXT: TglVariantdvEXT;
+ glVariantubvEXT: TglVariantubvEXT;
+ glVariantusvEXT: TglVariantusvEXT;
+ glVariantuivEXT: TglVariantuivEXT;
+ glVariantPointerEXT: TglVariantPointerEXT;
+ glEnableVariantClientStateEXT: TglEnableVariantClientStateEXT;
+ glDisableVariantClientStateEXT: TglDisableVariantClientStateEXT;
+ glBindLightParameterEXT: TglBindLightParameterEXT;
+ glBindMaterialParameterEXT: TglBindMaterialParameterEXT;
+ glBindTexGenParameterEXT: TglBindTexGenParameterEXT;
+ glBindTextureUnitParameterEXT: TglBindTextureUnitParameterEXT;
+ glBindParameterEXT: TglBindParameterEXT;
+ glIsVariantEnabledEXT: TglIsVariantEnabledEXT;
+ glGetVariantBooleanvEXT: TglGetVariantBooleanvEXT;
+ glGetVariantIntegervEXT: TglGetVariantIntegervEXT;
+ glGetVariantFloatvEXT: TglGetVariantFloatvEXT;
+ glGetVariantPointervEXT: TglGetVariantPointervEXT;
+ glGetInvariantBooleanvEXT: TglGetInvariantBooleanvEXT;
+ glGetInvariantIntegervEXT: TglGetInvariantIntegervEXT;
+ glGetInvariantFloatvEXT: TglGetInvariantFloatvEXT;
+ glGetLocalConstantBooleanvEXT: TglGetLocalConstantBooleanvEXT;
+ glGetLocalConstantIntegervEXT: TglGetLocalConstantIntegervEXT;
+ glGetLocalConstantFloatvEXT: TglGetLocalConstantFloatvEXT;
+
+ // GL_EXT_vertex_weighting
+ glVertexWeightfEXT: TglVertexWeightfEXT;
+ glVertexWeightfvEXT: TglVertexWeightfvEXT;
+ glVertexWeightPointerEXT: TglVertexWeightPointerEXT;
+
+ // GL_EXT_stencil_clear_tag
+ glStencilClearTagEXT: TglStencilClearTagEXT;
+
+ // GL_EXT_framebuffer_blit
+ glBlitFramebufferEXT: TglBlitFramebufferEXT;
+
+ // GL_EXT_framebuffer_multisample
+ glRenderbufferStorageMultisampleEXT: TglRenderbufferStorageMultisampleEXT;
+
+ // GL_EXT_timer_query
+ glGetQueryObjecti64vEXT: TglGetQueryObjecti64vEXT;
+ glGetQueryObjectui64vEXT: TglGetQueryObjectui64vEXT;
+
+ // GL_EXT_gpu_program_parameters
+ glProgramEnvParameters4fvEXT: TglProgramEnvParameters4fvEXT;
+ glProgramLocalParameters4fvEXT: TglProgramLocalParameters4fvEXT;
+
+ // GL_EXT_bindable_uniform
+ glUniformBufferEXT: TglUniformBufferEXT;
+ glGetUniformBufferSizeEXT: TglGetUniformBufferSizeEXT;
+ glGetUniformOffsetEXT: TglGetUniformOffsetEXT;
+
+ // GL_EXT_draw_buffers2
+ glColorMaskIndexedEXT: TglColorMaskIndexedEXT;
+ glGetBooleanIndexedvEXT: TglGetBooleanIndexedvEXT;
+ glGetIntegerIndexedvEXT: TglGetIntegerIndexedvEXT;
+ glEnableIndexedEXT: TglEnableIndexedEXT;
+ glDisableIndexedEXT: TglDisableIndexedEXT;
+ glIsEnabledIndexedEXT: TglIsEnabledIndexedEXT;
+
+ // GL_EXT_draw_instanced
+ glDrawArraysInstancedEXT: TglDrawArraysInstancedEXT;
+ glDrawElementsInstancedEXT: TglDrawElementsInstancedEXT;
+
+ // GL_EXT_geometry_shader4
+ glProgramParameteriEXT: TglProgramParameteriEXT;
+ glFramebufferTextureEXT: TglFramebufferTextureEXT;
+// glFramebufferTextureLayerEXT: TglFramebufferTextureLayerEXT;
+ glFramebufferTextureFaceEXT: TglFramebufferTextureFaceEXT;
+
+ // GL_EXT_gpu_shader4
+ glVertexAttribI1iEXT: TglVertexAttribI1iEXT;
+ glVertexAttribI2iEXT: TglVertexAttribI2iEXT;
+ glVertexAttribI3iEXT: TglVertexAttribI3iEXT;
+ glVertexAttribI4iEXT: TglVertexAttribI4iEXT;
+ glVertexAttribI1uiEXT: TglVertexAttribI1uiEXT;
+ glVertexAttribI2uiEXT: TglVertexAttribI2uiEXT;
+ glVertexAttribI3uiEXT: TglVertexAttribI3uiEXT;
+ glVertexAttribI4uiEXT: TglVertexAttribI4uiEXT;
+ glVertexAttribI1ivEXT: TglVertexAttribI1ivEXT;
+ glVertexAttribI2ivEXT: TglVertexAttribI2ivEXT;
+ glVertexAttribI3ivEXT: TglVertexAttribI3ivEXT;
+ glVertexAttribI4ivEXT: TglVertexAttribI4ivEXT;
+ glVertexAttribI1uivEXT: TglVertexAttribI1uivEXT;
+ glVertexAttribI2uivEXT: TglVertexAttribI2uivEXT;
+ glVertexAttribI3uivEXT: TglVertexAttribI3uivEXT;
+ glVertexAttribI4uivEXT: TglVertexAttribI4uivEXT;
+ glVertexAttribI4bvEXT: TglVertexAttribI4bvEXT;
+ glVertexAttribI4svEXT: TglVertexAttribI4svEXT;
+ glVertexAttribI4ubvEXT: TglVertexAttribI4ubvEXT;
+ glVertexAttribI4usvEXT: TglVertexAttribI4usvEXT;
+ glVertexAttribIPointerEXT: TglVertexAttribIPointerEXT;
+ glGetVertexAttribIivEXT: TglGetVertexAttribIivEXT;
+ glGetVertexAttribIuivEXT: TglGetVertexAttribIuivEXT;
+ glUniform1uiEXT: TglUniform1uiEXT;
+ glUniform2uiEXT: TglUniform2uiEXT;
+ glUniform3uiEXT: TglUniform3uiEXT;
+ glUniform4uiEXT: TglUniform4uiEXT;
+ glUniform1uivEXT: TglUniform1uivEXT;
+ glUniform2uivEXT: TglUniform2uivEXT;
+ glUniform3uivEXT: TglUniform3uivEXT;
+ glUniform4uivEXT: TglUniform4uivEXT;
+ glGetUniformuivEXT: TglGetUniformuivEXT;
+ glBindFragDataLocationEXT: TglBindFragDataLocationEXT;
+ glGetFragDataLocationEXT: TglGetFragDataLocationEXT;
+
+ // GL_EXT_texture_array
+ glFramebufferTextureLayerEXT: TglFramebufferTextureLayerEXT;
+
+ // GL_EXT_texture_buffer_object
+ glTexBufferEXT: TglTexBufferEXT;
+
+ // GL_EXT_texture_integer
+ glClearColorIiEXT: TglClearColorIiEXT;
+ glClearColorIuiEXT: TglClearColorIuiEXT;
+ glTexParameterIivEXT: TglTexParameterIivEXT;
+ glTexParameterIuivEXT: TglTexParameterIuivEXT;
+ glGetTexParameterIivEXT: TglGetTexParameterIivEXT;
+ glGetTexParameterIiuvEXT: TglGetTexParameterIiuvEXT;
+
+ // GL_EXT_transform_feedback
+ glBeginTransformFeedbackEXT: TglBeginTransformFeedbackEXT;
+ glEndTransformFeedbackEXT: TglEndTransformFeedbackEXT;
+ glBindBufferRangeEXT: TglBindBufferRangeEXT;
+ glBindBufferOffsetEXT: TglBindBufferOffsetEXT;
+ glBindBufferBaseEXT: TglBindBufferBaseEXT;
+ glTransformFeedbackVaryingsEXT: TglTransformFeedbackVaryingsEXT;
+ glGetTransformFeedbackVaryingEXT: TglGetTransformFeedbackVaryingEXT;
+
+ // GL_EXT_direct_state_access
+ glClientAttribDefaultEXT: TglClientAttribDefaultEXT;
+ glPushClientAttribDefaultEXT: TglPushClientAttribDefaultEXT;
+ glMatrixLoadfEXT: TglMatrixLoadfEXT;
+ glMatrixLoaddEXT: TglMatrixLoaddEXT;
+ glMatrixMultfEXT: TglMatrixMultfEXT;
+ glMatrixMultdEXT: TglMatrixMultdEXT;
+ glMatrixLoadIdentityEXT: TglMatrixLoadIdentityEXT;
+ glMatrixRotatefEXT: TglMatrixRotatefEXT;
+ glMatrixRotatedEXT: TglMatrixRotatedEXT;
+ glMatrixScalefEXT: TglMatrixScalefEXT;
+ glMatrixScaledEXT: TglMatrixScaledEXT;
+ glMatrixTranslatefEXT: TglMatrixTranslatefEXT;
+ glMatrixTranslatedEXT: TglMatrixTranslatedEXT;
+ glMatrixFrustumEXT: TglMatrixFrustumEXT;
+ glMatrixOrthoEXT: TglMatrixOrthoEXT;
+ glMatrixPopEXT: TglMatrixPopEXT;
+ glMatrixPushEXT: TglMatrixPushEXT;
+ glMatrixLoadTransposefEXT: TglMatrixLoadTransposefEXT;
+ glMatrixLoadTransposedEXT: TglMatrixLoadTransposedEXT;
+ glMatrixMultTransposefEXT: TglMatrixMultTransposefEXT;
+ glMatrixMultTransposedEXT: TglMatrixMultTransposedEXT;
+ glTextureParameterfEXT: TglTextureParameterfEXT;
+ glTextureParameterfvEXT: TglTextureParameterfvEXT;
+ glTextureParameteriEXT: TglTextureParameteriEXT;
+ glTextureParameterivEXT: TglTextureParameterivEXT;
+ glTextureImage1DEXT: TglTextureImage1DEXT;
+ glTextureImage2DEXT: TglTextureImage2DEXT;
+ glTextureSubImage1DEXT: TglTextureSubImage1DEXT;
+ glTextureSubImage2DEXT: TglTextureSubImage2DEXT;
+ glCopyTextureImage1DEXT: TglCopyTextureImage1DEXT;
+ glCopyTextureImage2DEXT: TglCopyTextureImage2DEXT;
+ glCopyTextureSubImage1DEXT: TglCopyTextureSubImage1DEXT;
+ glCopyTextureSubImage2DEXT: TglCopyTextureSubImage2DEXT;
+ glGetTextureImageEXT: TglGetTextureImageEXT;
+ glGetTextureParameterfvEXT: TglGetTextureParameterfvEXT;
+ glGetTextureParameterivEXT: TglGetTextureParameterivEXT;
+ glGetTextureLevelParameterfvEXT: TglGetTextureLevelParameterfvEXT;
+ glGetTextureLevelParameterivEXT: TglGetTextureLevelParameterivEXT;
+ glTextureImage3DEXT: TglTextureImage3DEXT;
+ glTextureSubImage3DEXT: TglTextureSubImage3DEXT;
+ glCopyTextureSubImage3DEXT: TglCopyTextureSubImage3DEXT;
+ glMultiTexParameterfEXT: TglMultiTexParameterfEXT;
+ glMultiTexParameterfvEXT: TglMultiTexParameterfvEXT;
+ glMultiTexParameteriEXT: TglMultiTexParameteriEXT;
+ glMultiTexParameterivEXT: TglMultiTexParameterivEXT;
+ glMultiTexImage1DEXT: TglMultiTexImage1DEXT;
+ glMultiTexImage2DEXT: TglMultiTexImage2DEXT;
+ glMultiTexSubImage1DEXT: TglMultiTexSubImage1DEXT;
+ glMultiTexSubImage2DEXT: TglMultiTexSubImage2DEXT;
+ glCopyMultiTexImage1DEXT: TglCopyMultiTexImage1DEXT;
+ glCopyMultiTexImage2DEXT: TglCopyMultiTexImage2DEXT;
+ glCopyMultiTexSubImage1DEXT: TglCopyMultiTexSubImage1DEXT;
+ glCopyMultiTexSubImage2DEXT: TglCopyMultiTexSubImage2DEXT;
+ glGetMultiTexImageEXT: TglGetMultiTexImageEXT;
+ glGetMultiTexParameterfvEXT: TglGetMultiTexParameterfvEXT;
+ glGetMultiTexParameterivEXT: TglGetMultiTexParameterivEXT;
+ glGetMultiTexLevelParameterfvEXT: TglGetMultiTexLevelParameterfvEXT;
+ glGetMultiTexLevelParameterivEXT: TglGetMultiTexLevelParameterivEXT;
+ glMultiTexImage3DEXT: TglMultiTexImage3DEXT;
+ glMultiTexSubImage3DEXT: TglMultiTexSubImage3DEXT;
+ glCopyMultiTexSubImage3DEXT: TglCopyMultiTexSubImage3DEXT;
+ glBindMultiTextureEXT: TglBindMultiTextureEXT;
+ glEnableClientStateIndexedEXT: TglEnableClientStateIndexedEXT;
+ glDisableClientStateIndexedEXT: TglDisableClientStateIndexedEXT;
+ glMultiTexCoordPointerEXT: TglMultiTexCoordPointerEXT;
+ glMultiTexEnvfEXT: TglMultiTexEnvfEXT;
+ glMultiTexEnvfvEXT: TglMultiTexEnvfvEXT;
+ glMultiTexEnviEXT: TglMultiTexEnviEXT;
+ glMultiTexEnvivEXT: TglMultiTexEnvivEXT;
+ glMultiTexGendEXT: TglMultiTexGendEXT;
+ glMultiTexGendvEXT: TglMultiTexGendvEXT;
+ glMultiTexGenfEXT: TglMultiTexGenfEXT;
+ glMultiTexGenfvEXT: TglMultiTexGenfvEXT;
+ glMultiTexGeniEXT: TglMultiTexGeniEXT;
+ glMultiTexGenivEXT: TglMultiTexGenivEXT;
+ glGetMultiTexEnvfvEXT: TglGetMultiTexEnvfvEXT;
+ glGetMultiTexEnvivEXT: TglGetMultiTexEnvivEXT;
+ glGetMultiTexGendvEXT: TglGetMultiTexGendvEXT;
+ glGetMultiTexGenfvEXT: TglGetMultiTexGenfvEXT;
+ glGetMultiTexGenivEXT: TglGetMultiTexGenivEXT;
+ glGetFloatIndexedvEXT: TglGetFloatIndexedvEXT;
+ glGetDoubleIndexedvEXT: TglGetDoubleIndexedvEXT;
+ glGetPointerIndexedvEXT: TglGetPointerIndexedvEXT;
+ glCompressedTextureImage3DEXT: TglCompressedTextureImage3DEXT;
+ glCompressedTextureImage2DEXT: TglCompressedTextureImage2DEXT;
+ glCompressedTextureImage1DEXT: TglCompressedTextureImage1DEXT;
+ glCompressedTextureSubImage3DEXT: TglCompressedTextureSubImage3DEXT;
+ glCompressedTextureSubImage2DEXT: TglCompressedTextureSubImage2DEXT;
+ glCompressedTextureSubImage1DEXT: TglCompressedTextureSubImage1DEXT;
+ glGetCompressedTextureImageEXT: TglGetCompressedTextureImageEXT;
+ glCompressedMultiTexImage3DEXT: TglCompressedMultiTexImage3DEXT;
+ glCompressedMultiTexImage2DEXT: TglCompressedMultiTexImage2DEXT;
+ glCompressedMultiTexImage1DEXT: TglCompressedMultiTexImage1DEXT;
+ glCompressedMultiTexSubImage3DEXT: TglCompressedMultiTexSubImage3DEXT;
+ glCompressedMultiTexSubImage2DEXT: TglCompressedMultiTexSubImage2DEXT;
+ glCompressedMultiTexSubImage1DEXT: TglCompressedMultiTexSubImage1DEXT;
+ glGetCompressedMultiTexImageEXT: TglGetCompressedMultiTexImageEXT;
+ glNamedProgramStringEXT: TglNamedProgramStringEXT;
+ glNamedProgramLocalParameter4dEXT: TglNamedProgramLocalParameter4dEXT;
+ glNamedProgramLocalParameter4dvEXT: TglNamedProgramLocalParameter4dvEXT;
+ glNamedProgramLocalParameter4fEXT: TglNamedProgramLocalParameter4fEXT;
+ glNamedProgramLocalParameter4fvEXT: TglNamedProgramLocalParameter4fvEXT;
+ glGetNamedProgramLocalParameterdvEXT: TglGetNamedProgramLocalParameterdvEXT;
+ glGetNamedProgramLocalParameterfvEXT: TglGetNamedProgramLocalParameterfvEXT;
+ glGetNamedProgramivEXT: TglGetNamedProgramivEXT;
+ glGetNamedProgramStringEXT: TglGetNamedProgramStringEXT;
+ glNamedProgramLocalParameters4fvEXT: TglNamedProgramLocalParameters4fvEXT;
+ glNamedProgramLocalParameterI4iEXT: TglNamedProgramLocalParameterI4iEXT;
+ glNamedProgramLocalParameterI4ivEXT: TglNamedProgramLocalParameterI4ivEXT;
+ glNamedProgramLocalParametersI4ivEXT: TglNamedProgramLocalParametersI4ivEXT;
+ glNamedProgramLocalParameterI4uiEXT: TglNamedProgramLocalParameterI4uiEXT;
+ glNamedProgramLocalParameterI4uivEXT: TglNamedProgramLocalParameterI4uivEXT;
+ glNamedProgramLocalParametersI4uivEXT: TglNamedProgramLocalParametersI4uivEXT;
+ glGetNamedProgramLocalParameterIivEXT: TglGetNamedProgramLocalParameterIivEXT;
+ glGetNamedProgramLocalParameterIuivEXT: TglGetNamedProgramLocalParameterIuivEXT;
+ glTextureParameterIivEXT: TglTextureParameterIivEXT;
+ glTextureParameterIuivEXT: TglTextureParameterIuivEXT;
+ glGetTextureParameterIivEXT: TglGetTextureParameterIivEXT;
+ glGetTextureParameterIuivEXT: TglGetTextureParameterIuivEXT;
+ glMultiTexParameterIivEXT: TglMultiTexParameterIivEXT;
+ glMultiTexParameterIuivEXT: TglMultiTexParameterIuivEXT;
+ glGetMultiTexParameterIivEXT: TglGetMultiTexParameterIivEXT;
+ glGetMultiTexParameterIuivEXT: TglGetMultiTexParameterIuivEXT;
+ glProgramUniform1fEXT: TglProgramUniform1fEXT;
+ glProgramUniform2fEXT: TglProgramUniform2fEXT;
+ glProgramUniform3fEXT: TglProgramUniform3fEXT;
+ glProgramUniform4fEXT: TglProgramUniform4fEXT;
+ glProgramUniform1iEXT: TglProgramUniform1iEXT;
+ glProgramUniform2iEXT: TglProgramUniform2iEXT;
+ glProgramUniform3iEXT: TglProgramUniform3iEXT;
+ glProgramUniform4iEXT: TglProgramUniform4iEXT;
+ glProgramUniform1fvEXT: TglProgramUniform1fvEXT;
+ glProgramUniform2fvEXT: TglProgramUniform2fvEXT;
+ glProgramUniform3fvEXT: TglProgramUniform3fvEXT;
+ glProgramUniform4fvEXT: TglProgramUniform4fvEXT;
+ glProgramUniform1ivEXT: TglProgramUniform1ivEXT;
+ glProgramUniform2ivEXT: TglProgramUniform2ivEXT;
+ glProgramUniform3ivEXT: TglProgramUniform3ivEXT;
+ glProgramUniform4ivEXT: TglProgramUniform4ivEXT;
+ glProgramUniformMatrix2fvEXT: TglProgramUniformMatrix2fvEXT;
+ glProgramUniformMatrix3fvEXT: TglProgramUniformMatrix3fvEXT;
+ glProgramUniformMatrix4fvEXT: TglProgramUniformMatrix4fvEXT;
+ glProgramUniformMatrix2x3fvEXT: TglProgramUniformMatrix2x3fvEXT;
+ glProgramUniformMatrix3x2fvEXT: TglProgramUniformMatrix3x2fvEXT;
+ glProgramUniformMatrix2x4fvEXT: TglProgramUniformMatrix2x4fvEXT;
+ glProgramUniformMatrix4x2fvEXT: TglProgramUniformMatrix4x2fvEXT;
+ glProgramUniformMatrix3x4fvEXT: TglProgramUniformMatrix3x4fvEXT;
+ glProgramUniformMatrix4x3fvEXT: TglProgramUniformMatrix4x3fvEXT;
+ glProgramUniform1uiEXT: TglProgramUniform1uiEXT;
+ glProgramUniform2uiEXT: TglProgramUniform2uiEXT;
+ glProgramUniform3uiEXT: TglProgramUniform3uiEXT;
+ glProgramUniform4uiEXT: TglProgramUniform4uiEXT;
+ glProgramUniform1uivEXT: TglProgramUniform1uivEXT;
+ glProgramUniform2uivEXT: TglProgramUniform2uivEXT;
+ glProgramUniform3uivEXT: TglProgramUniform3uivEXT;
+ glProgramUniform4uivEXT: TglProgramUniform4uivEXT;
+ glNamedBufferDataEXT: TglNamedBufferDataEXT;
+ glNamedBufferSubDataEXT: TglNamedBufferSubDataEXT;
+ glMapNamedBufferEXT: TglMapNamedBufferEXT;
+ glUnmapNamedBufferEXT: TglUnmapNamedBufferEXT;
+ glMapNamedBufferRangeEXT: TglMapNamedBufferRangeEXT;
+ glFlushMappedNamedBufferRangeEXT: TglFlushMappedNamedBufferRangeEXT;
+ glNamedCopyBufferSubDataEXT: TglNamedCopyBufferSubDataEXT;
+ glGetNamedBufferParameterivEXT: TglGetNamedBufferParameterivEXT;
+ glGetNamedBufferPointervEXT: TglGetNamedBufferPointervEXT;
+ glGetNamedBufferSubDataEXT: TglGetNamedBufferSubDataEXT;
+ glTextureBufferEXT: TglTextureBufferEXT;
+ glMultiTexBufferEXT: TglMultiTexBufferEXT;
+ glNamedRenderbufferStorageEXT: TglNamedRenderbufferStorageEXT;
+ glGetNamedRenderbufferParameterivEXT: TglGetNamedRenderbufferParameterivEXT;
+ glCheckNamedFramebufferStatusEXT: TglCheckNamedFramebufferStatusEXT;
+ glNamedFramebufferTexture1DEXT: TglNamedFramebufferTexture1DEXT;
+ glNamedFramebufferTexture2DEXT: TglNamedFramebufferTexture2DEXT;
+ glNamedFramebufferTexture3DEXT: TglNamedFramebufferTexture3DEXT;
+ glNamedFramebufferRenderbufferEXT: TglNamedFramebufferRenderbufferEXT;
+ glGetNamedFramebufferAttachmentParameterivEXT: TglGetNamedFramebufferAttachmentParameterivEXT;
+ glGenerateTextureMipmapEXT: TglGenerateTextureMipmapEXT;
+ glGenerateMultiTexMipmapEXT: TglGenerateMultiTexMipmapEXT;
+ glFramebufferDrawBufferEXT: TglFramebufferDrawBufferEXT;
+ glFramebufferDrawBuffersEXT: TglFramebufferDrawBuffersEXT;
+ glFramebufferReadBufferEXT: TglFramebufferReadBufferEXT;
+ glGetFramebufferParameterivEXT: TglGetFramebufferParameterivEXT;
+ glNamedRenderbufferStorageMultisampleEXT: TglNamedRenderbufferStorageMultisampleEXT;
+ glNamedRenderbufferStorageMultisampleCoverageEXT: TglNamedRenderbufferStorageMultisampleCoverageEXT;
+ glNamedFramebufferTextureEXT: TglNamedFramebufferTextureEXT;
+ glNamedFramebufferTextureLayerEXT: TglNamedFramebufferTextureLayerEXT;
+ glNamedFramebufferTextureFaceEXT: TglNamedFramebufferTextureFaceEXT;
+ glTextureRenderbufferEXT: TglTextureRenderbufferEXT;
+ glMultiTexRenderbufferEXT: TglMultiTexRenderbufferEXT;
+ glProgramUniform1dEXT: TglProgramUniform1dEXT;
+ glProgramUniform2dEXT: TglProgramUniform2dEXT;
+ glProgramUniform3dEXT: TglProgramUniform3dEXT;
+ glProgramUniform4dEXT: TglProgramUniform4dEXT;
+ glProgramUniform1dvEXT: TglProgramUniform1dvEXT;
+ glProgramUniform2dvEXT: TglProgramUniform2dvEXT;
+ glProgramUniform3dvEXT: TglProgramUniform3dvEXT;
+ glProgramUniform4dvEXT: TglProgramUniform4dvEXT;
+ glProgramUniformMatrix2dvEXT: TglProgramUniformMatrix2dvEXT;
+ glProgramUniformMatrix3dvEXT: TglProgramUniformMatrix3dvEXT;
+ glProgramUniformMatrix4dvEXT: TglProgramUniformMatrix4dvEXT;
+ glProgramUniformMatrix2x3dvEXT: TglProgramUniformMatrix2x3dvEXT;
+ glProgramUniformMatrix2x4dvEXT: TglProgramUniformMatrix2x4dvEXT;
+ glProgramUniformMatrix3x2dvEXT: TglProgramUniformMatrix3x2dvEXT;
+ glProgramUniformMatrix3x4dvEXT: TglProgramUniformMatrix3x4dvEXT;
+ glProgramUniformMatrix4x2dvEXT: TglProgramUniformMatrix4x2dvEXT;
+ glProgramUniformMatrix4x3dvEXT: TglProgramUniformMatrix4x3dvEXT;
+
+ // GL_EXT_separate_shader_objects
+ glUseShaderProgramEXT: TglUseShaderProgramEXT;
+ glActiveProgramEXT: TglActiveProgramEXT;
+ glCreateShaderProgramEXT: TglCreateShaderProgramEXT;
+
+ // GL_EXT_shader_image_load_store
+ glBindImageTextureEXT: TglBindImageTextureEXT;
+ glMemoryBarrierEXT: TglMemoryBarrierEXT;
+
+ // GL_EXT_vertex_attrib_64bit
+ glVertexAttribL1dEXT: TglVertexAttribL1dEXT;
+ glVertexAttribL2dEXT: TglVertexAttribL2dEXT;
+ glVertexAttribL3dEXT: TglVertexAttribL3dEXT;
+ glVertexAttribL4dEXT: TglVertexAttribL4dEXT;
+ glVertexAttribL1dvEXT: TglVertexAttribL1dvEXT;
+ glVertexAttribL2dvEXT: TglVertexAttribL2dvEXT;
+ glVertexAttribL3dvEXT: TglVertexAttribL3dvEXT;
+ glVertexAttribL4dvEXT: TglVertexAttribL4dvEXT;
+ glVertexAttribLPointerEXT: TglVertexAttribLPointerEXT;
+ glGetVertexAttribLdvEXT: TglGetVertexAttribLdvEXT;
+ glVertexArrayVertexAttribLOffsetEXT: TglVertexArrayVertexAttribLOffsetEXT;
+
+ // GL_HP_image_transform
+ glImageTransformParameteriHP: TglImageTransformParameteriHP;
+ glImageTransformParameterfHP: TglImageTransformParameterfHP;
+ glImageTransformParameterivHP: TglImageTransformParameterivHP;
+ glImageTransformParameterfvHP: TglImageTransformParameterfvHP;
+ glGetImageTransformParameterivHP: TglGetImageTransformParameterivHP;
+ glGetImageTransformParameterfvHP: TglGetImageTransformParameterfvHP;
+
+ // GL_EXT_depth_bounds_test
+ glDepthBoundsEXT: TglDepthBoundsEXT;
+
+ // GL_EXT_blend_equation_separate
+ glBlendEquationSeparateEXT: TglBlendEquationSeparateEXT;
+
+ // GL_IBM_multimode_draw_arrays
+ glMultiModeDrawArraysIBM: TglMultiModeDrawArraysIBM;
+ glMultiModeDrawElementsIBM: TglMultiModeDrawElementsIBM;
+
+ // GL_IBM_vertex_array_lists
+ glColorPointerListIBM: TglColorPointerListIBM;
+ glSecondaryColorPointerListIBM: TglSecondaryColorPointerListIBM;
+ glEdgeFlagPointerListIBM: TglEdgeFlagPointerListIBM;
+ glFogCoordPointerListIBM: TglFogCoordPointerListIBM;
+ glIndexPointerListIBM: TglIndexPointerListIBM;
+ glNormalPointerListIBM: TglNormalPointerListIBM;
+ glTexCoordPointerListIBM: TglTexCoordPointerListIBM;
+ glVertexPointerListIBM: TglVertexPointerListIBM;
+
+ // GL_INGR_blend_func_separate
+ glBlendFuncSeparateINGR: TglBlendFuncSeparateINGR;
+
+ // GL_INTEL_framebuffer_CMAA
+ glApplyFramebufferAttachmentCMAAINTEL : TglApplyFramebufferAttachmentCMAAINTEL;
+
+ // GL_INTEL_parallel_arrays
+ glVertexPointervINTEL: TglVertexPointervINTEL;
+ glNormalPointervINTEL: TglNormalPointervINTEL;
+ glColorPointervINTEL: TglColorPointervINTEL;
+ glTexCoordPointervINTEL: TglTexCoordPointervINTEL;
+
+ // GL_MESA_resize_buffers
+ glResizeBuffersMESA: TglResizeBuffersMESA;
+
+ // GL_MESA_window_pos
+ glWindowPos2dMESA: TglWindowPos2dMESA;
+ glWindowPos2dvMESA: TglWindowPos2dvMESA;
+ glWindowPos2fMESA: TglWindowPos2fMESA;
+ glWindowPos2fvMESA: TglWindowPos2fvMESA;
+ glWindowPos2iMESA: TglWindowPos2iMESA;
+ glWindowPos2ivMESA: TglWindowPos2ivMESA;
+ glWindowPos2sMESA: TglWindowPos2sMESA;
+ glWindowPos2svMESA: TglWindowPos2svMESA;
+ glWindowPos3dMESA: TglWindowPos3dMESA;
+ glWindowPos3dvMESA: TglWindowPos3dvMESA;
+ glWindowPos3fMESA: TglWindowPos3fMESA;
+ glWindowPos3fvMESA: TglWindowPos3fvMESA;
+ glWindowPos3iMESA: TglWindowPos3iMESA;
+ glWindowPos3ivMESA: TglWindowPos3ivMESA;
+ glWindowPos3sMESA: TglWindowPos3sMESA;
+ glWindowPos3svMESA: TglWindowPos3svMESA;
+ glWindowPos4dMESA: TglWindowPos4dMESA;
+ glWindowPos4dvMESA: TglWindowPos4dvMESA;
+ glWindowPos4fMESA: TglWindowPos4fMESA;
+ glWindowPos4fvMESA: TglWindowPos4fvMESA;
+ glWindowPos4iMESA: TglWindowPos4iMESA;
+ glWindowPos4ivMESA: TglWindowPos4ivMESA;
+ glWindowPos4sMESA: TglWindowPos4sMESA;
+ glWindowPos4svMESA: TglWindowPos4svMESA;
+
+ // GL_NV_evaluators
+ glMapControlPointsNV: TglMapControlPointsNV;
+ glMapParameterivNV: TglMapParameterivNV;
+ glMapParameterfvNV: TglMapParameterfvNV;
+ glGetMapControlPointsNV: TglGetMapControlPointsNV;
+ glGetMapParameterivNV: TglGetMapParameterivNV;
+ glGetMapParameterfvNV: TglGetMapParameterfvNV;
+ glGetMapAttribParameterivNV: TglGetMapAttribParameterivNV;
+ glGetMapAttribParameterfvNV: TglGetMapAttribParameterfvNV;
+ glEvalMapsNV: TglEvalMapsNV;
+
+ // GL_NV_fence
+ glDeleteFencesNV: TglDeleteFencesNV;
+ glGenFencesNV: TglGenFencesNV;
+ glIsFenceNV: TglIsFenceNV;
+ glTestFenceNV: TglTestFenceNV;
+ glGetFenceivNV: TglGetFenceivNV;
+ glFinishFenceNV: TglFinishFenceNV;
+ glSetFenceNV: TglSetFenceNV;
+
+ // GL_NV_fragment_program
+ glProgramNamedParameter4fNV: TglProgramNamedParameter4fNV;
+ glProgramNamedParameter4dNV: TglProgramNamedParameter4dNV;
+ glProgramNamedParameter4fvNV: TglProgramNamedParameter4fvNV;
+ glProgramNamedParameter4dvNV: TglProgramNamedParameter4dvNV;
+ glGetProgramNamedParameterfvNV: TglGetProgramNamedParameterfvNV;
+ glGetProgramNamedParameterdvNV: TglGetProgramNamedParameterdvNV;
+
+ // GL_NV_half_float
+ glVertex2hNV: TglVertex2hNV;
+ glVertex2hvNV: TglVertex2hvNV;
+ glVertex3hNV: TglVertex3hNV;
+ glVertex3hvNV: TglVertex3hvNV;
+ glVertex4hNV: TglVertex4hNV;
+ glVertex4hvNV: TglVertex4hvNV;
+ glNormal3hNV: TglNormal3hNV;
+ glNormal3hvNV: TglNormal3hvNV;
+ glColor3hNV: TglColor3hNV;
+ glColor3hvNV: TglColor3hvNV;
+ glColor4hNV: TglColor4hNV;
+ glColor4hvNV: TglColor4hvNV;
+ glTexCoord1hNV: TglTexCoord1hNV;
+ glTexCoord1hvNV: TglTexCoord1hvNV;
+ glTexCoord2hNV: TglTexCoord2hNV;
+ glTexCoord2hvNV: TglTexCoord2hvNV;
+ glTexCoord3hNV: TglTexCoord3hNV;
+ glTexCoord3hvNV: TglTexCoord3hvNV;
+ glTexCoord4hNV: TglTexCoord4hNV;
+ glTexCoord4hvNV: TglTexCoord4hvNV;
+ glMultiTexCoord1hNV: TglMultiTexCoord1hNV;
+ glMultiTexCoord1hvNV: TglMultiTexCoord1hvNV;
+ glMultiTexCoord2hNV: TglMultiTexCoord2hNV;
+ glMultiTexCoord2hvNV: TglMultiTexCoord2hvNV;
+ glMultiTexCoord3hNV: TglMultiTexCoord3hNV;
+ glMultiTexCoord3hvNV: TglMultiTexCoord3hvNV;
+ glMultiTexCoord4hNV: TglMultiTexCoord4hNV;
+ glMultiTexCoord4hvNV: TglMultiTexCoord4hvNV;
+ glFogCoordhNV: TglFogCoordhNV;
+ glFogCoordhvNV: TglFogCoordhvNV;
+ glSecondaryColor3hNV: TglSecondaryColor3hNV;
+ glSecondaryColor3hvNV: TglSecondaryColor3hvNV;
+ glVertexWeighthNV: TglVertexWeighthNV;
+ glVertexWeighthvNV: TglVertexWeighthvNV;
+ glVertexAttrib1hNV: TglVertexAttrib1hNV;
+ glVertexAttrib1hvNV: TglVertexAttrib1hvNV;
+ glVertexAttrib2hNV: TglVertexAttrib2hNV;
+ glVertexAttrib2hvNV: TglVertexAttrib2hvNV;
+ glVertexAttrib3hNV: TglVertexAttrib3hNV;
+ glVertexAttrib3hvNV: TglVertexAttrib3hvNV;
+ glVertexAttrib4hNV: TglVertexAttrib4hNV;
+ glVertexAttrib4hvNV: TglVertexAttrib4hvNV;
+ glVertexAttribs1hvNV: TglVertexAttribs1hvNV;
+ glVertexAttribs2hvNV: TglVertexAttribs2hvNV;
+ glVertexAttribs3hvNV: TglVertexAttribs3hvNV;
+ glVertexAttribs4hvNV: TglVertexAttribs4hvNV;
+
+ // GL_NV_occlusion_query
+ glGenOcclusionQueriesNV: TglGenOcclusionQueriesNV;
+ glDeleteOcclusionQueriesNV: TglDeleteOcclusionQueriesNV;
+ glIsOcclusionQueryNV: TglIsOcclusionQueryNV;
+ glBeginOcclusionQueryNV: TglBeginOcclusionQueryNV;
+ glEndOcclusionQueryNV: TglEndOcclusionQueryNV;
+ glGetOcclusionQueryivNV: TglGetOcclusionQueryivNV;
+ glGetOcclusionQueryuivNV: TglGetOcclusionQueryuivNV;
+
+ // GL_NV_pixel_data_range
+ glPixelDataRangeNV: TglPixelDataRangeNV;
+ glFlushPixelDataRangeNV: TglFlushPixelDataRangeNV;
+
+ // GL_NV_point_sprite
+ glPointParameteriNV: TglPointParameteriNV;
+ glPointParameterivNV: TglPointParameterivNV;
+
+ // GL_NV_primitive_restart
+ glPrimitiveRestartNV: TglPrimitiveRestartNV;
+ glPrimitiveRestartIndexNV: TglPrimitiveRestartIndexNV;
+
+ // GL_NV_register_combiners
+ glCombinerParameterfvNV: TglCombinerParameterfvNV;
+ glCombinerParameterfNV: TglCombinerParameterfNV;
+ glCombinerParameterivNV: TglCombinerParameterivNV;
+ glCombinerParameteriNV: TglCombinerParameteriNV;
+ glCombinerInputNV: TglCombinerInputNV;
+ glCombinerOutputNV: TglCombinerOutputNV;
+ glFinalCombinerInputNV: TglFinalCombinerInputNV;
+ glGetCombinerInputParameterfvNV: TglGetCombinerInputParameterfvNV;
+ glGetCombinerInputParameterivNV: TglGetCombinerInputParameterivNV;
+ glGetCombinerOutputParameterfvNV: TglGetCombinerOutputParameterfvNV;
+ glGetCombinerOutputParameterivNV: TglGetCombinerOutputParameterivNV;
+ glGetFinalCombinerInputParameterfvNV: TglGetFinalCombinerInputParameterfvNV;
+ glGetFinalCombinerInputParameterivNV: TglGetFinalCombinerInputParameterivNV;
+
+ // GL_NV_register_combiners2
+ glCombinerStageParameterfvNV: TglCombinerStageParameterfvNV;
+ glGetCombinerStageParameterfvNV: TglGetCombinerStageParameterfvNV;
+
+ // GL_NV_vertex_array_range
+ glFlushVertexArrayRangeNV: TglFlushVertexArrayRangeNV;
+ glVertexArrayRangeNV: TglVertexArrayRangeNV;
+
+ // GL_NV_vertex_program
+ glAreProgramsResidentNV: TglAreProgramsResidentNV;
+ glBindProgramNV: TglBindProgramNV;
+ glDeleteProgramsNV: TglDeleteProgramsNV;
+ glExecuteProgramNV: TglExecuteProgramNV;
+ glGenProgramsNV: TglGenProgramsNV;
+ glGetProgramParameterdvNV: TglGetProgramParameterdvNV;
+ glGetProgramParameterfvNV: TglGetProgramParameterfvNV;
+ glGetProgramivNV: TglGetProgramivNV;
+ glGetProgramStringNV: TglGetProgramStringNV;
+ glGetTrackMatrixivNV: TglGetTrackMatrixivNV;
+ glGetVertexAttribdvNV: TglGetVertexAttribdvNV;
+ glGetVertexAttribfvNV: TglGetVertexAttribfvNV;
+ glGetVertexAttribivNV: TglGetVertexAttribivNV;
+ glGetVertexAttribPointervNV: TglGetVertexAttribPointervNV;
+ glIsProgramNV: TglIsProgramNV;
+ glLoadProgramNV: TglLoadProgramNV;
+ glProgramParameter4dNV: TglProgramParameter4dNV;
+ glProgramParameter4dvNV: TglProgramParameter4dvNV;
+ glProgramParameter4fNV: TglProgramParameter4fNV;
+ glProgramParameter4fvNV: TglProgramParameter4fvNV;
+ glProgramParameters4dvNV: TglProgramParameters4dvNV;
+ glProgramParameters4fvNV: TglProgramParameters4fvNV;
+ glRequestResidentProgramsNV: TglRequestResidentProgramsNV;
+ glTrackMatrixNV: TglTrackMatrixNV;
+ glVertexAttribPointerNV: TglVertexAttribPointerNV;
+ glVertexAttrib1dNV: TglVertexAttrib1dNV;
+ glVertexAttrib1dvNV: TglVertexAttrib1dvNV;
+ glVertexAttrib1fNV: TglVertexAttrib1fNV;
+ glVertexAttrib1fvNV: TglVertexAttrib1fvNV;
+ glVertexAttrib1sNV: TglVertexAttrib1sNV;
+ glVertexAttrib1svNV: TglVertexAttrib1svNV;
+ glVertexAttrib2dNV: TglVertexAttrib2dNV;
+ glVertexAttrib2dvNV: TglVertexAttrib2dvNV;
+ glVertexAttrib2fNV: TglVertexAttrib2fNV;
+ glVertexAttrib2fvNV: TglVertexAttrib2fvNV;
+ glVertexAttrib2sNV: TglVertexAttrib2sNV;
+ glVertexAttrib2svNV: TglVertexAttrib2svNV;
+ glVertexAttrib3dNV: TglVertexAttrib3dNV;
+ glVertexAttrib3dvNV: TglVertexAttrib3dvNV;
+ glVertexAttrib3fNV: TglVertexAttrib3fNV;
+ glVertexAttrib3fvNV: TglVertexAttrib3fvNV;
+ glVertexAttrib3sNV: TglVertexAttrib3sNV;
+ glVertexAttrib3svNV: TglVertexAttrib3svNV;
+ glVertexAttrib4dNV: TglVertexAttrib4dNV;
+ glVertexAttrib4dvNV: TglVertexAttrib4dvNV;
+ glVertexAttrib4fNV: TglVertexAttrib4fNV;
+ glVertexAttrib4fvNV: TglVertexAttrib4fvNV;
+ glVertexAttrib4sNV: TglVertexAttrib4sNV;
+ glVertexAttrib4svNV: TglVertexAttrib4svNV;
+ glVertexAttrib4ubNV: TglVertexAttrib4ubNV;
+ glVertexAttrib4ubvNV: TglVertexAttrib4ubvNV;
+ glVertexAttribs1dvNV: TglVertexAttribs1dvNV;
+ glVertexAttribs1fvNV: TglVertexAttribs1fvNV;
+ glVertexAttribs1svNV: TglVertexAttribs1svNV;
+ glVertexAttribs2dvNV: TglVertexAttribs2dvNV;
+ glVertexAttribs2fvNV: TglVertexAttribs2fvNV;
+ glVertexAttribs2svNV: TglVertexAttribs2svNV;
+ glVertexAttribs3dvNV: TglVertexAttribs3dvNV;
+ glVertexAttribs3fvNV: TglVertexAttribs3fvNV;
+ glVertexAttribs3svNV: TglVertexAttribs3svNV;
+ glVertexAttribs4dvNV: TglVertexAttribs4dvNV;
+ glVertexAttribs4fvNV: TglVertexAttribs4fvNV;
+ glVertexAttribs4svNV: TglVertexAttribs4svNV;
+ glVertexAttribs4ubvNV: TglVertexAttribs4ubvNV;
+
+ // GL_NV_depth_buffer_float
+ glDepthRangedNV: TglDepthRangedNV;
+ glClearDepthdNV: TglClearDepthdNV;
+ glDepthBoundsdNV: TglDepthBoundsdNV;
+
+ // GL_NV_framebuffer_multisample_coverage
+ glRenderbufferStorageMultsampleCoverageNV: TglRenderbufferStorageMultsampleCoverageNV;
+
+ // GL_NV_geometry_program4
+ glProgramVertexLimitNV: TglProgramVertexLimitNV;
+
+ // GL_NV_gpu_program4
+ glProgramLocalParameterI4iNV: TglProgramLocalParameterI4iNV;
+ glProgramLocalParameterI4ivNV: TglProgramLocalParameterI4ivNV;
+ glProgramLocalParametersI4ivNV: TglProgramLocalParametersI4ivNV;
+ glProgramLocalParameterI4uiNV: TglProgramLocalParameterI4uiNV;
+ glProgramLocalParameterI4uivNV: TglProgramLocalParameterI4uivNV;
+ glProgramLocalParametersI4uivNV: TglProgramLocalParametersI4uivNV;
+ glProgramEnvParameterI4iNV: TglProgramEnvParameterI4iNV;
+ glProgramEnvParameterI4ivNV: TglProgramEnvParameterI4ivNV;
+ glProgramEnvParametersI4ivNV: TglProgramEnvParametersI4ivNV;
+ glProgramEnvParameterI4uiNV: TglProgramEnvParameterI4uiNV;
+ glProgramEnvParameterI4uivNV: TglProgramEnvParameterI4uivNV;
+ glProgramEnvParametersI4uivNV: TglProgramEnvParametersI4uivNV;
+ glGetProgramLocalParameterIivNV: TglGetProgramLocalParameterIivNV;
+ glGetProgramLocalParameterIuivNV: TglGetProgramLocalParameterIuivNV;
+ glGetProgramEnvParameterIivNV: TglGetProgramEnvParameterIivNV;
+ glGetProgramEnvParameterIuivNV: TglGetProgramEnvParameterIuivNV;
+
+ // GL_NV_parameter_buffer_object
+ glProgramBufferParametersfvNV: TglProgramBufferParametersfvNV;
+ glProgramBufferParametersIivNV: TglProgramBufferParametersIivNV;
+ glProgramBufferParametersIuivNV: TglProgramBufferParametersIuivNV;
+
+ // GL_NV_transform_feedback
+ glBeginTransformFeedbackNV: TglBeginTransformFeedbackNV;
+ glEndTransformFeedbackNV: TglEndTransformFeedbackNV;
+ glTransformFeedbackAttribsNV: TglTransformFeedbackAttribsNV;
+ glBindBufferRangeNV: TglBindBufferRangeNV;
+ glBindBufferOffsetNV: TglBindBufferOffsetNV;
+ glBindBufferBaseNV: TglBindBufferBaseNV;
+ glTransformFeedbackVaryingsNV: TglTransformFeedbackVaryingsNV;
+ glActiveVaryingNV: TglActiveVaryingNV;
+ glGetVaryingLocationNV: TglGetVaryingLocationNV;
+ glGetActiveVaryingNV: TglGetActiveVaryingNV;
+ glGetTransformFeedbackVaryingNV: TglGetTransformFeedbackVaryingNV;
+ glTransformFeedbackStreamAttribsNV: TglTransformFeedbackStreamAttribsNV;
+
+ // GL_NV_conditional_render
+ glBeginConditionalRenderNV: TglBeginConditionalRenderNV;
+ glEndConditionalRenderNV: TglEndConditionalRenderNV;
+
+ // GL_NV_conservative_raster
+ glSubpixelPrecisionBiasNV : TglSubpixelPrecisionBiasNV;
+
+ // GL_NV_conservative_raster_dilate
+ glConservativeRasterParameterfNV : TglConservativeRasterParameterfNV;
+
+ // GL_NV_present_video
+ glPresentFrameKeyedNV: TglPresentFrameKeyedNV;
+ glPresentFrameDualFillNV: TglPresentFrameDualFillNV;
+ glGetVideoivNV: TglGetVideoivNV;
+ glGetVideouivNV: TglGetVideouivNV;
+ glGetVideoi64vNV: TglGetVideoi64vNV;
+ glGetVideoui64vNV: TglGetVideoui64vNV;
+// glVideoParameterivNV: TglVideoParameterivNV;
+
+ // GL_NV_explicit_multisample
+ glGetMultisamplefvNV: TglGetMultisamplefvNV;
+ glSampleMaskIndexedNV: TglSampleMaskIndexedNV;
+ glTexRenderbufferNV: TglTexRenderbufferNV;
+
+ // GL_NV_transform_feedback2
+ glBindTransformFeedbackNV: TglBindTransformFeedbackNV;
+ glDeleteTransformFeedbacksNV: TglDeleteTransformFeedbacksNV;
+ glGenTransformFeedbacksNV: TglGenTransformFeedbacksNV;
+ glIsTransformFeedbackNV: TglIsTransformFeedbackNV;
+ glPauseTransformFeedbackNV: TglPauseTransformFeedbackNV;
+ glResumeTransformFeedbackNV: TglResumeTransformFeedbackNV;
+ glDrawTransformFeedbackNV: TglDrawTransformFeedbackNV;
+
+ // GL_NV_video_capture
+ glBeginVideoCaptureNV: TglBeginVideoCaptureNV;
+ glBindVideoCaptureStreamBufferNV: TglBindVideoCaptureStreamBufferNV;
+ glBindVideoCaptureStreamTextureNV: TglBindVideoCaptureStreamTextureNV;
+ glEndVideoCaptureNV: TglEndVideoCaptureNV;
+ glGetVideoCaptureivNV: TglGetVideoCaptureivNV;
+ glGetVideoCaptureStreamivNV: TglGetVideoCaptureStreamivNV;
+ glGetVideoCaptureStreamfvNV: TglGetVideoCaptureStreamfvNV;
+ glGetVideoCaptureStreamdvNV: TglGetVideoCaptureStreamdvNV;
+ glVideoCaptureNV: TglVideoCaptureNV;
+ glVideoCaptureStreamParameterivNV: TglVideoCaptureStreamParameterivNV;
+ glVideoCaptureStreamParameterfvNV: TglVideoCaptureStreamParameterfvNV;
+ glVideoCaptureStreamParameterdvNV: TglVideoCaptureStreamParameterdvNV;
+
+ // GL_NV_copy_image
+ glCopyImageSubDataNV: TglCopyImageSubDataNV;
+
+ // GL_NV_shader_buffer_load
+ glMakeBufferResidentNV: TglMakeBufferResidentNV;
+ glMakeBufferNonResidentNV: TglMakeBufferNonResidentNV;
+ glIsBufferResidentNV: TglIsBufferResidentNV;
+ glMakeNamedBufferResidentNV: TglMakeNamedBufferResidentNV;
+ glMakeNamedBufferNonResidentNV: TglMakeNamedBufferNonResidentNV;
+ glIsNamedBufferResidentNV: TglIsNamedBufferResidentNV;
+ glGetBufferParameterui64vNV: TglGetBufferParameterui64vNV;
+ glGetNamedBufferParameterui64vNV: TglGetNamedBufferParameterui64vNV;
+ glGetIntegerui64vNV: TglGetIntegerui64vNV;
+ glUniformui64NV: TglUniformui64NV;
+ glUniformui64vNV: TglUniformui64vNV;
+ glGetUniformui64vNV: TglGetUniformui64vNV;
+ glProgramUniformui64NV: TglProgramUniformui64NV;
+ glProgramUniformui64vNV: TglProgramUniformui64vNV;
+
+ // GL_NV_vertex_buffer_unified_memory
+ glBufferAddressRangeNV: TglBufferAddressRangeNV;
+ glVertexFormatNV: TglVertexFormatNV;
+ glNormalFormatNV: TglNormalFormatNV;
+ glColorFormatNV: TglColorFormatNV;
+ glIndexFormatNV: TglIndexFormatNV;
+ glTexCoordFormatNV: TglTexCoordFormatNV;
+ glEdgeFlagFormatNV: TglEdgeFlagFormatNV;
+ glSecondaryColorFormatNV: TglSecondaryColorFormatNV;
+ glFogCoordFormatNV: TglFogCoordFormatNV;
+ glVertexAttribFormatNV: TglVertexAttribFormatNV;
+ glVertexAttribIFormatNV: TglVertexAttribIFormatNV;
+ glGetIntegerui64i_vNV: TglGetIntegerui64i_vNV;
+
+ // GL_NV_gpu_program5
+ glProgramSubroutineParametersuivNV: TglProgramSubroutineParametersuivNV;
+ glGetProgramSubroutineParameteruivNV: TglGetProgramSubroutineParameteruivNV;
+
+ // GL_NV_gpu_shader5
+ glUniform1i64NV: TglUniform1i64NV;
+ glUniform2i64NV: TglUniform2i64NV;
+ glUniform3i64NV: TglUniform3i64NV;
+ glUniform4i64NV: TglUniform4i64NV;
+ glUniform1i64vNV: TglUniform1i64vNV;
+ glUniform2i64vNV: TglUniform2i64vNV;
+ glUniform3i64vNV: TglUniform3i64vNV;
+ glUniform4i64vNV: TglUniform4i64vNV;
+ glUniform1ui64NV: TglUniform1ui64NV;
+ glUniform2ui64NV: TglUniform2ui64NV;
+ glUniform3ui64NV: TglUniform3ui64NV;
+ glUniform4ui64NV: TglUniform4ui64NV;
+ glUniform1ui64vNV: TglUniform1ui64vNV;
+ glUniform2ui64vNV: TglUniform2ui64vNV;
+ glUniform3ui64vNV: TglUniform3ui64vNV;
+ glUniform4ui64vNV: TglUniform4ui64vNV;
+ glGetUniformi64vNV: TglGetUniformi64vNV;
+ glProgramUniform1i64NV: TglProgramUniform1i64NV;
+ glProgramUniform2i64NV: TglProgramUniform2i64NV;
+ glProgramUniform3i64NV: TglProgramUniform3i64NV;
+ glProgramUniform4i64NV: TglProgramUniform4i64NV;
+ glProgramUniform1i64vNV: TglProgramUniform1i64vNV;
+ glProgramUniform2i64vNV: TglProgramUniform2i64vNV;
+ glProgramUniform3i64vNV: TglProgramUniform3i64vNV;
+ glProgramUniform4i64vNV: TglProgramUniform4i64vNV;
+ glProgramUniform1ui64NV: TglProgramUniform1ui64NV;
+ glProgramUniform2ui64NV: TglProgramUniform2ui64NV;
+ glProgramUniform3ui64NV: TglProgramUniform3ui64NV;
+ glProgramUniform4ui64NV: TglProgramUniform4ui64NV;
+ glProgramUniform1ui64vNV: TglProgramUniform1ui64vNV;
+ glProgramUniform2ui64vNV: TglProgramUniform2ui64vNV;
+ glProgramUniform3ui64vNV: TglProgramUniform3ui64vNV;
+ glProgramUniform4ui64vNV: TglProgramUniform4ui64vNV;
+
+ // GL_NV_vertex_attrib_integer_64bit
+ glVertexAttribL1i64NV: TglVertexAttribL1i64NV;
+ glVertexAttribL2i64NV: TglVertexAttribL2i64NV;
+ glVertexAttribL3i64NV: TglVertexAttribL3i64NV;
+ glVertexAttribL4i64NV: TglVertexAttribL4i64NV;
+ glVertexAttribL1i64vNV: TglVertexAttribL1i64vNV;
+ glVertexAttribL2i64vNV: TglVertexAttribL2i64vNV;
+ glVertexAttribL3i64vNV: TglVertexAttribL3i64vNV;
+ glVertexAttribL4i64vNV: TglVertexAttribL4i64vNV;
+ glVertexAttribL1ui64NV: TglVertexAttribL1ui64NV;
+ glVertexAttribL2ui64NV: TglVertexAttribL2ui64NV;
+ glVertexAttribL3ui64NV: TglVertexAttribL3ui64NV;
+ glVertexAttribL4ui64NV: TglVertexAttribL4ui64NV;
+ glVertexAttribL1ui64vNV: TglVertexAttribL1ui64vNV;
+ glVertexAttribL2ui64vNV: TglVertexAttribL2ui64vNV;
+ glVertexAttribL3ui64vNV: TglVertexAttribL3ui64vNV;
+ glVertexAttribL4ui64vNV: TglVertexAttribL4ui64vNV;
+ glGetVertexAttribLi64vNV: TglGetVertexAttribLi64vNV;
+ glGetVertexAttribLui64vNV: TglGetVertexAttribLui64vNV;
+ glVertexAttribLFormatNV: TglVertexAttribLFormatNV;
+
+ // GL_NV_vdpau_interop
+ glVDPAUInitNV: TglVDPAUInitNV;
+ glVDPAUFiniNV: TglVDPAUFiniNV;
+ glVDPAURegisterVideoSurfaceNV: TglVDPAURegisterVideoSurfaceNV;
+ glVDPAURegisterOutputSurfaceNV: TglVDPAURegisterOutputSurfaceNV;
+ glVDPAUIsSurfaceNV: TglVDPAUIsSurfaceNV;
+ glVDPAUUnregisterSurfaceNV: TglVDPAUUnregisterSurfaceNV;
+ glVDPAUGetSurfaceivNV: TglVDPAUGetSurfaceivNV;
+ glVDPAUSurfaceAccessNV: TglVDPAUSurfaceAccessNV;
+ glVDPAUMapSurfacesNV: TglVDPAUMapSurfacesNV;
+ glVDPAUUnmapSurfacesNV: TglVDPAUUnmapSurfacesNV;
+
+ // GL_NV_texture_barrier
+ glTextureBarrierNV: TglTextureBarrierNV;
+
+ // (4.3) GL_NV_path_rendering
+ glGenPathsNV : TglGenPathsNV;
+ glDeletePathsNV : TglDeletePathsNV;
+ glIsPathNV : TglIsPathNV;
+ glPathCommandsNV : TglPathCommandsNV;
+ glPathCoordsNV : TglPathCoordsNV;
+ glPathSubCommandsNV : TglPathSubCommandsNV;
+ glPathSubCoordsNV : TglPathSubCoordsNV;
+ glPathStringNV : TglPathStringNV;
+ glPathGlyphsNV : TglPathGlyphsNV;
+ glPathGlyphRangeNV : TglPathGlyphRangeNV;
+ glWeightPathsNV : TglWeightPathsNV;
+ glCopyPathNV : TglCopyPathNV;
+ glInterpolatePathsNV : TglInterpolatePathsNV;
+ glTransformPathNV : TglTransformPathNV;
+ glPathParameterivNV : TglPathParameterivNV;
+ glPathParameteriNV : TglPathParameteriNV;
+ glPathParameterfvNV : TglPathParameterfvNV;
+ glPathParameterfNV : TglPathParameterfNV;
+ glPathDashArrayNV : TglPathDashArrayNV;
+ glPathStencilFuncNV : TglPathStencilFuncNV;
+ glPathStencilDepthOffsetNV : TglPathStencilDepthOffsetNV;
+ glStencilFillPathNV : TglStencilFillPathNV;
+ glStencilStrokePathNV : TglStencilStrokePathNV;
+ glStencilFillPathInstancedNV : TglStencilFillPathInstancedNV;
+ glStencilStrokePathInstancedNV : TglStencilStrokePathInstancedNV;
+ glPathCoverDepthFuncNV : TglPathCoverDepthFuncNV;
+ glPathColorGenNV : TglPathColorGenNV;
+ glPathTexGenNV : TglPathTexGenNV;
+ glPathFogGenNV : TglPathFogGenNV;
+ glCoverFillPathNV : TglCoverFillPathNV;
+ glCoverStrokePathNV : TglCoverStrokePathNV;
+ glCoverFillPathInstancedNV : TglCoverFillPathInstancedNV;
+ glCoverStrokePathInstancedNV : TglCoverStrokePathInstancedNV;
+ glGetPathParameterivNV : TglGetPathParameterivNV;
+ glGetPathParameterfvNV : TglGetPathParameterfvNV;
+ glGetPathCommandsNV : TglGetPathCommandsNV;
+ glGetPathCoordsNV : TglGetPathCoordsNV;
+ glGetPathDashArrayNV : TglGetPathDashArrayNV;
+ glGetPathMetricsNV : TglGetPathMetricsNV;
+ glGetPathMetricRangeNV : TglGetPathMetricRangeNV;
+ glGetPathSpacingNV : TglGetPathSpacingNV;
+ glGetPathColorGenivNV : TglGetPathColorGenivNV;
+ glGetPathColorGenfvNV : TglGetPathColorGenfvNV;
+ glGetPathTexGenivNV : TglGetPathTexGenivNV;
+ glGetPathTexGenfvNV : TglGetPathTexGenfvNV;
+ glIsPointInFillPathNV : TglIsPointInFillPathNV;
+ glIsPointInStrokePathNV : TglIsPointInStrokePathNV;
+ glGetPathLengthNV : TglGetPathLengthNV;
+ glPointAlongPathNV : TglPointAlongPathNV;
+
+ // GL_AMD_pinned_memory
+
+ // GL_AMD_stencil_operation_extended
+ glStencilOpValueAMD : TglStencilOpValueAMD;
+
+ // GL_AMD_vertex_shader_viewport_index
+
+ // GL_AMD_vertex_shader_layer
+
+ // GL_NV_bindless_texture
+ glGetTextureHandleNV : TglGetTextureHandleNV;
+ glGetTextureSamplerHandleNV : TglGetTextureSamplerHandleNV;
+ glMakeTextureHandleResidentNV : TglMakeTextureHandleResidentNV;
+ glMakeTextureHandleNonResidentNV : TglMakeTextureHandleNonResidentNV;
+ glGetImageHandleNV : TglGetImageHandleNV;
+ glMakeImageHandleResidentNV : TglMakeImageHandleResidentNV;
+ glMakeImageHandleNonResidentNV : TglMakeImageHandleNonResidentNV;
+ glUniformHandleui64NV : TglUniformHandleui64NV;
+ glUniformHandleui64vNV : TglUniformHandleui64vNV;
+ glProgramUniformHandleui64NV : TglProgramUniformHandleui64NV;
+ glProgramUniformHandleui64vNV : TglProgramUniformHandleui64vNV;
+ glIsTextureHandleResidentNV : TglIsTextureHandleResidentNV;
+ glIsImageHandleResidentNV : TglIsImageHandleResidentNV;
+
+ // GL_ARB_bindless_texture
+ glGetTextureHandleARB : TglGetTextureHandleARB;
+ glGetTextureSamplerHandleARB : TglGetTextureSamplerHandleARB;
+ glMakeTextureHandleResidentARB : TglMakeTextureHandleResidentARB;
+ glMakeTextureHandleNonResidentARB : TglMakeTextureHandleNonResidentARB;
+ glGetImageHandleARB : TglGetImageHandleARB;
+ glMakeImageHandleResidentARB : TglMakeImageHandleResidentARB;
+ glMakeImageHandleNonResidentARB : TglMakeImageHandleNonResidentARB;
+ glUniformHandleui64ARB : TglUniformHandleui64ARB;
+ glUniformHandleui64vARB : TglUniformHandleui64vARB;
+ glProgramUniformHandleui64ARB : TglProgramUniformHandleui64ARB;
+ glProgramUniformHandleui64vARB : TglProgramUniformHandleui64vARB;
+ glIsTextureHandleResidentARB : TglIsTextureHandleResidentARB;
+ glIsImageHandleResidentARB : TglIsImageHandleResidentARB;
+ glVertexAttribL1ui64ARB : TglVertexAttribL1ui64ARB;
+ glVertexAttribL1ui64vARB : TglVertexAttribL1ui64vARB;
+ glGetVertexAttribLui64vARB : TglGetVertexAttribLui64vARB;
+
+ // GL_PGI_misc_hints
+ glHintPGI: TglHintPGI;
+
+ // GL_OVR_multiview
+ glFramebufferTextureMultiviewOVR : TglFramebufferTextureMultiviewOVR;
+
+ // GL_SGIS_detail_texture
+ glDetailTexFuncSGIS: TglDetailTexFuncSGIS;
+ glGetDetailTexFuncSGIS: TglGetDetailTexFuncSGIS;
+
+ // GL_SGIS_fog_function
+ glFogFuncSGIS: TglFogFuncSGIS;
+ glGetFogFuncSGIS: TglGetFogFuncSGIS;
+
+ // GL_SGIS_multisample
+ glSampleMaskSGIS: TglSampleMaskSGIS;
+ glSamplePatternSGIS: TglSamplePatternSGIS;
+
+ // GL_SGIS_pixel_texture
+ glPixelTexGenParameteriSGIS: TglPixelTexGenParameteriSGIS;
+ glPixelTexGenParameterivSGIS: TglPixelTexGenParameterivSGIS;
+ glPixelTexGenParameterfSGIS: TglPixelTexGenParameterfSGIS;
+ glPixelTexGenParameterfvSGIS: TglPixelTexGenParameterfvSGIS;
+ glGetPixelTexGenParameterivSGIS: TglGetPixelTexGenParameterivSGIS;
+ glGetPixelTexGenParameterfvSGIS: TglGetPixelTexGenParameterfvSGIS;
+
+ // GL_SGIS_point_parameters
+ glPointParameterfSGIS: TglPointParameterfSGIS;
+ glPointParameterfvSGIS: TglPointParameterfvSGIS;
+
+ // GL_SGIS_sharpen_texture
+ glSharpenTexFuncSGIS: TglSharpenTexFuncSGIS;
+ glGetSharpenTexFuncSGIS: TglGetSharpenTexFuncSGIS;
+
+ // GL_SGIS_texture4D
+ glTexImage4DSGIS: TglTexImage4DSGIS;
+ glTexSubImage4DSGIS: TglTexSubImage4DSGIS;
+
+ // GL_SGIS_texture_color_mask
+ glTextureColorMaskSGIS: TglTextureColorMaskSGIS;
+
+ // GL_SGIS_texture_filter4
+ glGetTexFilterFuncSGIS: TglGetTexFilterFuncSGIS;
+ glTexFilterFuncSGIS: TglTexFilterFuncSGIS;
+
+ // GL_SGIX_async
+ glAsyncMarkerSGIX: TglAsyncMarkerSGIX;
+ glFinishAsyncSGIX: TglFinishAsyncSGIX;
+ glPollAsyncSGIX: TglPollAsyncSGIX;
+ glGenAsyncMarkersSGIX: TglGenAsyncMarkersSGIX;
+ glDeleteAsyncMarkersSGIX: TglDeleteAsyncMarkersSGIX;
+ glIsAsyncMarkerSGIX: TglIsAsyncMarkerSGIX;
+
+ // GL_SGIX_flush_raster
+ glFlushRasterSGIX: TglFlushRasterSGIX;
+
+ // GL_SGIX_fragment_lighting
+ glFragmentColorMaterialSGIX: TglFragmentColorMaterialSGIX;
+ glFragmentLightfSGIX: TglFragmentLightfSGIX;
+ glFragmentLightfvSGIX: TglFragmentLightfvSGIX;
+ glFragmentLightiSGIX: TglFragmentLightiSGIX;
+ glFragmentLightivSGIX: TglFragmentLightivSGIX;
+ glFragmentLightModelfSGIX: TglFragmentLightModelfSGIX;
+ glFragmentLightModelfvSGIX: TglFragmentLightModelfvSGIX;
+ glFragmentLightModeliSGIX: TglFragmentLightModeliSGIX;
+ glFragmentLightModelivSGIX: TglFragmentLightModelivSGIX;
+ glFragmentMaterialfSGIX: TglFragmentMaterialfSGIX;
+ glFragmentMaterialfvSGIX: TglFragmentMaterialfvSGIX;
+ glFragmentMaterialiSGIX: TglFragmentMaterialiSGIX;
+ glFragmentMaterialivSGIX: TglFragmentMaterialivSGIX;
+ glGetFragmentLightfvSGIX: TglGetFragmentLightfvSGIX;
+ glGetFragmentLightivSGIX: TglGetFragmentLightivSGIX;
+ glGetFragmentMaterialfvSGIX: TglGetFragmentMaterialfvSGIX;
+ glGetFragmentMaterialivSGIX: TglGetFragmentMaterialivSGIX;
+ glLightEnviSGIX: TglLightEnviSGIX;
+
+ // GL_SGIX_framezoom
+ glFrameZoomSGIX: TglFrameZoomSGIX;
+
+ // GL_SGIX_igloo_interface
+ glIglooInterfaceSGIX: TglIglooInterfaceSGIX;
+
+ // GL_SGIX_instruments
+ glGetInstrumentsSGIX: TglGetInstrumentsSGIX;
+ glInstrumentsBufferSGIX: TglInstrumentsBufferSGIX;
+ glPollInstrumentsSGIX: TglPollInstrumentsSGIX;
+ glReadInstrumentsSGIX: TglReadInstrumentsSGIX;
+ glStartInstrumentsSGIX: TglStartInstrumentsSGIX;
+ glStopInstrumentsSGIX: TglStopInstrumentsSGIX;
+
+ // GL_SGIX_list_priority
+ glGetListParameterfvSGIX: TglGetListParameterfvSGIX;
+ glGetListParameterivSGIX: TglGetListParameterivSGIX;
+ glListParameterfSGIX: TglListParameterfSGIX;
+ glListParameterfvSGIX: TglListParameterfvSGIX;
+ glListParameteriSGIX: TglListParameteriSGIX;
+ glListParameterivSGIX: TglListParameterivSGIX;
+
+ // GL_SGIX_pixel_texture
+ glPixelTexGenSGIX: TglPixelTexGenSGIX;
+
+ // GL_SGIX_polynomial_ffd
+ glDeformationMap3dSGIX: TglDeformationMap3dSGIX;
+ glDeformationMap3fSGIX: TglDeformationMap3fSGIX;
+ glDeformSGIX: TglDeformSGIX;
+ glLoadIdentityDeformationMapSGIX: TglLoadIdentityDeformationMapSGIX;
+
+ // GL_SGIX_reference_plane
+ glReferencePlaneSGIX: TglReferencePlaneSGIX;
+
+ // GL_SGIX_sprite
+ glSpriteParameterfSGIX: TglSpriteParameterfSGIX;
+ glSpriteParameterfvSGIX: TglSpriteParameterfvSGIX;
+ glSpriteParameteriSGIX: TglSpriteParameteriSGIX;
+ glSpriteParameterivSGIX: TglSpriteParameterivSGIX;
+
+ // GL_SGIX_tag_sample_buffer
+ glTagSampleBufferSGIX: TglTagSampleBufferSGIX;
+
+ // GL_SGI_color_table
+ glColorTableSGI: TglColorTableSGI;
+ glColorTableParameterfvSGI: TglColorTableParameterfvSGI;
+ glColorTableParameterivSGI: TglColorTableParameterivSGI;
+ glCopyColorTableSGI: TglCopyColorTableSGI;
+ glGetColorTableSGI: TglGetColorTableSGI;
+ glGetColorTableParameterfvSGI: TglGetColorTableParameterfvSGI;
+ glGetColorTableParameterivSGI: TglGetColorTableParameterivSGI;
+
+ // GL_SUNX_constant_data
+ glFinishTextureSUNX: TglFinishTextureSUNX;
+
+ // GL_SUN_global_alpha
+ glGlobalAlphaFactorbSUN: TglGlobalAlphaFactorbSUN;
+ glGlobalAlphaFactorsSUN: TglGlobalAlphaFactorsSUN;
+ glGlobalAlphaFactoriSUN: TglGlobalAlphaFactoriSUN;
+ glGlobalAlphaFactorfSUN: TglGlobalAlphaFactorfSUN;
+ glGlobalAlphaFactordSUN: TglGlobalAlphaFactordSUN;
+ glGlobalAlphaFactorubSUN: TglGlobalAlphaFactorubSUN;
+ glGlobalAlphaFactorusSUN: TglGlobalAlphaFactorusSUN;
+ glGlobalAlphaFactoruiSUN: TglGlobalAlphaFactoruiSUN;
+
+ // GL_SUN_mesh_array
+ glDrawMeshArraysSUN: TglDrawMeshArraysSUN;
+
+ // GL_SUN_triangle_list
+ glReplacementCodeuiSUN: TglReplacementCodeuiSUN;
+ glReplacementCodeusSUN: TglReplacementCodeusSUN;
+ glReplacementCodeubSUN: TglReplacementCodeubSUN;
+ glReplacementCodeuivSUN: TglReplacementCodeuivSUN;
+ glReplacementCodeusvSUN: TglReplacementCodeusvSUN;
+ glReplacementCodeubvSUN: TglReplacementCodeubvSUN;
+ glReplacementCodePointerSUN: TglReplacementCodePointerSUN;
+
+ // GL_SUN_vertex
+ glColor4ubVertex2fSUN: TglColor4ubVertex2fSUN;
+ glColor4ubVertex2fvSUN: TglColor4ubVertex2fvSUN;
+ glColor4ubVertex3fSUN: TglColor4ubVertex3fSUN;
+ glColor4ubVertex3fvSUN: TglColor4ubVertex3fvSUN;
+ glColor3fVertex3fSUN: TglColor3fVertex3fSUN;
+ glColor3fVertex3fvSUN: TglColor3fVertex3fvSUN;
+ glNormal3fVertex3fSUN: TglNormal3fVertex3fSUN;
+ glNormal3fVertex3fvSUN: TglNormal3fVertex3fvSUN;
+ glColor4fNormal3fVertex3fSUN: TglColor4fNormal3fVertex3fSUN;
+ glColor4fNormal3fVertex3fvSUN: TglColor4fNormal3fVertex3fvSUN;
+ glTexCoord2fVertex3fSUN: TglTexCoord2fVertex3fSUN;
+ glTexCoord2fVertex3fvSUN: TglTexCoord2fVertex3fvSUN;
+ glTexCoord4fVertex4fSUN: TglTexCoord4fVertex4fSUN;
+ glTexCoord4fVertex4fvSUN: TglTexCoord4fVertex4fvSUN;
+ glTexCoord2fColor4ubVertex3fSUN: TglTexCoord2fColor4ubVertex3fSUN;
+ glTexCoord2fColor4ubVertex3fvSUN: TglTexCoord2fColor4ubVertex3fvSUN;
+ glTexCoord2fColor3fVertex3fSUN: TglTexCoord2fColor3fVertex3fSUN;
+ glTexCoord2fColor3fVertex3fvSUN: TglTexCoord2fColor3fVertex3fvSUN;
+ glTexCoord2fNormal3fVertex3fSUN: TglTexCoord2fNormal3fVertex3fSUN;
+ glTexCoord2fNormal3fVertex3fvSUN: TglTexCoord2fNormal3fVertex3fvSUN;
+ glTexCoord2fColor4fNormal3fVertex3fSUN: TglTexCoord2fColor4fNormal3fVertex3fSUN;
+ glTexCoord2fColor4fNormal3fVertex3fvSUN: TglTexCoord2fColor4fNormal3fVertex3fvSUN;
+ glTexCoord4fColor4fNormal3fVertex4fSUN: TglTexCoord4fColor4fNormal3fVertex4fSUN;
+ glTexCoord4fColor4fNormal3fVertex4fvSUN: TglTexCoord4fColor4fNormal3fVertex4fvSUN;
+ glReplacementCodeuiVertex3fSUN: TglReplacementCodeuiVertex3fSUN;
+ glReplacementCodeuiVertex3fvSUN: TglReplacementCodeuiVertex3fvSUN;
+ glReplacementCodeuiColor4ubVertex3fSUN: TglReplacementCodeuiColor4ubVertex3fSUN;
+ glReplacementCodeuiColor4ubVertex3fvSUN: TglReplacementCodeuiColor4ubVertex3fvSUN;
+ glReplacementCodeuiColor3fVertex3fSUN: TglReplacementCodeuiColor3fVertex3fSUN;
+ glReplacementCodeuiColor3fVertex3fvSUN: TglReplacementCodeuiColor3fVertex3fvSUN;
+ glReplacementCodeuiNormal3fVertex3fSUN: TglReplacementCodeuiNormal3fVertex3fSUN;
+ glReplacementCodeuiNormal3fVertex3fvSUN: TglReplacementCodeuiNormal3fVertex3fvSUN;
+ glReplacementCodeuiColor4fNormal3fVertex3fSUN: TglReplacementCodeuiColor4fNormal3fVertex3fSUN;
+ glReplacementCodeuiColor4fNormal3fVertex3fvSUN: TglReplacementCodeuiColor4fNormal3fVertex3fvSUN;
+ glReplacementCodeuiTexCoord2fVertex3fSUN: TglReplacementCodeuiTexCoord2fVertex3fSUN;
+ glReplacementCodeuiTexCoord2fVertex3fvSUN: TglReplacementCodeuiTexCoord2fVertex3fvSUN;
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN: TglReplacementCodeuiTexCoord2fNormal3fVertex3fSUN;
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN: TglReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN;
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN: TglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN;
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN: TglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN;
+
+{$IFDEF DGL_WIN}
+ wglGetProcAddress: TwglGetProcAddress;
+ wglCopyContext: TwglCopyContext;
+ wglCreateContext: TwglCreateContext;
+ wglCreateLayerContext: TwglCreateLayerContext;
+ wglDeleteContext: TwglDeleteContext;
+ wglDescribeLayerPlane: TwglDescribeLayerPlane;
+ wglGetCurrentContext: TwglGetCurrentContext;
+ wglGetCurrentDC: TwglGetCurrentDC;
+ wglGetLayerPaletteEntries: TwglGetLayerPaletteEntries;
+ wglMakeCurrent: TwglMakeCurrent;
+ wglRealizeLayerPalette: TwglRealizeLayerPalette;
+ wglSetLayerPaletteEntries: TwglSetLayerPaletteEntries;
+ wglShareLists: TwglShareLists;
+ wglSwapLayerBuffers: TwglSwapLayerBuffers;
+ wglSwapMultipleBuffers: TwglSwapMultipleBuffers;
+ wglUseFontBitmapsA: TwglUseFontBitmapsA;
+ wglUseFontOutlinesA: TwglUseFontOutlinesA;
+ wglUseFontBitmapsW: TwglUseFontBitmapsW;
+ wglUseFontOutlinesW: TwglUseFontOutlinesW;
+ wglUseFontBitmaps: TwglUseFontBitmaps;
+ wglUseFontOutlines: TwglUseFontOutlines;
+
+ // WGL_ARB_buffer_region
+ wglCreateBufferRegionARB: TwglCreateBufferRegionARB;
+ wglDeleteBufferRegionARB: TwglDeleteBufferRegionARB;
+ wglSaveBufferRegionARB: TwglSaveBufferRegionARB;
+ wglRestoreBufferRegionARB: TwglRestoreBufferRegionARB;
+
+ // WGL_ARB_extensions_string
+ wglGetExtensionsStringARB: TwglGetExtensionsStringARB;
+
+ // WGL_ARB_make_current_read
+ wglMakeContextCurrentARB: TwglMakeContextCurrentARB;
+ wglGetCurrentReadDCARB: TwglGetCurrentReadDCARB;
+
+ // WGL_ARB_pbuffer
+ wglCreatePbufferARB: TwglCreatePbufferARB;
+ wglGetPbufferDCARB: TwglGetPbufferDCARB;
+ wglReleasePbufferDCARB: TwglReleasePbufferDCARB;
+ wglDestroyPbufferARB: TwglDestroyPbufferARB;
+ wglQueryPbufferARB: TwglQueryPbufferARB;
+
+ // WGL_ARB_pixel_format
+ wglGetPixelFormatAttribivARB: TwglGetPixelFormatAttribivARB;
+ wglGetPixelFormatAttribfvARB: TwglGetPixelFormatAttribfvARB;
+ wglChoosePixelFormatARB: TwglChoosePixelFormatARB;
+ // WGL_ARB_color_buffer_float
+ wglClampColorARB: TwglClampColorARB;
+
+ // WGL_ARB_render_texture
+ wglBindTexImageARB: TwglBindTexImageARB;
+ wglReleaseTexImageARB: TwglReleaseTexImageARB;
+ wglSetPbufferAttribARB: TwglSetPbufferAttribARB;
+
+ // WGL_ARB_create_context
+ wglCreateContextAttribsARB: TwglCreateContextAttribsARB;
+
+ // WGL_AMD_gpu_association
+ wglGetGPUIDsAMD: TwglGetGPUIDsAMD;
+ wglGetGPUInfoAMD: TwglGetGPUInfoAMD;
+ wglGetContextGPUIDAMD: TwglGetContextGPUIDAMD;
+ wglCreateAssociatedContextAMD: TwglCreateAssociatedContextAMD;
+ wglCreateAssociatedContextAttribsAMD: TwglCreateAssociatedContextAttribsAMD;
+ wglDeleteAssociatedContextAMD: TwglDeleteAssociatedContextAMD;
+ wglMakeAssociatedContextCurrentAMD: TwglMakeAssociatedContextCurrentAMD;
+ wglGetCurrentAssociatedContextAMD: TwglGetCurrentAssociatedContextAMD;
+ wglBlitContextFramebufferAMD: TwglBlitContextFramebufferAMD;
+
+ // WGL_EXT_display_color_table
+ wglCreateDisplayColorTableEXT: TwglCreateDisplayColorTableEXT;
+ wglLoadDisplayColorTableEXT: TwglLoadDisplayColorTableEXT;
+ wglBindDisplayColorTableEXT: TwglBindDisplayColorTableEXT;
+ wglDestroyDisplayColorTableEXT: TwglDestroyDisplayColorTableEXT;
+
+ // WGL_EXT_extensions_string
+ wglGetExtensionsStringEXT: TwglGetExtensionsStringEXT;
+
+ // WGL_EXT_make_current_read
+ wglMakeContextCurrentEXT: TwglMakeContextCurrentEXT;
+ wglGetCurrentReadDCEXT: TwglGetCurrentReadDCEXT;
+
+ // WGL_EXT_pbuffer
+ wglCreatePbufferEXT: TwglCreatePbufferEXT;
+ wglGetPbufferDCEXT: TwglGetPbufferDCEXT;
+ wglReleasePbufferDCEXT: TwglReleasePbufferDCEXT;
+ wglDestroyPbufferEXT: TwglDestroyPbufferEXT;
+ wglQueryPbufferEXT: TwglQueryPbufferEXT;
+
+ // WGL_EXT_pixel_format
+ wglGetPixelFormatAttribivEXT: TwglGetPixelFormatAttribivEXT;
+ wglGetPixelFormatAttribfvEXT: TwglGetPixelFormatAttribfvEXT;
+ wglChoosePixelFormatEXT: TwglChoosePixelFormatEXT;
+
+ // WGL_EXT_swap_control
+ wglSwapIntervalEXT: TwglSwapIntervalEXT;
+ wglGetSwapIntervalEXT: TwglGetSwapIntervalEXT;
+
+ // WGL_I3D_digital_video_control
+ wglGetDigitalVideoParametersI3D: TwglGetDigitalVideoParametersI3D;
+ wglSetDigitalVideoParametersI3D: TwglSetDigitalVideoParametersI3D;
+
+ // WGL_I3D_gamma
+ wglGetGammaTableParametersI3D: TwglGetGammaTableParametersI3D;
+ wglSetGammaTableParametersI3D: TwglSetGammaTableParametersI3D;
+ wglGetGammaTableI3D: TwglGetGammaTableI3D;
+ wglSetGammaTableI3D: TwglSetGammaTableI3D;
+
+ // WGL_I3D_genlock
+ wglEnableGenlockI3D: TwglEnableGenlockI3D;
+ wglDisableGenlockI3D: TwglDisableGenlockI3D;
+ wglIsEnabledGenlockI3D: TwglIsEnabledGenlockI3D;
+ wglGenlockSourceI3D: TwglGenlockSourceI3D;
+ wglGetGenlockSourceI3D: TwglGetGenlockSourceI3D;
+ wglGenlockSourceEdgeI3D: TwglGenlockSourceEdgeI3D;
+ wglGetGenlockSourceEdgeI3D: TwglGetGenlockSourceEdgeI3D;
+ wglGenlockSampleRateI3D: TwglGenlockSampleRateI3D;
+ wglGetGenlockSampleRateI3D: TwglGetGenlockSampleRateI3D;
+ wglGenlockSourceDelayI3D: TwglGenlockSourceDelayI3D;
+ wglGetGenlockSourceDelayI3D: TwglGetGenlockSourceDelayI3D;
+ wglQueryGenlockMaxSourceDelayI3D: TwglQueryGenlockMaxSourceDelayI3D;
+
+ // WGL_I3D_image_buffer
+ wglCreateImageBufferI3D: TwglCreateImageBufferI3D;
+ wglDestroyImageBufferI3D: TwglDestroyImageBufferI3D;
+ wglAssociateImageBufferEventsI3D: TwglAssociateImageBufferEventsI3D;
+ wglReleaseImageBufferEventsI3D: TwglReleaseImageBufferEventsI3D;
+
+ // WGL_I3D_swap_frame_lock
+ wglEnableFrameLockI3D: TwglEnableFrameLockI3D;
+ wglDisableFrameLockI3D: TwglDisableFrameLockI3D;
+ wglIsEnabledFrameLockI3D: TwglIsEnabledFrameLockI3D;
+ wglQueryFrameLockMasterI3D: TwglQueryFrameLockMasterI3D;
+
+ // WGL_I3D_swap_frame_usage
+ wglGetFrameUsageI3D: TwglGetFrameUsageI3D;
+ wglBeginFrameTrackingI3D: TwglBeginFrameTrackingI3D;
+ wglEndFrameTrackingI3D: TwglEndFrameTrackingI3D;
+ wglQueryFrameTrackingI3D: TwglQueryFrameTrackingI3D;
+
+ // WGL_NV_vertex_array_range
+ wglAllocateMemoryNV: TwglAllocateMemoryNV;
+ wglFreeMemoryNV: TwglFreeMemoryNV;
+
+ // WGL_NV_present_video
+ wglEnumerateVideoDevicesNV: TwglEnumerateVideoDevicesNV;
+ wglBindVideoDeviceNV: TwglBindVideoDeviceNV;
+ wglQueryCurrentContextNV: TwglQueryCurrentContextNV;
+
+ // WGL_NV_video_output
+ wglGetVideoDeviceNV: TwglGetVideoDeviceNV;
+ wglReleaseVideoDeviceNV: TwglReleaseVideoDeviceNV;
+ wglBindVideoImageNV: TwglBindVideoImageNV;
+ wglReleaseVideoImageNV: TwglReleaseVideoImageNV;
+ wglSendPbufferToVideoNV: TwglSendPbufferToVideoNV;
+ wglGetVideoInfoNV: TwglGetVideoInfoNV;
+
+ // WGL_NV_swap_group
+ wglJoinSwapGroupNV: TwglJoinSwapGroupNV;
+ wglBindSwapBarrierNV: TwglBindSwapBarrierNV;
+ wglQuerySwapGroupNV: TwglQuerySwapGroupNV;
+ wglQueryMaxSwapGroupsNV: TwglQueryMaxSwapGroupsNV;
+ wglQueryFrameCountNV: TwglQueryFrameCountNV;
+ wglResetFrameCountNV: TwglResetFrameCountNV;
+
+ // WGL_NV_gpu_affinity
+ wglEnumGpusNV: TwglEnumGpusNV;
+ wglEnumGpuDevicesNV: TwglEnumGpuDevicesNV;
+ wglCreateAffinityDCNV: TwglCreateAffinityDCNV;
+ wglEnumGpusFromAffinityDCNV: TwglEnumGpusFromAffinityDCNV;
+ wglDeleteDCNV: TwglDeleteDCNV;
+
+ // WGL_NV_video_capture
+ wglBindVideoCaptureDeviceNV: TwglBindVideoCaptureDeviceNV;
+ wglEnumerateVideoCaptureDevicesNV: TwglEnumerateVideoCaptureDevicesNV;
+ wglLockVideoCaptureDeviceNV: TwglLockVideoCaptureDeviceNV;
+ wglQueryVideoCaptureDeviceNV: TwglQueryVideoCaptureDeviceNV;
+ wglReleaseVideoCaptureDeviceNV: TwglReleaseVideoCaptureDeviceNV;
+
+ // WGL_NV_copy_image
+ wglCopyImageSubDataNV: TwglCopyImageSubDataNV;
+
+ // WGL_NV_DX_interop
+ wglDXSetResourceShareHandleNV : TwglDXSetResourceShareHandleNV;
+ wglDXOpenDeviceNV : TwglDXOpenDeviceNV;
+ wglDXCloseDeviceNV : TwglDXCloseDeviceNV;
+ wglDXRegisterObjectNV : TwglDXRegisterObjectNV;
+ wglDXUnregisterObjectNV : TwglDXUnregisterObjectNV;
+ wglDXObjectAccessNV : TwglDXObjectAccessNV;
+ wglDXLockObjectsNV : TwglDXLockObjectsNV;
+ wglDXUnlockObjectsNV : TwglDXUnlockObjectsNV;
+
+ // WGL_OML_sync_control
+ wglGetSyncValuesOML: TwglGetSyncValuesOML;
+ wglGetMscRateOML: TwglGetMscRateOML;
+ wglSwapBuffersMscOML: TwglSwapBuffersMscOML;
+ wglSwapLayerBuffersMscOML: TwglSwapLayerBuffersMscOML;
+ wglWaitForMscOML: TwglWaitForMscOML;
+ wglWaitForSbcOML: TwglWaitForSbcOML;
+
+ // WGL_3DL_stereo_control
+ wglSetStereoEmitterState3DL: TwglSetStereoEmitterState3DL;
+
+ // WIN_draw_range_elements
+ glDrawRangeElementsWIN: TglDrawRangeElementsWIN;
+
+ // WIN_swap_hint
+ glAddSwapHintRectWIN: TglAddSwapHintRectWIN;
+{$ENDIF}
+
+{$IFDEF DGL_LINUX}
+ glXChooseVisual: TglXChooseVisual;
+ glXCopyContext: TglXCopyContext;
+ glXCreateContext: TglXCreateContext;
+ glXCreateGLXPixmap: TglXCreateGLXPixmap;
+ glXDestroyContext: TglXDestroyContext;
+ glXDestroyGLXPixmap: TglXDestroyGLXPixmap;
+ glXGetConfig: TglXGetConfig;
+ glXGetCurrentContext: TglXGetCurrentContext;
+ glXGetCurrentDrawable: TglXGetCurrentDrawable;
+ glXIsDirect: TglXIsDirect;
+ glXMakeCurrent: TglXMakeCurrent;
+ glXQueryExtension: TglXQueryExtension;
+ glXQueryVersion: TglXQueryVersion;
+ glXSwapBuffers: TglXSwapBuffers;
+ glXUseXFont: TglXUseXFont;
+ glXWaitGL: TglXWaitGL;
+ glXWaitX: TglXWaitX;
+
+ glXGetClientString: TglXGetClientString;
+ glXQueryServerString: TglXQueryServerString;
+ glXQueryExtensionsString: TglXQueryExtensionsString;
+
+ // GLX_VERSION_1_3
+ glXGetFBConfigs: TglXGetFBConfigs;
+ glXChooseFBConfig: TglXChooseFBConfig;
+ glXGetFBConfigAttrib: TglXGetFBConfigAttrib;
+ glXGetVisualFromFBConfig: TglXGetVisualFromFBConfig;
+ glXCreateWindow: TglXCreateWindow;
+ glXDestroyWindow: TglXDestroyWindow;
+ glXCreatePixmap: TglXCreatePixmap;
+
+ glXDestroyPixmap: TglXDestroyPixmap;
+ glXCreatePbuffer: TglXCreatePbuffer;
+ glXDestroyPbuffer: TglXDestroyPbuffer;
+ glXQueryDrawable: TglXQueryDrawable;
+ glXCreateNewContext: TglXCreateNewContext;
+ glXMakeContextCurrent: TglXMakeContextCurrent;
+ glXGetCurrentReadDrawable: TglXGetCurrentReadDrawable;
+ glXGetCurreentDisplay: TglXGetCurreentDisplay;
+
+ glXQueryContext: TglXQueryContext;
+ glXSelectEvent: TglXSelectEvent;
+ glXGetSelectedEvent: TglXGetSelectedEvent;
+
+ // GLX_VERSION_1_4
+ glXGetProcAddress: TglXGetProcAddress;
+
+ // GLX_ARB_get_proc_address
+ glXGetProcAddressARB: TglXGetProcAddressARB;
+
+ // GLX_ARB_create_context
+ glXCreateContextAttribsARB: TglXCreateContextAttribsARB;
+
+ // GLX_EXT_import_context
+ glXGetCurrentDisplayEXT: TglXGetCurrentDisplayEXT;
+ glXQueryContextInfoEXT: TglXQueryContextInfoEXT;
+ glXGetContextIDEXT: TglXGetContextIDEXT;
+ glXImportContextEXT: TglXImportContextEXT;
+ glXFreeContextEXT: TglXFreeContextEXT;
+
+ // GLX_EXT_texture_from_pixmap
+ glXBindTexImageEXT: TglXBindTexImageEXT;
+ glXReleaseTexImageEXT: TglXReleaseTexImageEXT;
+
+ glXSwapIntervalEXT : TglXSwapIntervalEXT;
+{$ENDIF}
+
+ // GL utility functions and procedures
+ gluErrorString: TgluErrorString;
+ gluGetString: TgluGetString;
+ gluOrtho2D: TgluOrtho2D;
+ gluPerspective: TgluPerspective;
+ gluPickMatrix: TgluPickMatrix;
+ gluLookAt: TgluLookAt;
+ gluProject: TgluProject;
+ gluUnProject: TgluUnProject;
+ gluScaleImage: TgluScaleImage;
+ gluBuild1DMipmaps: TgluBuild1DMipmaps;
+ gluBuild2DMipmaps: TgluBuild2DMipmaps;
+ gluNewQuadric: TgluNewQuadric;
+ gluDeleteQuadric: TgluDeleteQuadric;
+ gluQuadricNormals: TgluQuadricNormals;
+ gluQuadricTexture: TgluQuadricTexture;
+ gluQuadricOrientation: TgluQuadricOrientation;
+ gluQuadricDrawStyle: TgluQuadricDrawStyle;
+ gluCylinder: TgluCylinder;
+ gluDisk: TgluDisk;
+ gluPartialDisk: TgluPartialDisk;
+ gluSphere: TgluSphere;
+ gluQuadricCallback: TgluQuadricCallback;
+ gluNewTess: TgluNewTess;
+ gluDeleteTess: TgluDeleteTess;
+ gluTessBeginPolygon: TgluTessBeginPolygon;
+ gluTessBeginContour: TgluTessBeginContour;
+ gluTessVertex: TgluTessVertex;
+ gluTessEndContour: TgluTessEndContour;
+ gluTessEndPolygon: TgluTessEndPolygon;
+ gluTessProperty: TgluTessProperty;
+ gluTessNormal: TgluTessNormal;
+ gluTessCallback: TgluTessCallback;
+ gluGetTessProperty: TgluGetTessProperty;
+ gluNewNurbsRenderer: TgluNewNurbsRenderer;
+ gluDeleteNurbsRenderer: TgluDeleteNurbsRenderer;
+ gluBeginSurface: TgluBeginSurface;
+ gluBeginCurve: TgluBeginCurve;
+ gluEndCurve: TgluEndCurve;
+ gluEndSurface: TgluEndSurface;
+ gluBeginTrim: TgluBeginTrim;
+ gluEndTrim: TgluEndTrim;
+ gluPwlCurve: TgluPwlCurve;
+ gluNurbsCurve: TgluNurbsCurve;
+ gluNurbsSurface: TgluNurbsSurface;
+ gluLoadSamplingMatrices: TgluLoadSamplingMatrices;
+ gluNurbsProperty: TgluNurbsProperty;
+ gluGetNurbsProperty: TgluGetNurbsProperty;
+ gluNurbsCallback: TgluNurbsCallback;
+ gluBeginPolygon: TgluBeginPolygon;
+ gluNextContour: TgluNextContour;
+ gluEndPolygon: TgluEndPolygon;
+
+
+type
+ TRCOptions = set of (opDoubleBuffered, opGDI, opStereo);
+
+var
+ GL_LibHandle: Pointer = nil;
+ GLU_LibHandle: Pointer = nil;
+
+ LastPixelFormat: Integer;
+ ExtensionsRead: Boolean;
+ ImplementationRead: Boolean;
+
+
+const
+{$IFDEF DGL_WIN}
+ OPENGL_LIBNAME = 'OpenGL32.dll';
+ GLU_LIBNAME = 'GLU32.dll';
+{$ELSE}
+ {$IFDEF darwin}
+ //provide explicit paths for macOS libraries: https://gist.github.com/frostney/1044116
+ //OPENGL_LIBNAME = 'libGL.dylib';
+ //GLU_LIBNAME = 'libGLU.dylib';
+ OPENGL_LIBNAME = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib';
+ GLU_LIBNAME = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib';
+ {$ELSE}
+ OPENGL_LIBNAME = 'libGL.so.1';
+ GLU_LIBNAME = 'libGLU.so.1';
+ {$ENDIF}
+{$ENDIF}
+
+function InitOpenGL(LibName: String = OPENGL_LIBNAME; GLULibName: String = GLU_LIBNAME): Boolean;
+
+function dglGetProcAddress(ProcName: PAnsiChar; LibHandle: Pointer = nil {$IFDEF DGL_LINUX}; ForceDLSym: Boolean = False{$ENDIF}): Pointer;
+function dglCheckExtension(Extension: AnsiString): Boolean;
+
+procedure ReadExtensions;
+procedure ReadImplementationProperties;
+
+// =============================================================================
+// Helper-Functions
+// =============================================================================
+{$IFDEF DGL_WIN}
+ function CreateRenderingContext(DC: HDC; Options: TRCOptions; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
+ function CreateRenderingContextVersion(DC: HDC; Options: TRCOptions; MajorVersion, MinorVersion : Integer; ForwardCompatible : Boolean; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
+ procedure DestroyRenderingContext(RC: HGLRC);
+
+ procedure ActivateRenderingContext(DC: HDC; RC: HGLRC; loadext: boolean = true);
+ procedure DeactivateRenderingContext;
+{$ENDIF}
+
+
+procedure ReadOpenGLCore;
+procedure Read_GL_3DFX_tbuffer;
+procedure Read_GL_APPLE_element_array;
+procedure Read_GL_APPLE_fence;
+procedure Read_GL_APPLE_vertex_array_object;
+procedure Read_GL_APPLE_vertex_array_range;
+procedure Read_GL_APPLE_texture_range;
+procedure Read_GL_APPLE_vertex_program_evaluators;
+procedure Read_GL_APPLE_object_purgeable;
+procedure Read_GL_ARB_matrix_palette;
+procedure Read_GL_ARB_multitexture;
+procedure Read_GL_ARB_point_parameters;
+procedure Read_GL_ARB_texture_compression;
+procedure Read_GL_ARB_transpose_matrix;
+procedure Read_GL_ARB_vertex_blend;
+procedure Read_GL_ARB_vertex_buffer_object;
+procedure Read_GL_ARB_vertex_program;
+procedure Read_GL_ARB_window_pos;
+procedure Read_GL_ARB_color_buffer_float;
+procedure Read_GL_ARB_Shader_Objects;
+procedure Read_GL_ARB_occlusion_query;
+procedure Read_GL_ARB_draw_instanced;
+procedure Read_GL_ARB_framebuffer_object;
+procedure Read_GL_ARB_geometry_shader4;
+procedure Read_GL_ARB_gl_spirv;
+procedure Read_GL_ARB_instanced_arrays;
+procedure Read_GL_ARB_map_buffer_range;
+procedure Read_GL_ARB_texture_buffer_object;
+procedure Read_GL_ARB_vertex_array_object;
+procedure Read_GL_ARB_uniform_buffer_object;
+procedure Read_GL_ARB_copy_buffer;
+procedure Read_GL_ARB_draw_elements_base_vertex;
+procedure Read_GL_ARB_provoking_vertex;
+procedure Read_GL_ARB_sync;
+procedure Read_GL_ARB_texture_multisample;
+procedure Read_GL_ARB_draw_buffers_blend;
+procedure Read_GL_ARB_sample_shading;
+procedure Read_GL_ARB_sample_locations;
+procedure Read_GL_ARB_shading_language_include;
+procedure Read_GL_ARB_blend_func_extended;
+procedure Read_GL_ARB_sampler_objects;
+procedure Read_GL_ARB_timer_query;
+procedure Read_GL_ARB_vertex_type_2_10_10_10_rev;
+procedure Read_GL_ARB_draw_indirect;
+procedure Read_GL_ARB_gpu_shader_fp64;
+procedure Read_GL_ARB_gpu_shader_int64;
+procedure Read_GL_ARB_shader_subroutine;
+procedure Read_GL_ARB_tessellation_shader;
+procedure Read_GL_ARB_transform_feedback2;
+procedure Read_GL_ARB_transform_feedback3;
+procedure Read_GL_ARB_ES2_compatibility;
+procedure Read_GL_ARB_get_program_binary;
+procedure Read_GL_ARB_separate_shader_objects;
+procedure Read_GL_ARB_vertex_attrib_64bit;
+procedure Read_GL_ARB_viewport_array;
+
+procedure Read_GL_ARB_ES3_2_compatibility;
+procedure Read_GL_ARB_parallel_shader_compile;
+
+// GL 4.2
+procedure Read_GL_ARB_base_instance;
+procedure Read_GL_ARB_transform_feedback_instanced;
+procedure Read_GL_ARB_internalformat_query;
+procedure Read_GL_ARB_shader_atomic_counters;
+procedure Read_GL_ARB_shader_image_load_store;
+procedure Read_GL_ARB_texture_storage;
+// GL 4.3
+procedure Read_GL_KHR_debug;
+procedure Read_GL_ARB_clear_buffer_object;
+procedure Read_GL_ARB_compute_shader;
+procedure Read_GL_ARB_copy_image;
+procedure Read_GL_ARB_framebuffer_no_attachments;
+procedure Read_GL_ARB_internalformat_query2;
+procedure Read_GL_ARB_invalidate_subdata;
+procedure Read_GL_ARB_multi_draw_indirect;
+procedure Read_GL_ARB_program_interface_query;
+procedure Read_GL_ARB_shader_storage_buffer_object;
+procedure Read_GL_ARB_texture_buffer_range;
+procedure Read_GL_ARB_texture_storage_multisample;
+procedure Read_GL_ARB_texture_view;
+procedure Read_GL_ARB_vertex_attrib_binding;
+
+
+procedure Read_GL_4_4;
+procedure Read_GL_4_5;
+procedure Read_GL_4_6;
+
+//
+procedure Read_GL_ARB_cl_event;
+procedure Read_GL_ARB_compute_variable_group_size;
+procedure Read_GL_ARB_debug_output;
+procedure Read_GL_ARB_robustness;
+procedure Read_GL_ATI_draw_buffers;
+procedure Read_GL_ATI_element_array;
+procedure Read_GL_ATI_envmap_bumpmap;
+procedure Read_GL_ATI_fragment_shader;
+procedure Read_GL_ATI_map_object_buffer;
+procedure Read_GL_ATI_pn_triangles;
+procedure Read_GL_ATI_separate_stencil;
+procedure Read_GL_ATI_vertex_array_object;
+procedure Read_GL_ATI_vertex_attrib_array_object;
+procedure Read_GL_ATI_vertex_streams;
+procedure Read_GL_AMD_performance_monitor;
+procedure Read_GL_AMD_vertex_shader_tesselator;
+procedure Read_GL_AMD_draw_buffers_blend;
+procedure Read_GL_AMD_name_gen_delete;
+procedure Read_GL_AMD_debug_output;
+procedure Read_GL_EXT_blend_color;
+procedure Read_GL_EXT_blend_func_separate;
+procedure Read_GL_EXT_blend_minmax;
+procedure Read_GL_EXT_color_subtable;
+procedure Read_GL_EXT_compiled_vertex_array;
+procedure Read_GL_EXT_convolution;
+procedure Read_GL_EXT_coordinate_frame;
+procedure Read_GL_EXT_copy_texture;
+procedure Read_GL_EXT_cull_vertex;
+procedure Read_GL_EXT_draw_range_elements;
+procedure Read_GL_EXT_fog_coord;
+procedure Read_GL_EXT_framebuffer_object;
+procedure Read_GL_EXT_histogram;
+procedure Read_GL_EXT_index_func;
+procedure Read_GL_EXT_index_material;
+procedure Read_GL_EXT_multi_draw_arrays;
+procedure Read_GL_EXT_multisample;
+procedure Read_GL_EXT_paletted_texture;
+procedure Read_GL_EXT_pixel_transform;
+procedure Read_GL_EXT_point_parameters;
+procedure Read_GL_EXT_polygon_offset;
+procedure Read_GL_EXT_secondary_color;
+procedure Read_GL_EXT_stencil_two_side;
+procedure Read_GL_EXT_subtexture;
+procedure Read_GL_EXT_texture3D;
+procedure Read_GL_EXT_texture_object;
+procedure Read_GL_EXT_texture_perturb_normal;
+procedure Read_GL_EXT_vertex_array;
+procedure Read_GL_EXT_vertex_shader;
+procedure Read_GL_EXT_vertex_weighting;
+procedure Read_GL_EXT_depth_bounds_test;
+procedure Read_GL_EXT_blend_equation_separate;
+procedure Read_GL_EXT_stencil_clear_tag;
+procedure Read_GL_EXT_framebuffer_blit;
+procedure Read_GL_EXT_framebuffer_multisample;
+procedure Read_GL_EXT_timer_query;
+procedure Read_GL_EXT_gpu_program_parameters;
+procedure Read_GL_EXT_bindable_uniform;
+procedure Read_GL_EXT_draw_buffers2;
+procedure Read_GL_EXT_draw_instanced;
+procedure Read_GL_EXT_geometry_shader4;
+procedure Read_GL_EXT_gpu_shader4;
+procedure Read_GL_EXT_texture_array;
+procedure Read_GL_EXT_texture_buffer_object;
+procedure Read_GL_EXT_texture_integer;
+procedure Read_GL_EXT_transform_feedback;
+procedure Read_GL_EXT_direct_state_access;
+procedure Read_GL_EXT_separate_shader_objects;
+procedure Read_GL_EXT_shader_image_load_store;
+procedure Read_GL_EXT_vertex_attrib_64bit;
+procedure Read_GL_HP_image_transform;
+procedure Read_GL_IBM_multimode_draw_arrays;
+procedure Read_GL_IBM_vertex_array_lists;
+procedure Read_GL_INGR_blend_func_separate;
+procedure Read_GL_INTEL_parallel_arrays;
+procedure Read_GL_INTEL_framebuffer_CMAA;
+procedure Read_GL_MESA_resize_buffers;
+procedure Read_GL_MESA_window_pos;
+procedure Read_GL_NV_evaluators;
+procedure Read_GL_NV_fence;
+procedure Read_GL_NV_fragment_program;
+procedure Read_GL_NV_half_float;
+procedure Read_GL_NV_occlusion_query;
+procedure Read_GL_NV_pixel_data_range;
+procedure Read_GL_NV_point_sprite;
+procedure Read_GL_NV_primitive_restart;
+procedure Read_GL_NV_register_combiners;
+procedure Read_GL_NV_register_combiners2;
+procedure Read_GL_NV_vertex_array_range;
+procedure Read_GL_NV_vertex_program;
+procedure Read_GL_NV_depth_buffer_float;
+procedure Read_GL_NV_framebuffer_multisample_coverage;
+procedure Read_GL_NV_geometry_program4;
+procedure Read_GL_NV_gpu_program4;
+procedure Read_GL_NV_parameter_buffer_object;
+procedure Read_GL_NV_transform_feedback;
+procedure Read_GL_NV_conditional_render;
+procedure Read_GL_NV_conservative_raster;
+procedure Read_GL_NV_conservative_raster_dilate;
+procedure Read_GL_NV_present_video;
+procedure Read_GL_NV_explicit_multisample;
+procedure Read_GL_NV_transform_feedback2;
+procedure Read_GL_NV_video_capture;
+procedure Read_GL_NV_copy_image;
+procedure Read_GL_NV_shader_buffer_load;
+procedure Read_GL_NV_vertex_buffer_unified_memory;
+procedure Read_GL_NV_gpu_program5;
+procedure Read_GL_NV_gpu_shader5;
+procedure Read_GL_NV_vertex_attrib_integer_64bit;
+procedure Read_GL_NV_vdpau_interop;
+procedure Read_GL_NV_texture_barrier;
+procedure Read_GL_PGI_misc_hints;
+procedure Read_GL_OVR_multiview;
+procedure Read_GL_SGIS_detail_texture;
+procedure Read_GL_SGIS_fog_function;
+procedure Read_GL_SGIS_multisample;
+procedure Read_GL_SGIS_pixel_texture;
+procedure Read_GL_SGIS_point_parameters;
+procedure Read_GL_SGIS_sharpen_texture;
+procedure Read_GL_SGIS_texture4D;
+procedure Read_GL_SGIS_texture_color_mask;
+procedure Read_GL_SGIS_texture_filter4;
+procedure Read_GL_SGIX_async;
+procedure Read_GL_SGIX_flush_raster;
+procedure Read_GL_SGIX_fragment_lighting;
+procedure Read_GL_SGIX_framezoom;
+procedure Read_GL_SGIX_igloo_interface;
+procedure Read_GL_SGIX_instruments;
+procedure Read_GL_SGIX_list_priority;
+procedure Read_GL_SGIX_pixel_texture;
+procedure Read_GL_SGIX_polynomial_ffd;
+procedure Read_GL_SGIX_reference_plane;
+procedure Read_GL_SGIX_sprite;
+procedure Read_GL_SGIX_tag_sample_buffer;
+procedure Read_GL_SGI_color_table;
+procedure Read_GL_SUNX_constant_data;
+procedure Read_GL_SUN_global_alpha;
+procedure Read_GL_SUN_mesh_array;
+procedure Read_GL_SUN_triangle_list;
+procedure Read_GL_SUN_vertex;
+
+{$IFDEF DGL_WIN}
+procedure Read_WGL_ARB_buffer_region;
+procedure Read_WGL_ARB_extensions_string;
+procedure Read_WGL_ARB_make_current_read;
+procedure Read_WGL_ARB_pbuffer;
+procedure Read_WGL_ARB_pixel_format;
+procedure Read_WGL_ARB_pixel_format_float;
+procedure Read_WGL_ARB_render_texture;
+procedure Read_WGL_ARB_create_context;
+procedure Read_WGL_AMD_gpu_association;
+procedure Read_WGL_EXT_display_color_table;
+procedure Read_WGL_EXT_extensions_string;
+procedure Read_WGL_EXT_make_current_read;
+procedure Read_WGL_EXT_pbuffer;
+procedure Read_WGL_EXT_pixel_format;
+procedure Read_WGL_EXT_swap_control;
+procedure Read_WGL_I3D_digital_video_control;
+procedure Read_WGL_I3D_gamma;
+procedure Read_WGL_I3D_genlock;
+procedure Read_WGL_I3D_image_buffer;
+procedure Read_WGL_I3D_swap_frame_lock;
+procedure Read_WGL_I3D_swap_frame_usage;
+procedure Read_WGL_NV_vertex_array_range;
+procedure Read_WGL_NV_present_video;
+procedure Read_WGL_NV_video_output;
+procedure Read_WGL_NV_swap_group;
+procedure Read_WGL_NV_gpu_affinity;
+procedure Read_WGL_NV_video_capture;
+procedure Read_WGL_NV_copy_image;
+procedure Read_WGL_OML_sync_control;
+procedure Read_WGL_3DL_stereo_control;
+
+procedure Read_WIN_draw_range_elements;
+procedure Read_WIN_swap_hint;
+{$ENDIF}
+
+
+implementation
+
+
+{$IFDEF DGL_LINUX}
+const
+ RTLD_LAZY = $001;
+ RTLD_NOW = $002;
+ RTLD_BINDING_MASK = $003;
+
+ // Seems to work on Debian / Fedora
+ LibraryLib = {$IFDEF Linux} 'libdl.so.2'{$ELSE} 'c'{$ENDIF};
+
+function dlopen(Name: PAnsiChar; Flags: LongInt): Pointer; cdecl; external LibraryLib name 'dlopen';
+function dlclose(Lib: Pointer): LongInt; cdecl; external LibraryLib name 'dlclose';
+
+function dlsym(Lib: Pointer; Name: PAnsiChar): Pointer; cdecl; external LibraryLib name 'dlsym';
+{$ENDIF}
+
+{$IFDEF DGL_MAC}{$IFDEF OPENGL_FRAMEWORK} // OpenGL framework used
+const
+ RTLD_DEFAULT = Pointer(-2);
+{$ENDIF}{$ENDIF}
+
+function dglLoadLibrary(Name: PChar): Pointer;
+begin
+ {$IFDEF DGL_WIN}
+ Result := Pointer(LoadLibrary(Name));
+ {$ENDIF}
+
+ {$IFDEF DGL_LINUX}
+ Result := dlopen(Name, RTLD_LAZY);
+ {$ENDIF}
+
+ {$IFDEF DGL_MAC}
+ {$IFDEF OPENGL_FRAMEWORK}
+ Result := RTLD_DEFAULT;
+ {$ELSE}
+ Result := Pointer(LoadLibrary(Name));
+ {$ENDIF}
+ {$ENDIF}
+end;
+
+
+function dglFreeLibrary(LibHandle: Pointer): Boolean;
+begin
+ if LibHandle = nil then
+ Result := False
+ else
+ {$IFDEF DGL_WIN}
+ Result := FreeLibrary(HMODULE(LibHandle));
+ {$ENDIF}
+
+ {$IFDEF DGL_LINUX}
+ Result := dlclose(LibHandle) = 0;
+ {$ENDIF}
+
+ {$IFDEF DGL_MAC}
+ {$IFDEF OPENGL_FRAMEWORK}
+ Result := true;
+ {$ELSE}
+ Result := FreeLibrary(HMODULE(LibHandle));
+ {$ENDIF}
+ {$ENDIF}
+end;
+
+
+function dglGetProcAddress(ProcName: PAnsiChar; LibHandle: Pointer = nil {$IFDEF DGL_LINUX}; ForceDLSym: Boolean = False{$ENDIF}): Pointer;
+begin
+ if LibHandle = nil then
+ LibHandle := GL_LibHandle;
+
+
+ {$IFDEF DGL_WIN}
+ Result := GetProcAddress(HMODULE(LibHandle), ProcName);
+
+ if result <> nil then
+ exit;
+
+ if Addr(wglGetProcAddress) <> nil then
+ Result := wglGetProcAddress(ProcName);
+ {$ENDIF}
+
+ {$IFDEF DGL_LINUX}
+ if not ForceDLSym then begin
+ if Addr(glXGetProcAddress) <> nil then
+ Result := glXGetProcAddress(ProcName);
+
+ if result <> nil then
+ exit;
+
+ if Addr(glXGetProcAddressARB) <> nil then
+ Result := glXGetProcAddressARB(ProcName);
+
+ if result <> nil then
+ exit;
+ end;
+
+ Result := dlsym(LibHandle, ProcName);
+ {$ENDIF}
+
+ {$IFDEF DGL_MAC}
+ Result := GetProcAddress(HMODULE(LibHandle), ProcName);
+ {$ENDIF}
+end;
+
+
+function Int_GetExtensionString: AnsiString;
+var
+ ExtensionCount : GLuint;
+ i : Integer;
+begin
+ if GL_VERSION_3_0
+ then
+ begin
+ if not Assigned(@glGetIntegerv) then glGetIntegerv := dglGetProcAddress('glGetIntegerv');
+ if not Assigned(@glGetStringi) then glGetStringi := dglGetProcAddress('glGetStringi');
+
+ result := '';
+
+ if Assigned(@glGetIntegerv) and Assigned(@glGetStringi)
+ then
+ begin
+ glGetIntegerv(GL_NUM_EXTENSIONS, @extensionCount);
+
+ For I := 0 to extensionCount - 1 do
+ result := result + #32 + PAnsiChar(glGetStringi(GL_EXTENSIONS, I));
+ end;
+ end
+ else
+ begin
+ if not Assigned(@glGetString) then glGetString := dglGetProcAddress('glGetString');
+
+ if Assigned(@glGetString)
+ then result := glGetString(GL_EXTENSIONS)
+ else result := '';
+ end;
+
+ if (GL_LibHandle <> nil) then begin
+ {$IFDEF DGL_WIN}
+ // wglGetExtensionsStringEXT
+ if not Assigned(@wglGetExtensionsStringEXT) then
+ wglGetExtensionsStringEXT := dglGetProcAddress('wglGetExtensionsStringEXT');
+
+ if Assigned(@wglGetExtensionsStringEXT) then
+ Result := Result + #32 + wglGetExtensionsStringEXT;
+
+ // wglGetExtensionsStringARB
+ if not Assigned(@wglGetExtensionsStringARB) then
+ wglGetExtensionsStringARB := dglGetProcAddress('wglGetExtensionsStringARB');
+
+ if Assigned(@wglGetExtensionsStringARB) then
+ Result := Result + #32 + wglGetExtensionsStringARB(wglGetCurrentDC);
+ {$ENDIF}
+ end;
+
+ Result := #32 + Result + #32;
+end;
+
+
+function Int_CheckExtension(AllExtensions, CheckExtension: AnsiString): Boolean;
+begin
+ Result := Pos(#32 + CheckExtension + #32, AllExtensions) > 0;
+end;
+
+
+function dglCheckExtension(Extension: AnsiString): Boolean;
+var
+ Extensions: AnsiString;
+begin
+ Extensions := Int_GetExtensionString;
+ Result := Int_CheckExtension(Extensions, Extension);
+end;
+
+
+
+function InitOpenGL(LibName: String; GLULibName: String): Boolean;
+begin
+ Result := False;
+
+ // free opened libraries
+ if GL_LibHandle <> nil then
+ dglFreeLibrary(GL_LibHandle);
+
+ if GLU_LibHandle <> nil then
+ dglFreeLibrary(GLU_LibHandle);
+
+ // load library
+ GL_LibHandle := dglLoadLibrary(PChar(LibName));
+ GLU_LibHandle := dglLoadLibrary(PChar(GLULibName));
+
+ // load GL functions
+ if (GL_LibHandle <> nil) then begin
+ {$IFDEF DGL_WIN}
+ wglCopyContext := dglGetProcAddress('wglCopyContext');
+ wglCreateLayerContext := dglGetProcAddress('wglCreateLayerContext');
+ wglCreateContext := dglGetProcAddress('wglCreateContext');
+ wglDeleteContext := dglGetProcAddress('wglDeleteContext');
+ wglDescribeLayerPlane := dglGetProcAddress('wglDescribeLayerPlane');
+ wglGetCurrentContext := dglGetProcAddress('wglGetCurrentContext');
+ wglGetCurrentDC := dglGetProcAddress('wglGetCurrentDC');
+ wglGetLayerPaletteEntries := dglGetProcAddress('wglGetLayerPaletteEntries');
+ wglGetProcAddress := dglGetProcAddress('wglGetProcAddress');
+ wglMakeCurrent := dglGetProcAddress('wglMakeCurrent');
+ wglRealizeLayerPalette := dglGetProcAddress('wglRealizeLayerPalette');
+ wglSetLayerPaletteEntries := dglGetProcAddress('wglSetLayerPaletteEntries');
+ wglShareLists := dglGetProcAddress('wglShareLists');
+ wglSwapLayerBuffers := dglGetProcAddress('wglSwapLayerBuffers');
+ wglSwapMultipleBuffers := dglGetProcAddress('wglSwapMultipleBuffers');
+ wglUseFontBitmapsA := dglGetProcAddress('wglUseFontBitmapsA');
+ wglUseFontOutlinesA := dglGetProcAddress('wglUseFontOutlinesA');
+ wglUseFontBitmapsW := dglGetProcAddress('wglUseFontBitmapsW');
+ wglUseFontOutlinesW := dglGetProcAddress('wglUseFontOutlinesW');
+ wglUseFontBitmaps := dglGetProcAddress('wglUseFontBitmapsA');
+ wglUseFontOutlines := dglGetProcAddress('wglUseFontOutlinesA');
+ {$ENDIF}
+
+ {$IFDEF DGL_LINUX}
+ // GLX_VERSION_1_4 (needs to be first)
+ glXGetProcAddress := dglGetProcAddress('glXGetProcAddress', nil, True);
+
+ // GLX_ARB_get_proc_address (also needs to be first)
+ glXGetProcAddressARB := dglGetProcAddress('glXGetProcAddressARB', nil, True);
+
+ glXChooseVisual := dglGetProcAddress('glXChooseVisual');
+ glXCopyContext := dglGetProcAddress('glXCopyContext');
+ glXCreateContext := dglGetProcAddress('glXCreateContext');
+ glXCreateGLXPixmap := dglGetProcAddress('glXCreateGLXPixmap');
+ glXDestroyContext := dglGetProcAddress('glXDestroyContext');
+ glXDestroyGLXPixmap := dglGetProcAddress('glXDestroyGLXPixmap');
+ glXGetConfig := dglGetProcAddress('glXGetConfig');
+ glXGetCurrentContext := dglGetProcAddress('glXGetCurrentContext');
+ glXGetCurrentDrawable := dglGetProcAddress('glXGetCurrentDrawable');
+ glXIsDirect := dglGetProcAddress('glXIsDirect');
+ glXMakeCurrent := dglGetProcAddress('glXMakeCurrent');
+ glXQueryExtension := dglGetProcAddress('glXQueryExtension');
+ glXQueryVersion := dglGetProcAddress('glXQueryVersion');
+ glXSwapBuffers := dglGetProcAddress('glXSwapBuffers');
+ glXUseXFont := dglGetProcAddress('glXUseXFont');
+ glXWaitGL := dglGetProcAddress('glXWaitGL');
+ glXWaitX := dglGetProcAddress('glXWaitX');
+
+ glXGetClientString := dglGetProcAddress('glXGetClientString');
+ glXQueryServerString := dglGetProcAddress('glXQueryServerString');
+ glXQueryExtensionsString := dglGetProcAddress('glXQueryExtensionsString');
+
+ // GLX_VERSION_1_3
+ glXGetFBConfigs := dglGetProcAddress('glXGetFBConfigs');
+ glXChooseFBConfig := dglGetProcAddress('glXChooseFBConfig');
+ glXGetFBConfigAttrib := dglGetProcAddress('glXGetFBConfigAttrib');
+ glXGetVisualFromFBConfig := dglGetProcAddress('glXGetVisualFromFBConfig');
+ glXCreateWindow := dglGetProcAddress('glXCreateWindow');
+ glXDestroyWindow := dglGetProcAddress('glXDestroyWindow');
+ glXCreatePixmap := dglGetProcAddress('glXCreatePixmap');
+
+ glXDestroyPixmap := dglGetProcAddress('glXDestroyPixmap');
+ glXCreatePbuffer := dglGetProcAddress('glXCreatePbuffer');
+ glXDestroyPbuffer := dglGetProcAddress('glXDestroyPbuffer');
+ glXQueryDrawable := dglGetProcAddress('glXQueryDrawable');
+ glXCreateNewContext := dglGetProcAddress('glXCreateNewContext');
+ glXMakeContextCurrent := dglGetProcAddress('glXMakeContextCurrent');
+ glXGetCurrentReadDrawable := dglGetProcAddress('glXGetCurrentReadDrawable');
+ glXGetCurreentDisplay := dglGetProcAddress('glXGetCurreentDisplay');
+
+ glXQueryContext := dglGetProcAddress('glXQueryContext');
+ glXSelectEvent := dglGetProcAddress('glXSelectEvent');
+ glXGetSelectedEvent := dglGetProcAddress('glXGetSelectedEvent');
+
+ // GLX_ARB_create_context
+ glXCreateContextAttribsARB := dglGetProcAddress('glXCreateContextAttribsARB');
+
+ // GLX_EXT_import_context
+ glXGetCurrentDisplayEXT := dglGetProcAddress('glXGetCurrentDisplayEXT');
+ glXQueryContextInfoEXT := dglGetProcAddress('glXQueryContextInfoEXT');
+ glXGetContextIDEXT := dglGetProcAddress('glXGetContextIDEXT');
+ glXImportContextEXT := dglGetProcAddress('glXImportContextEXT');
+ glXFreeContextEXT := dglGetProcAddress('glXFreeContextEXT');
+
+ // GLX_EXT_texture_from_pixmap
+ glXBindTexImageEXT := dglGetProcAddress('glXBindTexImageEXT');
+ glXReleaseTexImageEXT := dglGetProcAddress('glXReleaseTexImageEXT');
+
+ glXSwapIntervalEXT := dglGetProcAddress('glXSwapIntervalEXT');
+ {$ENDIF}
+
+ Result := True;
+ end;
+
+ // load GLU functions
+ if GLU_LibHandle <> nil then begin
+ // GLU ========================================================================
+ gluBeginCurve := dglGetProcAddress('gluBeginCurve', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluBeginPolygon := dglGetProcAddress('gluBeginPolygon', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluBeginSurface := dglGetProcAddress('gluBeginSurface', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluBeginTrim := dglGetProcAddress('gluBeginTrim', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluBuild1DMipmaps := dglGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluBuild2DMipmaps := dglGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluCylinder := dglGetProcAddress('gluCylinder', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluDeleteNurbsRenderer := dglGetProcAddress('gluDeleteNurbsRenderer', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluDeleteQuadric := dglGetProcAddress('gluDeleteQuadric', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluDeleteTess := dglGetProcAddress('gluDeleteTess', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluDisk := dglGetProcAddress('gluDisk', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluEndCurve := dglGetProcAddress('gluEndCurve', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluEndPolygon := dglGetProcAddress('gluEndPolygon', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluEndSurface := dglGetProcAddress('gluEndSurface', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluEndTrim := dglGetProcAddress('gluEndTrim', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluErrorString := dglGetProcAddress('gluErrorString', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluGetNurbsProperty := dglGetProcAddress('gluGetNurbsProperty', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluGetString := dglGetProcAddress('gluGetString', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluGetTessProperty := dglGetProcAddress('gluGetTessProperty', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluLoadSamplingMatrices := dglGetProcAddress('gluLoadSamplingMatrices', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluLookAt := dglGetProcAddress('gluLookAt', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNewNurbsRenderer := dglGetProcAddress('gluNewNurbsRenderer', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNewQuadric := dglGetProcAddress('gluNewQuadric', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNewTess := dglGetProcAddress('gluNewTess', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNextContour := dglGetProcAddress('gluNextContour', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNurbsCallback := dglGetProcAddress('gluNurbsCallback', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNurbsCurve := dglGetProcAddress('gluNurbsCurve', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNurbsProperty := dglGetProcAddress('gluNurbsProperty', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluNurbsSurface := dglGetProcAddress('gluNurbsSurface', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluOrtho2D := dglGetProcAddress('gluOrtho2D', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluPartialDisk := dglGetProcAddress('gluPartialDisk', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluPerspective := dglGetProcAddress('gluPerspective', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluPickMatrix := dglGetProcAddress('gluPickMatrix', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluProject := dglGetProcAddress('gluProject', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluPwlCurve := dglGetProcAddress('gluPwlCurve', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluQuadricCallback := dglGetProcAddress('gluQuadricCallback', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluQuadricDrawStyle := dglGetProcAddress('gluQuadricDrawStyle', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluQuadricNormals := dglGetProcAddress('gluQuadricNormals', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluQuadricOrientation := dglGetProcAddress('gluQuadricOrientation', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluQuadricTexture := dglGetProcAddress('gluQuadricTexture', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluScaleImage := dglGetProcAddress('gluScaleImage', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluSphere := dglGetProcAddress('gluSphere', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessBeginContour := dglGetProcAddress('gluTessBeginContour', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessBeginPolygon := dglGetProcAddress('gluTessBeginPolygon', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessCallback := dglGetProcAddress('gluTessCallback', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessEndContour := dglGetProcAddress('gluTessEndContour', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessEndPolygon := dglGetProcAddress('gluTessEndPolygon', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessNormal := dglGetProcAddress('gluTessNormal', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessProperty := dglGetProcAddress('gluTessProperty', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluTessVertex := dglGetProcAddress('gluTessVertex', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ gluUnProject := dglGetProcAddress('gluUnProject', GLU_LibHandle {$IFDEF DGL_LINUX}, True{$ENDIF});
+ end;
+end;
+
+procedure ReadOpenGLCore;
+begin
+ // GL_VERSION_1_0
+ glCullFace := dglGetProcAddress('glCullFace');
+ glFrontFace := dglGetProcAddress('glFrontFace');
+ glHint := dglGetProcAddress('glHint');
+ glLineWidth := dglGetProcAddress('glLineWidth');
+ glPointSize := dglGetProcAddress('glPointSize');
+ glPolygonMode := dglGetProcAddress('glPolygonMode');
+ glScissor := dglGetProcAddress('glScissor');
+ glTexParameterf := dglGetProcAddress('glTexParameterf');
+ glTexParameterfv := dglGetProcAddress('glTexParameterfv');
+ glTexParameteri := dglGetProcAddress('glTexParameteri');
+ glTexParameteriv := dglGetProcAddress('glTexParameteriv');
+ glTexImage1D := dglGetProcAddress('glTexImage1D');
+ glTexImage2D := dglGetProcAddress('glTexImage2D');
+ glDrawBuffer := dglGetProcAddress('glDrawBuffer');
+ glClear := dglGetProcAddress('glClear');
+ glClearColor := dglGetProcAddress('glClearColor');
+ glClearStencil := dglGetProcAddress('glClearStencil');
+ glClearDepth := dglGetProcAddress('glClearDepth');
+ glStencilMask := dglGetProcAddress('glStencilMask');
+ glColorMask := dglGetProcAddress('glColorMask');
+ glDepthMask := dglGetProcAddress('glDepthMask');
+ glDisable := dglGetProcAddress('glDisable');
+ glEnable := dglGetProcAddress('glEnable');
+ glFinish := dglGetProcAddress('glFinish');
+ glFlush := dglGetProcAddress('glFlush');
+ glBlendFunc := dglGetProcAddress('glBlendFunc');
+ glLogicOp := dglGetProcAddress('glLogicOp');
+ glStencilFunc := dglGetProcAddress('glStencilFunc');
+ glStencilOp := dglGetProcAddress('glStencilOp');
+ glDepthFunc := dglGetProcAddress('glDepthFunc');
+ glPixelStoref := dglGetProcAddress('glPixelStoref');
+ glPixelStorei := dglGetProcAddress('glPixelStorei');
+ glReadBuffer := dglGetProcAddress('glReadBuffer');
+ glReadPixels := dglGetProcAddress('glReadPixels');
+ glGetBooleanv := dglGetProcAddress('glGetBooleanv');
+ glGetDoublev := dglGetProcAddress('glGetDoublev');
+ glGetError := dglGetProcAddress('glGetError');
+ glGetFloatv := dglGetProcAddress('glGetFloatv');
+ glGetIntegerv := dglGetProcAddress('glGetIntegerv');
+ glGetString := dglGetProcAddress('glGetString');
+ glGetTexImage := dglGetProcAddress('glGetTexImage');
+ glGetTexParameteriv := dglGetProcAddress('glGetTexParameteriv');
+ glGetTexParameterfv := dglGetProcAddress('glGetTexParameterfv');
+ glGetTexLevelParameterfv := dglGetProcAddress('glGetTexLevelParameterfv');
+ glGetTexLevelParameteriv := dglGetProcAddress('glGetTexLevelParameteriv');
+ glIsEnabled := dglGetProcAddress('glIsEnabled');
+ glDepthRange := dglGetProcAddress('glDepthRange');
+ glViewport := dglGetProcAddress('glViewport');
+
+ // GL_VERSION_1_1
+ glDrawArrays := dglGetProcAddress('glDrawArrays');
+ glDrawElements := dglGetProcAddress('glDrawElements');
+ glGetPointerv := dglGetProcAddress('glGetPointerv');
+ glPolygonOffset := dglGetProcAddress('glPolygonOffset');
+ glCopyTexImage1D := dglGetProcAddress('glCopyTexImage1D');
+ glCopyTexImage2D := dglGetProcAddress('glCopyTexImage2D');
+ glCopyTexSubImage1D := dglGetProcAddress('glCopyTexSubImage1D');
+ glCopyTexSubImage2D := dglGetProcAddress('glCopyTexSubImage2D');
+ glTexSubImage1D := dglGetProcAddress('glTexSubImage1D');
+ glTexSubImage2D := dglGetProcAddress('glTexSubImage2D');
+ glBindTexture := dglGetProcAddress('glBindTexture');
+ glDeleteTextures := dglGetProcAddress('glDeleteTextures');
+ glGenTextures := dglGetProcAddress('glGenTextures');
+
+{$ifdef DGL_DEPRECATED}
+ glAccum := dglGetProcAddress('glAccum');
+ glAlphaFunc := dglGetProcAddress('glAlphaFunc');
+ glAreTexturesResident := dglGetProcAddress('glAreTexturesResident');
+ glArrayElement := dglGetProcAddress('glArrayElement');
+ glBegin := dglGetProcAddress('glBegin');
+ glBitmap := dglGetProcAddress('glBitmap');
+ glCallList := dglGetProcAddress('glCallList');
+ glCallLists := dglGetProcAddress('glCallLists');
+ glClearAccum := dglGetProcAddress('glClearAccum');
+ glClearIndex := dglGetProcAddress('glClearIndex');
+ glClipPlane := dglGetProcAddress('glClipPlane');
+ glColor3b := dglGetProcAddress('glColor3b');
+ glColor3bv := dglGetProcAddress('glColor3bv');
+ glColor3d := dglGetProcAddress('glColor3d');
+ glColor3dv := dglGetProcAddress('glColor3dv');
+ glColor3f := dglGetProcAddress('glColor3f');
+ glColor3fv := dglGetProcAddress('glColor3fv');
+ glColor3i := dglGetProcAddress('glColor3i');
+ glColor3iv := dglGetProcAddress('glColor3iv');
+ glColor3s := dglGetProcAddress('glColor3s');
+ glColor3sv := dglGetProcAddress('glColor3sv');
+ glColor3ub := dglGetProcAddress('glColor3ub');
+ glColor3ubv := dglGetProcAddress('glColor3ubv');
+ glColor3ui := dglGetProcAddress('glColor3ui');
+ glColor3uiv := dglGetProcAddress('glColor3uiv');
+ glColor3us := dglGetProcAddress('glColor3us');
+ glColor3usv := dglGetProcAddress('glColor3usv');
+ glColor4b := dglGetProcAddress('glColor4b');
+ glColor4bv := dglGetProcAddress('glColor4bv');
+ glColor4d := dglGetProcAddress('glColor4d');
+ glColor4dv := dglGetProcAddress('glColor4dv');
+ glColor4f := dglGetProcAddress('glColor4f');
+ glColor4fv := dglGetProcAddress('glColor4fv');
+ glColor4i := dglGetProcAddress('glColor4i');
+ glColor4iv := dglGetProcAddress('glColor4iv');
+ glColor4s := dglGetProcAddress('glColor4s');
+ glColor4sv := dglGetProcAddress('glColor4sv');
+ glColor4ub := dglGetProcAddress('glColor4ub');
+ glColor4ubv := dglGetProcAddress('glColor4ubv');
+ glColor4ui := dglGetProcAddress('glColor4ui');
+ glColor4uiv := dglGetProcAddress('glColor4uiv');
+ glColor4us := dglGetProcAddress('glColor4us');
+ glColor4usv := dglGetProcAddress('glColor4usv');
+ glColorMaterial := dglGetProcAddress('glColorMaterial');
+ glColorPointer := dglGetProcAddress('glColorPointer');
+ glCopyPixels := dglGetProcAddress('glCopyPixels');
+ glDeleteLists := dglGetProcAddress('glDeleteLists');
+ glDisableClientState := dglGetProcAddress('glDisableClientState');
+ glDrawPixels := dglGetProcAddress('glDrawPixels');
+ glEdgeFlag := dglGetProcAddress('glEdgeFlag');
+ glEdgeFlagPointer := dglGetProcAddress('glEdgeFlagPointer');
+ glEdgeFlagv := dglGetProcAddress('glEdgeFlagv');
+ glEnableClientState := dglGetProcAddress('glEnableClientState');
+ glEnd := dglGetProcAddress('glEnd');
+ glEndList := dglGetProcAddress('glEndList');
+ glEvalCoord1d := dglGetProcAddress('glEvalCoord1d');
+ glEvalCoord1dv := dglGetProcAddress('glEvalCoord1dv');
+ glEvalCoord1f := dglGetProcAddress('glEvalCoord1f');
+ glEvalCoord1fv := dglGetProcAddress('glEvalCoord1fv');
+ glEvalCoord2d := dglGetProcAddress('glEvalCoord2d');
+ glEvalCoord2dv := dglGetProcAddress('glEvalCoord2dv');
+ glEvalCoord2f := dglGetProcAddress('glEvalCoord2f');
+ glEvalCoord2fv := dglGetProcAddress('glEvalCoord2fv');
+ glEvalMesh1 := dglGetProcAddress('glEvalMesh1');
+ glEvalMesh2 := dglGetProcAddress('glEvalMesh2');
+ glEvalPoint1 := dglGetProcAddress('glEvalPoint1');
+ glEvalPoint2 := dglGetProcAddress('glEvalPoint2');
+ glFeedbackBuffer := dglGetProcAddress('glFeedbackBuffer');
+ glFogf := dglGetProcAddress('glFogf');
+ glFogfv := dglGetProcAddress('glFogfv');
+ glFogi := dglGetProcAddress('glFogi');
+ glFogiv := dglGetProcAddress('glFogiv');
+ glFrustum := dglGetProcAddress('glFrustum');
+ glGenLists := dglGetProcAddress('glGenLists');
+ glGetClipPlane := dglGetProcAddress('glGetClipPlane');
+ glGetLightfv := dglGetProcAddress('glGetLightfv');
+ glGetLightiv := dglGetProcAddress('glGetLightiv');
+ glGetMapdv := dglGetProcAddress('glGetMapdv');
+ glGetMapfv := dglGetProcAddress('glGetMapfv');
+ glGetMapiv := dglGetProcAddress('glGetMapiv');
+ glGetMaterialfv := dglGetProcAddress('glGetMaterialfv');
+ glGetMaterialiv := dglGetProcAddress('glGetMaterialiv');
+ glGetPixelMapfv := dglGetProcAddress('glGetPixelMapfv');
+ glGetPixelMapuiv := dglGetProcAddress('glGetPixelMapuiv');
+ glGetPixelMapusv := dglGetProcAddress('glGetPixelMapusv');
+ glGetPolygonStipple := dglGetProcAddress('glGetPolygonStipple');
+ glGetTexEnvfv := dglGetProcAddress('glGetTexEnvfv');
+ glGetTexEnviv := dglGetProcAddress('glGetTexEnviv');
+ glGetTexGendv := dglGetProcAddress('glGetTexGendv');
+ glGetTexGenfv := dglGetProcAddress('glGetTexGenfv');
+ glGetTexGeniv := dglGetProcAddress('glGetTexGeniv');
+ glIndexMask := dglGetProcAddress('glIndexMask');
+ glIndexPointer := dglGetProcAddress('glIndexPointer');
+ glIndexd := dglGetProcAddress('glIndexd');
+ glIndexdv := dglGetProcAddress('glIndexdv');
+ glIndexf := dglGetProcAddress('glIndexf');
+ glIndexfv := dglGetProcAddress('glIndexfv');
+ glIndexi := dglGetProcAddress('glIndexi');
+ glIndexiv := dglGetProcAddress('glIndexiv');
+ glIndexs := dglGetProcAddress('glIndexs');
+ glIndexsv := dglGetProcAddress('glIndexsv');
+ glIndexub := dglGetProcAddress('glIndexub');
+ glIndexubv := dglGetProcAddress('glIndexubv');
+ glInitNames := dglGetProcAddress('glInitNames');
+ glInterleavedArrays := dglGetProcAddress('glInterleavedArrays');
+ glIsList := dglGetProcAddress('glIsList');
+ glIsTexture := dglGetProcAddress('glIsTexture');
+ glLightModelf := dglGetProcAddress('glLightModelf');
+ glLightModelfv := dglGetProcAddress('glLightModelfv');
+ glLightModeli := dglGetProcAddress('glLightModeli');
+ glLightModeliv := dglGetProcAddress('glLightModeliv');
+ glLightf := dglGetProcAddress('glLightf');
+ glLightfv := dglGetProcAddress('glLightfv');
+ glLighti := dglGetProcAddress('glLighti');
+ glLightiv := dglGetProcAddress('glLightiv');
+ glLineStipple := dglGetProcAddress('glLineStipple');
+ glListBase := dglGetProcAddress('glListBase');
+ glLoadIdentity := dglGetProcAddress('glLoadIdentity');
+ glLoadMatrixd := dglGetProcAddress('glLoadMatrixd');
+ glLoadMatrixf := dglGetProcAddress('glLoadMatrixf');
+ glLoadName := dglGetProcAddress('glLoadName');
+ glMap1d := dglGetProcAddress('glMap1d');
+ glMap1f := dglGetProcAddress('glMap1f');
+ glMap2d := dglGetProcAddress('glMap2d');
+ glMap2f := dglGetProcAddress('glMap2f');
+ glMapGrid1d := dglGetProcAddress('glMapGrid1d');
+ glMapGrid1f := dglGetProcAddress('glMapGrid1f');
+ glMapGrid2d := dglGetProcAddress('glMapGrid2d');
+ glMapGrid2f := dglGetProcAddress('glMapGrid2f');
+ glMaterialf := dglGetProcAddress('glMaterialf');
+ glMaterialfv := dglGetProcAddress('glMaterialfv');
+ glMateriali := dglGetProcAddress('glMateriali');
+ glMaterialiv := dglGetProcAddress('glMaterialiv');
+ glMatrixMode := dglGetProcAddress('glMatrixMode');
+ glMultMatrixd := dglGetProcAddress('glMultMatrixd');
+ glMultMatrixf := dglGetProcAddress('glMultMatrixf');
+ glNewList := dglGetProcAddress('glNewList');
+ glNormal3b := dglGetProcAddress('glNormal3b');
+ glNormal3bv := dglGetProcAddress('glNormal3bv');
+ glNormal3d := dglGetProcAddress('glNormal3d');
+ glNormal3dv := dglGetProcAddress('glNormal3dv');
+ glNormal3f := dglGetProcAddress('glNormal3f');
+ glNormal3fv := dglGetProcAddress('glNormal3fv');
+ glNormal3i := dglGetProcAddress('glNormal3i');
+ glNormal3iv := dglGetProcAddress('glNormal3iv');
+ glNormal3s := dglGetProcAddress('glNormal3s');
+ glNormal3sv := dglGetProcAddress('glNormal3sv');
+ glNormalPointer := dglGetProcAddress('glNormalPointer');
+ glOrtho := dglGetProcAddress('glOrtho');
+ glPassThrough := dglGetProcAddress('glPassThrough');
+ glPixelMapfv := dglGetProcAddress('glPixelMapfv');
+ glPixelMapuiv := dglGetProcAddress('glPixelMapuiv');
+ glPixelMapusv := dglGetProcAddress('glPixelMapusv');
+ glPixelTransferf := dglGetProcAddress('glPixelTransferf');
+ glPixelTransferi := dglGetProcAddress('glPixelTransferi');
+ glPixelZoom := dglGetProcAddress('glPixelZoom');
+ glPolygonStipple := dglGetProcAddress('glPolygonStipple');
+ glPopAttrib := dglGetProcAddress('glPopAttrib');
+ glPopClientAttrib := dglGetProcAddress('glPopClientAttrib');
+ glPopMatrix := dglGetProcAddress('glPopMatrix');
+ glPopName := dglGetProcAddress('glPopName');
+ glPrioritizeTextures := dglGetProcAddress('glPrioritizeTextures');
+ glPushAttrib := dglGetProcAddress('glPushAttrib');
+ glPushClientAttrib := dglGetProcAddress('glPushClientAttrib');
+ glPushMatrix := dglGetProcAddress('glPushMatrix');
+ glPushName := dglGetProcAddress('glPushName');
+ glRasterPos2d := dglGetProcAddress('glRasterPos2d');
+ glRasterPos2dv := dglGetProcAddress('glRasterPos2dv');
+ glRasterPos2f := dglGetProcAddress('glRasterPos2f');
+ glRasterPos2fv := dglGetProcAddress('glRasterPos2fv');
+ glRasterPos2i := dglGetProcAddress('glRasterPos2i');
+ glRasterPos2iv := dglGetProcAddress('glRasterPos2iv');
+ glRasterPos2s := dglGetProcAddress('glRasterPos2s');
+ glRasterPos2sv := dglGetProcAddress('glRasterPos2sv');
+ glRasterPos3d := dglGetProcAddress('glRasterPos3d');
+ glRasterPos3dv := dglGetProcAddress('glRasterPos3dv');
+ glRasterPos3f := dglGetProcAddress('glRasterPos3f');
+ glRasterPos3fv := dglGetProcAddress('glRasterPos3fv');
+ glRasterPos3i := dglGetProcAddress('glRasterPos3i');
+ glRasterPos3iv := dglGetProcAddress('glRasterPos3iv');
+ glRasterPos3s := dglGetProcAddress('glRasterPos3s');
+ glRasterPos3sv := dglGetProcAddress('glRasterPos3sv');
+ glRasterPos4d := dglGetProcAddress('glRasterPos4d');
+ glRasterPos4dv := dglGetProcAddress('glRasterPos4dv');
+ glRasterPos4f := dglGetProcAddress('glRasterPos4f');
+ glRasterPos4fv := dglGetProcAddress('glRasterPos4fv');
+ glRasterPos4i := dglGetProcAddress('glRasterPos4i');
+ glRasterPos4iv := dglGetProcAddress('glRasterPos4iv');
+ glRasterPos4s := dglGetProcAddress('glRasterPos4s');
+ glRasterPos4sv := dglGetProcAddress('glRasterPos4sv');
+ glRectd := dglGetProcAddress('glRectd');
+ glRectdv := dglGetProcAddress('glRectdv');
+ glRectf := dglGetProcAddress('glRectf');
+ glRectfv := dglGetProcAddress('glRectfv');
+ glRecti := dglGetProcAddress('glRecti');
+ glRectiv := dglGetProcAddress('glRectiv');
+ glRects := dglGetProcAddress('glRects');
+ glRectsv := dglGetProcAddress('glRectsv');
+ glRenderMode := dglGetProcAddress('glRenderMode');
+ glRotated := dglGetProcAddress('glRotated');
+ glRotatef := dglGetProcAddress('glRotatef');
+ glScaled := dglGetProcAddress('glScaled');
+ glScalef := dglGetProcAddress('glScalef');
+ glSelectBuffer := dglGetProcAddress('glSelectBuffer');
+ glShadeModel := dglGetProcAddress('glShadeModel');
+ glTexCoord1d := dglGetProcAddress('glTexCoord1d');
+ glTexCoord1dv := dglGetProcAddress('glTexCoord1dv');
+ glTexCoord1f := dglGetProcAddress('glTexCoord1f');
+ glTexCoord1fv := dglGetProcAddress('glTexCoord1fv');
+ glTexCoord1i := dglGetProcAddress('glTexCoord1i');
+ glTexCoord1iv := dglGetProcAddress('glTexCoord1iv');
+ glTexCoord1s := dglGetProcAddress('glTexCoord1s');
+ glTexCoord1sv := dglGetProcAddress('glTexCoord1sv');
+ glTexCoord2d := dglGetProcAddress('glTexCoord2d');
+ glTexCoord2dv := dglGetProcAddress('glTexCoord2dv');
+ glTexCoord2f := dglGetProcAddress('glTexCoord2f');
+ glTexCoord2fv := dglGetProcAddress('glTexCoord2fv');
+ glTexCoord2i := dglGetProcAddress('glTexCoord2i');
+ glTexCoord2iv := dglGetProcAddress('glTexCoord2iv');
+ glTexCoord2s := dglGetProcAddress('glTexCoord2s');
+ glTexCoord2sv := dglGetProcAddress('glTexCoord2sv');
+ glTexCoord3d := dglGetProcAddress('glTexCoord3d');
+ glTexCoord3dv := dglGetProcAddress('glTexCoord3dv');
+ glTexCoord3f := dglGetProcAddress('glTexCoord3f');
+ glTexCoord3fv := dglGetProcAddress('glTexCoord3fv');
+ glTexCoord3i := dglGetProcAddress('glTexCoord3i');
+ glTexCoord3iv := dglGetProcAddress('glTexCoord3iv');
+ glTexCoord3s := dglGetProcAddress('glTexCoord3s');
+ glTexCoord3sv := dglGetProcAddress('glTexCoord3sv');
+ glTexCoord4d := dglGetProcAddress('glTexCoord4d');
+ glTexCoord4dv := dglGetProcAddress('glTexCoord4dv');
+ glTexCoord4f := dglGetProcAddress('glTexCoord4f');
+ glTexCoord4fv := dglGetProcAddress('glTexCoord4fv');
+ glTexCoord4i := dglGetProcAddress('glTexCoord4i');
+ glTexCoord4iv := dglGetProcAddress('glTexCoord4iv');
+ glTexCoord4s := dglGetProcAddress('glTexCoord4s');
+ glTexCoord4sv := dglGetProcAddress('glTexCoord4sv');
+ glTexCoordPointer := dglGetProcAddress('glTexCoordPointer');
+ glTexEnvf := dglGetProcAddress('glTexEnvf');
+ glTexEnvfv := dglGetProcAddress('glTexEnvfv');
+ glTexEnvi := dglGetProcAddress('glTexEnvi');
+ glTexEnviv := dglGetProcAddress('glTexEnviv');
+ glTexGend := dglGetProcAddress('glTexGend');
+ glTexGendv := dglGetProcAddress('glTexGendv');
+ glTexGenf := dglGetProcAddress('glTexGenf');
+ glTexGenfv := dglGetProcAddress('glTexGenfv');
+ glTexGeni := dglGetProcAddress('glTexGeni');
+ glTexGeniv := dglGetProcAddress('glTexGeniv');
+ glTranslated := dglGetProcAddress('glTranslated');
+ glTranslatef := dglGetProcAddress('glTranslatef');
+ glVertex2d := dglGetProcAddress('glVertex2d');
+ glVertex2dv := dglGetProcAddress('glVertex2dv');
+ glVertex2f := dglGetProcAddress('glVertex2f');
+ glVertex2fv := dglGetProcAddress('glVertex2fv');
+ glVertex2i := dglGetProcAddress('glVertex2i');
+ glVertex2iv := dglGetProcAddress('glVertex2iv');
+ glVertex2s := dglGetProcAddress('glVertex2s');
+ glVertex2sv := dglGetProcAddress('glVertex2sv');
+ glVertex3d := dglGetProcAddress('glVertex3d');
+ glVertex3dv := dglGetProcAddress('glVertex3dv');
+ glVertex3f := dglGetProcAddress('glVertex3f');
+ glVertex3fv := dglGetProcAddress('glVertex3fv');
+ glVertex3i := dglGetProcAddress('glVertex3i');
+ glVertex3iv := dglGetProcAddress('glVertex3iv');
+ glVertex3s := dglGetProcAddress('glVertex3s');
+ glVertex3sv := dglGetProcAddress('glVertex3sv');
+ glVertex4d := dglGetProcAddress('glVertex4d');
+ glVertex4dv := dglGetProcAddress('glVertex4dv');
+ glVertex4f := dglGetProcAddress('glVertex4f');
+ glVertex4fv := dglGetProcAddress('glVertex4fv');
+ glVertex4i := dglGetProcAddress('glVertex4i');
+ glVertex4iv := dglGetProcAddress('glVertex4iv');
+ glVertex4s := dglGetProcAddress('glVertex4s');
+ glVertex4sv := dglGetProcAddress('glVertex4sv');
+ glVertexPointer := dglGetProcAddress('glVertexPointer');
+{$endif}
+
+ // GL_VERSION_1_2
+ glBlendColor := dglGetProcAddress('glBlendColor');
+ glBlendEquation := dglGetProcAddress('glBlendEquation');
+ glDrawRangeElements := dglGetProcAddress('glDrawRangeElements');
+ glTexImage3D := dglGetProcAddress('glTexImage3D');
+ glTexSubImage3D := dglGetProcAddress('glTexSubImage3D');
+ glCopyTexSubImage3D := dglGetProcAddress('glCopyTexSubImage3D');
+{$ifdef DGL_DEPRECATED}
+ glColorTable := dglGetProcAddress('glColorTable');
+ glColorTableParameterfv := dglGetProcAddress('glColorTableParameterfv');
+ glColorTableParameteriv := dglGetProcAddress('glColorTableParameteriv');
+ glCopyColorTable := dglGetProcAddress('glCopyColorTable');
+ glGetColorTable := dglGetProcAddress('glGetColorTable');
+ glGetColorTableParameterfv := dglGetProcAddress('glGetColorTableParameterfv');
+ glGetColorTableParameteriv := dglGetProcAddress('glGetColorTableParameteriv');
+ glColorSubTable := dglGetProcAddress('glColorSubTable');
+ glCopyColorSubTable := dglGetProcAddress('glCopyColorSubTable');
+ glConvolutionFilter1D := dglGetProcAddress('glConvolutionFilter1D');
+ glConvolutionFilter2D := dglGetProcAddress('glConvolutionFilter2D');
+ glConvolutionParameterf := dglGetProcAddress('glConvolutionParameterf');
+ glConvolutionParameterfv := dglGetProcAddress('glConvolutionParameterfv');
+ glConvolutionParameteri := dglGetProcAddress('glConvolutionParameteri');
+ glConvolutionParameteriv := dglGetProcAddress('glConvolutionParameteriv');
+ glCopyConvolutionFilter1D := dglGetProcAddress('glCopyConvolutionFilter1D');
+ glCopyConvolutionFilter2D := dglGetProcAddress('glCopyConvolutionFilter2D');
+ glGetConvolutionFilter := dglGetProcAddress('glGetConvolutionFilter');
+ glGetConvolutionParameterfv := dglGetProcAddress('glGetConvolutionParameterfv');
+ glGetConvolutionParameteriv := dglGetProcAddress('glGetConvolutionParameteriv');
+ glGetSeparableFilter := dglGetProcAddress('glGetSeparableFilter');
+ glSeparableFilter2D := dglGetProcAddress('glSeparableFilter2D');
+ glGetHistogram := dglGetProcAddress('glGetHistogram');
+ glGetHistogramParameterfv := dglGetProcAddress('glGetHistogramParameterfv');
+ glGetHistogramParameteriv := dglGetProcAddress('glGetHistogramParameteriv');
+ glGetMinmax := dglGetProcAddress('glGetMinmax');
+ glGetMinmaxParameterfv := dglGetProcAddress('glGetMinmaxParameterfv');
+ glGetMinmaxParameteriv := dglGetProcAddress('glGetMinmaxParameteriv');
+ glHistogram := dglGetProcAddress('glHistogram');
+ glMinmax := dglGetProcAddress('glMinmax');
+ glResetHistogram := dglGetProcAddress('glResetHistogram');
+ glResetMinmax := dglGetProcAddress('glResetMinmax');
+{$endif}
+
+ // GL_VERSION_1_3
+ glActiveTexture := dglGetProcAddress('glActiveTexture');
+ glSampleCoverage := dglGetProcAddress('glSampleCoverage');
+ glCompressedTexImage3D := dglGetProcAddress('glCompressedTexImage3D');
+ glCompressedTexImage2D := dglGetProcAddress('glCompressedTexImage2D');
+ glCompressedTexImage1D := dglGetProcAddress('glCompressedTexImage1D');
+ glCompressedTexSubImage3D := dglGetProcAddress('glCompressedTexSubImage3D');
+ glCompressedTexSubImage2D := dglGetProcAddress('glCompressedTexSubImage2D');
+ glCompressedTexSubImage1D := dglGetProcAddress('glCompressedTexSubImage1D');
+ glGetCompressedTexImage := dglGetProcAddress('glGetCompressedTexImage');
+{$ifdef DGL_DEPRECATED}
+ glClientActiveTexture := dglGetProcAddress('glClientActiveTexture');
+ glMultiTexCoord1d := dglGetProcAddress('glMultiTexCoord1d');
+ glMultiTexCoord1dv := dglGetProcAddress('glMultiTexCoord1dv');
+ glMultiTexCoord1f := dglGetProcAddress('glMultiTexCoord1f');
+ glMultiTexCoord1fv := dglGetProcAddress('glMultiTexCoord1fv');
+ glMultiTexCoord1i := dglGetProcAddress('glMultiTexCoord1i');
+ glMultiTexCoord1iv := dglGetProcAddress('glMultiTexCoord1iv');
+ glMultiTexCoord1s := dglGetProcAddress('glMultiTexCoord1s');
+ glMultiTexCoord1sv := dglGetProcAddress('glMultiTexCoord1sv');
+ glMultiTexCoord2d := dglGetProcAddress('glMultiTexCoord2d');
+ glMultiTexCoord2dv := dglGetProcAddress('glMultiTexCoord2dv');
+ glMultiTexCoord2f := dglGetProcAddress('glMultiTexCoord2f');
+ glMultiTexCoord2fv := dglGetProcAddress('glMultiTexCoord2fv');
+ glMultiTexCoord2i := dglGetProcAddress('glMultiTexCoord2i');
+ glMultiTexCoord2iv := dglGetProcAddress('glMultiTexCoord2iv');
+ glMultiTexCoord2s := dglGetProcAddress('glMultiTexCoord2s');
+ glMultiTexCoord2sv := dglGetProcAddress('glMultiTexCoord2sv');
+ glMultiTexCoord3d := dglGetProcAddress('glMultiTexCoord3d');
+ glMultiTexCoord3dv := dglGetProcAddress('glMultiTexCoord3dv');
+ glMultiTexCoord3f := dglGetProcAddress('glMultiTexCoord3f');
+ glMultiTexCoord3fv := dglGetProcAddress('glMultiTexCoord3fv');
+ glMultiTexCoord3i := dglGetProcAddress('glMultiTexCoord3i');
+ glMultiTexCoord3iv := dglGetProcAddress('glMultiTexCoord3iv');
+ glMultiTexCoord3s := dglGetProcAddress('glMultiTexCoord3s');
+ glMultiTexCoord3sv := dglGetProcAddress('glMultiTexCoord3sv');
+ glMultiTexCoord4d := dglGetProcAddress('glMultiTexCoord4d');
+ glMultiTexCoord4dv := dglGetProcAddress('glMultiTexCoord4dv');
+ glMultiTexCoord4f := dglGetProcAddress('glMultiTexCoord4f');
+ glMultiTexCoord4fv := dglGetProcAddress('glMultiTexCoord4fv');
+ glMultiTexCoord4i := dglGetProcAddress('glMultiTexCoord4i');
+ glMultiTexCoord4iv := dglGetProcAddress('glMultiTexCoord4iv');
+ glMultiTexCoord4s := dglGetProcAddress('glMultiTexCoord4s');
+ glMultiTexCoord4sv := dglGetProcAddress('glMultiTexCoord4sv');
+ glLoadTransposeMatrixf := dglGetProcAddress('glLoadTransposeMatrixf');
+ glLoadTransposeMatrixd := dglGetProcAddress('glLoadTransposeMatrixd');
+ glMultTransposeMatrixf := dglGetProcAddress('glMultTransposeMatrixf');
+ glMultTransposeMatrixd := dglGetProcAddress('glMultTransposeMatrixd');
+{$endif}
+
+ // GL_VERSION_1_4
+ glBlendFuncSeparate := dglGetProcAddress('glBlendFuncSeparate');
+ glMultiDrawArrays := dglGetProcAddress('glMultiDrawArrays');
+ glMultiDrawElements := dglGetProcAddress('glMultiDrawElements');
+ glPointParameterf := dglGetProcAddress('glPointParameterf');
+ glPointParameterfv := dglGetProcAddress('glPointParameterfv');
+ glPointParameteri := dglGetProcAddress('glPointParameteri');
+ glPointParameteriv := dglGetProcAddress('glPointParameteriv');
+{$ifdef DGL_DEPRECATED}
+ glFogCoordf := dglGetProcAddress('glFogCoordf');
+ glFogCoordfv := dglGetProcAddress('glFogCoordfv');
+ glFogCoordd := dglGetProcAddress('glFogCoordd');
+ glFogCoorddv := dglGetProcAddress('glFogCoorddv');
+ glFogCoordPointer := dglGetProcAddress('glFogCoordPointer');
+ glSecondaryColor3b := dglGetProcAddress('glSecondaryColor3b');
+ glSecondaryColor3bv := dglGetProcAddress('glSecondaryColor3bv');
+ glSecondaryColor3d := dglGetProcAddress('glSecondaryColor3d');
+ glSecondaryColor3dv := dglGetProcAddress('glSecondaryColor3dv');
+ glSecondaryColor3f := dglGetProcAddress('glSecondaryColor3f');
+ glSecondaryColor3fv := dglGetProcAddress('glSecondaryColor3fv');
+ glSecondaryColor3i := dglGetProcAddress('glSecondaryColor3i');
+ glSecondaryColor3iv := dglGetProcAddress('glSecondaryColor3iv');
+ glSecondaryColor3s := dglGetProcAddress('glSecondaryColor3s');
+ glSecondaryColor3sv := dglGetProcAddress('glSecondaryColor3sv');
+ glSecondaryColor3ub := dglGetProcAddress('glSecondaryColor3ub');
+ glSecondaryColor3ubv := dglGetProcAddress('glSecondaryColor3ubv');
+ glSecondaryColor3ui := dglGetProcAddress('glSecondaryColor3ui');
+ glSecondaryColor3uiv := dglGetProcAddress('glSecondaryColor3uiv');
+ glSecondaryColor3us := dglGetProcAddress('glSecondaryColor3us');
+ glSecondaryColor3usv := dglGetProcAddress('glSecondaryColor3usv');
+ glSecondaryColorPointer := dglGetProcAddress('glSecondaryColorPointer');
+ glWindowPos2d := dglGetProcAddress('glWindowPos2d');
+ glWindowPos2dv := dglGetProcAddress('glWindowPos2dv');
+ glWindowPos2f := dglGetProcAddress('glWindowPos2f');
+ glWindowPos2fv := dglGetProcAddress('glWindowPos2fv');
+ glWindowPos2i := dglGetProcAddress('glWindowPos2i');
+ glWindowPos2iv := dglGetProcAddress('glWindowPos2iv');
+ glWindowPos2s := dglGetProcAddress('glWindowPos2s');
+ glWindowPos2sv := dglGetProcAddress('glWindowPos2sv');
+ glWindowPos3d := dglGetProcAddress('glWindowPos3d');
+ glWindowPos3dv := dglGetProcAddress('glWindowPos3dv');
+ glWindowPos3f := dglGetProcAddress('glWindowPos3f');
+ glWindowPos3fv := dglGetProcAddress('glWindowPos3fv');
+ glWindowPos3i := dglGetProcAddress('glWindowPos3i');
+ glWindowPos3iv := dglGetProcAddress('glWindowPos3iv');
+ glWindowPos3s := dglGetProcAddress('glWindowPos3s');
+ glWindowPos3sv := dglGetProcAddress('glWindowPos3sv');
+{$endif}
+
+ // GL_VERSION_1_5
+ glGenQueries := dglGetProcAddress('glGenQueries');
+ glDeleteQueries := dglGetProcAddress('glDeleteQueries');
+ glIsQuery := dglGetProcAddress('glIsQuery');
+ glBeginQuery := dglGetProcAddress('glBeginQuery');
+ glEndQuery := dglGetProcAddress('glEndQuery');
+ glGetQueryiv := dglGetProcAddress('glGetQueryiv');
+ glGetQueryObjectiv := dglGetProcAddress('glGetQueryObjectiv');
+ glGetQueryObjectuiv := dglGetProcAddress('glGetQueryObjectuiv');
+ glBindBuffer := dglGetProcAddress('glBindBuffer');
+ glDeleteBuffers := dglGetProcAddress('glDeleteBuffers');
+ glGenBuffers := dglGetProcAddress('glGenBuffers');
+ glIsBuffer := dglGetProcAddress('glIsBuffer');
+ glBufferData := dglGetProcAddress('glBufferData');
+ glBufferSubData := dglGetProcAddress('glBufferSubData');
+ glGetBufferSubData := dglGetProcAddress('glGetBufferSubData');
+ glMapBuffer := dglGetProcAddress('glMapBuffer');
+ glUnmapBuffer := dglGetProcAddress('glUnmapBuffer');
+ glGetBufferParameteriv := dglGetProcAddress('glGetBufferParameteriv');
+ glGetBufferPointerv := dglGetProcAddress('glGetBufferPointerv');
+
+ // GL_VERSION_2_0
+ glBlendEquationSeparate := dglGetProcAddress('glBlendEquationSeparate');
+ glDrawBuffers := dglGetProcAddress('glDrawBuffers');
+ glStencilOpSeparate := dglGetProcAddress('glStencilOpSeparate');
+ glStencilFuncSeparate := dglGetProcAddress('glStencilFuncSeparate');
+ glStencilMaskSeparate := dglGetProcAddress('glStencilMaskSeparate');
+ glAttachShader := dglGetProcAddress('glAttachShader');
+ glBindAttribLocation := dglGetProcAddress('glBindAttribLocation');
+ glCompileShader := dglGetProcAddress('glCompileShader');
+ glCreateProgram := dglGetProcAddress('glCreateProgram');
+ glCreateShader := dglGetProcAddress('glCreateShader');
+ glDeleteProgram := dglGetProcAddress('glDeleteProgram');
+ glDeleteShader := dglGetProcAddress('glDeleteShader');
+ glDetachShader := dglGetProcAddress('glDetachShader');
+ glDisableVertexAttribArray := dglGetProcAddress('glDisableVertexAttribArray');
+ glEnableVertexAttribArray := dglGetProcAddress('glEnableVertexAttribArray');
+ glGetActiveAttrib := dglGetProcAddress('glGetActiveAttrib');
+ glGetActiveUniform := dglGetProcAddress('glGetActiveUniform');
+ glGetAttachedShaders := dglGetProcAddress('glGetAttachedShaders');
+ glGetAttribLocation := dglGetProcAddress('glGetAttribLocation');
+ glGetProgramiv := dglGetProcAddress('glGetProgramiv');
+ glGetProgramInfoLog := dglGetProcAddress('glGetProgramInfoLog');
+ glGetShaderiv := dglGetProcAddress('glGetShaderiv');
+ glGetShaderInfoLog := dglGetProcAddress('glGetShaderInfoLog');
+ glGetShaderSource := dglGetProcAddress('glGetShaderSource');
+ glGetUniformLocation := dglGetProcAddress('glGetUniformLocation');
+ glGetUniformfv := dglGetProcAddress('glGetUniformfv');
+ glGetUniformiv := dglGetProcAddress('glGetUniformiv');
+ glGetVertexAttribfv := dglGetProcAddress('glGetVertexAttribfv');
+ glGetVertexAttribiv := dglGetProcAddress('glGetVertexAttribiv');
+ glGetVertexAttribPointerv := dglGetProcAddress('glGetVertexAttribPointerv');
+ glIsProgram := dglGetProcAddress('glIsProgram');
+ glIsShader := dglGetProcAddress('glIsShader');
+ glLinkProgram := dglGetProcAddress('glLinkProgram');
+ glShaderSource := dglGetProcAddress('glShaderSource');
+ glUseProgram := dglGetProcAddress('glUseProgram');
+ glUniform1f := dglGetProcAddress('glUniform1f');
+ glUniform2f := dglGetProcAddress('glUniform2f');
+ glUniform3f := dglGetProcAddress('glUniform3f');
+ glUniform4f := dglGetProcAddress('glUniform4f');
+ glUniform1i := dglGetProcAddress('glUniform1i');
+ glUniform2i := dglGetProcAddress('glUniform2i');
+ glUniform3i := dglGetProcAddress('glUniform3i');
+ glUniform4i := dglGetProcAddress('glUniform4i');
+ glUniform1fv := dglGetProcAddress('glUniform1fv');
+ glUniform2fv := dglGetProcAddress('glUniform2fv');
+ glUniform3fv := dglGetProcAddress('glUniform3fv');
+ glUniform4fv := dglGetProcAddress('glUniform4fv');
+ glUniform1iv := dglGetProcAddress('glUniform1iv');
+ glUniform2iv := dglGetProcAddress('glUniform2iv');
+ glUniform3iv := dglGetProcAddress('glUniform3iv');
+ glUniform4iv := dglGetProcAddress('glUniform4iv');
+ glUniformMatrix2fv := dglGetProcAddress('glUniformMatrix2fv');
+ glUniformMatrix3fv := dglGetProcAddress('glUniformMatrix3fv');
+ glUniformMatrix4fv := dglGetProcAddress('glUniformMatrix4fv');
+ glValidateProgram := dglGetProcAddress('glValidateProgram');
+ glVertexAttrib1d := dglGetProcAddress('glVertexAttrib1d');
+ glVertexAttrib1dv := dglGetProcAddress('glVertexAttrib1dv');
+ glVertexAttrib1f := dglGetProcAddress('glVertexAttrib1f');
+ glVertexAttrib1fv := dglGetProcAddress('glVertexAttrib1fv');
+ glVertexAttrib1s := dglGetProcAddress('glVertexAttrib1s');
+ glVertexAttrib1sv := dglGetProcAddress('glVertexAttrib1sv');
+ glVertexAttrib2d := dglGetProcAddress('glVertexAttrib2d');
+ glVertexAttrib2dv := dglGetProcAddress('glVertexAttrib2dv');
+ glVertexAttrib2f := dglGetProcAddress('glVertexAttrib2f');
+ glVertexAttrib2fv := dglGetProcAddress('glVertexAttrib2fv');
+ glVertexAttrib2s := dglGetProcAddress('glVertexAttrib2s');
+ glVertexAttrib2sv := dglGetProcAddress('glVertexAttrib2sv');
+ glVertexAttrib3d := dglGetProcAddress('glVertexAttrib3d');
+ glVertexAttrib3dv := dglGetProcAddress('glVertexAttrib3dv');
+ glVertexAttrib3f := dglGetProcAddress('glVertexAttrib3f');
+ glVertexAttrib3fv := dglGetProcAddress('glVertexAttrib3fv');
+ glVertexAttrib3s := dglGetProcAddress('glVertexAttrib3s');
+ glVertexAttrib3sv := dglGetProcAddress('glVertexAttrib3sv');
+ glVertexAttrib4Nbv := dglGetProcAddress('glVertexAttrib4Nbv');
+ glVertexAttrib4Niv := dglGetProcAddress('glVertexAttrib4Niv');
+ glVertexAttrib4Nsv := dglGetProcAddress('glVertexAttrib4Nsv');
+ glVertexAttrib4Nub := dglGetProcAddress('glVertexAttrib4Nub');
+ glVertexAttrib4Nubv := dglGetProcAddress('glVertexAttrib4Nubv');
+ glVertexAttrib4Nuiv := dglGetProcAddress('glVertexAttrib4Nuiv');
+ glVertexAttrib4Nusv := dglGetProcAddress('glVertexAttrib4Nusv');
+ glVertexAttrib4bv := dglGetProcAddress('glVertexAttrib4bv');
+ glVertexAttrib4d := dglGetProcAddress('glVertexAttrib4d');
+ glVertexAttrib4dv := dglGetProcAddress('glVertexAttrib4dv');
+ glVertexAttrib4f := dglGetProcAddress('glVertexAttrib4f');
+ glVertexAttrib4fv := dglGetProcAddress('glVertexAttrib4fv');
+ glVertexAttrib4iv := dglGetProcAddress('glVertexAttrib4iv');
+ glVertexAttrib4s := dglGetProcAddress('glVertexAttrib4s');
+ glVertexAttrib4sv := dglGetProcAddress('glVertexAttrib4sv');
+ glVertexAttrib4ubv := dglGetProcAddress('glVertexAttrib4ubv');
+ glVertexAttrib4uiv := dglGetProcAddress('glVertexAttrib4uiv');
+ glVertexAttrib4usv := dglGetProcAddress('glVertexAttrib4usv');
+ glVertexAttribPointer := dglGetProcAddress('glVertexAttribPointer');
+
+ // GL_VERSION_2_1
+ glUniformMatrix2x3fv := dglGetProcAddress('glUniformMatrix2x3fv');
+ glUniformMatrix3x2fv := dglGetProcAddress('glUniformMatrix3x2fv');
+ glUniformMatrix2x4fv := dglGetProcAddress('glUniformMatrix2x4fv');
+ glUniformMatrix4x2fv := dglGetProcAddress('glUniformMatrix4x2fv');
+ glUniformMatrix3x4fv := dglGetProcAddress('glUniformMatrix3x4fv');
+ glUniformMatrix4x3fv := dglGetProcAddress('glUniformMatrix4x3fv');
+
+ // GL_VERSION_3_0
+ { OpenGL 3.0 also reuses entry points from these extensions: }
+ Read_GL_ARB_framebuffer_object;
+ Read_GL_ARB_map_buffer_range;
+ Read_GL_ARB_vertex_array_object;
+
+ glColorMaski := dglGetProcAddress('glColorMaski');
+ glGetBooleani_v := dglGetProcAddress('glGetBooleani_v');
+ glGetIntegeri_v := dglGetProcAddress('glGetIntegeri_v');
+ glEnablei := dglGetProcAddress('glEnablei');
+ glDisablei := dglGetProcAddress('glDisablei');
+ glIsEnabledi := dglGetProcAddress('glIsEnabledi');
+ glBeginTransformFeedback := dglGetProcAddress('glBeginTransformFeedback');
+ glEndTransformFeedback := dglGetProcAddress('glEndTransformFeedback');
+ glBindBufferRange := dglGetProcAddress('glBindBufferRange');
+ glBindBufferBase := dglGetProcAddress('glBindBufferBase');
+ glTransformFeedbackVaryings := dglGetProcAddress('glTransformFeedbackVaryings');
+ glGetTransformFeedbackVarying := dglGetProcAddress('glGetTransformFeedbackVarying');
+ glClampColor := dglGetProcAddress('glClampColor');
+ glBeginConditionalRender := dglGetProcAddress('glBeginConditionalRender');
+ glEndConditionalRender := dglGetProcAddress('glEndConditionalRender');
+ glVertexAttribI1i := dglGetProcAddress('glVertexAttribI1i');
+ glVertexAttribI2i := dglGetProcAddress('glVertexAttribI2i');
+ glVertexAttribI3i := dglGetProcAddress('glVertexAttribI3i');
+ glVertexAttribI4i := dglGetProcAddress('glVertexAttribI4i');
+ glVertexAttribI1ui := dglGetProcAddress('glVertexAttribI1ui');
+ glVertexAttribI2ui := dglGetProcAddress('glVertexAttribI2ui');
+ glVertexAttribI3ui := dglGetProcAddress('glVertexAttribI3ui');
+ glVertexAttribI4ui := dglGetProcAddress('glVertexAttribI4ui');
+ glVertexAttribI1iv := dglGetProcAddress('glVertexAttribI1iv');
+ glVertexAttribI2iv := dglGetProcAddress('glVertexAttribI2iv');
+ glVertexAttribI3iv := dglGetProcAddress('glVertexAttribI3iv');
+ glVertexAttribI4iv := dglGetProcAddress('glVertexAttribI4iv');
+ glVertexAttribI1uiv := dglGetProcAddress('glVertexAttribI1uiv');
+ glVertexAttribI2uiv := dglGetProcAddress('glVertexAttribI2uiv');
+ glVertexAttribI3uiv := dglGetProcAddress('glVertexAttribI3uiv');
+ glVertexAttribI4uiv := dglGetProcAddress('glVertexAttribI4uiv');
+ glVertexAttribI4bv := dglGetProcAddress('glVertexAttribI4bv');
+ glVertexAttribI4sv := dglGetProcAddress('glVertexAttribI4sv');
+ glVertexAttribI4ubv := dglGetProcAddress('glVertexAttribI4ubv');
+ glVertexAttribI4usv := dglGetProcAddress('glVertexAttribI4usv');
+ glVertexAttribIPointer := dglGetProcAddress('glVertexAttribIPointer');
+ glGetVertexAttribIiv := dglGetProcAddress('glGetVertexAttribIiv');
+ glGetVertexAttribIuiv := dglGetProcAddress('glGetVertexAttribIuiv');
+ glGetUniformuiv := dglGetProcAddress('glGetUniformuiv');
+ glBindFragDataLocation := dglGetProcAddress('glBindFragDataLocation');
+ glGetFragDataLocation := dglGetProcAddress('glGetFragDataLocation');
+ glUniform1ui := dglGetProcAddress('glUniform1ui');
+ glUniform2ui := dglGetProcAddress('glUniform2ui');
+ glUniform3ui := dglGetProcAddress('glUniform3ui');
+ glUniform4ui := dglGetProcAddress('glUniform4ui');
+ glUniform1uiv := dglGetProcAddress('glUniform1uiv');
+ glUniform2uiv := dglGetProcAddress('glUniform2uiv');
+ glUniform3uiv := dglGetProcAddress('glUniform3uiv');
+ glUniform4uiv := dglGetProcAddress('glUniform4uiv');
+ glTexParameterIiv := dglGetProcAddress('glTexParameterIiv');
+ glTexParameterIuiv := dglGetProcAddress('glTexParameterIuiv');
+ glGetTexParameterIiv := dglGetProcAddress('glGetTexParameterIiv');
+ glGetTexParameterIuiv := dglGetProcAddress('glGetTexParameterIuiv');
+ glClearBufferiv := dglGetProcAddress('glClearBufferiv');
+ glClearBufferuiv := dglGetProcAddress('glClearBufferuiv');
+ glClearBufferfv := dglGetProcAddress('glClearBufferfv');
+ glClearBufferfi := dglGetProcAddress('glClearBufferfi');
+ glGetStringi := dglGetProcAddress('glGetStringi');
+
+ // GL_VERSION_2_1
+ glEnableVertexArrayEXT := dglGetProcAddress('glEnableVertexArrayEXT');
+ glEnableVertexArrayAttribEXT := dglGetProcAddress('glEnableVertexArrayAttribEXT');
+ glVertexArrayVertexAttribOffsetEXT := dglGetProcAddress('glVertexArrayVertexAttribOffsetEXT');
+
+ // GL_VERSION_3_1
+ { OpenGL 3.1 also reuses entry points from these extensions: }
+ Read_GL_ARB_copy_buffer;
+ Read_GL_ARB_uniform_buffer_object;
+
+ glDrawArraysInstanced := dglGetProcAddress('glDrawArraysInstanced');
+ glDrawElementsInstanced := dglGetProcAddress('glDrawElementsInstanced');
+ glTexBuffer := dglGetProcAddress('glTexBuffer');
+ glPrimitiveRestartIndex := dglGetProcAddress('glPrimitiveRestartIndex');
+
+ // GL_VERSION_3_2
+ { OpenGL 3.2 also reuses entry points from these extensions: }
+ Read_GL_ARB_draw_elements_base_vertex;
+ Read_GL_ARB_provoking_vertex;
+ Read_GL_ARB_sync;
+ Read_GL_ARB_texture_multisample;
+
+ glGetInteger64i_v := dglGetProcAddress('glGetInteger64i_v');
+ glGetBufferParameteri64v := dglGetProcAddress('glGetBufferParameteri64v');
+ glFramebufferTexture := dglGetProcAddress('glFramebufferTexture');
+// glFramebufferTextureFace := dglGetProcAddress('glFramebufferTextureFace');
+
+ // GL_VERSION_3_3
+ { OpenGL 3.3 also reuses entry points from these extensions: }
+ Read_GL_ARB_blend_func_extended;
+ Read_GL_ARB_sampler_objects;
+ { ARB_explicit_attrib_location, but it has none }
+ { ARB_occlusion_query2 (no entry points) }
+ { ARB_shader_bit_encoding (no entry points) }
+ { ARB_texture_rgb10_a2ui (no entry points) }
+ { ARB_texture_swizzle (no entry points) }
+ Read_GL_ARB_timer_query;
+ Read_GL_ARB_vertex_type_2_10_10_10_rev;
+
+ glVertexAttribDivisor := dglGetProcAddress('glVertexAttribDivisor');
+
+ // GL_VERSION_4_0
+ { OpenGL 4.0 also reuses entry points from these extensions: }
+ { ARB_texture_query_lod (no entry points) }
+ Read_GL_ARB_draw_indirect;
+ { ARB_gpu_shader5 (no entry points) }
+ Read_GL_ARB_gpu_shader_fp64;
+ Read_GL_ARB_shader_subroutine;
+ Read_GL_ARB_tessellation_shader;
+ { ARB_texture_buffer_object_rgb32 (no entry points) }
+ { ARB_texture_cube_map_array (no entry points) }
+ { ARB_texture_gather (no entry points) }
+ Read_GL_ARB_transform_feedback2;
+ Read_GL_ARB_transform_feedback3;
+
+ glMinSampleShading := dglGetProcAddress('glMinSampleShading');
+ glBlendEquationi := dglGetProcAddress('glBlendEquationi');
+ glBlendEquationSeparatei := dglGetProcAddress('glBlendEquationSeparatei');
+ glBlendFunci := dglGetProcAddress('glBlendFunci');
+ glBlendFuncSeparatei := dglGetProcAddress('glBlendFuncSeparatei');
+
+ // GL_VERSION_4_1
+ { OpenGL 4.1 also reuses entry points from these extensions: }
+ Read_GL_ARB_ES2_compatibility;
+ Read_GL_ARB_get_program_binary;
+ Read_GL_ARB_separate_shader_objects;
+ { ARB_shader_precision (no entry points) }
+ Read_GL_ARB_vertex_attrib_64bit;
+ Read_GL_ARB_viewport_array;
+
+ // GL_VERSION_4_2
+ { OpenGL 4.2 reuses entry points from these extensions: }
+ Read_GL_ARB_base_instance;
+ //Read_GL_ARB_shading_language_420pack (no entry points)
+ Read_GL_ARB_transform_feedback_instanced;
+ //Read_GL_ARB_compressed_texture_pixel_storage (no entry points)
+ //Read_GL_ARB_conservative_depth;
+ Read_GL_ARB_internalformat_query;
+ //Read_GL_ARB_map_buffer_alignment;
+ Read_GL_ARB_shader_atomic_counters;
+ Read_GL_ARB_shader_image_load_store;
+ //Read_GL_ARB_shading_language_packing;
+ Read_GL_ARB_texture_storage;
+
+ // GL_VERSION_4_3
+ // OpenGL 4.3 reuses entry points from these extensions:
+ // Read_GL_ARB_arrays_of_arrays (none, GLSL only) (no entry points)
+ // Read_GL_ARB_fragment_layer_viewport (none, GLSL only) (no entry points)
+ // Read_GL_ARB_shader_image_size (none, GLSL only) (no entry points)
+ // Read_GL_ARB_ES3_compatibility (no entry points)
+ Read_GL_ARB_clear_buffer_object;
+ Read_GL_ARB_compute_shader;
+ Read_GL_ARB_copy_image;
+ Read_GL_KHR_debug;
+ // Read_GL_ARB_explicit_uniform_location (no entry points)
+ Read_GL_ARB_framebuffer_no_attachments;
+ Read_GL_ARB_internalformat_query2;
+ Read_GL_ARB_invalidate_subdata;
+ Read_GL_ARB_multi_draw_indirect;
+ Read_GL_ARB_program_interface_query;
+ // Read_GL_ARB_robust_buffer_access_behavior (none) (no entry points)
+ Read_GL_ARB_shader_storage_buffer_object;
+ // Read_GL_ARB_stencil_texturing (no entry points)
+ Read_GL_ARB_texture_buffer_range;
+ // Read_GL_ARB_texture_query_levels (none) (no entry points)
+ Read_GL_ARB_texture_storage_multisample;
+ Read_GL_ARB_texture_view;
+ Read_GL_ARB_vertex_attrib_binding;
+
+ Read_GL_4_4;
+ Read_GL_4_5;
+ Read_GL_4_6;
+end;
+
+procedure Read_GL_3DFX_tbuffer;
+begin
+ glTbufferMask3DFX := dglGetProcAddress('glTbufferMask3DFX');
+end;
+
+procedure Read_GL_APPLE_element_array;
+begin
+ glElementPointerAPPLE := dglGetProcAddress('glElementPointerAPPLE');
+ glDrawElementArrayAPPLE := dglGetProcAddress('glDrawElementArrayAPPLE');
+ glDrawRangeElementArrayAPPLE := dglGetProcAddress('glDrawRangeElementArrayAPPLE');
+ glMultiDrawElementArrayAPPLE := dglGetProcAddress('glMultiDrawElementArrayAPPLE');
+ glMultiDrawRangeElementArrayAPPLE := dglGetProcAddress('glMultiDrawRangeElementArrayAPPLE');
+end;
+
+procedure Read_GL_APPLE_fence;
+begin
+ glGenFencesAPPLE := dglGetProcAddress('glGenFencesAPPLE');
+ glDeleteFencesAPPLE := dglGetProcAddress('glDeleteFencesAPPLE');
+ glSetFenceAPPLE := dglGetProcAddress('glSetFenceAPPLE');
+ glIsFenceAPPLE := dglGetProcAddress('glIsFenceAPPLE');
+ glTestFenceAPPLE := dglGetProcAddress('glTestFenceAPPLE');
+ glFinishFenceAPPLE := dglGetProcAddress('glFinishFenceAPPLE');
+ glTestObjectAPPLE := dglGetProcAddress('glTestObjectAPPLE');
+ glFinishObjectAPPLE := dglGetProcAddress('glFinishObjectAPPLE');
+end;
+
+procedure Read_GL_APPLE_vertex_array_object;
+begin
+ glBindVertexArrayAPPLE := dglGetProcAddress('glBindVertexArrayAPPLE');
+ glDeleteVertexArraysAPPLE := dglGetProcAddress('glDeleteVertexArraysAPPLE');
+ glGenVertexArraysAPPLE := dglGetProcAddress('glGenVertexArraysAPPLE');
+ glIsVertexArrayAPPLE := dglGetProcAddress('glIsVertexArrayAPPLE');
+end;
+
+procedure Read_GL_APPLE_vertex_array_range;
+begin
+ glVertexArrayRangeAPPLE := dglGetProcAddress('glVertexArrayRangeAPPLE');
+ glFlushVertexArrayRangeAPPLE := dglGetProcAddress('glFlushVertexArrayRangeAPPLE');
+ glVertexArrayParameteriAPPLE := dglGetProcAddress('glVertexArrayParameteriAPPLE');
+end;
+
+procedure Read_GL_APPLE_texture_range;
+begin
+ glTextureRangeAPPLE := dglGetProcAddress('glTextureRangeAPPLE');
+ glGetTexParameterPointervAPPLE := dglGetProcAddress('glGetTexParameterPointervAPPLE');
+end;
+
+procedure Read_GL_APPLE_vertex_program_evaluators;
+begin
+ glEnableVertexAttribAPPLE := dglGetProcAddress('glEnableVertexAttribAPPLE');
+ glDisableVertexAttribAPPLE := dglGetProcAddress('glDisableVertexAttribAPPLE');
+ glIsVertexAttribEnabledAPPLE := dglGetProcAddress('glIsVertexAttribEnabledAPPLE');
+ glMapVertexAttrib1dAPPLE := dglGetProcAddress('glMapVertexAttrib1dAPPLE');
+ glMapVertexAttrib1fAPPLE := dglGetProcAddress('glMapVertexAttrib1fAPPLE');
+ glMapVertexAttrib2dAPPLE := dglGetProcAddress('glMapVertexAttrib2dAPPLE');
+ glMapVertexAttrib2fAPPLE := dglGetProcAddress('glMapVertexAttrib2fAPPLE');
+end;
+
+procedure Read_GL_APPLE_object_purgeable;
+begin
+ glObjectPurgeableAPPLE := dglGetProcAddress('glObjectPurgeableAPPLE');
+ glObjectUnpurgeableAPPLE := dglGetProcAddress('glObjectUnpurgeableAPPLE');
+ glGetObjectParameterivAPPLE := dglGetProcAddress('glGetObjectParameterivAPPLE');
+end;
+
+procedure Read_GL_ARB_matrix_palette;
+begin
+ glCurrentPaletteMatrixARB := dglGetProcAddress('glCurrentPaletteMatrixARB');
+ glMatrixIndexubvARB := dglGetProcAddress('glMatrixIndexubvARB');
+ glMatrixIndexusvARB := dglGetProcAddress('glMatrixIndexusvARB');
+ glMatrixIndexuivARB := dglGetProcAddress('glMatrixIndexuivARB');
+ glMatrixIndexPointerARB := dglGetProcAddress('glMatrixIndexPointerARB');
+end;
+
+procedure Read_GL_ARB_multisample;
+begin
+ glSampleCoverageARB := dglGetProcAddress('glSampleCoverageARB');
+end;
+
+procedure Read_GL_ARB_multitexture;
+begin
+ glActiveTextureARB := dglGetProcAddress('glActiveTextureARB');
+ glClientActiveTextureARB := dglGetProcAddress('glClientActiveTextureARB');
+ glMultiTexCoord1dARB := dglGetProcAddress('glMultiTexCoord1dARB');
+ glMultiTexCoord1dvARB := dglGetProcAddress('glMultiTexCoord1dvARB');
+ glMultiTexCoord1fARB := dglGetProcAddress('glMultiTexCoord1fARB');
+ glMultiTexCoord1fvARB := dglGetProcAddress('glMultiTexCoord1fvARB');
+ glMultiTexCoord1iARB := dglGetProcAddress('glMultiTexCoord1iARB');
+ glMultiTexCoord1ivARB := dglGetProcAddress('glMultiTexCoord1ivARB');
+ glMultiTexCoord1sARB := dglGetProcAddress('glMultiTexCoord1sARB');
+ glMultiTexCoord1svARB := dglGetProcAddress('glMultiTexCoord1svARB');
+ glMultiTexCoord2dARB := dglGetProcAddress('glMultiTexCoord2dARB');
+ glMultiTexCoord2dvARB := dglGetProcAddress('glMultiTexCoord2dvARB');
+ glMultiTexCoord2fARB := dglGetProcAddress('glMultiTexCoord2fARB');
+ glMultiTexCoord2fvARB := dglGetProcAddress('glMultiTexCoord2fvARB');
+ glMultiTexCoord2iARB := dglGetProcAddress('glMultiTexCoord2iARB');
+ glMultiTexCoord2ivARB := dglGetProcAddress('glMultiTexCoord2ivARB');
+ glMultiTexCoord2sARB := dglGetProcAddress('glMultiTexCoord2sARB');
+ glMultiTexCoord2svARB := dglGetProcAddress('glMultiTexCoord2svARB');
+ glMultiTexCoord3dARB := dglGetProcAddress('glMultiTexCoord3dARB');
+ glMultiTexCoord3dvARB := dglGetProcAddress('glMultiTexCoord3dvARB');
+ glMultiTexCoord3fARB := dglGetProcAddress('glMultiTexCoord3fARB');
+ glMultiTexCoord3fvARB := dglGetProcAddress('glMultiTexCoord3fvARB');
+ glMultiTexCoord3iARB := dglGetProcAddress('glMultiTexCoord3iARB');
+ glMultiTexCoord3ivARB := dglGetProcAddress('glMultiTexCoord3ivARB');
+ glMultiTexCoord3sARB := dglGetProcAddress('glMultiTexCoord3sARB');
+ glMultiTexCoord3svARB := dglGetProcAddress('glMultiTexCoord3svARB');
+ glMultiTexCoord4dARB := dglGetProcAddress('glMultiTexCoord4dARB');
+ glMultiTexCoord4dvARB := dglGetProcAddress('glMultiTexCoord4dvARB');
+ glMultiTexCoord4fARB := dglGetProcAddress('glMultiTexCoord4fARB');
+ glMultiTexCoord4fvARB := dglGetProcAddress('glMultiTexCoord4fvARB');
+ glMultiTexCoord4iARB := dglGetProcAddress('glMultiTexCoord4iARB');
+ glMultiTexCoord4ivARB := dglGetProcAddress('glMultiTexCoord4ivARB');
+ glMultiTexCoord4sARB := dglGetProcAddress('glMultiTexCoord4sARB');
+ glMultiTexCoord4svARB := dglGetProcAddress('glMultiTexCoord4svARB');
+end;
+
+procedure Read_GL_ARB_point_parameters;
+begin
+ glPointParameterfARB := dglGetProcAddress('glPointParameterfARB');
+ glPointParameterfvARB := dglGetProcAddress('glPointParameterfvARB');
+end;
+
+procedure Read_GL_ARB_texture_compression;
+begin
+ glCompressedTexImage3DARB := dglGetProcAddress('glCompressedTexImage3DARB');
+ glCompressedTexImage2DARB := dglGetProcAddress('glCompressedTexImage2DARB');
+ glCompressedTexImage1DARB := dglGetProcAddress('glCompressedTexImage1DARB');
+ glCompressedTexSubImage3DARB := dglGetProcAddress('glCompressedTexSubImage3DARB');
+ glCompressedTexSubImage2DARB := dglGetProcAddress('glCompressedTexSubImage2DARB');
+ glCompressedTexSubImage1DARB := dglGetProcAddress('glCompressedTexSubImage1DARB');
+ glGetCompressedTexImageARB := dglGetProcAddress('glGetCompressedTexImageARB');
+end;
+
+procedure Read_GL_ARB_transpose_matrix;
+begin
+ glLoadTransposeMatrixfARB := dglGetProcAddress('glLoadTransposeMatrixfARB');
+ glLoadTransposeMatrixdARB := dglGetProcAddress('glLoadTransposeMatrixdARB');
+ glMultTransposeMatrixfARB := dglGetProcAddress('glMultTransposeMatrixfARB');
+ glMultTransposeMatrixdARB := dglGetProcAddress('glMultTransposeMatrixdARB');
+end;
+
+procedure Read_GL_ARB_vertex_blend;
+begin
+ glWeightbvARB := dglGetProcAddress('glWeightbvARB');
+ glWeightsvARB := dglGetProcAddress('glWeightsvARB');
+ glWeightivARB := dglGetProcAddress('glWeightivARB');
+ glWeightfvARB := dglGetProcAddress('glWeightfvARB');
+ glWeightdvARB := dglGetProcAddress('glWeightdvARB');
+ glWeightubvARB := dglGetProcAddress('glWeightubvARB');
+ glWeightusvARB := dglGetProcAddress('glWeightusvARB');
+ glWeightuivARB := dglGetProcAddress('glWeightuivARB');
+ glWeightPointerARB := dglGetProcAddress('glWeightPointerARB');
+ glVertexBlendARB := dglGetProcAddress('glVertexBlendARB');
+end;
+
+procedure Read_GL_ARB_vertex_buffer_object;
+begin
+ glBindBufferARB := dglGetProcAddress('glBindBufferARB');
+ glDeleteBuffersARB := dglGetProcAddress('glDeleteBuffersARB');
+ glGenBuffersARB := dglGetProcAddress('glGenBuffersARB');
+ glIsBufferARB := dglGetProcAddress('glIsBufferARB');
+ glBufferDataARB := dglGetProcAddress('glBufferDataARB');
+ glBufferSubDataARB := dglGetProcAddress('glBufferSubDataARB');
+ glGetBufferSubDataARB := dglGetProcAddress('glGetBufferSubDataARB');
+ glMapBufferARB := dglGetProcAddress('glMapBufferARB');
+ glUnmapBufferARB := dglGetProcAddress('glUnmapBufferARB');
+ glGetBufferParameterivARB := dglGetProcAddress('glGetBufferParameterivARB');
+ glGetBufferPointervARB := dglGetProcAddress('glGetBufferPointervARB');
+end;
+
+procedure Read_GL_ARB_vertex_program;
+begin
+ glVertexAttrib1dARB := dglGetProcAddress('glVertexAttrib1dARB');
+ glVertexAttrib1dvARB := dglGetProcAddress('glVertexAttrib1dvARB');
+ glVertexAttrib1fARB := dglGetProcAddress('glVertexAttrib1fARB');
+ glVertexAttrib1fvARB := dglGetProcAddress('glVertexAttrib1fvARB');
+ glVertexAttrib1sARB := dglGetProcAddress('glVertexAttrib1sARB');
+ glVertexAttrib1svARB := dglGetProcAddress('glVertexAttrib1svARB');
+ glVertexAttrib2dARB := dglGetProcAddress('glVertexAttrib2dARB');
+ glVertexAttrib2dvARB := dglGetProcAddress('glVertexAttrib2dvARB');
+ glVertexAttrib2fARB := dglGetProcAddress('glVertexAttrib2fARB');
+ glVertexAttrib2fvARB := dglGetProcAddress('glVertexAttrib2fvARB');
+ glVertexAttrib2sARB := dglGetProcAddress('glVertexAttrib2sARB');
+ glVertexAttrib2svARB := dglGetProcAddress('glVertexAttrib2svARB');
+ glVertexAttrib3dARB := dglGetProcAddress('glVertexAttrib3dARB');
+ glVertexAttrib3dvARB := dglGetProcAddress('glVertexAttrib3dvARB');
+ glVertexAttrib3fARB := dglGetProcAddress('glVertexAttrib3fARB');
+ glVertexAttrib3fvARB := dglGetProcAddress('glVertexAttrib3fvARB');
+ glVertexAttrib3sARB := dglGetProcAddress('glVertexAttrib3sARB');
+ glVertexAttrib3svARB := dglGetProcAddress('glVertexAttrib3svARB');
+ glVertexAttrib4NbvARB := dglGetProcAddress('glVertexAttrib4NbvARB');
+ glVertexAttrib4NivARB := dglGetProcAddress('glVertexAttrib4NivARB');
+ glVertexAttrib4NsvARB := dglGetProcAddress('glVertexAttrib4NsvARB');
+ glVertexAttrib4NubARB := dglGetProcAddress('glVertexAttrib4NubARB');
+ glVertexAttrib4NubvARB := dglGetProcAddress('glVertexAttrib4NubvARB');
+ glVertexAttrib4NuivARB := dglGetProcAddress('glVertexAttrib4NuivARB');
+ glVertexAttrib4NusvARB := dglGetProcAddress('glVertexAttrib4NusvARB');
+ glVertexAttrib4bvARB := dglGetProcAddress('glVertexAttrib4bvARB');
+ glVertexAttrib4dARB := dglGetProcAddress('glVertexAttrib4dARB');
+ glVertexAttrib4dvARB := dglGetProcAddress('glVertexAttrib4dvARB');
+ glVertexAttrib4fARB := dglGetProcAddress('glVertexAttrib4fARB');
+ glVertexAttrib4fvARB := dglGetProcAddress('glVertexAttrib4fvARB');
+ glVertexAttrib4ivARB := dglGetProcAddress('glVertexAttrib4ivARB');
+ glVertexAttrib4sARB := dglGetProcAddress('glVertexAttrib4sARB');
+ glVertexAttrib4svARB := dglGetProcAddress('glVertexAttrib4svARB');
+ glVertexAttrib4ubvARB := dglGetProcAddress('glVertexAttrib4ubvARB');
+ glVertexAttrib4uivARB := dglGetProcAddress('glVertexAttrib4uivARB');
+ glVertexAttrib4usvARB := dglGetProcAddress('glVertexAttrib4usvARB');
+ glVertexAttribPointerARB := dglGetProcAddress('glVertexAttribPointerARB');
+ glEnableVertexAttribArrayARB := dglGetProcAddress('glEnableVertexAttribArrayARB');
+ glDisableVertexAttribArrayARB := dglGetProcAddress('glDisableVertexAttribArrayARB');
+ glProgramStringARB := dglGetProcAddress('glProgramStringARB');
+ glBindProgramARB := dglGetProcAddress('glBindProgramARB');
+ glDeleteProgramsARB := dglGetProcAddress('glDeleteProgramsARB');
+ glGenProgramsARB := dglGetProcAddress('glGenProgramsARB');
+ glProgramEnvParameter4dARB := dglGetProcAddress('glProgramEnvParameter4dARB');
+ glProgramEnvParameter4dvARB := dglGetProcAddress('glProgramEnvParameter4dvARB');
+ glProgramEnvParameter4fARB := dglGetProcAddress('glProgramEnvParameter4fARB');
+ glProgramEnvParameter4fvARB := dglGetProcAddress('glProgramEnvParameter4fvARB');
+ glProgramLocalParameter4dARB := dglGetProcAddress('glProgramLocalParameter4dARB');
+ glProgramLocalParameter4dvARB := dglGetProcAddress('glProgramLocalParameter4dvARB');
+ glProgramLocalParameter4fARB := dglGetProcAddress('glProgramLocalParameter4fARB');
+ glProgramLocalParameter4fvARB := dglGetProcAddress('glProgramLocalParameter4fvARB');
+ glGetProgramEnvParameterdvARB := dglGetProcAddress('glGetProgramEnvParameterdvARB');
+ glGetProgramEnvParameterfvARB := dglGetProcAddress('glGetProgramEnvParameterfvARB');
+ glGetProgramLocalParameterdvARB := dglGetProcAddress('glGetProgramLocalParameterdvARB');
+ glGetProgramLocalParameterfvARB := dglGetProcAddress('glGetProgramLocalParameterfvARB');
+ glGetProgramivARB := dglGetProcAddress('glGetProgramivARB');
+ glGetProgramStringARB := dglGetProcAddress('glGetProgramStringARB');
+ glGetVertexAttribdvARB := dglGetProcAddress('glGetVertexAttribdvARB');
+ glGetVertexAttribfvARB := dglGetProcAddress('glGetVertexAttribfvARB');
+ glGetVertexAttribivARB := dglGetProcAddress('glGetVertexAttribivARB');
+ glGetVertexAttribPointervARB := dglGetProcAddress('glGetVertexAttribPointervARB');
+ glIsProgramARB := dglGetProcAddress('glIsProgramARB');
+end;
+
+procedure Read_GL_ARB_window_pos;
+begin
+ glWindowPos2dARB := dglGetProcAddress('glWindowPos2dARB');
+ glWindowPos2dvARB := dglGetProcAddress('glWindowPos2dvARB');
+ glWindowPos2fARB := dglGetProcAddress('glWindowPos2fARB');
+ glWindowPos2fvARB := dglGetProcAddress('glWindowPos2fvARB');
+ glWindowPos2iARB := dglGetProcAddress('glWindowPos2iARB');
+ glWindowPos2ivARB := dglGetProcAddress('glWindowPos2ivARB');
+ glWindowPos2sARB := dglGetProcAddress('glWindowPos2sARB');
+ glWindowPos2svARB := dglGetProcAddress('glWindowPos2svARB');
+ glWindowPos3dARB := dglGetProcAddress('glWindowPos3dARB');
+ glWindowPos3dvARB := dglGetProcAddress('glWindowPos3dvARB');
+ glWindowPos3fARB := dglGetProcAddress('glWindowPos3fARB');
+ glWindowPos3fvARB := dglGetProcAddress('glWindowPos3fvARB');
+ glWindowPos3iARB := dglGetProcAddress('glWindowPos3iARB');
+ glWindowPos3ivARB := dglGetProcAddress('glWindowPos3ivARB');
+ glWindowPos3sARB := dglGetProcAddress('glWindowPos3sARB');
+ glWindowPos3svARB := dglGetProcAddress('glWindowPos3svARB');
+end;
+
+procedure Read_GL_ARB_draw_buffers;
+begin
+ glDrawBuffersARB := dglGetProcAddress('glDrawBuffersARB');
+end;
+
+procedure Read_GL_ARB_color_buffer_float;
+begin
+ glClampColorARB := dglGetProcAddress('glClampColorARB');
+end;
+
+procedure Read_GL_ARB_Shader_Objects;
+begin
+ // GL_ARB_Shader_Objects
+ glCreateShaderObjectARB := dglGetProcAddress('glCreateShaderObjectARB');
+ glShaderSourceARB := dglGetProcAddress('glShaderSourceARB');
+ glCompileShaderARB := dglGetProcAddress('glCompileShaderARB');
+ glDeleteObjectARB := dglGetProcAddress('glDeleteObjectARB');
+ glGetHandleARB := dglGetProcAddress('glGetHandleARB');
+ glDetachObjectARB := dglGetProcAddress('glDetachObjectARB');
+ glCreateProgramObjectARB := dglGetProcAddress('glCreateProgramObjectARB');
+ glAttachObjectARB := dglGetProcAddress('glAttachObjectARB');
+ glLinkProgramARB := dglGetProcAddress('glLinkProgramARB');
+ glUseProgramObjectARB := dglGetProcAddress('glUseProgramObjectARB');
+ glValidateProgramARB := dglGetProcAddress('glValidateProgramARB');
+ glGetObjectParameterfvARB := dglGetProcAddress('glGetObjectParameterfvARB');
+ glGetObjectParameterivARB := dglGetProcAddress('glGetObjectParameterivARB');
+ glGetActiveUniformARB := dglGetProcAddress('glGetActiveUniformARB');
+ glGetAttachedObjectsARB := dglGetProcAddress('glGetAttachedObjectsARB');
+ glGetShaderSourceARB := dglGetProcAddress('glGetShaderSourceARB');
+ glGetUniformfvARB := dglGetProcAddress('glGetUniformfvARB');
+ glGetUniformivARB := dglGetProcAddress('glGetUniformivARB');
+ glGetUniformLocationARB := dglGetProcAddress('glGetUniformLocationARB');
+ glGetInfoLogARB := dglGetProcAddress('glGetInfoLogARB');
+ glUniform1fARB := dglGetProcAddress('glUniform1fARB');
+ glUniform2fARB := dglGetProcAddress('glUniform2fARB');
+ glUniform3fARB := dglGetProcAddress('glUniform3fARB');
+ glUniform4fARB := dglGetProcAddress('glUniform4fARB');
+ glUniform1iARB := dglGetProcAddress('glUniform1iARB');
+ glUniform2iARB := dglGetProcAddress('glUniform2iARB');
+ glUniform3iARB := dglGetProcAddress('glUniform3iARB');
+ glUniform4iARB := dglGetProcAddress('glUniform4iARB');
+ glUniform1fvARB := dglGetProcAddress('glUniform1fvARB');
+ glUniform2fvARB := dglGetProcAddress('glUniform2fvARB');
+ glUniform3fvARB := dglGetProcAddress('glUniform3fvARB');
+ glUniform4fvARB := dglGetProcAddress('glUniform4fvARB');
+ glUniform1ivARB := dglGetProcAddress('glUniform1ivARB');
+ glUniform2ivARB := dglGetProcAddress('glUniform2ivARB');
+ glUniform3ivARB := dglGetProcAddress('glUniform3ivARB');
+ glUniform4ivARB := dglGetProcAddress('glUniform4ivARB');
+ glUniformMatrix2fvARB := dglGetProcAddress('glUniformMatrix2fvARB');
+ glUniformMatrix3fvARB := dglGetProcAddress('glUniformMatrix3fvARB');
+ glUniformMatrix4fvARB := dglGetProcAddress('glUniformMatrix4fvARB');
+
+ // GL_ARB_vertex_shader
+ glGetActiveAttribARB := dglGetProcAddress('glGetActiveAttribARB');
+ glGetAttribLocationARB := dglGetProcAddress('glGetAttribLocationARB');
+ glBindAttribLocationARB := dglGetProcAddress('glBindAttribLocationARB');
+ glGetVertexAttribPointervARB := dglGetProcAddress('glGetVertexAttribPointervARB');
+end;
+
+procedure Read_GL_ARB_occlusion_query;
+begin
+ glGenQueriesARB := dglGetProcAddress('glGenQueriesARB');
+ glDeleteQueriesARB := dglGetProcAddress('glDeleteQueriesARB');
+ glIsQueryARB := dglGetProcAddress('glIsQueryARB');
+ glBeginQueryARB := dglGetProcAddress('glBeginQueryARB');
+ glEndQueryARB := dglGetProcAddress('glEndQueryARB');
+ glGetQueryivARB := dglGetProcAddress('glGetQueryivARB');
+ glGetQueryObjectivARB := dglGetProcAddress('glGetQueryObjectivARB');
+ glGetQueryObjectuivARB := dglGetProcAddress('glGetQueryObjectuivARB');
+end;
+
+procedure Read_GL_ARB_draw_instanced;
+begin
+ glDrawArraysInstancedARB := dglGetProcAddress('glDrawArraysInstancedARB');
+ glDrawElementsInstancedARB := dglGetProcAddress('glDrawElementsInstancedARB');
+end;
+
+procedure Read_GL_ARB_framebuffer_object;
+begin
+ glIsRenderbuffer := dglGetProcAddress('glIsRenderbuffer');
+ glBindRenderbuffer := dglGetProcAddress('glBindRenderbuffer');
+ glDeleteRenderbuffers := dglGetProcAddress('glDeleteRenderbuffers');
+ glGenRenderbuffers := dglGetProcAddress('glGenRenderbuffers');
+ glRenderbufferStorage := dglGetProcAddress('glRenderbufferStorage');
+ glGetRenderbufferParameteriv := dglGetProcAddress('glGetRenderbufferParameteriv');
+ glIsFramebuffer := dglGetProcAddress('glIsFramebuffer');
+ glBindFramebuffer := dglGetProcAddress('glBindFramebuffer');
+ glDeleteFramebuffers := dglGetProcAddress('glDeleteFramebuffers');
+ glGenFramebuffers := dglGetProcAddress('glGenFramebuffers');
+ glCheckFramebufferStatus := dglGetProcAddress('glCheckFramebufferStatus');
+ glFramebufferTexture1D := dglGetProcAddress('glFramebufferTexture1D');
+ glFramebufferTexture2D := dglGetProcAddress('glFramebufferTexture2D');
+ glFramebufferTexture3D := dglGetProcAddress('glFramebufferTexture3D');
+ glFramebufferRenderbuffer := dglGetProcAddress('glFramebufferRenderbuffer');
+ glGetFramebufferAttachmentParameteriv := dglGetProcAddress('glGetFramebufferAttachmentParameteriv');
+ glGenerateMipmap := dglGetProcAddress('glGenerateMipmap');
+ glBlitFramebuffer := dglGetProcAddress('glBlitFramebuffer');
+ glRenderbufferStorageMultisample := dglGetProcAddress('glRenderbufferStorageMultisample');
+ glFramebufferTextureLayer := dglGetProcAddress('glFramebufferTextureLayer');
+end;
+
+procedure Read_GL_ARB_geometry_shader4;
+begin
+ glProgramParameteriARB := dglGetProcAddress('glProgramParameteriARB');
+ glFramebufferTextureARB := dglGetProcAddress('glFramebufferTextureARB');
+ glFramebufferTextureLayerARB := dglGetProcAddress('glFramebufferTextureLayerARB');
+ glFramebufferTextureFaceARB := dglGetProcAddress('glFramebufferTextureFaceARB');
+end;
+
+procedure Read_GL_ARB_gl_spirv;
+begin
+ glSpecializeShaderARB := dglGetProcAddress('glSpecializeShaderARB');
+end;
+
+procedure Read_GL_ARB_instanced_arrays;
+begin
+ glVertexAttribDivisorARB := dglGetProcAddress('glVertexAttribDivisorARB');
+end;
+
+procedure Read_GL_ARB_map_buffer_range;
+begin
+ glMapBufferRange := dglGetProcAddress('glMapBufferRange');
+ glFlushMappedBufferRange := dglGetProcAddress('glFlushMappedBufferRange');
+end;
+
+procedure Read_GL_ARB_texture_buffer_object;
+begin
+ glTexBufferARB := dglGetProcAddress('glTexBufferARB');
+end;
+
+procedure Read_GL_ARB_vertex_array_object;
+begin
+ glBindVertexArray := dglGetProcAddress('glBindVertexArray');
+ glDeleteVertexArrays := dglGetProcAddress('glDeleteVertexArrays');
+ glGenVertexArrays := dglGetProcAddress('glGenVertexArrays');
+ glIsVertexArray := dglGetProcAddress('glIsVertexArray');
+end;
+
+procedure Read_GL_ARB_uniform_buffer_object;
+begin
+ glGetUniformIndices := dglGetProcAddress('glGetUniformIndices');
+ glGetActiveUniformsiv := dglGetProcAddress('glGetActiveUniformsiv');
+ glGetActiveUniformName := dglGetProcAddress('glGetActiveUniformName');
+ glGetUniformBlockIndex := dglGetProcAddress('glGetUniformBlockIndex');
+ glGetActiveUniformBlockiv := dglGetProcAddress('glGetActiveUniformBlockiv');
+ glGetActiveUniformBlockName := dglGetProcAddress('glGetActiveUniformBlockName');
+ glUniformBlockBinding := dglGetProcAddress('glUniformBlockBinding');
+end;
+
+procedure Read_GL_ARB_copy_buffer;
+begin
+ glCopyBufferSubData := dglGetProcAddress('glCopyBufferSubData');
+end;
+
+procedure Read_GL_ARB_draw_elements_base_vertex;
+begin
+ glDrawElementsBaseVertex := dglGetProcAddress('glDrawElementsBaseVertex');
+ glDrawRangeElementsBaseVertex := dglGetProcAddress('glDrawRangeElementsBaseVertex');
+ glDrawElementsInstancedBaseVertex := dglGetProcAddress('glDrawElementsInstancedBaseVertex');
+ glMultiDrawElementsBaseVertex := dglGetProcAddress('glMultiDrawElementsBaseVertex');
+end;
+
+procedure Read_GL_ARB_provoking_vertex;
+begin
+ glProvokingVertex := dglGetProcAddress('glProvokingVertex');
+end;
+
+procedure Read_GL_ARB_sync;
+begin
+ glFenceSync := dglGetProcAddress('glFenceSync');
+ glIsSync := dglGetProcAddress('glIsSync');
+ glDeleteSync := dglGetProcAddress('glDeleteSync');
+ glClientWaitSync := dglGetProcAddress('glClientWaitSync');
+ glWaitSync := dglGetProcAddress('glWaitSync');
+ glGetInteger64v := dglGetProcAddress('glGetInteger64v');
+ glGetSynciv := dglGetProcAddress('glGetSynciv');
+end;
+
+procedure Read_GL_ARB_texture_multisample;
+begin
+ glTexImage2DMultisample := dglGetProcAddress('glTexImage2DMultisample');
+ glTexImage3DMultisample := dglGetProcAddress('glTexImage3DMultisample');
+ glGetMultisamplefv := dglGetProcAddress('glGetMultisamplefv');
+ glSampleMaski := dglGetProcAddress('glSampleMaski');
+end;
+
+procedure Read_GL_ARB_draw_buffers_blend;
+begin
+ glBlendEquationiARB := dglGetProcAddress('glBlendEquationiARB');
+ glBlendEquationSeparateiARB := dglGetProcAddress('glBlendEquationSeparateiARB');
+ glBlendFunciARB := dglGetProcAddress('glBlendFunciARB');
+ glBlendFuncSeparateiARB := dglGetProcAddress('glBlendFuncSeparateiARB');
+end;
+
+procedure Read_GL_ARB_sample_shading;
+begin
+ glMinSampleShadingARB := dglGetProcAddress('glMinSampleShadingARB');
+end;
+
+procedure Read_GL_ARB_sample_locations;
+begin
+ glFramebufferSampleLocationsfvARB := dglGetProcAddress('glFramebufferSampleLocationsfvARB');
+ glNamedFramebufferSampleLocationsfvARB := dglGetProcAddress('glNamedFramebufferSampleLocationsfvARB');
+ glEvaluateDepthValuesARB := dglGetProcAddress('glEvaluateDepthValuesARB');;
+end;
+
+procedure Read_GL_ARB_shading_language_include;
+begin
+ glNamedStringARB := dglGetProcAddress('glNamedStringARB');
+ glDeleteNamedStringARB := dglGetProcAddress('glDeleteNamedStringARB');
+ glCompileShaderIncludeARB := dglGetProcAddress('glCompileShaderIncludeARB');
+ glIsNamedStringARB := dglGetProcAddress('glIsNamedStringARB');
+ glGetNamedStringARB := dglGetProcAddress('glGetNamedStringARB');
+ glGetNamedStringivARB := dglGetProcAddress('glGetNamedStringivARB');
+end;
+
+procedure Read_GL_ARB_sparse_texture;
+begin
+ glTexPageCommitmentARB := dglGetProcAddress('glTexPageCommitmentARB');
+end;
+
+procedure Read_GL_ARB_sparse_buffer;
+begin
+ glBufferPageCommitmentARB := dglGetProcAddress('glBufferPageCommitmentARB');
+ glNamedBufferPageCommitmentEXT := dglGetProcAddress('glNamedBufferPageCommitmentEXT');
+ glNamedBufferPageCommitmentARB := dglGetProcAddress('glNamedBufferPageCommitmentARB');
+end;
+
+procedure Read_GL_KHR_blend_equation_advanced;
+begin
+ glBlendBarrierKHR := dglGetProcAddress('glBlendBarrierKHR');
+end;
+
+
+procedure Read_GL_ARB_blend_func_extended;
+begin
+ glBindFragDataLocationIndexed := dglGetProcAddress('glBindFragDataLocationIndexed');
+ glGetFragDataIndex := dglGetProcAddress('glGetFragDataIndex');
+end;
+
+procedure Read_GL_ARB_sampler_objects;
+begin
+ glGenSamplers := dglGetProcAddress('glGenSamplers');
+ glDeleteSamplers := dglGetProcAddress('glDeleteSamplers');
+ glIsSampler := dglGetProcAddress('glIsSampler');
+ glBindSampler := dglGetProcAddress('glBindSampler');
+ glSamplerParameteri := dglGetProcAddress('glSamplerParameteri');
+ glSamplerParameteriv := dglGetProcAddress('glSamplerParameteriv');
+ glSamplerParameterf := dglGetProcAddress('glSamplerParameterf');
+ glSamplerParameterfv := dglGetProcAddress('glSamplerParameterfv');
+ glSamplerParameterIiv := dglGetProcAddress('glSamplerParameterIiv');
+ glSamplerParameterIuiv := dglGetProcAddress('glSamplerParameterIuiv');
+ glGetSamplerParameteriv := dglGetProcAddress('glGetSamplerParameteriv');
+ glGetSamplerParameterIiv := dglGetProcAddress('glGetSamplerParameterIiv');
+ glGetSamplerParameterfv := dglGetProcAddress('glGetSamplerParameterfv');
+ glGetSamplerParameterIuiv := dglGetProcAddress('glGetSamplerParameterIuiv');
+end;
+
+procedure Read_GL_ARB_timer_query;
+begin
+ glQueryCounter := dglGetProcAddress('glQueryCounter');
+ glGetQueryObjecti64v := dglGetProcAddress('glGetQueryObjecti64v');
+ glGetQueryObjectui64v := dglGetProcAddress('glGetQueryObjectui64v');
+end;
+
+procedure Read_GL_ARB_vertex_type_2_10_10_10_rev;
+begin
+ glVertexP2ui := dglGetProcAddress('glVertexP2ui');
+ glVertexP2uiv := dglGetProcAddress('glVertexP2uiv');
+ glVertexP3ui := dglGetProcAddress('glVertexP3ui');
+ glVertexP3uiv := dglGetProcAddress('glVertexP3uiv');
+ glVertexP4ui := dglGetProcAddress('glVertexP4ui');
+ glVertexP4uiv := dglGetProcAddress('glVertexP4uiv');
+ glTexCoordP1ui := dglGetProcAddress('glTexCoordP1ui');
+ glTexCoordP1uiv := dglGetProcAddress('glTexCoordP1uiv');
+ glTexCoordP2ui := dglGetProcAddress('glTexCoordP2ui');
+ glTexCoordP2uiv := dglGetProcAddress('glTexCoordP2uiv');
+ glTexCoordP3ui := dglGetProcAddress('glTexCoordP3ui');
+ glTexCoordP3uiv := dglGetProcAddress('glTexCoordP3uiv');
+ glTexCoordP4ui := dglGetProcAddress('glTexCoordP4ui');
+ glTexCoordP4uiv := dglGetProcAddress('glTexCoordP4uiv');
+ glMultiTexCoordP1ui := dglGetProcAddress('glMultiTexCoordP1ui');
+ glMultiTexCoordP1uiv := dglGetProcAddress('glMultiTexCoordP1uiv');
+ glMultiTexCoordP2ui := dglGetProcAddress('glMultiTexCoordP2ui');
+ glMultiTexCoordP2uiv := dglGetProcAddress('glMultiTexCoordP2uiv');
+ glMultiTexCoordP3ui := dglGetProcAddress('glMultiTexCoordP3ui');
+ glMultiTexCoordP3uiv := dglGetProcAddress('glMultiTexCoordP3uiv');
+ glMultiTexCoordP4ui := dglGetProcAddress('glMultiTexCoordP4ui');
+ glMultiTexCoordP4uiv := dglGetProcAddress('glMultiTexCoordP4uiv');
+ glNormalP3ui := dglGetProcAddress('glNormalP3ui');
+ glNormalP3uiv := dglGetProcAddress('glNormalP3uiv');
+ glColorP3ui := dglGetProcAddress('glColorP3ui');
+ glColorP3uiv := dglGetProcAddress('glColorP3uiv');
+ glColorP4ui := dglGetProcAddress('glColorP4ui');
+ glColorP4uiv := dglGetProcAddress('glColorP4uiv');
+ glSecondaryColorP3ui := dglGetProcAddress('glSecondaryColorP3ui');
+ glSecondaryColorP3uiv := dglGetProcAddress('glSecondaryColorP3uiv');
+ glVertexAttribP1ui := dglGetProcAddress('glVertexAttribP1ui');
+ glVertexAttribP1uiv := dglGetProcAddress('glVertexAttribP1uiv');
+ glVertexAttribP2ui := dglGetProcAddress('glVertexAttribP2ui');
+ glVertexAttribP2uiv := dglGetProcAddress('glVertexAttribP2uiv');
+ glVertexAttribP3ui := dglGetProcAddress('glVertexAttribP3ui');
+ glVertexAttribP3uiv := dglGetProcAddress('glVertexAttribP3uiv');
+ glVertexAttribP4ui := dglGetProcAddress('glVertexAttribP4ui');
+ glVertexAttribP4uiv := dglGetProcAddress('glVertexAttribP4uiv');
+end;
+
+procedure Read_GL_ARB_draw_indirect;
+begin
+ glDrawArraysIndirect := dglGetProcAddress('glDrawArraysIndirect');
+ glDrawElementsIndirect := dglGetProcAddress('glDrawElementsIndirect');
+end;
+
+procedure Read_GL_ARB_gpu_shader_fp64;
+begin
+ glUniform1d := dglGetProcAddress('glUniform1d');
+ glUniform2d := dglGetProcAddress('glUniform2d');
+ glUniform3d := dglGetProcAddress('glUniform3d');
+ glUniform4d := dglGetProcAddress('glUniform4d');
+ glUniform1dv := dglGetProcAddress('glUniform1dv');
+ glUniform2dv := dglGetProcAddress('glUniform2dv');
+ glUniform3dv := dglGetProcAddress('glUniform3dv');
+ glUniform4dv := dglGetProcAddress('glUniform4dv');
+ glUniformMatrix2dv := dglGetProcAddress('glUniformMatrix2dv');
+ glUniformMatrix3dv := dglGetProcAddress('glUniformMatrix3dv');
+ glUniformMatrix4dv := dglGetProcAddress('glUniformMatrix4dv');
+ glUniformMatrix2x3dv := dglGetProcAddress('glUniformMatrix2x3dv');
+ glUniformMatrix2x4dv := dglGetProcAddress('glUniformMatrix2x4dv');
+ glUniformMatrix3x2dv := dglGetProcAddress('glUniformMatrix3x2dv');
+ glUniformMatrix3x4dv := dglGetProcAddress('glUniformMatrix3x4dv');
+ glUniformMatrix4x2dv := dglGetProcAddress('glUniformMatrix4x2dv');
+ glUniformMatrix4x3dv := dglGetProcAddress('glUniformMatrix4x3dv');
+ glGetUniformdv := dglGetProcAddress('glGetUniformdv');
+end;
+
+procedure Read_GL_ARB_gpu_shader_int64;
+begin
+ glUniform1i64ARB := dglGetProcAddress('glUniform1i64ARB');
+ glUniform2i64ARB := dglGetProcAddress('glUniform2i64ARB');
+ glUniform3i64ARB := dglGetProcAddress('glUniform3i64ARB');
+ glUniform4i64ARB := dglGetProcAddress('glUniform4i64ARB');
+ glUniform1i64vARB := dglGetProcAddress('glUniform1i64vARB');
+ glUniform2i64vARB := dglGetProcAddress('glUniform2i64vARB');
+ glUniform3i64vARB := dglGetProcAddress('glUniform3i64vARB');
+ glUniform4i64vARB := dglGetProcAddress('glUniform4i64vARB');
+ glUniform1ui64ARB := dglGetProcAddress('glUniform1ui64ARB');
+ glUniform2ui64ARB := dglGetProcAddress('glUniform2ui64ARB');
+ glUniform3ui64ARB := dglGetProcAddress('glUniform3ui64ARB');
+ glUniform4ui64ARB := dglGetProcAddress('glUniform4ui64ARB');
+ glUniform1ui64vARB := dglGetProcAddress('glUniform1ui64vARB');
+ glUniform2ui64vARB := dglGetProcAddress('glUniform2ui64vARB');
+ glUniform3ui64vARB := dglGetProcAddress('glUniform3ui64vARB');
+ glUniform4ui64vARB := dglGetProcAddress('glUniform4ui64vARB');
+ glGetUniformi64vARB := dglGetProcAddress('glGetUniformi64vARB');
+ glGetUniformui64vARB := dglGetProcAddress('glGetUniformui64vARB');
+ glGetnUniformi64vARB := dglGetProcAddress('glGetnUniformi64vARB');
+ glGetnUniformui64vARB := dglGetProcAddress('glGetnUniformui64vARB');
+ glProgramUniform1i64ARB := dglGetProcAddress('glProgramUniform1i64ARB');
+ glProgramUniform2i64ARB := dglGetProcAddress('glProgramUniform2i64ARB');
+ glProgramUniform3i64ARB := dglGetProcAddress('glProgramUniform3i64ARB');
+ glProgramUniform4i64ARB := dglGetProcAddress('glProgramUniform4i64ARB');
+ glProgramUniform1i64vARB := dglGetProcAddress('glProgramUniform1i64vARB');
+ glProgramUniform2i64vARB := dglGetProcAddress('glProgramUniform2i64vARB');
+ glProgramUniform3i64vARB := dglGetProcAddress('glProgramUniform3i64vARB');
+ glProgramUniform4i64vARB := dglGetProcAddress('glProgramUniform4i64vARB');
+ glProgramUniform1ui64ARB := dglGetProcAddress('glProgramUniform1ui64ARB');
+ glProgramUniform2ui64ARB := dglGetProcAddress('glProgramUniform2ui64ARB');
+ glProgramUniform3ui64ARB := dglGetProcAddress('glProgramUniform3ui64ARB');
+ glProgramUniform4ui64ARB := dglGetProcAddress('glProgramUniform4ui64ARB ');
+ glProgramUniform1ui64vARB := dglGetProcAddress('glProgramUniform1ui64vARB');
+ glProgramUniform2ui64vARB := dglGetProcAddress('glProgramUniform2ui64vARB');
+ glProgramUniform3ui64vARB := dglGetProcAddress('glProgramUniform3ui64vARB');
+ glProgramUniform4ui64vARB := dglGetProcAddress('glProgramUniform4ui64vARB');
+end;
+
+procedure Read_GL_ARB_shader_subroutine;
+begin
+ glGetSubroutineUniformLocation := dglGetProcAddress('glGetSubroutineUniformLocation');
+ glGetSubroutineIndex := dglGetProcAddress('glGetSubroutineIndex');
+ glGetActiveSubroutineUniformiv := dglGetProcAddress('glGetActiveSubroutineUniformiv');
+ glGetActiveSubroutineUniformName := dglGetProcAddress('glGetActiveSubroutineUniformName');
+ glGetActiveSubroutineName := dglGetProcAddress('glGetActiveSubroutineName');
+ glUniformSubroutinesuiv := dglGetProcAddress('glUniformSubroutinesuiv');
+ glGetUniformSubroutineuiv := dglGetProcAddress('glGetUniformSubroutineuiv');
+ glGetProgramStageiv := dglGetProcAddress('glGetProgramStageiv');
+end;
+
+procedure Read_GL_ARB_tessellation_shader;
+begin
+ glPatchParameteri := dglGetProcAddress('glPatchParameteri');
+ glPatchParameterfv := dglGetProcAddress('glPatchParameterfv');
+end;
+
+procedure Read_GL_ARB_transform_feedback2;
+begin
+ glBindTransformFeedback := dglGetProcAddress('glBindTransformFeedback');
+ glDeleteTransformFeedbacks := dglGetProcAddress('glDeleteTransformFeedbacks');
+ glGenTransformFeedbacks := dglGetProcAddress('glGenTransformFeedbacks');
+ glIsTransformFeedback := dglGetProcAddress('glIsTransformFeedback');
+ glPauseTransformFeedback := dglGetProcAddress('glPauseTransformFeedback');
+ glResumeTransformFeedback := dglGetProcAddress('glResumeTransformFeedback');
+ glDrawTransformFeedback := dglGetProcAddress('glDrawTransformFeedback');
+end;
+
+procedure Read_GL_ARB_transform_feedback3;
+begin
+ glDrawTransformFeedbackStream := dglGetProcAddress('glDrawTransformFeedbackStream');
+ glBeginQueryIndexed := dglGetProcAddress('glBeginQueryIndexed');
+ glEndQueryIndexed := dglGetProcAddress('glEndQueryIndexed');
+ glGetQueryIndexediv := dglGetProcAddress('glGetQueryIndexediv');
+end;
+
+procedure Read_GL_ARB_ES2_compatibility;
+begin
+ glReleaseShaderCompiler := dglGetProcAddress('glReleaseShaderCompiler');
+ glShaderBinary := dglGetProcAddress('glShaderBinary');
+ glGetShaderPrecisionFormat := dglGetProcAddress('glGetShaderPrecisionFormat');
+ glDepthRangef := dglGetProcAddress('glDepthRangef');
+ glClearDepthf := dglGetProcAddress('glClearDepthf');
+end;
+
+procedure Read_GL_ARB_ES3_2_compatibility;
+begin
+ glPrimitiveBoundingBoxARB := dglGetProcAddress('glPrimitiveBoundingBoxARB');
+end;
+
+procedure Read_GL_ARB_parallel_shader_compile;
+begin
+ glMaxShaderCompilerThreadsARB := dglGetProcAddress('glMaxShaderCompilerThreadsARB');
+end;
+
+procedure Read_GL_ARB_get_program_binary;
+begin
+ glGetProgramBinary := dglGetProcAddress('glGetProgramBinary');
+ glProgramBinary := dglGetProcAddress('glProgramBinary');
+ glProgramParameteri := dglGetProcAddress('glProgramParameteri');
+end;
+
+procedure Read_GL_ARB_separate_shader_objects;
+begin
+ glUseProgramStages := dglGetProcAddress('glUseProgramStages');
+ glActiveShaderProgram := dglGetProcAddress('glActiveShaderProgram');
+ glCreateShaderProgramv := dglGetProcAddress('glCreateShaderProgramv');
+ glBindProgramPipeline := dglGetProcAddress('glBindProgramPipeline');
+ glDeleteProgramPipelines := dglGetProcAddress('glDeleteProgramPipelines');
+ glGenProgramPipelines := dglGetProcAddress('glGenProgramPipelines');
+ glIsProgramPipeline := dglGetProcAddress('glIsProgramPipeline');
+ glGetProgramPipelineiv := dglGetProcAddress('glGetProgramPipelineiv');
+ glProgramUniform1i := dglGetProcAddress('glProgramUniform1i');
+ glProgramUniform1iv := dglGetProcAddress('glProgramUniform1iv');
+ glProgramUniform1f := dglGetProcAddress('glProgramUniform1f');
+ glProgramUniform1fv := dglGetProcAddress('glProgramUniform1fv');
+ glProgramUniform1d := dglGetProcAddress('glProgramUniform1d');
+ glProgramUniform1dv := dglGetProcAddress('glProgramUniform1dv');
+ glProgramUniform1ui := dglGetProcAddress('glProgramUniform1ui');
+ glProgramUniform1uiv := dglGetProcAddress('glProgramUniform1uiv');
+ glProgramUniform2i := dglGetProcAddress('glProgramUniform2i');
+ glProgramUniform2iv := dglGetProcAddress('glProgramUniform2iv');
+ glProgramUniform2f := dglGetProcAddress('glProgramUniform2f');
+ glProgramUniform2fv := dglGetProcAddress('glProgramUniform2fv');
+ glProgramUniform2d := dglGetProcAddress('glProgramUniform2d');
+ glProgramUniform2dv := dglGetProcAddress('glProgramUniform2dv');
+ glProgramUniform2ui := dglGetProcAddress('glProgramUniform2ui');
+ glProgramUniform2uiv := dglGetProcAddress('glProgramUniform2uiv');
+ glProgramUniform3i := dglGetProcAddress('glProgramUniform3i');
+ glProgramUniform3iv := dglGetProcAddress('glProgramUniform3iv');
+ glProgramUniform3f := dglGetProcAddress('glProgramUniform3f');
+ glProgramUniform3fv := dglGetProcAddress('glProgramUniform3fv');
+ glProgramUniform3d := dglGetProcAddress('glProgramUniform3d');
+ glProgramUniform3dv := dglGetProcAddress('glProgramUniform3dv');
+ glProgramUniform3ui := dglGetProcAddress('glProgramUniform3ui');
+ glProgramUniform3uiv := dglGetProcAddress('glProgramUniform3uiv');
+ glProgramUniform4i := dglGetProcAddress('glProgramUniform4i');
+ glProgramUniform4iv := dglGetProcAddress('glProgramUniform4iv');
+ glProgramUniform4f := dglGetProcAddress('glProgramUniform4f');
+ glProgramUniform4fv := dglGetProcAddress('glProgramUniform4fv');
+ glProgramUniform4d := dglGetProcAddress('glProgramUniform4d');
+ glProgramUniform4dv := dglGetProcAddress('glProgramUniform4dv');
+ glProgramUniform4ui := dglGetProcAddress('glProgramUniform4ui');
+ glProgramUniform4uiv := dglGetProcAddress('glProgramUniform4uiv');
+ glProgramUniformMatrix2fv := dglGetProcAddress('glProgramUniformMatrix2fv');
+ glProgramUniformMatrix3fv := dglGetProcAddress('glProgramUniformMatrix3fv');
+ glProgramUniformMatrix4fv := dglGetProcAddress('glProgramUniformMatrix4fv');
+ glProgramUniformMatrix2dv := dglGetProcAddress('glProgramUniformMatrix2dv');
+ glProgramUniformMatrix3dv := dglGetProcAddress('glProgramUniformMatrix3dv');
+ glProgramUniformMatrix4dv := dglGetProcAddress('glProgramUniformMatrix4dv');
+ glProgramUniformMatrix2x3fv := dglGetProcAddress('glProgramUniformMatrix2x3fv');
+ glProgramUniformMatrix3x2fv := dglGetProcAddress('glProgramUniformMatrix3x2fv');
+ glProgramUniformMatrix2x4fv := dglGetProcAddress('glProgramUniformMatrix2x4fv');
+ glProgramUniformMatrix4x2fv := dglGetProcAddress('glProgramUniformMatrix4x2fv');
+ glProgramUniformMatrix3x4fv := dglGetProcAddress('glProgramUniformMatrix3x4fv');
+ glProgramUniformMatrix4x3fv := dglGetProcAddress('glProgramUniformMatrix4x3fv');
+ glProgramUniformMatrix2x3dv := dglGetProcAddress('glProgramUniformMatrix2x3dv');
+ glProgramUniformMatrix3x2dv := dglGetProcAddress('glProgramUniformMatrix3x2dv');
+ glProgramUniformMatrix2x4dv := dglGetProcAddress('glProgramUniformMatrix2x4dv');
+ glProgramUniformMatrix4x2dv := dglGetProcAddress('glProgramUniformMatrix4x2dv');
+ glProgramUniformMatrix3x4dv := dglGetProcAddress('glProgramUniformMatrix3x4dv');
+ glProgramUniformMatrix4x3dv := dglGetProcAddress('glProgramUniformMatrix4x3dv');
+ glValidateProgramPipeline := dglGetProcAddress('glValidateProgramPipeline');
+ glGetProgramPipelineInfoLog := dglGetProcAddress('glGetProgramPipelineInfoLog');
+end;
+
+procedure Read_GL_ARB_vertex_attrib_64bit;
+begin
+ glVertexAttribL1d := dglGetProcAddress('glVertexAttribL1d');
+ glVertexAttribL2d := dglGetProcAddress('glVertexAttribL2d');
+ glVertexAttribL3d := dglGetProcAddress('glVertexAttribL3d');
+ glVertexAttribL4d := dglGetProcAddress('glVertexAttribL4d');
+ glVertexAttribL1dv := dglGetProcAddress('glVertexAttribL1dv');
+ glVertexAttribL2dv := dglGetProcAddress('glVertexAttribL2dv');
+ glVertexAttribL3dv := dglGetProcAddress('glVertexAttribL3dv');
+ glVertexAttribL4dv := dglGetProcAddress('glVertexAttribL4dv');
+ glVertexAttribLPointer := dglGetProcAddress('glVertexAttribLPointer');
+ glGetVertexAttribLdv := dglGetProcAddress('glGetVertexAttribLdv');
+end;
+
+procedure Read_GL_ARB_viewport_array;
+begin
+ glViewportArrayv := dglGetProcAddress('glViewportArrayv');
+ glViewportIndexedf := dglGetProcAddress('glViewportIndexedf');
+ glViewportIndexedfv := dglGetProcAddress('glViewportIndexedfv');
+ glScissorArrayv := dglGetProcAddress('glScissorArrayv');
+ glScissorIndexed := dglGetProcAddress('glScissorIndexed');
+ glScissorIndexedv := dglGetProcAddress('glScissorIndexedv');
+ glDepthRangeArrayv := dglGetProcAddress('glDepthRangeArrayv');
+ glDepthRangeIndexed := dglGetProcAddress('glDepthRangeIndexed');
+ glGetFloati_v := dglGetProcAddress('glGetFloati_v');
+ glGetDoublei_v := dglGetProcAddress('glGetDoublei_v');
+end;
+
+// GL 4.2
+
+procedure Read_GL_ARB_base_instance;
+begin
+glDrawArraysInstancedBaseInstance := dglGetProcAddress('glDrawArraysInstancedBaseInstance');
+glDrawElementsInstancedBaseInstance := dglGetProcAddress('glDrawElementsInstancedBaseInstance');
+glDrawElementsInstancedBaseVertexBaseInstance := dglGetProcAddress('glDrawElementsInstancedBaseVertexBaseInstance');
+end;
+
+procedure Read_GL_ARB_transform_feedback_instanced;
+begin
+glDrawTransformFeedbackInstanced := dglGetProcAddress('glDrawTransformFeedbackInstanced');
+glDrawTransformFeedbackStreamInstanced := dglGetProcAddress('glDrawTransformFeedbackStreamInstanced');
+end;
+
+procedure Read_GL_ARB_internalformat_query;
+begin
+glGetInternalformativ := dglGetProcAddress('glGetInternalformativ');
+end;
+
+procedure Read_GL_ARB_shader_atomic_counters;
+begin
+glGetActiveAtomicCounterBufferiv := dglGetProcAddress('glGetActiveAtomicCounterBufferiv');
+end;
+
+procedure Read_GL_ARB_shader_image_load_store;
+begin
+glBindImageTexture := dglGetProcAddress('glBindImageTexture');
+glMemoryBarrier := dglGetProcAddress('glMemoryBarrier');
+end;
+
+procedure Read_GL_ARB_texture_storage;
+begin
+glTexStorage1D := dglGetProcAddress('glTexStorage1D');
+glTexStorage2D := dglGetProcAddress('glTexStorage2D');
+glTexStorage3D := dglGetProcAddress('glTexStorage3D');
+glTextureStorage1DEXT := dglGetProcAddress('glTextureStorage1DEXT');
+glTextureStorage2DEXT := dglGetProcAddress('glTextureStorage2DEXT');
+glTextureStorage3DEXT := dglGetProcAddress('glTextureStorage3DEXT');
+end;
+
+
+// GL 4.3
+procedure Read_GL_KHR_debug;
+begin
+ glDebugMessageControl := dglGetProcAddress('glDebugMessageControl');
+ glDebugMessageInsert := dglGetProcAddress('glDebugMessageInsert');
+ glDebugMessageCallback := dglGetProcAddress('glDebugMessageCallback');
+ glGetDebugMessageLog := dglGetProcAddress('glGetDebugMessageLog');
+ glPushDebugGroup := dglGetProcAddress('glPushDebugGroup');
+ glPopDebugGroup := dglGetProcAddress('glPopDebugGroup');
+ glObjectLabel := dglGetProcAddress('glObjectLabel');
+ glGetObjectLabel := dglGetProcAddress('glGetObjectLabel');
+ glObjectPtrLabel := dglGetProcAddress('glObjectPtrLabel');
+ glGetObjectPtrLabel := dglGetProcAddress('glGetObjectPtrLabel');
+end;
+
+procedure Read_GL_ARB_clear_buffer_object;
+begin
+ glClearBufferData := dglGetProcAddress('glClearBufferData');
+ glClearBufferSubData := dglGetProcAddress('glClearBufferSubData');
+ glClearNamedBufferDataEXT := dglGetProcAddress('glClearNamedBufferDataEXT');
+ glClearNamedBufferSubDataEXT := dglGetProcAddress('glClearNamedBufferSubDataEXT');
+end;
+
+procedure Read_GL_ARB_compute_shader;
+begin
+ glDispatchCompute := dglGetProcAddress('glDispatchCompute');
+ glDispatchComputeIndirect := dglGetProcAddress('glDispatchComputeIndirect');
+end;
+
+procedure Read_GL_ARB_copy_image;
+begin
+ glCopyImageSubData := dglGetProcAddress('glCopyImageSubData');
+end;
+
+procedure Read_GL_ARB_framebuffer_no_attachments;
+begin
+ glFramebufferParameteri := dglGetProcAddress('glFramebufferParameteri');
+ glGetFramebufferParameteriv := dglGetProcAddress('glGetFramebufferParameteriv');
+ glNamedFramebufferParameteriEXT := dglGetProcAddress('glNamedFramebufferParameteriEXT');
+ glGetNamedFramebufferParameterivEXT := dglGetProcAddress('glGetNamedFramebufferParameterivEXT');
+end;
+
+procedure Read_GL_ARB_internalformat_query2;
+begin
+ glGetInternalformati64v := dglGetProcAddress('glGetInternalformati64v');;
+end;
+
+procedure Read_GL_ARB_invalidate_subdata;
+begin
+ glInvalidateTexSubImage := dglGetProcAddress('glInvalidateTexSubImage');
+ glInvalidateTexImage := dglGetProcAddress('glInvalidateTexImage');
+ glInvalidateBufferSubData := dglGetProcAddress('glInvalidateBufferSubData');
+ glInvalidateBufferData := dglGetProcAddress('glInvalidateBufferData');
+ glInvalidateFramebuffer := dglGetProcAddress('glInvalidateFramebuffer');
+ glInvalidateSubFramebuffer := dglGetProcAddress('glInvalidateSubFramebuffer');
+end;
+
+procedure Read_GL_ARB_multi_draw_indirect;
+begin
+ glMultiDrawArraysIndirect := dglGetProcAddress('glMultiDrawArraysIndirect');
+ glMultiDrawElementsIndirect := dglGetProcAddress('glMultiDrawElementsIndirect');
+end;
+
+procedure Read_GL_ARB_program_interface_query;
+begin
+ glGetProgramInterfaceiv := dglGetProcAddress('glGetProgramInterfaceiv');
+ glGetProgramResourceIndex := dglGetProcAddress('glGetProgramResourceIndex');
+ glGetProgramResourceName := dglGetProcAddress('glGetProgramResourceName');
+ glGetProgramResourceiv := dglGetProcAddress('glGetProgramResourceiv');
+ glGetProgramResourceLocation := dglGetProcAddress('glGetProgramResourceLocation');
+ glGetProgramResourceLocationIndex := dglGetProcAddress('glGetProgramResourceLocationIndex');
+end;
+
+procedure Read_GL_ARB_shader_storage_buffer_object;
+begin
+ glShaderStorageBlockBinding := dglGetProcAddress('glShaderStorageBlockBinding');
+end;
+
+procedure Read_GL_ARB_texture_buffer_range;
+begin
+ glTexBufferRange := dglGetProcAddress('glTexBufferRange');
+ glTextureBufferRangeEXT := dglGetProcAddress('glTextureBufferRangeEXT');
+end;
+
+procedure Read_GL_ARB_texture_storage_multisample;
+begin
+ glTexStorage2DMultisample := dglGetProcAddress('glTexStorage2DMultisample');
+ glTexStorage3DMultisample := dglGetProcAddress('glTexStorage3DMultisample');
+ glTextureStorage2DMultisampleEXT := dglGetProcAddress('glTextureStorage2DMultisampleEXT');
+ glTextureStorage3DMultisampleEXT := dglGetProcAddress('glTextureStorage3DMultisampleEXT');
+end;
+
+procedure Read_GL_ARB_texture_view;
+begin
+ glTextureView := dglGetProcAddress('glTextureView');
+end;
+
+procedure Read_GL_ARB_vertex_attrib_binding;
+begin
+ glBindVertexBuffer := dglGetProcAddress('glBindVertexBuffer');
+ glVertexAttribFormat := dglGetProcAddress('glVertexAttribFormat');
+ glVertexAttribIFormat := dglGetProcAddress('glVertexAttribIFormat');
+ glVertexAttribLFormat := dglGetProcAddress('glVertexAttribLFormat');
+ glVertexAttribBinding := dglGetProcAddress('glVertexAttribBinding');
+ glVertexBindingDivisor := dglGetProcAddress('glVertexBindingDivisor');
+ glVertexArrayBindVertexBufferEXT := dglGetProcAddress('glVertexArrayBindVertexBufferEXT');
+ glVertexArrayVertexAttribFormatEXT := dglGetProcAddress('glVertexArrayVertexAttribFormatEXT');
+ glVertexArrayVertexAttribIFormatEXT := dglGetProcAddress('glVertexArrayVertexAttribIFormatEXT');
+ glVertexArrayVertexAttribLFormatEXT := dglGetProcAddress('glVertexArrayVertexAttribLFormatEXT');
+ glVertexArrayVertexAttribBindingEXT := dglGetProcAddress('glVertexArrayVertexAttribBindingEXT');
+ glVertexArrayVertexBindingDivisorEXT := dglGetProcAddress('glVertexArrayVertexBindingDivisorEXT');
+end;
+
+procedure Read_GL_4_4;
+begin
+ glBufferStorage := dglGetProcAddress('glBufferStorage');
+ glClearTexImage := dglGetProcAddress('glClearTexImage');
+ glClearTexSubImage := dglGetProcAddress('glClearTexSubImage');
+ glBindBuffersBase := dglGetProcAddress('glBindBuffersBase');
+ glBindBuffersRange := dglGetProcAddress('glBindBuffersRange');
+ glBindTextures := dglGetProcAddress('glBindTextures');
+ glBindSamplers := dglGetProcAddress('glBindSamplers');
+ glBindImageTextures := dglGetProcAddress('glBindImageTextures');
+ glBindVertexBuffers := dglGetProcAddress('glBindVertexBuffers');
+end;
+
+procedure Read_GL_4_5;
+begin
+ glClipControl:= dglGetProcAddress('glClipControl');
+ glCreateTransformFeedbacks:= dglGetProcAddress('glCreateTransformFeedbacks');
+ glTransformFeedbackBufferBase:= dglGetProcAddress('glTransformFeedbackBufferBase');
+ glTransformFeedbackBufferRange:= dglGetProcAddress('glTransformFeedbackBufferRange');
+ glGetTransformFeedbackiv:= dglGetProcAddress('glGetTransformFeedbackiv');
+ glGetTransformFeedbacki_v:= dglGetProcAddress('glGetTransformFeedbacki_v');
+ glGetTransformFeedbacki64_v:= dglGetProcAddress('glGetTransformFeedbacki64_v');
+ glCreateBuffers:= dglGetProcAddress('glCreateBuffers');
+ glNamedBufferStorage:= dglGetProcAddress('glNamedBufferStorage');
+ glNamedBufferData:= dglGetProcAddress('glNamedBufferData');
+ glNamedBufferSubData:= dglGetProcAddress('glNamedBufferSubData');
+ glCopyNamedBufferSubData:= dglGetProcAddress('glCopyNamedBufferSubData');
+ glClearNamedBufferData:= dglGetProcAddress('glClearNamedBufferData');
+ glClearNamedBufferSubData:= dglGetProcAddress('glClearNamedBufferSubData');
+ glMapNamedBuffer:= dglGetProcAddress('glMapNamedBuffer');
+ glMapNamedBufferRange:= dglGetProcAddress('glMapNamedBufferRange');
+ glUnmapNamedBuffer:= dglGetProcAddress('glUnmapNamedBuffer');
+ glFlushMappedNamedBufferRange:= dglGetProcAddress('glFlushMappedNamedBufferRange');
+ glGetNamedBufferParameteriv:= dglGetProcAddress('glGetNamedBufferParameteriv');
+ glGetNamedBufferParameteri64v:= dglGetProcAddress('glGetNamedBufferParameteri64v');
+ glGetNamedBufferPointerv:= dglGetProcAddress('glGetNamedBufferPointerv');
+ glGetNamedBufferSubData:= dglGetProcAddress('glGetNamedBufferSubData');
+ glCreateFramebuffers:= dglGetProcAddress('glCreateFramebuffers');
+ glNamedFramebufferRenderbuffer:= dglGetProcAddress('glNamedFramebufferRenderbuffer');
+ glNamedFramebufferParameteri:= dglGetProcAddress('glNamedFramebufferParameteri');
+ glNamedFramebufferTexture:= dglGetProcAddress('glNamedFramebufferTexture');
+ glNamedFramebufferTextureLayer:= dglGetProcAddress('glNamedFramebufferTextureLayer');
+ glNamedFramebufferDrawBuffer:= dglGetProcAddress('glNamedFramebufferDrawBuffer');
+ glNamedFramebufferDrawBuffers:= dglGetProcAddress('glNamedFramebufferDrawBuffers');
+ glNamedFramebufferReadBuffer:= dglGetProcAddress('glNamedFramebufferReadBuffer');
+ glInvalidateNamedFramebufferData:= dglGetProcAddress('glInvalidateNamedFramebufferData');
+ glInvalidateNamedFramebufferSubData:= dglGetProcAddress('glInvalidateNamedFramebufferSubData');
+ glClearNamedFramebufferiv:= dglGetProcAddress('glClearNamedFramebufferiv');
+ glClearNamedFramebufferuiv:= dglGetProcAddress('glClearNamedFramebufferuiv');
+ glClearNamedFramebufferfv:= dglGetProcAddress('glClearNamedFramebufferfv');
+ glClearNamedFramebufferfi:= dglGetProcAddress('glClearNamedFramebufferfi');
+ glBlitNamedFramebuffer:= dglGetProcAddress('glBlitNamedFramebuffer');
+ glCheckNamedFramebufferStatus:= dglGetProcAddress('glCheckNamedFramebufferStatus');
+ glGetNamedFramebufferParameteriv:= dglGetProcAddress('glGetNamedFramebufferParameteriv');
+ glGetNamedFramebufferAttachmentParameteriv:= dglGetProcAddress('glGetNamedFramebufferAttachmentParameteriv');
+ glCreateRenderbuffers:= dglGetProcAddress('glCreateRenderbuffers');
+ glNamedRenderbufferStorage:= dglGetProcAddress('glNamedRenderbufferStorage');
+ glNamedRenderbufferStorageMultisample:= dglGetProcAddress('glNamedRenderbufferStorageMultisample');
+ glGetNamedRenderbufferParameteriv:= dglGetProcAddress('glGetNamedRenderbufferParameteriv');
+ glCreateTextures:= dglGetProcAddress('glCreateTextures');
+ glTextureBuffer:= dglGetProcAddress('glTextureBuffer');
+ glTextureBufferRange:= dglGetProcAddress('glTextureBufferRange');
+ glTextureStorage1D:= dglGetProcAddress('glTextureStorage1D');
+ glTextureStorage2D:= dglGetProcAddress('glTextureStorage2D');
+ glTextureStorage3D:= dglGetProcAddress('glTextureStorage3D');
+ glTextureStorage2DMultisample:= dglGetProcAddress('glTextureStorage2DMultisample');
+ glTextureStorage3DMultisample:= dglGetProcAddress('glTextureStorage3DMultisample');
+ glTextureSubImage1D:= dglGetProcAddress('glTextureSubImage1D');
+ glTextureSubImage2D:= dglGetProcAddress('glTextureSubImage2D');
+ glTextureSubImage3D:= dglGetProcAddress('glTextureSubImage3D');
+ glCompressedTextureSubImage1D:= dglGetProcAddress('glCompressedTextureSubImage1D');
+ glCompressedTextureSubImage2D:= dglGetProcAddress('glCompressedTextureSubImage2D');
+ glCompressedTextureSubImage3D:= dglGetProcAddress('glCompressedTextureSubImage3D');
+ glCopyTextureSubImage1D:= dglGetProcAddress('glCopyTextureSubImage1D');
+ glCopyTextureSubImage2D:= dglGetProcAddress('glCopyTextureSubImage2D');
+ glCopyTextureSubImage3D:= dglGetProcAddress('glCopyTextureSubImage3D');
+ glTextureParameterf:= dglGetProcAddress('glTextureParameterf');
+ glTextureParameterfv:= dglGetProcAddress('glTextureParameterfv');
+ glTextureParameteri:= dglGetProcAddress('glTextureParameteri');
+ glTextureParameterIiv:= dglGetProcAddress('glTextureParameterIiv');
+ glTextureParameterIuiv:= dglGetProcAddress('glTextureParameterIuiv');
+ glTextureParameteriv:= dglGetProcAddress('glTextureParameteriv');
+ glGenerateTextureMipmap:= dglGetProcAddress('glGenerateTextureMipmap');
+ glBindTextureUnit:= dglGetProcAddress('glBindTextureUnit');
+ glGetTextureImage:= dglGetProcAddress('glGetTextureImage');
+ glGetCompressedTextureImage:= dglGetProcAddress('glGetCompressedTextureImage');
+ glGetTextureLevelParameterfv:= dglGetProcAddress('glGetTextureLevelParameterfv');
+ glGetTextureLevelParameteriv:= dglGetProcAddress('glGetTextureLevelParameteriv');
+ glGetTextureParameterfv:= dglGetProcAddress('glGetTextureParameterfv');
+ glGetTextureParameterIiv:= dglGetProcAddress('glGetTextureParameterIiv');
+ glGetTextureParameterIuiv:= dglGetProcAddress('glGetTextureParameterIuiv');
+ glGetTextureParameteriv:= dglGetProcAddress('glGetTextureParameteriv');
+ glCreateVertexArrays:= dglGetProcAddress('glCreateVertexArrays');
+ glDisableVertexArrayAttrib:= dglGetProcAddress('glDisableVertexArrayAttrib');
+ glEnableVertexArrayAttrib:= dglGetProcAddress('glEnableVertexArrayAttrib');
+ glVertexArrayElementBuffer:= dglGetProcAddress('glVertexArrayElementBuffer');
+ glVertexArrayVertexBuffer:= dglGetProcAddress('glVertexArrayVertexBuffer');
+ glVertexArrayVertexBuffers:= dglGetProcAddress('glVertexArrayVertexBuffers');
+ glVertexArrayAttribBinding:= dglGetProcAddress('glVertexArrayAttribBinding');
+ glVertexArrayAttribFormat:= dglGetProcAddress('glVertexArrayAttribFormat');
+ glVertexArrayAttribIFormat:= dglGetProcAddress('glVertexArrayAttribIFormat');
+ glVertexArrayAttribLFormat:= dglGetProcAddress('glVertexArrayAttribLFormat');
+ glVertexArrayBindingDivisor:= dglGetProcAddress('glVertexArrayBindingDivisor');
+ glGetVertexArrayiv:= dglGetProcAddress('glGetVertexArrayiv');
+ glGetVertexArrayIndexediv:= dglGetProcAddress('glGetVertexArrayIndexediv');
+ glGetVertexArrayIndexed64iv:= dglGetProcAddress('glGetVertexArrayIndexed64iv');
+ glCreateSamplers:= dglGetProcAddress('glCreateSamplers');
+ glCreateProgramPipelines:= dglGetProcAddress('glCreateProgramPipelines');
+ glCreateQueries:= dglGetProcAddress('glCreateQueries');
+ glMemoryBarrierByRegion:= dglGetProcAddress('glMemoryBarrierByRegion');
+ glGetTextureSubImage:= dglGetProcAddress('glGetTextureSubImage');
+ glGetCompressedTextureSubImage:= dglGetProcAddress('glGetCompressedTextureSubImage');
+ glGetGraphicsResetStatus:= dglGetProcAddress('glGetGraphicsResetStatus');
+ glGetnCompressedTexImage:= dglGetProcAddress('glGetnCompressedTexImage');
+ glGetnTexImage:= dglGetProcAddress('glGetnTexImage');
+ glGetnUniformdv:= dglGetProcAddress('glGetnUniformdv');
+ glGetnUniformfv:= dglGetProcAddress('glGetnUniformfv');
+ glGetnUniformiv:= dglGetProcAddress('glGetnUniformiv');
+ glGetnUniformuiv:= dglGetProcAddress('glGetnUniformuiv');
+ glReadnPixels:= dglGetProcAddress('glReadnPixels');
+ glGetnMapdv:= dglGetProcAddress('glGetnMapdv');
+ glGetnMapfv:= dglGetProcAddress('glGetnMapfv');
+ glGetnMapiv:= dglGetProcAddress('glGetnMapiv');
+ glGetnPixelMapfv:= dglGetProcAddress('glGetnPixelMapfv');
+ glGetnPixelMapuiv:= dglGetProcAddress('glGetnPixelMapuiv');
+ glGetnPixelMapusv:= dglGetProcAddress('glGetnPixelMapusv');
+ glGetnPolygonStipple:= dglGetProcAddress('glGetnPolygonStipple');
+ glGetnColorTable:= dglGetProcAddress('glGetnColorTable');
+ glGetnConvolutionFilter:= dglGetProcAddress('glGetnConvolutionFilter');
+ glGetnSeparableFilter:= dglGetProcAddress('glGetnSeparableFilter');
+ glGetnHistogram:= dglGetProcAddress('glGetnHistogram');
+ glGetnMinmax:= dglGetProcAddress('glGetnMinmax');
+ glTextureBarrier:= dglGetProcAddress('glTextureBarrier');
+end;
+
+procedure Read_GL_4_6;
+begin
+ glSpecializeShader := dglGetProcAddress('glSpecializeShader');
+ glMultiDrawArraysIndirectCount := dglGetProcAddress('glMultiDrawArraysIndirectCount');
+ glMultiDrawElementsIndirectCount := dglGetProcAddress('glMultiDrawElementsIndirectCount');
+ glPolygonOffsetClamp := dglGetProcAddress('glPolygonOffsetClamp');
+end;
+
+procedure Read_GL_NV_path_rendering;
+begin
+ glGenPathsNV := dglGetProcAddress('glGenPathsNV');
+ glDeletePathsNV := dglGetProcAddress('glDeletePathsNV');
+ glIsPathNV := dglGetProcAddress('glIsPathNV');
+ glPathCommandsNV := dglGetProcAddress('glPathCommandsNV');
+ glPathCoordsNV := dglGetProcAddress('glPathCoordsNV');
+ glPathSubCommandsNV := dglGetProcAddress('glPathSubCommandsNV');
+ glPathSubCoordsNV := dglGetProcAddress('glPathSubCoordsNV');
+ glPathStringNV := dglGetProcAddress('glPathStringNV');
+ glPathGlyphsNV := dglGetProcAddress('glPathGlyphsNV');
+ glPathGlyphRangeNV := dglGetProcAddress('glPathGlyphRangeNV');
+ glWeightPathsNV := dglGetProcAddress('glWeightPathsNV');
+ glCopyPathNV := dglGetProcAddress('glCopyPathNV');
+ glInterpolatePathsNV := dglGetProcAddress('glInterpolatePathsNV');
+ glTransformPathNV := dglGetProcAddress('glTransformPathNV');
+ glPathParameterivNV := dglGetProcAddress('glPathParameterivNV');
+ glPathParameteriNV := dglGetProcAddress('glPathParameteriNV');
+ glPathParameterfvNV := dglGetProcAddress('glPathParameterfvNV');
+ glPathParameterfNV := dglGetProcAddress('glPathParameterfNV');
+ glPathDashArrayNV := dglGetProcAddress('glPathDashArrayNV');
+ glPathStencilFuncNV := dglGetProcAddress('glPathStencilFuncNV');
+ glPathStencilDepthOffsetNV := dglGetProcAddress('glPathStencilDepthOffsetNV');
+ glStencilFillPathNV := dglGetProcAddress('glStencilFillPathNV');
+ glStencilStrokePathNV := dglGetProcAddress('glStencilStrokePathNV');
+ glStencilFillPathInstancedNV := dglGetProcAddress('glStencilFillPathInstancedNV');
+ glStencilStrokePathInstancedNV := dglGetProcAddress('glStencilStrokePathInstancedNV');
+ glPathCoverDepthFuncNV := dglGetProcAddress('glPathCoverDepthFuncNV');
+ glPathColorGenNV := dglGetProcAddress('glPathColorGenNV');
+ glPathTexGenNV := dglGetProcAddress('glPathTexGenNV');
+ glPathFogGenNV := dglGetProcAddress('glPathFogGenNV');
+ glCoverFillPathNV := dglGetProcAddress('glCoverFillPathNV');
+ glCoverStrokePathNV := dglGetProcAddress('glCoverStrokePathNV');
+ glCoverFillPathInstancedNV := dglGetProcAddress('glCoverFillPathInstancedNV');
+ glCoverStrokePathInstancedNV := dglGetProcAddress('glCoverStrokePathInstancedNV');
+ glGetPathParameterivNV := dglGetProcAddress('glGetPathParameterivNV');
+ glGetPathParameterfvNV := dglGetProcAddress('glGetPathParameterfvNV');
+ glGetPathCommandsNV := dglGetProcAddress('glGetPathCommandsNV');
+ glGetPathCoordsNV := dglGetProcAddress('glGetPathCoordsNV');
+ glGetPathDashArrayNV := dglGetProcAddress('glGetPathDashArrayNV');
+ glGetPathMetricsNV := dglGetProcAddress('glGetPathMetricsNV');
+ glGetPathMetricRangeNV := dglGetProcAddress('glGetPathMetricRangeNV');
+ glGetPathSpacingNV := dglGetProcAddress('glGetPathSpacingNV');
+ glGetPathColorGenivNV := dglGetProcAddress('glGetPathColorGenivNV');
+ glGetPathColorGenfvNV := dglGetProcAddress('glGetPathColorGenfvNV');
+ glGetPathTexGenivNV := dglGetProcAddress('glGetPathTexGenivNV');
+ glGetPathTexGenfvNV := dglGetProcAddress('glGetPathTexGenfvNV');
+ glIsPointInFillPathNV := dglGetProcAddress('glIsPointInFillPathNV');
+ glIsPointInStrokePathNV := dglGetProcAddress('glIsPointInStrokePathNV');
+ glGetPathLengthNV := dglGetProcAddress('glGetPathLengthNV');
+ glPointAlongPathNV := dglGetProcAddress('glPointAlongPathNV');
+end;
+
+procedure Read_GL_AMD_stencil_operation_extended;
+begin
+ glStencilOpValueAMD := dglGetProcAddress('glStencilOpValueAMD');
+end;
+
+procedure Read_GL_NV_bindless_texture;
+begin
+ glGetTextureHandleNV := dglGetProcAddress('glGetTextureHandleNV');
+ glGetTextureSamplerHandleNV := dglGetProcAddress('glGetTextureSamplerHandleNV');
+ glMakeTextureHandleResidentNV := dglGetProcAddress('glMakeTextureHandleResidentNV');
+ glMakeTextureHandleNonResidentNV := dglGetProcAddress('glMakeTextureHandleNonResidentNV');
+ glGetImageHandleNV := dglGetProcAddress('glGetImageHandleNV');
+ glMakeImageHandleResidentNV := dglGetProcAddress('glMakeImageHandleResidentNV');
+ glMakeImageHandleNonResidentNV := dglGetProcAddress('glMakeImageHandleNonResidentNV');
+ glUniformHandleui64NV := dglGetProcAddress('glUniformHandleui64NV');
+ glUniformHandleui64vNV := dglGetProcAddress('glUniformHandleui64vNV');
+ glProgramUniformHandleui64NV := dglGetProcAddress('glProgramUniformHandleui64NV');
+ glProgramUniformHandleui64vNV := dglGetProcAddress('glProgramUniformHandleui64vNV');
+ glIsTextureHandleResidentNV := dglGetProcAddress('glIsTextureHandleResidentNV');
+ glIsImageHandleResidentNV := dglGetProcAddress('glIsImageHandleResidentNV');
+end;
+
+procedure Read_GL_ARB_bindless_texture;
+begin
+ glGetTextureHandleARB := dglGetProcAddress('glGetTextureHandleARB');
+ glGetTextureSamplerHandleARB := dglGetProcAddress('glGetTextureSamplerHandleARB');
+ glMakeTextureHandleResidentARB := dglGetProcAddress('glMakeTextureHandleResidentARB');
+ glMakeTextureHandleNonResidentARB := dglGetProcAddress('glMakeTextureHandleNonResidentARB');
+ glGetImageHandleARB := dglGetProcAddress('glGetImageHandleARB');
+ glMakeImageHandleResidentARB := dglGetProcAddress('glMakeImageHandleResidentARB');
+ glMakeImageHandleNonResidentARB := dglGetProcAddress('glMakeImageHandleNonResidentARB');
+ glUniformHandleui64ARB := dglGetProcAddress('glUniformHandleui64ARB');
+ glUniformHandleui64vARB := dglGetProcAddress('glUniformHandleui64vARB');
+ glProgramUniformHandleui64ARB := dglGetProcAddress('glProgramUniformHandleui64ARB');
+ glProgramUniformHandleui64vARB := dglGetProcAddress('glProgramUniformHandleui64vARB');
+ glIsTextureHandleResidentARB := dglGetProcAddress('glIsTextureHandleResidentARB');
+ glIsImageHandleResidentARB := dglGetProcAddress('glIsImageHandleResidentARB');
+ glVertexAttribL1ui64ARB := dglGetProcAddress('glVertexAttribL1ui64ARB');
+ glVertexAttribL1ui64vARB := dglGetProcAddress('glVertexAttribL1ui64vARB');
+ glGetVertexAttribLui64vARB := dglGetProcAddress('glGetVertexAttribLui64vARB');
+end;
+
+procedure Read_GL_ARB_cl_event;
+begin
+ glCreateSyncFromCLeventARB := dglGetProcAddress('glCreateSyncFromCLeventARB');
+end;
+
+procedure Read_GL_ARB_compute_variable_group_size;
+begin
+ glDispatchComputeGroupSizeARB := dglGetProcAddress('glDispatchComputeGroupSizeARB');
+end;
+
+procedure Read_GL_ARB_debug_output;
+begin
+ glDebugMessageControlARB := dglGetProcAddress('glDebugMessageControlARB');
+ glDebugMessageInsertARB := dglGetProcAddress('glDebugMessageInsertARB');
+ glDebugMessageCallbackARB := dglGetProcAddress('glDebugMessageCallbackARB');
+ glGetDebugMessageLogARB := dglGetProcAddress('glGetDebugMessageLogARB');
+end;
+
+procedure Read_GL_ARB_robustness;
+begin
+ glGetGraphicsResetStatusARB := dglGetProcAddress('glGetGraphicsResetStatusARB');
+ glGetnMapdvARB := dglGetProcAddress('glGetnMapdvARB');
+ glGetnMapfvARB := dglGetProcAddress('glGetnMapfvARB');
+ glGetnMapivARB := dglGetProcAddress('glGetnMapivARB');
+ glGetnPixelMapfvARB := dglGetProcAddress('glGetnPixelMapfvARB');
+ glGetnPixelMapuivARB := dglGetProcAddress('glGetnPixelMapuivARB');
+ glGetnPixelMapusvARB := dglGetProcAddress('glGetnPixelMapusvARB');
+ glGetnPolygonStippleARB := dglGetProcAddress('glGetnPolygonStippleARB');
+ glGetnColorTableARB := dglGetProcAddress('glGetnColorTableARB');
+ glGetnConvolutionFilterARB := dglGetProcAddress('glGetnConvolutionFilterARB');
+ glGetnSeparableFilterARB := dglGetProcAddress('glGetnSeparableFilterARB');
+ glGetnHistogramARB := dglGetProcAddress('glGetnHistogramARB');
+ glGetnMinmaxARB := dglGetProcAddress('glGetnMinmaxARB');
+ glGetnTexImageARB := dglGetProcAddress('glGetnTexImageARB');
+ glReadnPixelsARB := dglGetProcAddress('glReadnPixelsARB');
+ glGetnCompressedTexImageARB := dglGetProcAddress('glGetnCompressedTexImageARB');
+ glGetnUniformfvARB := dglGetProcAddress('glGetnUniformfvARB');
+ glGetnUniformivARB := dglGetProcAddress('glGetnUniformivARB');
+ glGetnUniformuivARB := dglGetProcAddress('glGetnUniformuivARB');
+ glGetnUniformdvARB := dglGetProcAddress('glGetnUniformdvARB');
+end;
+
+procedure Read_GL_ATI_draw_buffers;
+begin
+ glDrawBuffersATI := dglGetProcAddress('glDrawBuffersATI');
+end;
+
+procedure Read_GL_ATI_element_array;
+begin
+ glElementPointerATI := dglGetProcAddress('glElementPointerATI');
+ glDrawElementArrayATI := dglGetProcAddress('glDrawElementArrayATI');
+ glDrawRangeElementArrayATI := dglGetProcAddress('glDrawRangeElementArrayATI');
+end;
+
+procedure Read_GL_ATI_envmap_bumpmap;
+begin
+ glTexBumpParameterivATI := dglGetProcAddress('glTexBumpParameterivATI');
+ glTexBumpParameterfvATI := dglGetProcAddress('glTexBumpParameterfvATI');
+ glGetTexBumpParameterivATI := dglGetProcAddress('glGetTexBumpParameterivATI');
+ glGetTexBumpParameterfvATI := dglGetProcAddress('glGetTexBumpParameterfvATI');
+end;
+
+procedure Read_GL_ATI_fragment_shader;
+begin
+ glGenFragmentShadersATI := dglGetProcAddress('glGenFragmentShadersATI');
+ glBindFragmentShaderATI := dglGetProcAddress('glBindFragmentShaderATI');
+ glDeleteFragmentShaderATI := dglGetProcAddress('glDeleteFragmentShaderATI');
+ glBeginFragmentShaderATI := dglGetProcAddress('glBeginFragmentShaderATI');
+ glEndFragmentShaderATI := dglGetProcAddress('glEndFragmentShaderATI');
+ glPassTexCoordATI := dglGetProcAddress('glPassTexCoordATI');
+ glSampleMapATI := dglGetProcAddress('glSampleMapATI');
+ glColorFragmentOp1ATI := dglGetProcAddress('glColorFragmentOp1ATI');
+ glColorFragmentOp2ATI := dglGetProcAddress('glColorFragmentOp2ATI');
+ glColorFragmentOp3ATI := dglGetProcAddress('glColorFragmentOp3ATI');
+ glAlphaFragmentOp1ATI := dglGetProcAddress('glAlphaFragmentOp1ATI');
+ glAlphaFragmentOp2ATI := dglGetProcAddress('glAlphaFragmentOp2ATI');
+ glAlphaFragmentOp3ATI := dglGetProcAddress('glAlphaFragmentOp3ATI');
+ glSetFragmentShaderConstantATI := dglGetProcAddress('glSetFragmentShaderConstantATI');
+end;
+
+procedure Read_GL_ATI_map_object_buffer;
+begin
+ glMapObjectBufferATI := dglGetProcAddress('glMapObjectBufferATI');
+ glUnmapObjectBufferATI := dglGetProcAddress('glUnmapObjectBufferATI');
+end;
+
+procedure Read_GL_ATI_pn_triangles;
+begin
+ glPNTrianglesiATI := dglGetProcAddress('glPNTrianglesiATI');
+ glPNTrianglesfATI := dglGetProcAddress('glPNTrianglesfATI');
+end;
+
+procedure Read_GL_ATI_separate_stencil;
+begin
+ glStencilOpSeparateATI := dglGetProcAddress('glStencilOpSeparateATI');
+ glStencilFuncSeparateATI := dglGetProcAddress('glStencilFuncSeparateATI');
+end;
+
+procedure Read_GL_ATI_vertex_array_object;
+begin
+ glNewObjectBufferATI := dglGetProcAddress('glNewObjectBufferATI');
+ glIsObjectBufferATI := dglGetProcAddress('glIsObjectBufferATI');
+ glUpdateObjectBufferATI := dglGetProcAddress('glUpdateObjectBufferATI');
+ glGetObjectBufferfvATI := dglGetProcAddress('glGetObjectBufferfvATI');
+ glGetObjectBufferivATI := dglGetProcAddress('glGetObjectBufferivATI');
+ glFreeObjectBufferATI := dglGetProcAddress('glFreeObjectBufferATI');
+ glArrayObjectATI := dglGetProcAddress('glArrayObjectATI');
+ glGetArrayObjectfvATI := dglGetProcAddress('glGetArrayObjectfvATI');
+ glGetArrayObjectivATI := dglGetProcAddress('glGetArrayObjectivATI');
+ glVariantArrayObjectATI := dglGetProcAddress('glVariantArrayObjectATI');
+ glGetVariantArrayObjectfvATI := dglGetProcAddress('glGetVariantArrayObjectfvATI');
+ glGetVariantArrayObjectivATI := dglGetProcAddress('glGetVariantArrayObjectivATI');
+
+end;
+
+procedure Read_GL_ATI_vertex_attrib_array_object;
+begin
+ glVertexAttribArrayObjectATI := dglGetProcAddress('glVertexAttribArrayObjectATI');
+ glGetVertexAttribArrayObjectfvATI := dglGetProcAddress('glGetVertexAttribArrayObjectfvATI');
+ glGetVertexAttribArrayObjectivATI := dglGetProcAddress('glGetVertexAttribArrayObjectivATI');
+end;
+
+procedure Read_GL_ATI_vertex_streams;
+begin
+ glVertexStream1sATI := dglGetProcAddress('glVertexStream1sATI');
+ glVertexStream1svATI := dglGetProcAddress('glVertexStream1svATI');
+ glVertexStream1iATI := dglGetProcAddress('glVertexStream1iATI');
+ glVertexStream1ivATI := dglGetProcAddress('glVertexStream1ivATI');
+ glVertexStream1fATI := dglGetProcAddress('glVertexStream1fATI');
+ glVertexStream1fvATI := dglGetProcAddress('glVertexStream1fvATI');
+ glVertexStream1dATI := dglGetProcAddress('glVertexStream1dATI');
+ glVertexStream1dvATI := dglGetProcAddress('glVertexStream1dvATI');
+ glVertexStream2sATI := dglGetProcAddress('glVertexStream2sATI');
+ glVertexStream2svATI := dglGetProcAddress('glVertexStream2svATI');
+ glVertexStream2iATI := dglGetProcAddress('glVertexStream2iATI');
+ glVertexStream2ivATI := dglGetProcAddress('glVertexStream2ivATI');
+ glVertexStream2fATI := dglGetProcAddress('glVertexStream2fATI');
+ glVertexStream2fvATI := dglGetProcAddress('glVertexStream2fvATI');
+ glVertexStream2dATI := dglGetProcAddress('glVertexStream2dATI');
+ glVertexStream2dvATI := dglGetProcAddress('glVertexStream2dvATI');
+ glVertexStream3sATI := dglGetProcAddress('glVertexStream3sATI');
+ glVertexStream3svATI := dglGetProcAddress('glVertexStream3svATI');
+ glVertexStream3iATI := dglGetProcAddress('glVertexStream3iATI');
+ glVertexStream3ivATI := dglGetProcAddress('glVertexStream3ivATI');
+ glVertexStream3fATI := dglGetProcAddress('glVertexStream3fATI');
+ glVertexStream3fvATI := dglGetProcAddress('glVertexStream3fvATI');
+ glVertexStream3dATI := dglGetProcAddress('glVertexStream3dATI');
+ glVertexStream3dvATI := dglGetProcAddress('glVertexStream3dvATI');
+ glVertexStream4sATI := dglGetProcAddress('glVertexStream4sATI');
+ glVertexStream4svATI := dglGetProcAddress('glVertexStream4svATI');
+ glVertexStream4iATI := dglGetProcAddress('glVertexStream4iATI');
+ glVertexStream4ivATI := dglGetProcAddress('glVertexStream4ivATI');
+ glVertexStream4fATI := dglGetProcAddress('glVertexStream4fATI');
+ glVertexStream4fvATI := dglGetProcAddress('glVertexStream4fvATI');
+ glVertexStream4dATI := dglGetProcAddress('glVertexStream4dATI');
+ glVertexStream4dvATI := dglGetProcAddress('glVertexStream4dvATI');
+ glNormalStream3bATI := dglGetProcAddress('glNormalStream3bATI');
+ glNormalStream3bvATI := dglGetProcAddress('glNormalStream3bvATI');
+ glNormalStream3sATI := dglGetProcAddress('glNormalStream3sATI');
+ glNormalStream3svATI := dglGetProcAddress('glNormalStream3svATI');
+ glNormalStream3iATI := dglGetProcAddress('glNormalStream3iATI');
+ glNormalStream3ivATI := dglGetProcAddress('glNormalStream3ivATI');
+ glNormalStream3fATI := dglGetProcAddress('glNormalStream3fATI');
+ glNormalStream3fvATI := dglGetProcAddress('glNormalStream3fvATI');
+ glNormalStream3dATI := dglGetProcAddress('glNormalStream3dATI');
+ glNormalStream3dvATI := dglGetProcAddress('glNormalStream3dvATI');
+ glClientActiveVertexStreamATI := dglGetProcAddress('glClientActiveVertexStreamATI');
+ glVertexBlendEnviATI := dglGetProcAddress('glVertexBlendEnviATI');
+ glVertexBlendEnvfATI := dglGetProcAddress('glVertexBlendEnvfATI');
+end;
+
+procedure Read_GL_AMD_performance_monitor;
+begin
+ glGetPerfMonitorGroupsAMD := dglGetProcAddress('glGetPerfMonitorGroupsAMD');
+ glGetPerfMonitorCountersAMD := dglGetProcAddress('glGetPerfMonitorCountersAMD');
+ glGetPerfMonitorGroupStringAMD := dglGetProcAddress('glGetPerfMonitorGroupStringAMD');
+ glGetPerfMonitorCounterStringAMD := dglGetProcAddress('glGetPerfMonitorCounterStringAMD');
+ glGetPerfMonitorCounterInfoAMD := dglGetProcAddress('glGetPerfMonitorCounterInfoAMD');
+ glGenPerfMonitorsAMD := dglGetProcAddress('glGenPerfMonitorsAMD');
+ glDeletePerfMonitorsAMD := dglGetProcAddress('glDeletePerfMonitorsAMD');
+ glSelectPerfMonitorCountersAMD := dglGetProcAddress('glSelectPerfMonitorCountersAMD');
+ glBeginPerfMonitorAMD := dglGetProcAddress('glBeginPerfMonitorAMD');
+ glEndPerfMonitorAMD := dglGetProcAddress('glEndPerfMonitorAMD');
+ glGetPerfMonitorCounterDataAMD := dglGetProcAddress('glGetPerfMonitorCounterDataAMD');
+end;
+
+procedure Read_GL_AMD_vertex_shader_tesselator;
+begin
+ glTessellationFactorAMD := dglGetProcAddress('glTessellationFactorAMD');
+ glTessellationModeAMD := dglGetProcAddress('glTessellationModeAMD');
+end;
+
+procedure Read_GL_AMD_draw_buffers_blend;
+begin
+ glBlendFuncIndexedAMD := dglGetProcAddress('glBlendFuncIndexedAMD');
+ glBlendFuncSeparateIndexedAMD := dglGetProcAddress('glBlendFuncSeparateIndexedAMD');
+ glBlendEquationIndexedAMD := dglGetProcAddress('glBlendEquationIndexedAMD');
+ glBlendEquationSeparateIndexedAMD := dglGetProcAddress('glBlendEquationSeparateIndexedAMD');
+end;
+
+procedure Read_GL_AMD_name_gen_delete;
+begin
+ glGenNamesAMD := dglGetProcAddress('glGenNamesAMD');
+ glDeleteNamesAMD := dglGetProcAddress('glDeleteNamesAMD');
+ glIsNameAMD := dglGetProcAddress('glIsNameAMD');
+end;
+
+procedure Read_GL_AMD_debug_output;
+begin
+ glDebugMessageEnableAMD := dglGetProcAddress('glDebugMessageEnableAMD');
+ glDebugMessageInsertAMD := dglGetProcAddress('glDebugMessageInsertAMD');
+ glDebugMessageCallbackAMD := dglGetProcAddress('glDebugMessageCallbackAMD');
+ glGetDebugMessageLogAMD := dglGetProcAddress('glGetDebugMessageLogAMD');
+end;
+
+procedure Read_GL_EXT_blend_color;
+begin
+ glBlendColorEXT := dglGetProcAddress('glBlendColorEXT');
+end;
+
+procedure Read_GL_EXT_blend_func_separate;
+begin
+ glBlendFuncSeparateEXT := dglGetProcAddress('glBlendFuncSeparateEXT');
+end;
+
+procedure Read_GL_EXT_blend_minmax;
+begin
+ glBlendEquationEXT := dglGetProcAddress('glBlendEquationEXT');
+end;
+
+procedure Read_GL_EXT_color_subtable;
+begin
+ glColorSubTableEXT := dglGetProcAddress('glColorSubTableEXT');
+ glCopyColorSubTableEXT := dglGetProcAddress('glCopyColorSubTableEXT');
+end;
+
+procedure Read_GL_EXT_compiled_vertex_array;
+begin
+ glLockArraysEXT := dglGetProcAddress('glLockArraysEXT');
+ glUnlockArraysEXT := dglGetProcAddress('glUnlockArraysEXT');
+end;
+
+procedure Read_GL_EXT_convolution;
+begin
+ glConvolutionFilter1DEXT := dglGetProcAddress('glConvolutionFilter1DEXT');
+ glConvolutionFilter2DEXT := dglGetProcAddress('glConvolutionFilter2DEXT');
+ glConvolutionParameterfEXT := dglGetProcAddress('glConvolutionParameterfEXT');
+ glConvolutionParameterfvEXT := dglGetProcAddress('glConvolutionParameterfvEXT');
+ glConvolutionParameteriEXT := dglGetProcAddress('glConvolutionParameteriEXT');
+ glConvolutionParameterivEXT := dglGetProcAddress('glConvolutionParameterivEXT');
+ glCopyConvolutionFilter1DEXT := dglGetProcAddress('glCopyConvolutionFilter1DEXT');
+ glCopyConvolutionFilter2DEXT := dglGetProcAddress('glCopyConvolutionFilter2DEXT');
+ glGetConvolutionFilterEXT := dglGetProcAddress('glGetConvolutionFilterEXT');
+ glGetConvolutionParameterfvEXT := dglGetProcAddress('glGetConvolutionParameterfvEXT');
+ glGetConvolutionParameterivEXT := dglGetProcAddress('glGetConvolutionParameterivEXT');
+ glGetSeparableFilterEXT := dglGetProcAddress('glGetSeparableFilterEXT');
+ glSeparableFilter2DEXT := dglGetProcAddress('glSeparableFilter2DEXT');
+end;
+
+procedure Read_GL_EXT_coordinate_frame;
+begin
+ glTangent3bEXT := dglGetProcAddress('glTangent3bEXT');
+ glTangent3bvEXT := dglGetProcAddress('glTangent3bvEXT');
+ glTangent3dEXT := dglGetProcAddress('glTangent3dEXT');
+ glTangent3dvEXT := dglGetProcAddress('glTangent3dvEXT');
+ glTangent3fEXT := dglGetProcAddress('glTangent3fEXT');
+ glTangent3fvEXT := dglGetProcAddress('glTangent3fvEXT');
+ glTangent3iEXT := dglGetProcAddress('glTangent3iEXT');
+ glTangent3ivEXT := dglGetProcAddress('glTangent3ivEXT');
+ glTangent3sEXT := dglGetProcAddress('glTangent3sEXT');
+ glTangent3svEXT := dglGetProcAddress('glTangent3svEXT');
+ glBinormal3bEXT := dglGetProcAddress('glBinormal3bEXT');
+ glBinormal3bvEXT := dglGetProcAddress('glBinormal3bvEXT');
+ glBinormal3dEXT := dglGetProcAddress('glBinormal3dEXT');
+ glBinormal3dvEXT := dglGetProcAddress('glBinormal3dvEXT');
+ glBinormal3fEXT := dglGetProcAddress('glBinormal3fEXT');
+ glBinormal3fvEXT := dglGetProcAddress('glBinormal3fvEXT');
+ glBinormal3iEXT := dglGetProcAddress('glBinormal3iEXT');
+ glBinormal3ivEXT := dglGetProcAddress('glBinormal3ivEXT');
+ glBinormal3sEXT := dglGetProcAddress('glBinormal3sEXT');
+ glBinormal3svEXT := dglGetProcAddress('glBinormal3svEXT');
+ glTangentPointerEXT := dglGetProcAddress('glTangentPointerEXT');
+ glBinormalPointerEXT := dglGetProcAddress('glBinormalPointerEXT');
+end;
+
+procedure Read_GL_EXT_copy_texture;
+begin
+ glCopyTexImage1DEXT := dglGetProcAddress('glCopyTexImage1DEXT');
+ glCopyTexImage2DEXT := dglGetProcAddress('glCopyTexImage2DEXT');
+ glCopyTexSubImage1DEXT := dglGetProcAddress('glCopyTexSubImage1DEXT');
+ glCopyTexSubImage2DEXT := dglGetProcAddress('glCopyTexSubImage2DEXT');
+ glCopyTexSubImage3DEXT := dglGetProcAddress('glCopyTexSubImage3DEXT');
+end;
+
+procedure Read_GL_EXT_cull_vertex;
+begin
+ glCullParameterdvEXT := dglGetProcAddress('glCullParameterdvEXT');
+ glCullParameterfvEXT := dglGetProcAddress('glCullParameterfvEXT');
+end;
+
+procedure Read_GL_EXT_draw_range_elements;
+begin
+ glDrawRangeElementsEXT := dglGetProcAddress('glDrawRangeElementsEXT');
+end;
+
+procedure Read_GL_EXT_fog_coord;
+begin
+ glFogCoordfEXT := dglGetProcAddress('glFogCoordfEXT');
+ glFogCoordfvEXT := dglGetProcAddress('glFogCoordfvEXT');
+ glFogCoorddEXT := dglGetProcAddress('glFogCoorddEXT');
+ glFogCoorddvEXT := dglGetProcAddress('glFogCoorddvEXT');
+ glFogCoordPointerEXT := dglGetProcAddress('glFogCoordPointerEXT');
+end;
+
+procedure Read_GL_EXT_framebuffer_object;
+begin
+ glIsRenderbufferEXT := dglGetProcAddress('glIsRenderbufferEXT');
+ glBindRenderbufferEXT := dglGetProcAddress('glBindRenderbufferEXT');
+ glDeleteRenderbuffersEXT := dglGetProcAddress('glDeleteRenderbuffersEXT');
+ glGenRenderbuffersEXT := dglGetProcAddress('glGenRenderbuffersEXT');
+ glRenderbufferStorageEXT := dglGetProcAddress('glRenderbufferStorageEXT');
+ glGetRenderbufferParameterivEXT := dglGetProcAddress('glGetRenderbufferParameterivEXT');
+ glIsFramebufferEXT := dglGetProcAddress('glIsFramebufferEXT');
+ glBindFramebufferEXT := dglGetProcAddress('glBindFramebufferEXT');
+ glDeleteFramebuffersEXT := dglGetProcAddress('glDeleteFramebuffersEXT');
+ glGenFramebuffersEXT := dglGetProcAddress('glGenFramebuffersEXT');
+ glCheckFramebufferStatusEXT := dglGetProcAddress('glCheckFramebufferStatusEXT');
+ glFramebufferTexture1DEXT := dglGetProcAddress('glFramebufferTexture1DEXT');
+ glFramebufferTexture2DEXT := dglGetProcAddress('glFramebufferTexture2DEXT');
+ glFramebufferTexture3DEXT := dglGetProcAddress('glFramebufferTexture3DEXT');
+ glFramebufferRenderbufferEXT := dglGetProcAddress('glFramebufferRenderbufferEXT');
+ glGetFramebufferAttachmentParameterivEXT := dglGetProcAddress('glGetFramebufferAttachmentParameterivEXT');
+ glGenerateMipmapEXT := dglGetProcAddress('glGenerateMipmapEXT');
+end;
+
+procedure Read_GL_EXT_histogram;
+begin
+ glGetHistogramEXT := dglGetProcAddress('glGetHistogramEXT');
+ glGetHistogramParameterfvEXT := dglGetProcAddress('glGetHistogramParameterfvEXT');
+ glGetHistogramParameterivEXT := dglGetProcAddress('glGetHistogramParameterivEXT');
+ glGetMinmaxEXT := dglGetProcAddress('glGetMinmaxEXT');
+ glGetMinmaxParameterfvEXT := dglGetProcAddress('glGetMinmaxParameterfvEXT');
+ glGetMinmaxParameterivEXT := dglGetProcAddress('glGetMinmaxParameterivEXT');
+ glHistogramEXT := dglGetProcAddress('glHistogramEXT');
+ glMinmaxEXT := dglGetProcAddress('glMinmaxEXT');
+ glResetHistogramEXT := dglGetProcAddress('glResetHistogramEXT');
+ glResetMinmaxEXT := dglGetProcAddress('glResetMinmaxEXT');
+end;
+
+procedure Read_GL_EXT_index_func;
+begin
+ glIndexFuncEXT := dglGetProcAddress('glIndexFuncEXT');
+end;
+
+procedure Read_GL_EXT_index_material;
+begin
+ glIndexMaterialEXT := dglGetProcAddress('glIndexMaterialEXT');
+end;
+
+procedure Read_GL_EXT_light_texture;
+begin
+ glApplyTextureEXT := dglGetProcAddress('glApplyTextureEXT');
+ glTextureLightEXT := dglGetProcAddress('glTextureLightEXT');
+ glTextureMaterialEXT := dglGetProcAddress('glTextureMaterialEXT');
+end;
+
+procedure Read_GL_EXT_multi_draw_arrays;
+begin
+ glMultiDrawArraysEXT := dglGetProcAddress('glMultiDrawArraysEXT');
+ glMultiDrawElementsEXT := dglGetProcAddress('glMultiDrawElementsEXT');
+end;
+
+procedure Read_GL_EXT_multisample;
+begin
+ glSampleMaskEXT := dglGetProcAddress('glSampleMaskEXT');
+ glSamplePatternEXT := dglGetProcAddress('glSamplePatternEXT');
+end;
+
+procedure Read_GL_EXT_paletted_texture;
+begin
+ glColorTableEXT := dglGetProcAddress('glColorTableEXT');
+ glGetColorTableEXT := dglGetProcAddress('glGetColorTableEXT');
+ glGetColorTableParameterivEXT := dglGetProcAddress('glGetColorTableParameterivEXT');
+ glGetColorTableParameterfvEXT := dglGetProcAddress('glGetColorTableParameterfvEXT');
+end;
+
+procedure Read_GL_EXT_pixel_transform;
+begin
+ glPixelTransformParameteriEXT := dglGetProcAddress('glPixelTransformParameteriEXT');
+ glPixelTransformParameterfEXT := dglGetProcAddress('glPixelTransformParameterfEXT');
+ glPixelTransformParameterivEXT := dglGetProcAddress('glPixelTransformParameterivEXT');
+ glPixelTransformParameterfvEXT := dglGetProcAddress('glPixelTransformParameterfvEXT');
+end;
+
+procedure Read_GL_EXT_point_parameters;
+begin
+ glPointParameterfEXT := dglGetProcAddress('glPointParameterfEXT');
+ glPointParameterfvEXT := dglGetProcAddress('glPointParameterfvEXT');
+end;
+
+procedure Read_GL_EXT_polygon_offset;
+begin
+ glPolygonOffsetEXT := dglGetProcAddress('glPolygonOffsetEXT');
+end;
+
+procedure Read_GL_EXT_secondary_color;
+begin
+ glSecondaryColor3bEXT := dglGetProcAddress('glSecondaryColor3bEXT');
+ glSecondaryColor3bvEXT := dglGetProcAddress('glSecondaryColor3bvEXT');
+ glSecondaryColor3dEXT := dglGetProcAddress('glSecondaryColor3dEXT');
+ glSecondaryColor3dvEXT := dglGetProcAddress('glSecondaryColor3dvEXT');
+ glSecondaryColor3fEXT := dglGetProcAddress('glSecondaryColor3fEXT');
+ glSecondaryColor3fvEXT := dglGetProcAddress('glSecondaryColor3fvEXT');
+ glSecondaryColor3iEXT := dglGetProcAddress('glSecondaryColor3iEXT');
+ glSecondaryColor3ivEXT := dglGetProcAddress('glSecondaryColor3ivEXT');
+ glSecondaryColor3sEXT := dglGetProcAddress('glSecondaryColor3sEXT');
+ glSecondaryColor3svEXT := dglGetProcAddress('glSecondaryColor3svEXT');
+ glSecondaryColor3ubEXT := dglGetProcAddress('glSecondaryColor3ubEXT');
+ glSecondaryColor3ubvEXT := dglGetProcAddress('glSecondaryColor3ubvEXT');
+ glSecondaryColor3uiEXT := dglGetProcAddress('glSecondaryColor3uiEXT');
+ glSecondaryColor3uivEXT := dglGetProcAddress('glSecondaryColor3uivEXT');
+ glSecondaryColor3usEXT := dglGetProcAddress('glSecondaryColor3usEXT');
+ glSecondaryColor3usvEXT := dglGetProcAddress('glSecondaryColor3usvEXT');
+ glSecondaryColorPointerEXT := dglGetProcAddress('glSecondaryColorPointerEXT');
+end;
+
+procedure Read_GL_EXT_stencil_two_side;
+begin
+ glActiveStencilFaceEXT := dglGetProcAddress('glActiveStencilFaceEXT');
+end;
+
+procedure Read_GL_EXT_subtexture;
+begin
+ glTexSubImage1DEXT := dglGetProcAddress('glTexSubImage1DEXT');
+ glTexSubImage2DEXT := dglGetProcAddress('glTexSubImage2DEXT');
+end;
+
+procedure Read_GL_EXT_texture3D;
+begin
+ glTexImage3DEXT := dglGetProcAddress('glTexImage3DEXT');
+ glTexSubImage3DEXT := dglGetProcAddress('glTexSubImage3DEXT');
+end;
+
+procedure Read_GL_EXT_texture_object;
+begin
+ glAreTexturesResidentEXT := dglGetProcAddress('glAreTexturesResidentEXT');
+ glBindTextureEXT := dglGetProcAddress('glBindTextureEXT');
+ glDeleteTexturesEXT := dglGetProcAddress('glDeleteTexturesEXT');
+ glGenTexturesEXT := dglGetProcAddress('glGenTexturesEXT');
+ glIsTextureEXT := dglGetProcAddress('glIsTextureEXT');
+ glPrioritizeTexturesEXT := dglGetProcAddress('glPrioritizeTexturesEXT');
+end;
+
+procedure Read_GL_EXT_texture_perturb_normal;
+begin
+ glTextureNormalEXT := dglGetProcAddress('glTextureNormalEXT');
+end;
+
+procedure Read_GL_EXT_vertex_array;
+begin
+ glArrayElementEXT := dglGetProcAddress('glArrayElementEXT');
+ glColorPointerEXT := dglGetProcAddress('glColorPointerEXT');
+ glDrawArraysEXT := dglGetProcAddress('glDrawArraysEXT');
+ glEdgeFlagPointerEXT := dglGetProcAddress('glEdgeFlagPointerEXT');
+ glGetPointervEXT := dglGetProcAddress('glGetPointervEXT');
+ glIndexPointerEXT := dglGetProcAddress('glIndexPointerEXT');
+ glNormalPointerEXT := dglGetProcAddress('glNormalPointerEXT');
+ glTexCoordPointerEXT := dglGetProcAddress('glTexCoordPointerEXT');
+ glVertexPointerEXT := dglGetProcAddress('glVertexPointerEXT');
+end;
+
+procedure Read_GL_EXT_vertex_shader;
+begin
+ glBeginVertexShaderEXT := dglGetProcAddress('glBeginVertexShaderEXT');
+ glEndVertexShaderEXT := dglGetProcAddress('glEndVertexShaderEXT');
+ glBindVertexShaderEXT := dglGetProcAddress('glBindVertexShaderEXT');
+ glGenVertexShadersEXT := dglGetProcAddress('glGenVertexShadersEXT');
+ glDeleteVertexShaderEXT := dglGetProcAddress('glDeleteVertexShaderEXT');
+ glShaderOp1EXT := dglGetProcAddress('glShaderOp1EXT');
+ glShaderOp2EXT := dglGetProcAddress('glShaderOp2EXT');
+ glShaderOp3EXT := dglGetProcAddress('glShaderOp3EXT');
+ glSwizzleEXT := dglGetProcAddress('glSwizzleEXT');
+ glWriteMaskEXT := dglGetProcAddress('glWriteMaskEXT');
+ glInsertComponentEXT := dglGetProcAddress('glInsertComponentEXT');
+ glExtractComponentEXT := dglGetProcAddress('glExtractComponentEXT');
+ glGenSymbolsEXT := dglGetProcAddress('glGenSymbolsEXT');
+ glSetInvariantEXT := dglGetProcAddress('glSetInvariantEXT');
+ glSetLocalConstantEXT := dglGetProcAddress('glSetLocalConstantEXT');
+ glVariantbvEXT := dglGetProcAddress('glVariantbvEXT');
+ glVariantsvEXT := dglGetProcAddress('glVariantsvEXT');
+ glVariantivEXT := dglGetProcAddress('glVariantivEXT');
+ glVariantfvEXT := dglGetProcAddress('glVariantfvEXT');
+ glVariantdvEXT := dglGetProcAddress('glVariantdvEXT');
+ glVariantubvEXT := dglGetProcAddress('glVariantubvEXT');
+ glVariantusvEXT := dglGetProcAddress('glVariantusvEXT');
+ glVariantuivEXT := dglGetProcAddress('glVariantuivEXT');
+ glVariantPointerEXT := dglGetProcAddress('glVariantPointerEXT');
+ glEnableVariantClientStateEXT := dglGetProcAddress('glEnableVariantClientStateEXT');
+ glDisableVariantClientStateEXT := dglGetProcAddress('glDisableVariantClientStateEXT');
+ glBindLightParameterEXT := dglGetProcAddress('glBindLightParameterEXT');
+ glBindMaterialParameterEXT := dglGetProcAddress('glBindMaterialParameterEXT');
+ glBindTexGenParameterEXT := dglGetProcAddress('glBindTexGenParameterEXT');
+ glBindTextureUnitParameterEXT := dglGetProcAddress('glBindTextureUnitParameterEXT');
+ glBindParameterEXT := dglGetProcAddress('glBindParameterEXT');
+ glIsVariantEnabledEXT := dglGetProcAddress('glIsVariantEnabledEXT');
+ glGetVariantBooleanvEXT := dglGetProcAddress('glGetVariantBooleanvEXT');
+ glGetVariantIntegervEXT := dglGetProcAddress('glGetVariantIntegervEXT');
+ glGetVariantFloatvEXT := dglGetProcAddress('glGetVariantFloatvEXT');
+ glGetVariantPointervEXT := dglGetProcAddress('glGetVariantPointervEXT');
+ glGetInvariantBooleanvEXT := dglGetProcAddress('glGetInvariantBooleanvEXT');
+ glGetInvariantIntegervEXT := dglGetProcAddress('glGetInvariantIntegervEXT');
+ glGetInvariantFloatvEXT := dglGetProcAddress('glGetInvariantFloatvEXT');
+ glGetLocalConstantBooleanvEXT := dglGetProcAddress('glGetLocalConstantBooleanvEXT');
+ glGetLocalConstantIntegervEXT := dglGetProcAddress('glGetLocalConstantIntegervEXT');
+ glGetLocalConstantFloatvEXT := dglGetProcAddress('glGetLocalConstantFloatvEXT');
+end;
+
+procedure Read_GL_EXT_vertex_weighting;
+begin
+ glVertexWeightfEXT := dglGetProcAddress('glVertexWeightfEXT');
+ glVertexWeightfvEXT := dglGetProcAddress('glVertexWeightfvEXT');
+ glVertexWeightPointerEXT := dglGetProcAddress('glVertexWeightPointerEXT');
+end;
+
+procedure Read_GL_EXT_depth_bounds_test;
+begin
+ glImageTransformParameteriHP := dglGetProcAddress('glImageTransformParameteriHP');
+ glDepthBoundsEXT := dglGetProcAddress('glDepthBoundsEXT');
+end;
+
+procedure Read_GL_EXT_blend_equation_separate;
+begin
+ glBlendEquationSeparateEXT := dglGetProcAddress('glBlendEquationSeparateEXT');
+end;
+
+procedure Read_GL_EXT_stencil_clear_tag;
+begin
+ glStencilClearTagEXT := dglGetProcAddress('glStencilClearTagEXT');
+end;
+
+procedure Read_GL_EXT_framebuffer_blit;
+begin
+ glBlitFramebufferEXT := dglGetProcAddress('glBlitFramebufferEXT');
+end;
+
+procedure Read_GL_EXT_framebuffer_multisample;
+begin
+ glRenderbufferStorageMultisampleEXT := dglGetProcAddress('glRenderbufferStorageMultisampleEXT');
+end;
+
+procedure Read_GL_EXT_timer_query;
+begin
+ glGetQueryObjecti64vEXT := dglGetProcAddress('glGetQueryObjecti64vEXT');
+ glGetQueryObjectui64vEXT := dglGetProcAddress('glGetQueryObjectui64vEXT');
+end;
+
+procedure Read_GL_EXT_gpu_program_parameters;
+begin
+ glProgramEnvParameters4fvEXT := dglGetProcAddress('glProgramEnvParameters4fvEXT');
+ glProgramLocalParameters4fvEXT := dglGetProcAddress('glProgramLocalParameters4fvEXT');
+end;
+
+procedure Read_GL_EXT_bindable_uniform;
+begin
+ glUniformBufferEXT := dglGetProcAddress('glUniformBufferEXT');
+ glGetUniformBufferSizeEXT := dglGetProcAddress('glGetUniformBufferSizeEXT');
+ glGetUniformOffsetEXT := dglGetProcAddress('glGetUniformOffsetEXT');
+end;
+
+procedure Read_GL_EXT_draw_buffers2;
+begin
+ glColorMaskIndexedEXT := dglGetProcAddress('glColorMaskIndexedEXT');
+ glGetBooleanIndexedvEXT := dglGetProcAddress('glGetBooleanIndexedvEXT');
+ glGetIntegerIndexedvEXT := dglGetProcAddress('glGetIntegerIndexedvEXT');
+ glEnableIndexedEXT := dglGetProcAddress('glEnableIndexedEXT');
+ glDisableIndexedEXT := dglGetProcAddress('glDisableIndexedEXT');
+ glIsEnabledIndexedEXT := dglGetProcAddress('glIsEnabledIndexedEXT');
+end;
+
+procedure Read_GL_EXT_draw_instanced;
+begin
+ glDrawArraysInstancedEXT := dglGetProcAddress('glDrawArraysInstancedEXT');
+ glDrawElementsInstancedEXT := dglGetProcAddress('glDrawElementsInstancedEXT');
+end;
+
+procedure Read_GL_EXT_geometry_shader4;
+begin
+ glProgramParameteriEXT := dglGetProcAddress('glProgramParameteriEXT');
+ glFramebufferTextureEXT := dglGetProcAddress('glFramebufferTextureEXT');
+// glFramebufferTextureLayerEXT := dglGetProcAddress('glFramebufferTextureLayerEXT');
+ glFramebufferTextureFaceEXT := dglGetProcAddress('glFramebufferTextureFaceEXT');
+end;
+
+procedure Read_GL_EXT_gpu_shader4;
+begin
+ glVertexAttribI1iEXT := dglGetProcAddress('glVertexAttribI1iEXT');
+ glVertexAttribI2iEXT := dglGetProcAddress('glVertexAttribI2iEXT');
+ glVertexAttribI3iEXT := dglGetProcAddress('glVertexAttribI3iEXT');
+ glVertexAttribI4iEXT := dglGetProcAddress('glVertexAttribI4iEXT');
+ glVertexAttribI1uiEXT := dglGetProcAddress('glVertexAttribI1uiEXT');
+ glVertexAttribI2uiEXT := dglGetProcAddress('glVertexAttribI2uiEXT');
+ glVertexAttribI3uiEXT := dglGetProcAddress('glVertexAttribI3uiEXT');
+ glVertexAttribI4uiEXT := dglGetProcAddress('glVertexAttribI4uiEXT');
+ glVertexAttribI1ivEXT := dglGetProcAddress('glVertexAttribI1ivEXT');
+ glVertexAttribI2ivEXT := dglGetProcAddress('glVertexAttribI2ivEXT');
+ glVertexAttribI3ivEXT := dglGetProcAddress('glVertexAttribI3ivEXT');
+ glVertexAttribI4ivEXT := dglGetProcAddress('glVertexAttribI4ivEXT');
+ glVertexAttribI1uivEXT := dglGetProcAddress('glVertexAttribI1uivEXT');
+ glVertexAttribI2uivEXT := dglGetProcAddress('glVertexAttribI2uivEXT');
+ glVertexAttribI3uivEXT := dglGetProcAddress('glVertexAttribI3uivEXT');
+ glVertexAttribI4uivEXT := dglGetProcAddress('glVertexAttribI4uivEXT');
+ glVertexAttribI4bvEXT := dglGetProcAddress('glVertexAttribI4bvEXT');
+ glVertexAttribI4svEXT := dglGetProcAddress('glVertexAttribI4svEXT');
+ glVertexAttribI4ubvEXT := dglGetProcAddress('glVertexAttribI4ubvEXT');
+ glVertexAttribI4usvEXT := dglGetProcAddress('glVertexAttribI4usvEXT');
+ glVertexAttribIPointerEXT := dglGetProcAddress('glVertexAttribIPointerEXT');
+ glGetVertexAttribIivEXT := dglGetProcAddress('glGetVertexAttribIivEXT');
+ glGetVertexAttribIuivEXT := dglGetProcAddress('glGetVertexAttribIuivEXT');
+ glUniform1uiEXT := dglGetProcAddress('glUniform1uiEXT');
+ glUniform2uiEXT := dglGetProcAddress('glUniform2uiEXT');
+ glUniform3uiEXT := dglGetProcAddress('glUniform3uiEXT');
+ glUniform4uiEXT := dglGetProcAddress('glUniform4uiEXT');
+ glUniform1uivEXT := dglGetProcAddress('glUniform1uivEXT');
+ glUniform2uivEXT := dglGetProcAddress('glUniform2uivEXT');
+ glUniform3uivEXT := dglGetProcAddress('glUniform3uivEXT');
+ glUniform4uivEXT := dglGetProcAddress('glUniform4uivEXT');
+ glGetUniformuivEXT := dglGetProcAddress('glGetUniformuivEXT');
+ glBindFragDataLocationEXT := dglGetProcAddress('glBindFragDataLocationEXT');
+ glGetFragDataLocationEXT := dglGetProcAddress('glGetFragDataLocationEXT');
+end;
+
+procedure Read_GL_EXT_texture_array;
+begin
+ glFramebufferTextureLayerEXT := dglGetProcAddress('glFramebufferTextureLayerEXT');
+end;
+
+procedure Read_GL_EXT_texture_buffer_object;
+begin
+ glTexBufferEXT := dglGetProcAddress('glTexBufferEXT');
+end;
+
+procedure Read_GL_EXT_texture_integer;
+begin
+ glClearColorIiEXT := dglGetProcAddress('glClearColorIiEXT');
+ glClearColorIuiEXT := dglGetProcAddress('glClearColorIuiEXT');
+ glTexParameterIivEXT := dglGetProcAddress('glTexParameterIivEXT');
+ glTexParameterIuivEXT := dglGetProcAddress('glTexParameterIuivEXT');
+ glGetTexParameterIivEXT := dglGetProcAddress('glGetTexParameterIivEXT');
+ glGetTexParameterIiuvEXT := dglGetProcAddress('glGetTexParameterIiuvEXT');
+end;
+
+procedure Read_GL_EXT_transform_feedback;
+begin
+ glBeginTransformFeedbackEXT := dglGetProcAddress('lBeginTransformFeedbackEXT');
+ glEndTransformFeedbackEXT := dglGetProcAddress('glEndTransformFeedbackEXT');
+ glBindBufferRangeEXT := dglGetProcAddress('glBindBufferRangeEXT');
+ glBindBufferOffsetEXT := dglGetProcAddress('glBindBufferOffsetEXT');
+ glBindBufferBaseEXT := dglGetProcAddress('glBindBufferBaseEXT');
+ glTransformFeedbackVaryingsEXT := dglGetProcAddress('glTransformFeedbackVaryingsEXT');
+ glGetTransformFeedbackVaryingEXT := dglGetProcAddress('glGetTransformFeedbackVaryingEXT');
+end;
+
+procedure Read_GL_EXT_direct_state_access;
+begin
+ glClientAttribDefaultEXT := dglGetProcAddress('glClientAttribDefaultEXT');
+ glPushClientAttribDefaultEXT := dglGetProcAddress('glPushClientAttribDefaultEXT');
+ glMatrixLoadfEXT := dglGetProcAddress('glMatrixLoadfEXT');
+ glMatrixLoaddEXT := dglGetProcAddress('glMatrixLoaddEXT');
+ glMatrixMultfEXT := dglGetProcAddress('glMatrixMultfEXT');
+ glMatrixMultdEXT := dglGetProcAddress('glMatrixMultdEXT');
+ glMatrixLoadIdentityEXT := dglGetProcAddress('glMatrixLoadIdentityEXT');
+ glMatrixRotatefEXT := dglGetProcAddress('glMatrixRotatefEXT');
+ glMatrixRotatedEXT := dglGetProcAddress('glMatrixRotatedEXT');
+ glMatrixScalefEXT := dglGetProcAddress('glMatrixScalefEXT');
+ glMatrixScaledEXT := dglGetProcAddress('glMatrixScaledEXT');
+ glMatrixTranslatefEXT := dglGetProcAddress('glMatrixTranslatefEXT');
+ glMatrixTranslatedEXT := dglGetProcAddress('glMatrixTranslatedEXT');
+ glMatrixFrustumEXT := dglGetProcAddress('glMatrixFrustumEXT');
+ glMatrixOrthoEXT := dglGetProcAddress('glMatrixOrthoEXT');
+ glMatrixPopEXT := dglGetProcAddress('glMatrixPopEXT');
+ glMatrixPushEXT := dglGetProcAddress('glMatrixPushEXT');
+ glMatrixLoadTransposefEXT := dglGetProcAddress('glMatrixLoadTransposefEXT');
+ glMatrixLoadTransposedEXT := dglGetProcAddress('glMatrixLoadTransposedEXT');
+ glMatrixMultTransposefEXT := dglGetProcAddress('glMatrixMultTransposefEXT');
+ glMatrixMultTransposedEXT := dglGetProcAddress('glMatrixMultTransposedEXT');
+ glTextureParameterfEXT := dglGetProcAddress('glTextureParameterfEXT');
+ glTextureParameterfvEXT := dglGetProcAddress('glTextureParameterfvEXT');
+ glTextureParameteriEXT := dglGetProcAddress('glTextureParameteriEXT');
+ glTextureParameterivEXT := dglGetProcAddress('glTextureParameterivEXT');
+ glTextureImage1DEXT := dglGetProcAddress('glTextureImage1DEXT');
+ glTextureImage2DEXT := dglGetProcAddress('glTextureImage2DEXT');
+ glTextureSubImage1DEXT := dglGetProcAddress('glTextureSubImage1DEXT');
+ glTextureSubImage2DEXT := dglGetProcAddress('glTextureSubImage2DEXT');
+ glCopyTextureImage1DEXT := dglGetProcAddress('glCopyTextureImage1DEXT');
+ glCopyTextureImage2DEXT := dglGetProcAddress('glCopyTextureImage2DEXT');
+ glCopyTextureSubImage1DEXT := dglGetProcAddress('glCopyTextureSubImage1DEXT');
+ glCopyTextureSubImage2DEXT := dglGetProcAddress('glCopyTextureSubImage2DEXT');
+ glGetTextureImageEXT := dglGetProcAddress('glGetTextureImageEXT');
+ glGetTextureParameterfvEXT := dglGetProcAddress('glGetTextureParameterfvEXT');
+ glGetTextureParameterivEXT := dglGetProcAddress('glGetTextureParameterivEXT');
+ glGetTextureLevelParameterfvEXT := dglGetProcAddress('glGetTextureLevelParameterfvEXT');
+ glGetTextureLevelParameterivEXT := dglGetProcAddress('glGetTextureLevelParameterivEXT');
+ glTextureImage3DEXT := dglGetProcAddress('glTextureImage3DEXT');
+ glTextureSubImage3DEXT := dglGetProcAddress('glTextureSubImage3DEXT');
+ glCopyTextureSubImage3DEXT := dglGetProcAddress('glCopyTextureSubImage3DEXT');
+ glMultiTexParameterfEXT := dglGetProcAddress('glMultiTexParameterfEXT');
+ glMultiTexParameterfvEXT := dglGetProcAddress('glMultiTexParameterfvEXT');
+ glMultiTexParameteriEXT := dglGetProcAddress('glMultiTexParameteriEXT');
+ glMultiTexParameterivEXT := dglGetProcAddress('glMultiTexParameterivEXT');
+ glMultiTexImage1DEXT := dglGetProcAddress('glMultiTexImage1DEXT');
+ glMultiTexImage2DEXT := dglGetProcAddress('glMultiTexImage2DEXT');
+ glMultiTexSubImage1DEXT := dglGetProcAddress('glMultiTexSubImage1DEXT');
+ glMultiTexSubImage2DEXT := dglGetProcAddress('glMultiTexSubImage2DEXT');
+ glCopyMultiTexImage1DEXT := dglGetProcAddress('glCopyMultiTexImage1DEXT');
+ glCopyMultiTexImage2DEXT := dglGetProcAddress('glCopyMultiTexImage2DEXT');
+ glCopyMultiTexSubImage1DEXT := dglGetProcAddress('glCopyMultiTexSubImage1DEXT');
+ glCopyMultiTexSubImage2DEXT := dglGetProcAddress('glCopyMultiTexSubImage2DEXT');
+ glGetMultiTexImageEXT := dglGetProcAddress('glGetMultiTexImageEXT');
+ glGetMultiTexParameterfvEXT := dglGetProcAddress('glGetMultiTexParameterfvEXT');
+ glGetMultiTexParameterivEXT := dglGetProcAddress('glGetMultiTexParameterivEXT');
+ glGetMultiTexLevelParameterfvEXT := dglGetProcAddress('glGetMultiTexLevelParameterfvEXT');
+ glGetMultiTexLevelParameterivEXT := dglGetProcAddress('glGetMultiTexLevelParameterivEXT');
+ glMultiTexImage3DEXT := dglGetProcAddress('glMultiTexImage3DEXT');
+ glMultiTexSubImage3DEXT := dglGetProcAddress('glMultiTexSubImage3DEXT');
+ glCopyMultiTexSubImage3DEXT := dglGetProcAddress('glCopyMultiTexSubImage3DEXT');
+ glBindMultiTextureEXT := dglGetProcAddress('glBindMultiTextureEXT');
+ glEnableClientStateIndexedEXT := dglGetProcAddress('glEnableClientStateIndexedEXT');
+ glDisableClientStateIndexedEXT := dglGetProcAddress('glDisableClientStateIndexedEXT');
+ glMultiTexCoordPointerEXT := dglGetProcAddress('glMultiTexCoordPointerEXT');
+ glMultiTexEnvfEXT := dglGetProcAddress('glMultiTexEnvfEXT');
+ glMultiTexEnvfvEXT := dglGetProcAddress('glMultiTexEnvfvEXT');
+ glMultiTexEnviEXT := dglGetProcAddress('glMultiTexEnviEXT');
+ glMultiTexEnvivEXT := dglGetProcAddress('glMultiTexEnvivEXT');
+ glMultiTexGendEXT := dglGetProcAddress('glMultiTexGendEXT');
+ glMultiTexGendvEXT := dglGetProcAddress('glMultiTexGendvEXT');
+ glMultiTexGenfEXT := dglGetProcAddress('glMultiTexGenfEXT');
+ glMultiTexGenfvEXT := dglGetProcAddress('glMultiTexGenfvEXT');
+ glMultiTexGeniEXT := dglGetProcAddress('glMultiTexGeniEXT');
+ glMultiTexGenivEXT := dglGetProcAddress('glMultiTexGenivEXT');
+ glGetMultiTexEnvfvEXT := dglGetProcAddress('glGetMultiTexEnvfvEXT');
+ glGetMultiTexEnvivEXT := dglGetProcAddress('glGetMultiTexEnvivEXT');
+ glGetMultiTexGendvEXT := dglGetProcAddress('glGetMultiTexGendvEXT');
+ glGetMultiTexGenfvEXT := dglGetProcAddress('glGetMultiTexGenfvEXT');
+ glGetMultiTexGenivEXT := dglGetProcAddress('glGetMultiTexGenivEXT');
+ glGetFloatIndexedvEXT := dglGetProcAddress('glGetFloatIndexedvEXT');
+ glGetDoubleIndexedvEXT := dglGetProcAddress('glGetDoubleIndexedvEXT');
+ glGetPointerIndexedvEXT := dglGetProcAddress('glGetPointerIndexedvEXT');
+ glCompressedTextureImage3DEXT := dglGetProcAddress('glCompressedTextureImage3DEXT');
+ glCompressedTextureImage2DEXT := dglGetProcAddress('glCompressedTextureImage2DEXT');
+ glCompressedTextureImage1DEXT := dglGetProcAddress('glCompressedTextureImage1DEXT');
+ glCompressedTextureSubImage3DEXT := dglGetProcAddress('glCompressedTextureSubImage3DEXT');
+ glCompressedTextureSubImage2DEXT := dglGetProcAddress('glCompressedTextureSubImage2DEXT');
+ glCompressedTextureSubImage1DEXT := dglGetProcAddress('glCompressedTextureSubImage1DEXT');
+ glGetCompressedTextureImageEXT := dglGetProcAddress('glGetCompressedTextureImageEXT');
+ glCompressedMultiTexImage3DEXT := dglGetProcAddress('glCompressedMultiTexImage3DEXT');
+ glCompressedMultiTexImage2DEXT := dglGetProcAddress('glCompressedMultiTexImage2DEXT');
+ glCompressedMultiTexImage1DEXT := dglGetProcAddress('glCompressedMultiTexImage1DEXT');
+ glCompressedMultiTexSubImage3DEXT := dglGetProcAddress('glCompressedMultiTexSubImage3DEXT');
+ glCompressedMultiTexSubImage2DEXT := dglGetProcAddress('glCompressedMultiTexSubImage2DEXT');
+ glCompressedMultiTexSubImage1DEXT := dglGetProcAddress('glCompressedMultiTexSubImage1DEXT');
+ glGetCompressedMultiTexImageEXT := dglGetProcAddress('glGetCompressedMultiTexImageEXT');
+ glNamedProgramStringEXT := dglGetProcAddress('glNamedProgramStringEXT');
+ glNamedProgramLocalParameter4dEXT := dglGetProcAddress('glNamedProgramLocalParameter4dEXT');
+ glNamedProgramLocalParameter4dvEXT := dglGetProcAddress('glNamedProgramLocalParameter4dvEXT');
+ glNamedProgramLocalParameter4fEXT := dglGetProcAddress('glNamedProgramLocalParameter4fEXT');
+ glNamedProgramLocalParameter4fvEXT := dglGetProcAddress('glNamedProgramLocalParameter4fvEXT');
+ glGetNamedProgramLocalParameterdvEXT := dglGetProcAddress('glGetNamedProgramLocalParameterdvEXT');
+ glGetNamedProgramLocalParameterfvEXT := dglGetProcAddress('glGetNamedProgramLocalParameterfvEXT');
+ glGetNamedProgramivEXT := dglGetProcAddress('glGetNamedProgramivEXT');
+ glGetNamedProgramStringEXT := dglGetProcAddress('glGetNamedProgramStringEXT');
+ glNamedProgramLocalParameters4fvEXT := dglGetProcAddress('glNamedProgramLocalParameters4fvEXT');
+ glNamedProgramLocalParameterI4iEXT := dglGetProcAddress('glNamedProgramLocalParameterI4iEXT');
+ glNamedProgramLocalParameterI4ivEXT := dglGetProcAddress('glNamedProgramLocalParameterI4ivEXT');
+ glNamedProgramLocalParametersI4ivEXT := dglGetProcAddress('glNamedProgramLocalParametersI4ivEXT');
+ glNamedProgramLocalParameterI4uiEXT := dglGetProcAddress('glNamedProgramLocalParameterI4uiEXT');
+ glNamedProgramLocalParameterI4uivEXT := dglGetProcAddress('glNamedProgramLocalParameterI4uivEXT');
+ glNamedProgramLocalParametersI4uivEXT := dglGetProcAddress('glNamedProgramLocalParametersI4uivEXT');
+ glGetNamedProgramLocalParameterIivEXT := dglGetProcAddress('glGetNamedProgramLocalParameterIivEXT');
+ glGetNamedProgramLocalParameterIuivEXT := dglGetProcAddress('glGetNamedProgramLocalParameterIuivEXT');
+ glTextureParameterIivEXT := dglGetProcAddress('glTextureParameterIivEXT');
+ glTextureParameterIuivEXT := dglGetProcAddress('glTextureParameterIuivEXT');
+ glGetTextureParameterIivEXT := dglGetProcAddress('glGetTextureParameterIivEXT');
+ glGetTextureParameterIuivEXT := dglGetProcAddress('glGetTextureParameterIuivEXT');
+ glMultiTexParameterIivEXT := dglGetProcAddress('glMultiTexParameterIivEXT');
+ glMultiTexParameterIuivEXT := dglGetProcAddress('glMultiTexParameterIuivEXT');
+ glGetMultiTexParameterIivEXT := dglGetProcAddress('glGetMultiTexParameterIivEXT');
+ glGetMultiTexParameterIuivEXT := dglGetProcAddress('glGetMultiTexParameterIuivEXT');
+ glProgramUniform1fEXT := dglGetProcAddress('glProgramUniform1fEXT');
+ glProgramUniform2fEXT := dglGetProcAddress('glProgramUniform2fEXT');
+ glProgramUniform3fEXT := dglGetProcAddress('glProgramUniform3fEXT');
+ glProgramUniform4fEXT := dglGetProcAddress('glProgramUniform4fEXT');
+ glProgramUniform1iEXT := dglGetProcAddress('glProgramUniform1iEXT');
+ glProgramUniform2iEXT := dglGetProcAddress('glProgramUniform2iEXT');
+ glProgramUniform3iEXT := dglGetProcAddress('glProgramUniform3iEXT');
+ glProgramUniform4iEXT := dglGetProcAddress('glProgramUniform4iEXT');
+ glProgramUniform1fvEXT := dglGetProcAddress('glProgramUniform1fvEXT');
+ glProgramUniform2fvEXT := dglGetProcAddress('glProgramUniform2fvEXT');
+ glProgramUniform3fvEXT := dglGetProcAddress('glProgramUniform3fvEXT');
+ glProgramUniform4fvEXT := dglGetProcAddress('glProgramUniform4fvEXT');
+ glProgramUniform1ivEXT := dglGetProcAddress('glProgramUniform1ivEXT');
+ glProgramUniform2ivEXT := dglGetProcAddress('glProgramUniform2ivEXT');
+ glProgramUniform3ivEXT := dglGetProcAddress('glProgramUniform3ivEXT');
+ glProgramUniform4ivEXT := dglGetProcAddress('glProgramUniform4ivEXT');
+ glProgramUniformMatrix2fvEXT := dglGetProcAddress('glProgramUniformMatrix2fvEXT');
+ glProgramUniformMatrix3fvEXT := dglGetProcAddress('glProgramUniformMatrix3fvEXT');
+ glProgramUniformMatrix4fvEXT := dglGetProcAddress('glProgramUniformMatrix4fvEXT');
+ glProgramUniformMatrix2x3fvEXT := dglGetProcAddress('glProgramUniformMatrix2x3fvEXT');
+ glProgramUniformMatrix3x2fvEXT := dglGetProcAddress('glProgramUniformMatrix3x2fvEXT');
+ glProgramUniformMatrix2x4fvEXT := dglGetProcAddress('glProgramUniformMatrix2x4fvEXT');
+ glProgramUniformMatrix4x2fvEXT := dglGetProcAddress('glProgramUniformMatrix4x2fvEXT');
+ glProgramUniformMatrix3x4fvEXT := dglGetProcAddress('glProgramUniformMatrix3x4fvEXT');
+ glProgramUniformMatrix4x3fvEXT := dglGetProcAddress('glProgramUniformMatrix4x3fvEXT');
+ glProgramUniform1uiEXT := dglGetProcAddress('glProgramUniform1uiEXT');
+ glProgramUniform2uiEXT := dglGetProcAddress('glProgramUniform2uiEXT');
+ glProgramUniform3uiEXT := dglGetProcAddress('glProgramUniform3uiEXT');
+ glProgramUniform4uiEXT := dglGetProcAddress('glProgramUniform4uiEXT');
+ glProgramUniform1uivEXT := dglGetProcAddress('glProgramUniform1uivEXT');
+ glProgramUniform2uivEXT := dglGetProcAddress('glProgramUniform2uivEXT');
+ glProgramUniform3uivEXT := dglGetProcAddress('glProgramUniform3uivEXT');
+ glProgramUniform4uivEXT := dglGetProcAddress('glProgramUniform4uivEXT');
+ glNamedBufferDataEXT := dglGetProcAddress('glNamedBufferDataEXT');
+ glNamedBufferSubDataEXT := dglGetProcAddress('glNamedBufferSubDataEXT');
+ glMapNamedBufferEXT := dglGetProcAddress('glMapNamedBufferEXT');
+ glUnmapNamedBufferEXT := dglGetProcAddress('glUnmapNamedBufferEXT');
+ glMapNamedBufferRangeEXT := dglGetProcAddress('glMapNamedBufferRangeEXT');
+ glFlushMappedNamedBufferRangeEXT := dglGetProcAddress('glFlushMappedNamedBufferRangeEXT');
+ glNamedCopyBufferSubDataEXT := dglGetProcAddress('glNamedCopyBufferSubDataEXT');
+ glGetNamedBufferParameterivEXT := dglGetProcAddress('glGetNamedBufferParameterivEXT');
+ glGetNamedBufferPointervEXT := dglGetProcAddress('glGetNamedBufferPointervEXT');
+ glGetNamedBufferSubDataEXT := dglGetProcAddress('glGetNamedBufferSubDataEXT');
+ glTextureBufferEXT := dglGetProcAddress('glTextureBufferEXT');
+ glMultiTexBufferEXT := dglGetProcAddress('glMultiTexBufferEXT');
+ glNamedRenderbufferStorageEXT := dglGetProcAddress('glNamedRenderbufferStorageEXT');
+ glGetNamedRenderbufferParameterivEXT := dglGetProcAddress('glGetNamedRenderbufferParameterivEXT');
+ glCheckNamedFramebufferStatusEXT := dglGetProcAddress('glCheckNamedFramebufferStatusEXT');
+ glNamedFramebufferTexture1DEXT := dglGetProcAddress('glNamedFramebufferTexture1DEXT');
+ glNamedFramebufferTexture2DEXT := dglGetProcAddress('glNamedFramebufferTexture2DEXT');
+ glNamedFramebufferTexture3DEXT := dglGetProcAddress('glNamedFramebufferTexture3DEXT');
+ glNamedFramebufferRenderbufferEXT := dglGetProcAddress('glNamedFramebufferRenderbufferEXT');
+ glGetNamedFramebufferAttachmentParameterivEXT := dglGetProcAddress('glGetNamedFramebufferAttachmentParameterivEXT');
+ glGenerateTextureMipmapEXT := dglGetProcAddress('glGenerateTextureMipmapEXT');
+ glGenerateMultiTexMipmapEXT := dglGetProcAddress('glGenerateMultiTexMipmapEXT');
+ glFramebufferDrawBufferEXT := dglGetProcAddress('glFramebufferDrawBufferEXT');
+ glFramebufferDrawBuffersEXT := dglGetProcAddress('glFramebufferDrawBuffersEXT');
+ glFramebufferReadBufferEXT := dglGetProcAddress('glFramebufferReadBufferEXT');
+ glGetFramebufferParameterivEXT := dglGetProcAddress('glGetFramebufferParameterivEXT');
+ glNamedRenderbufferStorageMultisampleEXT := dglGetProcAddress('glNamedRenderbufferStorageMultisampleEXT');
+ glNamedRenderbufferStorageMultisampleCoverageEXT := dglGetProcAddress('glNamedRenderbufferStorageMultisampleCoverageEXT');
+ glNamedFramebufferTextureEXT := dglGetProcAddress('glNamedFramebufferTextureEXT');
+ glNamedFramebufferTextureLayerEXT := dglGetProcAddress('glNamedFramebufferTextureLayerEXT');
+ glNamedFramebufferTextureFaceEXT := dglGetProcAddress('glNamedFramebufferTextureFaceEXT');
+ glTextureRenderbufferEXT := dglGetProcAddress('glTextureRenderbufferEXT');
+ glMultiTexRenderbufferEXT := dglGetProcAddress('glMultiTexRenderbufferEXT');
+ glProgramUniform1dEXT := dglGetProcAddress('glProgramUniform1dEXT');
+ glProgramUniform2dEXT := dglGetProcAddress('glProgramUniform2dEXT');
+ glProgramUniform3dEXT := dglGetProcAddress('glProgramUniform3dEXT');
+ glProgramUniform4dEXT := dglGetProcAddress('glProgramUniform4dEXT');
+ glProgramUniform1dvEXT := dglGetProcAddress('glProgramUniform1dvEXT');
+ glProgramUniform2dvEXT := dglGetProcAddress('glProgramUniform2dvEXT');
+ glProgramUniform3dvEXT := dglGetProcAddress('glProgramUniform3dvEXT');
+ glProgramUniform4dvEXT := dglGetProcAddress('glProgramUniform4dvEXT');
+ glProgramUniformMatrix2dvEXT := dglGetProcAddress('glProgramUniformMatrix2dvEXT');
+ glProgramUniformMatrix3dvEXT := dglGetProcAddress('glProgramUniformMatrix3dvEXT');
+ glProgramUniformMatrix4dvEXT := dglGetProcAddress('glProgramUniformMatrix4dvEXT');
+ glProgramUniformMatrix2x3dvEXT := dglGetProcAddress('glProgramUniformMatrix2x3dvEXT');
+ glProgramUniformMatrix2x4dvEXT := dglGetProcAddress('glProgramUniformMatrix2x4dvEXT');
+ glProgramUniformMatrix3x2dvEXT := dglGetProcAddress('glProgramUniformMatrix3x2dvEXT');
+ glProgramUniformMatrix3x4dvEXT := dglGetProcAddress('glProgramUniformMatrix3x4dvEXT');
+ glProgramUniformMatrix4x2dvEXT := dglGetProcAddress('glProgramUniformMatrix4x2dvEXT');
+ glProgramUniformMatrix4x3dvEXT := dglGetProcAddress('glProgramUniformMatrix4x3dvEXT');
+end;
+
+procedure Read_GL_EXT_separate_shader_objects;
+begin
+ glUseShaderProgramEXT := dglGetProcAddress('glUseShaderProgramEXT');
+ glActiveProgramEXT := dglGetProcAddress('glActiveProgramEXT');
+ glCreateShaderProgramEXT := dglGetProcAddress('glCreateShaderProgramEXT');
+end;
+
+procedure Read_GL_EXT_shader_image_load_store;
+begin
+ glBindImageTextureEXT := dglGetProcAddress('glBindImageTextureEXT');
+ glMemoryBarrierEXT := dglGetProcAddress('glMemoryBarrierEXT');
+end;
+
+procedure Read_GL_EXT_vertex_attrib_64bit;
+begin
+ glVertexAttribL1dEXT := dglGetProcAddress('glVertexAttribL1dEXT');
+ glVertexAttribL2dEXT := dglGetProcAddress('glVertexAttribL2dEXT');
+ glVertexAttribL3dEXT := dglGetProcAddress('glVertexAttribL3dEXT');
+ glVertexAttribL4dEXT := dglGetProcAddress('glVertexAttribL4dEXT');
+ glVertexAttribL1dvEXT := dglGetProcAddress('glVertexAttribL1dvEXT');
+ glVertexAttribL2dvEXT := dglGetProcAddress('glVertexAttribL2dvEXT');
+ glVertexAttribL3dvEXT := dglGetProcAddress('glVertexAttribL3dvEXT');
+ glVertexAttribL4dvEXT := dglGetProcAddress('glVertexAttribL4dvEXT');
+ glVertexAttribLPointerEXT := dglGetProcAddress('glVertexAttribLPointerEXT');
+ glGetVertexAttribLdvEXT := dglGetProcAddress('glGetVertexAttribLdvEXT');
+ glVertexArrayVertexAttribLOffsetEXT := dglGetProcAddress('glVertexArrayVertexAttribLOffsetEXT');
+end;
+
+procedure Read_GL_HP_image_transform;
+begin
+ glImageTransformParameteriHP := dglGetProcAddress('glImageTransformParameteriHP');
+ glImageTransformParameterfHP := dglGetProcAddress('glImageTransformParameterfHP');
+ glImageTransformParameterivHP := dglGetProcAddress('glImageTransformParameterivHP');
+ glImageTransformParameterfvHP := dglGetProcAddress('glImageTransformParameterfvHP');
+ glGetImageTransformParameterivHP := dglGetProcAddress('glGetImageTransformParameterivHP');
+ glGetImageTransformParameterfvHP := dglGetProcAddress('glGetImageTransformParameterfvHP');
+end;
+
+procedure Read_GL_IBM_multimode_draw_arrays;
+begin
+ glMultiModeDrawArraysIBM := dglGetProcAddress('glMultiModeDrawArraysIBM');
+ glMultiModeDrawElementsIBM := dglGetProcAddress('glMultiModeDrawElementsIBM');
+end;
+
+procedure Read_GL_IBM_vertex_array_lists;
+begin
+ glColorPointerListIBM := dglGetProcAddress('glColorPointerListIBM');
+ glSecondaryColorPointerListIBM := dglGetProcAddress('glSecondaryColorPointerListIBM');
+ glEdgeFlagPointerListIBM := dglGetProcAddress('glEdgeFlagPointerListIBM');
+ glFogCoordPointerListIBM := dglGetProcAddress('glFogCoordPointerListIBM');
+ glIndexPointerListIBM := dglGetProcAddress('glIndexPointerListIBM');
+ glNormalPointerListIBM := dglGetProcAddress('glNormalPointerListIBM');
+ glTexCoordPointerListIBM := dglGetProcAddress('glTexCoordPointerListIBM');
+ glVertexPointerListIBM := dglGetProcAddress('glVertexPointerListIBM');
+end;
+
+procedure Read_GL_INGR_blend_func_separate;
+begin
+ glBlendFuncSeparateINGR := dglGetProcAddress('glBlendFuncSeparateINGR');
+end;
+
+procedure Read_GL_INTEL_parallel_arrays;
+begin
+ glVertexPointervINTEL := dglGetProcAddress('glVertexPointervINTEL');
+ glNormalPointervINTEL := dglGetProcAddress('glNormalPointervINTEL');
+ glColorPointervINTEL := dglGetProcAddress('glColorPointervINTEL');
+ glTexCoordPointervINTEL := dglGetProcAddress('glTexCoordPointervINTEL');
+end;
+
+procedure Read_GL_INTEL_framebuffer_CMAA;
+begin
+ glApplyFramebufferAttachmentCMAAINTEL := dglGetProcAddress('glApplyFramebufferAttachmentCMAAINTEL');
+end;
+
+procedure Read_GL_MESA_resize_buffers;
+begin
+ glResizeBuffersMESA := dglGetProcAddress('glResizeBuffersMESA');
+end;
+
+procedure Read_GL_MESA_window_pos;
+begin
+ glWindowPos2dMESA := dglGetProcAddress('glWindowPos2dMESA');
+ glWindowPos2dvMESA := dglGetProcAddress('glWindowPos2dvMESA');
+ glWindowPos2fMESA := dglGetProcAddress('glWindowPos2fMESA');
+ glWindowPos2fvMESA := dglGetProcAddress('glWindowPos2fvMESA');
+ glWindowPos2iMESA := dglGetProcAddress('glWindowPos2iMESA');
+ glWindowPos2ivMESA := dglGetProcAddress('glWindowPos2ivMESA');
+ glWindowPos2sMESA := dglGetProcAddress('glWindowPos2sMESA');
+ glWindowPos2svMESA := dglGetProcAddress('glWindowPos2svMESA');
+ glWindowPos3dMESA := dglGetProcAddress('glWindowPos3dMESA');
+ glWindowPos3dvMESA := dglGetProcAddress('glWindowPos3dvMESA');
+ glWindowPos3fMESA := dglGetProcAddress('glWindowPos3fMESA');
+ glWindowPos3fvMESA := dglGetProcAddress('glWindowPos3fvMESA');
+ glWindowPos3iMESA := dglGetProcAddress('glWindowPos3iMESA');
+ glWindowPos3ivMESA := dglGetProcAddress('glWindowPos3ivMESA');
+ glWindowPos3sMESA := dglGetProcAddress('glWindowPos3sMESA');
+ glWindowPos3svMESA := dglGetProcAddress('glWindowPos3svMESA');
+ glWindowPos4dMESA := dglGetProcAddress('glWindowPos4dMESA');
+ glWindowPos4dvMESA := dglGetProcAddress('glWindowPos4dvMESA');
+ glWindowPos4fMESA := dglGetProcAddress('glWindowPos4fMESA');
+ glWindowPos4fvMESA := dglGetProcAddress('glWindowPos4fvMESA');
+ glWindowPos4iMESA := dglGetProcAddress('glWindowPos4iMESA');
+ glWindowPos4ivMESA := dglGetProcAddress('glWindowPos4ivMESA');
+ glWindowPos4sMESA := dglGetProcAddress('glWindowPos4sMESA');
+ glWindowPos4svMESA := dglGetProcAddress('glWindowPos4svMESA');
+end;
+
+procedure Read_GL_NV_evaluators;
+begin
+ glMapControlPointsNV := dglGetProcAddress('glMapControlPointsNV');
+ glMapParameterivNV := dglGetProcAddress('glMapParameterivNV');
+ glMapParameterfvNV := dglGetProcAddress('glMapParameterfvNV');
+ glGetMapControlPointsNV := dglGetProcAddress('glGetMapControlPointsNV');
+ glGetMapParameterivNV := dglGetProcAddress('glGetMapParameterivNV');
+ glGetMapParameterfvNV := dglGetProcAddress('glGetMapParameterfvNV');
+ glGetMapAttribParameterivNV := dglGetProcAddress('glGetMapAttribParameterivNV');
+ glGetMapAttribParameterfvNV := dglGetProcAddress('glGetMapAttribParameterfvNV');
+ glEvalMapsNV := dglGetProcAddress('glEvalMapsNV');
+end;
+
+procedure Read_GL_NV_fence;
+begin
+ glDeleteFencesNV := dglGetProcAddress('glDeleteFencesNV');
+ glGenFencesNV := dglGetProcAddress('glGenFencesNV');
+ glIsFenceNV := dglGetProcAddress('glIsFenceNV');
+ glTestFenceNV := dglGetProcAddress('glTestFenceNV');
+ glGetFenceivNV := dglGetProcAddress('glGetFenceivNV');
+ glFinishFenceNV := dglGetProcAddress('glFinishFenceNV');
+ glSetFenceNV := dglGetProcAddress('glSetFenceNV');
+end;
+
+procedure Read_GL_NV_fragment_program;
+begin
+ glProgramNamedParameter4fNV := dglGetProcAddress('glProgramNamedParameter4fNV');
+ glProgramNamedParameter4dNV := dglGetProcAddress('glProgramNamedParameter4dNV');
+ glProgramNamedParameter4fvNV := dglGetProcAddress('glProgramNamedParameter4fvNV');
+ glProgramNamedParameter4dvNV := dglGetProcAddress('glProgramNamedParameter4dvNV');
+ glGetProgramNamedParameterfvNV := dglGetProcAddress('glGetProgramNamedParameterfvNV');
+ glGetProgramNamedParameterdvNV := dglGetProcAddress('glGetProgramNamedParameterdvNV');
+end;
+
+procedure Read_GL_NV_half_float;
+begin
+ glVertex2hNV := dglGetProcAddress('glVertex2hNV');
+ glVertex2hvNV := dglGetProcAddress('glVertex2hvNV');
+ glVertex3hNV := dglGetProcAddress('glVertex3hNV');
+ glVertex3hvNV := dglGetProcAddress('glVertex3hvNV');
+ glVertex4hNV := dglGetProcAddress('glVertex4hNV');
+ glVertex4hvNV := dglGetProcAddress('glVertex4hvNV');
+ glNormal3hNV := dglGetProcAddress('glNormal3hNV');
+ glNormal3hvNV := dglGetProcAddress('glNormal3hvNV');
+ glColor3hNV := dglGetProcAddress('glColor3hNV');
+ glColor3hvNV := dglGetProcAddress('glColor3hvNV');
+ glColor4hNV := dglGetProcAddress('glColor4hNV');
+ glColor4hvNV := dglGetProcAddress('glColor4hvNV');
+ glTexCoord1hNV := dglGetProcAddress('glTexCoord1hNV');
+ glTexCoord1hvNV := dglGetProcAddress('glTexCoord1hvNV');
+ glTexCoord2hNV := dglGetProcAddress('glTexCoord2hNV');
+ glTexCoord2hvNV := dglGetProcAddress('glTexCoord2hvNV');
+ glTexCoord3hNV := dglGetProcAddress('glTexCoord3hNV');
+ glTexCoord3hvNV := dglGetProcAddress('glTexCoord3hvNV');
+ glTexCoord4hNV := dglGetProcAddress('glTexCoord4hNV');
+ glTexCoord4hvNV := dglGetProcAddress('glTexCoord4hvNV');
+ glMultiTexCoord1hNV := dglGetProcAddress('glMultiTexCoord1hNV');
+ glMultiTexCoord1hvNV := dglGetProcAddress('glMultiTexCoord1hvNV');
+ glMultiTexCoord2hNV := dglGetProcAddress('glMultiTexCoord2hNV');
+ glMultiTexCoord2hvNV := dglGetProcAddress('glMultiTexCoord2hvNV');
+ glMultiTexCoord3hNV := dglGetProcAddress('glMultiTexCoord3hNV');
+ glMultiTexCoord3hvNV := dglGetProcAddress('glMultiTexCoord3hvNV');
+ glMultiTexCoord4hNV := dglGetProcAddress('glMultiTexCoord4hNV');
+ glMultiTexCoord4hvNV := dglGetProcAddress('glMultiTexCoord4hvNV');
+ glFogCoordhNV := dglGetProcAddress('glFogCoordhNV');
+ glFogCoordhvNV := dglGetProcAddress('glFogCoordhvNV');
+ glSecondaryColor3hNV := dglGetProcAddress('glSecondaryColor3hNV');
+ glSecondaryColor3hvNV := dglGetProcAddress('glSecondaryColor3hvNV');
+ glVertexWeighthNV := dglGetProcAddress('glVertexWeighthNV');
+ glVertexWeighthvNV := dglGetProcAddress('glVertexWeighthvNV');
+ glVertexAttrib1hNV := dglGetProcAddress('glVertexAttrib1hNV');
+ glVertexAttrib1hvNV := dglGetProcAddress('glVertexAttrib1hvNV');
+ glVertexAttrib2hNV := dglGetProcAddress('glVertexAttrib2hNV');
+ glVertexAttrib2hvNV := dglGetProcAddress('glVertexAttrib2hvNV');
+ glVertexAttrib3hNV := dglGetProcAddress('glVertexAttrib3hNV');
+ glVertexAttrib3hvNV := dglGetProcAddress('glVertexAttrib3hvNV');
+ glVertexAttrib4hNV := dglGetProcAddress('glVertexAttrib4hNV');
+ glVertexAttrib4hvNV := dglGetProcAddress('glVertexAttrib4hvNV');
+ glVertexAttribs1hvNV := dglGetProcAddress('glVertexAttribs1hvNV');
+ glVertexAttribs2hvNV := dglGetProcAddress('glVertexAttribs2hvNV');
+ glVertexAttribs3hvNV := dglGetProcAddress('glVertexAttribs3hvNV');
+ glVertexAttribs4hvNV := dglGetProcAddress('glVertexAttribs4hvNV');
+end;
+
+procedure Read_GL_NV_occlusion_query;
+begin
+ glGenOcclusionQueriesNV := dglGetProcAddress('glGenOcclusionQueriesNV');
+ glDeleteOcclusionQueriesNV := dglGetProcAddress('glDeleteOcclusionQueriesNV');
+ glIsOcclusionQueryNV := dglGetProcAddress('glIsOcclusionQueryNV');
+ glBeginOcclusionQueryNV := dglGetProcAddress('glBeginOcclusionQueryNV');
+ glEndOcclusionQueryNV := dglGetProcAddress('glEndOcclusionQueryNV');
+ glGetOcclusionQueryivNV := dglGetProcAddress('glGetOcclusionQueryivNV');
+ glGetOcclusionQueryuivNV := dglGetProcAddress('glGetOcclusionQueryuivNV');
+end;
+
+procedure Read_GL_NV_pixel_data_range;
+begin
+ glPixelDataRangeNV := dglGetProcAddress('glPixelDataRangeNV');
+ glFlushPixelDataRangeNV := dglGetProcAddress('glFlushPixelDataRangeNV');
+end;
+
+procedure Read_GL_NV_point_sprite;
+begin
+ glPointParameteriNV := dglGetProcAddress('glPointParameteriNV');
+ glPointParameterivNV := dglGetProcAddress('glPointParameterivNV');
+end;
+
+procedure Read_GL_NV_primitive_restart;
+begin
+ glPrimitiveRestartNV := dglGetProcAddress('glPrimitiveRestartNV');
+ glPrimitiveRestartIndexNV := dglGetProcAddress('glPrimitiveRestartIndexNV');
+end;
+
+procedure Read_GL_NV_register_combiners;
+begin
+ glCombinerParameterfvNV := dglGetProcAddress('glCombinerParameterfvNV');
+ glCombinerParameterfNV := dglGetProcAddress('glCombinerParameterfNV');
+ glCombinerParameterivNV := dglGetProcAddress('glCombinerParameterivNV');
+ glCombinerParameteriNV := dglGetProcAddress('glCombinerParameteriNV');
+ glCombinerInputNV := dglGetProcAddress('glCombinerInputNV');
+ glCombinerOutputNV := dglGetProcAddress('glCombinerOutputNV');
+ glFinalCombinerInputNV := dglGetProcAddress('glFinalCombinerInputNV');
+ glGetCombinerInputParameterfvNV := dglGetProcAddress('glGetCombinerInputParameterfvNV');
+ glGetCombinerInputParameterivNV := dglGetProcAddress('glGetCombinerInputParameterivNV');
+ glGetCombinerOutputParameterfvNV := dglGetProcAddress('glGetCombinerOutputParameterfvNV');
+ glGetCombinerOutputParameterivNV := dglGetProcAddress('glGetCombinerOutputParameterivNV');
+ glGetFinalCombinerInputParameterfvNV := dglGetProcAddress('glGetFinalCombinerInputParameterfvNV');
+ glGetFinalCombinerInputParameterivNV := dglGetProcAddress('glGetFinalCombinerInputParameterivNV');
+end;
+
+procedure Read_GL_NV_register_combiners2;
+begin
+ glCombinerStageParameterfvNV := dglGetProcAddress('glCombinerStageParameterfvNV');
+ glGetCombinerStageParameterfvNV := dglGetProcAddress('glGetCombinerStageParameterfvNV');
+end;
+
+procedure Read_GL_NV_vertex_array_range;
+begin
+ glFlushVertexArrayRangeNV := dglGetProcAddress('glFlushVertexArrayRangeNV');
+ glVertexArrayRangeNV := dglGetProcAddress('glVertexArrayRangeNV');
+end;
+
+procedure Read_GL_NV_vertex_program;
+begin
+ glAreProgramsResidentNV := dglGetProcAddress('glAreProgramsResidentNV');
+ glBindProgramNV := dglGetProcAddress('glBindProgramNV');
+ glDeleteProgramsNV := dglGetProcAddress('glDeleteProgramsNV');
+ glExecuteProgramNV := dglGetProcAddress('glExecuteProgramNV');
+ glGenProgramsNV := dglGetProcAddress('glGenProgramsNV');
+ glGetProgramParameterdvNV := dglGetProcAddress('glGetProgramParameterdvNV');
+ glGetProgramParameterfvNV := dglGetProcAddress('glGetProgramParameterfvNV');
+ glGetProgramivNV := dglGetProcAddress('glGetProgramivNV');
+ glGetProgramStringNV := dglGetProcAddress('glGetProgramStringNV');
+ glGetTrackMatrixivNV := dglGetProcAddress('glGetTrackMatrixivNV');
+ glGetVertexAttribdvNV := dglGetProcAddress('glGetVertexAttribdvNV');
+ glGetVertexAttribfvNV := dglGetProcAddress('glGetVertexAttribfvNV');
+ glGetVertexAttribivNV := dglGetProcAddress('glGetVertexAttribivNV');
+ glGetVertexAttribPointervNV := dglGetProcAddress('glGetVertexAttribPointervNV');
+ glIsProgramNV := dglGetProcAddress('glIsProgramNV');
+ glLoadProgramNV := dglGetProcAddress('glLoadProgramNV');
+ glProgramParameter4dNV := dglGetProcAddress('glProgramParameter4dNV');
+ glProgramParameter4dvNV := dglGetProcAddress('glProgramParameter4dvNV');
+ glProgramParameter4fNV := dglGetProcAddress('glProgramParameter4fNV');
+ glProgramParameter4fvNV := dglGetProcAddress('glProgramParameter4fvNV');
+ glProgramParameters4dvNV := dglGetProcAddress('glProgramParameters4dvNV');
+ glProgramParameters4fvNV := dglGetProcAddress('glProgramParameters4fvNV');
+ glRequestResidentProgramsNV := dglGetProcAddress('glRequestResidentProgramsNV');
+ glTrackMatrixNV := dglGetProcAddress('glTrackMatrixNV');
+ glVertexAttribPointerNV := dglGetProcAddress('glVertexAttribPointerNV');
+ glVertexAttrib1dNV := dglGetProcAddress('glVertexAttrib1dNV');
+ glVertexAttrib1dvNV := dglGetProcAddress('glVertexAttrib1dvNV');
+ glVertexAttrib1fNV := dglGetProcAddress('glVertexAttrib1fNV');
+ glVertexAttrib1fvNV := dglGetProcAddress('glVertexAttrib1fvNV');
+ glVertexAttrib1sNV := dglGetProcAddress('glVertexAttrib1sNV');
+ glVertexAttrib1svNV := dglGetProcAddress('glVertexAttrib1svNV');
+ glVertexAttrib2dNV := dglGetProcAddress('glVertexAttrib2dNV');
+ glVertexAttrib2dvNV := dglGetProcAddress('glVertexAttrib2dvNV');
+ glVertexAttrib2fNV := dglGetProcAddress('glVertexAttrib2fNV');
+ glVertexAttrib2fvNV := dglGetProcAddress('glVertexAttrib2fvNV');
+ glVertexAttrib2sNV := dglGetProcAddress('glVertexAttrib2sNV');
+ glVertexAttrib2svNV := dglGetProcAddress('glVertexAttrib2svNV');
+ glVertexAttrib3dNV := dglGetProcAddress('glVertexAttrib3dNV');
+ glVertexAttrib3dvNV := dglGetProcAddress('glVertexAttrib3dvNV');
+ glVertexAttrib3fNV := dglGetProcAddress('glVertexAttrib3fNV');
+ glVertexAttrib3fvNV := dglGetProcAddress('glVertexAttrib3fvNV');
+ glVertexAttrib3sNV := dglGetProcAddress('glVertexAttrib3sNV');
+ glVertexAttrib3svNV := dglGetProcAddress('glVertexAttrib3svNV');
+ glVertexAttrib4dNV := dglGetProcAddress('glVertexAttrib4dNV');
+ glVertexAttrib4dvNV := dglGetProcAddress('glVertexAttrib4dvNV');
+ glVertexAttrib4fNV := dglGetProcAddress('glVertexAttrib4fNV');
+ glVertexAttrib4fvNV := dglGetProcAddress('glVertexAttrib4fvNV');
+ glVertexAttrib4sNV := dglGetProcAddress('glVertexAttrib4sNV');
+ glVertexAttrib4svNV := dglGetProcAddress('glVertexAttrib4svNV');
+ glVertexAttrib4ubNV := dglGetProcAddress('glVertexAttrib4ubNV');
+ glVertexAttrib4ubvNV := dglGetProcAddress('glVertexAttrib4ubvNV');
+ glVertexAttribs1dvNV := dglGetProcAddress('glVertexAttribs1dvNV');
+ glVertexAttribs1fvNV := dglGetProcAddress('glVertexAttribs1fvNV');
+ glVertexAttribs1svNV := dglGetProcAddress('glVertexAttribs1svNV');
+ glVertexAttribs2dvNV := dglGetProcAddress('glVertexAttribs2dvNV');
+ glVertexAttribs2fvNV := dglGetProcAddress('glVertexAttribs2fvNV');
+ glVertexAttribs2svNV := dglGetProcAddress('glVertexAttribs2svNV');
+ glVertexAttribs3dvNV := dglGetProcAddress('glVertexAttribs3dvNV');
+ glVertexAttribs3fvNV := dglGetProcAddress('glVertexAttribs3fvNV');
+ glVertexAttribs3svNV := dglGetProcAddress('glVertexAttribs3svNV');
+ glVertexAttribs4dvNV := dglGetProcAddress('glVertexAttribs4dvNV');
+ glVertexAttribs4fvNV := dglGetProcAddress('glVertexAttribs4fvNV');
+ glVertexAttribs4svNV := dglGetProcAddress('glVertexAttribs4svNV');
+ glVertexAttribs4ubvNV := dglGetProcAddress('glVertexAttribs4ubvNV');
+end;
+
+procedure Read_GL_NV_depth_buffer_float;
+begin
+ glDepthRangedNV := dglGetProcAddress('glDepthRangedNV');
+ glClearDepthdNV := dglGetProcAddress('glClearDepthdNV');
+ glDepthBoundsdNV := dglGetProcAddress('glDepthBoundsdNV');
+end;
+
+procedure Read_GL_NV_framebuffer_multisample_coverage;
+begin
+ glRenderbufferStorageMultsampleCoverageNV := dglGetProcAddress('glRenderbufferStorageMultsampleCoverageNV');
+end;
+
+procedure Read_GL_NV_geometry_program4;
+begin
+ glProgramVertexLimitNV := dglGetProcAddress('glProgramVertexLimitNV');
+end;
+
+procedure Read_GL_NV_gpu_program4;
+begin
+ glProgramLocalParameterI4iNV := dglGetProcAddress('glProgramLocalParameterI4iNV');
+ glProgramLocalParameterI4ivNV := dglGetProcAddress('glProgramLocalParameterI4ivNV');
+ glProgramLocalParametersI4ivNV := dglGetProcAddress('glProgramLocalParametersI4ivNV');
+ glProgramLocalParameterI4uiNV := dglGetProcAddress('glProgramLocalParameterI4uiNV');
+ glProgramLocalParameterI4uivNV := dglGetProcAddress('glProgramLocalParameterI4uivNV');
+ glProgramLocalParametersI4uivNV := dglGetProcAddress('glProgramLocalParametersI4uivNV');
+ glProgramEnvParameterI4iNV := dglGetProcAddress('glProgramEnvParameterI4iNV');
+ glProgramEnvParameterI4ivNV := dglGetProcAddress('glProgramEnvParameterI4ivNV');
+ glProgramEnvParametersI4ivNV := dglGetProcAddress('glProgramEnvParametersI4ivNV');
+ glProgramEnvParameterI4uiNV := dglGetProcAddress('glProgramEnvParameterI4uiNV');
+ glProgramEnvParameterI4uivNV := dglGetProcAddress('glProgramEnvParameterI4uivNV');
+ glProgramEnvParametersI4uivNV := dglGetProcAddress('glProgramEnvParametersI4uivNV');
+ glGetProgramLocalParameterIivNV := dglGetProcAddress('glGetProgramLocalParameterIivNV');
+ glGetProgramLocalParameterIuivNV := dglGetProcAddress('glGetProgramLocalParameterIuivNV');
+ glGetProgramEnvParameterIivNV := dglGetProcAddress('glGetProgramEnvParameterIivNV');
+ glGetProgramEnvParameterIuivNV := dglGetProcAddress('glGetProgramEnvParameterIuivNV');
+end;
+
+procedure Read_GL_NV_parameter_buffer_object;
+begin
+ glProgramBufferParametersfvNV := dglGetProcAddress('glProgramBufferParametersfvNV');
+ glProgramBufferParametersIivNV := dglGetProcAddress('glProgramBufferParametersIivNV');
+ glProgramBufferParametersIuivNV := dglGetProcAddress('glProgramBufferParametersIuivNV');
+end;
+
+procedure Read_GL_NV_transform_feedback;
+begin
+ glBeginTransformFeedbackNV := dglGetProcAddress('glBeginTransformFeedbackNV');
+ glEndTransformFeedbackNV := dglGetProcAddress('glEndTransformFeedbackNV');
+ glTransformFeedbackAttribsNV := dglGetProcAddress('glTransformFeedbackAttribsNV');
+ glBindBufferRangeNV := dglGetProcAddress('glBindBufferRangeNV');
+ glBindBufferOffsetNV := dglGetProcAddress('glBindBufferOffsetNV');
+ glBindBufferBaseNV := dglGetProcAddress('glBindBufferBaseNV');
+ glTransformFeedbackVaryingsNV := dglGetProcAddress('glTransformFeedbackVaryingsNV');
+ glActiveVaryingNV := dglGetProcAddress('glActiveVaryingNV');
+ glGetVaryingLocationNV := dglGetProcAddress('glGetVaryingLocationNV');
+ glGetActiveVaryingNV := dglGetProcAddress('glGetActiveVaryingNV');
+ glGetTransformFeedbackVaryingNV := dglGetProcAddress('glGetTransformFeedbackVaryingNV');
+ glTransformFeedbackStreamAttribsNV := dglGetProcAddress('glTransformFeedbackStreamAttribsNV');
+end;
+
+procedure Read_GL_NV_conditional_render;
+begin
+ glBeginConditionalRenderNV := dglGetProcAddress('glBeginConditionalRenderNV');
+ glEndConditionalRenderNV := dglGetProcAddress('glEndConditionalRenderNV');
+end;
+
+procedure Read_GL_NV_conservative_raster;
+begin
+ glSubpixelPrecisionBiasNV := dglGetProcAddress('glSubpixelPrecisionBiasNV');
+end;
+
+procedure Read_GL_NV_conservative_raster_dilate;
+begin
+ glConservativeRasterParameterfNV := dglGetProcAddress('glConservativeRasterParameterfNV');
+end;
+
+
+procedure Read_GL_NV_present_video;
+begin
+ glPresentFrameKeyedNV := dglGetProcAddress('glPresentFrameKeyedNV');
+ glPresentFrameDualFillNV := dglGetProcAddress('glPresentFrameDualFillNV');
+ glGetVideoivNV := dglGetProcAddress('glGetVideoivNV');
+ glGetVideouivNV := dglGetProcAddress('glGetVideouivNV');
+ glGetVideoi64vNV := dglGetProcAddress('glGetVideoi64vNV');
+ glGetVideoui64vNV := dglGetProcAddress('glGetVideoui64vNV');
+// glVideoParameterivNV := dglGetProcAddress('glVideoParameterivNV');
+end;
+
+procedure Read_GL_NV_explicit_multisample;
+begin
+ glGetMultisamplefvNV := dglGetProcAddress('glGetMultisamplefvNV');
+ glSampleMaskIndexedNV := dglGetProcAddress('glSampleMaskIndexedNV');
+ glTexRenderbufferNV := dglGetProcAddress('glTexRenderbufferNV');
+end;
+
+procedure Read_GL_NV_transform_feedback2;
+begin
+ glBindTransformFeedbackNV := dglGetProcAddress('glBindTransformFeedbackNV');
+ glDeleteTransformFeedbacksNV := dglGetProcAddress('glDeleteTransformFeedbacksNV');
+ glGenTransformFeedbacksNV := dglGetProcAddress('glGenTransformFeedbacksNV');
+ glIsTransformFeedbackNV := dglGetProcAddress('glIsTransformFeedbackNV');
+ glPauseTransformFeedbackNV := dglGetProcAddress('glPauseTransformFeedbackNV');
+ glResumeTransformFeedbackNV := dglGetProcAddress('glResumeTransformFeedbackNV');
+ glDrawTransformFeedbackNV := dglGetProcAddress('glDrawTransformFeedbackNV');
+end;
+
+procedure Read_GL_NV_video_capture;
+begin
+ glBeginVideoCaptureNV := dglGetProcAddress('glBeginVideoCaptureNV');
+ glBindVideoCaptureStreamBufferNV := dglGetProcAddress('glBindVideoCaptureStreamBufferNV');
+ glBindVideoCaptureStreamTextureNV := dglGetProcAddress('glBindVideoCaptureStreamTextureNV');
+ glEndVideoCaptureNV := dglGetProcAddress('glEndVideoCaptureNV');
+ glGetVideoCaptureivNV := dglGetProcAddress('glGetVideoCaptureivNV');
+ glGetVideoCaptureStreamivNV := dglGetProcAddress('glGetVideoCaptureStreamivNV');
+ glGetVideoCaptureStreamfvNV := dglGetProcAddress('glGetVideoCaptureStreamfvNV');
+ glGetVideoCaptureStreamdvNV := dglGetProcAddress('glGetVideoCaptureStreamdvNV');
+ glVideoCaptureNV := dglGetProcAddress('glVideoCaptureNV');
+ glVideoCaptureStreamParameterivNV := dglGetProcAddress('glVideoCaptureStreamParameterivNV');
+ glVideoCaptureStreamParameterfvNV := dglGetProcAddress('glVideoCaptureStreamParameterfvNV');
+ glVideoCaptureStreamParameterdvNV := dglGetProcAddress('glVideoCaptureStreamParameterdvNV');
+end;
+
+procedure Read_GL_NV_copy_image;
+begin
+ glCopyImageSubDataNV := dglGetProcAddress('glCopyImageSubDataNV');
+end;
+
+procedure Read_GL_NV_shader_buffer_load;
+begin
+ glMakeBufferResidentNV := dglGetProcAddress('glMakeBufferResidentNV');
+ glMakeBufferNonResidentNV := dglGetProcAddress('glMakeBufferNonResidentNV');
+ glIsBufferResidentNV := dglGetProcAddress('glIsBufferResidentNV');
+ glMakeNamedBufferResidentNV := dglGetProcAddress('glMakeNamedBufferResidentNV');
+ glMakeNamedBufferNonResidentNV := dglGetProcAddress('glMakeNamedBufferNonResidentNV');
+ glIsNamedBufferResidentNV := dglGetProcAddress('glIsNamedBufferResidentNV');
+ glGetBufferParameterui64vNV := dglGetProcAddress('glGetBufferParameterui64vNV');
+ glGetNamedBufferParameterui64vNV := dglGetProcAddress('glGetNamedBufferParameterui64vNV');
+ glGetIntegerui64vNV := dglGetProcAddress('glGetIntegerui64vNV');
+ glUniformui64NV := dglGetProcAddress('glUniformui64NV');
+ glUniformui64vNV := dglGetProcAddress('glUniformui64vNV');
+ glGetUniformui64vNV := dglGetProcAddress('glGetUniformui64vNV');
+ glProgramUniformui64NV := dglGetProcAddress('glProgramUniformui64NV');
+ glProgramUniformui64vNV := dglGetProcAddress('glProgramUniformui64vNV');
+end;
+
+procedure Read_GL_NV_vertex_buffer_unified_memory;
+begin
+ glBufferAddressRangeNV := dglGetProcAddress('glBufferAddressRangeNV');
+ glVertexFormatNV := dglGetProcAddress('glVertexFormatNV');
+ glNormalFormatNV := dglGetProcAddress('glNormalFormatNV');
+ glColorFormatNV := dglGetProcAddress('glColorFormatNV');
+ glIndexFormatNV := dglGetProcAddress('glIndexFormatNV');
+ glTexCoordFormatNV := dglGetProcAddress('glTexCoordFormatNV');
+ glEdgeFlagFormatNV := dglGetProcAddress('glEdgeFlagFormatNV');
+ glSecondaryColorFormatNV := dglGetProcAddress('glSecondaryColorFormatNV');
+ glFogCoordFormatNV := dglGetProcAddress('glFogCoordFormatNV');
+ glVertexAttribFormatNV := dglGetProcAddress('glVertexAttribFormatNV');
+ glVertexAttribIFormatNV := dglGetProcAddress('glVertexAttribIFormatNV');
+ glGetIntegerui64i_vNV := dglGetProcAddress('glGetIntegerui64i_vNV');
+end;
+
+procedure Read_GL_NV_gpu_program5;
+begin
+ glProgramSubroutineParametersuivNV := dglGetProcAddress('glProgramSubroutineParametersuivNV');
+ glGetProgramSubroutineParameteruivNV := dglGetProcAddress('glGetProgramSubroutineParameteruivNV');
+end;
+
+procedure Read_GL_NV_gpu_shader5;
+begin
+ glUniform1i64NV := dglGetProcAddress('glUniform1i64NV');
+ glUniform2i64NV := dglGetProcAddress('glUniform2i64NV');
+ glUniform3i64NV := dglGetProcAddress('glUniform3i64NV');
+ glUniform4i64NV := dglGetProcAddress('glUniform4i64NV');
+ glUniform1i64vNV := dglGetProcAddress('glUniform1i64vNV');
+ glUniform2i64vNV := dglGetProcAddress('glUniform2i64vNV');
+ glUniform3i64vNV := dglGetProcAddress('glUniform3i64vNV');
+ glUniform4i64vNV := dglGetProcAddress('glUniform4i64vNV');
+ glUniform1ui64NV := dglGetProcAddress('glUniform1ui64NV');
+ glUniform2ui64NV := dglGetProcAddress('glUniform2ui64NV');
+ glUniform3ui64NV := dglGetProcAddress('glUniform3ui64NV');
+ glUniform4ui64NV := dglGetProcAddress('glUniform4ui64NV');
+ glUniform1ui64vNV := dglGetProcAddress('glUniform1ui64vNV');
+ glUniform2ui64vNV := dglGetProcAddress('glUniform2ui64vNV');
+ glUniform3ui64vNV := dglGetProcAddress('glUniform3ui64vNV');
+ glUniform4ui64vNV := dglGetProcAddress('glUniform4ui64vNV');
+ glGetUniformi64vNV := dglGetProcAddress('glGetUniformi64vNV');
+ glProgramUniform1i64NV := dglGetProcAddress('glProgramUniform1i64NV');
+ glProgramUniform2i64NV := dglGetProcAddress('glProgramUniform2i64NV');
+ glProgramUniform3i64NV := dglGetProcAddress('glProgramUniform3i64NV');
+ glProgramUniform4i64NV := dglGetProcAddress('glProgramUniform4i64NV');
+ glProgramUniform1i64vNV := dglGetProcAddress('glProgramUniform1i64vNV');
+ glProgramUniform2i64vNV := dglGetProcAddress('glProgramUniform2i64vNV');
+ glProgramUniform3i64vNV := dglGetProcAddress('glProgramUniform3i64vNV');
+ glProgramUniform4i64vNV := dglGetProcAddress('glProgramUniform4i64vNV');
+ glProgramUniform1ui64NV := dglGetProcAddress('glProgramUniform1ui64NV');
+ glProgramUniform2ui64NV := dglGetProcAddress('glProgramUniform2ui64NV');
+ glProgramUniform3ui64NV := dglGetProcAddress('glProgramUniform3ui64NV');
+ glProgramUniform4ui64NV := dglGetProcAddress('glProgramUniform4ui64NV');
+ glProgramUniform1ui64vNV := dglGetProcAddress('glProgramUniform1ui64vNV');
+ glProgramUniform2ui64vNV := dglGetProcAddress('glProgramUniform2ui64vNV');
+ glProgramUniform3ui64vNV := dglGetProcAddress('glProgramUniform3ui64vNV');
+ glProgramUniform4ui64vNV := dglGetProcAddress('glProgramUniform4ui64vNV');
+end;
+
+procedure Read_GL_NV_vertex_attrib_integer_64bit;
+begin
+ glVertexAttribL1i64NV := dglGetProcAddress('glVertexAttribL1i64NV');
+ glVertexAttribL2i64NV := dglGetProcAddress('glVertexAttribL2i64NV');
+ glVertexAttribL3i64NV := dglGetProcAddress('glVertexAttribL3i64NV');
+ glVertexAttribL4i64NV := dglGetProcAddress('glVertexAttribL4i64NV');
+ glVertexAttribL1i64vNV := dglGetProcAddress('glVertexAttribL1i64vNV');
+ glVertexAttribL2i64vNV := dglGetProcAddress('glVertexAttribL2i64vNV');
+ glVertexAttribL3i64vNV := dglGetProcAddress('glVertexAttribL3i64vNV');
+ glVertexAttribL4i64vNV := dglGetProcAddress('glVertexAttribL4i64vNV');
+ glVertexAttribL1ui64NV := dglGetProcAddress('glVertexAttribL1ui64NV');
+ glVertexAttribL2ui64NV := dglGetProcAddress('glVertexAttribL2ui64NV');
+ glVertexAttribL3ui64NV := dglGetProcAddress('glVertexAttribL3ui64NV');
+ glVertexAttribL4ui64NV := dglGetProcAddress('glVertexAttribL4ui64NV');
+ glVertexAttribL1ui64vNV := dglGetProcAddress('glVertexAttribL1ui64vNV');
+ glVertexAttribL2ui64vNV := dglGetProcAddress('glVertexAttribL2ui64vNV');
+ glVertexAttribL3ui64vNV := dglGetProcAddress('glVertexAttribL3ui64vNV');
+ glVertexAttribL4ui64vNV := dglGetProcAddress('glVertexAttribL4ui64vNV');
+ glGetVertexAttribLi64vNV := dglGetProcAddress('glGetVertexAttribLi64vNV');
+ glGetVertexAttribLui64vNV := dglGetProcAddress('glGetVertexAttribLui64vNV');
+ glVertexAttribLFormatNV := dglGetProcAddress('glVertexAttribLFormatNV');
+end;
+
+procedure Read_GL_NV_vdpau_interop;
+begin
+ glVDPAUInitNV := dglGetProcAddress('glVDPAUInitNV');
+ glVDPAUFiniNV := dglGetProcAddress('glVDPAUFiniNV');
+ glVDPAURegisterVideoSurfaceNV := dglGetProcAddress('glVDPAURegisterVideoSurfaceNV');
+ glVDPAURegisterOutputSurfaceNV := dglGetProcAddress('glVDPAURegisterOutputSurfaceNV');
+ glVDPAUIsSurfaceNV := dglGetProcAddress('glVDPAUIsSurfaceNV');
+ glVDPAUUnregisterSurfaceNV := dglGetProcAddress('glVDPAUUnregisterSurfaceNV');
+ glVDPAUGetSurfaceivNV := dglGetProcAddress('glVDPAUGetSurfaceivNV');
+ glVDPAUSurfaceAccessNV := dglGetProcAddress('glVDPAUSurfaceAccessNV');
+ glVDPAUMapSurfacesNV := dglGetProcAddress('glVDPAUMapSurfacesNV');
+ glVDPAUUnmapSurfacesNV := dglGetProcAddress('glVDPAUUnmapSurfacesNV');
+end;
+
+procedure Read_GL_NV_texture_barrier;
+begin
+ glTextureBarrierNV := dglGetProcAddress('glTextureBarrierNV');
+end;
+
+procedure Read_GL_PGI_misc_hints;
+begin
+ glHintPGI := dglGetProcAddress('glHintPGI');
+end;
+
+procedure Read_GL_OVR_multiview;
+begin
+ glFramebufferTextureMultiviewOVR := dglGetProcAddress('glFramebufferTextureMultiviewOVR');
+end;
+
+procedure Read_GL_SGIS_detail_texture;
+begin
+ glDetailTexFuncSGIS := dglGetProcAddress('glDetailTexFuncSGIS');
+ glGetDetailTexFuncSGIS := dglGetProcAddress('glGetDetailTexFuncSGIS');
+end;
+
+procedure Read_GL_SGIS_fog_function;
+begin
+ glFogFuncSGIS := dglGetProcAddress('glFogFuncSGIS');
+ glGetFogFuncSGIS := dglGetProcAddress('glGetFogFuncSGIS');
+end;
+
+procedure Read_GL_SGIS_multisample;
+begin
+ glSampleMaskSGIS := dglGetProcAddress('glSampleMaskSGIS');
+ glSamplePatternSGIS := dglGetProcAddress('glSamplePatternSGIS');
+end;
+
+procedure Read_GL_SGIS_pixel_texture;
+begin
+ glPixelTexGenParameteriSGIS := dglGetProcAddress('glPixelTexGenParameteriSGIS');
+ glPixelTexGenParameterivSGIS := dglGetProcAddress('glPixelTexGenParameterivSGIS');
+ glPixelTexGenParameterfSGIS := dglGetProcAddress('glPixelTexGenParameterfSGIS');
+ glPixelTexGenParameterfvSGIS := dglGetProcAddress('glPixelTexGenParameterfvSGIS');
+ glGetPixelTexGenParameterivSGIS := dglGetProcAddress('glGetPixelTexGenParameterivSGIS');
+ glGetPixelTexGenParameterfvSGIS := dglGetProcAddress('glGetPixelTexGenParameterfvSGIS');
+end;
+
+procedure Read_GL_SGIS_point_parameters;
+begin
+ glPointParameterfSGIS := dglGetProcAddress('glPointParameterfSGIS');
+ glPointParameterfvSGIS := dglGetProcAddress('glPointParameterfvSGIS');
+end;
+
+procedure Read_GL_SGIS_sharpen_texture;
+begin
+ glSharpenTexFuncSGIS := dglGetProcAddress('glSharpenTexFuncSGIS');
+ glGetSharpenTexFuncSGIS := dglGetProcAddress('glGetSharpenTexFuncSGIS');
+end;
+
+procedure Read_GL_SGIS_texture4D;
+begin
+ glTexImage4DSGIS := dglGetProcAddress('glTexImage4DSGIS');
+ glTexSubImage4DSGIS := dglGetProcAddress('glTexSubImage4DSGIS');
+end;
+
+procedure Read_GL_SGIS_texture_color_mask;
+begin
+ glTextureColorMaskSGIS := dglGetProcAddress('glTextureColorMaskSGIS');
+end;
+
+procedure Read_GL_SGIS_texture_filter4;
+begin
+ glGetTexFilterFuncSGIS := dglGetProcAddress('glGetTexFilterFuncSGIS');
+ glTexFilterFuncSGIS := dglGetProcAddress('glTexFilterFuncSGIS');
+end;
+
+procedure Read_GL_SGIX_async;
+begin
+ glAsyncMarkerSGIX := dglGetProcAddress('glAsyncMarkerSGIX');
+ glFinishAsyncSGIX := dglGetProcAddress('glFinishAsyncSGIX');
+ glPollAsyncSGIX := dglGetProcAddress('glPollAsyncSGIX');
+ glGenAsyncMarkersSGIX := dglGetProcAddress('glGenAsyncMarkersSGIX');
+ glDeleteAsyncMarkersSGIX := dglGetProcAddress('glDeleteAsyncMarkersSGIX');
+ glIsAsyncMarkerSGIX := dglGetProcAddress('glIsAsyncMarkerSGIX');
+end;
+
+procedure Read_GL_SGIX_flush_raster;
+begin
+ glFlushRasterSGIX := dglGetProcAddress('glFlushRasterSGIX');
+end;
+
+procedure Read_GL_SGIX_fragment_lighting;
+begin
+ glFragmentColorMaterialSGIX := dglGetProcAddress('glFragmentColorMaterialSGIX');
+ glFragmentLightfSGIX := dglGetProcAddress('glFragmentLightfSGIX');
+ glFragmentLightfvSGIX := dglGetProcAddress('glFragmentLightfvSGIX');
+ glFragmentLightiSGIX := dglGetProcAddress('glFragmentLightiSGIX');
+ glFragmentLightivSGIX := dglGetProcAddress('glFragmentLightivSGIX');
+ glFragmentLightModelfSGIX := dglGetProcAddress('glFragmentLightModelfSGIX');
+ glFragmentLightModelfvSGIX := dglGetProcAddress('glFragmentLightModelfvSGIX');
+ glFragmentLightModeliSGIX := dglGetProcAddress('glFragmentLightModeliSGIX');
+ glFragmentLightModelivSGIX := dglGetProcAddress('glFragmentLightModelivSGIX');
+ glFragmentMaterialfSGIX := dglGetProcAddress('glFragmentMaterialfSGIX');
+ glFragmentMaterialfvSGIX := dglGetProcAddress('glFragmentMaterialfvSGIX');
+ glFragmentMaterialiSGIX := dglGetProcAddress('glFragmentMaterialiSGIX');
+ glFragmentMaterialivSGIX := dglGetProcAddress('glFragmentMaterialivSGIX');
+ glGetFragmentLightfvSGIX := dglGetProcAddress('glGetFragmentLightfvSGIX');
+ glGetFragmentLightivSGIX := dglGetProcAddress('glGetFragmentLightivSGIX');
+ glGetFragmentMaterialfvSGIX := dglGetProcAddress('glGetFragmentMaterialfvSGIX');
+ glGetFragmentMaterialivSGIX := dglGetProcAddress('glGetFragmentMaterialivSGIX');
+ glLightEnviSGIX := dglGetProcAddress('glLightEnviSGIX');
+end;
+
+procedure Read_GL_SGIX_framezoom;
+begin
+ glFrameZoomSGIX := dglGetProcAddress('glFrameZoomSGIX');
+end;
+
+procedure Read_GL_SGIX_igloo_interface;
+begin
+ glIglooInterfaceSGIX := dglGetProcAddress('glIglooInterfaceSGIX');
+end;
+
+procedure Read_GL_SGIX_instruments;
+begin
+ glGetInstrumentsSGIX := dglGetProcAddress('glGetInstrumentsSGIX');
+ glInstrumentsBufferSGIX := dglGetProcAddress('glInstrumentsBufferSGIX');
+ glPollInstrumentsSGIX := dglGetProcAddress('glPollInstrumentsSGIX');
+ glReadInstrumentsSGIX := dglGetProcAddress('glReadInstrumentsSGIX');
+ glStartInstrumentsSGIX := dglGetProcAddress('glStartInstrumentsSGIX');
+ glStopInstrumentsSGIX := dglGetProcAddress('glStopInstrumentsSGIX');
+end;
+
+procedure Read_GL_SGIX_list_priority;
+begin
+ glGetListParameterfvSGIX := dglGetProcAddress('glGetListParameterfvSGIX');
+ glGetListParameterivSGIX := dglGetProcAddress('glGetListParameterivSGIX');
+ glListParameterfSGIX := dglGetProcAddress('glListParameterfSGIX');
+ glListParameterfvSGIX := dglGetProcAddress('glListParameterfvSGIX');
+ glListParameteriSGIX := dglGetProcAddress('glListParameteriSGIX');
+ glListParameterivSGIX := dglGetProcAddress('glListParameterivSGIX');
+end;
+
+procedure Read_GL_SGIX_pixel_texture;
+begin
+ glPixelTexGenSGIX := dglGetProcAddress('glPixelTexGenSGIX');
+end;
+
+procedure Read_GL_SGIX_polynomial_ffd;
+begin
+ glDeformationMap3dSGIX := dglGetProcAddress('glDeformationMap3dSGIX');
+ glDeformationMap3fSGIX := dglGetProcAddress('glDeformationMap3fSGIX');
+ glDeformSGIX := dglGetProcAddress('glDeformSGIX');
+ glLoadIdentityDeformationMapSGIX := dglGetProcAddress('glLoadIdentityDeformationMapSGIX');
+end;
+
+procedure Read_GL_SGIX_reference_plane;
+begin
+ glReferencePlaneSGIX := dglGetProcAddress('glReferencePlaneSGIX');
+end;
+
+procedure Read_GL_SGIX_sprite;
+begin
+ glSpriteParameterfSGIX := dglGetProcAddress('glSpriteParameterfSGIX');
+ glSpriteParameterfvSGIX := dglGetProcAddress('glSpriteParameterfvSGIX');
+ glSpriteParameteriSGIX := dglGetProcAddress('glSpriteParameteriSGIX');
+ glSpriteParameterivSGIX := dglGetProcAddress('glSpriteParameterivSGIX');
+end;
+
+procedure Read_GL_SGIX_tag_sample_buffer;
+begin
+ glTagSampleBufferSGIX := dglGetProcAddress('glTagSampleBufferSGIX');
+end;
+
+procedure Read_GL_SGI_color_table;
+begin
+ glColorTableSGI := dglGetProcAddress('glColorTableSGI');
+ glColorTableParameterfvSGI := dglGetProcAddress('glColorTableParameterfvSGI');
+ glColorTableParameterivSGI := dglGetProcAddress('glColorTableParameterivSGI');
+ glCopyColorTableSGI := dglGetProcAddress('glCopyColorTableSGI');
+ glGetColorTableSGI := dglGetProcAddress('glGetColorTableSGI');
+ glGetColorTableParameterfvSGI := dglGetProcAddress('glGetColorTableParameterfvSGI');
+ glGetColorTableParameterivSGI := dglGetProcAddress('glGetColorTableParameterivSGI');
+end;
+
+procedure Read_GL_SUNX_constant_data;
+begin
+ glFinishTextureSUNX := dglGetProcAddress('glFinishTextureSUNX');
+end;
+
+procedure Read_GL_SUN_global_alpha;
+begin
+ glGlobalAlphaFactorbSUN := dglGetProcAddress('glGlobalAlphaFactorbSUN');
+ glGlobalAlphaFactorsSUN := dglGetProcAddress('glGlobalAlphaFactorsSUN');
+ glGlobalAlphaFactoriSUN := dglGetProcAddress('glGlobalAlphaFactoriSUN');
+ glGlobalAlphaFactorfSUN := dglGetProcAddress('glGlobalAlphaFactorfSUN');
+ glGlobalAlphaFactordSUN := dglGetProcAddress('glGlobalAlphaFactordSUN');
+ glGlobalAlphaFactorubSUN := dglGetProcAddress('glGlobalAlphaFactorubSUN');
+ glGlobalAlphaFactorusSUN := dglGetProcAddress('glGlobalAlphaFactorusSUN');
+ glGlobalAlphaFactoruiSUN := dglGetProcAddress('glGlobalAlphaFactoruiSUN');
+end;
+
+procedure Read_GL_SUN_mesh_array;
+begin
+ glDrawMeshArraysSUN := dglGetProcAddress('glDrawMeshArraysSUN');
+end;
+
+procedure Read_GL_SUN_triangle_list;
+begin
+ glReplacementCodeuiSUN := dglGetProcAddress('glReplacementCodeuiSUN');
+ glReplacementCodeusSUN := dglGetProcAddress('glReplacementCodeusSUN');
+ glReplacementCodeubSUN := dglGetProcAddress('glReplacementCodeubSUN');
+ glReplacementCodeuivSUN := dglGetProcAddress('glReplacementCodeuivSUN');
+ glReplacementCodeusvSUN := dglGetProcAddress('glReplacementCodeusvSUN');
+ glReplacementCodeubvSUN := dglGetProcAddress('glReplacementCodeubvSUN');
+ glReplacementCodePointerSUN := dglGetProcAddress('glReplacementCodePointerSUN');
+end;
+
+procedure Read_GL_SUN_vertex;
+begin
+ glColor4ubVertex2fSUN := dglGetProcAddress('glColor4ubVertex2fSUN');
+ glColor4ubVertex2fvSUN := dglGetProcAddress('glColor4ubVertex2fvSUN');
+ glColor4ubVertex3fSUN := dglGetProcAddress('glColor4ubVertex3fSUN');
+ glColor4ubVertex3fvSUN := dglGetProcAddress('glColor4ubVertex3fvSUN');
+ glColor3fVertex3fSUN := dglGetProcAddress('glColor3fVertex3fSUN');
+ glColor3fVertex3fvSUN := dglGetProcAddress('glColor3fVertex3fvSUN');
+ glNormal3fVertex3fSUN := dglGetProcAddress('glNormal3fVertex3fSUN');
+ glNormal3fVertex3fvSUN := dglGetProcAddress('glNormal3fVertex3fvSUN');
+ glColor4fNormal3fVertex3fSUN := dglGetProcAddress('glColor4fNormal3fVertex3fSUN');
+ glColor4fNormal3fVertex3fvSUN := dglGetProcAddress('glColor4fNormal3fVertex3fvSUN');
+ glTexCoord2fVertex3fSUN := dglGetProcAddress('glTexCoord2fVertex3fSUN');
+ glTexCoord2fVertex3fvSUN := dglGetProcAddress('glTexCoord2fVertex3fvSUN');
+ glTexCoord4fVertex4fSUN := dglGetProcAddress('glTexCoord4fVertex4fSUN');
+ glTexCoord4fVertex4fvSUN := dglGetProcAddress('glTexCoord4fVertex4fvSUN');
+ glTexCoord2fColor4ubVertex3fSUN := dglGetProcAddress('glTexCoord2fColor4ubVertex3fSUN');
+ glTexCoord2fColor4ubVertex3fvSUN := dglGetProcAddress('glTexCoord2fColor4ubVertex3fvSUN');
+ glTexCoord2fColor3fVertex3fSUN := dglGetProcAddress('glTexCoord2fColor3fVertex3fSUN');
+ glTexCoord2fColor3fVertex3fvSUN := dglGetProcAddress('glTexCoord2fColor3fVertex3fvSUN');
+ glTexCoord2fNormal3fVertex3fSUN := dglGetProcAddress('glTexCoord2fNormal3fVertex3fSUN');
+ glTexCoord2fNormal3fVertex3fvSUN := dglGetProcAddress('glTexCoord2fNormal3fVertex3fvSUN');
+ glTexCoord2fColor4fNormal3fVertex3fSUN := dglGetProcAddress('glTexCoord2fColor4fNormal3fVertex3fSUN');
+ glTexCoord2fColor4fNormal3fVertex3fvSUN := dglGetProcAddress('glTexCoord2fColor4fNormal3fVertex3fvSUN');
+ glTexCoord4fColor4fNormal3fVertex4fSUN := dglGetProcAddress('glTexCoord4fColor4fNormal3fVertex4fSUN');
+ glTexCoord4fColor4fNormal3fVertex4fvSUN := dglGetProcAddress('glTexCoord4fColor4fNormal3fVertex4fvSUN');
+ glReplacementCodeuiVertex3fSUN := dglGetProcAddress('glReplacementCodeuiVertex3fSUN');
+ glReplacementCodeuiVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiVertex3fvSUN');
+ glReplacementCodeuiColor4ubVertex3fSUN := dglGetProcAddress('glReplacementCodeuiColor4ubVertex3fSUN');
+ glReplacementCodeuiColor4ubVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiColor4ubVertex3fvSUN');
+ glReplacementCodeuiColor3fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiColor3fVertex3fSUN');
+ glReplacementCodeuiColor3fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiColor3fVertex3fvSUN');
+ glReplacementCodeuiNormal3fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiNormal3fVertex3fSUN');
+ glReplacementCodeuiNormal3fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiNormal3fVertex3fvSUN');
+ glReplacementCodeuiColor4fNormal3fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fSUN');
+ glReplacementCodeuiColor4fNormal3fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiColor4fNormal3fVertex3fvSUN');
+ glReplacementCodeuiTexCoord2fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fVertex3fSUN');
+ glReplacementCodeuiTexCoord2fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fVertex3fvSUN');
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN');
+ glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN');
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN');
+ glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN := dglGetProcAddress('glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN');
+end;
+
+{$IFDEF DGL_WIN}
+procedure Read_WGL_ARB_buffer_region;
+begin
+ wglCreateBufferRegionARB := dglGetProcAddress('wglCreateBufferRegionARB');
+ wglDeleteBufferRegionARB := dglGetProcAddress('wglDeleteBufferRegionARB');
+ wglSaveBufferRegionARB := dglGetProcAddress('wglSaveBufferRegionARB');
+ wglRestoreBufferRegionARB := dglGetProcAddress('wglRestoreBufferRegionARB');
+end;
+
+procedure Read_WGL_ARB_extensions_string;
+begin
+ wglGetExtensionsStringARB := dglGetProcAddress('wglGetExtensionsStringARB');
+end;
+
+procedure Read_WGL_ARB_make_current_read;
+begin
+ wglMakeContextCurrentARB := dglGetProcAddress('wglMakeContextCurrentARB');
+ wglGetCurrentReadDCARB := dglGetProcAddress('wglGetCurrentReadDCARB');
+end;
+
+procedure Read_WGL_ARB_pbuffer;
+begin
+ wglCreatePbufferARB := dglGetProcAddress('wglCreatePbufferARB');
+ wglGetPbufferDCARB := dglGetProcAddress('wglGetPbufferDCARB');
+ wglReleasePbufferDCARB := dglGetProcAddress('wglReleasePbufferDCARB');
+ wglDestroyPbufferARB := dglGetProcAddress('wglDestroyPbufferARB');
+ wglQueryPbufferARB := dglGetProcAddress('wglQueryPbufferARB');
+end;
+
+procedure Read_WGL_ARB_pixel_format;
+begin
+ wglGetPixelFormatAttribivARB := dglGetProcAddress('wglGetPixelFormatAttribivARB');
+ wglGetPixelFormatAttribfvARB := dglGetProcAddress('wglGetPixelFormatAttribfvARB');
+ wglChoosePixelFormatARB := dglGetProcAddress('wglChoosePixelFormatARB');
+end;
+
+procedure Read_WGL_ARB_pixel_format_float;
+begin
+ wglClampColorARB := dglGetProcAddress('wglClampColorARB');
+end;
+
+procedure Read_WGL_ARB_render_texture;
+begin
+ wglBindTexImageARB := dglGetProcAddress('wglBindTexImageARB');
+ wglReleaseTexImageARB := dglGetProcAddress('wglReleaseTexImageARB');
+ wglSetPbufferAttribARB := dglGetProcAddress('wglSetPbufferAttribARB');
+end;
+
+procedure Read_WGL_ARB_create_context;
+begin
+ wglCreateContextAttribsARB := dglGetProcAddress('wglCreateContextAttribsARB');
+end;
+
+procedure Read_WGL_AMD_gpu_association;
+begin
+ wglGetGPUIDsAMD := dglGetProcAddress('wglGetGPUIDsAMD');
+ wglGetGPUInfoAMD := dglGetProcAddress('wglGetGPUInfoAMD');
+ wglGetContextGPUIDAMD := dglGetProcAddress('wglGetContextGPUIDAMD');
+ wglCreateAssociatedContextAMD := dglGetProcAddress('wglCreateAssociatedContextAMD');
+ wglCreateAssociatedContextAttribsAMD := dglGetProcAddress('wglCreateAssociatedContextAttribsAMD');
+ wglDeleteAssociatedContextAMD := dglGetProcAddress('wglDeleteAssociatedContextAMD');
+ wglMakeAssociatedContextCurrentAMD := dglGetProcAddress('wglMakeAssociatedContextCurrentAMD');
+ wglGetCurrentAssociatedContextAMD := dglGetProcAddress('wglGetCurrentAssociatedContextAMD');
+ wglBlitContextFramebufferAMD := dglGetProcAddress('wglBlitContextFramebufferAMD');
+end;
+
+procedure Read_WGL_EXT_display_color_table;
+begin
+ wglCreateDisplayColorTableEXT := dglGetProcAddress('wglCreateDisplayColorTableEXT');
+ wglLoadDisplayColorTableEXT := dglGetProcAddress('wglLoadDisplayColorTableEXT');
+ wglBindDisplayColorTableEXT := dglGetProcAddress('wglBindDisplayColorTableEXT');
+ wglDestroyDisplayColorTableEXT := dglGetProcAddress('wglDestroyDisplayColorTableEXT');
+end;
+
+procedure Read_WGL_EXT_extensions_string;
+begin
+ wglGetExtensionsStringEXT := dglGetProcAddress('wglGetExtensionsStringEXT');
+end;
+
+procedure Read_WGL_EXT_make_current_read;
+begin
+ wglMakeContextCurrentEXT := dglGetProcAddress('wglMakeContextCurrentEXT');
+ wglGetCurrentReadDCEXT := dglGetProcAddress('wglGetCurrentReadDCEXT');
+end;
+
+procedure Read_WGL_EXT_pbuffer;
+begin
+ wglCreatePbufferEXT := dglGetProcAddress('wglCreatePbufferEXT');
+ wglGetPbufferDCEXT := dglGetProcAddress('wglGetPbufferDCEXT');
+ wglReleasePbufferDCEXT := dglGetProcAddress('wglReleasePbufferDCEXT');
+ wglDestroyPbufferEXT := dglGetProcAddress('wglDestroyPbufferEXT');
+ wglQueryPbufferEXT := dglGetProcAddress('wglQueryPbufferEXT');
+end;
+
+procedure Read_WGL_EXT_pixel_format;
+begin
+ wglGetPixelFormatAttribivEXT := dglGetProcAddress('wglGetPixelFormatAttribivEXT');
+ wglGetPixelFormatAttribfvEXT := dglGetProcAddress('wglGetPixelFormatAttribfvEXT');
+ wglChoosePixelFormatEXT := dglGetProcAddress('wglChoosePixelFormatEXT');
+end;
+
+procedure Read_WGL_EXT_swap_control;
+begin
+ wglSwapIntervalEXT := dglGetProcAddress('wglSwapIntervalEXT');
+ wglGetSwapIntervalEXT := dglGetProcAddress('wglGetSwapIntervalEXT');
+end;
+
+procedure Read_WGL_I3D_digital_video_control;
+begin
+ wglGetDigitalVideoParametersI3D := dglGetProcAddress('wglGetDigitalVideoParametersI3D');
+ wglSetDigitalVideoParametersI3D := dglGetProcAddress('wglSetDigitalVideoParametersI3D');
+end;
+
+procedure Read_WGL_I3D_gamma;
+begin
+ wglGetGammaTableParametersI3D := dglGetProcAddress('wglGetGammaTableParametersI3D');
+ wglSetGammaTableParametersI3D := dglGetProcAddress('wglSetGammaTableParametersI3D');
+ wglGetGammaTableI3D := dglGetProcAddress('wglGetGammaTableI3D');
+ wglSetGammaTableI3D := dglGetProcAddress('wglSetGammaTableI3D');
+end;
+
+procedure Read_WGL_I3D_genlock;
+begin
+ wglEnableGenlockI3D := dglGetProcAddress('wglEnableGenlockI3D');
+ wglDisableGenlockI3D := dglGetProcAddress('wglDisableGenlockI3D');
+ wglIsEnabledGenlockI3D := dglGetProcAddress('wglIsEnabledGenlockI3D');
+ wglGenlockSourceI3D := dglGetProcAddress('wglGenlockSourceI3D');
+ wglGetGenlockSourceI3D := dglGetProcAddress('wglGetGenlockSourceI3D');
+ wglGenlockSourceEdgeI3D := dglGetProcAddress('wglGenlockSourceEdgeI3D');
+ wglGetGenlockSourceEdgeI3D := dglGetProcAddress('wglGetGenlockSourceEdgeI3D');
+ wglGenlockSampleRateI3D := dglGetProcAddress('wglGenlockSampleRateI3D');
+ wglGetGenlockSampleRateI3D := dglGetProcAddress('wglGetGenlockSampleRateI3D');
+ wglGenlockSourceDelayI3D := dglGetProcAddress('wglGenlockSourceDelayI3D');
+ wglGetGenlockSourceDelayI3D := dglGetProcAddress('wglGetGenlockSourceDelayI3D');
+ wglQueryGenlockMaxSourceDelayI3D := dglGetProcAddress('wglQueryGenlockMaxSourceDelayI3D');
+end;
+
+procedure Read_WGL_I3D_image_buffer;
+begin
+ wglCreateImageBufferI3D := dglGetProcAddress('wglCreateImageBufferI3D');
+ wglDestroyImageBufferI3D := dglGetProcAddress('wglDestroyImageBufferI3D');
+ wglAssociateImageBufferEventsI3D := dglGetProcAddress('wglAssociateImageBufferEventsI3D');
+ wglReleaseImageBufferEventsI3D := dglGetProcAddress('wglReleaseImageBufferEventsI3D');
+end;
+
+procedure Read_WGL_I3D_swap_frame_lock;
+begin
+ wglEnableFrameLockI3D := dglGetProcAddress('wglEnableFrameLockI3D');
+ wglDisableFrameLockI3D := dglGetProcAddress('wglDisableFrameLockI3D');
+ wglIsEnabledFrameLockI3D := dglGetProcAddress('wglIsEnabledFrameLockI3D');
+ wglQueryFrameLockMasterI3D := dglGetProcAddress('wglQueryFrameLockMasterI3D');
+end;
+
+procedure Read_WGL_I3D_swap_frame_usage;
+begin
+ wglGetFrameUsageI3D := dglGetProcAddress('wglGetFrameUsageI3D');
+ wglBeginFrameTrackingI3D := dglGetProcAddress('wglBeginFrameTrackingI3D');
+ wglEndFrameTrackingI3D := dglGetProcAddress('wglEndFrameTrackingI3D');
+ wglQueryFrameTrackingI3D := dglGetProcAddress('wglQueryFrameTrackingI3D');
+end;
+
+procedure Read_WGL_NV_vertex_array_range;
+begin
+ wglAllocateMemoryNV := dglGetProcAddress('wglAllocateMemoryNV');
+ wglFreeMemoryNV := dglGetProcAddress('wglFreeMemoryNV');
+end;
+
+procedure Read_WGL_NV_present_video;
+begin
+ wglEnumerateVideoDevicesNV := dglGetProcAddress('wglEnumerateVideoDevicesNV');
+ wglBindVideoDeviceNV := dglGetProcAddress('wglBindVideoDeviceNV');
+ wglQueryCurrentContextNV := dglGetProcAddress('wglQueryCurrentContextNV');
+end;
+
+procedure Read_WGL_NV_video_output;
+begin
+ wglGetVideoDeviceNV := dglGetProcAddress('wglGetVideoDeviceNV');
+ wglReleaseVideoDeviceNV := dglGetProcAddress('wglReleaseVideoDeviceNV');
+ wglBindVideoImageNV := dglGetProcAddress('wglBindVideoImageNV');
+ wglReleaseVideoImageNV := dglGetProcAddress('wglReleaseVideoImageNV');
+ wglSendPbufferToVideoNV := dglGetProcAddress('wglSendPbufferToVideoNV');
+ wglGetVideoInfoNV := dglGetProcAddress('wglGetVideoInfoNV');
+end;
+
+procedure Read_WGL_NV_swap_group;
+begin
+ wglJoinSwapGroupNV := dglGetProcAddress('wglJoinSwapGroupNV');
+ wglBindSwapBarrierNV := dglGetProcAddress('wglBindSwapBarrierNV');
+ wglQuerySwapGroupNV := dglGetProcAddress('wglQuerySwapGroupNV');
+ wglQueryMaxSwapGroupsNV := dglGetProcAddress('wglQueryMaxSwapGroupsNV');
+ wglQueryFrameCountNV := dglGetProcAddress('wglQueryFrameCountNV');
+ wglResetFrameCountNV := dglGetProcAddress('wglResetFrameCountNV');
+end;
+
+procedure Read_WGL_NV_gpu_affinity;
+begin
+ wglEnumGpusNV := dglGetProcAddress('wglEnumGpusNV');
+ wglEnumGpuDevicesNV := dglGetProcAddress('wglEnumGpuDevicesNV');
+ wglCreateAffinityDCNV := dglGetProcAddress('wglCreateAffinityDCNV');
+ wglEnumGpusFromAffinityDCNV := dglGetProcAddress('wglEnumGpusFromAffinityDCNV');
+ wglDeleteDCNV := dglGetProcAddress('wglDeleteDCNV');
+end;
+
+procedure Read_WGL_NV_video_capture;
+begin
+ wglBindVideoCaptureDeviceNV := dglGetProcAddress('wglBindVideoCaptureDeviceNV');
+ wglEnumerateVideoCaptureDevicesNV := dglGetProcAddress('wglEnumerateVideoCaptureDevicesNV');
+ wglLockVideoCaptureDeviceNV := dglGetProcAddress('wglLockVideoCaptureDeviceNV');
+ wglQueryVideoCaptureDeviceNV := dglGetProcAddress('wglQueryVideoCaptureDeviceNV');
+ wglReleaseVideoCaptureDeviceNV := dglGetProcAddress('wglReleaseVideoCaptureDeviceNV');
+end;
+
+procedure Read_WGL_NV_copy_image;
+begin
+ wglCopyImageSubDataNV := dglGetProcAddress('wglCopyImageSubDataNV');
+end;
+
+procedure Read_WGL_NV_DX_interop;
+begin
+ wglDXSetResourceShareHandleNV := dglGetProcAddress('wglDXSetResourceShareHandleNV');
+ wglDXOpenDeviceNV := dglGetProcAddress('wglDXOpenDeviceNV');
+ wglDXCloseDeviceNV := dglGetProcAddress('wglDXCloseDeviceNV');
+ wglDXRegisterObjectNV := dglGetProcAddress('wglDXRegisterObjectNV');
+ wglDXUnregisterObjectNV := dglGetProcAddress('wglDXUnregisterObjectNV');
+ wglDXObjectAccessNV := dglGetProcAddress('wglDXObjectAccessNV');
+ wglDXLockObjectsNV := dglGetProcAddress('wglDXLockObjectsNV');
+ wglDXUnlockObjectsNV := dglGetProcAddress('wglDXUnlockObjectsNV');
+end;
+
+
+procedure Read_WGL_OML_sync_control;
+begin
+ wglGetSyncValuesOML := dglGetProcAddress('wglGetSyncValuesOML');
+ wglGetMscRateOML := dglGetProcAddress('wglGetMscRateOML');
+ wglSwapBuffersMscOML := dglGetProcAddress('wglSwapBuffersMscOML');
+ wglSwapLayerBuffersMscOML := dglGetProcAddress('wglSwapLayerBuffersMscOML');
+ wglWaitForMscOML := dglGetProcAddress('wglWaitForMscOML');
+ wglWaitForSbcOML := dglGetProcAddress('wglWaitForSbcOML');
+end;
+
+procedure Read_WGL_3DL_stereo_control;
+begin
+ wglSetStereoEmitterState3DL := dglGetProcAddress('wglSetStereoEmitterState3DL');
+end;
+
+procedure Read_WIN_draw_range_elements;
+begin
+ glDrawRangeElementsWIN := dglGetProcAddress('glDrawRangeElementsWIN');
+end;
+
+procedure Read_WIN_swap_hint;
+begin
+ glAddSwapHintRectWIN := dglGetProcAddress('glAddSwapHintRectWIN');
+end;
+{$ENDIF}
+
+
+procedure ReadExtensions;
+begin
+ ReadOpenGLCore;
+
+ // ARB
+ Read_GL_ARB_matrix_palette;
+ Read_GL_ARB_multitexture;
+ Read_GL_ARB_point_parameters;
+ Read_GL_ARB_texture_compression;
+ Read_GL_ARB_transpose_matrix;
+ Read_GL_ARB_vertex_blend;
+ Read_GL_ARB_vertex_buffer_object;
+ Read_GL_ARB_vertex_program;
+ Read_GL_ARB_window_pos;
+ Read_GL_ARB_color_buffer_float;
+ Read_GL_ARB_Shader_Objects;
+ Read_GL_ARB_occlusion_query;
+ Read_GL_ARB_draw_instanced;
+ Read_GL_ARB_framebuffer_object;
+ Read_GL_ARB_geometry_shader4;
+ Read_GL_ARB_gl_spirv;
+ Read_GL_ARB_gpu_shader_int64;
+ Read_GL_ARB_instanced_arrays;
+ Read_GL_ARB_map_buffer_range;
+ Read_GL_ARB_texture_buffer_object;
+ Read_GL_ARB_vertex_array_object;
+ Read_GL_ARB_uniform_buffer_object;
+ Read_GL_ARB_copy_buffer;
+ Read_GL_ARB_draw_elements_base_vertex;
+ Read_GL_ARB_provoking_vertex;
+ Read_GL_ARB_sync;
+ Read_GL_ARB_texture_multisample;
+ Read_GL_ARB_draw_buffers_blend;
+ Read_GL_ARB_sample_shading;
+ Read_GL_ARB_sample_locations;
+ Read_GL_ARB_shading_language_include;
+ Read_GL_ARB_sparse_texture;
+ Read_GL_ARB_sparse_buffer;
+ Read_GL_ARB_blend_func_extended;
+ Read_GL_ARB_sampler_objects;
+ Read_GL_ARB_timer_query;
+ Read_GL_ARB_vertex_type_2_10_10_10_rev;
+ Read_GL_ARB_draw_indirect;
+ Read_GL_ARB_gpu_shader_fp64;
+ Read_GL_ARB_shader_subroutine;
+ Read_GL_ARB_tessellation_shader;
+ Read_GL_ARB_transform_feedback2;
+ Read_GL_ARB_transform_feedback3;
+ Read_GL_ARB_get_program_binary;
+ Read_GL_ARB_separate_shader_objects;
+ Read_GL_ARB_vertex_attrib_64bit;
+ Read_GL_ARB_viewport_array;
+ Read_GL_ARB_cl_event;
+ Read_GL_ARB_compute_variable_group_size;
+ Read_GL_ARB_debug_output;
+ Read_GL_ARB_robustness;
+ Read_GL_ARB_ES2_compatibility;
+ Read_GL_ARB_ES3_2_compatibility;
+ Read_GL_ARB_parallel_shader_compile;
+ Read_GL_ARB_bindless_texture;
+
+ // Vendor
+ Read_GL_3DFX_tbuffer;
+ Read_GL_APPLE_element_array;
+ Read_GL_APPLE_fence;
+ Read_GL_APPLE_vertex_array_object;
+ Read_GL_APPLE_vertex_array_range;
+ Read_GL_APPLE_texture_range;
+ Read_GL_APPLE_vertex_program_evaluators;
+ Read_GL_APPLE_object_purgeable;
+ Read_GL_ATI_draw_buffers;
+ Read_GL_ATI_element_array;
+ Read_GL_ATI_envmap_bumpmap;
+ Read_GL_ATI_fragment_shader;
+ Read_GL_ATI_map_object_buffer;
+ Read_GL_ATI_pn_triangles;
+ Read_GL_ATI_separate_stencil;
+ Read_GL_ATI_vertex_array_object;
+ Read_GL_ATI_vertex_attrib_array_object;
+ Read_GL_ATI_vertex_streams;
+ Read_GL_AMD_performance_monitor;
+ Read_GL_AMD_vertex_shader_tesselator;
+ Read_GL_AMD_draw_buffers_blend;
+ Read_GL_AMD_name_gen_delete;
+ Read_GL_AMD_debug_output;
+ Read_GL_AMD_stencil_operation_extended;
+ Read_GL_EXT_blend_color;
+ Read_GL_EXT_blend_func_separate;
+ Read_GL_EXT_blend_minmax;
+ Read_GL_EXT_color_subtable;
+ Read_GL_EXT_compiled_vertex_array;
+ Read_GL_EXT_convolution;
+ Read_GL_EXT_coordinate_frame;
+ Read_GL_EXT_copy_texture;
+ Read_GL_EXT_cull_vertex;
+ Read_GL_EXT_draw_range_elements;
+ Read_GL_EXT_fog_coord;
+ Read_GL_EXT_framebuffer_object;
+ Read_GL_EXT_histogram;
+ Read_GL_EXT_index_func;
+ Read_GL_EXT_index_material;
+ Read_GL_EXT_multi_draw_arrays;
+ Read_GL_EXT_multisample;
+ Read_GL_EXT_paletted_texture;
+ Read_GL_EXT_pixel_transform;
+ Read_GL_EXT_point_parameters;
+ Read_GL_EXT_polygon_offset;
+ Read_GL_EXT_secondary_color;
+ Read_GL_EXT_stencil_two_side;
+ Read_GL_EXT_subtexture;
+ Read_GL_EXT_texture3D;
+ Read_GL_EXT_texture_object;
+ Read_GL_EXT_texture_perturb_normal;
+ Read_GL_EXT_vertex_array;
+ Read_GL_EXT_vertex_shader;
+ Read_GL_EXT_vertex_weighting;
+ Read_GL_EXT_depth_bounds_test;
+ Read_GL_EXT_blend_equation_separate;
+ Read_GL_EXT_stencil_clear_tag;
+ Read_GL_EXT_framebuffer_blit;
+ Read_GL_EXT_framebuffer_multisample;
+ Read_GL_EXT_timer_query;
+ Read_GL_EXT_gpu_program_parameters;
+ Read_GL_EXT_bindable_uniform;
+ Read_GL_EXT_draw_buffers2;
+ Read_GL_EXT_draw_instanced;
+ Read_GL_EXT_geometry_shader4;
+ Read_GL_EXT_gpu_shader4;
+ Read_GL_EXT_texture_array;
+ Read_GL_EXT_texture_buffer_object;
+ Read_GL_EXT_texture_integer;
+ Read_GL_EXT_transform_feedback;
+ Read_GL_EXT_direct_state_access;
+ Read_GL_EXT_separate_shader_objects;
+ Read_GL_EXT_shader_image_load_store;
+ Read_GL_EXT_vertex_attrib_64bit;
+ Read_GL_HP_image_transform;
+ Read_GL_IBM_multimode_draw_arrays;
+ Read_GL_IBM_vertex_array_lists;
+ Read_GL_INGR_blend_func_separate;
+ Read_GL_INTEL_parallel_arrays;
+ Read_GL_INTEL_framebuffer_CMAA;
+ Read_GL_KHR_blend_equation_advanced;
+ Read_GL_MESA_resize_buffers;
+ Read_GL_MESA_window_pos;
+ Read_GL_NV_evaluators;
+ Read_GL_NV_fence;
+ Read_GL_NV_fragment_program;
+ Read_GL_NV_half_float;
+ Read_GL_NV_occlusion_query;
+ Read_GL_NV_pixel_data_range;
+ Read_GL_NV_point_sprite;
+ Read_GL_NV_primitive_restart;
+ Read_GL_NV_register_combiners;
+ Read_GL_NV_register_combiners2;
+ Read_GL_NV_vertex_array_range;
+ Read_GL_NV_vertex_program;
+ Read_GL_NV_depth_buffer_float;
+ Read_GL_NV_framebuffer_multisample_coverage;
+ Read_GL_NV_geometry_program4;
+ Read_GL_NV_gpu_program4;
+ Read_GL_NV_parameter_buffer_object;
+ Read_GL_NV_transform_feedback;
+ Read_GL_NV_conditional_render;
+ Read_GL_NV_conservative_raster;
+ Read_GL_NV_conservative_raster_dilate;
+ Read_GL_NV_present_video;
+ Read_GL_NV_explicit_multisample;
+ Read_GL_NV_transform_feedback2;
+ Read_GL_NV_video_capture;
+ Read_GL_NV_copy_image;
+ Read_GL_NV_shader_buffer_load;
+ Read_GL_NV_vertex_buffer_unified_memory;
+ Read_GL_NV_gpu_program5;
+ Read_GL_NV_gpu_shader5;
+ Read_GL_NV_vertex_attrib_integer_64bit;
+ Read_GL_NV_vdpau_interop;
+ Read_GL_NV_texture_barrier;
+ Read_GL_NV_path_rendering;
+ Read_GL_NV_bindless_texture;
+ Read_GL_PGI_misc_hints;
+ Read_GL_OVR_multiview;
+ Read_GL_SGIS_detail_texture;
+ Read_GL_SGIS_fog_function;
+ Read_GL_SGIS_multisample;
+ Read_GL_SGIS_pixel_texture;
+ Read_GL_SGIS_point_parameters;
+ Read_GL_SGIS_sharpen_texture;
+ Read_GL_SGIS_texture4D;
+ Read_GL_SGIS_texture_color_mask;
+ Read_GL_SGIS_texture_filter4;
+ Read_GL_SGIX_async;
+ Read_GL_SGIX_flush_raster;
+ Read_GL_SGIX_fragment_lighting;
+ Read_GL_SGIX_framezoom;
+ Read_GL_SGIX_igloo_interface;
+ Read_GL_SGIX_instruments;
+ Read_GL_SGIX_list_priority;
+ Read_GL_SGIX_pixel_texture;
+ Read_GL_SGIX_polynomial_ffd;
+ Read_GL_SGIX_reference_plane;
+ Read_GL_SGIX_sprite;
+ Read_GL_SGIX_tag_sample_buffer;
+ Read_GL_SGI_color_table;
+ Read_GL_SUNX_constant_data;
+ Read_GL_SUN_global_alpha;
+ Read_GL_SUN_mesh_array;
+ Read_GL_SUN_triangle_list;
+ Read_GL_SUN_vertex;
+{$IFDEF DGL_WIN}
+ Read_WGL_ARB_buffer_region;
+ Read_WGL_ARB_extensions_string;
+ Read_WGL_ARB_make_current_read;
+ Read_WGL_ARB_pbuffer;
+ Read_WGL_ARB_pixel_format;
+ Read_WGL_ARB_pixel_format_float;
+ Read_WGL_ARB_render_texture;
+ Read_WGL_ARB_create_context;
+ Read_WGL_AMD_gpu_association;
+ Read_WGL_EXT_display_color_table;
+ Read_WGL_EXT_extensions_string;
+ Read_WGL_EXT_make_current_read;
+ Read_WGL_EXT_pbuffer;
+ Read_WGL_EXT_pixel_format;
+ Read_WGL_EXT_swap_control;
+ Read_WGL_I3D_digital_video_control;
+ Read_WGL_I3D_gamma;
+ Read_WGL_I3D_genlock;
+ Read_WGL_I3D_image_buffer;
+ Read_WGL_I3D_swap_frame_lock;
+ Read_WGL_I3D_swap_frame_usage;
+ Read_WGL_NV_vertex_array_range;
+ Read_WGL_NV_present_video;
+ Read_WGL_NV_video_output;
+ Read_WGL_NV_swap_group;
+ Read_WGL_NV_gpu_affinity;
+ Read_WGL_NV_video_capture;
+ Read_WGL_NV_copy_image;
+ Read_WGL_NV_DX_interop;
+ Read_WGL_OML_sync_control;
+ Read_WGL_3DL_stereo_control;
+
+ Read_WIN_draw_range_elements;
+ Read_WIN_swap_hint;
+{$ENDIF}
+
+ ExtensionsRead := True;
+end;
+
+// =============================================================================
+// ReadCoreVersion
+// =============================================================================
+
+procedure ReadCoreVersion;
+var
+ AnsiBuffer: AnsiString;
+ Buffer: String;
+ MajorVersion, MinorVersion: Integer;
+
+ procedure TrimAndSplitVersionString(Buffer: String; var Max, Min: Integer);
+ // Peels out the X.Y form from the given Buffer which must contain a version string like "text Minor.Major.Build text"
+ // at least however "Major.Minor".
+ var
+ Separator: Integer;
+ begin
+ try
+ // There must be at least one dot to separate major and minor version number.
+ Separator := Pos('.', Buffer);
+ // At least one number must be before and one after the dot.
+ if (Separator > 1) and (Separator < Length(Buffer)) and (AnsiChar(Buffer[Separator - 1]) in ['0'..'9']) and
+ (AnsiChar(Buffer[Separator + 1]) in ['0'..'9']) then
+ begin
+ // OK, it's a valid version string. Now remove unnecessary parts.
+ Dec(Separator);
+ // Find last non-numeric character before version number.
+ while (Separator > 0) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
+ Dec(Separator);
+ // Delete leading characters which do not belong to the version string.
+ Delete(Buffer, 1, Separator);
+ Separator := Pos('.', Buffer) + 1;
+ // Find first non-numeric character after version number
+ while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
+ Inc(Separator);
+ // delete trailing characters not belonging to the version string
+ Delete(Buffer, Separator, 255);
+ // Now translate the numbers.
+ Separator := Pos('.', Buffer); // This is necessary because the buffer length might have changed.
+ Max := StrToInt(Copy(Buffer, 1, Separator - 1));
+ Min := StrToInt(Copy(Buffer, Separator + 1, 1));
+ end
+ else
+ Abort;
+ except
+ Min := 0;
+ Max := 0;
+ end;
+ end;
+
+
+begin
+ // determine version of implementation
+ // GL
+ if not Assigned(@glGetString) then
+ glGetString := dglGetProcAddress('glGetString');
+
+ AnsiBuffer := glGetString(GL_VERSION);
+ Buffer := String(AnsiBuffer);
+
+ TrimAndSplitVersionString(Buffer, MajorVersion, MinorVersion);
+
+ GL_VERSION_1_0 := True;
+ GL_VERSION_1_1 := False;
+ GL_VERSION_1_2 := False;
+ GL_VERSION_1_3 := False;
+ GL_VERSION_1_4 := False;
+ GL_VERSION_1_5 := False;
+ GL_VERSION_2_0 := False;
+ GL_VERSION_2_1 := False;
+ GL_VERSION_3_0 := False;
+ GL_VERSION_3_1 := False;
+ GL_VERSION_3_2 := False;
+ GL_VERSION_3_3 := False;
+ GL_VERSION_4_0 := False;
+ GL_VERSION_4_1 := False;
+ GL_VERSION_4_2 := False;
+ GL_VERSION_4_3 := False;
+ GL_VERSION_4_4 := False;
+ GL_VERSION_4_5 := False;
+ GL_VERSION_4_6 := False;
+
+ if MajorVersion = 1 then
+ begin
+ if MinorVersion >= 1 then
+ GL_VERSION_1_1 := True;
+ if MinorVersion >= 2 then
+ GL_VERSION_1_2 := True;
+ if MinorVersion >= 3 then
+ GL_VERSION_1_3 := True;
+ if MinorVersion >= 4 then
+ GL_VERSION_1_4 := True;
+ if MinorVersion >= 5 then
+ GL_VERSION_1_5 := True;
+ end;
+
+ if MajorVersion >= 2 then
+ begin
+ GL_VERSION_1_1 := True;
+ GL_VERSION_1_2 := True;
+ GL_VERSION_1_3 := True;
+ GL_VERSION_1_4 := True;
+ GL_VERSION_1_5 := True;
+ GL_VERSION_2_0 := True;
+
+ if MinorVersion >= 1 then
+ GL_VERSION_2_1 := True;
+ end;
+
+ if MajorVersion >= 3 then
+ begin
+ GL_VERSION_2_1 := True;
+ GL_VERSION_3_0 := True;
+
+ if MinorVersion >= 1 then
+ GL_VERSION_3_1 := True;
+ if MinorVersion >= 2 then
+ GL_VERSION_3_2 := True;
+ if MinorVersion >= 3 then
+ GL_VERSION_3_3 := True;
+ end;
+
+ if MajorVersion >= 4 then
+ begin
+ GL_VERSION_3_1 := True;
+ GL_VERSION_3_2 := True;
+ GL_VERSION_3_3 := True;
+ GL_VERSION_4_0 := True;
+
+ if MinorVersion >= 1 then
+ GL_VERSION_4_1 := True;
+ if MinorVersion >= 2 then
+ GL_VERSION_4_2 := True;
+ if MinorVersion >= 3 then
+ GL_VERSION_4_3 := True;
+ if MinorVersion >= 4 then
+ GL_VERSION_4_4 := True;
+ if MinorVersion >= 5 then
+ GL_VERSION_4_5 := True;
+ if MinorVersion >= 6 then
+ GL_VERSION_4_6 := True;
+ end;
+
+ // GLU
+ GLU_VERSION_1_1 := False;
+ GLU_VERSION_1_2 := False;
+ GLU_VERSION_1_3 := False;
+
+ if Assigned(gluGetString) then begin
+ AnsiBuffer := gluGetString(GLU_VERSION);
+ Buffer := String(AnsiBuffer);
+
+ TrimAndSplitVersionString(Buffer, Majorversion, MinorVersion);
+
+ GLU_VERSION_1_1 := True;
+
+ if MinorVersion >= 2 then
+ GLU_VERSION_1_2 := True;
+
+ if MinorVersion >= 3 then
+ GLU_VERSION_1_3 := True;
+ end;
+end;
+
+
+// =============================================================================
+// ReadImplementationProperties
+// =============================================================================
+
+procedure ReadImplementationProperties;
+var
+ Buffer: Ansistring;
+begin
+ ReadCoreVersion;
+
+ // Check all extensions
+ Buffer := Int_GetExtensionString;
+
+ // 3DFX
+ GL_3DFX_multisample := Int_CheckExtension(Buffer, 'GL_3DFX_multisample');
+ GL_3DFX_tbuffer := Int_CheckExtension(Buffer, 'GL_3DFX_tbuffer');
+ GL_3DFX_texture_compression_FXT1 := Int_CheckExtension(Buffer, 'GL_3DFX_texture_compression_FXT1');
+
+ // APPLE
+ GL_APPLE_client_storage := Int_CheckExtension(Buffer, 'GL_APPLE_client_storage');
+ GL_APPLE_element_array := Int_CheckExtension(Buffer, 'GL_APPLE_element_array');
+ GL_APPLE_fence := Int_CheckExtension(Buffer, 'GL_APPLE_fence');
+ GL_APPLE_specular_vector := Int_CheckExtension(Buffer, 'GL_APPLE_specular_vector');
+ GL_APPLE_transform_hint := Int_CheckExtension(Buffer, 'GL_APPLE_transform_hint');
+ GL_APPLE_vertex_array_object := Int_CheckExtension(Buffer, 'GL_APPLE_vertex_array_object');
+ GL_APPLE_vertex_array_range := Int_CheckExtension(Buffer, 'GL_APPLE_vertex_array_range');
+ GL_APPLE_ycbcr_422 := Int_CheckExtension(Buffer, 'GL_APPLE_ycbcr_422');
+ GL_APPLE_texture_range := Int_CheckExtension(Buffer, 'GL_APPLE_texture_range');
+ GL_APPLE_float_pixels := Int_CheckExtension(Buffer, 'GL_APPLE_float_pixels');
+ GL_APPLE_vertex_program_evaluators := Int_CheckExtension(Buffer, 'GL_APPLE_vertex_program_evaluators');
+ GL_APPLE_aux_depth_stencil := Int_CheckExtension(Buffer, 'GL_APPLE_aux_depth_stencil');
+ GL_APPLE_object_purgeable := Int_CheckExtension(Buffer, 'GL_APPLE_object_purgeable');
+ GL_APPLE_row_bytes := Int_CheckExtension(Buffer, 'GL_APPLE_row_bytes');
+ GL_APPLE_rgb_422 := Int_CheckExtension(Buffer, 'GL_APPLE_rgb_422');
+
+ // ARB
+ GL_ARB_depth_texture := Int_CheckExtension(Buffer, 'GL_ARB_depth_texture');
+ GL_ARB_fragment_program := Int_CheckExtension(Buffer, 'GL_ARB_fragment_program');
+ GL_ARB_imaging := Int_CheckExtension(Buffer, 'GL_ARB_imaging');
+ GL_ARB_matrix_palette := Int_CheckExtension(Buffer, 'GL_ARB_matrix_palette');
+ GL_ARB_multisample := Int_CheckExtension(Buffer, 'GL_ARB_multisample');
+ GL_ARB_multitexture := Int_CheckExtension(Buffer, 'GL_ARB_multitexture');
+ GL_ARB_point_parameters := Int_CheckExtension(Buffer, 'GL_ARB_point_parameters');
+ GL_ARB_shadow := Int_CheckExtension(Buffer, 'GL_ARB_shadow');
+ GL_ARB_shadow_ambient := Int_CheckExtension(Buffer, 'GL_ARB_shadow_ambient');
+ GL_ARB_sparse_texture := Int_CheckExtension(Buffer, 'GL_ARB_sparse_texture');
+ GL_ARB_sparse_texture2 := Int_CheckExtension(Buffer, 'GL_ARB_sparse_texture2');
+ GL_ARB_sparse_texture_clamp := Int_CheckExtension(Buffer, 'GL_ARB_sparse_texture_clamp');
+ GL_ARB_spirv_extensions := Int_CheckExtension(Buffer, 'GL_ARB_spirv_extensions');
+ GL_ARB_texture_border_clamp := Int_CheckExtension(Buffer, 'GL_ARB_texture_border_clamp');
+ GL_ARB_texture_compression := Int_CheckExtension(Buffer, 'GL_ARB_texture_compression');
+ GL_ARB_texture_cube_map := Int_CheckExtension(Buffer, 'GL_ARB_texture_cube_map');
+ GL_ARB_texture_env_add := Int_CheckExtension(Buffer, 'GL_ARB_texture_env_add');
+ GL_ARB_texture_env_combine := Int_CheckExtension(Buffer, 'GL_ARB_texture_env_combine');
+ GL_ARB_texture_env_crossbar := Int_CheckExtension(Buffer, 'GL_ARB_texture_env_crossbar');
+ GL_ARB_texture_env_dot3 := Int_CheckExtension(Buffer, 'GL_ARB_texture_env_dot3');
+ GL_ARB_texture_filter_minmax := Int_CheckExtension(Buffer, 'GL_ARB_texture_filter_minmax');
+ GL_ARB_texture_mirrored_repeat := Int_CheckExtension(Buffer, 'GL_ARB_texture_mirrored_repeat');
+ GL_ARB_transpose_matrix := Int_CheckExtension(Buffer, 'GL_ARB_transpose_matrix');
+ GL_ARB_vertex_blend := Int_CheckExtension(Buffer, 'GL_ARB_vertex_blend');
+ GL_ARB_vertex_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_vertex_buffer_object');
+ GL_ARB_vertex_program := Int_CheckExtension(Buffer, 'GL_ARB_vertex_program');
+ GL_ARB_window_pos := Int_CheckExtension(Buffer, 'GL_ARB_window_pos');
+ GL_ARB_shader_objects := Int_CheckExtension(Buffer, 'GL_ARB_shader_objects');
+ GL_ARB_vertex_shader := Int_CheckExtension(Buffer, 'GL_ARB_vertex_shader');
+ GL_ARB_fragment_shader := Int_CheckExtension(Buffer, 'GL_ARB_fragment_shader');
+ GL_ARB_fragment_shader_interlock := Int_CheckExtension(Buffer, 'GL_ARB_fragment_shader_interlock');
+ GL_ARB_occlusion_query := Int_CheckExtension(Buffer, 'GL_ARB_occlusion_query');
+ GL_ARB_shading_language_100 := Int_CheckExtension(Buffer, 'GL_ARB_shading_language_100');
+ GL_ARB_point_sprite := Int_CheckExtension(Buffer, 'GL_ARB_point_sprite');
+ GL_ARB_texture_non_power_of_two := Int_CheckExtension(Buffer, 'GL_ARB_texture_non_power_of_two');
+ GL_ARB_fragment_program_shadow := Int_CheckExtension(Buffer, 'GL_ARB_fragment_program_shadow');
+ GL_ARB_draw_buffers := Int_CheckExtension(Buffer, 'GL_ARB_draw_buffers');
+ GL_ARB_texture_rectangle := Int_CheckExtension(Buffer, 'GL_ARB_texture_rectangle');
+ GL_ARB_color_buffer_float := Int_CheckExtension(Buffer, 'GL_ARB_color_buffer_float');
+ GL_ARB_half_float_pixel := Int_CheckExtension(Buffer, 'GL_ARB_half_float_pixel');
+ GL_ARB_texture_float := Int_CheckExtension(Buffer, 'GL_ARB_texture_float');
+ GL_ARB_pixel_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_pixel_buffer_object');
+ GL_ARB_polygon_offset_clamp := Int_CheckExtension(Buffer, 'GL_ARB_polygon_offset_clamp');
+ GL_ARB_depth_buffer_float := Int_CheckExtension(Buffer, 'GL_ARB_depth_buffer_float');
+ GL_ARB_draw_instanced := Int_CheckExtension(Buffer, 'GL_ARB_draw_instanced');
+ GL_ARB_framebuffer_object := Int_CheckExtension(Buffer, 'GL_ARB_framebuffer_object');
+ GL_ARB_framebuffer_sRGB := Int_CheckExtension(Buffer, 'GL_ARB_framebuffer_sRGB');
+ GL_ARB_geometry_shader4 := Int_CheckExtension(Buffer, 'GL_ARB_geometry_shader4');
+ GL_ARB_gl_spirv := Int_CheckExtension(Buffer, 'GL_ARB_gl_spirv');
+ GL_ARB_half_float_vertex := Int_CheckExtension(Buffer, 'GL_ARB_half_float_vertex');
+ GL_ARB_instanced_arrays := Int_CheckExtension(Buffer, 'GL_ARB_instanced_arrays');
+ GL_ARB_map_buffer_range := Int_CheckExtension(Buffer, 'GL_ARB_map_buffer_range');
+ GL_ARB_texture_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_texture_buffer_object');
+ GL_ARB_texture_compression_rgtc := Int_CheckExtension(Buffer, 'GL_ARB_texture_compression_rgtc');
+ GL_ARB_texture_rg := Int_CheckExtension(Buffer, 'GL_ARB_texture_rg');
+ GL_ARB_vertex_array_object := Int_CheckExtension(Buffer, 'GL_ARB_vertex_array_object');
+ GL_ARB_uniform_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_uniform_buffer_object');
+ GL_ARB_compatibility := Int_CheckExtension(Buffer, 'GL_ARB_compatibility');
+ GL_ARB_copy_buffer := Int_CheckExtension(Buffer, 'GL_ARB_copy_buffer');
+ GL_ARB_shader_texture_lod := Int_CheckExtension(Buffer, 'GL_ARB_shader_texture_lod');
+ GL_ARB_shader_viewport_layer_array := Int_CheckExtension(Buffer, 'GL_ARB_shader_viewport_layer_array');
+ GL_ARB_depth_clamp := Int_CheckExtension(Buffer, 'GL_ARB_depth_clamp');
+ GL_ARB_draw_elements_base_vertex := Int_CheckExtension(Buffer, 'GL_ARB_draw_elements_base_vertex');
+ GL_ARB_fragment_coord_conventions := Int_CheckExtension(Buffer, 'GL_ARB_fragment_coord_conventions');
+ GL_ARB_provoking_vertex := Int_CheckExtension(Buffer, 'GL_ARB_provoking_vertex');
+ GL_ARB_seamless_cube_map := Int_CheckExtension(Buffer, 'GL_ARB_seamless_cube_map');
+ GL_ARB_sync := Int_CheckExtension(Buffer, 'GL_ARB_sync');
+ GL_ARB_texture_multisample := Int_CheckExtension(Buffer, 'GL_ARB_texture_multisample');
+ GL_ARB_vertex_array_bgra := Int_CheckExtension(Buffer, 'GL_ARB_vertex_array_bgra');
+ GL_ARB_draw_buffers_blend := Int_CheckExtension(Buffer, 'GL_ARB_draw_buffers_blend');
+ GL_ARB_sample_shading := Int_CheckExtension(Buffer, 'GL_ARB_sample_shading');
+ GL_ARB_texture_cube_map_array := Int_CheckExtension(Buffer, 'GL_ARB_texture_cube_map_array');
+ GL_ARB_texture_filter_anisotropic := Int_CheckExtension(Buffer, 'GL_ARB_texture_filter_anisotropic');
+ GL_ARB_texture_gather := Int_CheckExtension(Buffer, 'GL_ARB_texture_gather');
+ GL_ARB_texture_query_lod := Int_CheckExtension(Buffer, 'GL_ARB_texture_query_lod');
+ GL_ARB_shading_language_include := Int_CheckExtension(Buffer, 'GL_ARB_shading_language_include');
+ GL_ARB_texture_compression_bptc := Int_CheckExtension(Buffer, 'GL_ARB_texture_compression_bptc');
+ GL_ARB_blend_func_extended := Int_CheckExtension(Buffer, 'GL_ARB_blend_func_extended');
+ GL_ARB_explicit_attrib_location := Int_CheckExtension(Buffer, 'GL_ARB_explicit_attrib_location');
+ GL_ARB_occlusion_query2 := Int_CheckExtension(Buffer, 'GL_ARB_occlusion_query2');
+ GL_ARB_parallel_shader_compile := Int_CheckExtension(Buffer, 'GL_ARB_parallel_shader_compile');
+ GL_ARB_post_depth_coverage := Int_CheckExtension(Buffer, 'GL_ARB_post_depth_coverage');
+ GL_ARB_sampler_objects := Int_CheckExtension(Buffer, 'GL_ARB_sampler_objects');
+ GL_ARB_shader_bit_encoding := Int_CheckExtension(Buffer, 'GL_ARB_shader_bit_encoding');
+ GL_ARB_shader_clock := Int_CheckExtension(Buffer, 'GL_ARB_shader_clock');
+ GL_ARB_texture_rgb10_a2ui := Int_CheckExtension(Buffer, 'GL_ARB_texture_rgb10_a2ui');
+ GL_ARB_texture_swizzle := Int_CheckExtension(Buffer, 'GL_ARB_texture_swizzle');
+ GL_ARB_timer_query := Int_CheckExtension(Buffer, 'GL_ARB_timer_query');
+ GL_ARB_vertex_type_2_10_10_10_rev := Int_CheckExtension(Buffer, 'GL_ARB_vertex_type_2_10_10_10_rev');
+ GL_ARB_draw_indirect := Int_CheckExtension(Buffer, 'GL_ARB_draw_indirect');
+ GL_ARB_gpu_shader5 := Int_CheckExtension(Buffer, 'GL_ARB_gpu_shader5');
+ GL_ARB_gpu_shader_fp64 := Int_CheckExtension(Buffer, 'GL_ARB_gpu_shader_fp64');
+ GL_ARB_gpu_shader_int64 := Int_CheckExtension(Buffer, 'GL_ARB_gpu_shader_int64');
+ GL_ARB_shader_subroutine := Int_CheckExtension(Buffer, 'GL_ARB_shader_subroutine');
+ GL_ARB_tessellation_shader := Int_CheckExtension(Buffer, 'GL_ARB_tessellation_shader');
+ GL_ARB_texture_buffer_object_rgb32 := Int_CheckExtension(Buffer, 'GL_ARB_texture_buffer_object_rgb32');
+ GL_ARB_transform_feedback2 := Int_CheckExtension(Buffer, 'GL_ARB_transform_feedback2');
+ GL_ARB_transform_feedback3 := Int_CheckExtension(Buffer, 'GL_ARB_transform_feedback3');
+ GL_ARB_ES2_compatibility := Int_CheckExtension(Buffer, 'GL_ARB_ES2_compatibility');
+ GL_ARB_ES3_2_compatibility := Int_CheckExtension(Buffer, 'GL_ARB_ES3_2_compatibility');
+ GL_ARB_get_program_binary := Int_CheckExtension(Buffer, 'GL_ARB_get_program_binary');
+ GL_ARB_separate_shader_objects := Int_CheckExtension(Buffer, 'GL_ARB_separate_shader_objects');
+ GL_ARB_shader_atomic_counter_ops := Int_CheckExtension(Buffer, 'GL_ARB_shader_atomic_counter_ops');
+ GL_ARB_shader_ballot := Int_CheckExtension(Buffer, 'GL_ARB_shader_ballot');
+ GL_ARB_shader_precision := Int_CheckExtension(Buffer, 'GL_ARB_shader_precision');
+ GL_ARB_vertex_attrib_64bit := Int_CheckExtension(Buffer, 'GL_ARB_vertex_attrib_64bit');
+ GL_ARB_viewport_array := Int_CheckExtension(Buffer, 'GL_ARB_viewport_array');
+ GL_ARB_compute_variable_group_size := Int_CheckExtension(Buffer, 'GL_ARB_compute_variable_group_size');
+
+ // GL 4.2
+ GL_ARB_base_instance := Int_CheckExtension(Buffer, 'GL_ARB_base_instance');
+ GL_ARB_shading_language_420pack := Int_CheckExtension(Buffer, 'GL_ARB_shading_language_420pack');
+ GL_ARB_transform_feedback_instanced := Int_CheckExtension(Buffer, 'GL_ARB_transform_feedback_instanced');
+ GL_ARB_compressed_texture_pixel_storage := Int_CheckExtension(Buffer, 'GL_ARB_compressed_texture_pixel_storage');
+ GL_ARB_conservative_depth := Int_CheckExtension(Buffer, 'GL_ARB_conservative_depth');
+ GL_ARB_internalformat_query := Int_CheckExtension(Buffer, 'GL_ARB_internalformat_query');
+ GL_ARB_map_buffer_alignment := Int_CheckExtension(Buffer, 'GL_ARB_map_buffer_alignment');
+ GL_ARB_shader_atomic_counters := Int_CheckExtension(Buffer, 'GL_ARB_shader_atomic_counters');
+ GL_ARB_shader_image_load_store := Int_CheckExtension(Buffer, 'GL_ARB_shader_image_load_store');
+ GL_ARB_shading_language_packing := Int_CheckExtension(Buffer, 'GL_ARB_shading_language_packing');
+ GL_ARB_texture_storage := Int_CheckExtension(Buffer, 'GL_ARB_texture_storage');
+
+ // GL 4.3
+ GL_ARB_arrays_of_arrays := Int_CheckExtension(Buffer, 'GL_ARB_arrays_of_arrays');
+ GL_ARB_fragment_layer_viewport := Int_CheckExtension(Buffer, 'GL_ARB_fragment_layer_viewport');
+ GL_ARB_shader_image_size := Int_CheckExtension(Buffer, 'GL_ARB_shader_image_size');
+ GL_ARB_ES3_compatibility := Int_CheckExtension(Buffer, 'GL_ARB_ES3_compatibility');
+ GL_ARB_clear_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_clear_buffer_object');
+ GL_ARB_compute_shader := Int_CheckExtension(Buffer, 'GL_ARB_compute_shader');
+ GL_ARB_copy_image := Int_CheckExtension(Buffer, 'GL_ARB_copy_image');
+ GL_KHR_debug := Int_CheckExtension(Buffer, 'GL_KHR_debug');
+ GL_ARB_explicit_uniform_location := Int_CheckExtension(Buffer, 'GL_ARB_explicit_uniform_location');
+ GL_ARB_framebuffer_no_attachments := Int_CheckExtension(Buffer, 'GL_ARB_framebuffer_no_attachments');
+ GL_ARB_internalformat_query2 := Int_CheckExtension(Buffer, 'GL_ARB_internalformat_query2');
+ GL_ARB_invalidate_subdata := Int_CheckExtension(Buffer, 'GL_ARB_invalidate_subdata');
+ GL_ARB_multi_draw_indirect := Int_CheckExtension(Buffer, 'GL_ARB_multi_draw_indirect');
+ GL_ARB_program_interface_query := Int_CheckExtension(Buffer, 'GL_ARB_program_interface_query');
+ GL_ARB_robust_buffer_access_behavior := Int_CheckExtension(Buffer, 'GL_ARB_robust_buffer_access_behavior');
+ GL_ARB_shader_storage_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_shader_storage_buffer_object');
+ GL_ARB_stencil_texturing := Int_CheckExtension(Buffer, 'GL_ARB_stencil_texturing');
+ GL_ARB_texture_buffer_range := Int_CheckExtension(Buffer, 'GL_ARB_texture_buffer_range');
+ GL_ARB_texture_query_levels := Int_CheckExtension(Buffer, 'GL_ARB_texture_query_levels');
+ GL_ARB_texture_storage_multisample := Int_CheckExtension(Buffer, 'GL_ARB_texture_storage_multisample');
+ GL_ARB_texture_view := Int_CheckExtension(Buffer, 'GL_ARB_texture_view');
+ GL_ARB_vertex_attrib_binding := Int_CheckExtension(Buffer, 'GL_ARB_vertex_attrib_binding');
+ GL_ARB_cl_event := Int_CheckExtension(Buffer, 'GL_ARB_cl_event');
+ GL_ARB_debug_output := Int_CheckExtension(Buffer, 'GL_ARB_debug_output');
+ GL_ARB_robustness := Int_CheckExtension(Buffer, 'GL_ARB_robustness');
+ GL_ARB_shader_stencil_export := Int_CheckExtension(Buffer, 'GL_ARB_shader_stencil_export');
+
+ // GL 4.4
+ GL_ARB_buffer_storage := Int_CheckExtension(Buffer, 'GL_ARB_buffer_storage');
+ GL_ARB_clear_texture := Int_CheckExtension(Buffer, 'GL_ARB_clear_texture');
+ GL_ARB_enhanced_layouts := Int_CheckExtension(Buffer, 'GL_ARB_enhanced_layouts');
+ GL_ARB_multi_bind := Int_CheckExtension(Buffer, 'GL_ARB_multi_bind');
+ GL_ARB_query_buffer_object := Int_CheckExtension(Buffer, 'GL_ARB_query_buffer_object');
+ GL_ARB_texture_mirror_clamp_to_edge:= Int_CheckExtension(Buffer, 'GL_ARB_texture_mirror_clamp_to_edge');
+ GL_ARB_texture_stencil8 := Int_CheckExtension(Buffer, 'GL_ARB_texture_stencil8');
+ GL_ARB_vertex_type_10f_11f_11f_rev := Int_CheckExtension(Buffer, 'GL_ARB_vertex_type_10f_11f_11f_rev');
+ GL_ARB_bindless_texture := Int_CheckExtension(Buffer, 'GL_ARB_bindless_texture');
+ GL_ARB_sparse_texture := Int_CheckExtension(Buffer, 'GL_ARB_sparse_texture');
+
+ // GL 4.5
+ GL_ARB_clip_control := Int_CheckExtension(Buffer, 'GL_ARB_clip_control');
+ GL_ARB_cull_distance := Int_CheckExtension(Buffer, 'GL_ARB_cull_distance');
+ GL_ARB_ES3_1_compatibility := Int_CheckExtension(Buffer, 'GL_ARB_ES3_1_compatibility');
+ GL_ARB_conditional_render_inverted := Int_CheckExtension(Buffer, 'GL_ARB_conditional_render_inverted');
+ GL_KHR_context_flush_control := Int_CheckExtension(Buffer, 'GL_KHR_context_flush_control');
+ GL_ARB_derivative_control := Int_CheckExtension(Buffer, 'GL_ARB_derivative_control');
+ GL_ARB_direct_state_access := Int_CheckExtension(Buffer, 'GL_ARB_direct_state_access');
+ GL_ARB_get_texture_sub_image := Int_CheckExtension(Buffer, 'GL_ARB_get_texture_sub_image');
+ GL_KHR_robustness := Int_CheckExtension(Buffer, 'GL_KHR_robustness');
+ GL_ARB_shader_texture_image_samples := Int_CheckExtension(Buffer, 'GL_ARB_shader_texture_image_samples');
+ GL_ARB_texture_barrier := Int_CheckExtension(Buffer, 'GL_ARB_texture_barrier');
+
+ // GL 4.6
+ GL_ARB_indirect_parameters := Int_CheckExtension(Buffer, 'GL_ARB_indirect_parameters');
+ GL_ARB_pipeline_statistics_query := Int_CheckExtension(Buffer, 'GL_ARB_pipeline_statistics_query');
+ GL_ARB_polygon_offset_clamp := Int_CheckExtension(Buffer, 'GL_ARB_polygon_offset_clamp');
+ GL_KHR_no_error := Int_CheckExtension(Buffer, 'GL_KHR_no_error');
+ GL_ARB_shader_atomic_counter_ops := Int_CheckExtension(Buffer, 'GL_ARB_shader_atomic_counter_ops');
+ GL_ARB_shader_draw_parameters := Int_CheckExtension(Buffer, 'GL_ARB_shader_draw_parameters');
+ GL_ARB_shader_group_vote := Int_CheckExtension(Buffer, 'GL_ARB_shader_group_vote');
+ GL_ARB_gl_spirv := Int_CheckExtension(Buffer, 'GL_ARB_gl_spirv');
+ GL_ARB_spirv_extensions := Int_CheckExtension(Buffer, 'GL_ARB_spirv_extensions');
+ GL_ARB_texture_filter_anisotropic := Int_CheckExtension(Buffer, 'GL_ARB_texture_filter_anisotropic');
+ GL_ARB_transform_feedback_overflow_query := Int_CheckExtension(Buffer, 'GL_ARB_transform_feedback_overflow_query');
+
+ // ATI/AMD
+ GL_ATI_draw_buffers := Int_CheckExtension(Buffer, 'GL_ATI_draw_buffers');
+ GL_ATI_element_array := Int_CheckExtension(Buffer, 'GL_ATI_element_array');
+ GL_ATI_envmap_bumpmap := Int_CheckExtension(Buffer, 'GL_ATI_envmap_bumpmap');
+ GL_ATI_fragment_shader := Int_CheckExtension(Buffer, 'GL_ATI_fragment_shader');
+ GL_ATI_map_object_buffer := Int_CheckExtension(Buffer, 'GL_ATI_map_object_buffer');
+ GL_ATI_pn_triangles := Int_CheckExtension(Buffer, 'GL_ATI_pn_triangles');
+ GL_ATI_separate_stencil := Int_CheckExtension(Buffer, 'GL_ATI_separate_stencil');
+ GL_ATI_text_fragment_shader := Int_CheckExtension(Buffer, 'GL_ATI_text_fragment_shader');
+ GL_ATI_texture_env_combine3 := Int_CheckExtension(Buffer, 'GL_ATI_texture_env_combine3');
+ GL_ATI_texture_float := Int_CheckExtension(Buffer, 'GL_ATI_texture_float');
+ GL_ATI_texture_mirror_once := Int_CheckExtension(Buffer, 'GL_ATI_texture_mirror_once');
+ GL_ATI_vertex_array_object := Int_CheckExtension(Buffer, 'GL_ATI_vertex_array_object');
+ GL_ATI_vertex_attrib_array_object := Int_CheckExtension(Buffer, 'GL_ATI_vertex_attrib_array_object');
+ GL_ATI_vertex_streams := Int_CheckExtension(Buffer, 'GL_ATI_vertex_streams');
+ GL_ATI_meminfo := Int_CheckExtension(Buffer, 'GL_ATI_meminfo');
+ GL_AMD_performance_monitor := Int_CheckExtension(Buffer, 'GL_AMD_performance_monitor');
+ GL_AMD_texture_texture4 := Int_CheckExtension(Buffer, 'GL_AMD_texture_texture4');
+ GL_AMD_vertex_shader_tesselator := Int_CheckExtension(Buffer, 'GL_AMD_vertex_shader_tesselator');
+ GL_AMD_draw_buffers_blend := Int_CheckExtension(Buffer, 'GL_AMD_draw_buffers_blend');
+ GL_AMD_shader_stencil_export := Int_CheckExtension(Buffer, 'GL_AMD_shader_stencil_export');
+ GL_AMD_seamless_cubemap_per_texture := Int_CheckExtension(Buffer, 'GL_AMD_seamless_cubemap_per_texture');
+ GL_AMD_conservative_depth := Int_CheckExtension(Buffer, 'GL_AMD_conservative_depth');
+ GL_AMD_name_gen_delete := Int_CheckExtension(Buffer, 'GL_AMD_name_gen_delete');
+ GL_AMD_debug_output := Int_CheckExtension(Buffer, 'GL_AMD_debug_output');
+ GL_AMD_transform_feedback3_lines_triangles := Int_CheckExtension(Buffer, 'GL_AMD_transform_feedback3_lines_triangles');
+ GL_AMD_depth_clamp_separate := Int_CheckExtension(Buffer, 'GL_AMD_depth_clamp_separate');
+ // 4.3
+ GL_AMD_pinned_memory := Int_CheckExtension(Buffer, 'GL_AMD_pinned_memory');
+ GL_AMD_stencil_operation_extended := Int_CheckExtension(Buffer, 'GL_AMD_stencil_operation_extended');
+ GL_AMD_vertex_shader_viewport_index := Int_CheckExtension(Buffer, 'GL_AMD_vertex_shader_viewport_index');
+ GL_AMD_vertex_shader_layer := Int_CheckExtension(Buffer, 'GL_AMD_vertex_shader_layer');
+ GL_AMD_query_buffer_object := Int_CheckExtension(Buffer, 'GL_AMD_query_buffer_object');
+
+ // EXT
+ GL_EXT_422_pixels := Int_CheckExtension(Buffer, 'GL_EXT_422_pixels');
+ GL_EXT_abgr := Int_CheckExtension(Buffer, 'GL_EXT_abgr');
+ GL_EXT_bgra := Int_CheckExtension(Buffer, 'GL_EXT_bgra');
+ GL_EXT_blend_color := Int_CheckExtension(Buffer, 'GL_EXT_blend_color');
+ GL_EXT_blend_func_separate := Int_CheckExtension(Buffer, 'GL_EXT_blend_func_separate');
+ GL_EXT_blend_logic_op := Int_CheckExtension(Buffer, 'GL_EXT_blend_logic_op');
+ GL_EXT_blend_minmax := Int_CheckExtension(Buffer, 'GL_EXT_blend_minmax');
+ GL_EXT_blend_subtract := Int_CheckExtension(Buffer, 'GL_EXT_blend_subtract');
+ GL_EXT_clip_volume_hint := Int_CheckExtension(Buffer, 'GL_EXT_clip_volume_hint');
+ GL_EXT_cmyka := Int_CheckExtension(Buffer, 'GL_EXT_cmyka');
+ GL_EXT_color_matrix := Int_CheckExtension(Buffer, 'GL_EXT_color_matrix');
+ GL_EXT_color_subtable := Int_CheckExtension(Buffer, 'GL_EXT_color_subtable');
+ GL_EXT_compiled_vertex_array := Int_CheckExtension(Buffer, 'GL_EXT_compiled_vertex_array');
+ GL_EXT_convolution := Int_CheckExtension(Buffer, 'GL_EXT_convolution');
+ GL_EXT_coordinate_frame := Int_CheckExtension(Buffer, 'GL_EXT_coordinate_frame');
+ GL_EXT_copy_texture := Int_CheckExtension(Buffer, 'GL_EXT_copy_texture');
+ GL_EXT_cull_vertex := Int_CheckExtension(Buffer, 'GL_EXT_cull_vertex');
+ GL_EXT_draw_range_elements := Int_CheckExtension(Buffer, 'GL_EXT_draw_range_elements');
+ GL_EXT_fog_coord := Int_CheckExtension(Buffer, 'GL_EXT_fog_coord');
+ GL_EXT_framebuffer_object := Int_CheckExtension(Buffer, 'GL_EXT_framebuffer_object');
+ GL_EXT_histogram := Int_CheckExtension(Buffer, 'GL_EXT_histogram');
+ GL_EXT_index_array_formats := Int_CheckExtension(Buffer, 'GL_EXT_index_array_formats');
+ GL_EXT_index_func := Int_CheckExtension(Buffer, 'GL_EXT_index_func');
+ GL_EXT_index_material := Int_CheckExtension(Buffer, 'GL_EXT_index_material');
+ GL_EXT_index_texture := Int_CheckExtension(Buffer, 'GL_EXT_index_texture');
+ GL_EXT_light_texture := Int_CheckExtension(Buffer, 'GL_EXT_light_texture');
+ GL_EXT_misc_attribute := Int_CheckExtension(Buffer, 'GL_EXT_misc_attribute');
+ GL_EXT_multi_draw_arrays := Int_CheckExtension(Buffer, 'GL_EXT_multi_draw_arrays');
+ GL_EXT_multisample := Int_CheckExtension(Buffer, 'GL_EXT_multisample');
+ GL_EXT_packed_pixels := Int_CheckExtension(Buffer, 'GL_EXT_packed_pixels');
+ GL_EXT_paletted_texture := Int_CheckExtension(Buffer, 'GL_EXT_paletted_texture');
+ GL_EXT_pixel_transform := Int_CheckExtension(Buffer, 'GL_EXT_pixel_transform');
+ GL_EXT_pixel_transform_color_table := Int_CheckExtension(Buffer, 'GL_EXT_pixel_transform_color_table');
+ GL_EXT_point_parameters := Int_CheckExtension(Buffer, 'GL_EXT_point_parameters');
+ GL_EXT_polygon_offset := Int_CheckExtension(Buffer, 'GL_EXT_polygon_offset');
+ GL_EXT_rescale_normal := Int_CheckExtension(Buffer, 'GL_EXT_rescale_normal');
+ GL_EXT_secondary_color := Int_CheckExtension(Buffer, 'GL_EXT_secondary_color');
+ GL_EXT_separate_specular_color := Int_CheckExtension(Buffer, 'GL_EXT_separate_specular_color');
+ GL_EXT_shadow_funcs := Int_CheckExtension(Buffer, 'GL_EXT_shadow_funcs');
+ GL_EXT_shared_texture_palette := Int_CheckExtension(Buffer, 'GL_EXT_shared_texture_palette');
+ GL_EXT_stencil_two_side := Int_CheckExtension(Buffer, 'GL_EXT_stencil_two_side');
+ GL_EXT_stencil_wrap := Int_CheckExtension(Buffer, 'GL_EXT_stencil_wrap');
+ GL_EXT_subtexture := Int_CheckExtension(Buffer, 'GL_EXT_subtexture');
+ GL_EXT_texture := Int_CheckExtension(Buffer, 'GL_EXT_texture');
+ GL_EXT_texture3D := Int_CheckExtension(Buffer, 'GL_EXT_texture3D');
+ GL_EXT_texture_compression_s3tc := Int_CheckExtension(Buffer, 'GL_EXT_texture_compression_s3tc');
+ GL_EXT_texture_cube_map := Int_CheckExtension(Buffer, 'GL_EXT_texture_cube_map');
+ GL_EXT_texture_edge_clamp := Int_CheckExtension(Buffer, 'GL_EXT_texture_edge_clamp');
+ GL_EXT_texture_env_add := Int_CheckExtension(Buffer, 'GL_EXT_texture_env_add');
+ GL_EXT_texture_env_combine := Int_CheckExtension(Buffer, 'GL_EXT_texture_env_combine');
+ GL_EXT_texture_env_dot3 := Int_CheckExtension(Buffer, 'GL_EXT_texture_env_dot3');
+ GL_EXT_texture_filter_anisotropic := Int_CheckExtension(Buffer, 'GL_EXT_texture_filter_anisotropic');
+ GL_EXT_texture_lod_bias := Int_CheckExtension(Buffer, 'GL_EXT_texture_lod_bias');
+ GL_EXT_texture_object := Int_CheckExtension(Buffer, 'GL_EXT_texture_object');
+ GL_EXT_texture_perturb_normal := Int_CheckExtension(Buffer, 'GL_EXT_texture_perturb_normal');
+ GL_EXT_texture_rectangle := Int_CheckExtension(Buffer, 'GL_EXT_texture_rectangle');
+ GL_EXT_vertex_array := Int_CheckExtension(Buffer, 'GL_EXT_vertex_array');
+ GL_EXT_vertex_shader := Int_CheckExtension(Buffer, 'GL_EXT_vertex_shader');
+ GL_EXT_vertex_weighting := Int_CheckExtension(Buffer, 'GL_EXT_vertex_weighting');
+ GL_EXT_depth_bounds_test := Int_CheckExtension(Buffer, 'GL_EXT_depth_bounds_test');
+ GL_EXT_texture_mirror_clamp := Int_CheckExtension(Buffer, 'GL_EXT_texture_mirror_clamp');
+ GL_EXT_blend_equation_separate := Int_CheckExtension(Buffer, 'GL_EXT_blend_equation_separate');
+ GL_EXT_pixel_buffer_object := Int_CheckExtension(Buffer, 'GL_EXT_pixel_buffer_object');
+ GL_EXT_texture_compression_dxt1 := Int_CheckExtension(Buffer, 'GL_EXT_texture_compression_dxt1');
+ GL_EXT_stencil_clear_tag := Int_CheckExtension(Buffer, 'GL_EXT_stencil_clear_tag');
+ GL_EXT_packed_depth_stencil := Int_CheckExtension(Buffer, 'GL_EXT_packed_depth_stencil');
+ GL_EXT_texture_sRGB := Int_CheckExtension(Buffer, 'GL_EXT_texture_sRGB');
+ GL_EXT_framebuffer_blit := Int_CheckExtension(Buffer, 'GL_EXT_framebuffer_blit');
+ GL_EXT_framebuffer_multisample := Int_CheckExtension(Buffer, 'GL_EXT_framebuffer_multisample');
+ GL_EXT_timer_query := Int_CheckExtension(Buffer, 'GL_EXT_timer_query');
+ GL_EXT_gpu_program_parameters := Int_CheckExtension(Buffer, 'GL_EXT_gpu_program_parameters');
+ GL_EXT_bindable_uniform := Int_CheckExtension(Buffer, 'GL_EXT_bindable_uniform');
+ GL_EXT_draw_buffers2 := Int_CheckExtension(Buffer, 'GL_EXT_draw_buffers2');
+ GL_EXT_draw_instanced := Int_CheckExtension(Buffer, 'GL_EXT_draw_instanced');
+ GL_EXT_framebuffer_sRGB := Int_CheckExtension(Buffer, 'GL_EXT_framebuffer_sRGB');
+ GL_EXT_geometry_shader4 := Int_CheckExtension(Buffer, 'GL_EXT_geometry_shader4');
+ GL_EXT_gpu_shader4 := Int_CheckExtension(Buffer, 'GL_EXT_gpu_shader4');
+ GL_EXT_packed_float := Int_CheckExtension(Buffer, 'GL_EXT_packed_float');
+ GL_EXT_texture_array := Int_CheckExtension(Buffer, 'GL_EXT_texture_array');
+ GL_EXT_texture_buffer_object := Int_CheckExtension(Buffer, 'GL_EXT_texture_buffer_object');
+ GL_EXT_texture_compression_latc := Int_CheckExtension(Buffer, 'GL_EXT_texture_compression_latc');
+ GL_EXT_texture_compression_rgtc := Int_CheckExtension(Buffer, 'GL_EXT_texture_compression_rgtc');
+ GL_EXT_texture_integer := Int_CheckExtension(Buffer, 'GL_EXT_texture_integer');
+ GL_EXT_texture_shared_exponent := Int_CheckExtension(Buffer, 'GL_EXT_texture_shared_exponent');
+ GL_EXT_transform_feedback := Int_CheckExtension(Buffer, 'GL_EXT_transform_feedback');
+ GL_EXT_direct_state_access := Int_CheckExtension(Buffer, 'GL_EXT_direct_state_access');
+ GL_EXT_vertex_array_bgra := Int_CheckExtension(Buffer, 'GL_EXT_vertex_array_bgra');
+ GL_EXT_texture_swizzle := Int_CheckExtension(Buffer, 'GL_EXT_texture_swizzle');
+ GL_EXT_provoking_vertex := Int_CheckExtension(Buffer, 'GL_EXT_provoking_vertex');
+ GL_EXT_texture_snorm := Int_CheckExtension(Buffer, 'GL_EXT_texture_snorm');
+ GL_EXT_separate_shader_objects := Int_CheckExtension(Buffer, 'GL_EXT_separate_shader_objects');
+ GL_EXT_shader_image_load_store := Int_CheckExtension(Buffer, 'GL_EXT_shader_image_load_store');
+ GL_EXT_vertex_attrib_64bit := Int_CheckExtension(Buffer, 'GL_EXT_vertex_attrib_64bit');
+ GL_EXT_texture_sRGB_decode := Int_CheckExtension(Buffer, 'GL_EXT_texture_sRGB_decode');
+
+ // HP
+ GL_HP_convolution_border_modes := Int_CheckExtension(Buffer, 'GL_HP_convolution_border_modes');
+ GL_HP_image_transform := Int_CheckExtension(Buffer, 'GL_HP_image_transform');
+ GL_HP_occlusion_test := Int_CheckExtension(Buffer, 'GL_HP_occlusion_test');
+ GL_HP_texture_lighting := Int_CheckExtension(Buffer, 'GL_HP_texture_lighting');
+
+ // IBM
+ GL_IBM_cull_vertex := Int_CheckExtension(Buffer, 'GL_IBM_cull_vertex');
+ GL_IBM_multimode_draw_arrays := Int_CheckExtension(Buffer, 'GL_IBM_multimode_draw_arrays');
+ GL_IBM_rasterpos_clip := Int_CheckExtension(Buffer, 'GL_IBM_rasterpos_clip');
+ GL_IBM_texture_mirrored_repeat := Int_CheckExtension(Buffer, 'GL_IBM_texture_mirrored_repeat');
+ GL_IBM_vertex_array_lists := Int_CheckExtension(Buffer, 'GL_IBM_vertex_array_lists');
+
+ // INGR
+ GL_INGR_blend_func_separate := Int_CheckExtension(Buffer, 'GL_INGR_blend_func_separate');
+ GL_INGR_color_clamp := Int_CheckExtension(Buffer, 'GL_INGR_color_clamp');
+ GL_INGR_interlace_read := Int_CheckExtension(Buffer, 'GL_INGR_interlace_read');
+ GL_INGR_palette_buffer := Int_CheckExtension(Buffer, 'GL_INGR_palette_buffer');
+
+ // INTEL
+ GL_INTEL_framebuffer_CMAA := Int_CheckExtension(Buffer, 'GL_INTEL_framebuffer_CMAA');
+ GL_INTEL_parallel_arrays := Int_CheckExtension(Buffer, 'GL_INTEL_parallel_arrays');
+ GL_INTEL_texture_scissor := Int_CheckExtension(Buffer, 'GL_INTEL_texture_scissor');
+
+ // MESA
+ GL_MESA_resize_buffers := Int_CheckExtension(Buffer, 'GL_MESA_resize_buffers');
+ GL_MESA_window_pos := Int_CheckExtension(Buffer, 'GL_MESA_window_pos');
+
+ // Khronos
+ // 4.5
+ GL_KHR_blend_equation_advanced := Int_CheckExtension(Buffer, 'GL_KHR_blend_equation_advanced');
+ GL_KHR_blend_equation_advanced_coherent := Int_CheckExtension(Buffer, 'GL_KHR_blend_equation_advanced_coherent');
+ GL_KHR_no_error := Int_CheckExtension(Buffer, 'GL_KHR_no_error');
+ GL_KHR_robustness := Int_CheckExtension(Buffer, 'GL_KHR_robustness');
+ GL_KHR_robust_buffer_access_behavior := Int_CheckExtension(Buffer, 'GL_KHR_robust_buffer_access_behavior');
+
+ // NVIDIA
+ GL_NV_blend_square := Int_CheckExtension(Buffer, 'GL_NV_blend_square');
+ GL_NV_copy_depth_to_color := Int_CheckExtension(Buffer, 'GL_NV_copy_depth_to_color');
+ GL_NV_depth_clamp := Int_CheckExtension(Buffer, 'GL_NV_depth_clamp');
+ GL_NV_evaluators := Int_CheckExtension(Buffer, 'GL_NV_evaluators');
+ GL_NV_fence := Int_CheckExtension(Buffer, 'GL_NV_fence');
+ GL_NV_float_buffer := Int_CheckExtension(Buffer, 'GL_NV_float_buffer');
+ GL_NV_fog_distance := Int_CheckExtension(Buffer, 'GL_NV_fog_distance');
+ GL_NV_fragment_program := Int_CheckExtension(Buffer, 'GL_NV_fragment_program');
+ GL_NV_half_float := Int_CheckExtension(Buffer, 'GL_NV_half_float');
+ GL_NV_light_max_exponent := Int_CheckExtension(Buffer, 'GL_NV_light_max_exponent');
+ GL_NV_multisample_filter_hint := Int_CheckExtension(Buffer, 'GL_NV_multisample_filter_hint');
+ GL_NV_occlusion_query := Int_CheckExtension(Buffer, 'GL_NV_occlusion_query');
+ GL_NV_packed_depth_stencil := Int_CheckExtension(Buffer, 'GL_NV_packed_depth_stencil');
+ GL_NV_pixel_data_range := Int_CheckExtension(Buffer, 'GL_NV_pixel_data_range');
+ GL_NV_point_sprite := Int_CheckExtension(Buffer, 'GL_NV_point_sprite');
+ GL_NV_primitive_restart := Int_CheckExtension(Buffer, 'GL_NV_primitive_restart');
+ GL_NV_register_combiners := Int_CheckExtension(Buffer, 'GL_NV_register_combiners');
+ GL_NV_register_combiners2 := Int_CheckExtension(Buffer, 'GL_NV_register_combiners2');
+ GL_NV_texgen_emboss := Int_CheckExtension(Buffer, 'GL_NV_texgen_emboss');
+ GL_NV_texgen_reflection := Int_CheckExtension(Buffer, 'GL_NV_texgen_reflection');
+ GL_NV_texture_compression_vtc := Int_CheckExtension(Buffer, 'GL_NV_texture_compression_vtc');
+ GL_NV_texture_env_combine4 := Int_CheckExtension(Buffer, 'GL_NV_texture_env_combine4');
+ GL_NV_texture_expand_normal := Int_CheckExtension(Buffer, 'GL_NV_texture_expand_normal');
+ GL_NV_texture_rectangle := Int_CheckExtension(Buffer, 'GL_NV_texture_rectangle');
+ GL_NV_texture_shader := Int_CheckExtension(Buffer, 'GL_NV_texture_shader');
+ GL_NV_texture_shader2 := Int_CheckExtension(Buffer, 'GL_NV_texture_shader2');
+ GL_NV_texture_shader3 := Int_CheckExtension(Buffer, 'GL_NV_texture_shader3');
+ GL_NV_vertex_array_range := Int_CheckExtension(Buffer, 'GL_NV_vertex_array_range');
+ GL_NV_vertex_array_range2 := Int_CheckExtension(Buffer, 'GL_NV_vertex_array_range2');
+ GL_NV_vertex_program := Int_CheckExtension(Buffer, 'GL_NV_vertex_program');
+ GL_NV_vertex_program1_1 := Int_CheckExtension(Buffer, 'GL_NV_vertex_program1_1');
+ GL_NV_vertex_program2 := Int_CheckExtension(Buffer, 'GL_NV_vertex_program2');
+ GL_NV_fragment_program_option := Int_CheckExtension(Buffer, 'GL_NV_fragment_program_option');
+ GL_NV_fragment_program2 := Int_CheckExtension(Buffer, 'GL_NV_fragment_program2');
+ GL_NV_vertex_program2_option := Int_CheckExtension(Buffer, 'GL_NV_vertex_program2_option');
+ GL_NV_vertex_program3 := Int_CheckExtension(Buffer, 'GL_NV_vertex_program3');
+ GL_NV_depth_buffer_float := Int_CheckExtension(Buffer, 'GL_NV_depth_buffer_float');
+ GL_NV_fragment_program4 := Int_CheckExtension(Buffer, 'GL_NV_fragment_program4');
+ GL_NV_framebuffer_multisample_coverage := Int_CheckExtension(Buffer, 'GL_NV_framebuffer_multisample_coverage');
+ GL_NV_geometry_program4 := Int_CheckExtension(Buffer, 'GL_NV_geometry_program4');
+ GL_NV_gpu_program4 := Int_CheckExtension(Buffer, 'GL_NV_gpu_program4');
+ GL_NV_parameter_buffer_object := Int_CheckExtension(Buffer, 'GL_NV_parameter_buffer_object');
+ GL_NV_transform_feedback := Int_CheckExtension(Buffer, 'GL_NV_transform_feedback');
+ GL_NV_vertex_program4 := Int_CheckExtension(Buffer, 'GL_NV_vertex_program4');
+ GL_NV_conditional_render := Int_CheckExtension(Buffer, 'GL_NV_conditional_render');
+ GL_NV_conservative_raster := Int_CheckExtension(Buffer, 'GL_NV_conservative_raster');
+ GL_NV_conservative_raster_dilate := Int_CheckExtension(Buffer, 'GL_NV_conservative_raster_dilate');
+ GL_NV_present_video := Int_CheckExtension(Buffer, 'GL_NV_present_video');
+ GL_NV_explicit_multisample := Int_CheckExtension(Buffer, 'GL_NV_explicit_multisample');
+ GL_NV_transform_feedback2 := Int_CheckExtension(Buffer, 'GL_NV_transform_feedback2');
+ GL_NV_video_capture := Int_CheckExtension(Buffer, 'GL_NV_video_capture');
+ GL_NV_copy_image := Int_CheckExtension(Buffer, 'GL_NV_copy_image');
+ GL_NV_parameter_buffer_object2 := Int_CheckExtension(Buffer, 'GL_NV_parameter_buffer_object2');
+ GL_NV_shader_buffer_load := Int_CheckExtension(Buffer, 'GL_NV_shader_buffer_load');
+ GL_NV_vertex_buffer_unified_memory := Int_CheckExtension(Buffer, 'GL_NV_vertex_buffer_unified_memory');
+ GL_NV_gpu_program5 := Int_CheckExtension(Buffer, 'GL_NV_gpu_program5');
+ GL_NV_gpu_shader5 := Int_CheckExtension(Buffer, 'GL_NV_gpu_shader5');
+ GL_NV_shader_buffer_store := Int_CheckExtension(Buffer, 'GL_NV_shader_buffer_store');
+ GL_NV_tessellation_program5 := Int_CheckExtension(Buffer, 'GL_NV_tessellation_program5');
+ GL_NV_vertex_attrib_integer_64bit := Int_CheckExtension(Buffer, 'GL_NV_vertex_attrib_integer_64bit');
+ GL_NV_multisample_coverage := Int_CheckExtension(Buffer, 'GL_NV_multisample_coverage');
+ GL_NV_vdpau_interop := Int_CheckExtension(Buffer, 'GL_NV_vdpau_interop');
+ GL_NV_texture_barrier := Int_CheckExtension(Buffer, 'GL_NV_texture_barrier');
+ // 4.3
+ GL_NV_path_rendering := Int_CheckExtension(Buffer, 'GL_NV_path_rendering');
+ GL_NV_bindless_texture := Int_CheckExtension(Buffer, 'GL_NV_bindless_texture');
+ GL_NV_shader_atomic_float := Int_CheckExtension(Buffer, 'GL_NV_shader_atomic_float');
+
+ // OML
+ GL_OML_interlace := Int_CheckExtension(Buffer, 'GL_OML_interlace');
+ GL_OML_resample := Int_CheckExtension(Buffer, 'GL_OML_resample');
+ GL_OML_subsample := Int_CheckExtension(Buffer, 'GL_OML_subsample');
+
+ // OVR
+ GL_OVR_multiview := Int_CheckExtension(Buffer, 'GL_OVR_multiview');
+ GL_OVR_multiview2 := Int_CheckExtension(Buffer, 'GL_OVR_multiview2');
+
+ // PGI
+ GL_PGI_misc_hints := Int_CheckExtension(Buffer, 'GL_PGI_misc_hints');
+ GL_PGI_vertex_hints := Int_CheckExtension(Buffer, 'GL_PGI_vertex_hints');
+
+ // REND
+ GL_REND_screen_coordinates := Int_CheckExtension(Buffer, 'GL_REND_screen_coordinates');
+
+ // S3
+ GL_S3_s3tc := Int_CheckExtension(Buffer, 'GL_S3_s3tc');
+
+ // SGIS
+ GL_SGIS_detail_texture := Int_CheckExtension(Buffer, 'GL_SGIS_detail_texture');
+ GL_SGIS_fog_function := Int_CheckExtension(Buffer, 'GL_SGIS_fog_function');
+ GL_SGIS_generate_mipmap := Int_CheckExtension(Buffer, 'GL_SGIS_generate_mipmap');
+ GL_SGIS_multisample := Int_CheckExtension(Buffer, 'GL_SGIS_multisample');
+ GL_SGIS_pixel_texture := Int_CheckExtension(Buffer, 'GL_SGIS_pixel_texture');
+ GL_SGIS_point_line_texgen := Int_CheckExtension(Buffer, 'GL_SGIS_point_line_texgen');
+ GL_SGIS_point_parameters := Int_CheckExtension(Buffer, 'GL_SGIS_point_parameters');
+ GL_SGIS_sharpen_texture := Int_CheckExtension(Buffer, 'GL_SGIS_sharpen_texture');
+ GL_SGIS_texture4D := Int_CheckExtension(Buffer, 'GL_SGIS_texture4D');
+ GL_SGIS_texture_border_clamp := Int_CheckExtension(Buffer, 'GL_SGIS_texture_border_clamp');
+ GL_SGIS_texture_color_mask := Int_CheckExtension(Buffer, 'GL_SGIS_texture_color_mask');
+ GL_SGIS_texture_edge_clamp := Int_CheckExtension(Buffer, 'GL_SGIS_texture_edge_clamp');
+ GL_SGIS_texture_filter4 := Int_CheckExtension(Buffer, 'GL_SGIS_texture_filter4');
+ GL_SGIS_texture_lod := Int_CheckExtension(Buffer, 'GL_SGIS_texture_lod');
+ GL_SGIS_texture_select := Int_CheckExtension(Buffer, 'GL_SGIS_texture_select');
+
+ // SGIX
+ GL_FfdMaskSGIX := Int_CheckExtension(Buffer, 'GL_FfdMaskSGIX');
+ GL_SGIX_async := Int_CheckExtension(Buffer, 'GL_SGIX_async');
+ GL_SGIX_async_histogram := Int_CheckExtension(Buffer, 'GL_SGIX_async_histogram');
+ GL_SGIX_async_pixel := Int_CheckExtension(Buffer, 'GL_SGIX_async_pixel');
+ GL_SGIX_blend_alpha_minmax := Int_CheckExtension(Buffer, 'GL_SGIX_blend_alpha_minmax');
+ GL_SGIX_calligraphic_fragment := Int_CheckExtension(Buffer, 'GL_SGIX_calligraphic_fragment');
+ GL_SGIX_clipmap := Int_CheckExtension(Buffer, 'GL_SGIX_clipmap');
+ GL_SGIX_convolution_accuracy := Int_CheckExtension(Buffer, 'GL_SGIX_convolution_accuracy');
+ GL_SGIX_depth_pass_instrument := Int_CheckExtension(Buffer, 'GL_SGIX_depth_pass_instrument');
+ GL_SGIX_depth_texture := Int_CheckExtension(Buffer, 'GL_SGIX_depth_texture');
+ GL_SGIX_flush_raster := Int_CheckExtension(Buffer, 'GL_SGIX_flush_raster');
+ GL_SGIX_fog_offset := Int_CheckExtension(Buffer, 'GL_SGIX_fog_offset');
+ GL_SGIX_fog_scale := Int_CheckExtension(Buffer, 'GL_SGIX_fog_scale');
+ GL_SGIX_fragment_lighting := Int_CheckExtension(Buffer, 'GL_SGIX_fragment_lighting');
+ GL_SGIX_framezoom := Int_CheckExtension(Buffer, 'GL_SGIX_framezoom');
+ GL_SGIX_igloo_interface := Int_CheckExtension(Buffer, 'GL_SGIX_igloo_interface');
+ GL_SGIX_impact_pixel_texture := Int_CheckExtension(Buffer, 'GL_SGIX_impact_pixel_texture');
+ GL_SGIX_instruments := Int_CheckExtension(Buffer, 'GL_SGIX_instruments');
+ GL_SGIX_interlace := Int_CheckExtension(Buffer, 'GL_SGIX_interlace');
+ GL_SGIX_ir_instrument1 := Int_CheckExtension(Buffer, 'GL_SGIX_ir_instrument1');
+ GL_SGIX_list_priority := Int_CheckExtension(Buffer, 'GL_SGIX_list_priority');
+ GL_SGIX_pixel_texture := Int_CheckExtension(Buffer, 'GL_SGIX_pixel_texture');
+ GL_SGIX_pixel_tiles := Int_CheckExtension(Buffer, 'GL_SGIX_pixel_tiles');
+ GL_SGIX_polynomial_ffd := Int_CheckExtension(Buffer, 'GL_SGIX_polynomial_ffd');
+ GL_SGIX_reference_plane := Int_CheckExtension(Buffer, 'GL_SGIX_reference_plane');
+ GL_SGIX_resample := Int_CheckExtension(Buffer, 'GL_SGIX_resample');
+ GL_SGIX_scalebias_hint := Int_CheckExtension(Buffer, 'GL_SGIX_scalebias_hint');
+ GL_SGIX_shadow := Int_CheckExtension(Buffer, 'GL_SGIX_shadow');
+ GL_SGIX_shadow_ambient := Int_CheckExtension(Buffer, 'GL_SGIX_shadow_ambient');
+ GL_SGIX_sprite := Int_CheckExtension(Buffer, 'GL_SGIX_sprite');
+ GL_SGIX_subsample := Int_CheckExtension(Buffer, 'GL_SGIX_subsample');
+ GL_SGIX_tag_sample_buffer := Int_CheckExtension(Buffer, 'GL_SGIX_tag_sample_buffer');
+ GL_SGIX_texture_add_env := Int_CheckExtension(Buffer, 'GL_SGIX_texture_add_env');
+ GL_SGIX_texture_coordinate_clamp := Int_CheckExtension(Buffer, 'GL_SGIX_texture_coordinate_clamp');
+ GL_SGIX_texture_lod_bias := Int_CheckExtension(Buffer, 'GL_SGIX_texture_lod_bias');
+ GL_SGIX_texture_multi_buffer := Int_CheckExtension(Buffer, 'GL_SGIX_texture_multi_buffer');
+ GL_SGIX_texture_scale_bias := Int_CheckExtension(Buffer, 'GL_SGIX_texture_scale_bias');
+ GL_SGIX_texture_select := Int_CheckExtension(Buffer, 'GL_SGIX_texture_select');
+ GL_SGIX_vertex_preclip := Int_CheckExtension(Buffer, 'GL_SGIX_vertex_preclip');
+ GL_SGIX_ycrcb := Int_CheckExtension(Buffer, 'GL_SGIX_ycrcb');
+ GL_SGIX_ycrcb_subsample := Int_CheckExtension(Buffer, 'GL_SGIX_ycrcb_subsample');
+ GL_SGIX_ycrcba := Int_CheckExtension(Buffer, 'GL_SGIX_ycrcba');
+
+ // SGI
+ GL_SGI_color_matrix := Int_CheckExtension(Buffer, 'GL_SGI_color_matrix');
+ GL_SGI_color_table := Int_CheckExtension(Buffer, 'GL_SGI_color_table');
+ GL_SGI_depth_pass_instrument := Int_CheckExtension(Buffer, 'GL_SGI_depth_pass_instrument');
+ GL_SGI_texture_color_table := Int_CheckExtension(Buffer, 'GL_SGI_texture_color_table');
+
+ // SUN
+ GL_SUNX_constant_data := Int_CheckExtension(Buffer, 'GL_SUNX_constant_data');
+ GL_SUN_convolution_border_modes := Int_CheckExtension(Buffer, 'GL_SUN_convolution_border_modes');
+ GL_SUN_global_alpha := Int_CheckExtension(Buffer, 'GL_SUN_global_alpha');
+ GL_SUN_mesh_array := Int_CheckExtension(Buffer, 'GL_SUN_mesh_array');
+ GL_SUN_slice_accum := Int_CheckExtension(Buffer, 'GL_SUN_slice_accum');
+ GL_SUN_triangle_list := Int_CheckExtension(Buffer, 'GL_SUN_triangle_list');
+ GL_SUN_vertex := Int_CheckExtension(Buffer, 'GL_SUN_vertex');
+
+ // WIN
+ GL_WIN_phong_shading := Int_CheckExtension(Buffer, 'GL_WIN_phong_shading');
+ GL_WIN_specular_fog := Int_CheckExtension(Buffer, 'GL_WIN_specular_fog');
+
+ {$IFDEF DGL_WIN}
+ // WGL
+ WGL_3DFX_multisample := Int_CheckExtension(Buffer, 'WGL_3DFX_multisample');
+ WGL_ARB_buffer_region := Int_CheckExtension(Buffer, 'WGL_ARB_buffer_region');
+ WGL_ARB_extensions_string := Int_CheckExtension(Buffer, 'WGL_ARB_extensions_string');
+ WGL_ARB_make_current_read := Int_CheckExtension(Buffer, 'WGL_ARB_make_current_read');
+ WGL_ARB_multisample := Int_CheckExtension(Buffer, 'WGL_ARB_multisample');
+ WGL_ARB_pbuffer := Int_CheckExtension(Buffer, 'WGL_ARB_pbuffer');
+ WGL_ARB_pixel_format := Int_CheckExtension(Buffer, 'WGL_ARB_pixel_format');
+ WGL_ARB_pixel_format_float := Int_CheckExtension(Buffer, 'WGL_ARB_pixel_format_float');
+ WGL_ARB_render_texture := Int_CheckExtension(Buffer, 'WGL_ARB_render_texture');
+ WGL_ARB_create_context := Int_CheckExtension(Buffer, 'WGL_ARB_create_context');
+ WGL_ARB_create_context_profile := Int_CheckExtension(Buffer, 'WGL_ARB_create_context_profile');
+ WGL_ARB_framebuffer_sRGB := Int_CheckExtension(Buffer, 'WGL_ARB_framebuffer_sRGB');
+ WGL_ARB_create_context_robustness := Int_CheckExtension(Buffer, 'WGL_ARB_create_context_robustness');
+ WGL_ATI_pixel_format_float := Int_CheckExtension(Buffer, 'WGL_ATI_pixel_format_float');
+ WGL_AMD_gpu_association := Int_CheckExtension(Buffer, 'WGL_AMD_gpu_association');
+ WGL_EXT_depth_float := Int_CheckExtension(Buffer, 'WGL_EXT_depth_float');
+ WGL_EXT_display_color_table := Int_CheckExtension(Buffer, 'WGL_EXT_display_color_table');
+ WGL_EXT_extensions_string := Int_CheckExtension(Buffer, 'WGL_EXT_extensions_string');
+ WGL_EXT_make_current_read := Int_CheckExtension(Buffer, 'WGL_EXT_make_current_read');
+ WGL_EXT_multisample := Int_CheckExtension(Buffer, 'WGL_EXT_multisample');
+ WGL_EXT_pbuffer := Int_CheckExtension(Buffer, 'WGL_EXT_pbuffer');
+ WGL_EXT_pixel_format := Int_CheckExtension(Buffer, 'WGL_EXT_pixel_format');
+ WGL_EXT_swap_control := Int_CheckExtension(Buffer, 'WGL_EXT_swap_control');
+ WGL_EXT_create_context_es2_profile := Int_CheckExtension(Buffer, 'WGL_EXT_create_context_es2_profile');
+ WGL_I3D_digital_video_control := Int_CheckExtension(Buffer, 'WGL_I3D_digital_video_control');
+ WGL_I3D_gamma := Int_CheckExtension(Buffer, 'WGL_I3D_gamma');
+ WGL_I3D_genlock := Int_CheckExtension(Buffer, 'WGL_I3D_genlock');
+ WGL_I3D_image_buffer := Int_CheckExtension(Buffer, 'WGL_I3D_image_buffer');
+ WGL_I3D_swap_frame_lock := Int_CheckExtension(Buffer, 'WGL_I3D_swap_frame_lock');
+ WGL_I3D_swap_frame_usage := Int_CheckExtension(Buffer, 'WGL_I3D_swap_frame_usage');
+ WGL_NV_float_buffer := Int_CheckExtension(Buffer, 'WGL_NV_float_buffer');
+ WGL_NV_render_depth_texture := Int_CheckExtension(Buffer, 'WGL_NV_render_depth_texture');
+ WGL_NV_render_texture_rectangle := Int_CheckExtension(Buffer, 'WGL_NV_render_texture_rectangle');
+ WGL_NV_vertex_array_range := Int_CheckExtension(Buffer, 'WGL_NV_vertex_array_range');
+ WGL_NV_present_video := Int_CheckExtension(Buffer, 'WGL_NV_present_video');
+ WGL_NV_video_output := Int_CheckExtension(Buffer, 'WGL_NV_video_output');
+ WGL_NV_swap_group := Int_CheckExtension(Buffer, 'WGL_NV_swap_group');
+ WGL_NV_gpu_affinity := Int_CheckExtension(Buffer, 'WGL_NV_gpu_affinity');
+ WGL_NV_video_capture := Int_CheckExtension(Buffer, 'WGL_NV_video_capture');
+ WGL_NV_copy_image := Int_CheckExtension(Buffer, 'WGL_NV_copy_image');
+ WGL_NV_multisample_coverage := Int_CheckExtension(Buffer, 'WGL_NV_multisample_coverage');
+ WGL_NV_DX_interop := Int_CheckExtension(Buffer, 'WGL_NV_multisample_coverage');
+ WGL_OML_sync_control := Int_CheckExtension(Buffer, 'WGL_OML_sync_control');
+ WGL_3DL_stereo_control := Int_CheckExtension(Buffer, 'WGL_3DL_stereo_control');
+ WGL_ARB_context_flush_control := Int_CheckExtension(Buffer, 'WGL_ARB_context_flush_control');
+ WIN_draw_range_elements := Int_CheckExtension(Buffer, 'WIN_draw_range_elements');
+ WIN_swap_hint := Int_CheckExtension(Buffer, 'WIN_swap_hint');
+ {$ENDIF}
+
+ {$IFDEF DGL_LINUX}
+ // GLX
+ GLX_ARB_multisample := Int_CheckExtension(Buffer, 'GLX_ARB_multisample');
+ GLX_ARB_fbconfig_float := Int_CheckExtension(Buffer, 'GLX_ARB_fbconfig_float');
+ GLX_ARB_get_proc_address := Int_CheckExtension(Buffer, 'GLX_ARB_get_proc_address');
+ GLX_ARB_create_context := Int_CheckExtension(Buffer, 'GLX_ARB_create_context');
+ GLX_ARB_create_context_profile := Int_CheckExtension(Buffer, 'GLX_ARB_create_context_profile');
+ GLX_ARB_vertex_buffer_object := Int_CheckExtension(Buffer, 'GLX_ARB_vertex_buffer_object');
+ GLX_ARB_framebuffer_sRGB := Int_CheckExtension(Buffer, 'GLX_ARB_framebuffer_sRGB');
+ GLX_ARB_create_context_robustness := Int_CheckExtension(Buffer, 'GLX_ARB_create_context_robustness');
+ GLX_EXT_visual_info := Int_CheckExtension(Buffer, 'GLX_EXT_visual_info');
+ GLX_EXT_visual_rating := Int_CheckExtension(Buffer, 'GLX_EXT_visual_rating');
+ GLX_EXT_import_context := Int_CheckExtension(Buffer, 'GLX_EXT_import_context');
+ GLX_EXT_fbconfig_packed_float := Int_CheckExtension(Buffer, 'GLX_EXT_fbconfig_packed_float');
+ GLX_EXT_framebuffer_sRGB := Int_CheckExtension(Buffer, 'GLX_EXT_framebuffer_sRGB');
+ GLX_EXT_texture_from_pixmap := Int_CheckExtension(Buffer, 'GLX_EXT_texture_from_pixmap');
+ GLX_EXT_swap_control := Int_CheckExtension(Buffer, 'GLX_EXT_swap_control');
+ GLX_EXT_create_context_es2_profile := Int_CheckExtension(Buffer, 'GLX_EXT_create_context_es2_profile');
+ GLX_ARB_context_flush_control := Int_CheckExtension(Buffer, 'GLX_ARB_context_flush_control');
+ {$ENDIF}
+
+ ImplementationRead := True;
+end;
+
+{$IFDEF DGL_WIN}
+// =============================================================================
+// RaiseLastOSError
+// =============================================================================
+// Needed for compatibility with older Delphiversions
+// =============================================================================
+
+procedure RaiseLastOSError;
+begin
+{$IFDEF FPC}
+ raise Exception.Create('RaiseLastOSError!'); // To-Do: find a better solution
+{$ELSE}
+ {$IFDEF DELPHI6_AND_DOWN} // If Delphi 6 or later
+ SysUtils.RaiseLastWin32Error;
+ {$ELSE}
+ SysUtils.RaiseLastOSError;
+ {$ENDIF}
+{$ENDIF}
+end;
+
+// =============================================================================
+// CreateRenderingContext
+// =============================================================================
+
+function CreateRenderingContext(DC: HDC; Options: TRCOptions; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
+const
+ OBJ_MEMDC = 10;
+ OBJ_ENHMETADC = 12;
+ OBJ_METADC = 4;
+ PFD_DOUBLEBUFFER = $00000001;
+ PFD_STEREO = $00000002;
+ PFD_DRAW_TO_WINDOW = $00000004;
+ PFD_DRAW_TO_BITMAP = $00000008;
+ PFD_SUPPORT_GDI = $00000010;
+ PFD_SUPPORT_OPENGL = $00000020;
+ PFD_TYPE_RGBA = 0;
+ PFD_MAIN_PLANE = 0;
+ PFD_OVERLAY_PLANE = 1;
+ PFD_UNDERLAY_PLANE = LongWord(-1);
+ MemoryDCs = [OBJ_MEMDC, OBJ_METADC, OBJ_ENHMETADC];
+var
+ PFDescriptor: TPixelFormatDescriptor;
+ PixelFormat: Integer;
+ AType: DWORD;
+begin
+ if GL_LibHandle = nil then
+ InitOpenGL;
+
+ FillChar(PFDescriptor, SizeOf(PFDescriptor), 0);
+
+ with PFDescriptor do
+ begin
+ nSize := SizeOf(PFDescriptor);
+ nVersion := 1;
+ dwFlags := PFD_SUPPORT_OPENGL;
+
+ AType := GetObjectType(DC);
+
+ if AType = 0 then
+ RaiseLastOSError;
+
+ if AType in MemoryDCs then
+ dwFlags := dwFlags or PFD_DRAW_TO_BITMAP
+ else
+ dwFlags := dwFlags or PFD_DRAW_TO_WINDOW;
+
+ if opDoubleBuffered in Options then
+ dwFlags := dwFlags or PFD_DOUBLEBUFFER;
+
+ if opGDI in Options then
+ dwFlags := dwFlags or PFD_SUPPORT_GDI;
+
+ if opStereo in Options then
+ dwFlags := dwFlags or PFD_STEREO;
+
+ iPixelType := PFD_TYPE_RGBA;
+ cColorBits := ColorBits;
+ cDepthBits := zBits;
+ cStencilBits := StencilBits;
+ cAccumBits := AccumBits;
+ cAuxBuffers := AuxBuffers;
+
+ if Layer = 0 then
+ iLayerType := PFD_MAIN_PLANE
+ else
+ if Layer > 0 then
+ iLayerType := PFD_OVERLAY_PLANE
+ else
+ iLayerType := Byte(PFD_UNDERLAY_PLANE);
+ end;
+
+ PixelFormat := ChoosePixelFormat(DC, @PFDescriptor);
+
+ if PixelFormat = 0 then
+ RaiseLastOSError;
+
+ if GetPixelFormat(DC) <> PixelFormat then
+ if not SetPixelFormat(DC, PixelFormat, @PFDescriptor) then
+ RaiseLastOSError;
+
+ DescribePixelFormat(DC, PixelFormat, SizeOf(PFDescriptor), PFDescriptor);
+
+ Result := wglCreateContext(DC);
+
+ if Result = 0 then
+ RaiseLastOSError
+ else
+ LastPixelFormat := 0;
+end;
+
+// =============================================================================
+// CreateRenderingContextVersion
+// =============================================================================
+// Creates a context for the more recent OpenGL versions (3.0) and up
+// For that we first need to get a normal GL context for getting the
+// function pointer to wglCreateContextAttribsARB first
+// =============================================================================
+function CreateRenderingContextVersion(DC: HDC; Options: TRCOptions; MajorVersion, MinorVersion : Integer; ForwardCompatible : Boolean; ColorBits, ZBits, StencilBits, AccumBits, AuxBuffers: Integer; Layer: Integer): HGLRC;
+const
+ OBJ_MEMDC = 10;
+ OBJ_ENHMETADC = 12;
+ OBJ_METADC = 4;
+ PFD_DOUBLEBUFFER = $00000001;
+ PFD_STEREO = $00000002;
+ PFD_DRAW_TO_WINDOW = $00000004;
+ PFD_DRAW_TO_BITMAP = $00000008;
+ PFD_SUPPORT_GDI = $00000010;
+ PFD_SUPPORT_OPENGL = $00000020;
+ PFD_TYPE_RGBA = 0;
+ PFD_MAIN_PLANE = 0;
+ PFD_OVERLAY_PLANE = 1;
+ PFD_UNDERLAY_PLANE = LongWord(-1);
+ MemoryDCs = [OBJ_MEMDC, OBJ_METADC, OBJ_ENHMETADC];
+var
+ PFDescriptor : TPixelFormatDescriptor;
+ PixelFormat : Integer;
+ AType : DWORD;
+ LegacyRC : HGLRC;
+ Attribs : array of Integer;
+begin
+ if GL_LibHandle = nil then
+ InitOpenGL;
+
+ if not Assigned(GL_LibHandle) then
+ raise Exception.Create('GL_LibHandle is NIL. Could not load OpenGL library!');
+
+ FillChar(PFDescriptor, SizeOf(PFDescriptor), 0);
+
+ with PFDescriptor do
+ begin
+ nSize := SizeOf(PFDescriptor);
+ nVersion := 1;
+ dwFlags := PFD_SUPPORT_OPENGL;
+ AType := GetObjectType(DC);
+
+ if AType = 0 then
+ RaiseLastOSError;
+
+ if AType in MemoryDCs then
+ dwFlags := dwFlags or PFD_DRAW_TO_BITMAP
+ else
+ dwFlags := dwFlags or PFD_DRAW_TO_WINDOW;
+
+ if opDoubleBuffered in Options then
+ dwFlags := dwFlags or PFD_DOUBLEBUFFER;
+
+ if opGDI in Options then
+ dwFlags := dwFlags or PFD_SUPPORT_GDI;
+
+ if opStereo in Options then
+ dwFlags := dwFlags or PFD_STEREO;
+
+ iPixelType := PFD_TYPE_RGBA;
+ cColorBits := ColorBits;
+ cDepthBits := zBits;
+ cStencilBits := StencilBits;
+ cAccumBits := AccumBits;
+ cAuxBuffers := AuxBuffers;
+
+ if Layer = 0 then
+ iLayerType := PFD_MAIN_PLANE
+ else
+ if Layer > 0 then
+ iLayerType := PFD_OVERLAY_PLANE
+ else
+ iLayerType := Byte(PFD_UNDERLAY_PLANE);
+ end;
+
+ PixelFormat := ChoosePixelFormat(DC, @PFDescriptor);
+
+ if PixelFormat = 0 then
+ RaiseLastOSError;
+
+ if GetPixelFormat(DC) <> PixelFormat then
+ if not SetPixelFormat(DC, PixelFormat, @PFDescriptor) then
+ RaiseLastOSError;
+
+ DescribePixelFormat(DC, PixelFormat, SizeOf(PFDescriptor), PFDescriptor);
+
+ // Create legacy render context first for we need function pointers to
+ // create new OpenGL render contexts
+ LegacyRC := wglCreateContext(DC);
+ wglMakeCurrent(DC, LegacyRC);
+
+ // Set attributes to describe our requested context
+ SetLength(Attribs, 5);
+ Attribs[0] := WGL_CONTEXT_MAJOR_VERSION_ARB;
+ Attribs[1] := MajorVersion;
+ Attribs[2] := WGL_CONTEXT_MINOR_VERSION_ARB;
+ Attribs[3] := MinorVersion;
+
+ // Add context flag for forward compatible context
+ // Forward compatible means no more support for legacy functions like
+ // immediate mode (glvertex, glrotate, gltranslate, etc.)
+ if ForwardCompatible then
+ begin
+ SetLength(Attribs, Length(Attribs)+2);
+ Attribs[4] := WGL_CONTEXT_FLAGS_ARB;
+ Attribs[5] := WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ end;
+
+ // Attribute flags must be finalized with a zero
+ Attribs[High(Attribs)] := 0;
+
+ // Get function pointer for new context creation function
+ wglCreateContextAttribsARB := wglGetProcAddress('wglCreateContextAttribsARB');
+
+ if not Assigned(wglCreateContextAttribsARB) then
+ begin
+ raise Exception.Create('Could not get function pointer adress for wglCreateContextAttribsARB - OpenGL 3.x and above not supported!');
+ wglDeleteContext(LegacyRC);
+ exit;
+ end;
+
+ // Create context
+ Result := wglCreateContextAttribsARB(DC, 0, @Attribs[0]);
+
+ if Result = 0 then
+ begin
+ raise Exception.Create('Could not create the desired OpenGL rendering context!');
+ wglDeleteContext(LegacyRC);
+ exit;
+ end;
+
+ wglDeleteContext(LegacyRC);
+
+ if Result = 0 then
+ RaiseLastOSError
+ else
+ LastPixelFormat := 0;
+end;
+
+// =============================================================================
+// DestroyRenderingContext
+// =============================================================================
+
+procedure DestroyRenderingContext(RC: HGLRC);
+begin
+ wglDeleteContext(RC);
+end;
+
+
+// =============================================================================
+// ActivateRenderingContext
+// =============================================================================
+
+procedure ActivateRenderingContext(DC: HDC; RC: HGLRC; loadext: boolean = true);
+begin
+ Assert((DC <> 0), 'DC must not be 0');
+ Assert((RC <> 0), 'RC must not be 0');
+
+ wglMakeCurrent(DC, RC);
+
+ {$ifdef DGL_TINY_HEADER}
+ ReadCoreVersion;
+ {$else}
+ ReadImplementationProperties;
+
+ if (loadext) then
+ ReadExtensions;
+ {$endif}
+end;
+
+// =============================================================================
+// DeactivateRenderingContext
+// =============================================================================
+
+procedure DeactivateRenderingContext;
+begin
+ wglMakeCurrent(0, 0);
+end;
+{$ENDIF}
+
+
+initialization
+
+{$IFDEF CPU386}{$IFNDEF DARWIN}
+ Set8087CW($133F);
+{$ENDIF}{$ENDIF}
+{$IFDEF DGL_64BIT}
+ SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,exOverflow, exUnderflow, exPrecision]);
+{$ENDIF}
+
+
+finalization
+
+end.
+
diff --git a/units/sdl2_for_pascal/ctypes.inc b/units/sdl2_for_pascal/ctypes.inc
new file mode 100644
index 0000000..cd0b26f
--- /dev/null
+++ b/units/sdl2_for_pascal/ctypes.inc
@@ -0,0 +1,203 @@
+// C data types
+
+{
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2013 Sam Lantinga
+
+ Pascal-Header-Conversion
+ Copyright (C) 2012-2020 Tim Blume aka End/EV1313
+
+ SDL2-for-Pascal
+ Copyright (C) 2020-2021 PGD Community
+
+ This file is part of the project above. It has solely the purpose
+ to map common C data types correctly by Pascal compilers.
+
+ FPC: Most C data types are found in the native ctypes unit.
+ Delphi + others: Relies on this file for C data type mapping.
+
+ These native C types should be strictly separated from
+ types defined by SDL which can be found in sdlstdinc.inc.
+}
+
+{$IFNDEF FPC}
+type
+ DWord = LongWord;
+
+ ppcbool = ^pcbool;
+ pcbool = ^cbool;
+ cbool = LongBool;
+ {$EXTERNALSYM cbool}
+
+ ppcint8 = ^pcint8;
+ pcint8 = ^cint8;
+ cint8 = ShortInt;
+ {$EXTERNALSYM cint8}
+
+ pcuint8 = ^cuint8;
+ cuint8 = Byte;
+ {$EXTERNALSYM cuint8}
+
+ ppcint16 = ^pcint16;
+ pcint16 = ^cint16;
+ cint16 = SmallInt;
+ {$EXTERNALSYM cint16}
+
+ ppcuint16 = ^pcuint16;
+ pcuint16 = ^cuint16;
+ cuint16 = Word;
+ {$EXTERNALSYM cuint16}
+
+ ppcushort = ^pcushort;
+ pcushort = ^cushort;
+ cushort = Word;
+ {$EXTERNALSYM cushort}
+
+ ppcint32 = ^pcint32;
+ pcint32 = ^cint32;
+ cint32 = LongInt;
+ {$EXTERNALSYM cint32}
+
+ ppcuint32 = ^pcuint32;
+ pcuint32 = ^cuint32;
+ cuint32 = LongWord;
+ {$EXTERNALSYM cuint32}
+
+ {$IFNDEF Has_Int64}
+ ppcint64 = ^pcint64;
+ pcint64 = ^cint64;
+ cint64 = record
+ hi: cuint32;
+ lo: cuint32;
+ end;
+ {$EXTERNALSYM cint64}
+
+ ppcuint64 = ^pcuint64;
+ pcuint64 = ^cuint64;
+ cuint64 = record
+ hi: cuint32;
+ lo: cuint32;
+ end;
+ {$EXTERNALSYM cuint64}
+ {$ELSE}
+ ppcint64 = ^pcint64;
+ pcint64 = ^cint64;
+ cint64 = Int64;
+ {$EXTERNALSYM cint64}
+
+ ppcuint64 = ^pcuint64;
+ pcuint64 = ^cuint64;
+ cuint64 = UInt64;
+ {$EXTERNALSYM cuint64}
+ {$ENDIF}
+
+ ppcsize_t = ^pcsize_t;
+ pcsize_t = ^csize_t;
+ {$IFNDEF WIN64}
+ csize_t = cuint32;
+ {$ELSE}
+ csize_t = cuint64;
+ {$ENDIF}
+ {$EXTERNALSYM csize_t}
+
+ ppcfloat = ^pcfloat;
+ pcfloat = ^cfloat;
+ cfloat = Single;
+ {$EXTERNALSYM cfloat}
+
+ ppcdouble = ^pcdouble;
+ pcdouble = ^cdouble;
+ cdouble = Double;
+ {$EXTERNALSYM cfloat}
+
+ ppcint = ^pcint;
+ pcint = ^cint;
+
+ ppcuint = ^pcuint;
+ pcuint = ^cuint;
+
+ ppclong = ^pclong;
+ pclong = ^clong;
+
+ ppculong = ^pculong;
+ pculong = ^culong;
+ {
+ Integer type sizes based on:
+ https://en.cppreference.com/w/c/language/arithmetic_types#Data_models
+ }
+ cint = cint32;
+ cuint = cuint32;
+ {$IF DEFINED(CPU32) OR DEFINED(CPU32BITS)}
+ clong = cint32;
+ culong = cuint32;
+ {$ELSE} // 64-bit
+ {$IFDEF MSWINDOWS}
+ clong = cint32;
+ culong = cuint32;
+ {$ELSE}
+ clong = cint64;
+ culong = cuint64;
+ {$ENDIF}
+ {$ENDIF}
+ {$EXTERNALSYM cint}
+ {$EXTERNALSYM cuint}
+ {$EXTERNALSYM clong}
+ {$EXTERNALSYM culong}
+
+{$ENDIF}
+
+{ Data types for all compilers }
+type
+ PPUInt8Array = ^PUInt8Array;
+ PUInt8Array = ^TUInt8Array;
+ TUInt8Array = array [0..MAXINT shr 1] of cuint8;
+
+ ppcuint8 = ^pcuint8;
+
+ { "The following type designates an unsigned integer type [or signed respectivly]
+ with the property that any valid pointer to void can be
+ converted to this type, then converted back to a pointer
+ to void, and the result will compare equal to the original
+ pointer: uintptr_t"
+ Source: https://pubs.opengroup.org/onlinepubs/000095399/basedefs/stdint.h.html
+ }
+ {$IFNDEF FPC}
+ cuintptr_t = UIntPtr;
+ {$EXTERNALSYM cuintptr_t}
+ cintptr_t = IntPtr;
+ {$EXTERNALSYM cintptr_t}
+ {$ELSE}
+ cuintptr_t = PtrUInt;
+ {$EXTERNALSYM cuintptr_t}
+ cintptr_t = PtrInt;
+ {$EXTERNALSYM cintptr_t}
+ {$ENDIF}
+
+ {$IFDEF WANT_CWCHAR_T}
+ (* wchar_t is the "wide character" type of the C language.
+ * The size of this type is platform- and compiler-dependent.
+ *
+ * While FPC does have it's own "wide character" type, System.WideChar,
+ * that one is defined as always being 16-bits, so we can't re-use it here.
+ *
+ * When using FPC on Unices, the UnixType unit provides a wchar_t definition.
+ *
+ * On other systems/compiler combos, let's just go
+ * by what the CPP reference wiki claims, i.e:
+ * - wchar_t is 16-bits on Windows
+ * - wchar_t is 32-bits on Linux "and many other non-Windows systems"
+ *
+ * See: https://en.cppreference.com/w/cpp/language/types#Character_types
+ *)
+ {$IF DEFINED(FPC) AND DEFINED(UNIX)}
+ cwchar_t = UnixType.wchar_t;
+ {$ELSE}
+ {$IF DEFINED(WIN32) OR DEFINED(WIN64)}
+ cwchar_t = cuint16;
+ {$ELSE}
+ cwchar_t = cuint32;
+ {$ENDIF}
+ {$ENDIF}
+ {$EXTERNALSYM cwchar_t}
+ pcwchar_t = ^cwchar_t;
+ {$ENDIF}
diff --git a/units/sdl2_for_pascal/jedi.inc b/units/sdl2_for_pascal/jedi.inc
new file mode 100644
index 0000000..0e305e7
--- /dev/null
+++ b/units/sdl2_for_pascal/jedi.inc
@@ -0,0 +1,516 @@
+{
+ This file (jedi.inc) is part of SDL2-for-Pascal.
+ It defines some variables for several Pascal-Compilers and OS-versions.
+
+ It is based upon:
+
+ Pascal-Header-Conversion
+ Copyright (c) 2012/13 Tim Blume aka End
+
+ jedi-sdl.inc: Global Conditional Definitions for JEDI-SDL cross-compilation
+ Copyright (C) 2000 - 2013 Prof. Abimbola Olowofoyeku and Tim Blume
+ See: https://github.com/ev1313/
+
+ 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.
+}
+
+{.$define Debug} { uncomment for debugging }
+
+{$IFNDEF FPC}
+ {$IFDEF Debug}
+ {$F+,D+,Q-,L+,R+,I-,S+,Y+,A+}
+ {$ELSE}
+ {$F+,Q-,R-,S-,I-,A+}
+ {$ENDIF}
+{$ELSE}
+ {$MODE DELPHI}
+ {$IFDEF VER3_2}
+ {$WARN 6058 OFF} { Turn off compiler hint: Call to subroutine "..." marked as inline is not inlined
+ See: https://forum.lazarus.freepascal.org/index.php?topic=50585.0 }
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF LINUX}
+{$DEFINE UNIX}
+{$ENDIF}
+
+{$IFDEF ver70}
+ {$IFDEF Windows}
+ {$DEFINE Win16}
+ {$ENDIF Windows}
+ {$IFDEF MSDOS}
+ {$DEFINE NO_EXPORTS}
+ {$ENDIF MSDOS}
+ {$IFDEF DPMI}
+ {$DEFINE BP_DPMI}
+ {$ENDIF}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver70}
+
+{$IFDEF ver80}
+ {$DEFINE Delphi} {Delphi 1.x}
+ {$DEFINE Delphi16}
+ {$DEFINE Win16}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver80}
+
+{$IFDEF ver90}
+ {$DEFINE Delphi} {Delphi 2.x}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver90}
+
+{$IFDEF ver100}
+ {$DEFINE Delphi} {Delphi 3.x}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver100}
+
+{$IFDEF ver93}
+ {$DEFINE Delphi} {C++ Builder 1.x}
+ {$DEFINE WINDOWS}
+{$ENDIF ver93}
+
+{$IFDEF ver110}
+ {$DEFINE Delphi} {C++ Builder 3.x}
+ {$DEFINE WINDOWS}
+{$ENDIF ver110}
+
+{$IFDEF ver120}
+ {$DEFINE Delphi} {Delphi 4.x}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver120}
+
+{$IFDEF ver130}
+ {$DEFINE Delphi} {Delphi / C++ Builder 5.x}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver130}
+
+{$IFDEF ver140}
+ {$DEFINE Delphi} {Delphi / C++ Builder 6.x}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver140}
+
+{$IFDEF ver150}
+ {$DEFINE Delphi} {Delphi 7.x}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver150}
+
+{$IFDEF ver160}
+ {$DEFINE Delphi} {Delphi 8.x}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver160}
+
+{$IFDEF ver170}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2005}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver170}
+
+{$IFDEF ver180}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2006 / 2007}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver180}
+
+{$IFDEF ver185}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2007}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver185}
+
+{$IFDEF ver190}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2007 }
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver190}
+
+{$IFDEF ver200}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2009 }
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver200}
+
+{$IFDEF ver210}
+ {$DEFINE Delphi} {Delphi / C++ Builder 2010}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver210}
+
+{$IFDEF ver220}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver220}
+
+{$IFDEF ver230}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE2}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver230}
+
+{$IFDEF ver240}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE4}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$DEFINE Delphi17UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver240}
+
+{$IFDEF ver250}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE5}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$DEFINE Delphi17UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver250}
+
+{$IFDEF ver260}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE6}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$DEFINE Delphi17UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver260}
+
+{$IFDEF ver270}
+ {$DEFINE Delphi} {Delphi / C++ Builder XE7}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$DEFINE Delphi17UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver270}
+
+{$IFNDEF FPC}
+{$IF CompilerVersion > 27}
+ {$DEFINE Delphi} {Delphi / C++ Builder}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$DEFINE Delphi11UP}
+ {$DEFINE Delphi12UP}
+ {$DEFINE Delphi13UP}
+ {$DEFINE Delphi14UP}
+ {$DEFINE Delphi15UP}
+ {$DEFINE Delphi16UP}
+ {$DEFINE Delphi17UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Native}
+ {$DEFINE HAS_TYPES}
+{$IFEND}
+{$ENDIF}
+
+{*************** define 16/32/64 Bit ********************}
+
+{$IFDEF WIN16}
+ {$DEFINE 16BIT}
+ {$DEFINE WINDOWS}
+{$ELSE}
+ {$IFDEF WIN32}
+ {$DEFINE 32BIT}
+ {$DEFINE WINDOWS}
+ {$ELSE}
+ {$IFDEF WIN64}
+ {$DEFINE 64BIT}
+ {$DEFINE WINDOWS}
+ {$ELSE}
+ //TODO!!
+ {$DEFINE 32BIT}
+ {$ENDIF}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF Delphi}
+ {$DEFINE USE_STDCALL}
+ {$IFDEF 32Bit}
+ {$DEFINE DELPHI32}
+ {$ELSE}
+ {$IFDEF 64Bit}
+ {$DEFINE DELPHI64}
+ {$ELSE}
+ {$DEFINE DELPHI16}
+ {$ENDIF}
+ {$ENDIF}
+ //{$ALIGN ON}
+{$ENDIF Delphi}
+
+{$IFDEF FPC}
+ {$H+}
+ {$PACKRECORDS C} // Added for record
+ {$PACKENUM DEFAULT} // Added for c-like enumerators
+ {$MACRO ON} // Added For OpenGL
+ {$DEFINE Delphi}
+ {$DEFINE UseAT}
+ {$UNDEF USE_STDCALL}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE Has_UInt64}
+ {$DEFINE Has_Int64}
+ {$DEFINE Has_Native}
+ {$DEFINE NOCRT}
+ {$IFDEF UNIX}
+ {$DEFINE fpc_unix}
+ {$ELSE}
+ {$DEFINE __OS_DOS__}
+ {$ENDIF}
+ {$IFDEF WIN32}
+ {$DEFINE UseWin}
+ {$ENDIF}
+ {$DEFINE HAS_TYPES}
+{$ENDIF FPC}
+
+{$IFDEF Win16}
+ {$K+} {smart callbacks}
+{$ENDIF Win16}
+
+{$IFDEF Win32}
+ {$DEFINE OS_BigMem}
+{$ENDIF Win32}
+
+{ ************************** dos/dos-like platforms **************}
+{$IFDEF Windows}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE UseWin}
+ {$DEFINE MSWINDOWS}
+{$ENDIF Delphi}
+
+{$IFDEF OS2}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF Delphi}
+
+{$IFDEF UseWin}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF Win16}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF BP_DPMI}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF USE_STDCALL}
+ {$DEFINE BY_NAME}
+{$ENDIF}
+
+{*************** define LITTLE ENDIAN platforms ********************}
+
+
+{$IFDEF Delphi}
+ {$DEFINE IA32}
+{$ENDIF}
+
+{$IFDEF FPC}
+ {$IFDEF FPC_LITTLE_ENDIAN}
+ {$DEFINE IA32}
+ {$ENDIF}
+{$ENDIF}
diff --git a/units/sdl2_for_pascal/sdl.inc b/units/sdl2_for_pascal/sdl.inc
new file mode 100644
index 0000000..af51ffa
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl.inc
@@ -0,0 +1,114 @@
+// based on "sdl.h"
+
+type
+ PPSDL_Init = ^PSDL_Init;
+ PSDL_Init = ^TSDL_Init;
+ TSDL_Init = type cuint32;
+
+const
+ SDL_INIT_TIMER = TSDL_Init($00000001);
+ {$EXTERNALSYM SDL_INIT_TIMER}
+ SDL_INIT_AUDIO = TSDL_Init($00000010);
+ {$EXTERNALSYM SDL_INIT_AUDIO}
+ SDL_INIT_VIDEO = TSDL_Init($00000020); // SDL_INIT_VIDEO implies SDL_INIT_EVENTS
+ {$EXTERNALSYM SDL_INIT_VIDEO}
+ SDL_INIT_JOYSTICK = TSDL_Init($00000200); // SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS
+ {$EXTERNALSYM SDL_INIT_JOYSTICK}
+ SDL_INIT_HAPTIC = TSDL_Init($00001000);
+ {$EXTERNALSYM SDL_INIT_HAPTIC}
+ SDL_INIT_GAMECONTROLLER = TSDL_Init($00002000); //turn on game controller also implicitly does JOYSTICK
+ {$EXTERNALSYM SDL_INIT_GAMECONTROLLER} // SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK
+ SDL_INIT_EVENTS = TSDL_Init($00004000);
+ {$EXTERNALSYM SDL_INIT_EVENTS}
+ SDL_INIT_SENSOR = TSDL_Init($00008000);
+ {$EXTERNALSYM SDL_INIT_SENSOR}
+ SDL_INIT_NOPARACHUTE = TSDL_Init($00100000); //Don't catch fatal signals
+ {$EXTERNALSYM SDL_INIT_NOPARACHUTE} // compatibility; this flag is ignored.
+ SDL_INIT_EVERYTHING = TSDL_Init(
+ SDL_INIT_TIMER or
+ SDL_INIT_AUDIO or
+ SDL_INIT_VIDEO or
+ SDL_INIT_EVENTS or
+ SDL_INIT_JOYSTICK or
+ SDL_INIT_HAPTIC or
+ SDL_INIT_GAMECONTROLLER or
+ SDL_INIT_SENSOR
+ );
+ {$EXTERNALSYM SDL_INIT_EVERYTHING}
+
+{**
+ * This function initializes the subsystems specified by flags
+ * Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
+ * signal handlers for some commonly ignored fatal signals (like SIGSEGV).
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Init_func = function(flags: TSDL_Init): cint; cdecl;
+Var
+ SDL_Init : TSDL_Init_func = Nil;
+{$else}
+
+function SDL_Init(flags: TSDL_Init): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Init' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function initializes specific SDL subsystems
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_InitSubSystem_func = function(flags: TSDL_Init): cint; cdecl;
+Var
+ SDL_InitSubSystem : TSDL_InitSubSystem_func = Nil;
+{$else}
+
+function SDL_InitSubSystem(flags: TSDL_Init): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_InitSubSystem' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function cleans up specific SDL subsystems
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_QuitSubSystem_proc = procedure(flags: TSDL_Init); cdecl;
+Var
+ SDL_QuitSubSystem : TSDL_QuitSubSystem_proc = Nil;
+{$else}
+
+procedure SDL_QuitSubSystem(flags: TSDL_Init); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_QuitSubSystem' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function returns a mask of the specified subsystems which have
+ * previously been initialized.
+ *
+ * If flags is 0, it returns a mask of all initialized subsystems.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WasInit_func = function(flags: TSDL_Init): cuint32; cdecl;
+Var
+ SDL_WasInit : TSDL_WasInit_func = Nil;
+{$else}
+
+function SDL_WasInit(flags: TSDL_Init): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WasInit' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function cleans up all initialized subsystems. You should
+ * call it upon all exit conditions.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Quit_proc = procedure(); cdecl;
+Var
+ SDL_Quit : TSDL_Quit_proc = Nil;
+{$else}
+
+procedure SDL_Quit(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Quit' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdl2.pas b/units/sdl2_for_pascal/sdl2.pas
new file mode 100644
index 0000000..8c2bb22
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2.pas
@@ -0,0 +1,529 @@
+unit sdl2;
+
+{
+ SDL2-for-Pascal
+ =================
+ Pascal units for SDL2 - Simple Direct MediaLayer, Version 2
+
+ Copyright (C) 2020-2023 PGD Community
+ Maintainers: M. J. Molski and suve
+ Visit: https://github.com/PascalGameDevelopment/SDL2-for-Pascal
+
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2023 Sam Lantinga
+ Visit: http://libsdl.org
+
+ SDL2-for-Pascal is based upon:
+
+ Pascal-Header-Conversion
+ Copyright (C) 2012-2020 Tim Blume aka End/EV1313
+
+ JEDI-SDL : Pascal units for SDL
+ Copyright (C) 2000 - 2004 Dominique Louis
+
+ sdl2.pas is based on the C header files in the include folder
+ of the original Simple DirectMedia Layer repository.
+ See: https://github.com/libsdl-org/SDL
+
+ OpenGL header files are not translated:
+ "sdl_opengl.h",
+ "sdl_opengles.h"
+ "sdl_opengles2.h"
+
+ There is a much better OpenGL-Header avaible at delphigl.com: dglopengl.pas
+ See: https://github.com/SaschaWillems/dglOpenGL
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no case 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.
+
+ Special Thanks to:
+
+ - Tim Blume and everyone else contributing to the "Pascal-Header-Conversion"
+ - DelphiGL.com - Community
+ - Domenique Louis and everyone else from the JEDI-Team
+ - Sam Latinga and everyone else from the SDL-Team
+}
+
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+{$DEFINE SDL}
+
+{$I jedi.inc}
+
+(*
+ * If you get a compiler error with missing file
+ * just create a file namend "sdl2_cfg.inc" in your project folder and
+ * insert the following content:
+ *
+ * ---------- Content of file ----------
+
+ {*
+ * set this define if you want to use runtime loading instead of static linking
+ * ! Attention !
+ * Not all functions are "ported" yet, so use is on own risk
+ * port missing functions.
+ *}
+ {.$DEFINE SDL_RUNTIME_LOADING}
+
+ * ---------- End content of file ----------
+ *
+ * ! Attention !
+ * If you use the runtime loading feature, don't forget to call the SDL_LoadLib
+ * function.
+ *)
+
+{$I sdl2_cfg.inc}
+
+interface
+
+ {$IFDEF WINDOWS}
+ uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ Windows;
+ {$ENDIF}
+
+ {$IF DEFINED(UNIX) AND NOT DEFINED(ANDROID)}
+ uses
+ {$IFDEF FPC}
+ ctypes,
+ UnixType,
+ {$ENDIF}
+ {$IFDEF DARWIN}
+ CocoaAll;
+ {$ELSE}
+ X,
+ XLib;
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IF DEFINED(UNIX) AND DEFINED(ANDROID) AND DEFINED(FPC)}
+ uses
+ ctypes,
+ UnixType;
+ {$ENDIF}
+
+const
+
+ {$IFDEF WINDOWS}
+ SDL_LibName = 'SDL2.dll';
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ SDL_LibName = 'libSDL2.dylib';
+ {$IFDEF FPC}
+ {$LINKLIB libSDL2}
+ {$ENDIF}
+ {$ELSE}
+ {$IFDEF FPC}
+ SDL_LibName = 'libSDL2.so';
+ {$ELSE}
+ SDL_LibName = 'libSDL2.so.0';
+ {$ENDIF}
+ {$MESSAGE HINT 'Known MESA bug may generate float-point exception in software graphics mode! See https://github.com/PascalGameDevelopment/SDL2-for-Pascal/issues/56 for reference.'}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF MACOS}
+ SDL_LibName = 'SDL2';
+ {$IFDEF FPC}
+ {$linklib libSDL2}
+ {$ENDIF}
+ {$ENDIF}
+
+
+{$DEFINE WANT_CWCHAR_T}
+{$I ctypes.inc} // C data types
+
+ {SDL2 version of the represented header file}
+{$I sdlstdinc.inc}
+{$I sdlversion.inc} // 2.0.14
+{$I sdlerror.inc} // 2.0.14
+{$I sdlplatform.inc} // 2.0.14
+{$I sdlpower.inc} // 2.0.14
+{$I sdlthread.inc} // 2.30.2
+{$I sdlatomic.inc} // 2.0.20
+{$I sdlmutex.inc} // 2.26.5
+{$I sdltimer.inc} // 2.0.18
+{$I sdlpixels.inc} // 2.26.5
+{$I sdlrect.inc} // 2.24.0
+{$I sdlrwops.inc} // 2.0.14
+{$I sdlaudio.inc} // 2.26.3
+{$I sdlblendmode.inc} // 2.0.14
+{$I sdlsurface.inc} // 2.0.14
+{$I sdlvideo.inc} // 2.28.0
+{$I sdlshape.inc} // 2.24.0
+{$I sdlhints.inc} // 2.26.0
+{$I sdlloadso.inc} // 2.24.1
+{$I sdlmessagebox.inc} // 2.0.14
+{$I sdlrenderer.inc} // 2.0.22
+{$I sdlscancode.inc} // 2.26.2
+{$I sdlkeycode.inc} // 2.26.2
+{$I sdlkeyboard.inc} // 2.24.1
+{$I sdlmouse.inc} // 2.0.24
+{$I sdlguid.inc} // 2.24.0
+{$I sdljoystick.inc} // 2.24.0
+{$I sdlsensor.inc} // 2.26.0
+{$I sdlgamecontroller.inc} // 2.30.0
+{$I sdlhaptic.inc} // 2.26.2
+{$I sdlhidapi.inc} // 2.0.18
+{$I sdltouch.inc} // 2.24.0
+{$I sdlgesture.inc} // 2.26.2
+{$I sdlsyswm.inc} // 2.26.5
+{$I sdlevents.inc} // 2.24.0
+{$I sdllocale.inc} // 2.0.14
+{$I sdlclipboard.inc} // 2.24.1
+{$I sdlcpuinfo.inc} // 2.0.14
+{$I sdlfilesystem.inc} // 2.24.1
+{$I sdllog.inc} // 2.0.14
+{$I sdlmisc.inc} // 2.0.14
+{$I sdlsystem.inc} // 2.24.0
+{$I sdl.inc} // 2.0.14
+
+{$ifdef SDL_RUNTIME_LOADING}
+Function SDL_LoadLib(LibFilename: String): Boolean;
+Procedure SDL_UnLoadLib();
+{$endif}
+
+implementation
+
+(*
+ * We need an strlen() implementation for some operations on C-strings.
+ * FPC ships one in the Strings unit; Delphi has one in the AnsiStrings unit.
+ * Since FPC defines "DELPHI" when building in Delphi-compatibility mode,
+ * check if "FPC" is defined to determine which compiler is used.
+ *)
+uses
+ {$IFDEF FPC}
+ Strings
+ {$ELSE}
+ AnsiStrings
+ {$ENDIF}
+ {$ifdef SDL_RUNTIME_LOADING}
+ , dynlibs
+ {$endif}
+ ;
+
+{$I sdl_runtime_linking.inc}
+
+// Macros from "sdl_version.h"
+procedure SDL_VERSION(out x: TSDL_Version);
+begin
+ x.major := SDL_MAJOR_VERSION;
+ x.minor := SDL_MINOR_VERSION;
+ x.patch := SDL_PATCHLEVEL;
+end;
+
+function SDL_VERSIONNUM(X,Y,Z: cuint8): Cardinal;
+begin
+ Result := X*1000 + Y*100 + Z;
+end;
+
+function SDL_COMPILEDVERSION: Cardinal;
+begin
+ Result := SDL_VERSIONNUM(SDL_MAJOR_VERSION,
+ SDL_MINOR_VERSION,
+ SDL_PATCHLEVEL);
+end;
+
+function SDL_VERSION_ATLEAST(X,Y,Z: cuint8): Boolean;
+begin
+ Result := SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X,Y,Z);
+end;
+
+//Macros from "sdl_mouse.h"
+function SDL_Button(X: cint): cint;
+begin
+ Result := 1 shl (X - 1);
+end;
+
+{$IFDEF WINDOWS}
+//from "sdl_thread.h"
+
+function SDL_CreateThread2(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer): PSDL_Thread; overload;
+begin
+ Result := SDL_CreateThread(fn,name,data,nil,nil);
+end;
+
+function SDL_CreateThreadWithStackSize2(fn: TSDL_ThreadFunction;
+ name: PAnsiChar; const stacksize: csize_t; data: Pointer
+ ): PSDL_Thread; overload;
+begin
+ Result := SDL_CreateThreadWithStackSize(
+ fn,name,stacksize,data,nil,nil);
+end;
+
+{$ENDIF}
+
+//from "sdl_rect.h"
+function SDL_PointInRect(const p: PSDL_Point; const r: PSDL_Rect): Boolean;
+begin
+ Result :=
+ (p^.x >= r^.x) and (p^.x < (r^.x + r^.w))
+ and
+ (p^.y >= r^.y) and (p^.y < (r^.y + r^.h))
+end;
+
+function SDL_RectEmpty(const r: PSDL_Rect): Boolean;
+begin
+ Result := (r = NIL) or (r^.w <= 0) or (r^.h <= 0);
+end;
+
+function SDL_RectEquals(const a, b: PSDL_Rect): Boolean;
+begin
+ Result := (a^.x = b^.x) and (a^.y = b^.y) and (a^.w = b^.w) and (a^.h = b^.h);
+end;
+
+function SDL_PointInFRect(const p: PSDL_FPoint; const r: PSDL_FRect): Boolean;
+begin
+ Result :=
+ (p^.x >= r^.x) and (p^.x < (r^.x + r^.w))
+ and
+ (p^.y >= r^.y) and (p^.y < (r^.y + r^.h))
+end;
+
+function SDL_FRectEmpty(const r: PSDL_FRect): Boolean;
+begin
+ Result := (r = NIL) or (r^.w <= cfloat(0.0)) or (r^.h <= cfloat(0.0))
+end;
+
+function SDL_FRectEqualsEpsilon(const a, b: PSDL_FRect; const epsilon: cfloat): Boolean;
+begin
+ Result :=
+ (a <> NIL) and
+ (b <> NIL) and
+ (
+ (a = b)
+ or
+ (
+ (SDL_fabsf(a^.x - b^.x) <= epsilon)
+ and
+ (SDL_fabsf(a^.y - b^.y) <= epsilon)
+ and
+ (SDL_fabsf(a^.w - b^.w) <= epsilon)
+ and
+ (SDL_fabsf(a^.h - b^.h) <= epsilon)
+ )
+ )
+end;
+
+function SDL_FRectEquals(const a, b: PSDL_FRect): Boolean; Inline;
+begin
+ Result := SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON)
+end;
+
+//from "sdl_atomic.h"
+function SDL_AtomicIncRef(atomic: PSDL_Atomic): cint;
+begin
+ Result := SDL_AtomicAdd(atomic, 1)
+end;
+
+function SDL_AtomicDecRef(atomic: PSDL_Atomic): Boolean;
+begin
+ Result := SDL_AtomicAdd(atomic, -1) = 1
+end;
+
+procedure SDL_CompilerBarrier();
+{$IFDEF FPC}
+begin
+ ReadWriteBarrier()
+{$ELSE}
+var
+ lock: TSDL_SpinLock;
+begin
+ lock := 0;
+ SDL_AtomicLock(@lock);
+ SDL_AtomicUnlock(@lock)
+{$ENDIF}
+end;
+
+//from "sdl_audio.h"
+
+function SDL_LoadWAV(file_: PAnsiChar; spec: PSDL_AudioSpec; audio_buf: ppcuint8; audio_len: pcuint32): PSDL_AudioSpec;
+begin
+ Result := SDL_LoadWAV_RW(SDL_RWFromFile(file_, 'rb'), 1, spec, audio_buf, audio_len);
+end;
+
+function SDL_AUDIO_BITSIZE(x: Cardinal): Cardinal;
+begin
+ Result := x and SDL_AUDIO_MASK_BITSIZE;
+end;
+
+function SDL_AUDIO_ISFLOAT(x: Cardinal): Cardinal;
+begin
+ Result := x and SDL_AUDIO_MASK_DATATYPE;
+end;
+
+function SDL_AUDIO_ISBIGENDIAN(x: Cardinal): Cardinal;
+begin
+ Result := x and SDL_AUDIO_MASK_ENDIAN;
+end;
+
+function SDL_AUDIO_ISSIGNED(x: Cardinal): Cardinal;
+begin
+ Result := x and SDL_AUDIO_MASK_SIGNED;
+end;
+
+function SDL_AUDIO_ISINT(x: Cardinal): Cardinal;
+begin
+ Result := not SDL_AUDIO_ISFLOAT(x);
+end;
+
+function SDL_AUDIO_ISLITTLEENDIAN(x: Cardinal): Cardinal;
+begin
+ Result := not SDL_AUDIO_ISBIGENDIAN(x);
+end;
+
+function SDL_AUDIO_ISUNSIGNED(x: Cardinal): Cardinal;
+begin
+ Result := not SDL_AUDIO_ISSIGNED(x);
+end;
+
+//from "sdl_pixels.h"
+
+function SDL_PIXELFLAG(X: cuint32): cuint32;
+begin
+ Result := (X shr 28) and $0F;
+end;
+
+function SDL_PIXELTYPE(X: cuint32): cuint32;
+begin
+ Result := (X shr 24) and $0F;
+end;
+
+function SDL_PIXELORDER(X: cuint32): cuint32;
+begin
+ Result := (X shr 20) and $0F;
+end;
+
+function SDL_PIXELLAYOUT(X: cuint32): cuint32;
+begin
+ Result := (X shr 16) and $0F;
+end;
+
+function SDL_BITSPERPIXEL(X: cuint32): cuint32;
+begin
+ Result := (X shr 8) and $FF;
+end;
+
+function SDL_ISPIXELFORMAT_FOURCC(format: Variant): Boolean;
+begin
+ Result := (format and (SDL_PIXELFLAG(format) <> 1));
+end;
+
+// Macros from "sdl_surface.h"
+function SDL_LoadBMP(_file: PAnsiChar): PSDL_Surface;
+begin
+ Result := SDL_LoadBMP_RW(SDL_RWFromFile(_file, 'rb'), 1);
+end;
+
+function SDL_SaveBMP(const surface: PSDL_Surface; const filename: AnsiString
+ ): cint;
+begin
+ Result := SDL_SaveBMP_RW(surface, SDL_RWFromFile(PAnsiChar(filename), 'wb'), 1)
+end;
+
+{**
+ * Evaluates to true if the surface needs to be locked before access.
+ *}
+function SDL_MUSTLOCK(const S: PSDL_Surface): Boolean;
+begin
+ Result := ((S^.flags and SDL_RLEACCEL) <> 0)
+end;
+
+// Macros from "sdl_shape.h"
+function SDL_SHAPEMODEALPHA(mode: TWindowShapeMode): Boolean;
+begin
+ Result := (mode = ShapeModeDefault) or (mode = ShapeModeBinarizeAlpha) or (mode = ShapeModeReverseBinarizeAlpha);
+end;
+
+// from "sdl_stdinc.h"
+
+// Note: We're using FPC's Strings.strlen() here, not SDL_strlen().
+function SDL_iconv_utf8_locale(Const str: PAnsiChar): PAnsiChar; cdecl;
+begin
+ Result := SDL_iconv_string('', 'UTF-8', str, strlen(str)+1)
+end;
+
+function SDL_iconv_utf8_ucs2(Const str: PAnsiChar): pcUint16; cdecl;
+begin
+ Result := pcUint16(SDL_iconv_string('UCS-2-INTERNAL', 'UTF-8', str, strlen(str)+1))
+end;
+
+function SDL_iconv_utf8_ucs4(Const str: PAnsiChar): pcUint32; cdecl;
+begin
+ Result := pcUint32(SDL_iconv_string('UCS-4-INTERNAL', 'UTF-8', str, strlen(str)+1))
+end;
+
+//from "sdl_video.h"
+
+function SDL_WINDOWPOS_UNDEFINED_DISPLAY(X: Variant): Variant;
+begin
+ Result := (SDL_WINDOWPOS_UNDEFINED_MASK or X);
+end;
+
+function SDL_WINDOWPOS_ISUNDEFINED(X: Variant): Variant;
+begin
+ Result := (X and $FFFF0000) = SDL_WINDOWPOS_UNDEFINED_MASK;
+end;
+
+function SDL_WINDOWPOS_CENTERED_DISPLAY(X: Variant): Variant;
+begin
+ Result := (SDL_WINDOWPOS_CENTERED_MASK or X);
+end;
+
+function SDL_WINDOWPOS_ISCENTERED(X: Variant): Variant;
+begin
+ Result := (X and $FFFF0000) = SDL_WINDOWPOS_CENTERED_MASK;
+end;
+
+//from "sdl_events.h"
+
+function SDL_GetEventState(type_: TSDL_EventType): cuint8;
+begin
+ Result := SDL_EventState(type_, SDL_QUERY);
+end;
+
+// from "sdl_timer.h"
+function SDL_TICKS_PASSED(const A, B: cint32): Boolean;
+begin
+ Result := ((B - A) <= 0);
+end;
+
+// from "sdl_gamecontroller.h"
+ {**
+ * Load a set of mappings from a file, filtered by the current SDL_GetPlatform()
+ *}
+function SDL_GameControllerAddMappingsFromFile(const FilePath: PAnsiChar
+ ): cint32;
+begin
+ Result := SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(FilePath, 'rb'), 1)
+end;
+
+
+{$IFDEF SDL_RUNTIME_LOADING}
+
+Finalization
+ SDL_UnLoadLib();
+{$ENDIF}
+
+end.
diff --git a/units/sdl2_for_pascal/sdl2_gfx.pas b/units/sdl2_for_pascal/sdl2_gfx.pas
new file mode 100644
index 0000000..b559247
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2_gfx.pas
@@ -0,0 +1,566 @@
+unit sdl2_gfx;
+
+(*
+
+SDL2_framerate.h: framerate manager
+SDL2_gfxPrimitives.h: graphics primitives for SDL
+SDL2_imageFilter.h: byte-image "filter" routines
+SDL2_rotozoom.h: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012 Andreas Schiffler
+
+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.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+
+*)
+
+{$INCLUDE jedi.inc}
+
+interface
+
+uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ SDL2;
+
+{$I ctypes.inc}
+
+const
+ {$IFDEF WINDOWS}
+ GFX_LibName = 'SDL2_gfx.dll';
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ GFX_LibName = 'libSDL2_gfx.dylib';
+ {$ELSE}
+ {$IFDEF FPC}
+ GFX_LibName = 'libSDL2_gfx.so';
+ {$ELSE}
+ GFX_LibName = 'libSDL2_gfx.so.0';
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF MACOS}
+ GFX_LibName = 'SDL2_gfx';
+ {$IFDEF FPC}
+ {$linklib libSDL2_gfx}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IF DEFINED(DELPHI) AND DEFINED(MACOS)}
+ {$DEFINE DELMAC}
+ {$ENDIF}
+
+Procedure SDL_GFX_VERSION(Out X: TSDL_Version);
+
+{---< SDL2_framerate.h >---}
+
+Const
+ {*!
+ \brief Highest possible rate supported by framerate controller in Hz (1/s).
+ *}
+ FPS_UPPER_LIMIT = 200;
+
+ {*!
+ \brief Lowest possible rate supported by framerate controller in Hz (1/s).
+ *}
+ FPS_LOWER_LIMIT = 1;
+
+ {*!
+ \brief Default rate of framerate controller in Hz (1/s).
+ *}
+ FPS_DEFAULT = 30;
+
+Type
+ {*!
+ \brief Structure holding the state and timing information of the framerate controller.
+ *}
+
+ TFPSManager = record
+ framecount : cuint32;
+ rateticks : cfloat; // float rateticks;
+ baseticks : cuint32;
+ lastticks : cuint32;
+ rate : cuint32;
+ end;
+
+ PFPSManager = ^TFPSManager;
+
+Procedure SDL_initFramerate(manager: PFPSManager); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_initFramerate' {$ENDIF};
+
+Function SDL_setFramerate(manager: PFPSManager; rate: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_setFramerate' {$ENDIF};
+
+Function SDL_getFramerate(manager: PFPSManager):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_getFramerate' {$ENDIF};
+
+Function SDL_getFramecount(manager: PFPSManager):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_getFramecount' {$ENDIF};
+
+Function SDL_framerateDelay(manager: PFPSManager):cuint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_framerateDelay' {$ENDIF};
+
+
+{---< SDL2_gfxPrimitives.h >---}
+
+Const
+ SDL2_GFXPRIMITIVES_MAJOR = 1;
+ SDL2_GFXPRIMITIVES_MINOR = 0;
+ SDL2_GFXPRIMITIVES_MICRO = 1;
+
+(* Note: all ___Color routines expect the colour to be in format 0xRRGGBBAA *)
+
+
+{* Pixel *}
+
+Function pixelColor(renderer: PSDL_Renderer; x, y: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_pixelColor' {$ENDIF};
+
+Function pixelRGBA(renderer: PSDL_Renderer; x, y: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_pixelRGBA' {$ENDIF};
+
+{ Horizontal line }
+
+Function hlineColor(renderer: PSDL_Renderer; x1, x2, y: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_hlineColor' {$ENDIF};
+
+Function hlineRGBA(renderer: PSDL_Renderer; x1, x2, y:cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_hlineRGBA' {$ENDIF};
+
+{ Vertical line }
+
+Function vlineColor(renderer: PSDL_Renderer; x, y1, y2: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_vlineColor' {$ENDIF};
+
+Function vlineRGBA(renderer: PSDL_Renderer; x, y1, y2: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_vlineRGBA' {$ENDIF};
+
+{ Rectangle }
+
+Function rectangleColor(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rectangleColor' {$ENDIF};
+
+Function rectangleRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rectangleRGBA' {$ENDIF};
+
+{ Rounded-Corner Rectangle }
+
+Function roundedRectangleColor(renderer: PSDL_Renderer; x1, y1, x2, y2, rad: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_roundedRectangleColor' {$ENDIF};
+
+Function roundedRectangleRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2, rad: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_roundedRectangleRGBA' {$ENDIF};
+
+{ Filled rectangle (Box) }
+
+Function boxColor(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_boxColor' {$ENDIF};
+
+Function boxRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_boxRGBA' {$ENDIF};
+
+{ Rounded-Corner Filled rectangle (Box) }
+
+Function roundedBoxColor(renderer: PSDL_Renderer; x1, y1, x2, y2, rad: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_roundedBoxColor' {$ENDIF};
+
+Function roundedBoxRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2, rad: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_roundedBoxRGBA' {$ENDIF};
+
+{ Line }
+
+Function lineColor(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_lineColor' {$ENDIF};
+
+Function lineRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_lineRGBA' {$ENDIF};
+
+{ AA Line }
+
+Function aalineColor(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aalineColor' {$ENDIF};
+
+Function aalineRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aalineRGBA' {$ENDIF};
+
+{ Thick Line }
+Function thickLineColor(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; width: cuint8; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_thickLineColor' {$ENDIF};
+
+Function thickLineRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2: cint16; width, r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_thickLineRGBA' {$ENDIF};
+
+{ Circle }
+
+Function circleColor(renderer: PSDL_Renderer; x, y, rad: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_circleColor' {$ENDIF};
+
+Function circleRGBA(renderer: PSDL_Renderer; x, y, rad: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_circleRGBA' {$ENDIF};
+
+{ Arc }
+
+Function arcColor(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_arcColor' {$ENDIF};
+
+Function arcRGBA(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_arcRGBA' {$ENDIF};
+
+{ AA Circle }
+
+Function aacircleColor(renderer: PSDL_Renderer; x, y, rad: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aacircleColor' {$ENDIF};
+
+Function aacircleRGBA(renderer: PSDL_Renderer; x, y, rad: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aacircleRGBA' {$ENDIF};
+
+{ Filled Circle }
+
+Function filledCircleColor(renderer: PSDL_Renderer; x, y, rad: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledCircleColor' {$ENDIF};
+
+Function filledCircleRGBA(renderer: PSDL_Renderer; x, y, rad: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledCircleRGBA' {$ENDIF};
+
+{ Ellipse }
+
+Function ellipseColor(renderer: PSDL_Renderer; x, y, rx, ry: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_ellipseColor' {$ENDIF};
+
+Function ellipseRGBA(renderer: PSDL_Renderer; x, y, rx, ry: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_ellipseRGBA' {$ENDIF};
+
+{ AA Ellipse }
+
+Function aaellipseColor(renderer: PSDL_Renderer; x, y, rx, ry: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aaellipseColor' {$ENDIF};
+
+Function aaellipseRGBA(renderer: PSDL_Renderer; x, y, rx, ry: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aaellipseRGBA' {$ENDIF};
+
+{ Filled Ellipse }
+
+Function filledEllipseColor(renderer: PSDL_Renderer; x, y, rx, ry: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledEllipseColor' {$ENDIF};
+
+Function filledEllipseRGBA(renderer: PSDL_Renderer; x, y, rx, ry: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledEllipseRGBA' {$ENDIF};
+
+{ Pie }
+
+Function pieColor(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_pieColor' {$ENDIF};
+
+Function pieRGBA(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_pieRGBA' {$ENDIF};
+
+{ Filled Pie }
+
+Function filledPieColor(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledPieColor' {$ENDIF};
+
+Function filledPieRGBA(renderer: PSDL_Renderer; x, y, rad, start, finish: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledPieRGBA' {$ENDIF};
+
+{ Trigon }
+
+Function trigonColor(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_trigonColor' {$ENDIF};
+
+Function trigonRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_trigonRGBA' {$ENDIF};
+
+{ AA-Trigon }
+
+Function aatrigonColor(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aatrigonColor' {$ENDIF};
+
+Function aatrigonRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aatrigonRGBA' {$ENDIF};
+
+{ Filled Trigon }
+
+Function filledTrigonColor(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledTrigonColor' {$ENDIF};
+
+Function filledTrigonRGBA(renderer: PSDL_Renderer; x1, y1, x2, y2, x3, y3: cint16; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledTrigonRGBA' {$ENDIF};
+
+{ Polygon }
+
+Function polygonColor(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_polygonColor' {$ENDIF};
+
+Function polygonRGBA(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_polugonRGBA' {$ENDIF};
+
+{ AA-Polygon }
+
+Function aapolygonColor(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aapolygonColor' {$ENDIF};
+
+Function aapolygonRGBA(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_aapolygonRGBA' {$ENDIF};
+
+{ Filled Polygon }
+
+Function filledPolygonColor(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledPolygonColor' {$ENDIF};
+
+Function filledPolygonRGBA(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_filledPolygonRGBA' {$ENDIF};
+
+{ Textured Polygon }
+
+Function texturedPolygon(renderer: PSDL_Renderer; Const vx, vy: pcint16; n: cint32; texture: PSDL_Surface; texture_dx, texture_dy: cint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_texturedPolygon' {$ENDIF};
+
+{ Bezier }
+
+Function bezierColor(renderer: PSDL_Renderer; Const vx, vy: pcint16; n, s: cint32; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_bezierColor' {$ENDIF};
+
+Function bezierRGBA(renderer: PSDL_Renderer; Const vx, vy: pcint16; n, s: cint32; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_bezierRGBA' {$ENDIF};
+
+{ Characters/Strings }
+
+Procedure gfxPrimitivesSetFont(Const fontdata: Pointer; cw, ch: cuint32); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_gfxPrimitivesSetFont' {$ENDIF};
+
+Procedure gfxPrimitivesSetFontRotation(rotation: cuint32); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_gfxPrimitivesSetFontRotation' {$ENDIF};
+
+
+Function characterColor(renderer: PSDL_Renderer; x, y: cint16; c: Char; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_characterColor' {$ENDIF};
+
+Function characterRGBA(renderer: PSDL_Renderer; x, y: cint16; c: Char; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_characterRGBA' {$ENDIF};
+
+
+Function stringColor(renderer: PSDL_Renderer; x, y: cint16; Const str: PChar; colour: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_stringColor' {$ENDIF};
+
+Function stringRGBA(renderer: PSDL_Renderer; x, y: cint16; Const syt: PChar; r, g, b, a: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_stringRGBA' {$ENDIF};
+
+
+
+{---< SDL2_imageFilter.h >---}
+
+(* Comments: *
+ * 1.) MMX functions work best if all data blocks are aligned on a 32 bytes boundary. *
+ * 2.) Data that is not within an 8 byte boundary is processed using the C routine. *
+ * 3.) Convolution routines do not have C routines at this time. *)
+
+// Detect MMX capability in CPU
+Function SDL_imageFilterMMXdetect():cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMMXdetect' {$ENDIF};
+
+// Force use of MMX off (or turn possible use back on)
+Procedure SDL_imageFilterMMXoff(); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMMXoff' {$ENDIF};
+
+Procedure SDL_imageFilterMMXon(); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMMXon' {$ENDIF};
+
+
+// SDL_imageFilterAdd: D = saturation255(S1 + S2)
+Function SDL_imageFilterAdd(Src1, Src2, Dest : pcuint8; Length : cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterAdd' {$ENDIF};
+
+// SDL_imageFilterMean: D = S1/2 + S2/2
+Function SDL_imageFilterMean(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMean' {$ENDIF};
+
+// SDL_imageFilterSub: D = saturation0(S1 - S2)
+Function SDL_imageFilterSub(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterSub' {$ENDIF};
+
+// SDL_imageFilterAbsDiff: D = | S1 - S2 |
+Function SDL_imageFilterAbsDiff(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterAbsDiff' {$ENDIF};
+
+
+// SDL_imageFilterMult: D = saturation(S1 * S2)
+Function SDL_imageFilterMult(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMult' {$ENDIF};
+
+// SDL_imageFilterMultNor: D = S1 * S2 (non-MMX)
+Function SDL_imageFilterMultNor(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMultNor' {$ENDIF};
+
+// SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2)
+Function SDL_imageFilterMultDivby2(Src1, Src2, Dest : pcuint8; Length: cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMultDivby2' {$ENDIF};
+
+// SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2)
+Function SDL_imageFilterMultDivby4(Src1, Src2, Dest : pcuint8; Length : cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMultDivby4' {$ENDIF};
+
+
+// SDL_imageFilterBitAnd: D = S1 & S2
+Function SDL_imageFilterBitAnd(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterBitAnd' {$ENDIF};
+
+// SDL_imageFilterBitOr: D = S1 | S2
+Function SDL_imageFilterBitOr(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterBitOr' {$ENDIF};
+
+
+// SDL_imageFilterDiv: D = S1 / S2 (non-MMX)
+Function SDL_imageFilterDiv(Src1, Src2, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterDiv' {$ENDIF};
+
+// SDL_imageFilterBitNegation: D = !S
+Function SDL_imageFilterBitNegation(Src1, Dest : pcuint8; Length:cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterBitNegation' {$ENDIF};
+
+
+// SDL_imageFilterAddByte: D = saturation255(S + C)
+Function SDL_imageFilterAddByte(Src1, Dest : pcuint8; Length:cuint32; C : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterAddByte' {$ENDIF};
+
+// SDL_imageFilterAddUsInt32: D = saturation255(S + (usInt32)C)
+Function SDL_imageFilterAddUsInt32(Src1, Dest : pcuint8; Length:cuint32; C : cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterAddUsInt32' {$ENDIF};
+
+// SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C)
+Function SDL_imageFilterAddByteToHalf(Src1, Dest : pcuint8; Length:cuint32; C : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterAddByteToHalf' {$ENDIF};
+
+
+// SDL_imageFilterSubByte: D = saturation0(S - C)
+Function SDL_imageFilterSubByte(Src1, Dest : pcuint8; Length:cuint32; C : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterSubByte' {$ENDIF};
+
+// SDL_imageFilterSubUsInt32: D = saturation0(S - (usInt32)C)
+Function SDL_imageFilterSubUsInt32(Src1, Dest : pcuint8; Length:cuint32; C : cuint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterSubUsInt32' {$ENDIF};
+
+
+// SDL_imageFilterShiftRight: D = saturation0(S >> N)
+Function SDL_imageFilterShiftRight(Src1, Dest : pcuint8; Length:cuint32; N : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftRight' {$ENDIF};
+
+// SDL_imageFilterShiftRightUsInt32: D = saturation0((usInt32)S >> N)
+Function SDL_imageFilterShiftRightUsInt32(Src1, Dest : pcuint8; Length:cuint32; N : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftRightUsInt32' {$ENDIF};
+
+
+// SDL_imageFilterMultByByte: D = saturation255(S * C)
+Function SDL_imageFilterMultByByte(Src1, Dest : pcuint8; Length:cuint32; C : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterMultByByte' {$ENDIF};
+
+// SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C)
+Function SDL_imageFilterShiftRightAndMultByByte(Src1, Dest : pcuint8; Length:cuint32; N, C : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftRightAndMultByByte' {$ENDIF};
+
+
+// SDL_imageFilterShiftLeftByte: D = (S << N)
+Function SDL_imageFilterShiftLeftByte(Src1, Dest : pcuint8; Length:cuint32; N: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftLeftByte' {$ENDIF};
+
+// SDL_imageFilterShiftLeftUsInt32: D = ((usInt32)S << N)
+Function SDL_imageFilterShiftLeftUsInt32(Src1, Dest : pcuint8; Length:cuint32; N:cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftLeftUsInt32' {$ENDIF};
+
+// SDL_imageFilterShiftLeft: D = saturation255(S << N)
+Function SDL_imageFilterShiftLeft(Src1, Dest : pcuint8; Length:cuint32; N : cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterShiftLeft' {$ENDIF};
+
+
+// SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0
+Function SDL_imageFilterBinarizeUsingThreshold(Src1, Dest : pcuint8; Length:cuint32; T: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterBinarizeUsingThreshold' {$ENDIF};
+
+// SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0
+Function SDL_imageFilterClipToRange(Src1, Dest : pcuint8; Length:cuint32; Tmin, Tmax: cuint8):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterClipToRange' {$ENDIF};
+
+// SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin)
+Function SDL_imageFilterNormalizeLinear(Src, Dest: pcuint8; Length, Cmin, Cmax, Nmin, Nmax: cint32):cint32; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_SDL_imageFilterNormalizeLinear' {$ENDIF};
+
+
+{---< SDL2_rotozoom.h >---}
+
+Const
+ {*!
+ \brief Disable anti-aliasing (no smoothing).
+ *}
+ SMOOTHING_OFF = 0;
+
+ {*!
+ \brief Enable anti-aliasing (smoothing).
+ *}
+ SMOOTHING_ON = 1;
+
+{ Rotozoom functions }
+
+Function rotozoomSurface(src: PSDL_Surface; angle, zoom: Double; smooth: cint32):PSDL_Surface; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rotozoomSurface' {$ENDIF};
+
+Function rotozoomSurfaceXY(src: PSDL_Surface; angle, zoomx, zoomy: Double; smooth: cint32):PSDL_Surface; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rotozoomSurfaceXY' {$ENDIF};
+
+
+Procedure rotozoomSurfaceSize(width, height: cint32; angle, zoom: Double; dstwidth, dstheight: pcuint32); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rotozoomSurfaceSize' {$ENDIF};
+
+Procedure rotozoomSurfaceSizeXY(width, height: cint32; angle, zoomx, zoomy: Double; dstwidth, dstheight:pcuint32); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rotozoomSurfaceSizeXY' {$ENDIF};
+
+
+{ Zooming functions }
+
+Function zoomSurface(src: PSDL_Surface; zoomx, zoomy: Double; smooth: cint32):PSDL_Surface; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_zoomSurface' {$ENDIF};
+
+Procedure zoomSurfaceSize(width, height: cint32; zoomx, zoomy: Double; dstwidth, dstheight: pcuint32); cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_zoomSurfaceSize' {$ENDIF};
+
+{ Shrinking functions }
+
+Function shrinkSurface(src: PSDL_Surface; factorx, factory: cint32):PSDL_Surface; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_shrinkSurface' {$ENDIF};
+
+{ Specialized rotation functions }
+
+Function rotateSurface90Degrees(src: PSDL_Surface; numClockwiseTurns: cint32):PSDL_Surface; cdecl;
+ external GFX_LibName {$IFDEF DELMAC} name '_rotateSurface90Degrees' {$ENDIF};
+
+
+implementation
+
+Procedure SDL_GFX_VERSION(Out X: TSDL_Version);
+begin
+ X.Major := SDL2_GFXPRIMITIVES_MAJOR;
+ X.Minor := SDL2_GFXPRIMITIVES_MINOR;
+ X.Patch := SDL2_GFXPRIMITIVES_MICRO
+end;
+
+end.
diff --git a/units/sdl2_for_pascal/sdl2_image.pas b/units/sdl2_for_pascal/sdl2_image.pas
new file mode 100644
index 0000000..f102a03
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2_image.pas
@@ -0,0 +1,188 @@
+unit sdl2_image;
+
+{*
+ SDL_image: An example image loading library for use with SDL
+ Copyright (C) 1997-2013 Sam Lantinga
+
+ Pascal-Header-Translation 2013 by Tim Blume
+
+ Both, header translation and sdl_image, under following license:
+
+ 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.
+*}
+
+{$DEFINE SDL_IMAGE}
+
+{$I jedi.inc}
+
+interface
+
+uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ SDL2;
+
+{$I ctypes.inc}
+
+const
+ {$IFDEF WINDOWS}
+ IMG_LibName = 'SDL2_image.dll';
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ IMG_LibName = 'libSDL2_image.dylib';
+ {$ELSE}
+ {$IFDEF FPC}
+ IMG_LibName = 'libSDL2_image.so';
+ {$ELSE}
+ IMG_LibName = 'libSDL2_image.so.0';
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF MACOS}
+ IMG_LibName = 'SDL2_image';
+ {$IFDEF FPC}
+ {$linklib libSDL2_image}
+ {$ENDIF}
+ {$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_IMAGE_MAJOR_VERSION = 2;
+ SDL_IMAGE_MINOR_VERSION = 0;
+ SDL_IMAGE_PATCHLEVEL = 5;
+
+ {* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_image library.
+ *}
+
+procedure SDL_IMAGE_VERSION(Out X: TSDL_Version);
+
+ {* This function gets the version of the dynamically linked SDL_image library.
+ *
+ * Note that this function does NOT allocate a new TSDL_Version and fill it with info,
+ * but returns a pointer to a TSDL_Version residing inside dynlinked file.
+ *
+ * As such, attempting to Dispose() of this memory will result in access violation.
+ *}
+function IMG_Linked_Version: PSDL_Version cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_Linked_Version' {$ENDIF} {$ENDIF};
+
+const
+ IMG_INIT_JPG = $00000001;
+ IMG_INIT_PNG = $00000002;
+ IMG_INIT_TIF = $00000004;
+ IMG_INIT_WEBP = $00000008;
+
+type
+ PPIMG_InitFlags = ^PIMG_InitFlags;
+ PIMG_InitFlags = ^TIMG_InitFlags;
+ TIMG_InitFlags = DWord;
+
+ {* Loads dynamic libraries and prepares them for use. Flags should be
+ one or more flags from IMG_InitFlags OR'd together.
+ It returns the flags successfully initialized, or 0 on failure.
+ *}
+function IMG_Init(flags: cint32): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_Init' {$ENDIF} {$ENDIF};
+
+ {* Unloads libraries loaded with IMG_Init *}
+procedure IMG_Quit() cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_Quit' {$ENDIF} {$ENDIF};
+
+ {* Load an image from an SDL data source.
+ The 'type' may be one of: "BMP", "GIF", "PNG", etc.
+
+ If the image format supports a transparent pixel, SDL will set the
+ colorkey for the surface. You can enable RLE acceleration on the
+ surface afterwards by calling:
+ SDL_SetColorKey(image, SDL_RLEACCEL, image->format->colorkey);
+ *}
+function IMG_LoadTyped_RW(src: PSDL_RWops; freesrc: cint32; _type: PAnsiChar): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTyped_RW' {$ENDIF} {$ENDIF};
+ {* Convenience functions *}
+function IMG_Load(_file: PAnsiChar): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_Load' {$ENDIF} {$ENDIF};
+function IMG_Load_RW(src: PSDL_RWops; freesrc: cint32): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_Load_RW' {$ENDIF} {$ENDIF};
+
+ {* Load an image directly into a render texture. *}
+function IMG_LoadTexture(renderer: PSDL_Renderer; _file: PAnsiChar): PSDL_Texture cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTexture' {$ENDIF} {$ENDIF};
+function IMG_LoadTexture_RW(renderer: PSDL_Renderer; src: PSDL_RWops; freesrc: cint32): PSDL_Texture cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTexture_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadTextureTyped_RW(renderer: PSDL_Renderer; src: PSDL_RWops; freesrc: cint32; _type: PAnsiChar): PSDL_Texture cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTextureTyped_RW' {$ENDIF} {$ENDIF};
+
+ {* Functions to detect a file type, given a seekable source *}
+function IMG_isICO(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isICO' {$ENDIF} {$ENDIF};
+function IMG_isCUR(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isCUR' {$ENDIF} {$ENDIF};
+function IMG_isBMP(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isBMP' {$ENDIF} {$ENDIF};
+function IMG_isGIF(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isGIF' {$ENDIF} {$ENDIF};
+function IMG_isJPG(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isJPG' {$ENDIF} {$ENDIF};
+function IMG_isLBM(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isLBM' {$ENDIF} {$ENDIF};
+function IMG_isPCX(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isPCX' {$ENDIF} {$ENDIF};
+function IMG_isPNG(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isPNG' {$ENDIF} {$ENDIF};
+function IMG_isPNM(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isPNM' {$ENDIF} {$ENDIF};
+function IMG_isSVG(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isSVG' {$ENDIF} {$ENDIF};
+function IMG_isTIF(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isTIF' {$ENDIF} {$ENDIF};
+function IMG_isXCF(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '-IMG_isXCF' {$ENDIF} {$ENDIF};
+function IMG_isXPM(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isXPM' {$ENDIF} {$ENDIF};
+function IMG_isXV(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isXV' {$ENDIF} {$ENDIF};
+function IMG_isWEBP(src: PSDL_RWops): cint32 cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_isWEBP' {$ENDIF} {$ENDIF};
+
+ {* Individual loading functions *}
+function IMG_LoadICO_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadICO_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadCUR_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadCUR_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadBMP_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadBMP_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadGIF_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadGIF_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadJPG_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadJPG_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadLBM_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadLBM_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadPCX_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadPCX_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadPNG_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadPNG_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadPNM_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadPNM_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadSVG_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadSVG_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadTGA_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTGA_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadTIF_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadTIF_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadXCF_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadXCF_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadXPM_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadXMP_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadXV_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadXV_RW' {$ENDIF} {$ENDIF};
+function IMG_LoadWEBP_RW(src: PSDL_RWops): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_LoadWEBP_RW' {$ENDIF} {$ENDIF};
+
+function IMG_ReadXPMFromArray(xpm: PPChar): PSDL_Surface cdecl; external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_ReadXPMFromArray' {$ENDIF} {$ENDIF};
+
+ {* Individual saving functions *}
+function IMG_SavePNG(surface: PSDL_Surface; const _file: PAnsiChar): cint32 cdecl;
+ external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_SavePNG' {$ENDIF} {$ENDIF};
+function IMG_SavePNG_RW(surface: PSDL_Surface; dst: PSDL_RWops; freedst: cint32): cint32 cdecl;
+ external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_SavePNG_RW' {$ENDIF} {$ENDIF};
+function IMG_SaveJPG(surface: PSDL_Surface; const _file: PAnsiChar; quality: cint32): cint32 cdecl;
+ external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_SaveJPG' {$ENDIF} {$ENDIF};
+function IMG_SaveJPG_RW(surface: PSDL_Surface; dst: PSDL_RWops; freedst: cint32; quality: cint32): cint32 cdecl;
+ external IMG_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_IMG_SaveJPG_RW' {$ENDIF} {$ENDIF};
+
+{* We'll use SDL for reporting errors *}
+function IMG_SetError(fmt: PAnsiChar; args: array of const): cint; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_SetError' {$ELSE} 'SDL_SetError' {$ENDIF};
+function IMG_GetError: PAnsiChar; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_GetError' {$ELSE} 'SDL_GetError' {$ENDIF};
+
+implementation
+
+procedure SDL_IMAGE_VERSION(Out X: TSDL_Version);
+begin
+ X.major := SDL_IMAGE_MAJOR_VERSION;
+ X.minor := SDL_IMAGE_MINOR_VERSION;
+ X.patch := SDL_IMAGE_PATCHLEVEL;
+end;
+
+end.
diff --git a/units/sdl2_for_pascal/sdl2_mixer.pas b/units/sdl2_for_pascal/sdl2_mixer.pas
new file mode 100644
index 0000000..cebd014
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2_mixer.pas
@@ -0,0 +1,725 @@
+unit sdl2_mixer;
+
+{*
+ SDL_mixer: An audio mixer library based on the SDL library
+ Copyright (C) 1997-2013 Sam Lantinga
+
+ 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.
+*}
+
+{$I jedi.inc}
+
+interface
+
+uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ SDL2;
+
+{$I ctypes.inc}
+
+const
+ {$IFDEF WINDOWS}
+ MIX_LibName = 'SDL2_mixer.dll';
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ MIX_LibName = 'libSDL2_mixer.dylib';
+ {$ELSE}
+ {$IFDEF FPC}
+ MIX_LibName = 'libSDL2_mixer.so';
+ {$ELSE}
+ MIX_LibName = 'libSDL2_mixer.so.0';
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF MACOS}
+ MIX_LibName = 'SDL2_mixer';
+ {$IFDEF FPC}
+ {$linklib libSDL2_mixer}
+ {$ENDIF}
+ {$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+const
+ SDL_MIXER_MAJOR_VERSION = 2;
+ SDL_MIXER_MINOR_VERSION = 0;
+ SDL_MIXER_PATCHLEVEL = 4;
+
+ {* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_mixer library.
+ *}
+procedure SDL_MIXER_VERSION(Out X: TSDL_Version);
+
+ {* Backwards compatibility *}
+const
+ MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION;
+ MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION;
+ MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL;
+
+procedure MIX_VERSION(Out X: TSDL_Version);
+
+ {* This function gets the version of the dynamically linked SDL_mixer library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_MIXER_VERSION() macro.
+ *}
+function Mix_Linked_Version: PSDL_Version cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Linked_Version' {$ENDIF} {$ENDIF};
+
+const
+ MIX_INIT_FLAC = $00000001;
+ MIX_INIT_MOD = $00000002;
+ MIX_INIT_MP3 = $00000008;
+ MIX_INIT_OGG = $00000010;
+ MIX_INIT_MID = $00000020;
+ MIX_INIT_OPUS = $00000040;
+
+{ // Removed in SDL2_mixer 2.0.2
+ MIX_INIT_MODPLUG = $00000004;
+ MIX_INIT_FLUIDSYNTH = $00000020;
+}
+type
+ PPMIX_InitFlags = ^PMIX_InitFlags;
+ PMIX_InitFlags = ^TMIX_InitFlags;
+ TMIX_InitFlags = cint;
+
+ {* Loads dynamic libraries and prepares them for use. Flags should be
+ one or more flags from MIX_InitFlags OR'd together.
+ It returns the flags successfully initialized, or 0 on failure.
+ *}
+function Mix_Init(flags: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Init' {$ENDIF} {$ENDIF};
+
+ {* Unloads libraries loaded with Mix_Init *}
+procedure Mix_Quit() cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Quit' {$ENDIF} {$ENDIF};
+
+
+ {* The default mixer has 8 simultaneous mixing channels *}
+{$IFNDEF MIX_CHANNELS}
+const
+ MIX_CHANNELS = 8;
+{$ENDIF}
+
+ {* Good default values for a PC soundcard *}
+const
+ MIX_DEFAULT_FREQUENCY = 22050;
+ MIX_DEFAULT_CHANNELS = 2;
+ MIX_MAX_VOLUME = SDL2.SDL_MIX_MAXVOLUME; {* Volume of a chunk *}
+
+{$IFDEF FPC}
+ {$IF DEFINED(ENDIAN_LITTLE)}
+ MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
+ {$ELSEIF DEFINED(ENDIAN_BIG)}
+ MIX_DEFAULT_FORMAT = AUDIO_S16MSB;
+ {$ELSE}
+ {$FATAL Unable to determine endianness.}
+ {$IFEND}
+{$ENDIF}
+
+ {* The internal format for an audio chunk *}
+type
+ PPMix_Chunk = ^PMix_Chunk;
+ PMix_Chunk = ^TMix_Chunk;
+ TMix_Chunk = record
+ allocated: cint;
+ abuf: pcuint8;
+ alen: cuint32;
+ volume: cuint8; {* Per-sample volume, 0-128 *}
+ end;
+
+ {* The different fading types supported *}
+type
+ PPMix_Fading = ^PMix_Fading;
+ PMix_Fading = ^TMix_Fading;
+ TMix_Fading = (MIX_NO_FADING, MIX_FADING_OUT, MIX_FADING_IN);
+
+ PPMix_MusicType = ^PMix_MusicType;
+ PMix_MusicType = ^TMix_MusicType;
+ TMix_MusicType = (
+ MUS_NONE,
+ MUS_CMD,
+ MUS_WAV,
+ MUS_MOD,
+ MUS_MID,
+ MUS_OGG,
+ MUS_MP3,
+ MUS_MP3_MAD_UNUSED,
+ MUS_FLAC,
+ MUS_MODPLUG_UNUSED,
+ MUS_OPUS
+ );
+
+ {* The internal format for a music chunk interpreted via mikmod *}
+ PPMix_Music = ^PMix_Music;
+ PMix_Music = type Pointer;
+
+ {* Open the mixer with a certain audio format *}
+function Mix_OpenAudio(frequency: cint; format: cuint16; channels: cint; chunksize: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_OpenAudio' {$ENDIF} {$ENDIF};
+
+ {* Dynamically change the number of channels managed by the mixer.
+ If decreasing the number of channels, the upper channels are
+ stopped.
+ This function returns the new number of allocated channels.
+ *}
+function Mix_AllocateChannels(numchans: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_AllocateChannels' {$ENDIF} {$ENDIF};
+
+ {* Find out what the actual audio device parameters are.
+ This function returns 1 if the audio has been opened, 0 otherwise.
+ *}
+function Mix_QuerySpec(frequency: pcint; format: pcuint16; channels: pcint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_QuerySpec' {$ENDIF} {$ENDIF};
+
+ {* Load a wave file or a music (.mod .s3m .it .xm) file *}
+function Mix_LoadWAV_RW(src: PSDL_RWops; freesrc: cint): PMix_Chunk cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_LoadWAV_RW' {$ENDIF} {$ENDIF};
+function Mix_LoadWAV(_file: PAnsiChar): PMix_Chunk;
+function Mix_LoadMUS(_file: PAnsiChar): PMix_Music cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_LoadMUS' {$ENDIF} {$ENDIF};
+
+ {* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently)
+ Matt Campbell (matt@campbellhome.dhs.org) April 2000 *}
+function Mix_LoadMUS_RW(src: PSDL_RWops; freesrc: cint): PMix_Music cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_LoadMUS_RW' {$ENDIF} {$ENDIF};
+
+ {* Load a music file from an SDL_RWop object assuming a specific format *}
+function Mix_LoadMUSType_RW(src: PSDL_RWops; _type: TMix_MusicType; freesrc: cint): PMix_Music cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_LoadMUSType_RW' {$ENDIF} {$ENDIF};
+
+ {* Load a wave file of the mixer format from a memory buffer *}
+function Mix_QuickLoad_WAV(mem: pcuint8): PMix_Chunk cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_QuickLoad_WAV' {$ENDIF} {$ENDIF};
+
+ {* Load raw audio data of the mixer format from a memory buffer *}
+function Mix_QuickLoad_RAW(mem: pcuint8; len: cuint32): PMix_Chunk cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_QuickLoad_RAW' {$ENDIF} {$ENDIF};
+
+ {* Free an audio chunk previously loaded *}
+procedure Mix_FreeChunk(chunk: PMix_Chunk) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FreeChunk' {$ENDIF} {$ENDIF};
+procedure Mix_FreeMusic(music: PMix_Music) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FreeMusic' {$ENDIF} {$ENDIF};
+
+ {* Get a list of chunk/music decoders that this build of SDL_mixer provides.
+ This list can change between builds AND runs of the program, if external
+ libraries that add functionality become available.
+ You must successfully call Mix_OpenAudio() before calling these functions.
+ This API is only available in SDL_mixer 1.2.9 and later.
+
+ // usage...
+ int i;
+ const int total = Mix_GetNumChunkDecoders();
+ for (i = 0; i < total; i++)
+ printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
+
+ Appearing in this list doesn't promise your specific audio file will
+ decode...but it's handy to know if you have, say, a functioning Timidity
+ install.
+
+ These return values are static, read-only data; do not modify or free it.
+ The pointers remain valid until you call Mix_CloseAudio().
+ *}
+function Mix_GetNumChunkDecoders: cint cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetNumChunkDecoders' {$ENDIF} {$ENDIF};
+function Mix_GetChunkDecoder(index: cint): PAnsiChar cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetChunkDecoder' {$ENDIF} {$ENDIF};
+function Mix_HasChunkDecoder(const name: PAnsiChar): TSDL_Bool cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HasChunkDecoder' {$ENDIF} {$ENDIF};
+function Mix_GetNumMusicDecoders: cint cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetNumMusicDecoders' {$ENDIF} {$ENDIF};
+function Mix_GetMusicDecoder(index: cint): PAnsiChar cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetMusicDecoder' {$ENDIF} {$ENDIF};
+function Mix_HasMusicDecoder(const name: PAnsiChar): TSDL_Bool cdecl;
+ external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HasMusicDecoder' {$ENDIF} {$ENDIF};
+
+ {* Find out the music format of a mixer music, or the currently playing
+ music, if 'music' is NULL.
+ *}
+function Mix_GetMusicType(music: PMix_Music): TMix_MusicType cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetMusicType' {$ENDIF} {$ENDIF};
+
+ {* Set a function that is called after all mixing is performed.
+ This can be used to provide real-time visual display of the audio stream
+ or add a custom mixer filter for the stream data.
+ *}
+type
+ PPMix_Func = ^PMix_Func;
+ PMix_Func = ^TMix_Func;
+ TMix_Func = procedure(udata: Pointer; stream: pcuint8; len: cint) cdecl;
+
+procedure Mix_SetPostMix(func: TMix_Func; arg: Pointer) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetPostMix' {$ENDIF} {$ENDIF};
+
+ {* Add your own music player or additional mixer function.
+ If 'mix_func' is NULL, the default music player is re-enabled.
+ *}
+procedure Mix_HookMusic(func: TMix_Func; arg: Pointer) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HookMusic' {$ENDIF} {$ENDIF};
+
+ {* Add your own callback when the music has finished playing
+ * or when it is stopped from a call to Mix_HaltMusic.
+ *}
+type
+ PPMix_Music_Finished = ^PMix_Music_Finished;
+ PMix_Music_Finished = ^TMix_Music_Finished;
+ TMix_Music_Finished = procedure() cdecl;
+
+procedure Mix_HookMusicFinished(music_finished: PMix_Music_Finished) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HookMusicFinished' {$ENDIF} {$ENDIF};
+
+ {* Get a pointer to the user data for the current music hook *}
+function Mix_GetMusicHookData: Pointer cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetMusicHookData' {$ENDIF} {$ENDIF};
+
+ {*
+ * Add your own callback when a channel has finished playing. NULL
+ * to disable callback. The callback may be called from the mixer's audio
+ * callback or it could be called as a result of Mix_HaltChannel(), etc.
+ * do not call SDL_LockAudio() from this callback; you will either be
+ * inside the audio callback, or SDL_mixer will explicitly lock the audio
+ * before calling your callback.
+ *}
+type
+ PPMix_Channel_Finished = ^PMix_Channel_Finished;
+ PMix_Channel_Finished = ^TMix_Channel_Finished;
+ TMix_Channel_Finished = procedure(channel: cint) cdecl;
+
+procedure Mix_ChannelFinished(channel_finished: TMix_Channel_Finished) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_ChannelFinished' {$ENDIF} {$ENDIF};
+
+ {* Special Effects API by ryan c. gordon. (icculus@icculus.org) *}
+const
+ MIX_CHANNEL_POST = -2;
+
+ {* This is the format of a special effect callback:
+ *
+ * myeffect(int chan, void *stream, int len, void *udata);
+ *
+ * (chan) is the channel number that your effect is affecting. (stream) is
+ * the buffer of data to work upon. (len) is the size of (stream), and
+ * (udata) is a user-defined bit of data, which you pass as the last arg of
+ * Mix_RegisterEffect(), and is passed back unmolested to your callback.
+ * Your effect changes the contents of (stream) based on whatever parameters
+ * are significant, or just leaves it be, if you prefer. You can do whatever
+ * you like to the buffer, though, and it will continue in its changed state
+ * down the mixing pipeline, through any other effect functions, then finally
+ * to be mixed with the rest of the channels and music for the final output
+ * stream.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ *}
+type
+ PPMix_EffectFunc_t = ^PMix_EffectFunc_t;
+ PMix_EffectFunc_t = ^TMix_EffectFunc_t;
+ TMix_EffectFunc_t = procedure(chan: cint; stream: Pointer; len: cint; udata: Pointer) cdecl;
+
+ {*
+ * This is a callback that signifies that a channel has finished all its
+ * loops and has completed playback. This gets called if the buffer
+ * plays out normally, or if you call Mix_HaltChannel(), implicitly stop
+ * a channel via Mix_AllocateChannels(), or unregister a callback while
+ * it's still playing.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ *}
+type
+ PPMix_EffectDone_t = ^PMix_EffectDone_t;
+ PMix_EffectDone_t = ^TMix_EffectDone_t;
+ TMix_EffectDone_t = procedure(chan: cint; udata: Pointer) cdecl;
+
+ {* Register a special effect function. At mixing time, the channel data is
+ * copied into a buffer and passed through each registered effect function.
+ * After it passes through all the functions, it is mixed into the final
+ * output stream. The copy to buffer is performed once, then each effect
+ * function performs on the output of the previous effect. Understand that
+ * this extra copy to a buffer is not performed if there are no effects
+ * registered for a given chunk, which saves CPU cycles, and any given
+ * effect will be extra cycles, too, so it is crucial that your code run
+ * fast. Also note that the data that your function is given is in the
+ * format of the sound device, and not the format you gave to Mix_OpenAudio(),
+ * although they may in reality be the same. This is an unfortunate but
+ * necessary speed concern. Use Mix_QuerySpec() to determine if you can
+ * handle the data before you register your effect, and take appropriate
+ * actions.
+ * You may also specify a callback (Mix_EffectDone_t) that is called when
+ * the channel finishes playing. This gives you a more fine-grained control
+ * than Mix_ChannelFinished(), in case you need to free effect-specific
+ * resources, etc. If you don't need this, you can specify NULL.
+ * You may set the callbacks before or after calling Mix_PlayChannel().
+ * Things like Mix_SetPanning() are just internal special effect functions,
+ * so if you are using that, you've already incurred the overhead of a copy
+ * to a separate buffer, and that these effects will be in the queue with
+ * any functions you've registered. The list of registered effects for a
+ * channel is reset when a chunk finishes playing, so you need to explicitly
+ * set them with each call to Mix_PlayChannel*().
+ * You may also register a special effect function that is to be run after
+ * final mixing occurs. The rules for these callbacks are identical to those
+ * in Mix_RegisterEffect, but they are run after all the channels and the
+ * music have been mixed into a single stream, whereas channel-specific
+ * effects run on a given channel before any other mixing occurs. These
+ * global effect callbacks are call "posteffects". Posteffects only have
+ * their Mix_EffectDone_t function called when they are unregistered (since
+ * the main output stream is never "done" in the same sense as a channel).
+ * You must unregister them manually when you've had enough. Your callback
+ * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
+ * processing is considered a posteffect.
+ *
+ * After all these effects have finished processing, the callback registered
+ * through Mix_SetPostMix() runs, and then the stream goes to the audio
+ * device.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ *
+ * returns zero if error (no such channel), nonzero if added.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_RegisterEffect(chan: cint; f: TMix_EffectFunc_t; d: TMix_EffectDone_t; arg: Pointer): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_RegisterEffect' {$ENDIF} {$ENDIF};
+
+ {* You may not need to call this explicitly, unless you need to stop an
+ * effect from processing in the middle of a chunk's playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel or effect), nonzero if removed.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_UnregisterEffect(channel: cint; f: TMix_EffectFunc_t): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_UnregisterEffect' {$ENDIF} {$ENDIF};
+
+ {* You may not need to call this explicitly, unless you need to stop all
+ * effects from processing in the middle of a chunk's playback. Note that
+ * this will also shut off some internal effect processing, since
+ * Mix_SetPanning() and others may use this API under the hood. This is
+ * called internally when a channel completes playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel), nonzero if all effects removed.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_UnregisterAllEffects(channel: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_UnregisterEffects' {$ENDIF} {$ENDIF};
+
+const
+ MIX_EFFECTSMAXSPEED = 'MIX_EFFECTSMAXSPEED';
+
+ {*
+ * These are the internally-defined mixing effects. They use the same API that
+ * effects defined in the application use, but are provided here as a
+ * convenience. Some effects can reduce their quality or use more memory in
+ * the name of speed; to enable this, make sure the environment variable
+ * MIX_EFFECTSMAXSPEED (see above) is defined before you call
+ * Mix_OpenAudio().
+ *}
+
+ {* Set the panning of a channel. The left and right channels are specified
+ * as integers between 0 and 255, quietest to loudest, respectively.
+ *
+ * Technically, this is just individual volume control for a sample with
+ * two (stereo) channels, so it can be used for more than just panning.
+ * If you want real panning, call it like this:
+ *
+ * Mix_SetPanning(channel, left, 255 - left);
+ *
+ * ...which isn't so hard.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the panning will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and returns without
+ * registering the effect function if the audio device is not configured
+ * for stereo output. Setting both (left) and (right) to 255 causes this
+ * effect to be unregistered, since that is the data's normal state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if panning effect enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_SetPanning(channel: cint; left: cuint8; right: cuint8): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetPanning' {$ENDIF} {$ENDIF};
+
+ {* Set the position of a channel. (angle) is an integer from 0 to 360, that
+ * specifies the location of the sound in relation to the listener. (angle)
+ * will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
+ * Angle 0 is due north, and rotates clockwise as the value increases.
+ * For efficiency, the precision of this effect may be limited (angles 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is. Using 255 does not guarantee that the channel will be
+ * culled from the mixing process or be completely silent. For efficiency,
+ * the precision of this effect may be limited (distance 0 through 5 might
+ * all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
+ * and (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ *
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * If the audio device is configured for mono output, then you won't get
+ * any effectiveness from the angle; however, distance attenuation on the
+ * channel will still occur. While this effect will function with stereo
+ * voices, it makes more sense to use voices with only one channel of sound,
+ * so when they are mixed through this effect, the positioning will sound
+ * correct. You can convert them to mono through SDL before giving them to
+ * the mixer in the first place if you like.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the positioning will be done to the final mixed stream before passing it
+ * on to the audio device.
+ *
+ * This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_SetPosition(channel: cint; angle: cint16; distance: cuint8): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetPosition' {$ENDIF} {$ENDIF};
+
+ {* Set the "distance" of a channel. (distance) is an integer from 0 to 255
+ * that specifies the location of the sound in relation to the listener.
+ * Distance 0 is overlapping the listener, and 255 is as far away as possible
+ * A distance of 255 does not guarantee silence; in such a case, you might
+ * want to try changing the chunk's volume, or just cull the sample from the
+ * mixing process with Mix_HaltChannel().
+ * For efficiency, the precision of this effect may be limited (distances 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is.
+ * Setting (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the distance attenuation will be done to the final mixed stream before
+ * passing it on to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_SetDistance(channel: cint; distance: cuint8): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetDistance' {$ENDIF} {$ENDIF};
+
+{*
+ * !!! FIXME : Haven't implemented, since the effect goes past the
+ * end of the sound buffer. Will have to think about this.
+ * --ryan.
+ *}
+//#if 0
+{* Causes an echo effect to be mixed into a sound. (echo) is the amount
+ * of echo to mix. 0 is no echo, 255 is infinite (and probably not
+ * what you want).
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the reverbing will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally. If you specify an echo
+ * of zero, the effect is unregistered, as the data is already in that state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+//extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
+//#endif
+
+ {* Causes a channel to reverse its stereo. This is handy if the user has his
+ * speakers hooked up backwards, or you would like to have a minor bit of
+ * psychedelia in your sound code. :) Calling this function with (flip)
+ * set to non-zero reverses the chunks's usual channels. If (flip) is zero,
+ * the effect is unregistered.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and thus is probably
+ * more CPU intensive than having the user just plug in his speakers
+ * correctly. Mix_SetReverseStereo() returns without registering the effect
+ * function if the audio device is not configured for stereo output.
+ *
+ * If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
+ * on the final mixed stream before sending it on to the audio device (a
+ * posteffect).
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_SetReverseStereo(channel: cint; flip: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetReverseStereo' {$ENDIF} {$ENDIF};
+
+ {* end of effects API. --ryan. *}
+
+ {* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
+ them dynamically to the next sample if requested with a -1 value below.
+ Returns the number of reserved channels.
+ *}
+function Mix_ReserveChannels(num: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_ReverseChannels' {$ENDIF} {$ENDIF};
+
+ {* Channel grouping functions *}
+
+ {* Attach a tag to a channel. A tag can be assigned to several mixer
+ channels, to form groups of channels.
+ If 'tag' is -1, the tag is removed (actually -1 is the tag used to
+ represent the group of all the channels).
+ Returns true if everything was OK.
+ *}
+function Mix_GroupChannel(which: cint; tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupChannel' {$ENDIF} {$ENDIF};
+ {* Assign several consecutive channels to a group *}
+function Mix_GroupChannels(from: cint; _to: cint; tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupChannels' {$ENDIF} {$ENDIF};
+ {* Finds the first available channel in a group of channels,
+ returning -1 if none are available.
+ *}
+function Mix_GroupAvailable(tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupAvailable' {$ENDIF} {$ENDIF};
+ {* Returns the number of channels in a group. This is also a subtle
+ way to get the total number of channels when 'tag' is -1
+ *}
+function Mix_GroupCount(tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupCount' {$ENDIF} {$ENDIF};
+ {* Finds the "oldest" sample playing in a group of channels *}
+function Mix_GroupOldest(tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupOldest' {$ENDIF} {$ENDIF};
+ {* Finds the "most recent" (i.e. last) sample playing in a group of channels *}
+function Mix_GroupNewer(tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GroupNewer' {$ENDIF} {$ENDIF};
+
+ {* Play an audio chunk on a specific channel.
+ If the specified channel is -1, play on the first free channel.
+ If 'loops' is greater than zero, loop the sound that many times.
+ If 'loops' is -1, loop inifinitely (~65000 times).
+ Returns which channel was used to play the sound.
+ *}
+function Mix_PlayChannel(channel: cint; chunk: PMix_Chunk; loops: cint): cint;
+ {* The same as above, but the sound is played at most 'ticks' milliseconds *}
+function Mix_PlayChannelTimed(channel: cint; chunk: PMix_Chunk; loops: cint; ticks: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_PlayChannelTimed' {$ENDIF} {$ENDIF};
+function Mix_PlayMusic(music: PMix_Music; loops: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_PlayMusic' {$ENDIF} {$ENDIF};
+
+ {* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions *}
+function Mix_FadeInMusic(music: PMix_Music; loops: cint; ms: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeInMusic' {$ENDIF} {$ENDIF};
+function Mix_FadeInMusicPos(music: PMix_Music; loops: cint; ms: cint; position: Double): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeInMusicPos' {$ENDIF} {$ENDIF};
+function Mix_FadeInChannel(channel: cint; chunk: PMix_Chunk; loops: cint; ms: cint): cint;
+function Mix_FadeInChannelTimed(channel: cint; chunk: PMix_Chunk; loops: cint; ms: cint; ticks: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeInChannelTimed' {$ENDIF} {$ENDIF};
+
+ {* Set the volume in the range of 0-128 of a specific channel or chunk.
+ If the specified channel is -1, set volume for all channels.
+ Returns the original volume.
+ If the specified volume is -1, just return the current volume.
+ *}
+function Mix_Volume(channel: cint; volume: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Volume' {$ENDIF} {$ENDIF};
+function Mix_VolumeChunk(chunk: PMix_Chunk; volume: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_VolumeChunk' {$ENDIF} {$ENDIF};
+function Mix_VolumeMusic(volume: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_VolumeMusic' {$ENDIF} {$ENDIF};
+
+ {* Halt playing of a particular channel *}
+function Mix_HaltChannel(channel: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HaltChannel' {$ENDIF} {$ENDIF};
+function Mix_HaltGroup(tag: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HaltGroup' {$ENDIF} {$ENDIF};
+function Mix_HaltMusic: cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_HaltMusic' {$ENDIF} {$ENDIF};
+
+ {* Change the expiration delay for a particular channel.
+ The sample will stop playing after the 'ticks' milliseconds have elapsed,
+ or remove the expiration if 'ticks' is -1
+ *}
+function Mix_ExpireChannel(channel: cint; ticks: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_ExpireChannel' {$ENDIF} {$ENDIF};
+
+ {* Halt a channel, fading it out progressively till it's silent
+ The ms parameter indicates the number of milliseconds the fading
+ will take.
+ *}
+function Mix_FadeOutChannel(which: cint; ms: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeOutChannel' {$ENDIF} {$ENDIF};
+function Mix_FadeOutGroup(tag: cint; ms: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeOutGroup' {$ENDIF} {$ENDIF};
+function Mix_FadeOutMusic(ms: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadeOutMusic' {$ENDIF} {$ENDIF};
+
+ {* Query the fading status of a channel *}
+function Mix_FadingMusic: TMix_Fading cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadingMusic' {$ENDIF} {$ENDIF};
+function Mix_FadingChannel(which: cint): TMix_Fading cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_FadingChannel' {$ENDIF} {$ENDIF};
+
+ {* Pause/Resume a particular channel *}
+procedure Mix_Pause(channel: cint) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Pause' {$ENDIF} {$ENDIF};
+procedure Mix_Resume(channel: cint) cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Resume' {$ENDIF} {$ENDIF};
+function Mix_Paused(channel: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Paused' {$ENDIF} {$ENDIF};
+
+ {* Pause/Resume the music stream *}
+procedure Mix_PauseMusic cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_PauseMusic' {$ENDIF} {$ENDIF};
+procedure Mix_ResumeMusic cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_ResumeMusic' {$ENDIF} {$ENDIF};
+procedure Mix_RewindMusic cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_RewindMusic' {$ENDIF} {$ENDIF};
+function Mix_PausedMusic: cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_PausedMusic' {$ENDIF} {$ENDIF};
+
+ {* Set the current position in the music stream.
+ This returns 0 if successful, or -1 if it failed or isn't implemented.
+ This function is only implemented for MOD music formats (set pattern
+ order number) and for OGG, FLAC, MP3_MAD, MP3_MPG and MODPLUG music
+ (set position in seconds), at the moment.
+ *}
+function Mix_SetMusicPosition(position: Double): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetMusicPosition' {$ENDIF} {$ENDIF};
+
+ {* Check the status of a specific channel.
+ If the specified channel is -1, check all channels.
+ *}
+function Mix_Playing(channel: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_Playing' {$ENDIF} {$ENDIF};
+function Mix_PlayingMusic: cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_PlayingMusic' {$ENDIF} {$ENDIF};
+
+ {* Stop music and set external music playback command *}
+function Mix_SetMusicCMD(command: PAnsiChar): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetMusicCMD' {$ENDIF} {$ENDIF};
+
+ {* Synchro value is set by MikMod from modules while playing *}
+function Mix_SetSynchroValue(value: cint): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetSynchroValue' {$ENDIF} {$ENDIF};
+function Mix_GetSynchroValue: cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetSynchroValue' {$ENDIF} {$ENDIF};
+
+ {* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends *}
+function Mix_SetSoundFonts(paths: PAnsiChar): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_SetSoundFonts' {$ENDIF} {$ENDIF};
+function Mix_GetSoundFonts: PAnsiChar cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetSoundFonts' {$ENDIF} {$ENDIF};
+
+type
+ PPMix_SoundFunc = ^PMix_SoundFunc;
+ PMix_SoundFunc = ^TMix_SoundFunc;
+ TMix_SoundFunc = function(c: PAnsiChar; p: Pointer): cint cdecl;
+
+function Mix_EachSoundFont(func: TMix_SoundFunc; data: Pointer): cint cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_EachSoundFont' {$ENDIF} {$ENDIF};
+
+ {* Get the Mix_Chunk currently associated with a mixer channel
+ Returns NULL if it's an invalid channel, or there's no chunk associated.
+ *}
+function Mix_GetChunk(channel: cint): PMix_Chunk cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_GetChunk' {$ENDIF} {$ENDIF};
+
+ {* Close the mixer, halting all playing audio *}
+procedure Mix_CloseAudio cdecl; external MIX_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_MIX_CloseAudio' {$ENDIF} {$ENDIF};
+
+{* We'll use SDL for reporting errors *}
+function Mix_SetError(const fmt: PAnsiChar; args: array of const): cint; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_SetError' {$ELSE} 'SDL_SetError' {$ENDIF};
+function Mix_GetError: PAnsiChar; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_GetError' {$ELSE} 'SDL_GetError' {$ENDIF};
+procedure Mix_ClearError(); cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_ClearError' {$ELSE} 'SDL_ClearError' {$ENDIF};
+
+implementation
+
+procedure SDL_MIXER_VERSION(Out X: TSDL_Version);
+begin
+ X.major := SDL_MIXER_MAJOR_VERSION;
+ X.minor := SDL_MIXER_MINOR_VERSION;
+ X.patch := SDL_MIXER_PATCHLEVEL;
+end;
+
+procedure MIX_VERSION(Out X: TSDL_Version);
+begin
+ SDL_MIXER_VERSION(X);
+end;
+
+function Mix_FadeInChannel(channel: cint; chunk: PMix_Chunk; loops: cint; ms: cint): cint;
+begin
+ Result := Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
+end;
+
+function Mix_PlayChannel(channel: cint; chunk: PMix_Chunk; loops: cint): cint;
+begin
+ Result := Mix_PlayChannelTimed(channel, chunk, loops, -1);
+end;
+
+function Mix_LoadWAV(_file: PAnsiChar): PMix_Chunk;
+begin
+ Result := Mix_LoadWAV_RW(SDL_RWFromFile(_file, 'rb'), 1);
+end;
+
+end.
diff --git a/units/sdl2_for_pascal/sdl2_net.pas b/units/sdl2_for_pascal/sdl2_net.pas
new file mode 100644
index 0000000..aa00627
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2_net.pas
@@ -0,0 +1,432 @@
+{*
+ SDL_net: An example cross-platform network library for use with SDL
+ Copyright (C) 1997-2013 Sam Lantinga
+ Copyright (C) 2012 Simeon Maxein
+
+ 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.
+*}
+unit sdl2_net;
+
+{$INCLUDE jedi.inc}
+
+interface
+
+uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ SDL2;
+
+{$I ctypes.inc}
+
+const
+ {$IFDEF WINDOWS}
+ SDLNet_LibName = 'SDL2_net.dll';
+ {$ENDIF}
+
+{$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ SDLNet_LibName = 'libSDL2_net.dylib';
+ {$ELSE}
+ {$IFDEF FPC}
+ SDLNet_LibName = 'libSDL2_net.so';
+ {$ELSE}
+ SDLNet_LibName = 'libSDL2_net-2.0.so.0';
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+
+{$IFDEF MACOS}
+ SDLNet_LibName = 'SDL2_net';
+ {$IFDEF FPC}
+ {$linklib libSDL2_net}
+ {$ENDIF}
+ {$ENDIF}
+
+
+type
+ PPSDLNet_Version = ^PSDLNet_Version;
+ PSDLNet_Version = ^TSDLNet_Version;
+ TSDLNet_Version = TSDL_Version;
+
+const
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_NET_MAJOR_VERSION = 2;
+ SDL_NET_MINOR_VERSION = 0;
+ SDL_NET_PATCHLEVEL = 0;
+
+{* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_net library.
+*}
+procedure SDL_NET_VERSION(Out X: TSDL_Version);
+
+{* This function gets the version of the dynamically linked SDL_net library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_NET_VERSION() macro.
+*}
+function SDLNet_Linked_Version: PSDL_Version cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_Linked_Version' {$ENDIF} {$ENDIF};
+
+{* Initialize/Cleanup the network API
+ SDL must be initialized before calls to functions in this library,
+ because this library uses utility functions from the SDL library.
+*}
+function SDLNet_Init(): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_Init' {$ENDIF} {$ENDIF};
+procedure SDLNet_Quit() cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_Quit' {$ENDIF} {$ENDIF};
+
+type
+ {***********************************************************************}
+ {* IPv4 hostname resolution API *}
+ {***********************************************************************}
+ PPIPaddress = ^PIPaddress;
+ PIPaddress = ^TIPaddress;
+ TIPaddress = record
+ host: cuint32; {* 32-bit IPv4 host address *}
+ port: cuint16; {* 16-bit protocol port *}
+ end;
+
+{* Resolve a host name and port to an IP address in network form.
+ If the function succeeds, it will return 0.
+ If the host couldn't be resolved, the host portion of the returned
+ address will be INADDR_NONE, and the function will return -1.
+ If 'host' is NULL, the resolved host will be set to INADDR_ANY.
+*}
+const
+ INADDR_ANY = $00000000;
+ INADDR_NONE = $FFFFFFFF;
+ INADDR_LOOPBACK = $7f000001;
+ INADDR_BROADCAST = $FFFFFFFF;
+
+function SDLNet_ResolveHost(address: PIPaddress; const host: PAnsiChar; port: cuint16): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_ResolveHost' {$ENDIF} {$ENDIF};
+
+{* Resolve an ip address to a host name in canonical form.
+ If the ip couldn't be resolved, this function returns NULL,
+ otherwise a pointer to a static buffer containing the hostname
+ is returned. Note that this function is not thread-safe.
+*}
+function SDLNet_ResolveIP(const ip: PIPaddress): PAnsiChar cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_ResolveIP' {$ENDIF} {$ENDIF};
+
+{* Get the addresses of network interfaces on this system.
+ This returns the number of addresses saved in 'addresses'
+*}
+function SDLNet_GetLocalAddresses(addresses: PIPaddress; maxcount: cint): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_GetLocalAddresses' {$ENDIF} {$ENDIF};
+
+{***********************************************************************}
+{* TCP network API *}
+{***********************************************************************}
+type
+ _TCPSocket = record
+ end;
+ TTCPSocket = ^_TCPSocket;
+
+{* Open a TCP network socket
+ If ip.host is INADDR_NONE or INADDR_ANY, this creates a local server
+ socket on the given port, otherwise a TCP connection to the remote
+ host and port is attempted. The address passed in should already be
+ swapped to network byte order (addresses returned from
+ SDLNet_ResolveHost() are already in the correct form).
+ The newly created socket is returned, or NULL if there was an error.
+*}
+function SDLNet_TCP_Open(ip: PIPaddress): TTCPSocket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_Open' {$ENDIF} {$ENDIF};
+
+{* Accept an incoming connection on the given server socket.
+ The newly created socket is returned, or NULL if there was an error.
+*}
+function SDLNet_TCP_Accept(server: TTCPSocket): TTCPSocket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_Accept' {$ENDIF} {$ENDIF};
+
+{* Get the IP address of the remote system associated with the socket.
+ If the socket is a server socket, this function returns NULL.
+*}
+function SDLNet_TCP_GetPeerAddress(sock: TTCPSocket): PIPaddress cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_GetPeerAddress' {$ENDIF} {$ENDIF};
+
+{* Send 'len' bytes of 'data' over the non-server socket 'sock'
+ This function returns the actual amount of data sent. If the return value
+ is less than the amount of data sent, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*}
+function SDLNet_TCP_Send(sock: TTCPSocket; const data: Pointer; len: cint): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_Send' {$ENDIF} {$ENDIF};
+
+{* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
+ and store them in the buffer pointed to by 'data'.
+ This function returns the actual amount of data received. If the return
+ value is less than or equal to zero, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*}
+function SDLNet_TCP_Recv(sock: TTCPSocket; data: Pointer; maxlen: cint): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_Recv' {$ENDIF} {$ENDIF};
+
+{* Close a TCP network socket *}
+procedure SDLNet_TCP_Close(sock: TTCPSocket) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_TCP_Close' {$ENDIF} {$ENDIF};
+
+{***********************************************************************}
+{* UDP network API *}
+{***********************************************************************}
+
+const
+ {* The maximum channels on a a UDP socket *}
+ SDLNET_MAX_UDPCHANNELS = 32;
+ {* The maximum addresses bound to a single UDP socket channel *}
+ SDLNET_MAX_UDPADDRESSES = 4;
+
+type
+ PPUDPSocket = ^PUDPSocket;
+ PUDPSocket = ^TUDPSocket;
+ TUDPSocket = record
+ end;
+
+ PPUDPPacket = ^PUDPPacket;
+ PUDPPacket = ^TUDPPacket;
+ TUDPPacket = record
+ channel: cint; {* The src/dst channel of the packet *}
+ data: pcuint8; {* The packet data *}
+ len: cint; {* The length of the packet data *}
+ maxlen: cint; {* The size of the data buffer *}
+ status: cint; {* packet status after sending *}
+ address: TIPaddress; {* The source/dest address of an incoming/outgoing packet *}
+ end;
+
+{* Allocate/resize/free a single UDP packet 'size' bytes long.
+ The new packet is returned, or NULL if the function ran out of memory.
+*}
+function SDLNet_AllocPacket(size: cint): PUDPPacket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_AllocPacket' {$ENDIF} {$ENDIF};
+function SDLNet_ResizePacket(packet: PUDPPacket; newsize: cint): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_ResizePacket' {$ENDIF} {$ENDIF};
+procedure SDLNet_FreePacket(packet: PUDPPacket) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_FreePacket' {$ENDIF} {$ENDIF};
+
+{* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
+ each 'size' bytes long.
+ A pointer to the first packet in the array is returned, or NULL if the
+ function ran out of memory.
+*}
+function SDLNet_AllocPacketV(howmany: cint; size: cint): PPUDPPacket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_AllocPacketV' {$ENDIF} {$ENDIF};
+procedure SDLNet_FreePacketV(packetV: PPUDPPacket) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_FreePacketV' {$ENDIF} {$ENDIF};
+
+{* Open a UDP network socket
+ If 'port' is non-zero, the UDP socket is bound to a local port.
+ The 'port' should be given in native byte order, but is used
+ internally in network (big endian) byte order, in addresses, etc.
+ This allows other systems to send to this socket via a known port.
+*}
+function SDLNet_UDP_Open(port: cuint16): TUDPSocket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Open' {$ENDIF} {$ENDIF};
+
+{* Set the percentage of simulated packet loss for packets sent on the socket. *}
+procedure SDLNet_UDP_SetPacketLoss(sock: TUDPSocket; percent: cint) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_SetPacketLoss' {$ENDIF} {$ENDIF};
+
+{* Bind the address 'address' to the requested channel on the UDP socket.
+ If the channel is -1, then the first unbound channel that has not yet
+ been bound to the maximum number of addresses will be bound with
+ the given address as it's primary address.
+ If the channel is already bound, this new address will be added to the
+ list of valid source addresses for packets arriving on the channel.
+ If the channel is not already bound, then the address becomes the primary
+ address, to which all outbound packets on the channel are sent.
+ This function returns the channel which was bound, or -1 on error.
+*}
+function SDLNet_UDP_Bind(sock: TUDPSocket; channel: cint; const address: PIPaddress): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Bind' {$ENDIF} {$ENDIF};
+
+{* Unbind all addresses from the given channel *}
+procedure SDLNet_UDP_Unbind(sock: TUDPSocket; channel: cint) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Unbind' {$ENDIF} {$ENDIF};
+
+{* Get the primary IP address of the remote system associated with the
+ socket and channel. If the channel is -1, then the primary IP port
+ of the UDP socket is returned -- this is only meaningful for sockets
+ opened with a specific port.
+ If the channel is not bound and not -1, this function returns NULL.
+*}
+function SDLNet_UDP_GetPeerAddress(sock: TUDPSocket; channel: cint): PIPaddress cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_GetPeerAddress' {$ENDIF} {$ENDIF};
+
+{* Send a vector of packets to the the channels specified within the packet.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ Each packet will be updated with the status of the packet after it has
+ been sent, -1 if the packet send failed.
+ This function returns the number of packets sent.
+*}
+function SDLNet_UDP_SendV(sock: TUDPSocket; packets: PPUDPPacket; npackets: cint): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_SendV' {$ENDIF} {$ENDIF};
+
+{* Send a single packet to the specified channel.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ The packet will be updated with the status of the packet after it has
+ been sent.
+ This function returns 1 if the packet was sent, or 0 on error.
+
+ NOTE:
+ The maximum size of the packet is limited by the MTU (Maximum Transfer Unit)
+ of the transport medium. It can be as low as 250 bytes for some PPP links,
+ and as high as 1500 bytes for ethernet.
+*}
+function SDLNet_UDP_Send(sock: TUDPSocket; channel: cint; packet: PUDPPacket): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Send' {$ENDIF} {$ENDIF};
+
+{* Receive a vector of pending packets from the UDP socket.
+ The returned packets contain the source address and the channel they arrived
+ on. If they did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*}
+function SDLNet_UDP_RecvV(sock: TUDPSocket; packets: PPUDPPacket): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_RecvV' {$ENDIF} {$ENDIF};
+
+{* Receive a single packet from the UDP socket.
+ The returned packet contains the source address and the channel it arrived
+ on. If it did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*}
+function SDLNet_UDP_Recv(sock: TUDPSocket; packet: PUDPPacket): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Recv' {$ENDIF} {$ENDIF};
+
+{* Close a UDP network socket *}
+procedure SDLNet_UDP_Close(sock: TUDPSocket) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_UDP_Close' {$ENDIF} {$ENDIF};
+
+{***********************************************************************}
+{* Hooks for checking sockets for available data *}
+{***********************************************************************}
+
+type
+ PPSDLNet_SocketSet = ^PSDLNet_SocketSet;
+ PSDLNet_SocketSet = ^TSDLNet_SocketSet;
+ TSDLNet_SocketSet = record
+ end;
+
+ {* Any network socket can be safely cast to this socket type *}
+ PPSDLNet_GenericSocket = ^PSDLNet_GenericSocket;
+ PSDLNet_GenericSocket = ^TSDLNet_GenericSocket;
+ TSDLNet_GenericSocket = record
+ ready: cint;
+ end;
+
+{* Allocate a socket set for use with SDLNet_CheckSockets()
+ This returns a socket set for up to 'maxsockets' sockets, or NULL if
+ the function ran out of memory.
+*}
+function SDLNet_AllocSocketSet(maxsockets: cint): TSDLNet_GenericSocket cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_AllocSocketSet' {$ENDIF} {$ENDIF};
+
+{* Add a socket to a set of sockets to be checked for available data *}
+function SDLNet_AddSocket(set_: TSDLNet_SocketSet; sock: TSDLNet_GenericSocket): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_AddSocket' {$ENDIF} {$ENDIF};
+//function SDLNet_TCP_AddSocket(set_: TSDLNet_SocketSet; sock: TTCPSocket): cint; inline;
+//function SDLNet_UDP_AddSocket(set_: TSDLNet_SocketSet; sock: TUDPSocket): cint; inline;
+
+{* Remove a socket from a set of sockets to be checked for available data *}
+function SDLNet_DelSocket(set_: TSDLNet_SocketSet; sock: TSDLNet_GenericSocket): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_DelSocket' {$ENDIF} {$ENDIF};
+//function SDLNet_TCP_DelSocket(set_: TSDLNet_SocketSet; sock: TTCPSocket): cint; inline;
+//function SDLNet_UDP_DelSocket(set_: TSDLNet_SocketSet; sock: TUDPSocket): cint; inline;
+
+{* This function checks to see if data is available for reading on the
+ given set of sockets. If 'timeout' is 0, it performs a quick poll,
+ otherwise the function returns when either data is available for
+ reading, or the timeout in milliseconds has elapsed, which ever occurs
+ first. This function returns the number of sockets ready for reading,
+ or -1 if there was an error with the select() system call.
+*}
+function SDLNet_CheckSockets(set_: TSDLNet_SocketSet; timeout: cuint32): cint cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_CheckSockets' {$ENDIF} {$ENDIF};
+
+{* After calling SDLNet_CheckSockets(), you can use this function on a
+ socket that was in the socket set, to find out if data is available
+ for reading.
+*}
+function SDLNet_SocketReady(sock: TSDLNet_GenericSocket): cint; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF}
+
+{* Free a set of sockets allocated by SDL_NetAllocSocketSet() *}
+procedure SDLNet_FreeSocketSet(set_: TSDLNet_SocketSet) cdecl; external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_FreeSocketSet' {$ENDIF} {$ENDIF};
+
+{***********************************************************************}
+{* Error reporting functions *}
+{***********************************************************************}
+
+procedure SDLNet_SetError(const fmt: PAnsiChar; args: array of const); cdecl;
+external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_SetError' {$ENDIF} {$ENDIF};
+
+function SDLNet_GetError(): PAnsiChar; cdecl;
+external SDLNet_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDLNet_GetError' {$ENDIF} {$ENDIF};
+
+{***********************************************************************}
+{* Inline functions to read/write network data *}
+{***********************************************************************}
+
+{* Write a 16/32-bit value to network packet buffer *}
+
+//procedure SDLNet_Write16(value: cuint16; areap: Pointer); inline;
+//procedure SDLNet_Write32(value: cuint32; areap: Pointer); inline;
+
+{* Read a 16/32-bit value from network packet buffer *}
+//function SDLNet_Read16(const areap: Pointer): cuint16; inline;
+//function SDLNet_Read32(const areap: Pointer): cuint32; inline;
+
+implementation
+
+procedure SDL_NET_VERSION(Out X: TSDL_Version);
+begin
+ X.major := SDL_NET_MAJOR_VERSION;
+ X.minor := SDL_NET_MINOR_VERSION;
+ X.patch := SDL_NET_PATCHLEVEL;
+end;
+
+(*
+ function SDLNet_TCP_AddSocket(set_: TSDLNet_SocketSet; sock: TTCPSocket): cint;
+ begin
+ Result := SDLNet_AddSocket(set_, TSDLNet_GenericSocket(sock));
+ end;
+
+ function SDLNet_UDP_AddSocket(set_: TSDLNet_SocketSet; sock: TUDPSocket): cint;
+ begin
+ Result := SDLNet_AddSocket(set_, TSDLNet_GenericSocket(sock));
+ end;
+
+ function SDLNet_TCP_DelSocket(set_: TSDLNet_SocketSet; sock: TTCPSocket): cint;
+ begin
+ Result := SDLNet_DelSocket(set_, TSDLNet_GenericSocket(sock));
+ end;
+
+ function SDLNet_UDP_DelSocket(set_: TSDLNet_SocketSet; sock: TUDPSocket): cint;
+ begin
+ Result := SDLNet_DelSocket(set_, TSDLNet_GenericSocket(sock));
+ end;
+*)
+
+function SDLNet_SocketReady(sock: TSDLNet_GenericSocket): cint;
+begin
+ Result := sock.ready;
+end;
+
+(*
+ procedure SDLNet_Write16(value: cuint16; areap: Pointer);
+ begin
+ pcuint16(areap) := SDL_SwapBE16(value);
+ end;
+
+ procedure SDLNet_Write32(value: cuint32; areap: Pointer);
+ begin
+ pcuint32(areap) := SDL_SwapBE32(value);
+ end;
+
+ {* Read a 16/32-bit value from network packet buffer *}
+ function SDLNet_Read16(const areap: Pointer): cuint16;
+ begin
+ Result := SDL_SwapBE16(pcuint16(areap));
+ end;
+
+ function SDLNet_Read32(const areap: Pointer): cuint32;
+ begin
+ Result := SDL_SwapBE32(pcuint32(areap));
+ end;
+*)
+end.
+
diff --git a/units/sdl2_for_pascal/sdl2_ttf.pas b/units/sdl2_for_pascal/sdl2_ttf.pas
new file mode 100644
index 0000000..e9b716a
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl2_ttf.pas
@@ -0,0 +1,2408 @@
+unit sdl2_ttf;
+
+{*
+ SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts
+ Copyright (C) 2001-2013 Sam Lantinga
+
+ 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 acknowledgement 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.
+*}
+
+{*
+ * \file SDL_ttf.h
+ *
+ * Header file for SDL_ttf library
+ *
+ * This library is a wrapper around the excellent FreeType 2.0 library,
+ * available at: https://www.freetype.org/
+ *
+ * Note: In many places, SDL_ttf will say "glyph" when it means "code point."
+ * Unicode is hard, we learn as we go, and we apologize for adding to the
+ * confusion.
+ *
+ }
+
+interface
+
+{$I jedi.inc}
+
+uses
+ {$IFDEF FPC}
+ ctypes,
+ {$ENDIF}
+ SDL2;
+
+{$I ctypes.inc}
+
+const
+ {$IFDEF WINDOWS}
+ TTF_LibName = 'SDL2_ttf.dll';
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF DARWIN}
+ TTF_LibName = 'libSDL2_tff.dylib';
+ {$ELSE}
+ {$IFDEF FPC}
+ TTF_LibName = 'libSDL2_ttf.so';
+ {$ELSE}
+ TTF_LibName = 'libSDL2_ttf.so.0';
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF MACOS}
+ TTF_LibName = 'SDL2_ttf';
+ {$IFDEF FPC}
+ {$linklib libSDL2_ttf}
+ {$ENDIF}
+ {$ENDIF}
+
+{* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+const
+ SDL_TTF_MAJOR_VERSION = 2;
+ SDL_TTF_MINOR_VERSION = 21;
+ SDL_TTF_PATCHLEVEL = 0;
+
+procedure SDL_TTF_VERSION(Out X: TSDL_Version);
+
+{* Backwards compatibility *}
+const
+ TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION;
+ TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION;
+ TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL;
+procedure TTF_VERSION(Out X: TSDL_Version);
+
+{**
+ * This is the version number macro for the current SDL_ttf version.
+ *
+ * In versions higher than 2.9.0, the minor version overflows into
+ * the thousands digit: for example, 2.23.0 is encoded as 4300.
+ * This macro will not be available in SDL 3.x or SDL_ttf 3.x.
+ *
+ * \deprecated, use SDL_TTF_VERSION_ATLEAST or SDL_TTF_VERSION instead.
+ *}
+ { SDL2-for-Pascal: This conditional and deprecated macro is not translated.
+ It could be done easily but nobody ever asked for it and
+ it is probably for little use. }
+// function SDL_TTF_COMPILEDVERSION: Integer;
+
+{**
+ * This macro will evaluate to true if compiled with SDL_ttf at least X.Y.Z.
+ *}
+function SDL_TTF_VERSION_ATLEAST(X, Y, Z: Integer): Boolean;
+
+{*
+ * Query the version of SDL_ttf that the program is linked against.
+ *
+ * This function gets the version of the dynamically linked SDL_ttf library.
+ * This is separate from the SDL_TTF_VERSION() macro, which tells you what
+ * version of the SDL_ttf headers you compiled against.
+ *
+ * This returns static internal data; do not free or modify it!
+ *
+ * \returns a pointer to the version information.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+(* Const before type ignored *)
+function TTF_Linked_Version: PSDL_version; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_Linked_Version' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the version of the FreeType library in use.
+ *
+ * TTF_Init() should be called before calling this function.
+ *
+ * \param major to be filled in with the major version number. Can be nil.
+ * \param minor to be filled in with the minor version number. Can be nil.
+ * \param patch to be filled in with the param version number. Can be nil.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_Init
+ }
+procedure TTF_GetFreeTypeVersion(major: pcint; minor: pcint; patch: pcint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFreeTypeVersion' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the version of the HarfBuzz library in use.
+ *
+ * If HarfBuzz is not available, the version reported is 0.0.0.
+ *
+ * \param major to be filled in with the major version number. Can be nil.
+ * \param minor to be filled in with the minor version number. Can be nil.
+ * \param patch to be filled in with the param version number. Can be nil.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+procedure TTF_GetHarfBuzzVersion(major: pcint; minor: pcint; patch: pcint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetHarfBuzzVersion' {$ENDIF} {$ENDIF};
+
+{*
+ * ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark)
+ }
+const
+ UNICODE_BOM_NATIVE = $FEFF;
+ UNICODE_BOM_SWAPPED = $FFFE;
+
+{*
+ * Tell SDL_ttf whether UNICODE text is generally byteswapped.
+ *
+ * A UNICODE BOM character in a string will override this setting for the
+ * remainder of that string.
+ *
+ * \param swapped boolean to indicate whether text is byteswapped
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+procedure TTF_ByteSwappedUNICODE(swapped: TSDL_bool); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_ByteSwappedUNICODE' {$ENDIF} {$ENDIF};
+
+{* The internal structure containing font information *}
+type
+ PPTTF_Font = ^PTTF_Font;
+ PTTF_Font = type Pointer;
+
+{*
+ * Initialize SDL_ttf.
+ *
+ * You must successfully call this function before it is safe to call any
+ * other function in this library, with one exception: a human-readable error
+ * message can be retrieved from TTF_GetError() if this function fails.
+ *
+ * SDL must be initialized before calls to functions in this library, because
+ * this library uses utility functions from the SDL library.
+ *
+ * It is safe to call this more than once; the library keeps a counter of init
+ * calls, and decrements it on each call to TTF_Quit, so you must pair your
+ * init and quit calls.
+ *
+ * \returns 0 on success, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_Quit
+ }
+function TTF_Init(): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_Init' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from a file, using a specified point size.
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param file path to font file.
+ * \param ptsize point size to use for the newly-opened font.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFont(file_: PAnsiChar; ptsize: cint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFont' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from a file, using a specified face index.
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * Some fonts have multiple "faces" included. The index specifies which face
+ * to use from the font file. Font files with only one face should specify
+ * zero for the index.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param file path to font file.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param index index of the face in the font file.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontIndex(file_: PAnsiChar; ptsize: cint; index: clong): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontIndex' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from an SDL_RWops, using a specified point size.
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * If `freesrc` is non-zero, the RWops will be closed before returning,
+ * whether this function succeeds or not. SDL_ttf reads everything it needs
+ * from the RWops during this call in any case.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param src an SDL_RWops to provide a font file's data.
+ * \param freesrc non-zero to close the RWops before returning, zero to leave
+ * it open.
+ * \param ptsize point size to use for the newly-opened font.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontRW(src: PSDL_RWops; freesrc: cint; ptsize: cint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontRW' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from an SDL_RWops, using a specified face index.
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * If `freesrc` is non-zero, the RWops will be closed before returning,
+ * whether this function succeeds or not. SDL_ttf reads everything it needs
+ * from the RWops during this call in any case.
+ *
+ * Some fonts have multiple "faces" included. The index specifies which face
+ * to use from the font file. Font files with only one face should specify
+ * zero for the index.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param src an SDL_RWops to provide a font file's data.
+ * \param freesrc non-zero to close the RWops before returning, zero to leave
+ * it open.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param index index of the face in the font file.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontIndexRW(src: PSDL_RWops; freesrc: cint; ptsize: cint; index: clong): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontIndexRW' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from a file, using target resolutions (in DPI).
+ *
+ * DPI scaling only applies to scalable fonts (e.g. TrueType).
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param file path to font file.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param hdpi the target horizontal DPI.
+ * \param vdpi the target vertical DPI.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontDPI(file_: PAnsiChar; ptsize: cint; hdpi: cuint; vdpi: cuint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontDPI' {$ENDIF} {$ENDIF};
+
+{*
+ * Create a font from a file, using target resolutions (in DPI).
+ *
+ * DPI scaling only applies to scalable fonts (e.g. TrueType).
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * Some fonts have multiple "faces" included. The index specifies which face
+ * to use from the font file. Font files with only one face should specify
+ * zero for the index.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param file path to font file.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param index index of the face in the font file.
+ * \param hdpi the target horizontal DPI.
+ * \param vdpi the target vertical DPI.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontIndexDPI(file_: PAnsiChar; ptsize: cint; index: clong; hdpi: cuint; vdpi: cuint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontIndexDPI' {$ENDIF} {$ENDIF};
+
+{*
+ * Opens a font from an SDL_RWops with target resolutions (in DPI).
+ *
+ * DPI scaling only applies to scalable fonts (e.g. TrueType).
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * If `freesrc` is non-zero, the RWops will be closed before returning,
+ * whether this function succeeds or not. SDL_ttf reads everything it needs
+ * from the RWops during this call in any case.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param src an SDL_RWops to provide a font file's data.
+ * \param freesrc non-zero to close the RWops before returning, zero to leave
+ * it open.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param hdpi the target horizontal DPI.
+ * \param vdpi the target vertical DPI.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontDPIRW(src: PSDL_RWops; freesrc: cint; ptsize: cint; hdpi: cuint; vdpi: cuint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontDPIRW' {$ENDIF} {$ENDIF};
+
+{*
+ * Opens a font from an SDL_RWops with target resolutions (in DPI).
+ *
+ * DPI scaling only applies to scalable fonts (e.g. TrueType).
+ *
+ * Some .fon fonts will have several sizes embedded in the file, so the point
+ * size becomes the index of choosing which size. If the value is too high,
+ * the last indexed size will be the default.
+ *
+ * If `freesrc` is non-zero, the RWops will be closed before returning,
+ * whether this function succeeds or not. SDL_ttf reads everything it needs
+ * from the RWops during this call in any case.
+ *
+ * Some fonts have multiple "faces" included. The index specifies which face
+ * to use from the font file. Font files with only one face should specify
+ * zero for the index.
+ *
+ * When done with the returned TTF_Font, use TTF_CloseFont() to dispose of it.
+ *
+ * \param src an SDL_RWops to provide a font file's data.
+ * \param freesrc non-zero to close the RWops before returning, zero to leave
+ * it open.
+ * \param ptsize point size to use for the newly-opened font.
+ * \param index index of the face in the font file.
+ * \param hdpi the target horizontal DPI.
+ * \param vdpi the target vertical DPI.
+ * \returns a valid TTF_Font, or nil on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_CloseFont
+ }
+function TTF_OpenFontIndexDPIRW(src: PSDL_RWops; freesrc: cint; ptsize: cint; index: clong; hdpi: cuint; vdpi: cuint): PTTF_Font; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_OpenFontIndexDPIRW' {$ENDIF} {$ENDIF};
+
+{*
+ * Set a font's size dynamically.
+ *
+ * This clears already-generated glyphs, if any, from the cache.
+ *
+ * \param font the font to resize.
+ * \param ptsize the new point size.
+ * \returns 0 if successful, -1 on error
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+function TTF_SetFontSize(font: PTTF_Font; ptsize: cint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontSize' {$ENDIF} {$ENDIF};
+
+{*
+ * Set font size dynamically with target resolutions (in DPI).
+ *
+ * This clears already-generated glyphs, if any, from the cache.
+ *
+ * \param font the font to resize.
+ * \param ptsize the new point size.
+ * \param hdpi the target horizontal DPI.
+ * \param vdpi the target vertical DPI.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+function TTF_SetFontSizeDPI(font: PTTF_Font; ptsize: cint; hdpi: cuint; vdpi: cuint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontSizeDPI' {$ENDIF} {$ENDIF};
+
+{*
+ * Font style flags
+ }
+const
+ TTF_STYLE_NORMAL = $00;
+ TTF_STYLE_BOLD = $01;
+ TTF_STYLE_ITALIC = $02;
+ TTF_STYLE_UNDERLINE = $04;
+ TTF_STYLE_STRIKETHROUGH = $08;
+
+{*
+ * Query a font's current style.
+ *
+ * The font styles are a set of bit flags, OR'd together:
+ *
+ * - `TTF_STYLE_NORMAL` (is zero)
+ * - `TTF_STYLE_BOLD`
+ * - `TTF_STYLE_ITALIC`
+ * - `TTF_STYLE_UNDERLINE`
+ * - `TTF_STYLE_STRIKETHROUGH`
+ *
+ * \param font the font to query.
+ * \returns the current font style, as a set of bit flags.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SetFontStyle
+ }
+function TTF_GetFontStyle(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontStyle' {$ENDIF} {$ENDIF};
+
+{*
+ * Set a font's current style.
+ *
+ * Setting the style clears already-generated glyphs, if any, from the cache.
+ *
+ * The font styles are a set of bit flags, OR'd together:
+ *
+ * - `TTF_STYLE_NORMAL` (is zero)
+ * - `TTF_STYLE_BOLD`
+ * - `TTF_STYLE_ITALIC`
+ * - `TTF_STYLE_UNDERLINE`
+ * - `TTF_STYLE_STRIKETHROUGH`
+ *
+ * \param font the font to set a new style on.
+ * \param style the new style values to set, OR'd together.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GetFontStyle
+ }
+procedure TTF_SetFontStyle(font: PTTF_Font; style: cint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontStyle' {$ENDIF} {$ENDIF};
+
+{*
+ * Query a font's current outline.
+ *
+ * \param font the font to query.
+ * \returns the font's current outline value.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SetFontOutline
+ }
+function TTF_GetFontOutline(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontOutline' {$ENDIF} {$ENDIF};
+
+{*
+ * Set a font's current outline.
+ *
+ * \param font the font to set a new outline on.
+ * \param outline positive outline value, 0 to default.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GetFontOutline
+ }
+procedure TTF_SetFontOutline(font: PTTF_Font; outline: cint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontOutline' {$ENDIF} {$ENDIF};
+
+{*
+ * Hinting flags
+ }
+const
+ TTF_HINTING_NORMAL = 0;
+ TTF_HINTING_LIGHT = 1;
+ TTF_HINTING_MONO = 2;
+ TTF_HINTING_NONE = 3;
+ TTF_HINTING_LIGHT_SUBPIXEL = 4;
+
+{*
+ * Query a font's current FreeType hinter setting.
+ *
+ * The hinter setting is a single value:
+ *
+ * - `TTF_HINTING_NORMAL`
+ * - `TTF_HINTING_LIGHT`
+ * - `TTF_HINTING_MONO`
+ * - `TTF_HINTING_NONE`
+ * - `TTF_HINTING_LIGHT_SUBPIXEL` (available in SDL_ttf 2.0.18 and later)
+ *
+ * \param font the font to query.
+ * \returns the font's current hinter value.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SetFontHinting
+ }
+function TTF_GetFontHinting(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontHinting' {$ENDIF} {$ENDIF};
+
+{*
+ * Set a font's current hinter setting.
+ *
+ * Setting it clears already-generated glyphs, if any, from the cache.
+ *
+ * The hinter setting is a single value:
+ *
+ * - `TTF_HINTING_NORMAL`
+ * - `TTF_HINTING_LIGHT`
+ * - `TTF_HINTING_MONO`
+ * - `TTF_HINTING_NONE`
+ * - `TTF_HINTING_LIGHT_SUBPIXEL` (available in SDL_ttf 2.0.18 and later)
+ *
+ * \param font the font to set a new hinter setting on.
+ * \param hinting the new hinter setting.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GetFontHinting
+ }
+procedure TTF_SetFontHinting(font: PTTF_Font; hinting: cint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontHinting' {$ENDIF} {$ENDIF};
+
+{*
+ * Special layout option for rendering wrapped text
+ }
+const
+ TTF_WRAPPED_ALIGN_LEFT = 0;
+ TTF_WRAPPED_ALIGN_CENTER = 1;
+ TTF_WRAPPED_ALIGN_RIGHT = 2;
+
+{*
+ * Query a font's current wrap alignment option.
+ *
+ * The wrap alignment option can be one of the following:
+ *
+ * - `TTF_WRAPPED_ALIGN_LEFT`
+ * - `TTF_WRAPPED_ALIGN_CENTER`
+ * - `TTF_WRAPPED_ALIGN_RIGHT`
+ *
+ * \param font the font to query.
+ * \returns the font's current wrap alignment option.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_SetFontWrappedAlign
+ }
+function TTF_GetFontWrappedAlign(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontWrappedAlign' {$ENDIF} {$ENDIF};
+
+{*
+ * Set a font's current wrap alignment option.
+ *
+ * The wrap alignment option can be one of the following:
+ *
+ * - `TTF_WRAPPED_ALIGN_LEFT`
+ * - `TTF_WRAPPED_ALIGN_CENTER`
+ * - `TTF_WRAPPED_ALIGN_RIGHT`
+ *
+ * \param font the font to set a new wrap alignment option on.
+ * \param align the new wrap alignment option.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_GetFontWrappedAlign
+ }
+procedure TTF_SetFontWrappedAlign(font: PTTF_Font; align: cint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontWrappedAlign' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the total height of a font.
+ *
+ * This is usually equal to point size.
+ *
+ * \param font the font to query.
+ * \returns the font's height.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontHeight(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontHeight' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the offset from the baseline to the top of a font.
+ *
+ * This is a positive value, relative to the baseline.
+ *
+ * \param font the font to query.
+ * \returns the font's ascent.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontAscent(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontAscent' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the offset from the baseline to the bottom of a font.
+ *
+ * This is a negative value, relative to the baseline.
+ *
+ * \param font the font to query.
+ * \returns the font's descent.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontDescent(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontDescent' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the recommended spacing between lines of text for a font.
+ *
+ * \param font the font to query.
+ * \returns the font's recommended spacing.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontLineSkip(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontLineSkip' {$ENDIF} {$ENDIF};
+
+{*
+ * Query whether or not kerning is allowed for a font.
+ *
+ * \param font the font to query.
+ * \returns non-zero if kerning is enabled, zero otherwise.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_GetFontKerning(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontKerning' {$ENDIF} {$ENDIF};
+
+{*
+ * Set if kerning is allowed for a font.
+ *
+ * Newly-opened fonts default to allowing kerning. This is generally a good
+ * policy unless you have a strong reason to disable it, as it tends to
+ * produce better rendering (with kerning disabled, some fonts might render
+ * the word `kerning` as something that looks like `keming` for example).
+ *
+ * \param font the font to set kerning on.
+ * \param allowed non-zero to allow kerning, zero to disallow.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+procedure TTF_SetFontKerning(font: PTTF_Font; allowed: cint); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontKerning' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the number of faces of a font.
+ *
+ * \param font the font to query.
+ * \returns the number of FreeType font faces.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontFaces(font: PTTF_Font): clong; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontFaces' {$ENDIF} {$ENDIF};
+
+{*
+ * Query whether a font is fixed-width.
+ *
+ * A "fixed-width" font means all glyphs are the same width across; a
+ * lowercase 'i' will be the same size across as a capital 'W', for example.
+ * This is common for terminals and text editors, and other apps that treat
+ * text as a grid. Most other things (WYSIWYG word processors, web pages, etc)
+ * are more likely to not be fixed-width in most cases.
+ *
+ * \param font the font to query.
+ * \returns non-zero if fixed-width, zero if not.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontFaceIsFixedWidth(font: PTTF_Font): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontFaceIsFixedWidth' {$ENDIF} {$ENDIF};
+
+{*
+ * Query a font's family name.
+ *
+ * This string is dictated by the contents of the font file.
+ *
+ * Note that the returned string is to internal storage, and should not be
+ * modifed or free'd by the caller. The string becomes invalid, with the rest
+ * of the font, when `font` is handed to TTF_CloseFont().
+ *
+ * \param font the font to query.
+ * \returns the font's family name.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontFaceFamilyName(font: PTTF_Font): PAnsiChar; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontFaceFamilyName' {$ENDIF} {$ENDIF};
+
+{*
+ * Query a font's style name.
+ *
+ * This string is dictated by the contents of the font file.
+ *
+ * Note that the returned string is to internal storage, and should not be
+ * modifed or free'd by the caller. The string becomes invalid, with the rest
+ * of the font, when `font` is handed to TTF_CloseFont().
+ *
+ * \param font the font to query.
+ * \returns the font's style name.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+function TTF_FontFaceStyleName(font: PTTF_Font): PAnsiChar; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_FontFaceStyleName' {$ENDIF} {$ENDIF};
+
+{*
+ * Check whether a glyph is provided by the font for a 16-bit codepoint.
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_GlyphIsProvided32() instead, which offers the same functionality
+ * but takes a 32-bit codepoint instead.
+ *
+ * The only reason to use this function is that it was available since the
+ * beginning of time, more or less.
+ *
+ * \param font the font to query.
+ * \param ch the character code to check.
+ * \returns non-zero if font provides a glyph for this character, zero if not.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GlyphIsProvided32
+ }
+function TTF_GlyphIsProvided(font: PTTF_Font; ch: cuint16): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GlyphIsProvided' {$ENDIF} {$ENDIF};
+
+{*
+ * Check whether a glyph is provided by the font for a 32-bit codepoint.
+ *
+ * This is the same as TTF_GlyphIsProvided(), but takes a 32-bit character
+ * instead of 16-bit, and thus can query a larger range. If you are sure
+ * you'll have an SDL_ttf that's version 2.0.18 or newer, there's no reason
+ * not to use this function exclusively.
+ *
+ * \param font the font to query.
+ * \param ch the character code to check.
+ * \returns non-zero if font provides a glyph for this character, zero if not.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+function TTF_GlyphIsProvided32(font: PTTF_Font; ch: cuint32): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GlyphIsProvided32' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the metrics (dimensions) of a font's 16-bit glyph.
+ *
+ * To understand what these metrics mean, here is a useful link:
+ *
+ * https://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_GlyphMetrics32() instead, which offers the same functionality but
+ * takes a 32-bit codepoint instead.
+ *
+ * The only reason to use this function is that it was available since the
+ * beginning of time, more or less.
+ *
+ * \param font the font to query.
+ * \param ch the character code to check.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GlyphMetrics32
+ }
+function TTF_GlyphMetrics(font: PTTF_Font; ch: cuint16; minx: pcint; maxx: pcint; miny: pcint; maxy: pcint; advance: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GlyphMetrics' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the metrics (dimensions) of a font's 32-bit glyph.
+ *
+ * To understand what these metrics mean, here is a useful link:
+ *
+ * https://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+ *
+ * This is the same as TTF_GlyphMetrics(), but takes a 32-bit character
+ * instead of 16-bit, and thus can query a larger range. If you are sure
+ * you'll have an SDL_ttf that's version 2.0.18 or newer, there's no reason
+ * not to use this function exclusively.
+ *
+ * \param font the font to query.
+ * \param ch the character code to check.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+function TTF_GlyphMetrics32(font: PTTF_Font; ch: cuint32; minx: pcint; maxx: pcint; miny: pcint; maxy: pcint; advance: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GlyphMetrics32' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate the dimensions of a rendered string of Latin1 text.
+ *
+ * This will report the width and height, in pixels, of the space that the
+ * specified string will take to fully render.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * You almost certainly want TTF_SizeUTF8() unless you're sure you have a
+ * 1-byte Latin1 encoding. US ASCII characters will work with either function,
+ * but most other Unicode characters packed into a `const char *` will need
+ * UTF-8.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in Latin1 encoding.
+ * \param w will be filled with width, in pixels, on return.
+ * \param h will be filled with height, in pixels, on return.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SizeUTF8
+ * \sa TTF_SizeUNICODE
+ }
+function TTF_SizeText(font: PTTF_Font; text: PAnsiChar; w: pcint; h: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SizeText' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate the dimensions of a rendered string of UTF-8 text.
+ *
+ * This will report the width and height, in pixels, of the space that the
+ * specified string will take to fully render.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in UTF-8 encoding.
+ * \param w will be filled with width, in pixels, on return.
+ * \param h will be filled with height, in pixels, on return.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SizeUNICODE
+ }
+function TTF_SizeUTF8(font: PTTF_Font; text: PAnsiChar; w: pcint; h: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SizeUTF8' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate the dimensions of a rendered string of UCS-2 text.
+ *
+ * This will report the width and height, in pixels, of the space that the
+ * specified string will take to fully render.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in UCS-2 encoding.
+ * \param w will be filled with width, in pixels, on return.
+ * \param h will be filled with height, in pixels, on return.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_SizeUTF8
+ }
+function TTF_SizeUNICODE(font: PTTF_Font; text: pcuint16; w: pcint; h: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SizeUNICODE' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate how much of a Latin1 string will fit in a given width.
+ *
+ * This reports the number of characters that can be rendered before reaching
+ * `measure_width`.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * You almost certainly want TTF_MeasureUTF8() unless you're sure you have a
+ * 1-byte Latin1 encoding. US ASCII characters will work with either function,
+ * but most other Unicode characters packed into a `const char *` will need
+ * UTF-8.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in Latin1 encoding.
+ * \param measure_width maximum width, in pixels, available for the string.
+ * \param count on return, filled with number of characters that can be
+ * rendered.
+ * \param extent on return, filled with latest calculated width.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_MeasureText
+ * \sa TTF_MeasureUTF8
+ * \sa TTF_MeasureUNICODE
+ }
+function TTF_MeasureText(font: PTTF_Font; text: PAnsiChar; measure_width: cint; extent: pcint; count: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_MeasureText' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate how much of a UTF-8 string will fit in a given width.
+ *
+ * This reports the number of characters that can be rendered before reaching
+ * `measure_width`.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in UTF-8 encoding.
+ * \param measure_width maximum width, in pixels, available for the string.
+ * \param count on return, filled with number of characters that can be
+ * rendered.
+ * \param extent on return, filled with latest calculated width.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_MeasureText
+ * \sa TTF_MeasureUTF8
+ * \sa TTF_MeasureUNICODE
+ }
+function TTF_MeasureUTF8(font: PTTF_Font; text: PAnsiChar; measure_width: cint; extent: pcint; count: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_MeasureUTF8' {$ENDIF} {$ENDIF};
+
+{*
+ * Calculate how much of a UCS-2 string will fit in a given width.
+ *
+ * This reports the number of characters that can be rendered before reaching
+ * `measure_width`.
+ *
+ * This does not need to render the string to do this calculation.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * \param font the font to query.
+ * \param text text to calculate, in UCS-2 encoding.
+ * \param measure_width maximum width, in pixels, available for the string.
+ * \param count on return, filled with number of characters that can be
+ * rendered.
+ * \param extent on return, filled with latest calculated width.
+ * \returns 0 if successful, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_MeasureText
+ * \sa TTF_MeasureUTF8
+ * \sa TTF_MeasureUNICODE
+ }
+function TTF_MeasureUNICODE(font: PTTF_Font; text: pcuint16; measure_width: cint; extent: pcint; count: pcint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_MeasureUNICODE' {$ENDIF} {$ENDIF};
+
+{*
+ * Render Latin1 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderText_Solid_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Solid() unless you're sure you
+ * have a 1-byte Latin1 encoding. US ASCII characters will work with either
+ * function, but most other Unicode characters packed into a `const char *`
+ * will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Shaded,
+ * TTF_RenderText_Blended, and TTF_RenderText_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Solid
+ * \sa TTF_RenderUNICODE_Solid
+ }
+function TTF_RenderText_Solid(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Solid' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UTF-8 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUTF8_Solid_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Shaded,
+ * TTF_RenderUTF8_Blended, and TTF_RenderUTF8_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Shaded
+ * \sa TTF_RenderUTF8_Blended
+ * \sa TTF_RenderUTF8_LCD
+ }
+function TTF_RenderUTF8_Solid(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Solid' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UCS-2 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUNICODE_Solid_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with TTF_RenderUNICODE_Shaded,
+ * TTF_RenderUNICODE_Blended, and TTF_RenderUNICODE_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Solid
+ }
+function TTF_RenderUNICODE_Solid(font: PTTF_Font; text: pcuint16; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Solid' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped Latin1 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Solid_Wrapped() unless you're sure
+ * you have a 1-byte Latin1 encoding. US ASCII characters will work with
+ * either function, but most other Unicode characters packed into a `const
+ * char *` will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Shaded_Wrapped,
+ * TTF_RenderText_Blended_Wrapped, and TTF_RenderText_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Solid_Wrapped
+ * \sa TTF_RenderUNICODE_Solid_Wrapped
+ }
+function TTF_RenderText_Solid_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Solid_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UTF-8 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Shaded_Wrapped,
+ * TTF_RenderUTF8_Blended_Wrapped, and TTF_RenderUTF8_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Shaded_Wrapped
+ * \sa TTF_RenderUTF8_Blended_Wrapped
+ * \sa TTF_RenderUTF8_LCD_Wrapped
+ }
+function TTF_RenderUTF8_Solid_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Solid_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UCS-2 text at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with
+ * TTF_RenderUNICODE_Shaded_Wrapped, TTF_RenderUNICODE_Blended_Wrapped, and
+ * TTF_RenderUNICODE_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Solid_Wrapped
+ }
+function TTF_RenderUNICODE_Solid_Wrapped(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Solid_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 16-bit glyph at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_RenderGlyph32_Solid() instead, which offers the same functionality
+ * but takes a 32-bit codepoint instead.
+ *
+ * The only reason to use this function is that it was available since the
+ * beginning of time, more or less.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph_Shaded,
+ * TTF_RenderGlyph_Blended, and TTF_RenderGlyph_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderGlyph32_Solid
+ }
+function TTF_RenderGlyph_Solid(font: PTTF_Font; ch: cuint16; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph_Solid' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 32-bit glyph at fast quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel
+ * will be set to the text color.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * This is the same as TTF_RenderGlyph_Solid(), but takes a 32-bit character
+ * instead of 16-bit, and thus can render a larger range. If you are sure
+ * you'll have an SDL_ttf that's version 2.0.18 or newer, there's no reason
+ * not to use this function exclusively.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph32_Shaded,
+ * TTF_RenderGlyph32_Blended, and TTF_RenderGlyph32_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderGlyph32_Shaded
+ * \sa TTF_RenderGlyph32_Blended
+ * \sa TTF_RenderGlyph32_LCD
+ }
+function TTF_RenderGlyph32_Solid(font: PTTF_Font; ch: cuint32; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph32_Solid' {$ENDIF} {$ENDIF};
+
+{*
+ * Render Latin1 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderText_Shaded_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Shaded() unless you're sure you
+ * have a 1-byte Latin1 encoding. US ASCII characters will work with either
+ * function, but most other Unicode characters packed into a `const char *`
+ * will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid,
+ * TTF_RenderText_Blended, and TTF_RenderText_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Shaded
+ * \sa TTF_RenderUNICODE_Shaded
+ }
+function TTF_RenderText_Shaded(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Shaded' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UTF-8 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUTF8_Shaded_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid,
+ * TTF_RenderUTF8_Blended, and TTF_RenderUTF8_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUNICODE_Shaded
+ }
+function TTF_RenderUTF8_Shaded(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Shaded' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UCS-2 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUNICODE_Shaded_Wrapped() instead if you need to wrap the output
+ * to multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with TTF_RenderUNICODE_Solid,
+ * TTF_RenderUNICODE_Blended, and TTF_RenderUNICODE_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Shaded
+ }
+function TTF_RenderUNICODE_Shaded(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Shaded' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped Latin1 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Shaded_Wrapped() unless you're
+ * sure you have a 1-byte Latin1 encoding. US ASCII characters will work with
+ * either function, but most other Unicode characters packed into a `const
+ * char *` will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid_Wrapped,
+ * TTF_RenderText_Blended_Wrapped, and TTF_RenderText_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Shaded_Wrapped
+ * \sa TTF_RenderUNICODE_Shaded_Wrapped
+ }
+function TTF_RenderText_Shaded_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Shaded_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UTF-8 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid_Wrapped,
+ * TTF_RenderUTF8_Blended_Wrapped, and TTF_RenderUTF8_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Solid_Wrapped
+ * \sa TTF_RenderUTF8_Blended_Wrapped
+ * \sa TTF_RenderUTF8_LCD_Wrapped
+ }
+function TTF_RenderUTF8_Shaded_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Shaded_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UCS-2 text at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with
+ * TTF_RenderUNICODE_Solid_Wrapped, TTF_RenderUNICODE_Blended_Wrapped, and
+ * TTF_RenderUNICODE_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Shaded_Wrapped
+ }
+function TTF_RenderUNICODE_Shaded_Wrapped(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Shaded_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 16-bit glyph at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_RenderGlyph32_Shaded() instead, which offers the same functionality
+ * but takes a 32-bit codepoint instead.
+ *
+ * The only reason to use this function is that it was available since the
+ * beginning of time, more or less.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph_Solid,
+ * TTF_RenderGlyph_Blended, and TTF_RenderGlyph_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderGlyph32_Shaded
+ }
+function TTF_RenderGlyph_Shaded(font: PTTF_Font; ch: cuint16; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph_Shaded' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 32-bit glyph at high quality to a new 8-bit surface.
+ *
+ * This function will allocate a new 8-bit, palettized surface. The surface's
+ * 0 pixel will be the specified background color, while other pixels have
+ * varying degrees of the foreground color. This function returns the new
+ * surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * This is the same as TTF_RenderGlyph_Shaded(), but takes a 32-bit character
+ * instead of 16-bit, and thus can render a larger range. If you are sure
+ * you'll have an SDL_ttf that's version 2.0.18 or newer, there's no reason
+ * not to use this function exclusively.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph32_Solid,
+ * TTF_RenderGlyph32_Blended, and TTF_RenderGlyph32_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 8-bit, palettized surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderGlyph32_Solid
+ * \sa TTF_RenderGlyph32_Blended
+ * \sa TTF_RenderGlyph32_LCD
+ }
+function TTF_RenderGlyph32_Shaded(font: PTTF_Font; ch: cuint32; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph32_Shaded' {$ENDIF} {$ENDIF};
+
+{*
+ * Render Latin1 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderText_Blended_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Blended() unless you're sure you
+ * have a 1-byte Latin1 encoding. US ASCII characters will work with either
+ * function, but most other Unicode characters packed into a `const char *`
+ * will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid,
+ * TTF_RenderText_Blended, and TTF_RenderText_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Shaded
+ * \sa TTF_RenderUNICODE_Shaded
+ }
+function TTF_RenderText_Blended(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Blended' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UTF-8 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUTF8_Blended_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid,
+ * TTF_RenderUTF8_Shaded, and TTF_RenderUTF8_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUNICODE_Blended
+ }
+function TTF_RenderUTF8_Blended(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Blended' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UCS-2 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUNICODE_Blended_Wrapped() instead if you need to wrap the output
+ * to multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with TTF_RenderUNICODE_Solid,
+ * TTF_RenderUNICODE_Shaded, and TTF_RenderUNICODE_LCD.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderUTF8_Blended
+ }
+function TTF_RenderUNICODE_Blended(font: PTTF_Font; text: pcuint16; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Blended' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped Latin1 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_Blended_Wrapped() unless you're
+ * sure you have a 1-byte Latin1 encoding. US ASCII characters will work with
+ * either function, but most other Unicode characters packed into a `const
+ * char *` will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid_Wrapped,
+ * TTF_RenderText_Shaded_Wrapped, and TTF_RenderText_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Blended_Wrapped
+ * \sa TTF_RenderUNICODE_Blended_Wrapped
+ }
+function TTF_RenderText_Blended_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_Blended_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UTF-8 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid_Wrapped,
+ * TTF_RenderUTF8_Shaded_Wrapped, and TTF_RenderUTF8_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Solid_Wrapped
+ * \sa TTF_RenderUTF8_Shaded_Wrapped
+ * \sa TTF_RenderUTF8_LCD_Wrapped
+ }
+function TTF_RenderUTF8_Blended_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_Blended_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UCS-2 text at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with
+ * TTF_RenderUNICODE_Solid_Wrapped, TTF_RenderUNICODE_Shaded_Wrapped, and
+ * TTF_RenderUNICODE_LCD_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderUTF8_Blended_Wrapped
+ }
+function TTF_RenderUNICODE_Blended_Wrapped(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_Blended_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 16-bit glyph at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_RenderGlyph32_Blended() instead, which offers the same
+ * functionality but takes a 32-bit codepoint instead.
+ *
+ * The only reason to use this function is that it was available since the
+ * beginning of time, more or less.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph_Solid,
+ * TTF_RenderGlyph_Shaded, and TTF_RenderGlyph_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_RenderGlyph32_Blended
+ }
+function TTF_RenderGlyph_Blended(font: PTTF_Font; ch: cuint16; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph_Blended' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 32-bit glyph at high quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, using alpha
+ * blending to dither the font with the given color. This function returns the
+ * new surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * This is the same as TTF_RenderGlyph_Blended(), but takes a 32-bit character
+ * instead of 16-bit, and thus can render a larger range. If you are sure
+ * you'll have an SDL_ttf that's version 2.0.18 or newer, there's no reason
+ * not to use this function exclusively.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph32_Solid,
+ * TTF_RenderGlyph32_Shaded, and TTF_RenderGlyph32_LCD.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_RenderGlyph32_Solid
+ * \sa TTF_RenderGlyph32_Shaded
+ * \sa TTF_RenderGlyph32_LCD
+ }
+function TTF_RenderGlyph32_Blended(font: PTTF_Font; ch: cuint32; fg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph32_Blended' {$ENDIF} {$ENDIF};
+
+{*
+ * Render Latin1 text at LCD subpixel quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderText_LCD_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_LCD() unless you're sure you have
+ * a 1-byte Latin1 encoding. US ASCII characters will work with either
+ * function, but most other Unicode characters packed into a `const char *`
+ * will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid,
+ * TTF_RenderText_Shaded, and TTF_RenderText_Blended.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUTF8_LCD
+ * \sa TTF_RenderUNICODE_LCD
+ }
+function TTF_RenderText_LCD(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_LCD' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UTF-8 text at LCD subpixel quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUTF8_LCD_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid,
+ * TTF_RenderUTF8_Shaded, and TTF_RenderUTF8_Blended.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUNICODE_LCD
+ }
+function TTF_RenderUTF8_LCD(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_LCD' {$ENDIF} {$ENDIF};
+
+{*
+ * Render UCS-2 text at LCD subpixel quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * This will not word-wrap the string; you'll get a surface with a single line
+ * of text, as long as the string requires. You can use
+ * TTF_RenderUNICODE_LCD_Wrapped() instead if you need to wrap the output to
+ * multiple lines.
+ *
+ * This will not wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with TTF_RenderUNICODE_Solid,
+ * TTF_RenderUNICODE_Shaded, and TTF_RenderUNICODE_Blended.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUTF8_LCD
+ }
+function TTF_RenderUNICODE_LCD(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_LCD' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped Latin1 text at LCD subpixel quality to a new ARGB
+ * surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You almost certainly want TTF_RenderUTF8_LCD_Wrapped() unless you're sure
+ * you have a 1-byte Latin1 encoding. US ASCII characters will work with
+ * either function, but most other Unicode characters packed into a `const
+ * char *` will need UTF-8.
+ *
+ * You can render at other quality levels with TTF_RenderText_Solid_Wrapped,
+ * TTF_RenderText_Shaded_Wrapped, and TTF_RenderText_Blended_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in Latin1 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUTF8_LCD_Wrapped
+ * \sa TTF_RenderUNICODE_LCD_Wrapped
+ }
+function TTF_RenderText_LCD_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderText_LCD_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UTF-8 text at LCD subpixel quality to a new ARGB
+ * surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * You can render at other quality levels with TTF_RenderUTF8_Solid_Wrapped,
+ * TTF_RenderUTF8_Shaded_Wrapped, and TTF_RenderUTF8_Blended_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UTF-8 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUTF8_Solid_Wrapped
+ * \sa TTF_RenderUTF8_Shaded_Wrapped
+ * \sa TTF_RenderUTF8_Blended_Wrapped
+ }
+function TTF_RenderUTF8_LCD_Wrapped(font: PTTF_Font; text: PAnsiChar; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUTF8_LCD_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render word-wrapped UCS-2 text at LCD subpixel quality to a new ARGB
+ * surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * Text is wrapped to multiple lines on line endings and on word boundaries if
+ * it extends beyond `wrapLength` in pixels.
+ *
+ * If wrapLength is 0, this function will only wrap on newline characters.
+ *
+ * Please note that this function is named "Unicode" but currently expects
+ * UCS-2 encoding (16 bits per codepoint). This does not give you access to
+ * large Unicode values, such as emoji glyphs. These codepoints are accessible
+ * through the UTF-8 version of this function.
+ *
+ * You can render at other quality levels with
+ * TTF_RenderUNICODE_Solid_Wrapped, TTF_RenderUNICODE_Shaded_Wrapped, and
+ * TTF_RenderUNICODE_Blended_Wrapped.
+ *
+ * \param font the font to render with.
+ * \param text text to render, in UCS-2 encoding.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderUTF8_LCD_Wrapped
+ }
+function TTF_RenderUNICODE_LCD_Wrapped(font: PTTF_Font; text: pcuint16; fg: TSDL_Color; bg: TSDL_Color; wrapLength: cuint32): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderUNICODE_LCD_Wrapped' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 16-bit glyph at LCD subpixel quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * Note that this version of the function takes a 16-bit character code, which
+ * covers the Basic Multilingual Plane, but is insufficient to cover the
+ * entire set of possible Unicode values, including emoji glyphs. You should
+ * use TTF_RenderGlyph32_LCD() instead, which offers the same functionality
+ * but takes a 32-bit codepoint instead.
+ *
+ * This function only exists for consistency with the existing API at the time
+ * of its addition.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph_Solid,
+ * TTF_RenderGlyph_Shaded, and TTF_RenderGlyph_Blended.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderGlyph32_LCD
+ }
+function TTF_RenderGlyph_LCD(font: PTTF_Font; ch: cuint16; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph_LCD' {$ENDIF} {$ENDIF};
+
+{*
+ * Render a single 32-bit glyph at LCD subpixel quality to a new ARGB surface.
+ *
+ * This function will allocate a new 32-bit, ARGB surface, and render
+ * alpha-blended text using FreeType's LCD subpixel rendering. This function
+ * returns the new surface, or nil if there was an error.
+ *
+ * The glyph is rendered without any padding or centering in the X direction,
+ * and aligned normally in the Y direction.
+ *
+ * This is the same as TTF_RenderGlyph_LCD(), but takes a 32-bit character
+ * instead of 16-bit, and thus can render a larger range. Between the two, you
+ * should always use this function.
+ *
+ * You can render at other quality levels with TTF_RenderGlyph32_Solid,
+ * TTF_RenderGlyph32_Shaded, and TTF_RenderGlyph32_Blended.
+ *
+ * \param font the font to render with.
+ * \param ch the character to render.
+ * \param fg the foreground color for the text.
+ * \param bg the background color for the text.
+ * \returns a new 32-bit, ARGB surface, or nil if there was an error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ *
+ * \sa TTF_RenderGlyph32_Solid
+ * \sa TTF_RenderGlyph32_Shaded
+ * \sa TTF_RenderGlyph32_Blended
+ }
+function TTF_RenderGlyph32_LCD(font: PTTF_Font; ch: cuint32; fg: TSDL_Color; bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_RenderGlyph32_LCD' {$ENDIF} {$ENDIF};
+
+{* For compatibility with previous versions, here are the old functions *}
+function TTF_RenderText(font: PTTF_Font; text: PAnsiChar; fg, bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_TTF_RenderText_Shaded' {$ELSE} 'TTF_RenderText_Shaded' {$ENDIF};
+function TTF_RenderUTF8(font: PTTF_Font; text: PAnsiChar; fg, bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_TTF_RenderUTF8_Shaded' {$ELSE} 'TTF_RenderUTF8_Shaded' {$ENDIF};
+function TTF_RenderUNICODE(font: PTTF_Font; text: pcuint16; fg, bg: TSDL_Color): PSDL_Surface; cdecl;
+ external TTF_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_TTF_RenderUNICODE_Shaded' {$ELSE} 'TTF_RenderUNICODE_Shaded' {$ENDIF};
+
+{*
+ * Dispose of a previously-created font.
+ *
+ * Call this when done with a font. This function will free any resources
+ * associated with it. It is safe to call this function on nil, for example
+ * on the result of a failed call to TTF_OpenFont().
+ *
+ * The font is not valid after being passed to this function. String pointers
+ * from functions that return information on this font, such as
+ * TTF_FontFaceFamilyName() and TTF_FontFaceStyleName(), are no longer valid
+ * after this call, as well.
+ *
+ * \param font the font to dispose of.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_OpenFontIndexDPIRW
+ * \sa TTF_OpenFontRW
+ * \sa TTF_OpenFontDPI
+ * \sa TTF_OpenFontDPIRW
+ * \sa TTF_OpenFontIndex
+ * \sa TTF_OpenFontIndexDPI
+ * \sa TTF_OpenFontIndexDPIRW
+ * \sa TTF_OpenFontIndexRW
+ }
+procedure TTF_CloseFont(font: PTTF_Font); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_CloseFont' {$ENDIF} {$ENDIF};
+
+{*
+ * Deinitialize SDL_ttf.
+ *
+ * You must call this when done with the library, to free internal resources.
+ * It is safe to call this when the library isn't initialized, as it will just
+ * return immediately.
+ *
+ * Once you have as many quit calls as you have had successful calls to
+ * TTF_Init, the library will actually deinitialize.
+ *
+ * Please note that this does not automatically close any fonts that are still
+ * open at the time of deinitialization, and it is possibly not safe to close
+ * them afterwards, as parts of the library will no longer be initialized to
+ * deal with it. A well-written program should call TTF_CloseFont() on any
+ * open fonts before calling this function!
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ }
+procedure TTF_Quit(); cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_Quit' {$ENDIF} {$ENDIF};
+
+{*
+ * Check if SDL_ttf is initialized.
+ *
+ * This reports the number of times the library has been initialized by a call
+ * to TTF_Init(), without a paired deinitialization request from TTF_Quit().
+ *
+ * In short: if it's greater than zero, the library is currently initialized
+ * and ready to work. If zero, it is not initialized.
+ *
+ * Despite the return value being a signed integer, this function should not
+ * return a negative number.
+ *
+ * \returns the current number of initialization calls, that need to
+ * eventually be paired with this many calls to TTF_Quit().
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_Init
+ * \sa TTF_Quit
+ }
+function TTF_WasInit: cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_WasInit' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the kerning size of two glyphs indices.
+ *
+ * \deprecated This function accidentally requires FreeType font indexes,
+ * not codepoints, which we don't expose through this API, so
+ * it could give wildly incorrect results, especially with
+ * non-ASCII values. Going forward, please use
+ * TTF_GetFontKerningSizeGlyphs() instead, which does what you
+ * probably expected this function to do.
+ *
+ * \param font the font to query.
+ * \param prev_index the font index, NOT codepoint, of the previous character.
+ * \param index the font index, NOT codepoint, of the current character.
+ * \returns The kerning size between the two specified characters, in pixels, or -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.12.
+ *
+ * \sa TTF_GetFontKerningSizeGlyphs
+ }
+function TTF_GetFontKerningSize(font: PTTF_Font; prev_index: cint; index: cint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontKerningSize' {$ENDIF} {$ENDIF};
+ deprecated 'This function requires FreeType font indexes, not glyphs. Use TTF_GetFontKerningSizeGlyphs() instead';
+
+{*
+ * Query the kerning size of two 16-bit glyphs.
+ *
+ * Note that this version of the function takes 16-bit character
+ * codes, which covers the Basic Multilingual Plane, but is insufficient
+ * to cover the entire set of possible Unicode values, including emoji
+ * glyphs. You should use TTF_GetFontKerningSizeGlyphs32() instead, which
+ * offers the same functionality but takes a 32-bit codepoints instead.
+ *
+ * The only reason to use this function is that it was available since
+ * the beginning of time, more or less.
+ *
+ * \param font the font to query.
+ * \param previous_ch the previous character's code, 16 bits.
+ * \param ch the current character's code, 16 bits.
+ * \returns The kerning size between the two specified characters, in pixels, or -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.14.
+ *
+ * \sa TTF_GetFontKerningSizeGlyphs32
+ }
+function TTF_GetFontKerningSizeGlyphs(font: PTTF_Font; previous_ch: cuint16; ch: cuint16): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontKerningSizeGlyphs' {$ENDIF} {$ENDIF};
+
+{*
+ * Query the kerning size of two 32-bit glyphs.
+ *
+ * This is the same as TTF_GetFontKerningSizeGlyphs(), but takes 32-bit
+ * characters instead of 16-bit, and thus can manage a larger range. If
+ * you are sure you'll have an SDL_ttf that's version 2.0.18 or newer,
+ * there's no reason not to use this function exclusively.
+ *
+ * \param font the font to query.
+ * \param previous_ch the previous character's code, 32 bits.
+ * \param ch the current character's code, 32 bits.
+ * \returns The kerning size between the two specified characters, in pixels, or -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ }
+function TTF_GetFontKerningSizeGlyphs32(font: PTTF_Font; previous_ch: cuint32; ch: cuint32): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontKerningSizeGlyphs32' {$ENDIF} {$ENDIF};
+
+{*
+ * Enable Signed Distance Field rendering for a font.
+ *
+ * This works with the Blended APIs. SDF is a technique that
+ * helps fonts look sharp even when scaling and rotating.
+ *
+ * This clears already-generated glyphs, if any, from the cache.
+ *
+ * \param font the font to set SDF support on.
+ * \param on_off SDL_TRUE to enable SDF, SDL_FALSE to disable.
+ *
+ * \returns 0 on success, -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_GetFontSDF
+ }
+function TTF_SetFontSDF(font: PTTF_Font; on_off: TSDL_bool): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontSDF' {$ENDIF} {$ENDIF};
+
+{*
+ * Query whether Signed Distance Field rendering is enabled for a font.
+ *
+ * \param font the font to query
+ *
+ * \returns SDL_TRUE if enabled, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_SetFontSDF
+ }
+(* Const before type ignored *)
+function TTF_GetFontSDF(font: PTTF_Font): TSDL_bool; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_GetFontSDF' {$ENDIF} {$ENDIF};
+
+{*
+ * Report SDL_ttf errors
+ *
+ * \sa TTF_GetError
+ }
+function TTF_SetError(const fmt: PAnsiChar; args: array of const): cint; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_SetError' {$ELSE} 'SDL_SetError' {$ENDIF};
+
+{*
+ * Get last SDL_ttf error
+ *
+ * \sa TTF_SetError
+ }
+function TTF_GetError: PAnsiChar; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_GetError' {$ELSE} 'SDL_GetError' {$ENDIF};
+
+{*
+ * Direction flags
+ *
+ * \sa TTF_SetFontDirection
+ }
+type
+ PPTTF_Direction = ^PTTF_Direction;
+ PTTF_Direction = ^TTTF_Direction;
+ TTTF_Direction = type Integer;
+
+const
+ TTF_DIRECTION_LTR = TTTF_Direction(0); { Left to Right }
+ TTF_DIRECTION_RTL = TTTF_Direction(1); { Right to Left }
+ TTF_DIRECTION_TTB = TTTF_Direction(2); { Top to Bottom }
+ TTF_DIRECTION_BTT = TTTF_Direction(3); { Bottom to Top }
+
+{*
+ * Set a global direction to be used for text shaping.
+ *
+ * \deprecated This function expects an hb_direction_t value, from HarfBuzz,
+ * cast to an int, and affects all fonts globally. Please use
+ * TTF_SetFontDirection() instead, which uses an enum supplied by
+ * SDL_ttf itself and operates on a per-font basis.
+ *
+ * This is a global setting; fonts will favor a value set with
+ * TTF_SetFontDirection(), but if they have not had one explicitly
+ * set, they will use the value specified here.
+ *
+ * The default value is `HB_DIRECTION_LTR` (left-to-right text
+ * flow).
+ *
+ * \param direction an hb_direction_t value.
+ * \returns 0, or -1 if SDL_ttf is not compiled with HarfBuzz support.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_SetFontDirection
+ }
+function TTF_SetDirection(direction: cint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetDirection' {$ENDIF} {$ENDIF};
+ deprecated; { hb_direction_t }
+
+
+{*
+ * Set a global script to be used for text shaping.
+ *
+ * \deprecated This function expects an hb_script_t value, from HarfBuzz, cast
+ * to an int, and affects all fonts globally. Please use
+ * TTF_SetFontScriptName() instead, which accepts a string that is
+ * converted to an equivalent int internally, and operates on a
+ * per-font basis.
+ *
+ * This is a global setting; fonts will favor a value set with
+ * TTF_SetFontScriptName(), but if they have not had one
+ * explicitly set, they will use the value specified here.
+ *
+ * The default value is `HB_SCRIPT_UNKNOWN`.
+ *
+ * \returns 0, or -1 if SDL_ttf is not compiled with HarfBuzz support.
+ *
+ * \since This function is available since SDL_ttf 2.0.18.
+ *
+ * \sa TTF_SetFontScriptName
+ }
+function TTF_SetScript(script: cint): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetScript' {$ENDIF} {$ENDIF};
+ deprecated; { hb_script_t }
+
+{*
+ * Set direction to be used for text shaping by a font.
+ *
+ * Any value supplied here will override the global direction set with the
+ * deprecated TTF_SetDirection().
+ *
+ * Possible direction values are:
+ *
+ * - `TTF_DIRECTION_LTR` (Left to Right)
+ * - `TTF_DIRECTION_RTL` (Right to Left)
+ * - `TTF_DIRECTION_TTB` (Top to Bottom)
+ * - `TTF_DIRECTION_BTT` (Bottom to Top)
+ *
+ * If SDL_ttf was not built with HarfBuzz support, this function returns -1.
+ *
+ * \param font the font to specify a direction for.
+ * \param direction the new direction for text to flow.
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ }
+function TTF_SetFontDirection(font: PTTF_Font; direction: TTTF_Direction): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontDirection' {$ENDIF} {$ENDIF};
+
+{*
+ * Set script to be used for text shaping by a font.
+ *
+ * Any value supplied here will override the global script set with the
+ * deprecated TTF_SetScript().
+ *
+ * The supplied script value must be a null-terminated string of exactly four
+ * characters.
+ *
+ * If SDL_ttf was not built with HarfBuzz support, this function returns -1.
+ *
+ * \param font the font to specify a direction for.
+ * \param script null-terminated string of exactly 4 characters.
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL_ttf 2.20.0.
+ }
+function TTF_SetFontScriptName(font: PTTF_Font; script: PAnsiChar): cint; cdecl;
+ external TTF_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_TTF_SetFontScriptName' {$ENDIF} {$ENDIF};
+
+implementation
+
+procedure SDL_TTF_VERSION(out X: TSDL_Version);
+begin
+ x.major := SDL_TTF_MAJOR_VERSION;
+ x.minor := SDL_TTF_MINOR_VERSION;
+ x.patch := SDL_TTF_PATCHLEVEL;
+end;
+
+procedure TTF_VERSION(out X: TSDL_Version);
+begin
+ SDL_TTF_VERSION(X);
+end;
+
+function SDL_TTF_VERSION_ATLEAST(X, Y, Z: Integer): Boolean;
+begin
+ Result := (SDL_TTF_MAJOR_VERSION >= X) and
+ ((SDL_TTF_MAJOR_VERSION > X) or (SDL_TTF_MINOR_VERSION >= Y)) and
+ ((SDL_TTF_MAJOR_VERSION > X) or (SDL_TTF_MINOR_VERSION > Y) or (SDL_TTF_PATCHLEVEL >= Z));
+end;
+
+end.
+
diff --git a/units/sdl2_for_pascal/sdl_runtime_linking.inc b/units/sdl2_for_pascal/sdl_runtime_linking.inc
new file mode 100644
index 0000000..02070a2
--- /dev/null
+++ b/units/sdl2_for_pascal/sdl_runtime_linking.inc
@@ -0,0 +1,1159 @@
+
+{$IFDEF SDL_RUNTIME_LOADING}
+
+Var
+ LibHandle: TLibHandle = 0;
+
+Function SDL_LoadLib(LibFilename: String): Boolean;
+Begin
+ result := false;
+ SDL_UnLoadLib();
+ If LibFilename = '' Then
+ LibFilename := SDL_LibName;
+ LibHandle := LoadLibrary(LibFilename);
+ If LibHandle <> 0 Then Begin
+ (*
+ * Das hier ist nicht mal Ansatzweise fertig, aber es reicht um SDL2 zu initialisieren und einen Joystick ab zu fragen ;)
+ *)
+ result := true;
+
+ SDL_Init := TSDL_Init_func(GetProcAddress(LibHandle, 'SDL_Init'));
+ If Not assigned(SDL_Init) Then result := false;
+ SDL_InitSubSystem := TSDL_InitSubSystem_func(GetProcAddress(LibHandle, 'SDL_InitSubSystem'));
+ If Not assigned(SDL_InitSubSystem) Then result := false;
+ SDL_QuitSubSystem := TSDL_QuitSubSystem_proc(GetProcAddress(LibHandle, 'SDL_QuitSubSystem'));
+ If Not assigned(SDL_QuitSubSystem) Then result := false;
+ SDL_WasInit := TSDL_WasInit_func(GetProcAddress(LibHandle, 'SDL_WasInit'));
+ If Not assigned(SDL_WasInit) Then result := false;
+ SDL_Quit := TSDL_Quit_proc(GetProcAddress(LibHandle, 'SDL_Quit'));
+ If Not assigned(SDL_Quit) Then result := false;
+ SDL_GetAudioDriver := TSDL_GetAudioDriver_func(GetProcAddress(LibHandle, 'SDL_GetAudioDriver'));
+ If Not assigned(SDL_GetAudioDriver) Then result := false;
+ SDL_AudioInit := TSDL_AudioInit_func(GetProcAddress(LibHandle, 'SDL_AudioInit'));
+ If Not assigned(SDL_AudioInit) Then result := false;
+ SDL_OpenAudio := TSDL_OpenAudio_func(GetProcAddress(LibHandle, 'SDL_OpenAudio'));
+ If Not assigned(SDL_OpenAudio) Then result := false;
+ SDL_GetNumAudioDevices := TSDL_GetNumAudioDevices_func(GetProcAddress(LibHandle, 'SDL_GetNumAudioDevices'));
+ If Not assigned(SDL_GetNumAudioDevices) Then result := false;
+ SDL_GetAudioDeviceName := TSDL_GetAudioDeviceName_func(GetProcAddress(LibHandle, 'SDL_GetAudioDeviceName'));
+ If Not assigned(SDL_GetAudioDeviceName) Then result := false;
+ //SDL_GetAudioDeviceSpec := TSDL_GetAudioDeviceSpec_func(GetProcAddress(LibHandle, 'SDL_GetAudioDeviceSpec')); // TODO: Das geht nicht, warum ?
+ //If Not assigned(SDL_GetAudioDeviceSpec) Then result := false;
+ //SDL_GetDefaultAudioInfo := TSDL_GetDefaultAudioInfo_func(GetProcAddress(LibHandle, 'SDL_GetDefaultAudioInfo')); // TODO: Das geht nicht, warum ?
+ //If Not assigned(SDL_GetDefaultAudioInfo) Then result := false;
+ SDL_OpenAudioDevice := TSDL_OpenAudioDevice_func(GetProcAddress(LibHandle, 'SDL_OpenAudioDevice'));
+ If Not assigned(SDL_OpenAudioDevice) Then result := false;
+ SDL_GetAudioDeviceStatus := TSDL_GetAudioDeviceStatus_func(GetProcAddress(LibHandle, 'SDL_GetAudioDeviceStatus'));
+ If Not assigned(SDL_GetAudioDeviceStatus) Then result := false;
+ SDL_PauseAudio := TSDL_PauseAudio_proc(GetProcAddress(LibHandle, 'SDL_PauseAudio'));
+ If Not assigned(SDL_PauseAudio) Then result := false;
+ SDL_PauseAudioDevice := TSDL_PauseAudioDevice_proc(GetProcAddress(LibHandle, 'SDL_PauseAudioDevice'));
+ If Not assigned(SDL_PauseAudioDevice) Then result := false;
+ SDL_LoadWAV_RW := TSDL_LoadWAV_RW_func(GetProcAddress(LibHandle, 'SDL_LoadWAV_RW'));
+ If Not assigned(SDL_LoadWAV_RW) Then result := false;
+ SDL_FreeWAV := TSDL_FreeWAV_proc(GetProcAddress(LibHandle, 'SDL_FreeWAV'));
+ If Not assigned(SDL_FreeWAV) Then result := false;
+ SDL_BuildAudioCVT := TSDL_BuildAudioCVT_func(GetProcAddress(LibHandle, 'SDL_BuildAudioCVT'));
+ If Not assigned(SDL_BuildAudioCVT) Then result := false;
+ SDL_ConvertAudio := TSDL_ConvertAudio_func(GetProcAddress(LibHandle, 'SDL_ConvertAudio'));
+ If Not assigned(SDL_ConvertAudio) Then result := false;
+ SDL_NewAudioStream := TSDL_NewAudioStream_func(GetProcAddress(LibHandle, 'SDL_NewAudioStream'));
+ If Not assigned(SDL_NewAudioStream) Then result := false;
+ SDL_AudioStreamPut := TSDL_AudioStreamPut_func(GetProcAddress(LibHandle, 'SDL_AudioStreamPut'));
+ If Not assigned(SDL_AudioStreamPut) Then result := false;
+ SDL_AudioStreamGet := TSDL_AudioStreamGet_func(GetProcAddress(LibHandle, 'SDL_AudioStreamGet'));
+ If Not assigned(SDL_AudioStreamGet) Then result := false;
+ SDL_AudioStreamAvailable := TSDL_AudioStreamAvailable_func(GetProcAddress(LibHandle, 'SDL_AudioStreamAvailable'));
+ If Not assigned(SDL_AudioStreamAvailable) Then result := false;
+ SDL_AudioStreamFlush := TSDL_AudioStreamFlush_func(GetProcAddress(LibHandle, 'SDL_AudioStreamFlush'));
+ If Not assigned(SDL_AudioStreamFlush) Then result := false;
+ SDL_AudioStreamClear := TSDL_AudioStreamClear_proc(GetProcAddress(LibHandle, 'SDL_AudioStreamClear'));
+ If Not assigned(SDL_AudioStreamClear) Then result := false;
+ SDL_FreeAudioStream := TSDL_FreeAudioStream_proc(GetProcAddress(LibHandle, 'SDL_FreeAudioStream'));
+ If Not assigned(SDL_FreeAudioStream) Then result := false;
+ SDL_MixAudio := TSDL_MixAudio_proc(GetProcAddress(LibHandle, 'SDL_MixAudio'));
+ If Not assigned(SDL_MixAudio) Then result := false;
+ SDL_MixAudioFormat := TSDL_MixAudioFormat_proc(GetProcAddress(LibHandle, 'SDL_MixAudioFormat'));
+ If Not assigned(SDL_MixAudioFormat) Then result := false;
+ SDL_QueueAudio := TSDL_QueueAudio_func(GetProcAddress(LibHandle, 'SDL_QueueAudio'));
+ If Not assigned(SDL_QueueAudio) Then result := false;
+ SDL_DequeueAudio := TSDL_DequeueAudio_func(GetProcAddress(LibHandle, 'SDL_DequeueAudio'));
+ If Not assigned(SDL_DequeueAudio) Then result := false;
+ SDL_GetQueuedAudioSize := TSDL_GetQueuedAudioSize_func(GetProcAddress(LibHandle, 'SDL_GetQueuedAudioSize'));
+ If Not assigned(SDL_GetQueuedAudioSize) Then result := false;
+ SDL_ClearQueuedAudio := TSDL_ClearQueuedAudio_proc(GetProcAddress(LibHandle, 'SDL_ClearQueuedAudio'));
+ If Not assigned(SDL_ClearQueuedAudio) Then result := false;
+ SDL_LockAudioDevice := TSDL_LockAudioDevice_proc(GetProcAddress(LibHandle, 'SDL_LockAudioDevice'));
+ If Not assigned(SDL_LockAudioDevice) Then result := false;
+ SDL_UnlockAudioDevice := TSDL_UnlockAudioDevice_proc(GetProcAddress(LibHandle, 'SDL_UnlockAudioDevice'));
+ If Not assigned(SDL_UnlockAudioDevice) Then result := false;
+ SDL_CloseAudioDevice := TSDL_CloseAudioDevice_proc(GetProcAddress(LibHandle, 'SDL_CloseAudioDevice'));
+ If Not assigned(SDL_CloseAudioDevice) Then result := false;
+ SDL_ComposeCustomBlendMode := TSDL_ComposeCustomBlendMode_func(GetProcAddress(LibHandle, 'SDL_ComposeCustomBlendMode'));
+ If Not assigned(SDL_ComposeCustomBlendMode) Then result := false;
+ SDL_SetClipboardText := TSDL_SetClipboardText_func(GetProcAddress(LibHandle, 'SDL_SetClipboardText'));
+ If Not assigned(SDL_SetClipboardText) Then result := false;
+ SDL_GetClipboardText := TSDL_GetClipboardText_func(GetProcAddress(LibHandle, 'SDL_GetClipboardText'));
+ If Not assigned(SDL_GetClipboardText) Then result := false;
+ SDL_HasClipboardText := TSDL_HasClipboardText_func(GetProcAddress(LibHandle, 'SDL_HasClipboardText'));
+ If Not assigned(SDL_HasClipboardText) Then result := false;
+ //SDL_SetPrimarySelectionText := TSDL_SetPrimarySelectionText_func(GetProcAddress(LibHandle, 'SDL_SetPrimarySelectionText')); // TODO: Das geht nicht, warum ?
+ //If Not assigned(SDL_SetPrimarySelectionText) Then result := false;
+ //SDL_GetPrimarySelectionText := TSDL_GetPrimarySelectionText_func(GetProcAddress(LibHandle, 'SDL_GetPrimarySelectionText'));
+ //If Not assigned(SDL_GetPrimarySelectionText) Then result := false;
+ //SDL_HasPrimarySelectionText := TSDL_HasPrimarySelectionText_func(GetProcAddress(LibHandle, 'SDL_HasPrimarySelectionText'));
+ //If Not assigned(SDL_HasPrimarySelectionText) Then result := false;
+ SDL_GetCPUCount := TSDL_GetCPUCount_func(GetProcAddress(LibHandle, 'SDL_GetCPUCount'));
+ If Not assigned(SDL_GetCPUCount) Then result := false;
+ SDL_SetError := TSDL_SetError_func(GetProcAddress(LibHandle, 'SDL_SetError'));
+ If Not assigned(SDL_SetError) Then result := false;
+ //SDL_GetErrorMsg := TSDL_GetErrorMsg_func(GetProcAddress(LibHandle, 'SDL_GetErrorMsg'));
+ //If Not assigned(SDL_GetErrorMsg) Then result := false;
+ SDL_Error := TSDL_Error_func(GetProcAddress(LibHandle, 'SDL_Error'));
+ If Not assigned(SDL_Error) Then result := false;
+ SDL_GetBasePath := TSDL_GetBasePath_func(GetProcAddress(LibHandle, 'SDL_GetBasePath'));
+ If Not assigned(SDL_GetBasePath) Then result := false;
+ SDL_GetPrefPath := TSDL_GetPrefPath_func(GetProcAddress(LibHandle, 'SDL_GetPrefPath'));
+ If Not assigned(SDL_GetPrefPath) Then result := false;
+ SDL_GameControllerAddMappingsFromRW := TSDL_GameControllerAddMappingsFromRW_func(GetProcAddress(LibHandle, 'SDL_GameControllerAddMappingsFromRW'));
+ If Not assigned(SDL_GameControllerAddMappingsFromRW) Then result := false;
+ SDL_GameControllerNumMappings := TSDL_GameControllerNumMappings_func(GetProcAddress(LibHandle, 'SDL_GameControllerNumMappings'));
+ If Not assigned(SDL_GameControllerNumMappings) Then result := false;
+ SDL_GameControllerMappingForIndex := TSDL_GameControllerMappingForIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerMappingForIndex'));
+ If Not assigned(SDL_GameControllerMappingForIndex) Then result := false;
+ //SDL_GameControllerPathForIndex := TSDL_GameControllerPathForIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerPathForIndex'));
+ //If Not assigned(SDL_GameControllerPathForIndex) Then result := false;
+ SDL_GameControllerTypeForIndex := TSDL_GameControllerTypeForIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerTypeForIndex'));
+ If Not assigned(SDL_GameControllerTypeForIndex) Then result := false;
+ SDL_GameControllerMappingForDeviceIndex := TSDL_GameControllerMappingForDeviceIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerMappingForDeviceIndex'));
+ If Not assigned(SDL_GameControllerMappingForDeviceIndex) Then result := false;
+ SDL_GameControllerFromInstanceID := TSDL_GameControllerFromInstanceID_func(GetProcAddress(LibHandle, 'SDL_GameControllerFromInstanceID'));
+ If Not assigned(SDL_GameControllerFromInstanceID) Then result := false;
+ SDL_GameControllerFromPlayerIndex := TSDL_GameControllerFromPlayerIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerFromPlayerIndex'));
+ If Not assigned(SDL_GameControllerFromPlayerIndex) Then result := false;
+ //SDL_GameControllerPath := TSDL_GameControllerPath_func(GetProcAddress(LibHandle, 'SDL_GameControllerPath'));
+ //If Not assigned(SDL_GameControllerPath) Then result := false;
+ SDL_GameControllerGetType := TSDL_GameControllerGetType_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetType'));
+ If Not assigned(SDL_GameControllerGetType) Then result := false;
+ SDL_GameControllerGetPlayerIndex := TSDL_GameControllerGetPlayerIndex_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetPlayerIndex'));
+ If Not assigned(SDL_GameControllerGetPlayerIndex) Then result := false;
+ SDL_GameControllerSetPlayerIndex := TSDL_GameControllerSetPlayerIndex_proc(GetProcAddress(LibHandle, 'SDL_GameControllerSetPlayerIndex'));
+ If Not assigned(SDL_GameControllerSetPlayerIndex) Then result := false;
+ SDL_GameControllerGetVendor := TSDL_GameControllerGetVendor_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetVendor'));
+ If Not assigned(SDL_GameControllerGetVendor) Then result := false;
+ SDL_GameControllerGetProduct := TSDL_GameControllerGetProduct_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetProduct'));
+ If Not assigned(SDL_GameControllerGetProduct) Then result := false;
+ SDL_GameControllerGetProductVersion := TSDL_GameControllerGetProductVersion_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetProductVersion'));
+ If Not assigned(SDL_GameControllerGetProductVersion) Then result := false;
+ //SDL_GameControllerGetFirmwareVersion := TSDL_GameControllerGetFirmwareVersion_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetFirmwareVersion'));
+ //If Not assigned(SDL_GameControllerGetFirmwareVersion) Then result := false;
+ //SDL_GameControllerGetSerial := TSDL_GameControllerGetSerial_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetSerial'));
+ //If Not assigned(SDL_GameControllerGetSerial) Then result := false;
+ //SDL_GameControllerGetSteamHandle := TSDL_GameControllerGetSteamHandle_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetSteamHandle'));
+ //If Not assigned(SDL_GameControllerGetSteamHandle) Then result := false;
+ //SDL_GameControllerHasAxis := TSDL_GameControllerHasAxis_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasAxis'));
+ //If Not assigned(SDL_GameControllerHasAxis) Then result := false;
+ //SDL_GameControllerHasButton := TSDL_GameControllerHasButton_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasButton'));
+ //If Not assigned(SDL_GameControllerHasButton) Then result := false;
+ //SDL_GameControllerGetNumTouchpads := TSDL_GameControllerGetNumTouchpads_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetNumTouchpads'));
+ //If Not assigned(SDL_GameControllerGetNumTouchpads) Then result := false;
+ //SDL_GameControllerGetNumTouchpadFingers := TSDL_GameControllerGetNumTouchpadFingers_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetNumTouchpadFingers'));
+ //If Not assigned(SDL_GameControllerGetNumTouchpadFingers) Then result := false;
+ //SDL_GameControllerGetTouchpadFinger := TSDL_GameControllerGetTouchpadFinger_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetTouchpadFinger'));
+ //If Not assigned(SDL_GameControllerGetTouchpadFinger) Then result := false;
+ //SDL_GameControllerHasSensor := TSDL_GameControllerHasSensor_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasSensor'));
+ //If Not assigned(SDL_GameControllerHasSensor) Then result := false;
+ //SDL_GameControllerSetSensorEnabled := TSDL_GameControllerSetSensorEnabled_func(GetProcAddress(LibHandle, 'SDL_GameControllerSetSensorEnabled'));
+ //If Not assigned(SDL_GameControllerSetSensorEnabled) Then result := false;
+ //SDL_GameControllerIsSensorEnabled := TSDL_GameControllerIsSensorEnabled_func(GetProcAddress(LibHandle, 'SDL_GameControllerIsSensorEnabled'));
+ //If Not assigned(SDL_GameControllerIsSensorEnabled) Then result := false;
+ (*SDL_GameControllerGetSensorDataRate := TSDL_GameControllerGetSensorDataRate_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetSensorDataRate'));
+ If Not assigned(SDL_GameControllerGetSensorDataRate) Then result := false;
+ SDL_GameControllerGetSensorData := TSDL_GameControllerGetSensorData_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetSensorData'));
+ If Not assigned(SDL_GameControllerGetSensorData) Then result := false;
+ SDL_GameControllerGetSensorDataWithTimestamp := TSDL_GameControllerGetSensorDataWithTimestamp_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetSensorDataWithTimestamp'));
+ If Not assigned(SDL_GameControllerGetSensorDataWithTimestamp) Then result := false;
+ SDL_GameControllerHasRumble := TSDL_GameControllerHasRumble_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasRumble'));
+ If Not assigned(SDL_GameControllerHasRumble) Then result := false;
+ SDL_GameControllerRumble := TSDL_GameControllerRumble_func(GetProcAddress(LibHandle, 'SDL_GameControllerRumble'));
+ If Not assigned(SDL_GameControllerRumble) Then result := false;
+ SDL_GameControllerHasRumbleTriggers := TSDL_GameControllerHasRumbleTriggers_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasRumbleTriggers'));
+ If Not assigned(SDL_GameControllerHasRumbleTriggers) Then result := false;
+ SDL_GameControllerRumbleTriggers := TSDL_GameControllerRumbleTriggers_func(GetProcAddress(LibHandle, 'SDL_GameControllerRumbleTriggers'));
+ If Not assigned(SDL_GameControllerRumbleTriggers) Then result := false;
+ SDL_GameControllerHasLED := TSDL_GameControllerHasLED_func(GetProcAddress(LibHandle, 'SDL_GameControllerHasLED'));
+ If Not assigned(SDL_GameControllerHasLED) Then result := false;
+ SDL_GameControllerSetLED := TSDL_GameControllerSetLED_func(GetProcAddress(LibHandle, 'SDL_GameControllerSetLED'));
+ If Not assigned(SDL_GameControllerSetLED) Then result := false;
+ SDL_GameControllerSendEffect := TSDL_GameControllerSendEffect_func(GetProcAddress(LibHandle, 'SDL_GameControllerSendEffect'));
+ If Not assigned(SDL_GameControllerSendEffect) Then result := false;
+ SDL_GameControllerGetAppleSFSymbolsNameForAxis := TSDL_GameControllerGetAppleSFSymbolsNameForAxis_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetAppleSFSymbolsNameForAxis'));
+ If Not assigned(SDL_GameControllerGetAppleSFSymbolsNameForAxis) Then result := false;
+ SDL_GameControllerGetAppleSFSymbolsNameForButton := TSDL_GameControllerGetAppleSFSymbolsNameForButton_func(GetProcAddress(LibHandle, 'SDL_GameControllerGetAppleSFSymbolsNameForButton'));
+ If Not assigned(SDL_GameControllerGetAppleSFSymbolsNameForButton) Then result := false;
+ SDL_RecordGesture := TSDL_RecordGesture_func(GetProcAddress(LibHandle, 'SDL_RecordGesture'));
+ If Not assigned(SDL_RecordGesture) Then result := false;
+ SDL_SaveAllDollarTemplates := TSDL_SaveAllDollarTemplates_func(GetProcAddress(LibHandle, 'SDL_SaveAllDollarTemplates'));
+ If Not assigned(SDL_SaveAllDollarTemplates) Then result := false;
+ SDL_SaveDollarTemplate := TSDL_SaveDollarTemplate_func(GetProcAddress(LibHandle, 'SDL_SaveDollarTemplate'));
+ If Not assigned(SDL_SaveDollarTemplate) Then result := false;
+ SDL_LoadDollarTemplates := TSDL_LoadDollarTemplates_func(GetProcAddress(LibHandle, 'SDL_LoadDollarTemplates'));
+ If Not assigned(SDL_LoadDollarTemplates) Then result := false;
+ SDL_GUIDToString := TSDL_GUIDToString_proc(GetProcAddress(LibHandle, 'SDL_GUIDToString'));
+ If Not assigned(SDL_GUIDToString) Then result := false;
+ SDL_GUIDFromString := TSDL_GUIDFromString_func(GetProcAddress(LibHandle, 'SDL_GUIDFromString'));
+ If Not assigned(SDL_GUIDFromString) Then result := false;
+ SDL_HapticName := TSDL_HapticName_func(GetProcAddress(LibHandle, 'SDL_HapticName'));
+ If Not assigned(SDL_HapticName) Then result := false;
+ SDL_HapticOpen := TSDL_HapticOpen_func(GetProcAddress(LibHandle, 'SDL_HapticOpen'));
+ If Not assigned(SDL_HapticOpen) Then result := false;
+ SDL_HapticOpened := TSDL_HapticOpened_func(GetProcAddress(LibHandle, 'SDL_HapticOpened'));
+ If Not assigned(SDL_HapticOpened) Then result := false;
+ SDL_HapticIndex := TSDL_HapticIndex_func(GetProcAddress(LibHandle, 'SDL_HapticIndex'));
+ If Not assigned(SDL_HapticIndex) Then result := false;
+ SDL_JoystickIsHaptic := TSDL_JoystickIsHaptic_func(GetProcAddress(LibHandle, 'SDL_JoystickIsHaptic'));
+ If Not assigned(SDL_JoystickIsHaptic) Then result := false;
+ SDL_HapticOpenFromJoystick := TSDL_HapticOpenFromJoystick_func(GetProcAddress(LibHandle, 'SDL_HapticOpenFromJoystick'));
+ If Not assigned(SDL_HapticOpenFromJoystick) Then result := false;
+ SDL_HapticClose := TSDL_HapticClose_proc(GetProcAddress(LibHandle, 'SDL_HapticClose'));
+ If Not assigned(SDL_HapticClose) Then result := false;
+ SDL_HapticNumEffects := TSDL_HapticNumEffects_func(GetProcAddress(LibHandle, 'SDL_HapticNumEffects'));
+ If Not assigned(SDL_HapticNumEffects) Then result := false;
+ SDL_HapticNumEffectsPlaying := TSDL_HapticNumEffectsPlaying_func(GetProcAddress(LibHandle, 'SDL_HapticNumEffectsPlaying'));
+ If Not assigned(SDL_HapticNumEffectsPlaying) Then result := false;
+ SDL_HapticQuery := TSDL_HapticQuery_func(GetProcAddress(LibHandle, 'SDL_HapticQuery'));
+ If Not assigned(SDL_HapticQuery) Then result := false;
+ SDL_HapticNumAxes := TSDL_HapticNumAxes_func(GetProcAddress(LibHandle, 'SDL_HapticNumAxes'));
+ If Not assigned(SDL_HapticNumAxes) Then result := false;
+ SDL_HapticEffectSupported := TSDL_HapticEffectSupported_func(GetProcAddress(LibHandle, 'SDL_HapticEffectSupported'));
+ If Not assigned(SDL_HapticEffectSupported) Then result := false;
+ SDL_HapticNewEffect := TSDL_HapticNewEffect_func(GetProcAddress(LibHandle, 'SDL_HapticNewEffect'));
+ If Not assigned(SDL_HapticNewEffect) Then result := false;
+ SDL_HapticUpdateEffect := TSDL_HapticUpdateEffect_func(GetProcAddress(LibHandle, 'SDL_HapticUpdateEffect'));
+ If Not assigned(SDL_HapticUpdateEffect) Then result := false;
+ SDL_HapticRunEffect := TSDL_HapticRunEffect_func(GetProcAddress(LibHandle, 'SDL_HapticRunEffect'));
+ If Not assigned(SDL_HapticRunEffect) Then result := false;
+ SDL_HapticStopEffect := TSDL_HapticStopEffect_func(GetProcAddress(LibHandle, 'SDL_HapticStopEffect'));
+ If Not assigned(SDL_HapticStopEffect) Then result := false;
+ SDL_HapticDestroyEffect := TSDL_HapticDestroyEffect_proc(GetProcAddress(LibHandle, 'SDL_HapticDestroyEffect'));
+ If Not assigned(SDL_HapticDestroyEffect) Then result := false;
+ SDL_HapticGetEffectStatus := TSDL_HapticGetEffectStatus_func(GetProcAddress(LibHandle, 'SDL_HapticGetEffectStatus'));
+ If Not assigned(SDL_HapticGetEffectStatus) Then result := false;
+ SDL_HapticSetGain := TSDL_HapticSetGain_func(GetProcAddress(LibHandle, 'SDL_HapticSetGain'));
+ If Not assigned(SDL_HapticSetGain) Then result := false;
+ SDL_HapticSetAutocenter := TSDL_HapticSetAutocenter_func(GetProcAddress(LibHandle, 'SDL_HapticSetAutocenter'));
+ If Not assigned(SDL_HapticSetAutocenter) Then result := false;
+ SDL_HapticPause := TSDL_HapticPause_func(GetProcAddress(LibHandle, 'SDL_HapticPause'));
+ If Not assigned(SDL_HapticPause) Then result := false;
+ SDL_HapticUnpause := TSDL_HapticUnpause_func(GetProcAddress(LibHandle, 'SDL_HapticUnpause'));
+ If Not assigned(SDL_HapticUnpause) Then result := false;
+ SDL_HapticStopAll := TSDL_HapticStopAll_func(GetProcAddress(LibHandle, 'SDL_HapticStopAll'));
+ If Not assigned(SDL_HapticStopAll) Then result := false;
+ SDL_HapticRumbleSupported := TSDL_HapticRumbleSupported_func(GetProcAddress(LibHandle, 'SDL_HapticRumbleSupported'));
+ If Not assigned(SDL_HapticRumbleSupported) Then result := false;
+ SDL_HapticRumbleInit := TSDL_HapticRumbleInit_func(GetProcAddress(LibHandle, 'SDL_HapticRumbleInit'));
+ If Not assigned(SDL_HapticRumbleInit) Then result := false;
+ SDL_HapticRumblePlay := TSDL_HapticRumblePlay_func(GetProcAddress(LibHandle, 'SDL_HapticRumblePlay'));
+ If Not assigned(SDL_HapticRumblePlay) Then result := false;
+ SDL_HapticRumbleStop := TSDL_HapticRumbleStop_func(GetProcAddress(LibHandle, 'SDL_HapticRumbleStop'));
+ If Not assigned(SDL_HapticRumbleStop) Then result := false;
+ SDL_SetHintWithPriority := TSDL_SetHintWithPriority_func(GetProcAddress(LibHandle, 'SDL_SetHintWithPriority'));
+ If Not assigned(SDL_SetHintWithPriority) Then result := false;
+ SDL_SetHint := TSDL_SetHint_func(GetProcAddress(LibHandle, 'SDL_SetHint'));
+ If Not assigned(SDL_SetHint) Then result := false;
+ SDL_ResetHint := TSDL_ResetHint_func(GetProcAddress(LibHandle, 'SDL_ResetHint'));
+ If Not assigned(SDL_ResetHint) Then result := false;
+ SDL_ResetHints := TSDL_ResetHints_proc(GetProcAddress(LibHandle, 'SDL_ResetHints'));
+ If Not assigned(SDL_ResetHints) Then result := false;
+ SDL_GetHint := TSDL_GetHint_func(GetProcAddress(LibHandle, 'SDL_GetHint'));
+ If Not assigned(SDL_GetHint) Then result := false;
+ SDL_GetHintBoolean := TSDL_GetHintBoolean_func(GetProcAddress(LibHandle, 'SDL_GetHintBoolean'));
+ If Not assigned(SDL_GetHintBoolean) Then result := false;
+ SDL_AddHintCallback := TSDL_AddHintCallback_proc(GetProcAddress(LibHandle, 'SDL_AddHintCallback'));
+ If Not assigned(SDL_AddHintCallback) Then result := false;
+ SDL_DelHintCallback := TSDL_DelHintCallback_proc(GetProcAddress(LibHandle, 'SDL_DelHintCallback'));
+ If Not assigned(SDL_DelHintCallback) Then result := false;
+ SDL_ClearHints := TSDL_ClearHints_proc(GetProcAddress(LibHandle, 'SDL_ClearHints'));
+ If Not assigned(SDL_ClearHints) Then result := false;
+ SDL_LockJoysticks := TSDL_LockJoysticks_proc(GetProcAddress(LibHandle, 'SDL_LockJoysticks'));
+ If Not assigned(SDL_LockJoysticks) Then result := false;
+ SDL_UnlockJoysticks := TSDL_UnlockJoysticks_proc(GetProcAddress(LibHandle, 'SDL_UnlockJoysticks'));
+ If Not assigned(SDL_UnlockJoysticks) Then result := false;//*)
+ SDL_NumJoysticks := TSDL_NumJoysticks_func(GetProcAddress(LibHandle, 'SDL_NumJoysticks'));
+ If Not assigned(SDL_NumJoysticks) Then result := false;
+ SDL_JoystickNameForIndex := TSDL_JoystickNameForIndex_func(GetProcAddress(LibHandle, 'SDL_JoystickNameForIndex'));
+ If Not assigned(SDL_JoystickNameForIndex) Then result := false;
+ (* SDL_JoystickPathForIndex := TSDL_JoystickPathForIndex_func(GetProcAddress(LibHandle, 'SDL_JoystickPathForIndex'));
+ If Not assigned(SDL_JoystickPathForIndex) Then result := false;
+ SDL_JoystickGetDevicePlayerIndex := TSDL_JoystickGetDevicePlayerIndex_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDevicePlayerIndex'));
+ If Not assigned(SDL_JoystickGetDevicePlayerIndex) Then result := false;
+ SDL_JoystickGetDeviceGUID := TSDL_JoystickGetDeviceGUID_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceGUID'));
+ If Not assigned(SDL_JoystickGetDeviceGUID) Then result := false;
+ SDL_JoystickGetDeviceVendor := TSDL_JoystickGetDeviceVendor_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceVendor'));
+ If Not assigned(SDL_JoystickGetDeviceVendor) Then result := false;
+ SDL_JoystickGetDeviceProduct := TSDL_JoystickGetDeviceProduct_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceProduct'));
+ If Not assigned(SDL_JoystickGetDeviceProduct) Then result := false;
+ SDL_JoystickGetDeviceProductVersion := TSDL_JoystickGetDeviceProductVersion_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceProductVersion'));
+ If Not assigned(SDL_JoystickGetDeviceProductVersion) Then result := false;
+ SDL_JoystickGetDeviceType := TSDL_JoystickGetDeviceType_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceType'));
+ If Not assigned(SDL_JoystickGetDeviceType) Then result := false;
+ SDL_JoystickGetDeviceInstanceID := TSDL_JoystickGetDeviceInstanceID_func(GetProcAddress(LibHandle, 'SDL_JoystickGetDeviceInstanceID'));
+ If Not assigned(SDL_JoystickGetDeviceInstanceID) Then result := false;// *)
+ SDL_JoystickOpen := TSDL_JoystickOpen_func(GetProcAddress(LibHandle, 'SDL_JoystickOpen'));
+ If Not assigned(SDL_JoystickOpen) Then result := false;
+ (* SDL_JoystickFromInstanceID := TSDL_JoystickFromInstanceID_func(GetProcAddress(LibHandle, 'SDL_JoystickFromInstanceID'));
+ If Not assigned(SDL_JoystickFromInstanceID) Then result := false;
+ SDL_JoystickFromPlayerIndex := TSDL_JoystickFromPlayerIndex_func(GetProcAddress(LibHandle, 'SDL_JoystickFromPlayerIndex'));
+ If Not assigned(SDL_JoystickFromPlayerIndex) Then result := false;
+ SDL_JoystickAttachVirtual := TSDL_JoystickAttachVirtual_func(GetProcAddress(LibHandle, 'SDL_JoystickAttachVirtual'));
+ If Not assigned(SDL_JoystickAttachVirtual) Then result := false;
+ SDL_JoystickAttachVirtualEx := TSDL_JoystickAttachVirtualEx_func(GetProcAddress(LibHandle, 'SDL_JoystickAttachVirtualEx'));
+ If Not assigned(SDL_JoystickAttachVirtualEx) Then result := false;
+ SDL_JoystickDetachVirtual := TSDL_JoystickDetachVirtual_func(GetProcAddress(LibHandle, 'SDL_JoystickDetachVirtual'));
+ If Not assigned(SDL_JoystickDetachVirtual) Then result := false;
+ SDL_JoystickIsVirtual := TSDL_JoystickIsVirtual_func(GetProcAddress(LibHandle, 'SDL_JoystickIsVirtual'));
+ If Not assigned(SDL_JoystickIsVirtual) Then result := false;
+ SDL_JoystickSetVirtualAxis := TSDL_JoystickSetVirtualAxis_func(GetProcAddress(LibHandle, 'SDL_JoystickSetVirtualAxis'));
+ If Not assigned(SDL_JoystickSetVirtualAxis) Then result := false;
+ SDL_JoystickSetVirtualButton := TSDL_JoystickSetVirtualButton_func(GetProcAddress(LibHandle, 'SDL_JoystickSetVirtualButton'));
+ If Not assigned(SDL_JoystickSetVirtualButton) Then result := false;
+ SDL_JoystickSetVirtualHat := TSDL_JoystickSetVirtualHat_func(GetProcAddress(LibHandle, 'SDL_JoystickSetVirtualHat'));
+ If Not assigned(SDL_JoystickSetVirtualHat) Then result := false;
+ SDL_JoystickName := TSDL_JoystickName_func(GetProcAddress(LibHandle, 'SDL_JoystickName'));
+ If Not assigned(SDL_JoystickName) Then result := false;
+ SDL_JoystickPath := TSDL_JoystickPath_func(GetProcAddress(LibHandle, 'SDL_JoystickPath'));
+ If Not assigned(SDL_JoystickPath) Then result := false;
+ SDL_JoystickGetPlayerIndex := TSDL_JoystickGetPlayerIndex_func(GetProcAddress(LibHandle, 'SDL_JoystickGetPlayerIndex'));
+ If Not assigned(SDL_JoystickGetPlayerIndex) Then result := false;
+ SDL_JoystickSetPlayerIndex := TSDL_JoystickSetPlayerIndex_proc(GetProcAddress(LibHandle, 'SDL_JoystickSetPlayerIndex'));
+ If Not assigned(SDL_JoystickSetPlayerIndex) Then result := false;
+ SDL_JoystickGetGUID := TSDL_JoystickGetGUID_func(GetProcAddress(LibHandle, 'SDL_JoystickGetGUID'));
+ If Not assigned(SDL_JoystickGetGUID) Then result := false;
+ SDL_JoystickGetVendor := TSDL_JoystickGetVendor_func(GetProcAddress(LibHandle, 'SDL_JoystickGetVendor'));
+ If Not assigned(SDL_JoystickGetVendor) Then result := false;
+ SDL_JoystickGetProduct := TSDL_JoystickGetProduct_func(GetProcAddress(LibHandle, 'SDL_JoystickGetProduct'));
+ If Not assigned(SDL_JoystickGetProduct) Then result := false;
+ SDL_JoystickGetProductVersion := TSDL_JoystickGetProductVersion_func(GetProcAddress(LibHandle, 'SDL_JoystickGetProductVersion'));
+ If Not assigned(SDL_JoystickGetProductVersion) Then result := false;
+ SDL_JoystickGetFirmwareVersion := TSDL_JoystickGetFirmwareVersion_func(GetProcAddress(LibHandle, 'SDL_JoystickGetFirmwareVersion'));
+ If Not assigned(SDL_JoystickGetFirmwareVersion) Then result := false;
+ SDL_JoystickGetSerial := TSDL_JoystickGetSerial_func(GetProcAddress(LibHandle, 'SDL_JoystickGetSerial'));
+ If Not assigned(SDL_JoystickGetSerial) Then result := false;
+ SDL_JoystickGetType := TSDL_JoystickGetType_func(GetProcAddress(LibHandle, 'SDL_JoystickGetType'));
+ If Not assigned(SDL_JoystickGetType) Then result := false;
+ SDL_JoystickGetGUIDString := TSDL_JoystickGetGUIDString_proc(GetProcAddress(LibHandle, 'SDL_JoystickGetGUIDString'));
+ If Not assigned(SDL_JoystickGetGUIDString) Then result := false;
+ SDL_JoystickGetGUIDFromString := TSDL_JoystickGetGUIDFromString_func(GetProcAddress(LibHandle, 'SDL_JoystickGetGUIDFromString'));
+ If Not assigned(SDL_JoystickGetGUIDFromString) Then result := false;
+ SDL_GetJoystickGUIDInfo := TSDL_GetJoystickGUIDInfo_proc(GetProcAddress(LibHandle, 'SDL_GetJoystickGUIDInfo'));
+ If Not assigned(SDL_GetJoystickGUIDInfo) Then result := false;
+ SDL_JoystickGetAttached := TSDL_JoystickGetAttached_func(GetProcAddress(LibHandle, 'SDL_JoystickGetAttached'));
+ If Not assigned(SDL_JoystickGetAttached) Then result := false;
+ SDL_JoystickInstanceID := TSDL_JoystickInstanceID_func(GetProcAddress(LibHandle, 'SDL_JoystickInstanceID'));
+ If Not assigned(SDL_JoystickInstanceID) Then result := false;//*)
+ SDL_JoystickNumAxes := TSDL_JoystickNumAxes_func(GetProcAddress(LibHandle, 'SDL_JoystickNumAxes'));
+ If Not assigned(SDL_JoystickNumAxes) Then result := false;
+ (* SDL_JoystickNumBalls := TSDL_JoystickNumBalls_func(GetProcAddress(LibHandle, 'SDL_JoystickNumBalls'));
+ If Not assigned(SDL_JoystickNumBalls) Then result := false;
+ SDL_JoystickNumHats := TSDL_JoystickNumHats_func(GetProcAddress(LibHandle, 'SDL_JoystickNumHats'));
+ If Not assigned(SDL_JoystickNumHats) Then result := false; //*)
+ SDL_JoystickNumButtons := TSDL_JoystickNumButtons_func(GetProcAddress(LibHandle, 'SDL_JoystickNumButtons'));
+ If Not assigned(SDL_JoystickNumButtons) Then result := false;
+ (* SDL_JoystickUpdate := TSDL_JoystickUpdate_proc(GetProcAddress(LibHandle, 'SDL_JoystickUpdate'));
+ If Not assigned(SDL_JoystickUpdate) Then result := false;// *)
+ SDL_JoystickEventState := TSDL_JoystickEventState_func(GetProcAddress(LibHandle, 'SDL_JoystickEventState'));
+ If Not assigned(SDL_JoystickEventState) Then result := false;
+ SDL_JoystickGetAxis := TSDL_JoystickGetAxis_func(GetProcAddress(LibHandle, 'SDL_JoystickGetAxis'));
+ If Not assigned(SDL_JoystickGetAxis) Then result := false;
+ (* SDL_JoystickGetAxisInitialState := TSDL_JoystickGetAxisInitialState_func(GetProcAddress(LibHandle, 'SDL_JoystickGetAxisInitialState'));
+ If Not assigned(SDL_JoystickGetAxisInitialState) Then result := false;
+ SDL_JoystickGetHat := TSDL_JoystickGetHat_func(GetProcAddress(LibHandle, 'SDL_JoystickGetHat'));
+ If Not assigned(SDL_JoystickGetHat) Then result := false;
+ SDL_JoystickGetBall := TSDL_JoystickGetBall_func(GetProcAddress(LibHandle, 'SDL_JoystickGetBall'));
+ If Not assigned(SDL_JoystickGetBall) Then result := false;// *)
+ SDL_JoystickGetButton := TSDL_JoystickGetButton_func(GetProcAddress(LibHandle, 'SDL_JoystickGetButton'));
+ If Not assigned(SDL_JoystickGetButton) Then result := false;
+ (* SDL_JoystickRumble := TSDL_JoystickRumble_func(GetProcAddress(LibHandle, 'SDL_JoystickRumble'));
+ If Not assigned(SDL_JoystickRumble) Then result := false;
+ SDL_JoystickRumbleTriggers := TSDL_JoystickRumbleTriggers_func(GetProcAddress(LibHandle, 'SDL_JoystickRumbleTriggers'));
+ If Not assigned(SDL_JoystickRumbleTriggers) Then result := false;
+ SDL_JoystickHasLED := TSDL_JoystickHasLED_func(GetProcAddress(LibHandle, 'SDL_JoystickHasLED'));
+ If Not assigned(SDL_JoystickHasLED) Then result := false;
+ SDL_JoystickHasRumble := TSDL_JoystickHasRumble_func(GetProcAddress(LibHandle, 'SDL_JoystickHasRumble'));
+ If Not assigned(SDL_JoystickHasRumble) Then result := false;
+ SDL_JoystickHasRumbleTriggers := TSDL_JoystickHasRumbleTriggers_func(GetProcAddress(LibHandle, 'SDL_JoystickHasRumbleTriggers'));
+ If Not assigned(SDL_JoystickHasRumbleTriggers) Then result := false;
+ SDL_JoystickSetLED := TSDL_JoystickSetLED_func(GetProcAddress(LibHandle, 'SDL_JoystickSetLED'));
+ If Not assigned(SDL_JoystickSetLED) Then result := false;
+ SDL_JoystickSendEffect := TSDL_JoystickSendEffect_func(GetProcAddress(LibHandle, 'SDL_JoystickSendEffect'));
+ If Not assigned(SDL_JoystickSendEffect) Then result := false;*)
+ SDL_JoystickClose := TSDL_JoystickClose_proc(GetProcAddress(LibHandle, 'SDL_JoystickClose'));
+ If Not assigned(SDL_JoystickClose) Then result := false;
+ (* SDL_JoystickCurrentPowerLevel := TSDL_JoystickCurrentPowerLevel_func(GetProcAddress(LibHandle, 'SDL_JoystickCurrentPowerLevel'));
+ If Not assigned(SDL_JoystickCurrentPowerLevel) Then result := false;
+ SDL_GetKeyboardState := TSDL_GetKeyboardState_func(GetProcAddress(LibHandle, 'SDL_GetKeyboardState'));
+ If Not assigned(SDL_GetKeyboardState) Then result := false;
+ SDL_SetModState := TSDL_SetModState_proc(GetProcAddress(LibHandle, 'SDL_SetModState'));
+ If Not assigned(SDL_SetModState) Then result := false;
+ SDL_GetKeyFromScancode := TSDL_GetKeyFromScancode_func(GetProcAddress(LibHandle, 'SDL_GetKeyFromScancode'));
+ If Not assigned(SDL_GetKeyFromScancode) Then result := false;
+ SDL_GetScancodeFromKey := TSDL_GetScancodeFromKey_func(GetProcAddress(LibHandle, 'SDL_GetScancodeFromKey'));
+ If Not assigned(SDL_GetScancodeFromKey) Then result := false;
+ SDL_GetScancodeName := TSDL_GetScancodeName_func(GetProcAddress(LibHandle, 'SDL_GetScancodeName'));
+ If Not assigned(SDL_GetScancodeName) Then result := false;
+ SDL_GetScancodeFromName := TSDL_GetScancodeFromName_func(GetProcAddress(LibHandle, 'SDL_GetScancodeFromName'));
+ If Not assigned(SDL_GetScancodeFromName) Then result := false;
+ SDL_GetKeyName := TSDL_GetKeyName_func(GetProcAddress(LibHandle, 'SDL_GetKeyName'));
+ If Not assigned(SDL_GetKeyName) Then result := false;
+ SDL_GetKeyFromName := TSDL_GetKeyFromName_func(GetProcAddress(LibHandle, 'SDL_GetKeyFromName'));
+ If Not assigned(SDL_GetKeyFromName) Then result := false;
+ SDL_SetTextInputRect := TSDL_SetTextInputRect_proc(GetProcAddress(LibHandle, 'SDL_SetTextInputRect'));
+ If Not assigned(SDL_SetTextInputRect) Then result := false;
+ SDL_IsScreenKeyboardShown := TSDL_IsScreenKeyboardShown_func(GetProcAddress(LibHandle, 'SDL_IsScreenKeyboardShown'));
+ If Not assigned(SDL_IsScreenKeyboardShown) Then result := false;
+ SDL_LoadObject := TSDL_LoadObject_func(GetProcAddress(LibHandle, 'SDL_LoadObject'));
+ If Not assigned(SDL_LoadObject) Then result := false;
+ SDL_UnloadObject := TSDL_UnloadObject_proc(GetProcAddress(LibHandle, 'SDL_UnloadObject'));
+ If Not assigned(SDL_UnloadObject) Then result := false;
+ SDL_LogSetAllPriority := TSDL_LogSetAllPriority_proc(GetProcAddress(LibHandle, 'SDL_LogSetAllPriority'));
+ If Not assigned(SDL_LogSetAllPriority) Then result := false;
+ SDL_LogSetPriority := TSDL_LogSetPriority_proc(GetProcAddress(LibHandle, 'SDL_LogSetPriority'));
+ If Not assigned(SDL_LogSetPriority) Then result := false;
+ SDL_LogGetPriority := TSDL_LogGetPriority_func(GetProcAddress(LibHandle, 'SDL_LogGetPriority'));
+ If Not assigned(SDL_LogGetPriority) Then result := false;
+ SDL_LogResetPriorities := TSDL_LogResetPriorities_proc(GetProcAddress(LibHandle, 'SDL_LogResetPriorities'));
+ If Not assigned(SDL_LogResetPriorities) Then result := false;
+ SDL_Log := TSDL_Log_proc(GetProcAddress(LibHandle, 'SDL_Log'));
+ If Not assigned(SDL_Log) Then result := false;
+ SDL_LogVerbose := TSDL_LogVerbose_proc(GetProcAddress(LibHandle, 'SDL_LogVerbose'));
+ If Not assigned(SDL_LogVerbose) Then result := false;
+ SDL_LogDebug := TSDL_LogDebug_proc(GetProcAddress(LibHandle, 'SDL_LogDebug'));
+ If Not assigned(SDL_LogDebug) Then result := false;
+ SDL_LogInfo := TSDL_LogInfo_proc(GetProcAddress(LibHandle, 'SDL_LogInfo'));
+ If Not assigned(SDL_LogInfo) Then result := false;
+ SDL_LogWarn := TSDL_LogWarn_proc(GetProcAddress(LibHandle, 'SDL_LogWarn'));
+ If Not assigned(SDL_LogWarn) Then result := false;
+ SDL_LogError := TSDL_LogError_proc(GetProcAddress(LibHandle, 'SDL_LogError'));
+ If Not assigned(SDL_LogError) Then result := false;
+ SDL_LogCritical := TSDL_LogCritical_proc(GetProcAddress(LibHandle, 'SDL_LogCritical'));
+ If Not assigned(SDL_LogCritical) Then result := false;
+ SDL_LogMessage := TSDL_LogMessage_proc(GetProcAddress(LibHandle, 'SDL_LogMessage'));
+ If Not assigned(SDL_LogMessage) Then result := false;
+ SDL_LogMessageV := TSDL_LogMessageV_proc(GetProcAddress(LibHandle, 'SDL_LogMessageV'));
+ If Not assigned(SDL_LogMessageV) Then result := false;
+ SDL_ShowMessageBox := TSDL_ShowMessageBox_func(GetProcAddress(LibHandle, 'SDL_ShowMessageBox'));
+ If Not assigned(SDL_ShowMessageBox) Then result := false;
+ SDL_ShowSimpleMessageBox := TSDL_ShowSimpleMessageBox_func(GetProcAddress(LibHandle, 'SDL_ShowSimpleMessageBox'));
+ If Not assigned(SDL_ShowSimpleMessageBox) Then result := false;
+ SDL_GetMouseState := TSDL_GetMouseState_func(GetProcAddress(LibHandle, 'SDL_GetMouseState'));
+ If Not assigned(SDL_GetMouseState) Then result := false;
+ SDL_GetGlobalMouseState := TSDL_GetGlobalMouseState_func(GetProcAddress(LibHandle, 'SDL_GetGlobalMouseState'));
+ If Not assigned(SDL_GetGlobalMouseState) Then result := false;
+ SDL_GetRelativeMouseState := TSDL_GetRelativeMouseState_func(GetProcAddress(LibHandle, 'SDL_GetRelativeMouseState'));
+ If Not assigned(SDL_GetRelativeMouseState) Then result := false;
+ SDL_WarpMouseInWindow := TSDL_WarpMouseInWindow_proc(GetProcAddress(LibHandle, 'SDL_WarpMouseInWindow'));
+ If Not assigned(SDL_WarpMouseInWindow) Then result := false;
+ SDL_WarpMouseGlobal := TSDL_WarpMouseGlobal_func(GetProcAddress(LibHandle, 'SDL_WarpMouseGlobal'));
+ If Not assigned(SDL_WarpMouseGlobal) Then result := false;
+ SDL_SetRelativeMouseMode := TSDL_SetRelativeMouseMode_func(GetProcAddress(LibHandle, 'SDL_SetRelativeMouseMode'));
+ If Not assigned(SDL_SetRelativeMouseMode) Then result := false;
+ SDL_CaptureMouse := TSDL_CaptureMouse_func(GetProcAddress(LibHandle, 'SDL_CaptureMouse'));
+ If Not assigned(SDL_CaptureMouse) Then result := false;
+ SDL_CreateCursor := TSDL_CreateCursor_func(GetProcAddress(LibHandle, 'SDL_CreateCursor'));
+ If Not assigned(SDL_CreateCursor) Then result := false;
+ SDL_CreateColorCursor := TSDL_CreateColorCursor_func(GetProcAddress(LibHandle, 'SDL_CreateColorCursor'));
+ If Not assigned(SDL_CreateColorCursor) Then result := false;
+ SDL_CreateSystemCursor := TSDL_CreateSystemCursor_func(GetProcAddress(LibHandle, 'SDL_CreateSystemCursor'));
+ If Not assigned(SDL_CreateSystemCursor) Then result := false;
+ SDL_SetCursor := TSDL_SetCursor_proc(GetProcAddress(LibHandle, 'SDL_SetCursor'));
+ If Not assigned(SDL_SetCursor) Then result := false;
+ SDL_FreeCursor := TSDL_FreeCursor_proc(GetProcAddress(LibHandle, 'SDL_FreeCursor'));
+ If Not assigned(SDL_FreeCursor) Then result := false;
+ SDL_ShowCursor := TSDL_ShowCursor_func(GetProcAddress(LibHandle, 'SDL_ShowCursor'));
+ If Not assigned(SDL_ShowCursor) Then result := false;
+ SDL_LockMutex := TSDL_LockMutex_func(GetProcAddress(LibHandle, 'SDL_LockMutex'));
+ If Not assigned(SDL_LockMutex) Then result := false;
+ SDL_TryLockMutex := TSDL_TryLockMutex_func(GetProcAddress(LibHandle, 'SDL_TryLockMutex'));
+ If Not assigned(SDL_TryLockMutex) Then result := false;
+ SDL_UnlockMutex := TSDL_UnlockMutex_func(GetProcAddress(LibHandle, 'SDL_UnlockMutex'));
+ If Not assigned(SDL_UnlockMutex) Then result := false;
+ SDL_DestroyMutex := TSDL_DestroyMutex_proc(GetProcAddress(LibHandle, 'SDL_DestroyMutex'));
+ If Not assigned(SDL_DestroyMutex) Then result := false;
+ SDL_CreateSemaphore := TSDL_CreateSemaphore_func(GetProcAddress(LibHandle, 'SDL_CreateSemaphore'));
+ If Not assigned(SDL_CreateSemaphore) Then result := false;
+ SDL_DestroySemaphore := TSDL_DestroySemaphore_proc(GetProcAddress(LibHandle, 'SDL_DestroySemaphore'));
+ If Not assigned(SDL_DestroySemaphore) Then result := false;
+ SDL_SemWait := TSDL_SemWait_func(GetProcAddress(LibHandle, 'SDL_SemWait'));
+ If Not assigned(SDL_SemWait) Then result := false;
+ SDL_SemTryWait := TSDL_SemTryWait_func(GetProcAddress(LibHandle, 'SDL_SemTryWait'));
+ If Not assigned(SDL_SemTryWait) Then result := false;
+ SDL_SemWaitTimeout := TSDL_SemWaitTimeout_func(GetProcAddress(LibHandle, 'SDL_SemWaitTimeout'));
+ If Not assigned(SDL_SemWaitTimeout) Then result := false;
+ SDL_SemPost := TSDL_SemPost_func(GetProcAddress(LibHandle, 'SDL_SemPost'));
+ If Not assigned(SDL_SemPost) Then result := false;
+ SDL_SemValue := TSDL_SemValue_func(GetProcAddress(LibHandle, 'SDL_SemValue'));
+ If Not assigned(SDL_SemValue) Then result := false;
+ SDL_DestroyCond := TSDL_DestroyCond_proc(GetProcAddress(LibHandle, 'SDL_DestroyCond'));
+ If Not assigned(SDL_DestroyCond) Then result := false;
+ SDL_CondSignal := TSDL_CondSignal_func(GetProcAddress(LibHandle, 'SDL_CondSignal'));
+ If Not assigned(SDL_CondSignal) Then result := false;
+ SDL_CondBroadcast := TSDL_CondBroadcast_func(GetProcAddress(LibHandle, 'SDL_CondBroadcast'));
+ If Not assigned(SDL_CondBroadcast) Then result := false;
+ SDL_CondWait := TSDL_CondWait_func(GetProcAddress(LibHandle, 'SDL_CondWait'));
+ If Not assigned(SDL_CondWait) Then result := false;
+ SDL_CondWaitTimeout := TSDL_CondWaitTimeout_func(GetProcAddress(LibHandle, 'SDL_CondWaitTimeout'));
+ If Not assigned(SDL_CondWaitTimeout) Then result := false;
+ SDL_GetPixelFormatName := TSDL_GetPixelFormatName_func(GetProcAddress(LibHandle, 'SDL_GetPixelFormatName'));
+ If Not assigned(SDL_GetPixelFormatName) Then result := false;
+ SDL_PixelFormatEnumToMasks := TSDL_PixelFormatEnumToMasks_func(GetProcAddress(LibHandle, 'SDL_PixelFormatEnumToMasks'));
+ If Not assigned(SDL_PixelFormatEnumToMasks) Then result := false;
+ SDL_MasksToPixelFormatEnum := TSDL_MasksToPixelFormatEnum_func(GetProcAddress(LibHandle, 'SDL_MasksToPixelFormatEnum'));
+ If Not assigned(SDL_MasksToPixelFormatEnum) Then result := false;
+ SDL_AllocFormat := TSDL_AllocFormat_func(GetProcAddress(LibHandle, 'SDL_AllocFormat'));
+ If Not assigned(SDL_AllocFormat) Then result := false;
+ SDL_FreeFormat := TSDL_FreeFormat_proc(GetProcAddress(LibHandle, 'SDL_FreeFormat'));
+ If Not assigned(SDL_FreeFormat) Then result := false;
+ SDL_AllocPalette := TSDL_AllocPalette_func(GetProcAddress(LibHandle, 'SDL_AllocPalette'));
+ If Not assigned(SDL_AllocPalette) Then result := false;
+ SDL_SetPixelFormatPalette := TSDL_SetPixelFormatPalette_func(GetProcAddress(LibHandle, 'SDL_SetPixelFormatPalette'));
+ If Not assigned(SDL_SetPixelFormatPalette) Then result := false;
+ SDL_SetPaletteColors := TSDL_SetPaletteColors_func(GetProcAddress(LibHandle, 'SDL_SetPaletteColors'));
+ If Not assigned(SDL_SetPaletteColors) Then result := false;
+ SDL_FreePalette := TSDL_FreePalette_proc(GetProcAddress(LibHandle, 'SDL_FreePalette'));
+ If Not assigned(SDL_FreePalette) Then result := false;
+ SDL_MapRGB := TSDL_MapRGB_func(GetProcAddress(LibHandle, 'SDL_MapRGB'));
+ If Not assigned(SDL_MapRGB) Then result := false;
+ SDL_MapRGBA := TSDL_MapRGBA_func(GetProcAddress(LibHandle, 'SDL_MapRGBA'));
+ If Not assigned(SDL_MapRGBA) Then result := false;
+ SDL_GetRGB := TSDL_GetRGB_proc(GetProcAddress(LibHandle, 'SDL_GetRGB'));
+ If Not assigned(SDL_GetRGB) Then result := false;
+ SDL_GetRGBA := TSDL_GetRGBA_proc(GetProcAddress(LibHandle, 'SDL_GetRGBA'));
+ If Not assigned(SDL_GetRGBA) Then result := false;
+ SDL_CalculateGammaRamp := TSDL_CalculateGammaRamp_proc(GetProcAddress(LibHandle, 'SDL_CalculateGammaRamp'));
+ If Not assigned(SDL_CalculateGammaRamp) Then result := false;
+ SDL_GetPowerInfo := TSDL_GetPowerInfo_func(GetProcAddress(LibHandle, 'SDL_GetPowerInfo'));
+ If Not assigned(SDL_GetPowerInfo) Then result := false;
+ SDL_HasIntersection := TSDL_HasIntersection_func(GetProcAddress(LibHandle, 'SDL_HasIntersection'));
+ If Not assigned(SDL_HasIntersection) Then result := false;
+ SDL_IntersectRect := TSDL_IntersectRect_func(GetProcAddress(LibHandle, 'SDL_IntersectRect'));
+ If Not assigned(SDL_IntersectRect) Then result := false;
+ SDL_UnionRect := TSDL_UnionRect_proc(GetProcAddress(LibHandle, 'SDL_UnionRect'));
+ If Not assigned(SDL_UnionRect) Then result := false;
+ SDL_EnclosePoints := TSDL_EnclosePoints_func(GetProcAddress(LibHandle, 'SDL_EnclosePoints'));
+ If Not assigned(SDL_EnclosePoints) Then result := false;
+ SDL_IntersectRectAndLine := TSDL_IntersectRectAndLine_func(GetProcAddress(LibHandle, 'SDL_IntersectRectAndLine'));
+ If Not assigned(SDL_IntersectRectAndLine) Then result := false;
+ SDL_HasIntersectionF := TSDL_HasIntersectionF_func(GetProcAddress(LibHandle, 'SDL_HasIntersectionF'));
+ If Not assigned(SDL_HasIntersectionF) Then result := false;
+ SDL_IntersectFRect := TSDL_IntersectFRect_func(GetProcAddress(LibHandle, 'SDL_IntersectFRect'));
+ If Not assigned(SDL_IntersectFRect) Then result := false;
+ SDL_UnionFRect := TSDL_UnionFRect_func(GetProcAddress(LibHandle, 'SDL_UnionFRect'));
+ If Not assigned(SDL_UnionFRect) Then result := false;
+ SDL_EncloseFPoints := TSDL_EncloseFPoints_func(GetProcAddress(LibHandle, 'SDL_EncloseFPoints'));
+ If Not assigned(SDL_EncloseFPoints) Then result := false;
+ SDL_IntersectFRectAndLine := TSDL_IntersectFRectAndLine_func(GetProcAddress(LibHandle, 'SDL_IntersectFRectAndLine'));
+ If Not assigned(SDL_IntersectFRectAndLine) Then result := false;
+ SDL_LockTexture := TSDL_LockTexture_func(GetProcAddress(LibHandle, 'SDL_LockTexture'));
+ If Not assigned(SDL_LockTexture) Then result := false;
+ SDL_LockTextureToSurface := TSDL_LockTextureToSurface_func(GetProcAddress(LibHandle, 'SDL_LockTextureToSurface'));
+ If Not assigned(SDL_LockTextureToSurface) Then result := false;
+ SDL_RenderIsClipEnabled := TSDL_RenderIsClipEnabled_func(GetProcAddress(LibHandle, 'SDL_RenderIsClipEnabled'));
+ If Not assigned(SDL_RenderIsClipEnabled) Then result := false;
+ SDL_RenderDrawPointF := TSDL_RenderDrawPointF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawPointF'));
+ If Not assigned(SDL_RenderDrawPointF) Then result := false;
+ SDL_RenderDrawPointsF := TSDL_RenderDrawPointsF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawPointsF'));
+ If Not assigned(SDL_RenderDrawPointsF) Then result := false;
+ SDL_RenderDrawLineF := TSDL_RenderDrawLineF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawLineF'));
+ If Not assigned(SDL_RenderDrawLineF) Then result := false;
+ SDL_RenderDrawLinesF := TSDL_RenderDrawLinesF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawLinesF'));
+ If Not assigned(SDL_RenderDrawLinesF) Then result := false;
+ SDL_RenderDrawRectF := TSDL_RenderDrawRectF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawRectF'));
+ If Not assigned(SDL_RenderDrawRectF) Then result := false;
+ SDL_RenderDrawRectsF := TSDL_RenderDrawRectsF_func(GetProcAddress(LibHandle, 'SDL_RenderDrawRectsF'));
+ If Not assigned(SDL_RenderDrawRectsF) Then result := false;
+ SDL_RenderFillRectF := TSDL_RenderFillRectF_func(GetProcAddress(LibHandle, 'SDL_RenderFillRectF'));
+ If Not assigned(SDL_RenderFillRectF) Then result := false;
+ SDL_RenderFillRectsF := TSDL_RenderFillRectsF_func(GetProcAddress(LibHandle, 'SDL_RenderFillRectsF'));
+ If Not assigned(SDL_RenderFillRectsF) Then result := false;
+ SDL_RenderCopyF := TSDL_RenderCopyF_func(GetProcAddress(LibHandle, 'SDL_RenderCopyF'));
+ If Not assigned(SDL_RenderCopyF) Then result := false;
+ SDL_RenderCopyExF := TSDL_RenderCopyExF_func(GetProcAddress(LibHandle, 'SDL_RenderCopyExF'));
+ If Not assigned(SDL_RenderCopyExF) Then result := false;
+ SDL_RenderGetMetalLayer := TSDL_RenderGetMetalLayer_func(GetProcAddress(LibHandle, 'SDL_RenderGetMetalLayer'));
+ If Not assigned(SDL_RenderGetMetalLayer) Then result := false;
+ SDL_RenderGetMetalCommandEncoder := TSDL_RenderGetMetalCommandEncoder_func(GetProcAddress(LibHandle, 'SDL_RenderGetMetalCommandEncoder'));
+ If Not assigned(SDL_RenderGetMetalCommandEncoder) Then result := false;
+ SDL_UpdateYUVTexture := TSDL_UpdateYUVTexture_func(GetProcAddress(LibHandle, 'SDL_UpdateYUVTexture'));
+ If Not assigned(SDL_UpdateYUVTexture) Then result := false;
+ SDL_RWFromFile := TSDL_RWFromFile_func(GetProcAddress(LibHandle, 'SDL_RWFromFile'));
+ If Not assigned(SDL_RWFromFile) Then result := false;
+ SDL_RWFromFP := TSDL_RWFromFP_func(GetProcAddress(LibHandle, 'SDL_RWFromFP'));
+ If Not assigned(SDL_RWFromFP) Then result := false;
+ SDL_RWFromMem := TSDL_RWFromMem_func(GetProcAddress(LibHandle, 'SDL_RWFromMem'));
+ If Not assigned(SDL_RWFromMem) Then result := false;
+ SDL_RWFromConstMem := TSDL_RWFromConstMem_func(GetProcAddress(LibHandle, 'SDL_RWFromConstMem'));
+ If Not assigned(SDL_RWFromConstMem) Then result := false;
+ SDL_FreeRW := TSDL_FreeRW_proc(GetProcAddress(LibHandle, 'SDL_FreeRW'));
+ If Not assigned(SDL_FreeRW) Then result := false;
+ SDL_RWsize := TSDL_RWsize_func(GetProcAddress(LibHandle, 'SDL_RWsize'));
+ If Not assigned(SDL_RWsize) Then result := false;
+ SDL_RWseek := TSDL_RWseek_func(GetProcAddress(LibHandle, 'SDL_RWseek'));
+ If Not assigned(SDL_RWseek) Then result := false;
+ SDL_RWtell := TSDL_RWtell_func(GetProcAddress(LibHandle, 'SDL_RWtell'));
+ If Not assigned(SDL_RWtell) Then result := false;
+ SDL_RWread := TSDL_RWread_func(GetProcAddress(LibHandle, 'SDL_RWread'));
+ If Not assigned(SDL_RWread) Then result := false;
+ SDL_RWwrite := TSDL_RWwrite_func(GetProcAddress(LibHandle, 'SDL_RWwrite'));
+ If Not assigned(SDL_RWwrite) Then result := false;
+ SDL_RWclose := TSDL_RWclose_func(GetProcAddress(LibHandle, 'SDL_RWclose'));
+ If Not assigned(SDL_RWclose) Then result := false;
+ SDL_LoadFile_RW := TSDL_LoadFile_RW_func(GetProcAddress(LibHandle, 'SDL_LoadFile_RW'));
+ If Not assigned(SDL_LoadFile_RW) Then result := false;
+ SDL_LoadFile := TSDL_LoadFile_func(GetProcAddress(LibHandle, 'SDL_LoadFile'));
+ If Not assigned(SDL_LoadFile) Then result := false;
+ SDL_ReadU8 := TSDL_ReadU8_func(GetProcAddress(LibHandle, 'SDL_ReadU8'));
+ If Not assigned(SDL_ReadU8) Then result := false;
+ SDL_ReadLE16 := TSDL_ReadLE16_func(GetProcAddress(LibHandle, 'SDL_ReadLE16'));
+ If Not assigned(SDL_ReadLE16) Then result := false;
+ SDL_ReadBE16 := TSDL_ReadBE16_func(GetProcAddress(LibHandle, 'SDL_ReadBE16'));
+ If Not assigned(SDL_ReadBE16) Then result := false;
+ SDL_ReadLE32 := TSDL_ReadLE32_func(GetProcAddress(LibHandle, 'SDL_ReadLE32'));
+ If Not assigned(SDL_ReadLE32) Then result := false;
+ SDL_ReadBE32 := TSDL_ReadBE32_func(GetProcAddress(LibHandle, 'SDL_ReadBE32'));
+ If Not assigned(SDL_ReadBE32) Then result := false;
+ SDL_ReadLE64 := TSDL_ReadLE64_func(GetProcAddress(LibHandle, 'SDL_ReadLE64'));
+ If Not assigned(SDL_ReadLE64) Then result := false;
+ SDL_ReadBE64 := TSDL_ReadBE64_func(GetProcAddress(LibHandle, 'SDL_ReadBE64'));
+ If Not assigned(SDL_ReadBE64) Then result := false;
+ SDL_WriteU8 := TSDL_WriteU8_func(GetProcAddress(LibHandle, 'SDL_WriteU8'));
+ If Not assigned(SDL_WriteU8) Then result := false;
+ SDL_WriteLE16 := TSDL_WriteLE16_func(GetProcAddress(LibHandle, 'SDL_WriteLE16'));
+ If Not assigned(SDL_WriteLE16) Then result := false;
+ SDL_WriteBE16 := TSDL_WriteBE16_func(GetProcAddress(LibHandle, 'SDL_WriteBE16'));
+ If Not assigned(SDL_WriteBE16) Then result := false;
+ SDL_WriteLE32 := TSDL_WriteLE32_func(GetProcAddress(LibHandle, 'SDL_WriteLE32'));
+ If Not assigned(SDL_WriteLE32) Then result := false;
+ SDL_WriteBE32 := TSDL_WriteBE32_func(GetProcAddress(LibHandle, 'SDL_WriteBE32'));
+ If Not assigned(SDL_WriteBE32) Then result := false;
+ SDL_WriteLE64 := TSDL_WriteLE64_func(GetProcAddress(LibHandle, 'SDL_WriteLE64'));
+ If Not assigned(SDL_WriteLE64) Then result := false;
+ SDL_WriteBE64 := TSDL_WriteBE64_func(GetProcAddress(LibHandle, 'SDL_WriteBE64'));
+ If Not assigned(SDL_WriteBE64) Then result := false;
+ SDL_CreateShapedWindow := TSDL_CreateShapedWindow_func(GetProcAddress(LibHandle, 'SDL_CreateShapedWindow'));
+ If Not assigned(SDL_CreateShapedWindow) Then result := false;
+ SDL_IsShapedWindow := TSDL_IsShapedWindow_func(GetProcAddress(LibHandle, 'SDL_IsShapedWindow'));
+ If Not assigned(SDL_IsShapedWindow) Then result := false;
+ SDL_SetWindowShape := TSDL_SetWindowShape_func(GetProcAddress(LibHandle, 'SDL_SetWindowShape'));
+ If Not assigned(SDL_SetWindowShape) Then result := false;
+ SDL_GetShapedWindowMode := TSDL_GetShapedWindowMode_func(GetProcAddress(LibHandle, 'SDL_GetShapedWindowMode'));
+ If Not assigned(SDL_GetShapedWindowMode) Then result := false;
+ SDL_GetNumAllocations := TSDL_GetNumAllocations_func(GetProcAddress(LibHandle, 'SDL_GetNumAllocations'));
+ If Not assigned(SDL_GetNumAllocations) Then result := false;
+ SDL_malloc := TSDL_malloc_func(GetProcAddress(LibHandle, 'SDL_malloc'));
+ If Not assigned(SDL_malloc) Then result := false;
+ SDL_calloc := TSDL_calloc_func(GetProcAddress(LibHandle, 'SDL_calloc'));
+ If Not assigned(SDL_calloc) Then result := false;
+ SDL_realloc := TSDL_realloc_func(GetProcAddress(LibHandle, 'SDL_realloc'));
+ If Not assigned(SDL_realloc) Then result := false;
+ SDL_free := TSDL_free_proc(GetProcAddress(LibHandle, 'SDL_free'));
+ If Not assigned(SDL_free) Then result := false;
+ SDL_isalpha := TSDL_isalpha_func(GetProcAddress(LibHandle, 'SDL_isalpha'));
+ If Not assigned(SDL_isalpha) Then result := false;
+ SDL_isalnum := TSDL_isalnum_func(GetProcAddress(LibHandle, 'SDL_isalnum'));
+ If Not assigned(SDL_isalnum) Then result := false;
+ SDL_isblank := TSDL_isblank_func(GetProcAddress(LibHandle, 'SDL_isblank'));
+ If Not assigned(SDL_isblank) Then result := false;
+ SDL_iscntrl := TSDL_iscntrl_func(GetProcAddress(LibHandle, 'SDL_iscntrl'));
+ If Not assigned(SDL_iscntrl) Then result := false;
+ SDL_isdigit := TSDL_isdigit_func(GetProcAddress(LibHandle, 'SDL_isdigit'));
+ If Not assigned(SDL_isdigit) Then result := false;
+ SDL_isxdigit := TSDL_isxdigit_func(GetProcAddress(LibHandle, 'SDL_isxdigit'));
+ If Not assigned(SDL_isxdigit) Then result := false;
+ SDL_ispunct := TSDL_ispunct_func(GetProcAddress(LibHandle, 'SDL_ispunct'));
+ If Not assigned(SDL_ispunct) Then result := false;
+ SDL_isspace := TSDL_isspace_func(GetProcAddress(LibHandle, 'SDL_isspace'));
+ If Not assigned(SDL_isspace) Then result := false;
+ SDL_isupper := TSDL_isupper_func(GetProcAddress(LibHandle, 'SDL_isupper'));
+ If Not assigned(SDL_isupper) Then result := false;
+ SDL_islower := TSDL_islower_func(GetProcAddress(LibHandle, 'SDL_islower'));
+ If Not assigned(SDL_islower) Then result := false;
+ SDL_isprint := TSDL_isprint_func(GetProcAddress(LibHandle, 'SDL_isprint'));
+ If Not assigned(SDL_isprint) Then result := false;
+ SDL_isgraph := TSDL_isgraph_func(GetProcAddress(LibHandle, 'SDL_isgraph'));
+ If Not assigned(SDL_isgraph) Then result := false;
+ SDL_toupper := TSDL_toupper_func(GetProcAddress(LibHandle, 'SDL_toupper'));
+ If Not assigned(SDL_toupper) Then result := false;
+ SDL_tolower := TSDL_tolower_func(GetProcAddress(LibHandle, 'SDL_tolower'));
+ If Not assigned(SDL_tolower) Then result := false;
+ SDL_acos := TSDL_acos_func(GetProcAddress(LibHandle, 'SDL_acos'));
+ If Not assigned(SDL_acos) Then result := false;
+ SDL_acosf := TSDL_acosf_func(GetProcAddress(LibHandle, 'SDL_acosf'));
+ If Not assigned(SDL_acosf) Then result := false;
+ SDL_asin := TSDL_asin_func(GetProcAddress(LibHandle, 'SDL_asin'));
+ If Not assigned(SDL_asin) Then result := false;
+ SDL_asinf := TSDL_asinf_func(GetProcAddress(LibHandle, 'SDL_asinf'));
+ If Not assigned(SDL_asinf) Then result := false;
+ SDL_atan := TSDL_atan_func(GetProcAddress(LibHandle, 'SDL_atan'));
+ If Not assigned(SDL_atan) Then result := false;
+ SDL_atanf := TSDL_atanf_func(GetProcAddress(LibHandle, 'SDL_atanf'));
+ If Not assigned(SDL_atanf) Then result := false;
+ SDL_atan2 := TSDL_atan2_func(GetProcAddress(LibHandle, 'SDL_atan2'));
+ If Not assigned(SDL_atan2) Then result := false;
+ SDL_atan2f := TSDL_atan2f_func(GetProcAddress(LibHandle, 'SDL_atan2f'));
+ If Not assigned(SDL_atan2f) Then result := false;
+ SDL_ceil := TSDL_ceil_func(GetProcAddress(LibHandle, 'SDL_ceil'));
+ If Not assigned(SDL_ceil) Then result := false;
+ SDL_ceilf := TSDL_ceilf_func(GetProcAddress(LibHandle, 'SDL_ceilf'));
+ If Not assigned(SDL_ceilf) Then result := false;
+ SDL_copysign := TSDL_copysign_func(GetProcAddress(LibHandle, 'SDL_copysign'));
+ If Not assigned(SDL_copysign) Then result := false;
+ SDL_copysignf := TSDL_copysignf_func(GetProcAddress(LibHandle, 'SDL_copysignf'));
+ If Not assigned(SDL_copysignf) Then result := false;
+ SDL_cos := TSDL_cos_func(GetProcAddress(LibHandle, 'SDL_cos'));
+ If Not assigned(SDL_cos) Then result := false;
+ SDL_cosf := TSDL_cosf_func(GetProcAddress(LibHandle, 'SDL_cosf'));
+ If Not assigned(SDL_cosf) Then result := false;
+ SDL_exp := TSDL_exp_func(GetProcAddress(LibHandle, 'SDL_exp'));
+ If Not assigned(SDL_exp) Then result := false;
+ SDL_expf := TSDL_expf_func(GetProcAddress(LibHandle, 'SDL_expf'));
+ If Not assigned(SDL_expf) Then result := false;
+ SDL_fabs := TSDL_fabs_func(GetProcAddress(LibHandle, 'SDL_fabs'));
+ If Not assigned(SDL_fabs) Then result := false;
+ SDL_fabsf := TSDL_fabsf_func(GetProcAddress(LibHandle, 'SDL_fabsf'));
+ If Not assigned(SDL_fabsf) Then result := false;
+ SDL_floor := TSDL_floor_func(GetProcAddress(LibHandle, 'SDL_floor'));
+ If Not assigned(SDL_floor) Then result := false;
+ SDL_floorf := TSDL_floorf_func(GetProcAddress(LibHandle, 'SDL_floorf'));
+ If Not assigned(SDL_floorf) Then result := false;
+ SDL_fmod := TSDL_fmod_func(GetProcAddress(LibHandle, 'SDL_fmod'));
+ If Not assigned(SDL_fmod) Then result := false;
+ SDL_fmodf := TSDL_fmodf_func(GetProcAddress(LibHandle, 'SDL_fmodf'));
+ If Not assigned(SDL_fmodf) Then result := false;
+ SDL_nlog := TSDL_nlog_func(GetProcAddress(LibHandle, 'SDL_nlog'));
+ If Not assigned(SDL_nlog) Then result := false;
+ SDL_nlogf := TSDL_nlogf_func(GetProcAddress(LibHandle, 'SDL_nlogf'));
+ If Not assigned(SDL_nlogf) Then result := false;
+ SDL_log10 := TSDL_log10_func(GetProcAddress(LibHandle, 'SDL_log10'));
+ If Not assigned(SDL_log10) Then result := false;
+ SDL_log10f := TSDL_log10f_func(GetProcAddress(LibHandle, 'SDL_log10f'));
+ If Not assigned(SDL_log10f) Then result := false;
+ SDL_lround := TSDL_lround_func(GetProcAddress(LibHandle, 'SDL_lround'));
+ If Not assigned(SDL_lround) Then result := false;
+ SDL_lroundf := TSDL_lroundf_func(GetProcAddress(LibHandle, 'SDL_lroundf'));
+ If Not assigned(SDL_lroundf) Then result := false;
+ SDL_pow := TSDL_pow_func(GetProcAddress(LibHandle, 'SDL_pow'));
+ If Not assigned(SDL_pow) Then result := false;
+ SDL_powf := TSDL_powf_func(GetProcAddress(LibHandle, 'SDL_powf'));
+ If Not assigned(SDL_powf) Then result := false;
+ SDL_round := TSDL_round_func(GetProcAddress(LibHandle, 'SDL_round'));
+ If Not assigned(SDL_round) Then result := false;
+ SDL_roundf := TSDL_roundf_func(GetProcAddress(LibHandle, 'SDL_roundf'));
+ If Not assigned(SDL_roundf) Then result := false;
+ SDL_scalbn := TSDL_scalbn_func(GetProcAddress(LibHandle, 'SDL_scalbn'));
+ If Not assigned(SDL_scalbn) Then result := false;
+ SDL_scalbnf := TSDL_scalbnf_func(GetProcAddress(LibHandle, 'SDL_scalbnf'));
+ If Not assigned(SDL_scalbnf) Then result := false;
+ SDL_sin := TSDL_sin_func(GetProcAddress(LibHandle, 'SDL_sin'));
+ If Not assigned(SDL_sin) Then result := false;
+ SDL_sinf := TSDL_sinf_func(GetProcAddress(LibHandle, 'SDL_sinf'));
+ If Not assigned(SDL_sinf) Then result := false;
+ SDL_sqrt := TSDL_sqrt_func(GetProcAddress(LibHandle, 'SDL_sqrt'));
+ If Not assigned(SDL_sqrt) Then result := false;
+ SDL_sqrtf := TSDL_sqrtf_func(GetProcAddress(LibHandle, 'SDL_sqrtf'));
+ If Not assigned(SDL_sqrtf) Then result := false;
+ SDL_tan := TSDL_tan_func(GetProcAddress(LibHandle, 'SDL_tan'));
+ If Not assigned(SDL_tan) Then result := false;
+ SDL_tanf := TSDL_tanf_func(GetProcAddress(LibHandle, 'SDL_tanf'));
+ If Not assigned(SDL_tanf) Then result := false;
+ SDL_trunc := TSDL_trunc_func(GetProcAddress(LibHandle, 'SDL_trunc'));
+ If Not assigned(SDL_trunc) Then result := false;
+ SDL_truncf := TSDL_truncf_func(GetProcAddress(LibHandle, 'SDL_truncf'));
+ If Not assigned(SDL_truncf) Then result := false;
+ SDL_iconv_string := TSDL_iconv_string_func(GetProcAddress(LibHandle, 'SDL_iconv_string'));
+ If Not assigned(SDL_iconv_string) Then result := false;
+ SDL_iconv_open := TSDL_iconv_open_func(GetProcAddress(LibHandle, 'SDL_iconv_open'));
+ If Not assigned(SDL_iconv_open) Then result := false;
+ SDL_iconv_close := TSDL_iconv_close_func(GetProcAddress(LibHandle, 'SDL_iconv_close'));
+ If Not assigned(SDL_iconv_close) Then result := false;
+ SDL_iconv := TSDL_iconv_func(GetProcAddress(LibHandle, 'SDL_iconv'));
+ If Not assigned(SDL_iconv) Then result := false;
+ SDL_CreateRGBSurface := TSDL_CreateRGBSurface_func(GetProcAddress(LibHandle, 'SDL_CreateRGBSurface'));
+ If Not assigned(SDL_CreateRGBSurface) Then result := false;
+ SDL_CreateRGBSurfaceWithFormat := TSDL_CreateRGBSurfaceWithFormat_func(GetProcAddress(LibHandle, 'SDL_CreateRGBSurfaceWithFormat'));
+ If Not assigned(SDL_CreateRGBSurfaceWithFormat) Then result := false;
+ SDL_CreateRGBSurfaceFrom := TSDL_CreateRGBSurfaceFrom_func(GetProcAddress(LibHandle, 'SDL_CreateRGBSurfaceFrom'));
+ If Not assigned(SDL_CreateRGBSurfaceFrom) Then result := false;
+ SDL_CreateRGBSurfaceWithFormatFrom := TSDL_CreateRGBSurfaceWithFormatFrom_func(GetProcAddress(LibHandle, 'SDL_CreateRGBSurfaceWithFormatFrom'));
+ If Not assigned(SDL_CreateRGBSurfaceWithFormatFrom) Then result := false;
+ SDL_FreeSurface := TSDL_FreeSurface_proc(GetProcAddress(LibHandle, 'SDL_FreeSurface'));
+ If Not assigned(SDL_FreeSurface) Then result := false;
+ SDL_SetSurfacePalette := TSDL_SetSurfacePalette_func(GetProcAddress(LibHandle, 'SDL_SetSurfacePalette'));
+ If Not assigned(SDL_SetSurfacePalette) Then result := false;
+ SDL_LockSurface := TSDL_LockSurface_func(GetProcAddress(LibHandle, 'SDL_LockSurface'));
+ If Not assigned(SDL_LockSurface) Then result := false;
+ SDL_UnlockSurface := TSDL_UnlockSurface_proc(GetProcAddress(LibHandle, 'SDL_UnlockSurface'));
+ If Not assigned(SDL_UnlockSurface) Then result := false;
+ SDL_LoadBMP_RW := TSDL_LoadBMP_RW_func(GetProcAddress(LibHandle, 'SDL_LoadBMP_RW'));
+ If Not assigned(SDL_LoadBMP_RW) Then result := false;
+ SDL_SaveBMP_RW := TSDL_SaveBMP_RW_func(GetProcAddress(LibHandle, 'SDL_SaveBMP_RW'));
+ If Not assigned(SDL_SaveBMP_RW) Then result := false;
+ SDL_SetSurfaceRLE := TSDL_SetSurfaceRLE_func(GetProcAddress(LibHandle, 'SDL_SetSurfaceRLE'));
+ If Not assigned(SDL_SetSurfaceRLE) Then result := false;
+ SDL_HasSurfaceRLE := TSDL_HasSurfaceRLE_func(GetProcAddress(LibHandle, 'SDL_HasSurfaceRLE'));
+ If Not assigned(SDL_HasSurfaceRLE) Then result := false;
+ SDL_SetColorKey := TSDL_SetColorKey_func(GetProcAddress(LibHandle, 'SDL_SetColorKey'));
+ If Not assigned(SDL_SetColorKey) Then result := false;
+ SDL_HasColorKey := TSDL_HasColorKey_func(GetProcAddress(LibHandle, 'SDL_HasColorKey'));
+ If Not assigned(SDL_HasColorKey) Then result := false;
+ SDL_GetColorKey := TSDL_GetColorKey_func(GetProcAddress(LibHandle, 'SDL_GetColorKey'));
+ If Not assigned(SDL_GetColorKey) Then result := false;
+ SDL_SetSurfaceColorMod := TSDL_SetSurfaceColorMod_func(GetProcAddress(LibHandle, 'SDL_SetSurfaceColorMod'));
+ If Not assigned(SDL_SetSurfaceColorMod) Then result := false;
+ SDL_GetSurfaceColorMod := TSDL_GetSurfaceColorMod_func(GetProcAddress(LibHandle, 'SDL_GetSurfaceColorMod'));
+ If Not assigned(SDL_GetSurfaceColorMod) Then result := false;
+ SDL_SetSurfaceAlphaMod := TSDL_SetSurfaceAlphaMod_func(GetProcAddress(LibHandle, 'SDL_SetSurfaceAlphaMod'));
+ If Not assigned(SDL_SetSurfaceAlphaMod) Then result := false;
+ SDL_GetSurfaceAlphaMod := TSDL_GetSurfaceAlphaMod_func(GetProcAddress(LibHandle, 'SDL_GetSurfaceAlphaMod'));
+ If Not assigned(SDL_GetSurfaceAlphaMod) Then result := false;
+ SDL_SetSurfaceBlendMode := TSDL_SetSurfaceBlendMode_func(GetProcAddress(LibHandle, 'SDL_SetSurfaceBlendMode'));
+ If Not assigned(SDL_SetSurfaceBlendMode) Then result := false;
+ SDL_GetSurfaceBlendMode := TSDL_GetSurfaceBlendMode_func(GetProcAddress(LibHandle, 'SDL_GetSurfaceBlendMode'));
+ If Not assigned(SDL_GetSurfaceBlendMode) Then result := false;
+ SDL_SetClipRect := TSDL_SetClipRect_func(GetProcAddress(LibHandle, 'SDL_SetClipRect'));
+ If Not assigned(SDL_SetClipRect) Then result := false;
+ SDL_GetClipRect := TSDL_GetClipRect_proc(GetProcAddress(LibHandle, 'SDL_GetClipRect'));
+ If Not assigned(SDL_GetClipRect) Then result := false;
+ SDL_DuplicateSurface := TSDL_DuplicateSurface_func(GetProcAddress(LibHandle, 'SDL_DuplicateSurface'));
+ If Not assigned(SDL_DuplicateSurface) Then result := false;
+ SDL_ConvertSurface := TSDL_ConvertSurface_func(GetProcAddress(LibHandle, 'SDL_ConvertSurface'));
+ If Not assigned(SDL_ConvertSurface) Then result := false;
+ SDL_ConvertSurfaceFormat := TSDL_ConvertSurfaceFormat_func(GetProcAddress(LibHandle, 'SDL_ConvertSurfaceFormat'));
+ If Not assigned(SDL_ConvertSurfaceFormat) Then result := false;
+ SDL_ConvertPixels := TSDL_ConvertPixels_func(GetProcAddress(LibHandle, 'SDL_ConvertPixels'));
+ If Not assigned(SDL_ConvertPixels) Then result := false;
+ SDL_FillRect := TSDL_FillRect_func(GetProcAddress(LibHandle, 'SDL_FillRect'));
+ If Not assigned(SDL_FillRect) Then result := false;
+ SDL_FillRects := TSDL_FillRects_func(GetProcAddress(LibHandle, 'SDL_FillRects'));
+ If Not assigned(SDL_FillRects) Then result := false;
+ SDL_BlitSurface := TSDL_BlitSurface_func(GetProcAddress(LibHandle, 'SDL_BlitSurface'));
+ If Not assigned(SDL_BlitSurface) Then result := false;
+ SDL_UpperBlit := TSDL_UpperBlit_func(GetProcAddress(LibHandle, 'SDL_UpperBlit'));
+ If Not assigned(SDL_UpperBlit) Then result := false;
+ SDL_LowerBlit := TSDL_LowerBlit_func(GetProcAddress(LibHandle, 'SDL_LowerBlit'));
+ If Not assigned(SDL_LowerBlit) Then result := false;
+ SDL_SoftStretch := TSDL_SoftStretch_func(GetProcAddress(LibHandle, 'SDL_SoftStretch'));
+ If Not assigned(SDL_SoftStretch) Then result := false;
+ SDL_BlitSurfaceScaled := TSDL_BlitSurfaceScaled_func(GetProcAddress(LibHandle, 'SDL_BlitSurfaceScaled'));
+ If Not assigned(SDL_BlitSurfaceScaled) Then result := false;
+ SDL_UpperBlitScaled := TSDL_UpperBlitScaled_func(GetProcAddress(LibHandle, 'SDL_UpperBlitScaled'));
+ If Not assigned(SDL_UpperBlitScaled) Then result := false;
+ SDL_LowerBlitScaled := TSDL_LowerBlitScaled_func(GetProcAddress(LibHandle, 'SDL_LowerBlitScaled'));
+ If Not assigned(SDL_LowerBlitScaled) Then result := false;
+ SDL_SetYUVConversionMode := TSDL_SetYUVConversionMode_proc(GetProcAddress(LibHandle, 'SDL_SetYUVConversionMode'));
+ If Not assigned(SDL_SetYUVConversionMode) Then result := false;
+ SDL_GetYUVConversionModeForResolution := TSDL_GetYUVConversionModeForResolution_func(GetProcAddress(LibHandle, 'SDL_GetYUVConversionModeForResolution'));
+ If Not assigned(SDL_GetYUVConversionModeForResolution) Then result := false;
+ SDL_SetWindowsMessageHook := TSDL_SetWindowsMessageHook_proc(GetProcAddress(LibHandle, 'SDL_SetWindowsMessageHook'));
+ If Not assigned(SDL_SetWindowsMessageHook) Then result := false;
+ SDL_Direct3D9GetAdapterIndex := TSDL_Direct3D9GetAdapterIndex_func(GetProcAddress(LibHandle, 'SDL_Direct3D9GetAdapterIndex'));
+ If Not assigned(SDL_Direct3D9GetAdapterIndex) Then result := false;
+ SDL_RenderGetD3D9Device := TSDL_RenderGetD3D9Device_func(GetProcAddress(LibHandle, 'SDL_RenderGetD3D9Device'));
+ If Not assigned(SDL_RenderGetD3D9Device) Then result := false;
+ SDL_RenderGetD3D11Device := TSDL_RenderGetD3D11Device_func(GetProcAddress(LibHandle, 'SDL_RenderGetD3D11Device'));
+ If Not assigned(SDL_RenderGetD3D11Device) Then result := false;
+ SDL_RenderGetD3D12Device := TSDL_RenderGetD3D12Device_func(GetProcAddress(LibHandle, 'SDL_RenderGetD3D12Device'));
+ If Not assigned(SDL_RenderGetD3D12Device) Then result := false;
+ SDL_DXGIGetOutputInfo := TSDL_DXGIGetOutputInfo_func(GetProcAddress(LibHandle, 'SDL_DXGIGetOutputInfo'));
+ If Not assigned(SDL_DXGIGetOutputInfo) Then result := false; //*)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+{$IFDEF LINUX}
+ SDL_LinuxSetThreadPriority := TSDL_LinuxSetThreadPriority_func(GetProcAddress(LibHandle, 'SDL_LinuxSetThreadPriority'));
+ If Not assigned(SDL_LinuxSetThreadPriority) Then result := false;
+ SDL_LinuxSetThreadPriorityAndPolicy := TSDL_LinuxSetThreadPriorityAndPolicy_func(GetProcAddress(LibHandle, 'SDL_LinuxSetThreadPriorityAndPolicy'));
+ If Not assigned(SDL_LinuxSetThreadPriorityAndPolicy) Then result := false;
+{$IFDEF Windows}
+ SDL_iPhoneSetAnimationCallback := TSDL_iPhoneSetAnimationCallback_func(GetProcAddress(LibHandle, 'SDL_iPhoneSetAnimationCallback'));
+ If Not assigned(SDL_iPhoneSetAnimationCallback) Then result := false;
+ SDL_iPhoneSetEventPump := TSDL_iPhoneSetEventPump_proc(GetProcAddress(LibHandle, 'SDL_iPhoneSetEventPump'));
+ If Not assigned(SDL_iPhoneSetEventPump) Then result := false;
+ SDL_AndroidGetJNIEnv := TSDL_AndroidGetJNIEnv_func(GetProcAddress(LibHandle, 'SDL_AndroidGetJNIEnv'));
+ If Not assigned(SDL_AndroidGetJNIEnv) Then result := false;
+ SDL_AndroidGetActivity := TSDL_AndroidGetActivity_func(GetProcAddress(LibHandle, 'SDL_AndroidGetActivity'));
+ If Not assigned(SDL_AndroidGetActivity) Then result := false;
+ SDL_GetAndroidSDKVersion := TSDL_GetAndroidSDKVersion_func(GetProcAddress(LibHandle, 'SDL_GetAndroidSDKVersion'));
+ If Not assigned(SDL_GetAndroidSDKVersion) Then result := false;
+ SDL_IsAndroidTV := TSDL_IsAndroidTV_func(GetProcAddress(LibHandle, 'SDL_IsAndroidTV'));
+ If Not assigned(SDL_IsAndroidTV) Then result := false;
+ SDL_IsChromebook := TSDL_IsChromebook_func(GetProcAddress(LibHandle, 'SDL_IsChromebook'));
+ If Not assigned(SDL_IsChromebook) Then result := false;
+ SDL_IsDeXMode := TSDL_IsDeXMode_func(GetProcAddress(LibHandle, 'SDL_IsDeXMode'));
+ If Not assigned(SDL_IsDeXMode) Then result := false;
+ SDL_AndroidBackButton := TSDL_AndroidBackButton_proc(GetProcAddress(LibHandle, 'SDL_AndroidBackButton'));
+ If Not assigned(SDL_AndroidBackButton) Then result := false;
+ SDL_AndroidGetInternalStoragePath := TSDL_AndroidGetInternalStoragePath_func(GetProcAddress(LibHandle, 'SDL_AndroidGetInternalStoragePath'));
+ If Not assigned(SDL_AndroidGetInternalStoragePath) Then result := false;
+ SDL_AndroidGetExternalStorageState := TSDL_AndroidGetExternalStorageState_func(GetProcAddress(LibHandle, 'SDL_AndroidGetExternalStorageState'));
+ If Not assigned(SDL_AndroidGetExternalStorageState) Then result := false;
+ SDL_AndroidGetExternalStoragePath := TSDL_AndroidGetExternalStoragePath_func(GetProcAddress(LibHandle, 'SDL_AndroidGetExternalStoragePath'));
+ If Not assigned(SDL_AndroidGetExternalStoragePath) Then result := false;
+ SDL_AndroidRequestPermission := TSDL_AndroidRequestPermission_func(GetProcAddress(LibHandle, 'SDL_AndroidRequestPermission'));
+ If Not assigned(SDL_AndroidRequestPermission) Then result := false;
+ SDL_AndroidShowToast := TSDL_AndroidShowToast_func(GetProcAddress(LibHandle, 'SDL_AndroidShowToast'));
+ If Not assigned(SDL_AndroidShowToast) Then result := false;
+ SDL_AndroidSendMessage := TSDL_AndroidSendMessage_func(GetProcAddress(LibHandle, 'SDL_AndroidSendMessage'));
+ If Not assigned(SDL_AndroidSendMessage) Then result := false;
+ SDL_WinRTGetFSPathUNICODE := TSDL_WinRTGetFSPathUNICODE_func(GetProcAddress(LibHandle, 'SDL_WinRTGetFSPathUNICODE'));
+ If Not assigned(SDL_WinRTGetFSPathUNICODE) Then result := false;
+ SDL_WinRTGetFSPathUTF8 := TSDL_WinRTGetFSPathUTF8_func(GetProcAddress(LibHandle, 'SDL_WinRTGetFSPathUTF8'));
+ If Not assigned(SDL_WinRTGetFSPathUTF8) Then result := false;
+ SDL_WinRTGetDeviceFamily := TSDL_WinRTGetDeviceFamily_func(GetProcAddress(LibHandle, 'SDL_WinRTGetDeviceFamily'));
+ If Not assigned(SDL_WinRTGetDeviceFamily) Then result := false;
+{$ENDIF}
+{$ENDIF}
+ SDL_IsTablet := TSDL_IsTablet_func(GetProcAddress(LibHandle, 'SDL_IsTablet'));
+ If Not assigned(SDL_IsTablet) Then result := false;
+ SDL_PumpEvents := TSDL_PumpEvents_proc(GetProcAddress(LibHandle, 'SDL_PumpEvents'));
+ If Not assigned(SDL_PumpEvents) Then result := false;
+ SDL_PollEvent := TSDL_PollEvent_func(GetProcAddress(LibHandle, 'SDL_PollEvent'));
+ If Not assigned(SDL_PollEvent) Then result := false;
+ SDL_EventState := TSDL_EventState_func(GetProcAddress(LibHandle, 'SDL_EventState'));
+ If Not assigned(SDL_EventState) Then result := false;
+ SDL_GetWindowWMInfo := TSDL_GetWindowWMInfo_func(GetProcAddress(LibHandle, 'SDL_GetWindowWMInfo'));
+ If Not assigned(SDL_GetWindowWMInfo) Then result := false;
+ SDL_CreateThread := TSDL_CreateThread_func(GetProcAddress(LibHandle, 'SDL_CreateThread'));
+ If Not assigned(SDL_CreateThread) Then result := false;
+ SDL_CreateThreadWithStackSize := TSDL_CreateThreadWithStackSize_func(GetProcAddress(LibHandle, 'SDL_CreateThreadWithStackSize'));
+ If Not assigned(SDL_CreateThreadWithStackSize) Then result := false;
+ SDL_CreateThread := TSDL_CreateThread_func(GetProcAddress(LibHandle, 'SDL_CreateThread'));
+ If Not assigned(SDL_CreateThread) Then result := false;
+ SDL_CreateThreadWithStackSize := TSDL_CreateThreadWithStackSize_func(GetProcAddress(LibHandle, 'SDL_CreateThreadWithStackSize'));
+ If Not assigned(SDL_CreateThreadWithStackSize) Then result := false;
+ SDL_GetThreadName := TSDL_GetThreadName_func(GetProcAddress(LibHandle, 'SDL_GetThreadName'));
+ If Not assigned(SDL_GetThreadName) Then result := false;
+ SDL_GetThreadID := TSDL_GetThreadID_func(GetProcAddress(LibHandle, 'SDL_GetThreadID'));
+ If Not assigned(SDL_GetThreadID) Then result := false;
+ SDL_SetThreadPriority := TSDL_SetThreadPriority_func(GetProcAddress(LibHandle, 'SDL_SetThreadPriority'));
+ If Not assigned(SDL_SetThreadPriority) Then result := false;
+ SDL_WaitThread := TSDL_WaitThread_proc(GetProcAddress(LibHandle, 'SDL_WaitThread'));
+ If Not assigned(SDL_WaitThread) Then result := false;
+ SDL_DetachThread := TSDL_DetachThread_proc(GetProcAddress(LibHandle, 'SDL_DetachThread'));
+ If Not assigned(SDL_DetachThread) Then result := false;
+ SDL_TLSGet := TSDL_TLSGet_func(GetProcAddress(LibHandle, 'SDL_TLSGet'));
+ If Not assigned(SDL_TLSGet) Then result := false;
+ SDL_TLSSet := TSDL_TLSSet_func(GetProcAddress(LibHandle, 'SDL_TLSSet'));
+ If Not assigned(SDL_TLSSet) Then result := false;
+ SDL_Delay := TSDL_Delay_proc(GetProcAddress(LibHandle, 'SDL_Delay'));
+ If Not assigned(SDL_Delay) Then result := false;
+ SDL_AddTimer := TSDL_AddTimer_func(GetProcAddress(LibHandle, 'SDL_AddTimer'));
+ If Not assigned(SDL_AddTimer) Then result := false;
+ SDL_RemoveTimer := TSDL_RemoveTimer_func(GetProcAddress(LibHandle, 'SDL_RemoveTimer'));
+ If Not assigned(SDL_RemoveTimer) Then result := false;
+ SDL_GetNumTouchDevices := TSDL_GetNumTouchDevices_func(GetProcAddress(LibHandle, 'SDL_GetNumTouchDevices'));
+ If Not assigned(SDL_GetNumTouchDevices) Then result := false;
+ SDL_GetTouchDevice := TSDL_GetTouchDevice_func(GetProcAddress(LibHandle, 'SDL_GetTouchDevice'));
+ If Not assigned(SDL_GetTouchDevice) Then result := false;
+ (* SDL_GetTouchName := TSDL_GetTouchName_func(GetProcAddress(LibHandle, 'SDL_GetTouchName'));
+ If Not assigned(SDL_GetTouchName) Then result := false;
+ SDL_GetTouchDeviceType := TSDL_GetTouchDeviceType_func(GetProcAddress(LibHandle, 'SDL_GetTouchDeviceType'));
+ If Not assigned(SDL_GetTouchDeviceType) Then result := false;
+ SDL_GetNumTouchFingers := TSDL_GetNumTouchFingers_func(GetProcAddress(LibHandle, 'SDL_GetNumTouchFingers'));
+ If Not assigned(SDL_GetNumTouchFingers) Then result := false;
+ SDL_GetTouchFinger := TSDL_GetTouchFinger_func(GetProcAddress(LibHandle, 'SDL_GetTouchFinger'));
+ If Not assigned(SDL_GetTouchFinger) Then result := false; //*)
+ SDL_GetVersion := TSDL_GetVersion_proc(GetProcAddress(LibHandle, 'SDL_GetVersion'));
+ If Not assigned(SDL_GetVersion) Then result := false;
+ (* SDL_GetVideoDriver := TSDL_GetVideoDriver_func(GetProcAddress(LibHandle, 'SDL_GetVideoDriver'));
+ If Not assigned(SDL_GetVideoDriver) Then result := false;
+ SDL_VideoInit := TSDL_VideoInit_func(GetProcAddress(LibHandle, 'SDL_VideoInit'));
+ If Not assigned(SDL_VideoInit) Then result := false;
+ SDL_GetDisplayName := TSDL_GetDisplayName_func(GetProcAddress(LibHandle, 'SDL_GetDisplayName'));
+ If Not assigned(SDL_GetDisplayName) Then result := false;
+ SDL_GetDisplayBounds := TSDL_GetDisplayBounds_func(GetProcAddress(LibHandle, 'SDL_GetDisplayBounds'));
+ If Not assigned(SDL_GetDisplayBounds) Then result := false;
+ SDL_GetDisplayUsableBounds := TSDL_GetDisplayUsableBounds_func(GetProcAddress(LibHandle, 'SDL_GetDisplayUsableBounds'));
+ If Not assigned(SDL_GetDisplayUsableBounds) Then result := false;
+ SDL_GetDisplayDPI := TSDL_GetDisplayDPI_func(GetProcAddress(LibHandle, 'SDL_GetDisplayDPI'));
+ If Not assigned(SDL_GetDisplayDPI) Then result := false;
+ SDL_GetDisplayOrientation := TSDL_GetDisplayOrientation_func(GetProcAddress(LibHandle, 'SDL_GetDisplayOrientation'));
+ If Not assigned(SDL_GetDisplayOrientation) Then result := false;
+ SDL_GetNumDisplayModes := TSDL_GetNumDisplayModes_func(GetProcAddress(LibHandle, 'SDL_GetNumDisplayModes'));
+ If Not assigned(SDL_GetNumDisplayModes) Then result := false;
+ SDL_GetDisplayMode := TSDL_GetDisplayMode_func(GetProcAddress(LibHandle, 'SDL_GetDisplayMode'));
+ If Not assigned(SDL_GetDisplayMode) Then result := false;
+ SDL_GetDesktopDisplayMode := TSDL_GetDesktopDisplayMode_func(GetProcAddress(LibHandle, 'SDL_GetDesktopDisplayMode'));
+ If Not assigned(SDL_GetDesktopDisplayMode) Then result := false;
+ SDL_GetCurrentDisplayMode := TSDL_GetCurrentDisplayMode_func(GetProcAddress(LibHandle, 'SDL_GetCurrentDisplayMode'));
+ If Not assigned(SDL_GetCurrentDisplayMode) Then result := false;
+ SDL_GetClosestDisplayMode := TSDL_GetClosestDisplayMode_func(GetProcAddress(LibHandle, 'SDL_GetClosestDisplayMode'));
+ If Not assigned(SDL_GetClosestDisplayMode) Then result := false;
+ SDL_GetPointDisplayIndex := TSDL_GetPointDisplayIndex_func(GetProcAddress(LibHandle, 'SDL_GetPointDisplayIndex'));
+ If Not assigned(SDL_GetPointDisplayIndex) Then result := false;
+ SDL_GetRectDisplayIndex := TSDL_GetRectDisplayIndex_func(GetProcAddress(LibHandle, 'SDL_GetRectDisplayIndex'));
+ If Not assigned(SDL_GetRectDisplayIndex) Then result := false;
+ SDL_GetWindowDisplayIndex := TSDL_GetWindowDisplayIndex_func(GetProcAddress(LibHandle, 'SDL_GetWindowDisplayIndex'));
+ If Not assigned(SDL_GetWindowDisplayIndex) Then result := false;
+ SDL_SetWindowDisplayMode := TSDL_SetWindowDisplayMode_func(GetProcAddress(LibHandle, 'SDL_SetWindowDisplayMode'));
+ If Not assigned(SDL_SetWindowDisplayMode) Then result := false;
+ SDL_GetWindowDisplayMode := TSDL_GetWindowDisplayMode_func(GetProcAddress(LibHandle, 'SDL_GetWindowDisplayMode'));
+ If Not assigned(SDL_GetWindowDisplayMode) Then result := false;
+ SDL_GetWindowICCProfile := TSDL_GetWindowICCProfile_func(GetProcAddress(LibHandle, 'SDL_GetWindowICCProfile'));
+ If Not assigned(SDL_GetWindowICCProfile) Then result := false;
+ SDL_GetWindowPixelFormat := TSDL_GetWindowPixelFormat_func(GetProcAddress(LibHandle, 'SDL_GetWindowPixelFormat'));
+ If Not assigned(SDL_GetWindowPixelFormat) Then result := false;
+ SDL_CreateWindow := TSDL_CreateWindow_func(GetProcAddress(LibHandle, 'SDL_CreateWindow'));
+ If Not assigned(SDL_CreateWindow) Then result := false;
+ SDL_CreateWindowFrom := TSDL_CreateWindowFrom_func(GetProcAddress(LibHandle, 'SDL_CreateWindowFrom'));
+ If Not assigned(SDL_CreateWindowFrom) Then result := false;
+ SDL_GetWindowID := TSDL_GetWindowID_func(GetProcAddress(LibHandle, 'SDL_GetWindowID'));
+ If Not assigned(SDL_GetWindowID) Then result := false;
+ SDL_GetWindowFromID := TSDL_GetWindowFromID_func(GetProcAddress(LibHandle, 'SDL_GetWindowFromID'));
+ If Not assigned(SDL_GetWindowFromID) Then result := false;
+ SDL_GetWindowFlags := TSDL_GetWindowFlags_func(GetProcAddress(LibHandle, 'SDL_GetWindowFlags'));
+ If Not assigned(SDL_GetWindowFlags) Then result := false;
+ SDL_SetWindowTitle := TSDL_SetWindowTitle_proc(GetProcAddress(LibHandle, 'SDL_SetWindowTitle'));
+ If Not assigned(SDL_SetWindowTitle) Then result := false;
+ SDL_GetWindowTitle := TSDL_GetWindowTitle_func(GetProcAddress(LibHandle, 'SDL_GetWindowTitle'));
+ If Not assigned(SDL_GetWindowTitle) Then result := false;
+ SDL_SetWindowIcon := TSDL_SetWindowIcon_proc(GetProcAddress(LibHandle, 'SDL_SetWindowIcon'));
+ If Not assigned(SDL_SetWindowIcon) Then result := false;
+ SDL_SetWindowData := TSDL_SetWindowData_func(GetProcAddress(LibHandle, 'SDL_SetWindowData'));
+ If Not assigned(SDL_SetWindowData) Then result := false;
+ SDL_GetWindowData := TSDL_GetWindowData_func(GetProcAddress(LibHandle, 'SDL_GetWindowData'));
+ If Not assigned(SDL_GetWindowData) Then result := false;
+ SDL_SetWindowPosition := TSDL_SetWindowPosition_proc(GetProcAddress(LibHandle, 'SDL_SetWindowPosition'));
+ If Not assigned(SDL_SetWindowPosition) Then result := false;
+ SDL_GetWindowPosition := TSDL_GetWindowPosition_proc(GetProcAddress(LibHandle, 'SDL_GetWindowPosition'));
+ If Not assigned(SDL_GetWindowPosition) Then result := false;
+ SDL_SetWindowSize := TSDL_SetWindowSize_proc(GetProcAddress(LibHandle, 'SDL_SetWindowSize'));
+ If Not assigned(SDL_SetWindowSize) Then result := false;
+ SDL_GetWindowSize := TSDL_GetWindowSize_proc(GetProcAddress(LibHandle, 'SDL_GetWindowSize'));
+ If Not assigned(SDL_GetWindowSize) Then result := false;
+ SDL_GetWindowBordersSize := TSDL_GetWindowBordersSize_func(GetProcAddress(LibHandle, 'SDL_GetWindowBordersSize'));
+ If Not assigned(SDL_GetWindowBordersSize) Then result := false;
+ SDL_GetWindowSizeInPixels := TSDL_GetWindowSizeInPixels_proc(GetProcAddress(LibHandle, 'SDL_GetWindowSizeInPixels'));
+ If Not assigned(SDL_GetWindowSizeInPixels) Then result := false;
+ SDL_SetWindowMinimumSize := TSDL_SetWindowMinimumSize_proc(GetProcAddress(LibHandle, 'SDL_SetWindowMinimumSize'));
+ If Not assigned(SDL_SetWindowMinimumSize) Then result := false;
+ SDL_GetWindowMinimumSize := TSDL_GetWindowMinimumSize_proc(GetProcAddress(LibHandle, 'SDL_GetWindowMinimumSize'));
+ If Not assigned(SDL_GetWindowMinimumSize) Then result := false;
+ SDL_SetWindowMaximumSize := TSDL_SetWindowMaximumSize_proc(GetProcAddress(LibHandle, 'SDL_SetWindowMaximumSize'));
+ If Not assigned(SDL_SetWindowMaximumSize) Then result := false;
+ SDL_GetWindowMaximumSize := TSDL_GetWindowMaximumSize_proc(GetProcAddress(LibHandle, 'SDL_GetWindowMaximumSize'));
+ If Not assigned(SDL_GetWindowMaximumSize) Then result := false;
+ SDL_SetWindowBordered := TSDL_SetWindowBordered_proc(GetProcAddress(LibHandle, 'SDL_SetWindowBordered'));
+ If Not assigned(SDL_SetWindowBordered) Then result := false;
+ SDL_SetWindowResizable := TSDL_SetWindowResizable_proc(GetProcAddress(LibHandle, 'SDL_SetWindowResizable'));
+ If Not assigned(SDL_SetWindowResizable) Then result := false;
+ SDL_SetWindowAlwaysOnTop := TSDL_SetWindowAlwaysOnTop_proc(GetProcAddress(LibHandle, 'SDL_SetWindowAlwaysOnTop'));
+ If Not assigned(SDL_SetWindowAlwaysOnTop) Then result := false;
+ SDL_ShowWindow := TSDL_ShowWindow_proc(GetProcAddress(LibHandle, 'SDL_ShowWindow'));
+ If Not assigned(SDL_ShowWindow) Then result := false;
+ SDL_HideWindow := TSDL_HideWindow_proc(GetProcAddress(LibHandle, 'SDL_HideWindow'));
+ If Not assigned(SDL_HideWindow) Then result := false;
+ SDL_RaiseWindow := TSDL_RaiseWindow_proc(GetProcAddress(LibHandle, 'SDL_RaiseWindow'));
+ If Not assigned(SDL_RaiseWindow) Then result := false;
+ SDL_MaximizeWindow := TSDL_MaximizeWindow_proc(GetProcAddress(LibHandle, 'SDL_MaximizeWindow'));
+ If Not assigned(SDL_MaximizeWindow) Then result := false;
+ SDL_MinimizeWindow := TSDL_MinimizeWindow_proc(GetProcAddress(LibHandle, 'SDL_MinimizeWindow'));
+ If Not assigned(SDL_MinimizeWindow) Then result := false;
+ SDL_RestoreWindow := TSDL_RestoreWindow_proc(GetProcAddress(LibHandle, 'SDL_RestoreWindow'));
+ If Not assigned(SDL_RestoreWindow) Then result := false;
+ SDL_SetWindowFullscreen := TSDL_SetWindowFullscreen_func(GetProcAddress(LibHandle, 'SDL_SetWindowFullscreen'));
+ If Not assigned(SDL_SetWindowFullscreen) Then result := false;
+ SDL_HasWindowSurface := TSDL_HasWindowSurface_func(GetProcAddress(LibHandle, 'SDL_HasWindowSurface'));
+ If Not assigned(SDL_HasWindowSurface) Then result := false;
+ SDL_GetWindowSurface := TSDL_GetWindowSurface_func(GetProcAddress(LibHandle, 'SDL_GetWindowSurface'));
+ If Not assigned(SDL_GetWindowSurface) Then result := false;
+ SDL_UpdateWindowSurface := TSDL_UpdateWindowSurface_func(GetProcAddress(LibHandle, 'SDL_UpdateWindowSurface'));
+ If Not assigned(SDL_UpdateWindowSurface) Then result := false;
+ SDL_UpdateWindowSurfaceRects := TSDL_UpdateWindowSurfaceRects_func(GetProcAddress(LibHandle, 'SDL_UpdateWindowSurfaceRects'));
+ If Not assigned(SDL_UpdateWindowSurfaceRects) Then result := false;
+ SDL_DestroyWindowSurface := TSDL_DestroyWindowSurface_func(GetProcAddress(LibHandle, 'SDL_DestroyWindowSurface'));
+ If Not assigned(SDL_DestroyWindowSurface) Then result := false;
+ SDL_SetWindowGrab := TSDL_SetWindowGrab_proc(GetProcAddress(LibHandle, 'SDL_SetWindowGrab'));
+ If Not assigned(SDL_SetWindowGrab) Then result := false;
+ SDL_GetWindowGrab := TSDL_GetWindowGrab_func(GetProcAddress(LibHandle, 'SDL_GetWindowGrab'));
+ If Not assigned(SDL_GetWindowGrab) Then result := false;
+ SDL_SetWindowKeyboardGrab := TSDL_SetWindowKeyboardGrab_proc(GetProcAddress(LibHandle, 'SDL_SetWindowKeyboardGrab'));
+ If Not assigned(SDL_SetWindowKeyboardGrab) Then result := false;
+ SDL_GetWindowKeyboardGrab := TSDL_GetWindowKeyboardGrab_func(GetProcAddress(LibHandle, 'SDL_GetWindowKeyboardGrab'));
+ If Not assigned(SDL_GetWindowKeyboardGrab) Then result := false;
+ SDL_SetWindowMouseGrab := TSDL_SetWindowMouseGrab_proc(GetProcAddress(LibHandle, 'SDL_SetWindowMouseGrab'));
+ If Not assigned(SDL_SetWindowMouseGrab) Then result := false;
+ SDL_GetWindowMouseGrab := TSDL_GetWindowMouseGrab_func(GetProcAddress(LibHandle, 'SDL_GetWindowMouseGrab'));
+ If Not assigned(SDL_GetWindowMouseGrab) Then result := false;
+ SDL_SetWindowMouseRect := TSDL_SetWindowMouseRect_proc(GetProcAddress(LibHandle, 'SDL_SetWindowMouseRect'));
+ If Not assigned(SDL_SetWindowMouseRect) Then result := false;
+ SDL_GetWindowMouseRect := TSDL_GetWindowMouseRect_func(GetProcAddress(LibHandle, 'SDL_GetWindowMouseRect'));
+ If Not assigned(SDL_GetWindowMouseRect) Then result := false;
+ SDL_GetGrabbedWindow := TSDL_GetGrabbedWindow_func(GetProcAddress(LibHandle, 'SDL_GetGrabbedWindow'));
+ If Not assigned(SDL_GetGrabbedWindow) Then result := false;
+ SDL_SetWindowBrightness := TSDL_SetWindowBrightness_func(GetProcAddress(LibHandle, 'SDL_SetWindowBrightness'));
+ If Not assigned(SDL_SetWindowBrightness) Then result := false;
+ SDL_GetWindowBrightness := TSDL_GetWindowBrightness_func(GetProcAddress(LibHandle, 'SDL_GetWindowBrightness'));
+ If Not assigned(SDL_GetWindowBrightness) Then result := false;
+ SDL_SetWindowOpacity := TSDL_SetWindowOpacity_func(GetProcAddress(LibHandle, 'SDL_SetWindowOpacity'));
+ If Not assigned(SDL_SetWindowOpacity) Then result := false;
+ SDL_GetWindowOpacity := TSDL_GetWindowOpacity_func(GetProcAddress(LibHandle, 'SDL_GetWindowOpacity'));
+ If Not assigned(SDL_GetWindowOpacity) Then result := false;
+ SDL_SetWindowModalFor := TSDL_SetWindowModalFor_func(GetProcAddress(LibHandle, 'SDL_SetWindowModalFor'));
+ If Not assigned(SDL_SetWindowModalFor) Then result := false;
+ SDL_SetWindowInputFocus := TSDL_SetWindowInputFocus_func(GetProcAddress(LibHandle, 'SDL_SetWindowInputFocus'));
+ If Not assigned(SDL_SetWindowInputFocus) Then result := false;
+ SDL_SetWindowGammaRamp := TSDL_SetWindowGammaRamp_func(GetProcAddress(LibHandle, 'SDL_SetWindowGammaRamp'));
+ If Not assigned(SDL_SetWindowGammaRamp) Then result := false;
+ SDL_GetWindowGammaRamp := TSDL_GetWindowGammaRamp_func(GetProcAddress(LibHandle, 'SDL_GetWindowGammaRamp'));
+ If Not assigned(SDL_GetWindowGammaRamp) Then result := false;
+ SDL_SetWindowHitTest := TSDL_SetWindowHitTest_func(GetProcAddress(LibHandle, 'SDL_SetWindowHitTest'));
+ If Not assigned(SDL_SetWindowHitTest) Then result := false;
+ SDL_FlashWindow := TSDL_FlashWindow_func(GetProcAddress(LibHandle, 'SDL_FlashWindow'));
+ If Not assigned(SDL_FlashWindow) Then result := false;
+ SDL_DestroyWindow := TSDL_DestroyWindow_proc(GetProcAddress(LibHandle, 'SDL_DestroyWindow'));
+ If Not assigned(SDL_DestroyWindow) Then result := false;
+ SDL_GL_LoadLibrary := TSDL_GL_LoadLibrary_func(GetProcAddress(LibHandle, 'SDL_GL_LoadLibrary'));
+ If Not assigned(SDL_GL_LoadLibrary) Then result := false;
+ SDL_GL_GetProcAddress := TSDL_GL_GetProcAddress_func(GetProcAddress(LibHandle, 'SDL_GL_GetProcAddress'));
+ If Not assigned(SDL_GL_GetProcAddress) Then result := false;
+ SDL_GL_ExtensionSupported := TSDL_GL_ExtensionSupported_func(GetProcAddress(LibHandle, 'SDL_GL_ExtensionSupported'));
+ If Not assigned(SDL_GL_ExtensionSupported) Then result := false;
+ SDL_GL_ResetAttributes := TSDL_GL_ResetAttributes_proc(GetProcAddress(LibHandle, 'SDL_GL_ResetAttributes'));
+ If Not assigned(SDL_GL_ResetAttributes) Then result := false;
+ SDL_GL_SetAttribute := TSDL_GL_SetAttribute_func(GetProcAddress(LibHandle, 'SDL_GL_SetAttribute'));
+ If Not assigned(SDL_GL_SetAttribute) Then result := false;
+ SDL_GL_GetAttribute := TSDL_GL_GetAttribute_func(GetProcAddress(LibHandle, 'SDL_GL_GetAttribute'));
+ If Not assigned(SDL_GL_GetAttribute) Then result := false;
+ SDL_GL_CreateContext := TSDL_GL_CreateContext_func(GetProcAddress(LibHandle, 'SDL_GL_CreateContext'));
+ If Not assigned(SDL_GL_CreateContext) Then result := false;
+ SDL_GL_MakeCurrent := TSDL_GL_MakeCurrent_func(GetProcAddress(LibHandle, 'SDL_GL_MakeCurrent'));
+ If Not assigned(SDL_GL_MakeCurrent) Then result := false;
+ SDL_GL_GetDrawableSize := TSDL_GL_GetDrawableSize_proc(GetProcAddress(LibHandle, 'SDL_GL_GetDrawableSize'));
+ If Not assigned(SDL_GL_GetDrawableSize) Then result := false;
+ SDL_GL_SetSwapInterval := TSDL_GL_SetSwapInterval_func(GetProcAddress(LibHandle, 'SDL_GL_SetSwapInterval'));
+ If Not assigned(SDL_GL_SetSwapInterval) Then result := false;
+ SDL_GL_SwapWindow := TSDL_GL_SwapWindow_proc(GetProcAddress(LibHandle, 'SDL_GL_SwapWindow'));
+ If Not assigned(SDL_GL_SwapWindow) Then result := false;
+ SDL_GL_DeleteContext := TSDL_GL_DeleteContext_proc(GetProcAddress(LibHandle, 'SDL_GL_DeleteContext'));
+ If Not assigned(SDL_GL_DeleteContext) Then result := false;
+ *)
+ End
+ Else Begin
+ // Library load failed
+ End;
+ If Not result Then Begin
+ SDL_UnLoadLib();
+ End;
+End;
+
+Procedure SDL_UnLoadLib();
+Begin
+ If LibHandle <> 0 Then Begin
+ UnloadLibrary(LibHandle);
+ LibHandle := 0;
+ End;
+End;
+{$ENDIF}
+
diff --git a/units/sdl2_for_pascal/sdlatomic.inc b/units/sdl2_for_pascal/sdlatomic.inc
new file mode 100644
index 0000000..80bf1d5
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlatomic.inc
@@ -0,0 +1,179 @@
+// from SDL_atomic.h
+
+{**
+ * Atomic locks are efficient spinlocks using CPU instructions,
+ * but are vulnerable to starvation and can spin forever if a thread
+ * holding a lock has been terminated. For this reason you should
+ * minimize the code executed inside an atomic lock and never do
+ * expensive things like API or system calls while holding them.
+ *
+ * The atomic locks are not safe to lock recursively.
+ *}
+type
+ PPSDL_SpinLock = ^PSDL_SpinLock;
+ PSDL_SpinLock = ^TSDL_SpinLock;
+ TSDL_SpinLock = type cint;
+
+{**
+ * Try to lock a spin lock by setting it to a non-zero value.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicTryLock_func = function (lock: PSDL_SpinLock): TSDL_bool; cdecl;
+Var
+ SDL_AtomicTryLock : TSDL_AtomicTryLock_func = Nil;
+{$else}
+function SDL_AtomicTryLock(lock: PSDL_SpinLock): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicTryLock' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Lock a spin lock by setting it to a non-zero value.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicLock_func = function (lock: PSDL_SpinLock): TSDL_bool; cdecl;
+Var
+ SDL_AtomicLock : TSDL_AtomicLock_func = Nil;
+{$else}
+function SDL_AtomicLock(lock: PSDL_SpinLock): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicLock' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Unlock a spin lock by setting it to 0.
+ *
+ * Always returns immediately.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicUnlock_proc = procedure (lock: PSDL_SpinLock); cdecl;
+Var
+ SDL_AtomicUnlock : TSDL_AtomicUnlock_proc = Nil;
+{$else}
+procedure SDL_AtomicUnlock(lock: PSDL_SpinLock); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicUnlock' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * The compiler barrier prevents the compiler from reordering
+ * reads and writes to globally visible variables across the call.
+ *}
+procedure SDL_CompilerBarrier();
+
+type
+ {**
+ * A type representing an atomic integer value. It is a record
+ * so people don't accidentally use numeric operations on it.
+ *}
+ PPSDL_Atomic = ^PSDL_Atomic;
+ PSDL_Atomic = ^TSDL_Atomic;
+ TSDL_Atomic = record
+ Value: cint
+ end;
+
+{**
+ * Set an atomic variable to a new value if it is currently an old value.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_AtomicCAS_func = function (atomic: PSDL_Atomic; oldValue, newValue: cint): TSDL_bool; cdecl;
+ Var
+ SDL_AtomicCAS : TSDL_AtomicCAS_func = Nil;
+ {$else}
+ function SDL_AtomicCAS(atomic: PSDL_Atomic; oldValue, newValue: cint): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicCAS' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Set an atomic variable to a new value and return the old one.
+ *
+ * This function also acts as a full memory barrier.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_AtomicSet_func = function (atomic: PSDL_Atomic; value: cint): cint; cdecl;
+ Var
+ SDL_AtomicSet : TSDL_AtomicSet_func = Nil;
+ {$else}
+ function SDL_AtomicSet(atomic: PSDL_Atomic; value: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicSet' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Get the value of an atomic variable.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_AtomicGet_func = function (atomic: PSDL_Atomic): cint; cdecl;
+ Var
+ SDL_AtomicGet : TSDL_AtomicGet_func = Nil;
+ {$else}
+ function SDL_AtomicGet(atomic: PSDL_Atomic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicGet' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Add to an atomic variable, and return the old value.
+ *
+ * This function also acts as a full memory barrier.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_AtomicAdd_func = function (atomic: PSDL_Atomic; value: cint): cint; cdecl;
+ Var
+ SDL_AtomicAdd : TSDL_AtomicAdd_func = Nil;
+ {$else}
+ function SDL_AtomicAdd(atomic: PSDL_Atomic; value: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicAdd' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Increment an atomic variable used as a reference count.
+ *}
+function SDL_AtomicIncRef(atomic: PSDL_Atomic): cint;
+{**
+ * Decrement an atomic variable used as a reference count
+ * and check if it reached zero after decrementing.
+ *}
+function SDL_AtomicDecRef(atomic: PSDL_Atomic): Boolean;
+
+{**
+ * Set a pointer to a new value if it is currently an old value.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicCASPtr_func = function (ptr: PPointer; oldValue, newValue: Pointer): TSDL_bool; cdecl;
+Var
+ SDL_AtomicCASPtr : TSDL_AtomicCASPtr_func = Nil;
+{$else}
+function SDL_AtomicCASPtr(ptr: PPointer; oldValue, newValue: Pointer): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicCASPtr' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set a pointer to a new value atomically, and return the old value.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicSetPtr_func = function (ptr: PPointer; value: Pointer): Pointer; cdecl;
+Var
+ SDL_AtomicSetPtr : TSDL_AtomicSetPtr_func = Nil;
+{$else}
+function SDL_AtomicSetPtr(ptr: PPointer; value: Pointer): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicSetPtr' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the value of a pointer atomically.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AtomicGetPtr_func = function (ptr: PPointer): Pointer; cdecl;
+Var
+ SDL_AtomicGetPtr : TSDL_AtomicGetPtr_func = Nil;
+{$else}
+function SDL_AtomicGetPtr(ptr: PPointer): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AtomicGetPtr' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlaudio.inc b/units/sdl2_for_pascal/sdlaudio.inc
new file mode 100644
index 0000000..7c608cf
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlaudio.inc
@@ -0,0 +1,1766 @@
+//from sdl_audio.h
+ {**
+ * Audio format flags.
+ *
+ * These are what the 16 bits in SDL_AudioFormat currently mean...
+ * (Unspecified bits are always zero).
+ *
+ *
+ ++-----------------------sample is signed if set
+ ||
+ || ++-----------sample is bigendian if set
+ || ||
+ || || ++---sample is float if set
+ || || ||
+ || || || +---sample bit size---+
+ || || || | |
+ 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+ *
+ * There are macros in SDL 2.0 and later to query these bits.
+ *}
+type
+ PPSDL_AudioFormat = ^PSDL_AudioFormat;
+ PSDL_AudioFormat = ^TSDL_AudioFormat;
+ TSDL_AudioFormat = cuint16;
+
+ {**
+ * Audio flags
+ *}
+const
+ SDL_AUDIO_MASK_BITSIZE = ($FF);
+ SDL_AUDIO_MASK_DATATYPE = (1 shl 8);
+ SDL_AUDIO_MASK_ENDIAN = (1 shl 12);
+ SDL_AUDIO_MASK_SIGNED = (1 shl 15);
+
+function SDL_AUDIO_BITSIZE(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISFLOAT(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISBIGENDIAN(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISSIGNED(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISINT(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISLITTLEENDIAN(x: Cardinal): Cardinal;
+function SDL_AUDIO_ISUNSIGNED(x: Cardinal): Cardinal;
+
+ {**
+ * Audio format flags
+ *
+ * Defaults to LSB byte order.
+ *}
+const
+ AUDIO_U8 = $0008; {**< Unsigned 8-bit samples *}
+ AUDIO_S8 = $8008; {**< Signed 8-bit samples *}
+ AUDIO_U16LSB = $0010; {**< Unsigned 16-bit samples *}
+ AUDIO_S16LSB = $8010; {**< Signed 16-bit samples *}
+ AUDIO_U16MSB = $1010; {**< As above, but big-endian byte order *}
+ AUDIO_S16MSB = $9010; {**< As above, but big-endian byte order *}
+ AUDIO_U16 = AUDIO_U16LSB;
+ AUDIO_S16 = AUDIO_S16LSB;
+
+ {**
+ * int32 support
+ *}
+const
+ AUDIO_S32LSB = $8020; {**< 32-bit integer samples *}
+ AUDIO_S32MSB = $9020; {**< As above, but big-endian byte order *}
+ AUDIO_S32 = AUDIO_S32LSB;
+
+ {**
+ * float32 support
+ *}
+const
+ AUDIO_F32LSB = $8120; {**< 32-bit floating point samples *}
+ AUDIO_F32MSB = $9120; {**< As above, but big-endian byte order *}
+ AUDIO_F32 = AUDIO_F32LSB;
+
+ {**
+ * Native audio byte ordering
+ *}
+{$IFDEF FPC}
+ {$IF DEFINED(ENDIAN_LITTLE)}
+ AUDIO_U16SYS = AUDIO_U16LSB;
+ AUDIO_S16SYS = AUDIO_S16LSB;
+ AUDIO_S32SYS = AUDIO_S32LSB;
+ AUDIO_F32SYS = AUDIO_F32LSB;
+ {$ELSEIF DEFINED(ENDIAN_BIG)}
+ AUDIO_U16SYS = AUDIO_U16MSB;
+ AUDIO_S16SYS = AUDIO_S16MSB;
+ AUDIO_S32SYS = AUDIO_S32MSB;
+ AUDIO_F32SYS = AUDIO_F32MSB;
+ {$ELSE}
+ {$FATAL Cannot determine endianness.}
+ {$IFEND}
+{$ENDIF}
+
+ {**
+ * Allow change flags
+ *
+ * Which audio format changes are allowed when opening a device.
+ *}
+const
+ SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = $00000001;
+ SDL_AUDIO_ALLOW_FORMAT_CHANGE = $00000002;
+ SDL_AUDIO_ALLOW_CHANNELS_CHANGE = $00000004;
+ SDL_AUDIO_ALLOW_ANY_CHANGE = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE or
+ SDL_AUDIO_ALLOW_FORMAT_CHANGE or
+ SDL_AUDIO_ALLOW_CHANNELS_CHANGE);
+
+ {*Audio flags*}
+
+ {**
+ * This function is called when the audio device needs more data.
+ *
+ * \param userdata An application-specific parameter saved in
+ * the SDL_AudioSpec structure
+ * \param stream A pointer to the audio data buffer.
+ * \param len The length of that buffer in bytes.
+ *
+ * Once the callback returns, the buffer will no longer be valid.
+ * Stereo samples are stored in a LRLRLR ordering.
+ *
+ * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if
+ * you like. Just open your audio device with a NULL callback.
+ *}
+type
+ PPSDL_AudioCallback = ^PSDL_AudioCallback;
+ PSDL_AudioCallback = ^TSDL_AudioCallback;
+ TSDL_AudioCallback = procedure(userdata: Pointer; stream: pcuint8; len: cint); cdecl;
+
+ {**
+ * The calculated values in this structure are calculated by SDL_OpenAudio().
+ *
+ * For multi-channel audio, the default SDL channel mapping is:
+ * 2: FL FR (stereo)
+ * 3: FL FR LFE (2.1 surround)
+ * 4: FL FR BL BR (quad)
+ * 5: FL FR LFE BL BR (4.1 surround)
+ * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR)
+ * 7: FL FR FC LFE BC SL SR (6.1 surround)
+ * 8: FL FR FC LFE BL BR SL SR (7.1 surround)
+ *}
+type
+ PPSDL_AudioSpec = ^PSDL_AudioSpec;
+ PSDL_AudioSpec = ^TSDL_AudioSpec;
+ TSDL_AudioSpec = record
+ freq: cint; {**< DSP frequency -- samples per second *}
+ format: TSDL_AudioFormat; {**< Audio data format *}
+ channels: cuint8; {**< Number of channels: 1 mono, 2 stereo *}
+ silence: cuint8; {**< Audio buffer silence value (calculated) *}
+ samples: cuint16; {**< Audio buffer size in sample FRAMES (total samples divided by channel count) *}
+ padding: cuint16; {**< Necessary for some compile environments *}
+ size: cuint32; {**< Audio buffer size in bytes (calculated) *}
+ callback: TSDL_AudioCallback; {**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). *}
+ userdata: Pointer; {**< Userdata passed to callback (ignored for NULL callbacks). *}
+ end;
+
+ {**
+ * \brief Upper limit of filters in SDL_AudioCVT
+ *
+ * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is
+ * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers,
+ * one of which is the terminating NULL pointer.
+ *}
+const
+ SDL_AUDIOCVT_MAX_FILTERS = 9;
+
+type
+ PPSDL_AudioCVT = ^PSDL_AudioCVT;
+ PSDL_AudioCVT = ^TSDL_AudioCVT;
+ TSDL_AudioFilter = procedure(cvt: PSDL_AudioCVT; format: TSDL_AudioFormat); cdecl;
+
+ {**
+ * \struct SDL_AudioCVT
+ * \brief A structure to hold a set of audio conversion filters and buffers.
+ *
+ * Note that various parts of the conversion pipeline can take advantage
+ * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require
+ * you to pass it aligned data, but can possibly run much faster if you
+ * set both its (buf) field to a pointer that is aligned to 16 bytes, and its
+ * (len) field to something that's a multiple of 16, if possible.
+ *}
+ TSDL_AudioCVT = record
+ needed: cint; {**< Set to 1 if conversion possible *}
+ src_format: TSDL_AudioFormat; {**< Source audio format *}
+ dst_format: TSDL_AudioFormat; {**< Target audio format *}
+ rate_incr: cdouble; {**< Rate conversion increment *}
+ buf: pcuint8; {**< Buffer to hold entire audio data *}
+ len: cint; {**< Length of original audio buffer *}
+ len_cvt: cint; {**< Length of converted audio buffer *}
+ len_mult: cint; {**< buffer must be len*len_mult big *}
+ len_ratio: cdouble; {**< Given len, final size is len*len_ratio *}
+ filters: array[0..SDL_AUDIOCVT_MAX_FILTERS] of TSDL_AudioFilter; {**< NULL-terminated list of filter functions *}
+ filter_index: cint; {**< Current audio conversion function *}
+ end;
+
+
+ {* Function prototypes *}
+
+ {**
+ * Driver discovery functions
+ *
+ * These functions return the list of built in audio drivers, in the
+ * order that they are normally initialized by default.
+ *}
+
+ {**
+ * Use this function to get the number of built-in audio drivers.
+ *
+ * This function returns a hardcoded number. This never returns a negative
+ * value; if there are no drivers compiled into this build of SDL, this
+ * function returns zero. The presence of a driver in this list does not mean
+ * it will function, it just means SDL is capable of interacting with that
+ * interface. For example, a build of SDL might have esound support, but if
+ * there's no esound server available, SDL's esound driver would fail if used.
+ *
+ * By default, SDL tries all drivers, in its preferred order, until one is
+ * found to be usable.
+ *
+ * \returns the number of built-in audio drivers.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetAudioDriver
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetNumAudioDrivers_func = function : cint; cdecl;
+ Var
+ SDL_GetNumAudioDrivers : TSDL_GetNumAudioDrivers_func = Nil;
+ {$else}
+function SDL_GetNumAudioDrivers: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumAudioDrivers' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Use this function to get the name of a built in audio driver.
+ *
+ * The list of audio drivers is given in the order that they are normally
+ * initialized by default; the drivers that seem more reasonable to choose
+ * first (as far as the SDL developers believe) are earlier in the list.
+ *
+ * The names of drivers are all simple, low-ASCII identifiers, like "alsa",
+ * "coreaudio" or "xaudio2". These never have Unicode characters, and are not
+ * meant to be proper names.
+ *
+ * \param index the index of the audio driver; the value ranges from 0 to
+ * SDL_GetNumAudioDrivers() - 1
+ * \returns the name of the audio driver at the requested index, or NULL if an
+ * invalid index was specified.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetNumAudioDrivers
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetAudioDriver_func = function(index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetAudioDriver : TSDL_GetAudioDriver_func = Nil;
+{$else}
+
+function SDL_GetAudioDriver(index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDriver' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Initialization and cleanup
+ *
+ * These functions are used internally, and should not be used unless
+ * you have a specific need to specify the audio driver you want to
+ * use. You should normally use SDL_Init() or SDL_InitSubSystem().
+ *}
+
+{**
+ * Use this function to initialize a particular audio driver.
+ *
+ * This function is used internally, and should not be used unless you have a
+ * specific need to designate the audio driver you want to use. You should
+ * normally use SDL_Init() or SDL_InitSubSystem().
+ *
+ * \param driver_name the name of the desired audio driver
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AudioQuit
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioInit_func = function(driver_name: PAnsiChar): cint; cdecl;
+Var
+ SDL_AudioInit : TSDL_AudioInit_func = Nil;
+{$else}
+
+function SDL_AudioInit(driver_name: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioInit' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Use this function to shut down audio if you initialized it with
+ * SDL_AudioInit().
+ *
+ * This function is used internally, and should not be used unless you have a
+ * specific need to specify the audio driver you want to use. You should
+ * normally use SDL_Quit() or SDL_QuitSubSystem().
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AudioInit
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioQuit_proc = procedure ; cdecl;
+Var
+ SDL_AudioQuit : TSDL_AudioQuit_proc = Nil;
+{$else}
+procedure SDL_AudioQuit; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioQuit' {$ENDIF} {$ENDIF};
+{$endif}
+ {**
+ * Get the name of the current audio driver.
+ *
+ * The returned string points to internal static memory and thus never becomes
+ * invalid, even if you quit the audio subsystem and initialize a new driver
+ * (although such a case would return a different static string from another
+ * call to this function, of course). As such, you should not modify or free
+ * the returned string.
+ *
+ * \returns the name of the current audio driver or NULL if no driver has been
+ * initialized.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AudioInit
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetCurrentAudioDriver_func = function : PAnsiChar; cdecl;
+Var
+ SDL_GetCurrentAudioDriver : TSDL_GetCurrentAudioDriver_func = Nil;
+{$else}
+function SDL_GetCurrentAudioDriver: PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCurrentAudioDriver' {$ENDIF} {$ENDIF};
+{$endif}
+{**
+ * This function is a legacy means of opening the audio device.
+ *
+ * This function remains for compatibility with SDL 1.2, but also because it's
+ * slightly easier to use than the new functions in SDL 2.0. The new, more
+ * powerful, and preferred way to do this is SDL_OpenAudioDevice().
+ *
+ * This function is roughly equivalent to:
+ *
+ * ```c
+ * SDL_OpenAudioDevice(NULL, 0, desired, obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
+ * ```
+ *
+ * With two notable exceptions:
+ *
+ * - If `obtained` is NULL, we use `desired` (and allow no changes), which
+ * means desired will be modified to have the correct values for silence,
+ * etc, and SDL will convert any differences between your app's specific
+ * request and the hardware behind the scenes.
+ * - The return value is always success or failure, and not a device ID, which
+ * means you can only have one device open at a time with this function.
+ *
+ * \param desired an SDL_AudioSpec structure representing the desired output
+ * format. Please refer to the SDL_OpenAudioDevice
+ * documentation for details on how to prepare this structure.
+ * \param obtained an SDL_AudioSpec structure filled in with the actual
+ * parameters, or NULL.
+ * \returns 0 if successful, placing the actual hardware parameters in the
+ * structure pointed to by `obtained`.
+ *
+ * If `obtained` is NULL, the audio data passed to the callback
+ * function will be guaranteed to be in the requested format, and
+ * will be automatically converted to the actual hardware audio
+ * format if necessary. If `obtained` is NULL, `desired` will have
+ * fields modified.
+ *
+ * This function returns a negative error code on failure to open the
+ * audio device or failure to set up the audio thread; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CloseAudio
+ * \sa SDL_LockAudio
+ * \sa SDL_PauseAudio
+ * \sa SDL_UnlockAudio
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_OpenAudio_func = function(desired: PSDL_AudioSpec; obtained: PSDL_AudioSpec): cint; cdecl;
+Var
+ SDL_OpenAudio : TSDL_OpenAudio_func = Nil;
+{$else}
+
+function SDL_OpenAudio(desired: PSDL_AudioSpec; obtained: PSDL_AudioSpec): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * SDL Audio Device IDs.
+ *
+ * A successful call to SDL_OpenAudio() is always device id 1, and legacy
+ * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls
+ * always returns devices >= 2 on success. The legacy calls are good both
+ * for backwards compatibility and when you don't care about multiple,
+ * specific, or capture devices.
+ *}
+type
+ PPSDL_AudioDeviceID = ^PSDL_AudioDeviceID;
+ PSDL_AudioDeviceID = ^TSDL_AudioDeviceID;
+ TSDL_AudioDeviceID = cuint32;
+
+{**
+ * Get the number of built-in audio devices.
+ *
+ * This function is only valid after successfully initializing the audio
+ * subsystem.
+ *
+ * Note that audio capture support is not implemented as of SDL 2.0.4, so the
+ * `iscapture` parameter is for future expansion and should always be zero for
+ * now.
+ *
+ * This function will return -1 if an explicit list of devices can't be
+ * determined. Returning -1 is not an error. For example, if SDL is set up to
+ * talk to a remote audio server, it can't list every one available on the
+ * Internet, but it will still allow a specific host to be specified in
+ * SDL_OpenAudioDevice().
+ *
+ * In many common cases, when this function returns a value <= 0, it can still
+ * successfully open the default device (NULL for first argument of
+ * SDL_OpenAudioDevice()).
+ *
+ * This function may trigger a complete redetect of available hardware. It
+ * should not be called for each iteration of a loop, but rather once at the
+ * start of a loop:
+ *
+ * ```c
+ * // Don't do this:
+ * for (int i = 0; i < SDL_GetNumAudioDevices(0); i++)
+ *
+ * // do this instead:
+ * const int count = SDL_GetNumAudioDevices(0);
+ * for (int i = 0; i < count; ++i) do_something_here();
+ * ```
+ *
+ * \param iscapture zero to request playback devices, non-zero to request
+ * recording devices
+ * \returns the number of available devices exposed by the current driver or
+ * -1 if an explicit list of devices can't be determined. A return
+ * value of -1 does not necessarily mean an error condition.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetAudioDeviceName
+ * \sa SDL_OpenAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumAudioDevices_func = function(iscapture: cint): cint; cdecl;
+Var
+ SDL_GetNumAudioDevices : TSDL_GetNumAudioDevices_func = Nil;
+{$else}
+
+function SDL_GetNumAudioDevices(iscapture: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumAudioDevices' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the human-readable name of a specific audio device.
+ *
+ * This function is only valid after successfully initializing the audio
+ * subsystem. The values returned by this function reflect the latest call to
+ * SDL_GetNumAudioDevices(); re-call that function to redetect available
+ * hardware.
+ *
+ * The string returned by this function is UTF-8 encoded, read-only, and
+ * managed internally. You are not to free it. If you need to keep the string
+ * for any length of time, you should make your own copy of it, as it will be
+ * invalid next time any of several other SDL functions are called.
+ *
+ * \param index the index of the audio device; valid values range from 0 to
+ * SDL_GetNumAudioDevices() - 1
+ * \param iscapture non-zero to query the list of recording devices, zero to
+ * query the list of output devices.
+ * \returns the name of the audio device at the requested index, or NULL on
+ * error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetNumAudioDevices
+ * \sa SDL_GetDefaultAudioInfo
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetAudioDeviceName_func = function(index: cint; iscapture: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetAudioDeviceName : TSDL_GetAudioDeviceName_func = Nil;
+{$else}
+
+function SDL_GetAudioDeviceName(index: cint; iscapture: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the preferred audio format of a specific audio device.
+ *
+ * This function is only valid after a successfully initializing the audio
+ * subsystem. The values returned by this function reflect the latest call to
+ * SDL_GetNumAudioDevices(); re-call that function to redetect available
+ * hardware.
+ *
+ * `spec` will be filled with the sample rate, sample format, and channel
+ * count.
+ *
+ * \param index the index of the audio device; valid values range from 0 to
+ * SDL_GetNumAudioDevices() - 1
+ * \param iscapture non-zero to query the list of recording devices, zero to
+ * query the list of output devices.
+ * \param spec The SDL_AudioSpec to be initialized by this function.
+ * \returns 0 on success, nonzero on error
+ *
+ * \since This function is available since SDL 2.0.16.
+ *
+ * \sa SDL_GetNumAudioDevices
+ * \sa SDL_GetDefaultAudioInfo
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetAudioDeviceSpec_func = function(index: cint; iscapture: cint; spec: PSDL_AudioSpec): cint; cdecl;
+Var
+ SDL_GetAudioDeviceSpec : TSDL_GetAudioDeviceSpec_func = Nil;
+{$else}
+
+function SDL_GetAudioDeviceSpec(index: cint; iscapture: cint; spec: PSDL_AudioSpec): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceSpec' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the name and preferred format of the default audio device.
+ *
+ * Some (but not all!) platforms have an isolated mechanism to get information
+ * about the "default" device. This can actually be a completely different
+ * device that's not in the list you get from SDL_GetAudioDeviceSpec(). It can
+ * even be a network address! (This is discussed in SDL_OpenAudioDevice().)
+ *
+ * As a result, this call is not guaranteed to be performant, as it can query
+ * the sound server directly every time, unlike the other query functions. You
+ * should call this function sparingly!
+ *
+ * `spec` will be filled with the sample rate, sample format, and channel
+ * count, if a default device exists on the system. If `name` is provided,
+ * will be filled with either a dynamically-allocated UTF-8 string or nil.
+ *
+ * \param name A pointer to be filled with the name of the default device (can
+ * be nil). Please call SDL_free() when you are done with this
+ * pointer!
+ * \param spec The SDL_AudioSpec to be initialized by this function.
+ * \param iscapture non-zero to query the default recording device, zero to
+ * query the default output device.
+ * \returns 0 on success, nonzero on error
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GetAudioDeviceName
+ * \sa SDL_GetAudioDeviceSpec
+ * \sa SDL_OpenAudioDevice
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDefaultAudioInfo_func = function(name: PPAnsiChar; spec: PSDL_AudioSpec; iscapture: cint): cint; cdecl;
+Var
+ SDL_GetDefaultAudioInfo : TSDL_GetDefaultAudioInfo_func = Nil;
+{$else}
+
+function SDL_GetDefaultAudioInfo(name: PPAnsiChar; spec: PSDL_AudioSpec; iscapture: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDefaultAudioInfo' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Open a specific audio device.
+ *
+ * SDL_OpenAudio(), unlike this function, always acts on device ID 1. As such,
+ * this function will never return a 1 so as not to conflict with the legacy
+ * function.
+ *
+ * Please note that SDL 2.0 before 2.0.5 did not support recording; as such,
+ * this function would fail if `iscapture` was not zero. Starting with SDL
+ * 2.0.5, recording is implemented and this value can be non-zero.
+ *
+ * Passing in a `device` name of NULL requests the most reasonable default
+ * (and is equivalent to what SDL_OpenAudio() does to choose a device). The
+ * `device` name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but
+ * some drivers allow arbitrary and driver-specific strings, such as a
+ * hostname/IP address for a remote audio server, or a filename in the
+ * diskaudio driver.
+ *
+ * An opened audio device starts out paused, and should be enabled for playing
+ * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio
+ * callback function to be called. Since the audio driver may modify the
+ * requested size of the audio buffer, you should allocate any local mixing
+ * buffers after you open the audio device.
+ *
+ * The audio callback runs in a separate thread in most cases; you can prevent
+ * race conditions between your callback and other threads without fully
+ * pausing playback with SDL_LockAudioDevice(). For more information about the
+ * callback, see SDL_AudioSpec.
+ *
+ * Managing the audio spec via 'desired' and 'obtained':
+ *
+ * When filling in the desired audio spec structure:
+ *
+ * - `desired->freq` should be the frequency in sample-frames-per-second (Hz).
+ * - `desired->format` should be the audio format (`AUDIO_S16SYS`, etc).
+ * - `desired->samples` is the desired size of the audio buffer, in _sample
+ * frames_ (with stereo output, two samples--left and right--would make a
+ * single sample frame). This number should be a power of two, and may be
+ * adjusted by the audio driver to a value more suitable for the hardware.
+ * Good values seem to range between 512 and 8096 inclusive, depending on
+ * the application and CPU speed. Smaller values reduce latency, but can
+ * lead to underflow if the application is doing heavy processing and cannot
+ * fill the audio buffer in time. Note that the number of sample frames is
+ * directly related to time by the following formula: `ms =
+ * (sampleframes*1000)/freq`
+ * - `desired->size` is the size in _bytes_ of the audio buffer, and is
+ * calculated by SDL_OpenAudioDevice(). You don't initialize this.
+ * - `desired->silence` is the value used to set the buffer to silence, and is
+ * calculated by SDL_OpenAudioDevice(). You don't initialize this.
+ * - `desired->callback` should be set to a function that will be called when
+ * the audio device is ready for more data. It is passed a pointer to the
+ * audio buffer, and the length in bytes of the audio buffer. This function
+ * usually runs in a separate thread, and so you should protect data
+ * structures that it accesses by calling SDL_LockAudioDevice() and
+ * SDL_UnlockAudioDevice() in your code. Alternately, you may pass a NULL
+ * pointer here, and call SDL_QueueAudio() with some frequency, to queue
+ * more audio samples to be played (or for capture devices, call
+ * SDL_DequeueAudio() with some frequency, to obtain audio samples).
+ * - `desired->userdata` is passed as the first parameter to your callback
+ * function. If you passed a NULL callback, this value is ignored.
+ *
+ * `allowed_changes` can have the following flags OR'd together:
+ *
+ * - `SDL_AUDIO_ALLOW_FREQUENCY_CHANGE`
+ * - `SDL_AUDIO_ALLOW_FORMAT_CHANGE`
+ * - `SDL_AUDIO_ALLOW_CHANNELS_CHANGE`
+ * - `SDL_AUDIO_ALLOW_SAMPLES_CHANGE`
+ * - `SDL_AUDIO_ALLOW_ANY_CHANGE`
+ *
+ * These flags specify how SDL should behave when a device cannot offer a
+ * specific feature. If the application requests a feature that the hardware
+ * doesn't offer, SDL will always try to get the closest equivalent.
+ *
+ * For example, if you ask for float32 audio format, but the sound card only
+ * supports int16, SDL will set the hardware to int16. If you had set
+ * SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL will change the format in the `obtained`
+ * structure. If that flag was *not* set, SDL will prepare to convert your
+ * callback's float32 audio to int16 before feeding it to the hardware and
+ * will keep the originally requested format in the `obtained` structure.
+ *
+ * The resulting audio specs, varying depending on hardware and on what
+ * changes were allowed, will then be written back to `obtained`.
+ *
+ * If your application can only handle one specific data format, pass a zero
+ * for `allowed_changes` and let SDL transparently handle any differences.
+ *
+ * \param device a UTF-8 string reported by SDL_GetAudioDeviceName() or a
+ * driver-specific name as appropriate. NULL requests the most
+ * reasonable default device.
+ * \param iscapture non-zero to specify a device should be opened for
+ * recording, not playback
+ * \param desired an SDL_AudioSpec structure representing the desired output
+ * format; see SDL_OpenAudio() for more information
+ * \param obtained an SDL_AudioSpec structure filled in with the actual output
+ * format; see SDL_OpenAudio() for more information
+ * \param allowed_changes 0, or one or more flags OR'd together
+ * \returns a valid device ID that is > 0 on success or 0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * For compatibility with SDL 1.2, this will never return 1, since
+ * SDL reserves that ID for the legacy SDL_OpenAudio() function.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CloseAudioDevice
+ * \sa SDL_GetAudioDeviceName
+ * \sa SDL_LockAudioDevice
+ * \sa SDL_OpenAudio
+ * \sa SDL_PauseAudioDevice
+ * \sa SDL_UnlockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_OpenAudioDevice_func = function(device: PAnsiChar;
+ iscapture: cint;
+ desired: PSDL_AudioSpec;
+ obtained: PSDL_AudioSpec;
+ allowed_changes: cint): TSDL_AudioDeviceID; cdecl;
+Var
+ SDL_OpenAudioDevice : TSDL_OpenAudioDevice_func = Nil;
+{$else}
+
+function SDL_OpenAudioDevice(device: PAnsiChar;
+ iscapture: cint;
+ desired: PSDL_AudioSpec;
+ obtained: PSDL_AudioSpec;
+ allowed_changes: cint): TSDL_AudioDeviceID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenAudioDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Audio state
+ *
+ * Get the current audio state.
+ *}
+
+type
+ PPSDL_AudioStatus = ^PSDL_AudioStatus;
+ PSDL_AudioStatus = ^TSDL_AudioStatus;
+ TSDL_AudioStatus = type cint;
+
+const
+ SDL_AUDIO_STOPPED = TSDL_AudioStatus(0);
+ SDL_AUDIO_PLAYING = TSDL_AudioStatus(1);
+ SDL_AUDIO_PAUSED = TSDL_AudioStatus(2);
+
+{**
+ * This function is a legacy means of querying the audio device.
+ *
+ * New programs might want to use SDL_GetAudioDeviceStatus() instead. This
+ * function is equivalent to calling...
+ *
+ * ```c
+ * SDL_GetAudioDeviceStatus(1);
+ * ```
+ *
+ * ...and is only useful if you used the legacy SDL_OpenAudio() function.
+ *
+ * \returns the SDL_AudioStatus of the audio device opened by SDL_OpenAudio().
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetAudioDeviceStatus
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetAudioStatus_func = function : TSDL_AudioStatus; cdecl;
+ Var
+ SDL_GetAudioStatus : TSDL_GetAudioStatus_func = Nil;
+ {$else}
+ function SDL_GetAudioStatus: TSDL_AudioStatus; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStatus' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Use this function to get the current audio state of an audio device.
+ *
+ * \param dev the ID of an audio device previously opened with
+ * SDL_OpenAudioDevice()
+ * \returns the SDL_AudioStatus of the specified audio device.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_PauseAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetAudioDeviceStatus_func = function(dev: TSDL_AudioDeviceID): TSDL_AudioStatus; cdecl;
+Var
+ SDL_GetAudioDeviceStatus : TSDL_GetAudioDeviceStatus_func = Nil;
+{$else}
+
+function SDL_GetAudioDeviceStatus(dev: TSDL_AudioDeviceID): TSDL_AudioStatus; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceStatus' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*Audio State*}
+
+ {**
+ * Pause audio functions
+ *
+ * These functions pause and unpause the audio callback processing.
+ * They should be called with a parameter of 0 after opening the audio
+ * device to start playing sound. This is so you can safely initialize
+ * data for your callback function after opening the audio device.
+ * Silence will be written to the audio device during the pause.
+ *}
+
+{**
+ * This function is a legacy means of pausing the audio device.
+ *
+ * New programs might want to use SDL_PauseAudioDevice() instead. This
+ * function is equivalent to calling...
+ *
+ * ```c
+ * SDL_PauseAudioDevice(1, pause_on);
+ * ```
+ *
+ * ...and is only useful if you used the legacy SDL_OpenAudio() function.
+ *
+ * \param pause_on non-zero to pause, 0 to unpause
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetAudioStatus
+ * \sa SDL_PauseAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_PauseAudio_proc = procedure(pause_on: cint); cdecl;
+Var
+ SDL_PauseAudio : TSDL_PauseAudio_proc = Nil;
+{$else}
+
+procedure SDL_PauseAudio(pause_on: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PauseAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Use this function to pause and unpause audio playback on a specified
+ * device.
+ *
+ * This function pauses and unpauses the audio callback processing for a given
+ * device. Newly-opened audio devices start in the paused state, so you must
+ * call this function with **pause_on**=0 after opening the specified audio
+ * device to start playing sound. This allows you to safely initialize data
+ * for your callback function after opening the audio device. Silence will be
+ * written to the audio device while paused, and the audio callback is
+ * guaranteed to not be called. Pausing one device does not prevent other
+ * unpaused devices from running their callbacks.
+ *
+ * Pausing state does not stack; even if you pause a device several times, a
+ * single unpause will start the device playing again, and vice versa. This is
+ * different from how SDL_LockAudioDevice() works.
+ *
+ * If you just need to protect a few variables from race conditions vs your
+ * callback, you shouldn't pause the audio device, as it will lead to dropouts
+ * in the audio playback. Instead, you should use SDL_LockAudioDevice().
+ *
+ * \param dev a device opened by SDL_OpenAudioDevice()
+ * \param pause_on non-zero to pause, 0 to unpause
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_PauseAudioDevice_proc = procedure(dev: TSDL_AudioDeviceID; pause_on: cint); cdecl;
+Var
+ SDL_PauseAudioDevice : TSDL_PauseAudioDevice_proc = Nil;
+{$else}
+
+procedure SDL_PauseAudioDevice(dev: TSDL_AudioDeviceID; pause_on: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PauseAudioDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*Pause audio functions*}
+
+ {**
+ * Load the audio data of a WAVE file into memory.
+ *
+ * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to
+ * be valid pointers. The entire data portion of the file is then loaded into
+ * memory and decoded if necessary.
+ *
+ * If `freesrc` is non-zero, the data source gets automatically closed and
+ * freed before the function returns.
+ *
+ * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and
+ * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and
+ * A-law and mu-law (8 bits). Other formats are currently unsupported and
+ * cause an error.
+ *
+ * If this function succeeds, the pointer returned by it is equal to `spec`
+ * and the pointer to the audio data allocated by the function is written to
+ * `audio_buf` and its length in bytes to `audio_len`. The SDL_AudioSpec
+ * members `freq`, `channels`, and `format` are set to the values of the audio
+ * data in the buffer. The `samples` member is set to a sane default and all
+ * others are set to zero.
+ *
+ * It's necessary to use SDL_FreeWAV() to free the audio data returned in
+ * `audio_buf` when it is no longer used.
+ *
+ * Because of the underspecification of the .WAV format, there are many
+ * problematic files in the wild that cause issues with strict decoders. To
+ * provide compatibility with these files, this decoder is lenient in regards
+ * to the truncation of the file, the fact chunk, and the size of the RIFF
+ * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`,
+ * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to
+ * tune the behavior of the loading process.
+ *
+ * Any file that is invalid (due to truncation, corruption, or wrong values in
+ * the headers), too big, or unsupported causes an error. Additionally, any
+ * critical I/O error from the data source will terminate the loading process
+ * with an error. The function returns NULL on error and in all cases (with
+ * the exception of `src` being NULL), an appropriate error message will be
+ * set.
+ *
+ * It is required that the data source supports seeking.
+ *
+ * Example:
+ *
+ * ```c
+ * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, &spec, &buf, &len);
+ * ```
+ *
+ * Note that the SDL_LoadWAV macro does this same thing for you, but in a less
+ * messy way:
+ *
+ * ```c
+ * SDL_LoadWAV("sample.wav", &spec, &buf, &len);
+ * ```
+ *
+ * \param src The data source for the WAVE data
+ * \param freesrc If non-zero, SDL will _always_ free the data source
+ * \param spec An SDL_AudioSpec that will be filled in with the wave file's
+ * format details
+ * \param audio_buf A pointer filled with the audio data, allocated by the
+ * function.
+ * \param audio_len A pointer filled with the length of the audio data buffer
+ * in bytes
+ * \returns This function, if successfully called, returns `spec`, which will
+ * be filled with the audio data format of the wave source data.
+ * `audio_buf` will be filled with a pointer to an allocated buffer
+ * containing the audio data, and `audio_len` is filled with the
+ * length of that audio buffer in bytes.
+ *
+ * This function returns NULL if the .WAV file cannot be opened, uses
+ * an unknown data format, or is corrupt; call SDL_GetError() for
+ * more information.
+ *
+ * When the application is done with the data returned in
+ * `audio_buf`, it should call SDL_FreeWAV() to dispose of it.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_FreeWAV
+ * \sa SDL_LoadWAV
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadWAV_RW_func = function(src: PSDL_RWops;
+ freesrc: cint;
+ spec: PSDL_AudioSpec;
+ audio_buf: ppcuint8;
+ audio_len: pcuint32): PSDL_AudioSpec; cdecl;
+Var
+ SDL_LoadWAV_RW : TSDL_LoadWAV_RW_func = Nil;
+{$else}
+
+function SDL_LoadWAV_RW(src: PSDL_RWops;
+ freesrc: cint;
+ spec: PSDL_AudioSpec;
+ audio_buf: ppcuint8;
+ audio_len: pcuint32): PSDL_AudioSpec; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadWAV_RW' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Loads a WAV from a file.
+ * Compatibility convenience function.
+ *}
+function SDL_LoadWAV(file_: PAnsiChar; spec: PSDL_AudioSpec; audio_buf: ppcuint8; audio_len: pcuint32): PSDL_AudioSpec;
+
+{**
+ * Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW().
+ *
+ * After a WAVE file has been opened with SDL_LoadWAV() or SDL_LoadWAV_RW()
+ * its data can eventually be freed with SDL_FreeWAV(). It is safe to call
+ * this function with a NULL pointer.
+ *
+ * \param audio_buf a pointer to the buffer created by SDL_LoadWAV() or
+ * SDL_LoadWAV_RW()
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadWAV
+ * \sa SDL_LoadWAV_RW
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeWAV_proc = procedure(audio_buf: pcuint8); cdecl;
+Var
+ SDL_FreeWAV : TSDL_FreeWAV_proc = Nil;
+{$else}
+
+procedure SDL_FreeWAV(audio_buf: pcuint8); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeWAV' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Initialize an SDL_AudioCVT structure for conversion.
+ *
+ * Before an SDL_AudioCVT structure can be used to convert audio data it must
+ * be initialized with source and destination information.
+ *
+ * This function will zero out every field of the SDL_AudioCVT, so it must be
+ * called before the application fills in the final buffer information.
+ *
+ * Once this function has returned successfully, and reported that a
+ * conversion is necessary, the application fills in the rest of the fields in
+ * SDL_AudioCVT, now that it knows how large a buffer it needs to allocate,
+ * and then can call SDL_ConvertAudio() to complete the conversion.
+ *
+ * \param cvt an SDL_AudioCVT structure filled in with audio conversion
+ * information
+ * \param src_format the source format of the audio data; for more info see
+ * SDL_AudioFormat
+ * \param src_channels the number of channels in the source
+ * \param src_rate the frequency (sample-frames-per-second) of the source
+ * \param dst_format the destination format of the audio data; for more info
+ * see SDL_AudioFormat
+ * \param dst_channels the number of channels in the destination
+ * \param dst_rate the frequency (sample-frames-per-second) of the destination
+ * \returns 1 if the audio filter is prepared, 0 if no conversion is needed,
+ * or a negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_ConvertAudio
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_BuildAudioCVT_func = function(cvt: PSDL_AudioCVT;
+ src_format: TSDL_AudioFormat;
+ src_channels: cuint8;
+ src_rate: cint;
+ dst_format: TSDL_AudioFormat;
+ dst_channels: cuint8;
+ dst_rate: cint): cint; cdecl;
+Var
+ SDL_BuildAudioCVT : TSDL_BuildAudioCVT_func = Nil;
+{$else}
+
+function SDL_BuildAudioCVT(cvt: PSDL_AudioCVT;
+ src_format: TSDL_AudioFormat;
+ src_channels: cuint8;
+ src_rate: cint;
+ dst_format: TSDL_AudioFormat;
+ dst_channels: cuint8;
+ dst_rate: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_BuildAudioCVT' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Convert audio data to a desired audio format.
+ *
+ * This function does the actual audio data conversion, after the application
+ * has called SDL_BuildAudioCVT() to prepare the conversion information and
+ * then filled in the buffer details.
+ *
+ * Once the application has initialized the `cvt` structure using
+ * SDL_BuildAudioCVT(), allocated an audio buffer and filled it with audio
+ * data in the source format, this function will convert the buffer, in-place,
+ * to the desired format.
+ *
+ * The data conversion may go through several passes; any given pass may
+ * possibly temporarily increase the size of the data. For example, SDL might
+ * expand 16-bit data to 32 bits before resampling to a lower frequency,
+ * shrinking the data size after having grown it briefly. Since the supplied
+ * buffer will be both the source and destination, converting as necessary
+ * in-place, the application must allocate a buffer that will fully contain
+ * the data during its largest conversion pass. After SDL_BuildAudioCVT()
+ * returns, the application should set the `cvt->len` field to the size, in
+ * bytes, of the source data, and allocate a buffer that is `cvt->len *
+ * cvt->len_mult` bytes long for the `buf` field.
+ *
+ * The source data should be copied into this buffer before the call to
+ * SDL_ConvertAudio(). Upon successful return, this buffer will contain the
+ * converted audio, and `cvt->len_cvt` will be the size of the converted data,
+ * in bytes. Any bytes in the buffer past `cvt->len_cvt` are undefined once
+ * this function returns.
+ *
+ * \param cvt an SDL_AudioCVT structure that was previously set up by
+ * SDL_BuildAudioCVT().
+ * \returns 0 if the conversion was completed successfully or a negative error
+ * code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_BuildAudioCVT
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ConvertAudio_func = function(cvt: PSDL_AudioCVT): cint; cdecl;
+Var
+ SDL_ConvertAudio : TSDL_ConvertAudio_func = Nil;
+{$else}
+
+function SDL_ConvertAudio(cvt: PSDL_AudioCVT): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+{ SDL_AudioStream is a new audio conversion interface.
+ The benefits vs SDL_AudioCVT:
+ - it can handle resampling data in chunks without generating
+ artifacts, when it doesn't have the complete buffer available.
+ - it can handle incoming data in any variable size.
+ - You push data as you have it, and pull it when you need it
+ }
+{ this is opaque to the outside world. }
+type
+ PSDL_AudioStream = type Pointer;
+
+{*
+ * Create a new audio stream.
+ *
+ * \param src_format The format of the source audio
+ * \param src_channels The number of channels of the source audio
+ * \param src_rate The sampling rate of the source audio
+ * \param dst_format The format of the desired audio output
+ * \param dst_channels The number of channels of the desired audio output
+ * \param dst_rate The sampling rate of the desired audio output
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_AudioStreamClear
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_NewAudioStream_func = function(src_format: TSDL_AudioFormat; src_channels: cuint8; src_rate: cint; dst_format: TSDL_AudioFormat; dst_channels: cuint8;
+ dst_rate: cint): PSDL_AudioStream; cdecl;
+Var
+ SDL_NewAudioStream : TSDL_NewAudioStream_func = Nil;
+{$else}
+
+function SDL_NewAudioStream(src_format: TSDL_AudioFormat; src_channels: cuint8; src_rate: cint; dst_format: TSDL_AudioFormat; dst_channels: cuint8;
+ dst_rate: cint): PSDL_AudioStream; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_NewAudioStream' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Add data to be converted/resampled to the stream.
+ *
+ * \param stream The stream the audio data is being added to
+ * \param buf A pointer to the audio data to add
+ * \param len The number of bytes to write to the stream
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_AudioStreamClear
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioStreamPut_func = function(stream: PSDL_AudioStream; buf: pointer; len: cint): cint; cdecl;
+Var
+ SDL_AudioStreamPut : TSDL_AudioStreamPut_func = Nil;
+{$else}
+
+function SDL_AudioStreamPut(stream: PSDL_AudioStream; buf: pointer; len: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioStreamPut' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get converted/resampled data from the stream
+ *
+ * \param stream The stream the audio is being requested from
+ * \param buf A buffer to fill with audio data
+ * \param len The maximum number of bytes to fill
+ * \returns the number of bytes read from the stream, or -1 on error
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_AudioStreamClear
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioStreamGet_func = function(stream: PSDL_AudioStream; buf: pointer; len: cint): cint; cdecl;
+Var
+ SDL_AudioStreamGet : TSDL_AudioStreamGet_func = Nil;
+{$else}
+
+function SDL_AudioStreamGet(stream: PSDL_AudioStream; buf: pointer; len: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioStreamGet' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the number of converted/resampled bytes available.
+ *
+ * The stream may be buffering data behind the scenes until it has enough to
+ * resample correctly, so this number might be lower than what you expect, or
+ * even be zero. Add more data or flush the stream if you need the data now.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_AudioStreamClear
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioStreamAvailable_func = function(stream: PSDL_AudioStream): cint; cdecl;
+Var
+ SDL_AudioStreamAvailable : TSDL_AudioStreamAvailable_func = Nil;
+{$else}
+
+function SDL_AudioStreamAvailable(stream: PSDL_AudioStream): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioStreamAvailable' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Tell the stream that you're done sending data, and anything being buffered
+ * should be converted/resampled and made available immediately.
+ *
+ * It is legal to add more data to a stream after flushing, but there will be
+ * audio gaps in the output. Generally this is intended to signal the end of
+ * input, so the complete output becomes available.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamClear
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioStreamFlush_func = function(stream: PSDL_AudioStream): cint; cdecl;
+Var
+ SDL_AudioStreamFlush : TSDL_AudioStreamFlush_func = Nil;
+{$else}
+
+function SDL_AudioStreamFlush(stream: PSDL_AudioStream): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioStreamFlush' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Clear any pending data in the stream without converting it
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_FreeAudioStream
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AudioStreamClear_proc = procedure(stream: PSDL_AudioStream); cdecl;
+Var
+ SDL_AudioStreamClear : TSDL_AudioStreamClear_proc = Nil;
+{$else}
+
+procedure SDL_AudioStreamClear(stream: PSDL_AudioStream); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioStreamClear' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Free an audio stream
+ *
+ * \since This function is available since SDL 2.0.7.
+ *
+ * \sa SDL_NewAudioStream
+ * \sa SDL_AudioStreamPut
+ * \sa SDL_AudioStreamGet
+ * \sa SDL_AudioStreamAvailable
+ * \sa SDL_AudioStreamFlush
+ * \sa SDL_AudioStreamClear
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeAudioStream_proc = procedure(stream: PSDL_AudioStream); cdecl;
+Var
+ SDL_FreeAudioStream : TSDL_FreeAudioStream_proc = Nil;
+{$else}
+
+procedure SDL_FreeAudioStream(stream: PSDL_AudioStream); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeAudioStream' {$ENDIF} {$ENDIF};
+{$endif}
+
+const
+ SDL_MIX_MAXVOLUME = 128;
+
+{**
+ * This function is a legacy means of mixing audio.
+ *
+ * This function is equivalent to calling...
+ *
+ * ```c
+ * SDL_MixAudioFormat(dst, src, format, len, volume);
+ * ```
+ *
+ * ...where `format` is the obtained format of the audio device from the
+ * legacy SDL_OpenAudio() function.
+ *
+ * \param dst the destination for the mixed audio
+ * \param src the source audio buffer to be mixed
+ * \param len the length of the audio buffer in bytes
+ * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME
+ * for full audio volume
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_MixAudioFormat
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MixAudio_proc = procedure(dst: pcuint8; src: pcuint8; len: cuint32; volume: cint); cdecl;
+Var
+ SDL_MixAudio : TSDL_MixAudio_proc = Nil;
+{$else}
+
+procedure SDL_MixAudio(dst: pcuint8; src: pcuint8; len: cuint32; volume: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MixAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Mix audio data in a specified format.
+ *
+ * This takes an audio buffer `src` of `len` bytes of `format` data and mixes
+ * it into `dst`, performing addition, volume adjustment, and overflow
+ * clipping. The buffer pointed to by `dst` must also be `len` bytes of
+ * `format` data.
+ *
+ * This is provided for convenience -- you can mix your own audio data.
+ *
+ * Do not use this function for mixing together more than two streams of
+ * sample data. The output from repeated application of this function may be
+ * distorted by clipping, because there is no accumulator with greater range
+ * than the input (not to mention this being an inefficient way of doing it).
+ *
+ * It is a common misconception that this function is required to write audio
+ * data to an output stream in an audio callback. While you can do that,
+ * SDL_MixAudioFormat() is really only needed when you're mixing a single
+ * audio stream with a volume adjustment.
+ *
+ * \param dst the destination for the mixed audio
+ * \param src the source audio buffer to be mixed
+ * \param format the SDL_AudioFormat structure representing the desired audio
+ * format
+ * \param len the length of the audio buffer in bytes
+ * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME
+ * for full audio volume
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MixAudioFormat_proc = procedure(dst: pcuint8; src: pcuint8; format: TSDL_AudioFormat; len: cuint32; volume: cint); cdecl;
+Var
+ SDL_MixAudioFormat : TSDL_MixAudioFormat_proc = Nil;
+{$else}
+
+procedure SDL_MixAudioFormat(dst: pcuint8; src: pcuint8; format: TSDL_AudioFormat; len: cuint32; volume: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MixAudioFormat' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Queue more audio on non-callback devices.
+ *
+ * If you are looking to retrieve queued audio from a non-callback capture
+ * device, you want SDL_DequeueAudio() instead. SDL_QueueAudio() will return
+ * -1 to signify an error if you use it with capture devices.
+ *
+ * SDL offers two ways to feed audio to the device: you can either supply a
+ * callback that SDL triggers with some frequency to obtain more audio (pull
+ * method), or you can supply no callback, and then SDL will expect you to
+ * supply data at regular intervals (push method) with this function.
+ *
+ * There are no limits on the amount of data you can queue, short of
+ * exhaustion of address space. Queued data will drain to the device as
+ * necessary without further intervention from you. If the device needs audio
+ * but there is not enough queued, it will play silence to make up the
+ * difference. This means you will have skips in your audio playback if you
+ * aren't routinely queueing sufficient data.
+ *
+ * This function copies the supplied data, so you are safe to free it when the
+ * function returns. This function is thread-safe, but queueing to the same
+ * device from two threads at once does not promise which buffer will be
+ * queued first.
+ *
+ * You may not queue audio on a device that is using an application-supplied
+ * callback; doing so returns an error. You have to use the audio callback or
+ * queue audio with this function, but not both.
+ *
+ * You should not call SDL_LockAudio() on the device before queueing; SDL
+ * handles locking internally for this function.
+ *
+ * Note that SDL2 does not support planar audio. You will need to resample
+ * from planar audio formats into a non-planar one (see SDL_AudioFormat)
+ * before queuing audio.
+ *
+ * \param dev the device ID to which we will queue audio
+ * \param data the data to queue to the device for later playback
+ * \param len the number of bytes (not samples!) to which `data` points
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_ClearQueuedAudio
+ * \sa SDL_GetQueuedAudioSize
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_QueueAudio_func = function(dev: TSDL_AudioDeviceID; data: Pointer; len: cuint32): cint; cdecl;
+Var
+ SDL_QueueAudio : TSDL_QueueAudio_func = Nil;
+{$else}
+
+function SDL_QueueAudio(dev: TSDL_AudioDeviceID; data: Pointer; len: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_QueueAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Dequeue more audio on non-callback devices.
+ *
+ * If you are looking to queue audio for output on a non-callback playback
+ * device, you want SDL_QueueAudio() instead. SDL_DequeueAudio() will always
+ * return 0 if you use it with playback devices.
+ *
+ * SDL offers two ways to retrieve audio from a capture device: you can either
+ * supply a callback that SDL triggers with some frequency as the device
+ * records more audio data, (push method), or you can supply no callback, and
+ * then SDL will expect you to retrieve data at regular intervals (pull
+ * method) with this function.
+ *
+ * There are no limits on the amount of data you can queue, short of
+ * exhaustion of address space. Data from the device will keep queuing as
+ * necessary without further intervention from you. This means you will
+ * eventually run out of memory if you aren't routinely dequeueing data.
+ *
+ * Capture devices will not queue data when paused; if you are expecting to
+ * not need captured audio for some length of time, use SDL_PauseAudioDevice()
+ * to stop the capture device from queueing more data. This can be useful
+ * during, say, level loading times. When unpaused, capture devices will start
+ * queueing data from that point, having flushed any capturable data available
+ * while paused.
+ *
+ * This function is thread-safe, but dequeueing from the same device from two
+ * threads at once does not promise which thread will dequeue data first.
+ *
+ * You may not dequeue audio from a device that is using an
+ * application-supplied callback; doing so returns an error. You have to use
+ * the audio callback, or dequeue audio with this function, but not both.
+ *
+ * You should not call SDL_LockAudio() on the device before dequeueing; SDL
+ * handles locking internally for this function.
+ *
+ * \param dev the device ID from which we will dequeue audio
+ * \param data a pointer into where audio data should be copied
+ * \param len the number of bytes (not samples!) to which (data) points
+ * \returns the number of bytes dequeued, which could be less than requested;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.5.
+ *
+ * \sa SDL_ClearQueuedAudio
+ * \sa SDL_GetQueuedAudioSize
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DequeueAudio_func = function(dev: TSDL_AudioDeviceID; data: Pointer; len: cuint32): cuint32; cdecl;
+Var
+ SDL_DequeueAudio : TSDL_DequeueAudio_func = Nil;
+{$else}
+
+function SDL_DequeueAudio(dev: TSDL_AudioDeviceID; data: Pointer; len: cuint32): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DequeueAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of bytes of still-queued audio.
+ *
+ * For playback devices: this is the number of bytes that have been queued for
+ * playback with SDL_QueueAudio(), but have not yet been sent to the hardware.
+ *
+ * Once we've sent it to the hardware, this function can not decide the exact
+ * byte boundary of what has been played. It's possible that we just gave the
+ * hardware several kilobytes right before you called this function, but it
+ * hasn't played any of it yet, or maybe half of it, etc.
+ *
+ * For capture devices, this is the number of bytes that have been captured by
+ * the device and are waiting for you to dequeue. This number may grow at any
+ * time, so this only informs of the lower-bound of available data.
+ *
+ * You may not queue or dequeue audio on a device that is using an
+ * application-supplied callback; calling this function on such a device
+ * always returns 0. You have to use the audio callback or queue audio, but
+ * not both.
+ *
+ * You should not call SDL_LockAudio() on the device before querying; SDL
+ * handles locking internally for this function.
+ *
+ * \param dev the device ID of which we will query queued audio size
+ * \returns the number of bytes (not samples!) of queued audio.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_ClearQueuedAudio
+ * \sa SDL_QueueAudio
+ * \sa SDL_DequeueAudio
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetQueuedAudioSize_func = function(dev: TSDL_AudioDeviceID): cuint32; cdecl;
+Var
+ SDL_GetQueuedAudioSize : TSDL_GetQueuedAudioSize_func = Nil;
+{$else}
+
+function SDL_GetQueuedAudioSize(dev: TSDL_AudioDeviceID): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetQueuedAudioSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Drop any queued audio data waiting to be sent to the hardware.
+ *
+ * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For
+ * output devices, the hardware will start playing silence if more audio isn't
+ * queued. For capture devices, the hardware will start filling the empty
+ * queue with new data if the capture device isn't paused.
+ *
+ * This will not prevent playback of queued audio that's already been sent to
+ * the hardware, as we can not undo that, so expect there to be some fraction
+ * of a second of audio that might still be heard. This can be useful if you
+ * want to, say, drop any pending music or any unprocessed microphone input
+ * during a level change in your game.
+ *
+ * You may not queue or dequeue audio on a device that is using an
+ * application-supplied callback; calling this function on such a device
+ * always returns 0. You have to use the audio callback or queue audio, but
+ * not both.
+ *
+ * You should not call SDL_LockAudio() on the device before clearing the
+ * queue; SDL handles locking internally for this function.
+ *
+ * This function always succeeds and thus returns void.
+ *
+ * \param dev the device ID of which to clear the audio queue
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_GetQueuedAudioSize
+ * \sa SDL_QueueAudio
+ * \sa SDL_DequeueAudio
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ClearQueuedAudio_proc = procedure(dev: TSDL_AudioDeviceID); cdecl;
+Var
+ SDL_ClearQueuedAudio : TSDL_ClearQueuedAudio_proc = Nil;
+{$else}
+
+procedure SDL_ClearQueuedAudio(dev: TSDL_AudioDeviceID); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearQueuedAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Audio lock functions
+ *
+ * The lock manipulated by these functions protects the callback function.
+ * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that
+ * the callback function is not running. Do not call these from the callback
+ * function or you will cause deadlock.
+ *}
+
+{**
+ * This function is a legacy means of locking the audio device.
+ *
+ * New programs might want to use SDL_LockAudioDevice() instead. This function
+ * is equivalent to calling...
+ *
+ * ```c
+ * SDL_LockAudioDevice(1);
+ * ```
+ *
+ * ...and is only useful if you used the legacy SDL_OpenAudio() function.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LockAudioDevice
+ * \sa SDL_UnlockAudio
+ * \sa SDL_UnlockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockAudio_proc = procedure ; cdecl;
+Var
+ SDL_LockAudio : TSDL_LockAudio_proc = Nil;
+{$else}
+procedure SDL_LockAudio; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockAudio' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Use this function to lock out the audio callback function for a specified
+ * device.
+ *
+ * The lock manipulated by these functions protects the audio callback
+ * function specified in SDL_OpenAudioDevice(). During a
+ * SDL_LockAudioDevice()/SDL_UnlockAudioDevice() pair, you can be guaranteed
+ * that the callback function for that device is not running, even if the
+ * device is not paused. While a device is locked, any other unpaused,
+ * unlocked devices may still run their callbacks.
+ *
+ * Calling this function from inside your audio callback is unnecessary. SDL
+ * obtains this lock before calling your function, and releases it when the
+ * function returns.
+ *
+ * You should not hold the lock longer than absolutely necessary. If you hold
+ * it too long, you'll experience dropouts in your audio playback. Ideally,
+ * your application locks the device, sets a few variables and unlocks again.
+ * Do not do heavy work while holding the lock for a device.
+ *
+ * It is safe to lock the audio device multiple times, as long as you unlock
+ * it an equivalent number of times. The callback will not run until the
+ * device has been unlocked completely in this way. If your application fails
+ * to unlock the device appropriately, your callback will never run, you might
+ * hear repeating bursts of audio, and SDL_CloseAudioDevice() will probably
+ * deadlock.
+ *
+ * Internally, the audio device lock is a mutex; if you lock from two threads
+ * at once, not only will you block the audio callback, you'll block the other
+ * thread.
+ *
+ * \param dev the ID of the device to be locked
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_UnlockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockAudioDevice_proc = procedure(dev: TSDL_AudioDeviceID); cdecl;
+Var
+ SDL_LockAudioDevice : TSDL_LockAudioDevice_proc = Nil;
+{$else}
+
+procedure SDL_LockAudioDevice(dev: TSDL_AudioDeviceID); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockAudioDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function is a legacy means of unlocking the audio device.
+ *
+ * New programs might want to use SDL_UnlockAudioDevice() instead. This
+ * function is equivalent to calling...
+ *
+ * ```c
+ * SDL_UnlockAudioDevice(1);
+ * ```
+ *
+ * ...and is only useful if you used the legacy SDL_OpenAudio() function.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LockAudio
+ * \sa SDL_UnlockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnlockAudio_proc = procedure ; cdecl;
+Var
+ SDL_UnlockAudio : TSDL_UnlockAudio_proc = Nil;
+{$else}
+procedure SDL_UnlockAudio; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Unlock' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Use this function to unlock the audio callback function for a specified
+ * device.
+ *
+ * This function should be paired with a previous SDL_LockAudioDevice() call.
+ *
+ * \param dev the ID of the device to be unlocked
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LockAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnlockAudioDevice_proc = procedure(dev: TSDL_AudioDeviceID); cdecl;
+Var
+ SDL_UnlockAudioDevice : TSDL_UnlockAudioDevice_proc = Nil;
+{$else}
+
+procedure SDL_UnlockAudioDevice(dev: TSDL_AudioDeviceID); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockAudioDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*Audio lock functions*}
+
+{**
+ * This function is a legacy means of closing the audio device.
+ *
+ * This function is equivalent to calling...
+ *
+ * ```c
+ * SDL_CloseAudioDevice(1);
+ * ```
+ *
+ * ...and is only useful if you used the legacy SDL_OpenAudio() function.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_OpenAudio
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CloseAudio_proc = procedure ; cdecl;
+Var
+ SDL_CloseAudio : TSDL_CloseAudio_proc = Nil;
+{$else}
+procedure SDL_CloseAudio; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseAudio' {$ENDIF} {$ENDIF};
+{$endif}
+{**
+ * Use this function to shut down audio processing and close the audio device.
+ *
+ * The application should close open audio devices once they are no longer
+ * needed. Calling this function will wait until the device's audio callback
+ * is not running, release the audio hardware and then clean up internal
+ * state. No further audio will play from this device once this function
+ * returns.
+ *
+ * This function may block briefly while pending audio data is played by the
+ * hardware, so that applications don't drop the last buffer of data they
+ * supplied.
+ *
+ * The device ID is invalid as soon as the device is closed, and is eligible
+ * for reuse in a new SDL_OpenAudioDevice() call immediately.
+ *
+ * \param dev an audio device previously opened with SDL_OpenAudioDevice()
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_OpenAudioDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CloseAudioDevice_proc = procedure(dev: TSDL_AudioDeviceID); cdecl;
+Var
+ SDL_CloseAudioDevice : TSDL_CloseAudioDevice_proc = Nil;
+{$else}
+
+procedure SDL_CloseAudioDevice(dev: TSDL_AudioDeviceID); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseAudioDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlblendmode.inc b/units/sdl2_for_pascal/sdlblendmode.inc
new file mode 100644
index 0000000..c4ea1b3
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlblendmode.inc
@@ -0,0 +1,90 @@
+//from "sdl_blendmode.h"
+
+{**
+ * The blend mode used in SDL_RenderCopy() and drawing operations.
+ *}
+
+type
+ PPSDL_BlendMode = ^PSDL_BlendMode;
+ PSDL_BlendMode = ^TSDL_BlendMode;
+ TSDL_BlendMode = type DWord;
+
+const
+ SDL_BLENDMODE_NONE = TSDL_BlendMode($00000000); {**< no blending
+ dstRGBA = srcRGBA *}
+ SDL_BLENDMODE_BLEND = TSDL_BlendMode($00000001); {**< alpha blending
+ dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
+ dstA = srcA + (dstA * (1-srcA)) *}
+ SDL_BLENDMODE_ADD = TSDL_BlendMode($00000002); {**< additive blending
+ dstRGB = (srcRGB * srcA) + dstRGB
+ dstA = dstA *}
+ SDL_BLENDMODE_MOD = TSDL_BlendMode($00000004); {**< color modulate
+ dstRGB = srcRGB * dstRGB
+ dstA = dstA *}
+ SDL_BLENDMODE_MUL = TSDL_BlendMode($00000008); {**< color multiply
+ dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA))
+ dstA = (srcA * dstA) + (dstA * (1-srcA)) *}
+ SDL_BLENDMODE_INVALID = TSDL_BlendMode($7FFFFFFF); { }
+
+ {* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() *}
+
+ {**
+ * \brief The blend operation used when combining source and destination pixel components
+ *}
+type
+ PPSDL_BlendOperation = ^PSDL_BlendOperation;
+ PSDL_BlendOperation = ^TSDL_BlendOperation;
+ TSDL_BlendOperation = type DWord;
+
+const
+ SDL_BLENDOPERATION_ADD = TSDL_BlendOperation($1); {**< dst + src: supported by all renderers *}
+ SDL_BLENDOPERATION_SUBTRACT = TSDL_BlendOperation($2); {**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES}
+ SDL_BLENDOPERATION_REV_SUBTRACT = TSDL_BlendOperation($3); {**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES}
+ SDL_BLENDOPERATION_MINIMUM = TSDL_BlendOperation($4); {**< min(dst, src) : supported by D3D11 *}
+ SDL_BLENDOPERATION_MAXIMUM = TSDL_BlendOperation($5); {**< max(dst, src) : supported by D3D11 *}
+
+ {**
+ * \brief The normalized factor used to multiply pixel components
+ *}
+type
+ PPSDL_BlendFactor = ^PSDL_BlendFactor;
+ PSDL_BlendFactor = ^TSDL_BlendFactor;
+ TSDL_BlendFactor = type DWord;
+
+const
+ SDL_BLENDFACTOR_ZERO = TSDL_BlendFactor($1); {**< 0, 0, 0, 0 *}
+ SDL_BLENDFACTOR_ONE = TSDL_BlendFactor($2); {**< 1, 1, 1, 1 *}
+ SDL_BLENDFACTOR_SRC_COLOR = TSDL_BlendFactor($3); {**< srcR, srcG, srcB, srcA *}
+ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = TSDL_BlendFactor($4); {**< 1-srcR, 1-srcG, 1-srcB, 1-srcA *}
+ SDL_BLENDFACTOR_SRC_ALPHA = TSDL_BlendFactor($5); {**< srcA, srcA, srcA, srcA *}
+ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = TSDL_BlendFactor($6); {**< 1-srcA, 1-srcA, 1-srcA, 1-srcA *}
+ SDL_BLENDFACTOR_DST_COLOR = TSDL_BlendFactor($7); {**< dstR, dstG, dstB, dstA *}
+ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = TSDL_BlendFactor($8); {**< 1-dstR, 1-dstG, 1-dstB, 1-dstA *}
+ SDL_BLENDFACTOR_DST_ALPHA = TSDL_BlendFactor($9); {**< dstA, dstA, dstA, dstA *}
+ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = TSDL_BlendFactor($A); {**< 1-dstA, 1-dstA, 1-dstA, 1-dstA *}
+
+{**
+ * \brief Create a custom blend mode, which may or may not be supported by a given renderer
+ *
+ * \param srcColorFactor source color factor
+ * \param dstColorFactor destination color factor
+ * \param colorOperation color operation
+ * \param srcAlphaFactor source alpha factor
+ * \param dstAlphaFactor destination alpha factor
+ * \param alphaOperation alpha operation
+ *
+ * The result of the blend mode operation will be:
+ * dstRGB = dstRGB * dstColorFactor colorOperation srcRGB * srcColorFactor
+ * and
+ * dstA = dstA * dstAlphaFactor alphaOperation srcA * srcAlphaFactor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ComposeCustomBlendMode_func = function(srcColorFactor, dstColorFactor: TSDL_BlendFactor; colorOperation: TSDL_BlendOperation; srcAlphaFactor, dstAlphaFactor: TSDL_BlendFactor; alphaOperation: TSDL_BlendOperation): TSDL_BlendMode; cdecl;
+Var
+ SDL_ComposeCustomBlendMode : TSDL_ComposeCustomBlendMode_func = Nil;
+{$else}
+
+function SDL_ComposeCustomBlendMode(srcColorFactor, dstColorFactor: TSDL_BlendFactor; colorOperation: TSDL_BlendOperation; srcAlphaFactor, dstAlphaFactor: TSDL_BlendFactor; alphaOperation: TSDL_BlendOperation): TSDL_BlendMode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ComposeCustomBlendMode' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlclipboard.inc b/units/sdl2_for_pascal/sdlclipboard.inc
new file mode 100644
index 0000000..b38b579
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlclipboard.inc
@@ -0,0 +1,153 @@
+
+{*
+ * \file SDL_clipboard.h
+ *
+ * Include file for SDL clipboard handling
+ }
+
+{* Function prototypes *}
+
+{*
+ * Put UTF-8 text into the clipboard.
+ *
+ * \param text the text to store in the clipboard
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetClipboardText
+ * \sa SDL_HasClipboardText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetClipboardText_func = function(text: PAnsiChar): cint; cdecl;
+Var
+ SDL_SetClipboardText : TSDL_SetClipboardText_func = Nil;
+{$else}
+
+function SDL_SetClipboardText(text: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetClipboardText' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get UTF-8 text from the clipboard, which must be freed with SDL_free().
+ *
+ * This functions returns empty string if there was not enough memory left for
+ * a copy of the clipboard's content.
+ *
+ * \returns the clipboard text on success or an empty string on failure; call
+ * SDL_GetError() for more information. Caller must call SDL_free()
+ * on the returned pointer when done with it (even if there was an
+ * error).
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HasClipboardText
+ * \sa SDL_SetClipboardText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetClipboardText_func = function(): PAnsiChar; cdecl;
+Var
+ SDL_GetClipboardText : TSDL_GetClipboardText_func = Nil;
+{$else}
+
+function SDL_GetClipboardText(): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetClipboardText' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Query whether the clipboard exists and contains a non-empty text string.
+ *
+ * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetClipboardText
+ * \sa SDL_SetClipboardText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasClipboardText_func = function(): TSDL_bool; cdecl;
+Var
+ SDL_HasClipboardText : TSDL_HasClipboardText_func = Nil;
+{$else}
+
+function SDL_HasClipboardText(): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasClipboardText' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Put UTF-8 text into the primary selection.
+ *
+ * \param text the text to store in the primary selection
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.26.1.
+ *
+ * \sa SDL_GetPrimarySelectionText
+ * \sa SDL_HasPrimarySelectionText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetPrimarySelectionText_func = function(text: PAnsiChar): cint; cdecl;
+Var
+ SDL_SetPrimarySelectionText : TSDL_SetPrimarySelectionText_func = Nil;
+{$else}
+
+function SDL_SetPrimarySelectionText(text: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetPrimarySelectionText' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get UTF-8 text from the primary selection, which must be freed with
+ * SDL_free().
+ *
+ * This functions returns empty string if there was not enough memory left for
+ * a copy of the primary selection's content.
+ *
+ * \returns the primary selection text on success or an empty string on
+ * failure; call SDL_GetError() for more information. Caller must
+ * call SDL_free() on the returned pointer when done with it (even if
+ * there was an error).
+ *
+ * \since This function is available since SDL 2.26.1.
+ *
+ * \sa SDL_HasPrimarySelectionText
+ * \sa SDL_SetPrimarySelectionText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPrimarySelectionText_func = function(): PAnsiChar; cdecl;
+Var
+ SDL_GetPrimarySelectionText : TSDL_GetPrimarySelectionText_func = Nil;
+{$else}
+
+function SDL_GetPrimarySelectionText(): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPrimarySelectionText' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Query whether the primary selection exists and contains a non-empty text
+ * string.
+ *
+ * \returns SDL_TRUE if the primary selection has text, or SDL_FALSE if it
+ * does not.
+ *
+ * \since This function is available since SDL 2.26.1.
+ *
+ * \sa SDL_GetPrimarySelectionText
+ * \sa SDL_SetPrimarySelectionText
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasPrimarySelectionText_func = function(): TSDL_bool; cdecl;
+Var
+ SDL_HasPrimarySelectionText : TSDL_HasPrimarySelectionText_func = Nil;
+{$else}
+
+function SDL_HasPrimarySelectionText(): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasPrimarySelectionText' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlcpuinfo.inc b/units/sdl2_for_pascal/sdlcpuinfo.inc
new file mode 100644
index 0000000..30062a9
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlcpuinfo.inc
@@ -0,0 +1,227 @@
+
+{*
+ * This is a guess for the cacheline size used for padding.
+ * Most x86 processors have a 64 byte cache line.
+ * The 64-bit PowerPC processors have a 128 byte cache line.
+ * We'll use the larger value to be generally safe.
+ *}
+const
+ SDL_CACHELINE_SIZE = 128;
+
+{**
+ * This function returns the number of CPU cores available.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetCPUCount_func = function(): cint; cdecl;
+Var
+ SDL_GetCPUCount : TSDL_GetCPUCount_func = Nil;
+{$else}
+
+function SDL_GetCPUCount(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCPUCount' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * This function returns the L1 cache line size of the CPU.
+ *
+ * This is useful for determining multi-threaded structure padding
+ * or SIMD prefetch sizes.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+function SDL_GetCPUCacheLineSize(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCPUCacheLineSize' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has the RDTSC instruction.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasRDTSC(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasRDTSC' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has AltiVec features.
+ *
+ * This always returns false on CPUs that aren't using PowerPC
+ * instruction sets.
+ *}
+function SDL_HasAltiVec(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAltiVec' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has MMX features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasMMX(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasMMX' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has 3DNow! features.
+ *
+ * This always returns false on CPUs that aren't using AMD instruction sets.
+ *}
+function SDL_Has3DNow(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Has3DNow' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has SSE features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasSSE(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has SSE2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasSSE2(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE2' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has SSE3 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasSSE3(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE3' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has SSE4.1 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasSSE41(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE41' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has SSE4.2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasSSE42(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE42' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has AVX features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasAVX(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAVX' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns true if the CPU has AVX2 features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasAVX2(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAVX2' {$ENDIF} {$ENDIF};
+
+{**
+ * Determine whether the CPU has AVX-512F (foundation) features.
+ *
+ * This always returns false on CPUs that aren't using Intel instruction sets.
+ *}
+function SDL_HasAVX512F(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAVX512F' {$ENDIF} {$ENDIF};
+
+{**
+ * Determine whether the CPU has ARM SIMD (ARMv6) features.
+ * This is different from ARM NEON, which is a different instruction set.
+ *
+ * This always returns false on CPUs that aren't using ARM instruction sets.
+ *}
+function SDL_HasARMSIMD(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasARMSIMD' {$ENDIF} {$ENDIF};
+
+{**
+ * Determine whether the CPU has NEON (ARM SIMD) features.
+ *
+ * This always returns false on CPUs that aren't using ARM instruction sets.
+ *}
+function SDL_HasNEON(): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasNEON' {$ENDIF} {$ENDIF};
+
+{**
+ * This function returns the amount of RAM configured in the system, in MB.
+ *}
+function SDL_GetSystemRAM(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSystemRAM' {$ENDIF} {$ENDIF};
+
+{**
+ * Report the alignment this system needs for SIMD allocations.
+ *
+ * This will return the minimum number of bytes to which a pointer must be
+ * aligned to be compatible with SIMD instructions on the current machine. For
+ * example, if the machine supports SSE only, it will return 16, but if it
+ * supports AVX-512F, it'll return 64 (etc). This only reports values for
+ * instruction sets SDL knows about, so if your SDL build doesn't have
+ * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and
+ * not 64 for the AVX-512 instructions that exist but SDL doesn't know about.
+ * Plan accordingly.
+ *}
+function SDL_SIMDGetAlignment(): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SIMDGetAlignment' {$ENDIF} {$ENDIF};
+
+{*
+ * Allocate memory in a SIMD-friendly way.
+ *
+ * This will allocate a block of memory that is suitable for use with SIMD
+ * instructions. Specifically, it will be properly aligned and padded for the
+ * system's supported vector instructions.
+ *
+ * The memory returned will be padded such that it is safe to read or write an
+ * incomplete vector at the end of the memory block. This can be useful so you
+ * don't have to drop back to a scalar fallback at the end of your SIMD
+ * processing loop to deal with the final elements without overflowing the
+ * allocated buffer.
+ *
+ * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free().
+ *
+ * Note that SDL will only deal with SIMD instruction sets it is aware of; for
+ * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and
+ * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants
+ * 64. To be clear: if you can't decide to use an instruction set with an
+ * SDL_Has*() function, don't use that instruction set with memory allocated
+ * through here.
+ *
+ * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't
+ * out of memory, but you are not allowed to dereference it (because you only
+ * own zero bytes of that buffer).
+ *}
+function SDL_SIMDAlloc(const len: csize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SIMDAlloc' {$ENDIF} {$ENDIF};
+
+{**
+ * Reallocate memory obtained from SDL_SIMDAlloc.
+ *
+ * It is not valid to use this function on a pointer from anything but
+ * SDL_SIMDAlloc(). It can't be used on pointers from SDL_malloc, GetMem, etc.
+ *}
+function SDL_SIMDRealloc(mem: Pointer; const len: csize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SIMDRealloc' {$ENDIF} {$ENDIF};
+
+{**
+ * Deallocate memory obtained from SDL_SIMDAlloc.
+ *
+ * It is not valid to use this function on a pointer from anything but
+ * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from
+ * SDL_malloc, GetMem, etc.
+ *
+ * However, SDL_SIMDFree(NIL) is a legal no-op.
+ *
+ * The memory pointed to by `mem` is no longer valid for access upon return,
+ * and may be returned to the system or reused by a future allocation. The
+ * pointer passed to this function is no longer safe to dereference once this
+ * function returns, and should be discarded.
+ *}
+procedure SDL_SIMDFree(mem: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SIMDFree' {$ENDIF} {$ENDIF};
+
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlerror.inc b/units/sdl2_for_pascal/sdlerror.inc
new file mode 100644
index 0000000..b06f393
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlerror.inc
@@ -0,0 +1,116 @@
+// based on "sdl_error.h" (2.0.14)
+
+{**
+ * \file SDL_error.h
+ *
+ * Simple error message routines for SDL.
+ *}
+
+{* Public functions *}
+
+ {**
+ * \brief Set the error message for the current thread
+ *
+ * \return -1, there is no error handling for this function
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetError_func = function(const fmt: PAnsiChar; args: array of const): cint; cdecl;
+Var
+ SDL_SetError : TSDL_SetError_func = Nil;
+{$else}
+
+function SDL_SetError(const fmt: PAnsiChar; args: array of const): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetError' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the last error message that was set
+ *
+ * SDL API functions may set error messages and then succeed, so you should
+ * only use the error value if a function fails.
+ *
+ * This returns a pointer to a static buffer for convenience and should not
+ * be called by multiple threads simultaneously.
+ *
+ * \return a pointer to the last error message that was set
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetError_func = function (): PAnsiChar; cdecl;
+Var
+ SDL_GetError : TSDL_GetError_func = Nil;
+{$else}
+function SDL_GetError: PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetError' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the last error message that was set for the current thread
+ *
+ * SDL API functions may set error messages and then succeed, so you should
+ * only use the error value if a function fails.
+ *
+ * \param errstr A buffer to fill with the last error message that was set
+ * for the current thread
+ * \param maxlen The size of the buffer pointed to by the errstr parameter
+ *
+ * \return errstr
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetErrorMsg_func = function(const errstr: PAnsiChar; maxlen: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetErrorMsg : TSDL_GetErrorMsg_func = Nil;
+{$else}
+
+function SDL_GetErrorMsg(const errstr: PAnsiChar; maxlen: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetErrorMsg' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Clear the error message for the current thread
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ClearError_proc = procedure () cdecl;
+Var
+ SDL_ClearError : TSDL_ClearError_proc = Nil;
+{$else}
+procedure SDL_ClearError cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearError' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*Internal error functions*}
+{**
+ * Internal error functions
+ *
+ * Private error reporting function - used internally.
+ *}
+ {
+#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM)
+#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED)
+#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param))
+ }
+
+
+type
+ PPSDL_ErrorCode = ^PSDL_ErrorCode;
+ PSDL_ErrorCode = ^TSDL_ErrorCode;
+ TSDL_ErrorCode = (SDL_ENOMEM,
+ SDL_EFREAD,
+ SDL_EFWRITE,
+ SDL_EFSEEK,
+ SDL_UNSUPPORTED,
+ SDL_LASTERROR);
+
+{* SDL_Error() unconditionally returns -1. *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Error_func = function(code: TSDL_ErrorCode): cint; cdecl;
+Var
+ SDL_Error : TSDL_Error_func = Nil;
+{$else}
+
+function SDL_Error(code: TSDL_ErrorCode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Error' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlevents.inc b/units/sdl2_for_pascal/sdlevents.inc
new file mode 100644
index 0000000..82e8dba
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlevents.inc
@@ -0,0 +1,897 @@
+//from "sdl_events.h"
+
+type
+ PPSDL_EventType = ^PSDL_EventType;
+ PSDL_EventType = ^TSDL_EventType;
+ TSDL_EventType = type cuint32;
+
+ {**
+ * The types of events that can be delivered.
+ *}
+const
+
+ { General keyboard/mouse state definitions }
+ SDL_RELEASED = 0;
+ SDL_PRESSED = 1;
+
+ SDL_FIRSTEVENT = TSDL_EventType(0); // Unused (do not remove) (needed in pascal?)
+
+ SDL_COMMONEVENT = TSDL_EventType(1); //added for pascal-compatibility
+
+ { Application events }
+ SDL_QUITEV = TSDL_EventType($100); // User-requested quit (originally SDL_QUIT, but changed, cause theres a method called SDL_QUIT)
+
+
+ { These application events have special meaning on iOS, see README.iOS for details *}
+
+ {* The application is being terminated by the OS. *
+ * Called on iOS in applicationWillTerminate() *
+ * Called on Android in onDestroy() *}
+ SDL_APP_TERMINATING = TSDL_EventType($101);
+
+ {* The application is low on memory, free memory if possible. *
+ * Called on iOS in applicationDidReceiveMemoryWarning() *
+ * Called on Android in onLowMemory() *}
+ SDL_APP_LOWMEMORY = TSDL_EventType($102);
+
+ {* The application is about to enter the background. *
+ * Called on iOS in applicationWillResignActive() *
+ * Called on Android in onPause() *}
+ SDL_APP_WILLENTERBACKGROUND = TSDL_EventType($103);
+
+ {* The application did enter the background and may not get CPU for some time. *
+ * Called on iOS in applicationDidEnterBackground() *
+ * Called on Android in onPause() *}
+ SDL_APP_DIDENTERBACKGROUND = TSDL_EventType($104);
+
+ {* The application is about to enter the foreground. *
+ * Called on iOS in applicationWillEnterForeground() *
+ * Called on Android in onResume() *}
+ SDL_APP_WILLENTERFOREGROUND = TSDL_EventType($105);
+
+ {* The application is now interactive. *
+ * Called on iOS in applicationDidBecomeActive() *
+ * Called on Android in onResume() *}
+ SDL_APP_DIDENTERFOREGROUND = TSDL_EventType($106);
+
+ {* The user's locale preferences have changed. *}
+ SDL_LOCALECHANGED = TSDL_EventType($107);
+
+ { Display events }
+ SDL_DISPLAYEVENT = TSDL_EventType($150); // Display state change
+
+ { Window events }
+ SDL_WINDOWEVENT = TSDL_EventType($200); // Window state change
+ SDL_SYSWMEVENT = TSDL_EventType($201); // System specific event
+
+ { Keyboard events }
+ SDL_KEYDOWN = TSDL_EventType($300); // Key pressed
+ SDL_KEYUP = TSDL_EventType($301); // Key released
+ SDL_TEXTEDITING = TSDL_EventType($302); // Keyboard text editing (composition)
+ SDL_TEXTINPUT = TSDL_EventType($303); // Keyboard text input
+ SDL_KEYMAPCHANGED = TSDL_EventType($304); // Keymap changed due to a system event such as an input language or keyboard layout change.
+ SDL_TEXTEDITING_EXT = TSDL_EventType($305); // Extended keyboard text editing (composition)
+
+ { Mouse events }
+ SDL_MOUSEMOTION = TSDL_EventType($400); // Mouse moved
+ SDL_MOUSEBUTTONDOWN = TSDL_EventType($401); // Mouse button pressed
+ SDL_MOUSEBUTTONUP = TSDL_EventType($402); // Mouse button released
+ SDL_MOUSEWHEEL = TSDL_EventType($403); // Mouse wheel motion
+
+ { Joystick events }
+ SDL_JOYAXISMOTION = TSDL_EventType($600); // Joystick axis motion
+ SDL_JOYBALLMOTION = TSDL_EventType($601); // Joystick trackball motion
+ SDL_JOYHATMOTION = TSDL_EventType($602); // Joystick hat position change
+ SDL_JOYBUTTONDOWN = TSDL_EventType($603); // Joystick button pressed
+ SDL_JOYBUTTONUP = TSDL_EventType($604); // Joystick button released
+ SDL_JOYDEVICEADDED = TSDL_EventType($605); // A new joystick has been inserted into the system
+ SDL_JOYDEVICEREMOVED = TSDL_EventType($606); // An opened joystick has been removed
+ SDL_JOYBATTERYUPDATED = TSDL_EventType($607); // Joystick battery level change
+
+ { Game controller events }
+ SDL_CONTROLLERAXISMOTION = TSDL_EventType($650); // Game controller axis motion
+ SDL_CONTROLLERBUTTONDOWN = TSDL_EventType($651); // Game controller button pressed
+ SDL_CONTROLLERBUTTONUP = TSDL_EventType($652); // Game controller button released
+ SDL_CONTROLLERDEVICEADDED = TSDL_EventType($653); // A new Game controller has been inserted into the system
+ SDL_CONTROLLERDEVICEREMOVED = TSDL_EventType($654); // An opened Game controller has been removed
+ SDL_CONTROLLERDEVICEREMAPPED = TSDL_EventType($655); // The controller mapping was updated
+ SDL_CONTROLLERTOUCHPADDOWN = TSDL_EventType($666); // Game controller touchpad was touched
+ SDL_CONTROLLERTOUCHPADMOTION = TSDL_EventType($667); // Game controller touchpad finger was moved
+ SDL_CONTROLLERTOUCHPADUP = TSDL_EventType($668); // Game controller touchpad finger was lifted
+ SDL_CONTROLLERSENSORUPDATE = TSDL_EventType($669); // Game controller sensor was updated
+
+ { Touch events }
+ SDL_FINGERDOWN = TSDL_EventType($700);
+ SDL_FINGERUP = TSDL_EventType($701);
+ SDL_FINGERMOTION = TSDL_EventType($702);
+
+ { Gesture events }
+ SDL_DOLLARGESTURE = TSDL_EventType($800);
+ SDL_DOLLARRECORD = TSDL_EventType($801);
+ SDL_MULTIGESTURE = TSDL_EventType($802);
+
+ { Clipboard events }
+ SDL_CLIPBOARDUPDATE = TSDL_EventType($900); // The clipboard changed
+
+ { Drag and drop events }
+ SDL_DROPFILE = TSDL_EventType($1000); // The system requests a file open
+ SDL_DROPTEXT = TSDL_EventType($1001); // text/plain drag-and-drop event
+ SDL_DROPBEGIN = TSDL_EventType($1002); // A new set of drops is beginning (NULL filename)
+ SDL_DROPCOMPLETE = TSDL_EventType($1003); // Current set of drops is now complete (NULL filename)
+
+ { Audio hotplug events }
+ SDL_AUDIODEVICEADDED = TSDL_EventType($1100); // A new audio device is available
+ SDL_AUDIODEVICEREMOVED = TSDL_EventType($1101); // An audio device has been removed.
+
+ { Sensor events }
+ SDL_SENSORUPDATED = TSDL_EventType($1200); // A sensor was updated
+
+ { Render events }
+ SDL_RENDER_TARGETS_RESET = TSDL_EventType($2000); // The render targets have been reset
+ SDL_RENDER_DEVICE_RESET = TSDL_EventType($2001); // The device has been reset and all textures need to be recreated
+
+ { Internal events }
+ SDL_POLLSENTINEL = TSDL_EventType($7F00); // Signals the end of an event poll cycle
+
+ {** Events SDL_USEREVENT through SDL_LASTEVENT are for your use,
+ * and should be allocated with SDL_RegisterEvents()
+ *}
+ SDL_USEREVENT = TSDL_EventType($8000);
+
+ {**
+ * This last event is only for bounding internal arrays (needed in pascal ??)
+ *}
+ SDL_LASTEVENT = TSDL_EventType($FFFF);
+
+type
+ {**
+ * Fields shared by every event
+ *}
+ PPSDL_CommonEvent = ^PSDL_CommonEvent;
+ PSDL_CommonEvent = ^TSDL_CommonEvent;
+ TSDL_CommonEvent = record
+ type_: cuint32;
+ timestamp: cuint32;
+ end;
+
+ {**
+ * Display state change event data (event.display.*)
+ *}
+ PPSDL_DisplayEvent = ^PSDL_DisplayEvent;
+ PSDL_DisplayEvent = ^TSDL_DisplayEvent;
+ TSDL_DisplayEvent = record
+ type_: cuint32; // SDL_DISPLAYEVENT
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ display: cuint32; // The associated display index
+ event: cuint8; // SDL_DisplayEventID
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ data1: cint32; // event dependent data
+ end;
+
+ {**
+ * Window state change event data (event.window.*)
+ *}
+ PPSDL_WindowEvent = ^PSDL_WindowEvent;
+ PSDL_WindowEvent = ^TSDL_WindowEvent;
+ TSDL_WindowEvent = record
+ type_: cuint32; // SDL_WINDOWEVENT
+ timestamp: cuint32;
+ windowID: cuint32; // The associated window
+ event: cuint8; // SDL_WindowEventID
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ data1: cint32; // event dependent data
+ data2: cint32; // event dependent data
+ end;
+
+ {**
+ * Keyboard button event structure (event.key.*)
+ *}
+ PPSDL_KeyboardEvent = ^PSDL_KeyboardEvent;
+ PSDL_KeyboardEvent = ^TSDL_KeyboardEvent;
+ TSDL_KeyboardEvent = record
+ type_: cuint32; // SDL_KEYDOWN or SDL_KEYUP
+ timestamp: cuint32;
+ windowID: cuint32; // The window with keyboard focus, if any
+ state: cuint8; // SDL_PRESSED or SDL_RELEASED
+ repeat_: cuint8; // Non-zero if this is a key repeat
+ padding2: cuint8;
+ padding3: cuint8;
+ keysym: TSDL_KeySym; // The key that was pressed or released
+ end;
+
+const
+ SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32;
+
+type
+ {**
+ * Keyboard text editing event structure (event.edit.*)
+ *}
+ PPSDL_TextEditingEvent = ^PSDL_TextEditingEvent;
+ PSDL_TextEditingEvent = ^TSDL_TextEditingEvent;
+ TSDL_TextEditingEvent = record
+ type_: cuint32; // SDL_TEXTEDITING
+ timestamp: cuint32;
+ windowID: cuint32; // The window with keyboard focus, if any
+ text: array[0..SDL_TEXTEDITINGEVENT_TEXT_SIZE - 1] of Char; // The editing text
+ start: cint32; // The start cursor of selected editing text
+ length: cint32; // The length of selected editing text
+ end;
+
+ {**
+ * Extended keyboard text editing event structure (event.editExt.*) when text would be
+ * truncated if stored in the text buffer SDL_TextEditingEvent
+ *}
+ PPSDL_TextEditingExtEvent = ^PSDL_TextEditingExtEvent;
+ PSDL_TextEditingExtEvent = ^TSDL_TextEditingExtEvent;
+ TSDL_TextEditingExtEvent = record
+ type_: cuint32; // SDL_TEXTEDITING_EXT
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ windowID: cuint32; // The window with keyboard focus, if any
+ text: PAnsiChar; // The editing text, which should be freed with SDL_free(), and will not be NIL
+ start: cint32; // The start cursor of selected editing text
+ length: cint32; // The length of selected editing text
+ end;
+
+const
+ SDL_TEXTINPUTEVENT_TEXT_SIZE = 32;
+
+type
+
+ {**
+ * Keyboard text input event structure (event.text.*)
+ *}
+ PPSDL_TextInputEvent = ^PSDL_TextInputEvent;
+ PSDL_TextInputEvent = ^TSDL_TextInputEvent;
+ TSDL_TextInputEvent = record
+ type_: cuint32; // SDL_TEXTINPUT
+ timestamp: cuint32;
+ windowID: cuint32; // The window with keyboard focus, if any
+ text: array[0..SDL_TEXTINPUTEVENT_TEXT_SIZE - 1] of Char; // The input text
+ end;
+
+ {**
+ * Mouse motion event structure (event.motion.*)
+ *}
+ PPSDL_MouseMotionEvent = ^PSDL_MouseMotionEvent;
+ PSDL_MouseMotionEvent = ^TSDL_MouseMotionEvent;
+ TSDL_MouseMotionEvent = record
+ type_: cuint32; // SDL_MOUSEMOTION
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ windowID: cuint32; // The window with mouse focus, if any
+ which: cuint32; // The mouse instance id, or SDL_TOUCH_MOUSEID
+ state: cuint32; // The current button state
+ x: cint32; // X coordinate, relative to window
+ y: cint32; // Y coordinate, relative to window
+ xrel: cint32; // The relative motion in the X direction
+ yrel: cint32; // The relative motion in the Y direction
+ end;
+
+ {**
+ * Mouse button event structure (event.button.*)
+ *}
+ PPSDL_MouseButtonEvent = ^PSDL_MouseButtonEvent;
+ PSDL_MouseButtonEvent = ^TSDL_MouseButtonEvent;
+ TSDL_MouseButtonEvent = record
+ type_: cuint32; // SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
+ timestamp: cuint32;
+ windowID: cuint32; // The window with mouse focus, if any
+ which: cuint32; // The mouse instance id, or SDL_TOUCH_MOUSEID
+ button: cuint8; // The mouse button index
+ state: cuint8; // SDL_PRESSED or SDL_RELEASED
+ clicks: cuint8; // 1 for single-click, 2 for double-click, etc.
+ padding1: cuint8;
+ x: cint32; // X coordinate, relative to window
+ y: cint32; // Y coordinate, relative to window
+ end;
+
+ {**
+ * Mouse wheel event structure (event.wheel.*)
+ *}
+ PPSDL_MouseWheelEvent = ^PSDL_MouseWheelEvent;
+ PSDL_MouseWheelEvent = ^TSDL_MouseWheelEvent;
+ TSDL_MouseWheelEvent = record
+ type_: cuint32; // SDL_MOUSEWHEEL
+ timestamp: cuint32;
+ windowID: cuint32; // The window with mouse focus, if any
+ which: cuint32; // The mouse instance id, or SDL_TOUCH_MOUSEID
+ x: cint32; // The amount scrolled horizontally
+ y: cint32; // The amount scrolled vertically
+ direction: cuint32; // Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back
+ preciseX: cfloat; // The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18)
+ preciseY: cfloat; // The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18)
+ mouseX: cint32; // X coordinate, relative to window (added in 2.26.0)
+ mouseY: cint32; // Y coordinate, relative to window (added in 2.26.0)
+ end;
+
+ {**
+ * Joystick axis motion event structure (event.jaxis.*)
+ *}
+ PPSDL_JoyAxisEvent = ^PSDL_JoyAxisEvent;
+ PSDL_JoyAxisEvent = ^TSDL_JoyAxisEvent;
+ TSDL_JoyAxisEvent = record
+ type_: cuint32; // SDL_JOYAXISMOTION
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ axis: cuint8; // The joystick axis index
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ value: cint16; // The axis value (range: -32768 to 32767)
+ padding4: cuint16;
+ end;
+
+ {**
+ * Joystick trackball motion event structure (event.jball.*)
+ *}
+ PPSDL_JoyBallEvent = ^PSDL_JoyBallEvent;
+ PSDL_JoyBallEvent = ^TSDL_JoyBallEvent;
+ TSDL_JoyBallEvent = record
+ type_: cuint32; // SDL_JOYBALLMOTION
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ ball: cuint8; // The joystick trackball index
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ xrel: cint16; // The relative motion in the X direction
+ yrel: cint16; // The relative motion in the Y direction
+ end;
+
+ {**
+ * Joystick hat position change event structure (event.jhat.*)
+ *}
+ PPSDL_JoyHatEvent = ^PSDL_JoyHatEvent;
+ PSDL_JoyHatEvent = ^TSDL_JoyHatEvent;
+ TSDL_JoyHatEvent = record
+ type_: cuint32; // SDL_JOYHATMOTION
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ hat: cuint8; // The joystick hat index
+ value: cuint8; {* The hat position value.
+ * SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP
+ * SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT
+ * SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN
+ *
+ * Note that zero means the POV is centered.
+ *}
+ padding1: cuint8;
+ padding2: cuint8;
+ end;
+
+ {**
+ * Joystick button event structure (event.jbutton.*)
+ *}
+ PPSDL_JoyButtonEvent = ^PSDL_JoyButtonEvent;
+ PSDL_JoyButtonEvent = ^TSDL_JoyButtonEvent;
+ TSDL_JoyButtonEvent = record
+ type_: cuint32; // SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ button: cuint8; // The joystick button index
+ state: cuint8; // SDL_PRESSED or SDL_RELEASED
+ padding1: cuint8;
+ padding2: cuint8;
+ end;
+
+ {**
+ * Joystick device event structure (event.jdevice.*)
+ *}
+ PPSDL_JoyDeviceEvent = ^PSDL_JoyDeviceEvent;
+ PSDL_JoyDeviceEvent = ^TSDL_JoyDeviceEvent;
+ TSDL_JoyDeviceEvent = record
+ type_: cuint32; // SDL_JOYDEVICEADDED or SDL_JOYDEVICEREMOVED
+ timestamp: cuint32;
+ which: cint32; // The joystick device index for the ADDED event, instance id for the REMOVED event
+ end;
+
+ {**
+ * Joysick battery level change event structure (event.jbattery.*)
+ *}
+ PPSDL_JoyBatteryEvent = ^PSDL_JoyBatteryEvent;
+ PSDL_JoyBatteryEvent = ^TSDL_JoyBatteryEvent;
+ TSDL_JoyBatteryEvent = record
+ type_: cuint32; // SDL_JOYBATTERYUPDATED
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ which: TSDL_JoystickID; // The joystick instance id
+ level: TSDL_JoystickPowerLevel; // The joystick battery level
+ end;
+
+ {**
+ * Game controller axis motion event structure (event.caxis.*)
+ *}
+ PPSDL_ControllerAxisEvent = ^PSDL_ControllerAxisEvent;
+ PSDL_ControllerAxisEvent = ^TSDL_ControllerAxisEvent;
+ TSDL_ControllerAxisEvent = record
+ type_: cuint32; // SDL_CONTROLLERAXISMOTION
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ axis: cuint8; // The controller axis (SDL_GameControllerAxis)
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ value: cint16; // The axis value (range: -32768 to 32767)
+ padding4: cuint16;
+ end;
+
+ {**
+ * Game controller button event structure (event.cbutton.*)
+ *}
+ PPSDL_ControllerButtonEvent = ^PSDL_ControllerButtonEvent;
+ PSDL_ControllerButtonEvent = ^TSDL_ControllerButtonEvent;
+ TSDL_ControllerButtonEvent = record
+ type_: cuint32; // SDL_CONTROLLERBUTTONDOWN or SDL_CONTROLLERBUTTONUP
+ timestamp: cuint32;
+ which: TSDL_JoystickID; // The joystick instance id
+ button: cuint8; // The controller button (SDL_GameControllerButton)
+ state: cuint8; // SDL_PRESSED or SDL_RELEASED
+ padding1: cuint8;
+ padding2: cuint8;
+ end;
+
+
+ {**
+ * Controller device event structure (event.cdevice.*)
+ *}
+ PPSDL_ControllerDeviceEvent = ^PSDL_ControllerDeviceEvent;
+ PSDL_ControllerDeviceEvent = ^TSDL_ControllerDeviceEvent;
+ TSDL_ControllerDeviceEvent = record
+ type_: cuint32; // SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, or SDL_CONTROLLERDEVICEREMAPPED
+ timestamp: cuint32;
+ which: cint32; // The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event
+ end;
+
+ {**
+ * Game controller touchpad event structure (event.ctouchpad.*)
+ *}
+ PPSDL_ControllerTouchpadEvent = ^PSDL_ControllerTouchpadEvent;
+ PSDL_ControllerTouchpadEvent = ^TSDL_ControllerTouchpadEvent;
+ TSDL_ControllerTouchpadEvent = record
+ type_: cuint32; // SDL_CONTROLLERTOUCHPADDOWN or SDL_CONTROLLERTOUCHPADMOTION or SDL_CONTROLLERTOUCHPADUP
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ which: TSDL_JoystickID; // The joystick instance id
+ touchpad: cint32; // The index of the touchpad
+ finger: cint32; // The index of the finger on the touchpad
+ x: cfloat; // Normalized in the range 0...1 with 0 being on the left
+ y: cfloat; // Normalized in the range 0...1 with 0 being at the top
+ pressure: cfloat; // Normalized in the range 0...1
+ end;
+
+ {**
+ * Game controller sensor event structure (event.csensor.*)
+ *}
+ PPSDL_ControllerSensorEvent = ^PSDL_ControllerSensorEvent;
+ PSDL_ControllerSensorEvent = ^TSDL_ControllerSensorEvent;
+ TSDL_ControllerSensorEvent = record
+ type_: cuint32; // SDL_CONTROLLERSENSORUPDATE
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ which: TSDL_JoystickID; // The joystick instance id
+ sensor: cint32; // The type of the sensor, one of the values of SDL_SensorType
+ data: array[0..2] of cfloat; // Up to 3 values from the sensor, as defined in SDL_sensor.h
+ end;
+
+ {**
+ * Audio device event structure (event.adevice.*)
+ *}
+ PPSDL_AudioDeviceEvent = ^PSDL_AudioDeviceEvent;
+ PSDL_AudioDeviceEvent = ^TSDL_AudioDeviceEvent;
+ TSDL_AudioDeviceEvent = record
+ type_: cuint32; // ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED
+ timestamp: cuint32;
+ which: cuint32; // The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event
+ iscapture: cuint8; // zero if an output device, non-zero if a capture device.
+ padding1: cuint8;
+ padding2: cuint8;
+ padding3: cuint8;
+ end;
+
+
+ {**
+ * Touch finger event structure (event.tfinger.*)
+ *}
+ PPSDL_TouchFingerEvent = ^PSDL_TouchFingerEvent;
+ PSDL_TouchFingerEvent = ^TSDL_TouchFingerEvent;
+ TSDL_TouchFingerEvent = record
+ type_: cuint32; // SDL_FINGERMOTION or SDL_FINGERDOWN or SDL_FINGERUP
+ timestamp: cuint32;
+ touchId: TSDL_TouchID; // The touch device id
+ fingerId: TSDL_FingerID;
+ x: cfloat; // Normalized in the range 0...1
+ y: cfloat; // Normalized in the range 0...1
+ dx: cfloat; // Normalized in the range 0...1
+ dy: cfloat; // Normalized in the range 0...1
+ pressure: cfloat; // Normalized in the range 0...1
+ window: cuint32; // The window underneath the finger, if any
+ end;
+
+ {**
+ * Multiple Finger Gesture Event (event.mgesture.*)
+ *}
+ PPSDL_MultiGestureEvent = ^PSDL_MultiGestureEvent;
+ PSDL_MultiGestureEvent = ^TSDL_MultiGestureEvent;
+ TSDL_MultiGestureEvent = record
+ type_: cuint32; // SDL_MULTIGESTURE
+ timestamp: cuint32;
+ touchId: TSDL_TouchID; // The touch device index
+ dTheta: cfloat;
+ dDist: cfloat;
+ x: cfloat;
+ y: cfloat;
+ numFingers: cuint16;
+ padding: cuint16;
+ end;
+
+
+ {* (event.dgesture.*) *}
+ PPSDL_DollarGestureEvent = ^PSDL_DollarGestureEvent;
+ PSDL_DollarGestureEvent = ^TSDL_DollarGestureEvent;
+ TSDL_DollarGestureEvent = record
+ type_: cuint32; // SDL_DOLLARGESTURE
+ timestamp: cuint32;
+ touchId: TSDL_TouchID; // The touch device id
+ gestureId: TSDL_GestureID;
+ numFingers: cuint32;
+ error: cfloat;
+ x: cfloat; // Normalized center of gesture
+ y: cfloat; // Normalized center of gesture
+ end;
+
+
+ {**
+ * An event used to request a file open by the system (event.drop.*)
+ * This event is disabled by default, you can enable it with SDL_EventState()
+ * If you enable this event, you must free the filename in the event.
+ *}
+ PPSDL_DropEvent = ^PSDL_DropEvent;
+ PSDL_DropEvent = ^TSDL_DropEvent;
+ TSDL_DropEvent = record
+ type_: cuint32; // SDL_DROPBEGIN or SDL_DROPFILE or SDL_DROPTEXT or SDL_DROPCOMPLETE
+ timestamp: cuint32;
+ file_: PAnsiChar; // The file name, which should be freed with SDL_free(), is NIL on begin/complete
+ windowID: cuint32; // The window that was dropped on, if any
+ end;
+
+ {**
+ * Sensor event structure (event.sensor.*)
+ *}
+ PPSDL_SensorEvent = ^PSDL_SensorEvent;
+ PSDL_SensorEvent = ^TSDL_SensorEvent;
+ TSDL_SensorEvent = record
+ type_: cuint32; // SDL_SENSORUPDATED
+ timestamp: cuint32; // In milliseconds, populated using SDL_GetTicks()
+ which: cint32; // The instance ID of the sensor
+ data: array[0..5] of cfloat; // Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData()
+ end;
+
+ {**
+ * The "quit requested" event
+ *}
+ PPSDL_QuitEvent = ^PSDL_QuitEvent;
+ PSDL_QuitEvent = ^TSDL_QuitEvent;
+ TSDL_QuitEvent = record
+ type_: cuint32; // SDL_QUIT
+ timestamp: cuint32;
+ end;
+
+ {**
+ * A user-defined event type (event.user.*)
+ *}
+ PPSDL_UserEvent = ^PSDL_UserEvent;
+ PSDL_UserEvent = ^TSDL_UserEvent;
+ TSDL_UserEvent = record
+ type_: cuint32; // SDL_USEREVENT through SDL_NUMEVENTS-1
+ timestamp: cuint32;
+ windowID: cuint32; // The associated window if any
+ code: cint32; // User defined event code
+ data1: Pointer; // User defined data pointer
+ data2: Pointer; // User defined data pointer
+ end;
+
+ {**
+ * A video driver dependent system event (event.syswm.*)
+ * This event is disabled by default, you can enable it with SDL_EventState()
+ *
+ * If you want to use this event, you should include SDL_syswm.h.
+ *}
+ PPSDL_SysWMEvent = ^PSDL_SysWMEvent;
+ PSDL_SysWMEvent = ^TSDL_SysWMEvent;
+ TSDL_SysWMEvent = record
+ type_: cuint32; // SDL_SYSWMEVENT
+ timestamp: cuint32;
+ msg: PSDL_SysWMmsg; // driver dependent data (defined in SDL_syswm.h)
+ end;
+
+ {**
+ * General event structure
+ *}
+ PPSDL_Event = ^PSDL_Event;
+ PSDL_Event = ^TSDL_Event;
+ TSDL_Event = record
+ case cint of
+ 0: (type_: cuint32);
+
+ SDL_COMMONEVENT: (common: TSDL_CommonEvent);
+ SDL_DISPLAYEVENT: (display: TSDL_DisplayEvent);
+ SDL_WINDOWEVENT: (window: TSDL_WindowEvent);
+
+ SDL_KEYUP,
+ SDL_KEYDOWN: (key: TSDL_KeyboardEvent);
+ SDL_TEXTEDITING: (edit: TSDL_TextEditingEvent);
+ SDL_TEXTEDITING_EXT: (exitExt: TSDL_TextEditingExtEvent);
+ SDL_TEXTINPUT: (text: TSDL_TextInputEvent);
+
+ SDL_MOUSEMOTION: (motion: TSDL_MouseMotionEvent);
+ SDL_MOUSEBUTTONUP,
+ SDL_MOUSEBUTTONDOWN: (button: TSDL_MouseButtonEvent);
+ SDL_MOUSEWHEEL: (wheel: TSDL_MouseWheelEvent);
+
+ SDL_JOYAXISMOTION: (jaxis: TSDL_JoyAxisEvent);
+ SDL_JOYBALLMOTION: (jball: TSDL_JoyBallEvent);
+ SDL_JOYHATMOTION: (jhat: TSDL_JoyHatEvent);
+ SDL_JOYBUTTONDOWN,
+ SDL_JOYBUTTONUP: (jbutton: TSDL_JoyButtonEvent);
+ SDL_JOYDEVICEADDED,
+ SDL_JOYDEVICEREMOVED: (jdevice: TSDL_JoyDeviceEvent);
+ SDL_JOYBATTERYUPDATED: (jbattery: TSDL_JoyBatteryEvent);
+
+ SDL_CONTROLLERAXISMOTION: (caxis: TSDL_ControllerAxisEvent);
+ SDL_CONTROLLERBUTTONUP,
+ SDL_CONTROLLERBUTTONDOWN: (cbutton: TSDL_ControllerButtonEvent);
+ SDL_CONTROLLERDEVICEADDED,
+ SDL_CONTROLLERDEVICEREMOVED,
+ SDL_CONTROLLERDEVICEREMAPPED: (cdevice: TSDL_ControllerDeviceEvent);
+ SDL_CONTROLLERTOUCHPADDOWN,
+ SDL_CONTROLLERTOUCHPADMOTION,
+ SDL_CONTROLLERTOUCHPADUP: (ctouchpad: TSDL_ControllerTouchpadEvent);
+ SDL_CONTROLLERSENSORUPDATE: (csensor: TSDL_ControllerSensorEvent);
+
+ SDL_AUDIODEVICEADDED,
+ SDL_AUDIODEVICEREMOVED: (adevice: TSDL_AudioDeviceEvent);
+
+ SDL_SENSORUPDATED: (sensor: TSDL_SensorEvent);
+
+ SDL_QUITEV: (quit: TSDL_QuitEvent);
+
+ SDL_USEREVENT: (user: TSDL_UserEvent);
+ SDL_SYSWMEVENT: (syswm: TSDL_SysWMEvent);
+
+ SDL_FINGERDOWN,
+ SDL_FINGERUP,
+ SDL_FINGERMOTION: (tfinger: TSDL_TouchFingerEvent);
+ SDL_MULTIGESTURE: (mgesture: TSDL_MultiGestureEvent);
+ SDL_DOLLARGESTURE,SDL_DOLLARRECORD: (dgesture: TSDL_DollarGestureEvent);
+
+ SDL_DROPFILE: (drop: TSDL_DropEvent);
+ end;
+
+
+ {* Function prototypes *}
+
+ {**
+ * Pumps the event loop, gathering events from the input devices.
+ *
+ * This function updates the event queue and internal input device state.
+ *
+ * This should only be run in the thread that sets the video mode.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_PumpEvents_proc = Procedure (); cdecl;
+ var SDL_PumpEvents: TSDL_PumpEvents_proc = Nil;
+ {$else}
+
+ procedure SDL_PumpEvents cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PumpEvents' {$ENDIF} {$ENDIF};
+ {$endif}
+
+const
+ SDL_ADDEVENT = 0;
+ SDL_PEEKEVENT = 1;
+ SDL_GETEVENT = 2;
+
+type
+ PPSDL_EventAction = ^PSDL_EventAction;
+ PSDL_EventAction = ^TSDL_EventAction;
+ TSDL_EventAction = Word;
+
+ {**
+ * Checks the event queue for messages and optionally returns them.
+ *
+ * If action is SDL_ADDEVENT, up to numevents events will be added to
+ * the back of the event queue.
+ *
+ * If action is SDL_PEEKEVENT, up to numevents events at the front
+ * of the event queue, within the specified minimum and maximum type,
+ * will be returned and will not be removed from the queue.
+ *
+ * If action is SDL_GETEVENT, up to numevents events at the front
+ * of the event queue, within the specified minimum and maximum type,
+ * will be returned and will be removed from the queue.
+ *
+ * Result: The number of events actually stored, or -1 if there was an error.
+ *
+ * This function is thread-safe.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+
+ function SDL_PeepEvents(events: PSDL_Event; numevents: cint32; action: TSDL_EventAction; minType, maxType: TSDL_EventType): cint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PeepEvents' {$ENDIF} {$ENDIF};
+
+ {**
+ * Checks to see if certain event types are in the event queue.
+ *}
+
+ function SDL_HasEvent(type_: TSDL_EventType): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasEvent' {$ENDIF} {$ENDIF};
+ function SDL_HasEvents(minType, maxType: TSDL_EventType): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasEvents' {$ENDIF} {$ENDIF};
+
+ {**
+ * This function clears events from the event queue
+ *}
+
+ procedure SDL_FlushEvent(type_: TSDL_EventType) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlushEvent' {$ENDIF} {$ENDIF};
+ procedure SDL_FlushEvents(minType, maxType: TSDL_EventType) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlushEvents' {$ENDIF} {$ENDIF};
+
+ {**
+ * Polls for currently pending events.
+ *
+ * 1 if there are any pending events, or 0 if there are none available.
+ *
+ * event - If not nil, the next event is removed from the queue and
+ * stored in that area.
+ *}
+ {$endif}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_PollEvent_func = function (event: PSDL_Event): cint32 cdecl;
+ Var
+ SDL_PollEvent : TSDL_PollEvent_func = Nil;
+ {$else}
+ function SDL_PollEvent(event: PSDL_Event): cint32 cdecl;
+external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PollEvent' {$ENDIF} {$ENDIF};
+ {$endif}
+
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+ {**
+ * Waits indefinitely for the next available event.
+ *
+ * 1, or 0 if there was an error while waiting for events.
+ *
+ * event - If not nil, the next event is removed from the queue and
+ * stored in that area.
+ *}
+
+ function SDL_WaitEvent(event: PSDL_Event): cint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitEvent' {$ENDIF} {$ENDIF};
+
+ {**
+ * Waits until the specified timeout (in milliseconds) for the next
+ * available event.
+ *
+ * 1, or 0 if there was an error while waiting for events.
+ *
+ * event - If not nil, the next event is removed from the queue and
+ * stored in that area.
+ *}
+
+ function SDL_WaitEventTimeout(event: PSDL_Event; timeout: cint32): cint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitEventTimeout' {$ENDIF} {$ENDIF};
+
+ {**
+ * Add an event to the event queue.
+ *
+ * 1 on success, 0 if the event was filtered, or -1 if the event queue
+ * was full or there was some other error.
+ *}
+
+ function SDL_PushEvent(event: PSDL_Event): cint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PumpEvents' {$ENDIF} {$ENDIF};
+ {$endif}
+
+type
+ PPSDL_EventFilter = ^PSDL_EventFilter;
+ PSDL_EventFilter = ^TSDL_EventFilter;
+ {$IFNDEF GPC}
+ TSDL_EventFilter = function(userdata: Pointer; event: PSDL_Event): cint; cdecl;
+ {$ELSE}
+ TSDL_EventFilter = function( userdata: Pointer; event: PSDL_Event ): cint;
+ {$ENDIF}
+
+ {**
+ * Sets up a filter to process all events before they change internal state and
+ * are posted to the internal event queue.
+ *
+ * If the filter returns 1, then the event will be added to the internal queue.
+ * If it returns 0, then the event will be dropped from the queue, but the
+ * internal state will still be updated. This allows selective filtering of
+ * dynamically arriving events.
+ *
+ * Be very careful of what you do in the event filter function, as
+ * it may run in a different thread!
+ *
+ * There is one caveat when dealing with the SDL_QUITEVENT event type. The
+ * event filter is only called when the window manager desires to close the
+ * application window. If the event filter returns 1, then the window will
+ * be closed, otherwise the window will remain open if possible.
+ *
+ * If the quit event is generated by an interrupt signal, it will bypass the
+ * internal queue and be delivered to the application at the next event poll.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+
+
+ procedure SDL_SetEventFilter(filter: TSDL_EventFilter; userdata: Pointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetEventFilter' {$ENDIF} {$ENDIF};
+
+ {**
+ * Return the current event filter - can be used to "chain" filters.
+ * If there is no event filter set, this function returns SDL_FALSE.
+ *}
+
+ function SDL_GetEventFilter(var filter: PSDL_EventFilter; var userdata: PPointer): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetEventFilter' {$ENDIF} {$ENDIF};
+
+ {**
+ * Add a function which is called when an event is added to the queue.
+ *}
+
+ procedure SDL_AddEventWatch(filter: TSDL_EventFilter; userdata: Pointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AddEventWatch' {$ENDIF} {$ENDIF};
+
+ {**
+ * Remove an event watch function added with SDL_AddEventWatch()
+ *}
+
+ procedure SDL_DelEventWatch(filter: TSDL_EventFilter; userdata: Pointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DelEventWatch' {$ENDIF} {$ENDIF};
+
+ {**
+ * Run the filter function on the current event queue, removing any
+ * events for which the filter returns 0.
+ *}
+
+ procedure SDL_FilterEvents(filter: TSDL_EventFilter; userdata: Pointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FilterEvents' {$ENDIF} {$ENDIF};
+ {$endif}
+const
+
+ SDL_QUERY = -1;
+ SDL_IGNORE = 0;
+ SDL_DISABLE = 0;
+ SDL_ENABLE = 1;
+
+ {**
+ * This function allows you to set the state of processing certain events.
+ * - If state is set to SDL_IGNORE, that event will be automatically
+ * dropped from the event queue and will not event be filtered.
+ * - If state is set to SDL_ENABLE, that event will be processed
+ * normally.
+ * - If state is set to SDL_QUERY, SDL_EventState() will return the
+ * current processing state of the specified event.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_EventState_func = function (type_: TSDL_EventType; state: cint32): cuint8 cdecl;
+ Var
+ SDL_EventState : TSDL_EventState_func = Nil;
+
+ {$else}
+
+ function SDL_EventState(type_: TSDL_EventType; state: cint32): cuint8 cdecl;
+external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EventState' {$ENDIF} {$ENDIF};
+ {$endif}
+
+ function SDL_GetEventState(type_: TSDL_EventType): cuint8;
+
+ {**
+ * This function allocates a set of user-defined events, and returns
+ * the beginning event number for that set of events.
+ *
+ * If there aren't enough user-defined events left, this function
+ * returns (Uint32)-1
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+
+
+ function SDL_RegisterEvents(numevents: cint32): cuint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RegisterEvents' {$ENDIF} {$ENDIF};
+ {$endif}
diff --git a/units/sdl2_for_pascal/sdlfilesystem.inc b/units/sdl2_for_pascal/sdlfilesystem.inc
new file mode 100644
index 0000000..e8f84b7
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlfilesystem.inc
@@ -0,0 +1,121 @@
+{*
+ * \file SDL_filesystem.h
+ *
+ * \brief Include file for filesystem SDL API functions
+ }
+
+{*
+ * Get the directory where the application was run from.
+ *
+ * This is not necessarily a fast call, so you should call this once near
+ * startup and save the string if you need it.
+ *
+ * **Mac OS X and iOS Specific Functionality**: If the application is in a
+ * ".app" bundle, this function returns the Resource directory (e.g.
+ * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding
+ * a property to the Info.plist file. Adding a string key with the name
+ * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the
+ * behaviour.
+ *
+ * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an
+ * application in /Applications/SDLApp/MyApp.app):
+ *
+ * - `resource`: bundle resource directory (the default). For example:
+ * `/Applications/SDLApp/MyApp.app/Contents/Resources`
+ * - `bundle`: the Bundle directory. For example:
+ * `/Applications/SDLApp/MyApp.app/`
+ * - `parent`: the containing directory of the bundle. For example:
+ * `/Applications/SDLApp/`
+ *
+ * The returned path is guaranteed to end with a path separator ('\' on
+ * Windows, '/' on most other platforms).
+ *
+ * The pointer returned is owned by the caller. Please call SDL_free() on the
+ * pointer when done with it.
+ *
+ * \returns an absolute path in UTF-8 encoding to the application data
+ * directory. nil will be returned on error or when the platform
+ * doesn't implement this functionality, call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.1.
+ *
+ * \sa SDL_GetPrefPath
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetBasePath_func = function(): PAnsiChar; cdecl;
+Var
+ SDL_GetBasePath : TSDL_GetBasePath_func = Nil;
+{$else}
+
+function SDL_GetBasePath(): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetBasePath' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the user-and-app-specific path where files can be written.
+ *
+ * Get the "pref dir". This is meant to be where users can write personal
+ * files (preferences and save games, etc) that are specific to your
+ * application. This directory is unique per user, per application.
+ *
+ * This function will decide the appropriate location in the native
+ * filesystem, create the directory if necessary, and return a string of the
+ * absolute path to the directory in UTF-8 encoding.
+ *
+ * On Windows, the string might look like:
+ *
+ * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\`
+ *
+ * On Linux, the string might look like:
+ *
+ * `/home/bob/.local/share/My Program Name/`
+ *
+ * On Mac OS X, the string might look like:
+ *
+ * `/Users/bob/Library/Application Support/My Program Name/`
+ *
+ * You should assume the path returned by this function is the only safe place
+ * to write files (and that SDL_GetBasePath(), while it might be writable, or
+ * even the parent of the returned path, isn't where you should be writing
+ * things).
+ *
+ * Both the org and app strings may become part of a directory name, so please
+ * follow these rules:
+ *
+ * - Try to use the same org string (_including case-sensitivity_) for all
+ * your applications that use this function.
+ * - Always use a unique app string for each one, and make sure it never
+ * changes for an app once you've decided on it.
+ * - Unicode characters are legal, as long as it's UTF-8 encoded, but...
+ * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game
+ * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient.
+ *
+ * The returned path is guaranteed to end with a path separator ('\' on
+ * Windows, '/' on most other platforms).
+ *
+ * The pointer returned is owned by the caller. Please call SDL_free() on the
+ * pointer when done with it.
+ *
+ * \param org the name of your organization
+ * \param app the name of your application
+ * \returns a UTF-8 string of the user directory in platform-dependent
+ * notation. nil if there's a problem (creating directory failed,
+ * etc.).
+ *
+ * \since This function is available since SDL 2.0.1.
+ *
+ * \sa SDL_GetBasePath
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPrefPath_func = function(org: PAnsiChar; app: PAnsiChar): PAnsiChar; cdecl;
+Var
+ SDL_GetPrefPath : TSDL_GetPrefPath_func = Nil;
+{$else}
+
+function SDL_GetPrefPath(org: PAnsiChar; app: PAnsiChar): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPrefPath' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlgamecontroller.inc b/units/sdl2_for_pascal/sdlgamecontroller.inc
new file mode 100644
index 0000000..f7c330a
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlgamecontroller.inc
@@ -0,0 +1,1002 @@
+//from sdl_gamecontroller.h
+
+{**
+ * SDL_gamecontroller.h
+ *
+ * In order to use these functions, SDL_Init() must have been called
+ * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system
+ * for game controllers, and load appropriate drivers.
+ *
+ * If you would like to receive controller updates while the application
+ * is in the background, you should set the following hint before calling
+ * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
+ *}
+
+{* The gamecontroller structure used to identify an SDL game controller *}
+type
+ PPSDL_GameController = ^PSDL_GameController;
+ PSDL_GameController = type Pointer;
+
+ PPSDL_GameControllerType = ^PSDL_GameControllerType;
+ PSDL_GameControllerType = ^TSDL_GameControllerType;
+ TSDL_GameControllerType = type cint;
+const
+ SDL_CONTROLLER_TYPE_UNKNOWN = TSDL_GameControllerType(0);
+ SDL_CONTROLLER_TYPE_XBOX360 = TSDL_GameControllerType(1);
+ SDL_CONTROLLER_TYPE_XBOXONE = TSDL_GameControllerType(2);
+ SDL_CONTROLLER_TYPE_PS3 = TSDL_GameControllerType(3);
+ SDL_CONTROLLER_TYPE_PS4 = TSDL_GameControllerType(4);
+ SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO = TSDL_GameControllerType(5);
+ SDL_CONTROLLER_TYPE_VIRTUAL = TSDL_GameControllerType(6);
+ SDL_CONTROLLER_TYPE_PS5 = TSDL_GameControllerType(7);
+ SDL_CONTROLLER_TYPE_AMAZON_LUNA = TSDL_GameControllerType(8);
+ SDL_CONTROLLER_TYPE_GOOGLE_STADIA = TSDL_GameControllerType(9);
+ SDL_CONTROLLER_TYPE_NVIDIA_SHIELD = TSDL_GameControllerType(10);
+ SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT = TSDL_GameControllerType(11);
+ SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT = TSDL_GameControllerType(12);
+ SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR = TSDL_GameControllerType(13);
+
+type
+ PPSDL_GameControllerBindType = ^PSDL_GameControllerBindType;
+ PSDL_GameControllerBindType = ^TSDL_GameControllerBindType;
+ TSDL_GameControllerBindType = type cint;
+const
+ SDL_CONTROLLER_BINDTYPE_NONE = TSDL_GameControllerBindType(0);
+ SDL_CONTROLLER_BINDTYPE_BUTTON = TSDL_GameControllerBindType(1);
+ SDL_CONTROLLER_BINDTYPE_AXIS = TSDL_GameControllerBindType(2);
+ SDL_CONTROLLER_BINDTYPE_HAT = TSDL_GameControllerBindType(3);
+
+ {**
+ * Get the SDL joystick layer binding for this controller button/axis mapping
+ *}
+type
+ THat = record
+ hat: cint;
+ hat_mask: cint;
+ end;
+
+ PPSDL_GameControllerButtonBind = ^PSDL_GameControllerButtonBind;
+ PSDL_GameControllerButtonBind = ^TSDL_GameControllerButtonBind;
+ TSDL_GameControllerButtonBind = record
+ bindType: TSDL_GameControllerBindType;
+ case cint of
+ 0: ( button: cint; );
+ 1: ( axis: cint; );
+ 2: ( hat: THat; );
+ end;
+
+ {**
+ * To count the number of game controllers in the system for the following:
+ * int nJoysticks = SDL_NumJoysticks();
+ * int nGameControllers = 0;
+ * for ( int i = 0; i < nJoysticks; i++ ) [
+ * if ( SDL_IsGameController(i) ) [
+ * nGameControllers++;
+ *
+ * !! Pascal Conv.: Changed curly to square brackets in above example code
+ to prevent opening comment blocks!
+ *
+ * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
+ * guid,name,mappings
+ *
+ * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones.
+ * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices.
+ * The mapping format for joystick is:
+ * bX - a joystick button, index X
+ * hX.Y - hat X with value Y
+ * aX - axis X of the joystick
+ * Buttons can be used as a controller axis and vice versa.
+ *
+ * This string shows an example of a valid mapping for a controller
+ * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7",
+ *
+ *}
+
+ {**
+ * Add or update an existing mapping configuration
+ *
+ * 1 if mapping is added, 0 if updated, -1 on error
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerAddMapping( mappingString: PAnsiChar ): cint cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerAddMapping' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Load a set of mappings from a seekable SDL data stream (memory or file), filtered by the current SDL_GetPlatform()
+ * A community sourced database of controllers is available at https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
+ *
+ * If freerw is non-zero, the stream will be closed after being read.
+ *
+ * Returns number of mappings added, -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerAddMappingsFromRW_func = function(rw: PSDL_RWops; freerw: cint32):cint32;
+ cdecl;
+Var
+ SDL_GameControllerAddMappingsFromRW : TSDL_GameControllerAddMappingsFromRW_func = Nil;
+{$else}
+
+function SDL_GameControllerAddMappingsFromRW(rw: PSDL_RWops; freerw: cint32):cint32;
+ cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerAddMappingsFromRW' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of mappings installed.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerNumMappings_func = function():cint; cdecl;
+Var
+ SDL_GameControllerNumMappings : TSDL_GameControllerNumMappings_func = Nil;
+{$else}
+
+function SDL_GameControllerNumMappings():cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerNumMappings' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a mapping string for a GUID
+ *
+ * the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerMappingForGUID( guid: TSDL_JoystickGUID ): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerMappingForGUID' {$ENDIF} {$ENDIF};
+
+{$endif}
+{**
+ * Get the mapping at a particular index.
+ *
+ * Returns the mapping string. Must be freed with SDL_free().
+ * Returns NIL if the index is out of range.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerMappingForIndex_func = function(mapping_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerMappingForIndex : TSDL_GameControllerMappingForIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerMappingForIndex(mapping_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerMappingForIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a mapping string for an open GameController
+ *
+ * the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerMapping( gamecontroller: PSDL_GameController ): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerMapping' {$ENDIF} {$ENDIF};
+
+ {**
+ * Is the joystick on this index supported by the game controller interface?
+ *}
+function SDL_IsGameController(joystick_index: cint): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsGameController' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the implementation dependent name of a game controller.
+ * This can be called before any controllers are opened.
+ * If no name can be found, this function returns NULL.
+ *}
+function SDL_GameControllerNameForIndex(joystick_index: cint): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerNameForIndex' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Get the implementation dependent path for the game controller.
+ *
+ * This function can be called before any controllers are opened.
+ *
+ * `joystick_index` is the same as the `device_index` passed to
+ * SDL_JoystickOpen().
+ *
+ * \param joystick_index the device_index of a device, from zero to
+ * SDL_NumJoysticks()-1
+ * \returns the implementation-dependent path for the game controller, or NIL
+ * if there is no path or the index is invalid.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GameControllerPath
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerPathForIndex_func = function(joystick_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerPathForIndex : TSDL_GameControllerPathForIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerPathForIndex(joystick_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerPathForIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the type of a game controller.
+ * This can be called before any controllers are opened.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerTypeForIndex_func = function(joystick_index: cint): TSDL_GameControllerType; cdecl;
+Var
+ SDL_GameControllerTypeForIndex : TSDL_GameControllerTypeForIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerTypeForIndex(joystick_index: cint): TSDL_GameControllerType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerTypeForIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the mapping of a game controller.
+ * This can be called before any controllers are opened.
+ *
+ * Returns the mapping string. Must be freed with SDL_free().
+ * Returns NIL if no mapping is available.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerMappingForDeviceIndex_func = function(joystick_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerMappingForDeviceIndex : TSDL_GameControllerMappingForDeviceIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerMappingForDeviceIndex(joystick_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerMappingForDeviceIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Open a game controller for use.
+ * The index passed as an argument refers to the N'th game controller on the system.
+ * This index is the value which will identify this controller in future controller
+ * events.
+ *
+ * A controller identifier, or NULL if an error occurred.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerOpen(joystick_index: cint): PSDL_GameController cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerOpen' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Return the SDL_GameController associated with an instance id.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerFromInstanceID_func = function(joyid: TSDL_JoystickID): PSDL_GameController; cdecl;
+Var
+ SDL_GameControllerFromInstanceID : TSDL_GameControllerFromInstanceID_func = Nil;
+{$else}
+
+function SDL_GameControllerFromInstanceID(joyid: TSDL_JoystickID): PSDL_GameController; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerFromInstanceID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the SDL_GameController associated with a player index.
+ *
+ * Please note that the player index is _not_ the device index, nor is it the
+ * instance id!
+ *
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerFromPlayerIndex_func = function(player_index: cint): PSDL_GameController; cdecl;
+Var
+ SDL_GameControllerFromPlayerIndex : TSDL_GameControllerFromPlayerIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerFromPlayerIndex(player_index: cint): PSDL_GameController; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerFromPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Return the name for this currently opened controller
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerName(gamecontroller: PSDL_GameController): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerName' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Get the implementation-dependent path for an opened game controller.
+ *
+ * This is the same path as returned by SDL_GameControllerNameForIndex(), but
+ * it takes a controller identifier instead of the (unstable) device index.
+ *
+ * \param gamecontroller a game controller identifier previously returned by
+ * SDL_GameControllerOpen()
+ * \returns the implementation dependent path for the game controller, or NIL
+ * if there is no path or the identifier passed is invalid.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GameControllerPathForIndex
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerPath_func = function(gamecontroller: PSDL_GameController): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerPath : TSDL_GameControllerPath_func = Nil;
+{$else}
+
+function SDL_GameControllerPath(gamecontroller: PSDL_GameController): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerPath' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the type of this currently opened controller
+ *
+ * This is the same name as returned by SDL_GameControllerTypeForIndex(), but
+ * it takes a controller identifier instead of the (unstable) device index.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetType_func = function(gamecontroller: PSDL_GameController): TSDL_GameControllerType; cdecl;
+Var
+ SDL_GameControllerGetType : TSDL_GameControllerGetType_func = Nil;
+{$else}
+
+function SDL_GameControllerGetType(gamecontroller: PSDL_GameController): TSDL_GameControllerType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetType' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the player index of an opened game controller.
+ * For XInput controllers this returns the XInput user index.
+ *
+ * Returns the player index for controller, or -1 if it's not available.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetPlayerIndex_func = function(gamecontroller: PSDL_GameController): cint; cdecl;
+Var
+ SDL_GameControllerGetPlayerIndex : TSDL_GameControllerGetPlayerIndex_func = Nil;
+{$else}
+
+function SDL_GameControllerGetPlayerIndex(gamecontroller: PSDL_GameController): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set the player index of an opened game controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerSetPlayerIndex_proc = procedure(gamecontroller: PSDL_GameController; player_index: cint); cdecl;
+Var
+ SDL_GameControllerSetPlayerIndex : TSDL_GameControllerSetPlayerIndex_proc = Nil;
+{$else}
+
+procedure SDL_GameControllerSetPlayerIndex(gamecontroller: PSDL_GameController; player_index: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerSetPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB vendor ID of an opened controller, if available.
+ *
+ * If the vendor ID isn't available this function returns 0.
+ *
+ * \param gamecontroller the game controller object to query.
+ * \return the USB vendor ID, or zero if unavailable.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetVendor_func = function(gamecontroller: PSDL_GameController): cuint16; cdecl;
+Var
+ SDL_GameControllerGetVendor : TSDL_GameControllerGetVendor_func = Nil;
+{$else}
+
+function SDL_GameControllerGetVendor(gamecontroller: PSDL_GameController): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetVendor' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB product ID of an opened controller, if available.
+ * If the product ID isn't available, this function returns 0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetProduct_func = function(gamecontroller: PSDL_GameController): cuint16; cdecl;
+Var
+ SDL_GameControllerGetProduct : TSDL_GameControllerGetProduct_func = Nil;
+{$else}
+
+function SDL_GameControllerGetProduct(gamecontroller: PSDL_GameController): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetProduct' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the product version of an opened controller, if available.
+ * If the product version isn't available, this function returns 0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetProductVersion_func = function(gamecontroller: PSDL_GameController): cuint16; cdecl;
+Var
+ SDL_GameControllerGetProductVersion : TSDL_GameControllerGetProductVersion_func = Nil;
+{$else}
+
+function SDL_GameControllerGetProductVersion(gamecontroller: PSDL_GameController): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetProductVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the firmware version of an opened controller, if available.
+ *
+ * If the firmware version isn't available this function returns 0.
+ *
+ * \param gamecontroller the game controller object to query.
+ * \return the controller firmware version, or zero if unavailable.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetFirmwareVersion_func = function(gamecontroller: PSDL_GameController): cuint16; cdecl;
+Var
+ SDL_GameControllerGetFirmwareVersion : TSDL_GameControllerGetFirmwareVersion_func = Nil;
+{$else}
+
+function SDL_GameControllerGetFirmwareVersion(gamecontroller: PSDL_GameController): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetFirmwareVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the serial number of an opened controller, if available.
+ *
+ * Returns a string containing the serial number of the controller,
+ * or NIL if it is not available. Do _not_ free the string with SDL_free().
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetSerial_func = function(gamecontroller: PSDL_GameController): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerGetSerial : TSDL_GameControllerGetSerial_func = Nil;
+{$else}
+
+function SDL_GameControllerGetSerial(gamecontroller: PSDL_GameController): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetSerial' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the Steam Input handle of an opened controller, if available.
+ *
+ * Returns an InputHandle_t for the controller that can be used with Steam Input API:
+ * https://partner.steamgames.com/doc/api/ISteamInput
+ *
+ * \param gamecontroller the game controller object to query.
+ * \returns the gamepad handle, or 0 if unavailable.
+ *
+ * \since This function is available since SDL 2.30.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetSteamHandle_func = function(gamecontroller: PSDL_GameController): cuint64; cdecl;
+Var
+ SDL_GameControllerGetSteamHandle : TSDL_GameControllerGetSteamHandle_func = Nil;
+{$else}
+
+function SDL_GameControllerGetSteamHandle(gamecontroller: PSDL_GameController): cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetSteamHandle' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Returns SDL_TRUE if the controller has been opened and currently connected,
+ * or SDL_FALSE if it has not.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerGetAttached(gamecontroller: PSDL_GameController): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetAttached' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the underlying joystick object used by a controller
+ *}
+function SDL_GameControllerGetJoystick(gamecontroller: PSDL_GameController): PSDL_Joystick cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetJoystick' {$ENDIF} {$ENDIF};
+
+ {**
+ * Enable/disable controller event polling.
+ *
+ * If controller events are disabled, you must call SDL_GameControllerUpdate()
+ * yourself and check the state of the controller when you want controller
+ * information.
+ *
+ * The state can be one of ::SDL_QUERY, ::SDL_ENABLE or ::SDL_IGNORE.
+ *}
+function SDL_GameControllerEventState(state: cint): cint cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerEventState' {$ENDIF} {$ENDIF};
+
+ {**
+ * Update the current state of the open game controllers.
+ *
+ * This is called automatically by the event loop if any game controller
+ * events are enabled.
+ *}
+procedure SDL_GameControllerUpdate() cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerUpdate' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * The list of axes available from a controller
+ *}
+
+type
+ PPSDL_GameControllerAxis = ^PSDL_GameControllerAxis;
+ PSDL_GameControllerAxis = ^TSDL_GameControllerAxis;
+ TSDL_GameControllerAxis = type cint;
+const
+ SDL_CONTROLLER_AXIS_INVALID = TSDL_GameControllerAxis(-1);
+ SDL_CONTROLLER_AXIS_LEFTX = TSDL_GameControllerAxis(0);
+ SDL_CONTROLLER_AXIS_LEFTY = TSDL_GameControllerAxis(1);
+ SDL_CONTROLLER_AXIS_RIGHTX = TSDL_GameControllerAxis(2);
+ SDL_CONTROLLER_AXIS_RIGHTY = TSDL_GameControllerAxis(3);
+ SDL_CONTROLLER_AXIS_TRIGGERLEFT = TSDL_GameControllerAxis(4);
+ SDL_CONTROLLER_AXIS_TRIGGERRIGHT = TSDL_GameControllerAxis(5);
+ SDL_CONTROLLER_AXIS_MAX = TSDL_GameControllerAxis(6);
+ {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+ {**
+ * turn this string into a axis mapping
+ *}
+function SDL_GameControllerGetAxisFromString(pchString: PAnsiChar): TSDL_GameControllerAxis cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetAxisFromString' {$ENDIF} {$ENDIF};
+
+ {**
+ * turn this axis enum into a string mapping
+ *}
+function SDL_GameControllerGetStringForAxis(axis: TSDL_GameControllerAxis): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetStringForAxis' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the SDL joystick layer binding for this controller button mapping
+ *}
+function SDL_GameControllerGetBindForAxis(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): TSDL_GameControllerButtonBind cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetBindForAxis' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Query whether a game controller has a given axis.
+ *
+ * This merely reports whether the controller's mapping defined this axis,
+ * as that is all the information SDL has about the physical device.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasAxis_func = function(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasAxis : TSDL_GameControllerHasAxis_func = Nil;
+{$else}
+
+function SDL_GameControllerHasAxis(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasAxis' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the current state of an axis control on a game controller.
+ *
+ * The state is a value ranging from -32768 to 32767.
+ *
+ * The axis indices start at index 0.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerGetAxis(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): cint16 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetAxis' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * The list of buttons available from a controller
+ *}
+type
+ PPSDL_GameControllerButton = ^PSDL_GameControllerButton;
+ PSDL_GameControllerButton = ^TSDL_GameControllerButton;
+ TSDL_GameControllerButton = type cint;
+const
+ SDL_CONTROLLER_BUTTON_INVALID = TSDL_GameControllerButton(-1);
+ SDL_CONTROLLER_BUTTON_A = TSDL_GameControllerButton(0);
+ SDL_CONTROLLER_BUTTON_B = TSDL_GameControllerButton(1);
+ SDL_CONTROLLER_BUTTON_X = TSDL_GameControllerButton(2);
+ SDL_CONTROLLER_BUTTON_Y = TSDL_GameControllerButton(3);
+ SDL_CONTROLLER_BUTTON_BACK = TSDL_GameControllerButton(4);
+ SDL_CONTROLLER_BUTTON_GUIDE = TSDL_GameControllerButton(5);
+ SDL_CONTROLLER_BUTTON_START = TSDL_GameControllerButton(6);
+ SDL_CONTROLLER_BUTTON_LEFTSTICK = TSDL_GameControllerButton(7);
+ SDL_CONTROLLER_BUTTON_RIGHTSTICK = TSDL_GameControllerButton(8);
+ SDL_CONTROLLER_BUTTON_LEFTSHOULDER = TSDL_GameControllerButton(9);
+ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER = TSDL_GameControllerButton(10);
+ SDL_CONTROLLER_BUTTON_DPAD_UP = TSDL_GameControllerButton(11);
+ SDL_CONTROLLER_BUTTON_DPAD_DOWN = TSDL_GameControllerButton(12);
+ SDL_CONTROLLER_BUTTON_DPAD_LEFT = TSDL_GameControllerButton(13);
+ SDL_CONTROLLER_BUTTON_DPAD_RIGHT = TSDL_GameControllerButton(14);
+ SDL_CONTROLLER_BUTTON_MISC1 = TSDL_GameControllerButton(15); {**< Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button *}
+ SDL_CONTROLLER_BUTTON_PADDLE1 = TSDL_GameControllerButton(16); {**< Xbox Elite paddle P1 *}
+ SDL_CONTROLLER_BUTTON_PADDLE2 = TSDL_GameControllerButton(17); {**< Xbox Elite paddle P3 *}
+ SDL_CONTROLLER_BUTTON_PADDLE3 = TSDL_GameControllerButton(18); {**< Xbox Elite paddle P2 *}
+ SDL_CONTROLLER_BUTTON_PADDLE4 = TSDL_GameControllerButton(19); {**< Xbox Elite paddle P4 *}
+ SDL_CONTROLLER_BUTTON_TOUCHPAD = TSDL_GameControllerButton(20); {**< PS4/PS5 touchpad button *}
+ SDL_CONTROLLER_BUTTON_MAX = TSDL_GameControllerButton(21);
+ {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+ {**
+ * turn this string into a button mapping
+ *}
+function SDL_GameControllerGetButtonFromString(pchString: PAnsiChar): TSDL_GameControllerButton cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetButtonFromString' {$ENDIF} {$ENDIF};
+
+ {**
+ * turn this button enum into a string mapping
+ *}
+function SDL_GameControllerGetStringForButton(button: TSDL_GameControllerButton): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetStringForButton' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the SDL joystick layer binding for this controller button mapping
+ *}
+function SDL_GameControllerGetBindForButton(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): TSDL_GameControllerButtonBind cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetBindForButton' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Query whether a game controller has a given button.
+ *
+ * This merely reports whether the controller's mapping defined this button,
+ * as that is all the information SDL has about the physical device.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasButton_func = function(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasButton : TSDL_GameControllerHasButton_func = Nil;
+{$else}
+
+function SDL_GameControllerHasButton(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasButton' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current state of a button on a game controller.
+ *
+ * The button indices start at index 0.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GameControllerGetButton(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): cuint8 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetButton' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Get the number of touchpads on a game controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetNumTouchpads_func = function(gamecontroller: PSDL_GameController): cint; cdecl;
+Var
+ SDL_GameControllerGetNumTouchpads : TSDL_GameControllerGetNumTouchpads_func = Nil;
+{$else}
+
+function SDL_GameControllerGetNumTouchpads(gamecontroller: PSDL_GameController): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetNumTouchpads' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of supported simultaneous fingers on a touchpad on a game controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetNumTouchpadFingers_func = function(gamecontroller: PSDL_GameController; touchpad: cint): cint; cdecl;
+Var
+ SDL_GameControllerGetNumTouchpadFingers : TSDL_GameControllerGetNumTouchpadFingers_func = Nil;
+{$else}
+
+function SDL_GameControllerGetNumTouchpadFingers(gamecontroller: PSDL_GameController; touchpad: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetNumTouchpadFingers' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current state of a finger on a touchpad on a game controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetTouchpadFinger_func = function(
+ gamecontroller: PSDL_GameController;
+ touchpad, finger: cint;
+ state: pcuint8;
+ x, y, pressure: pcfloat
+ ): cint; cdecl;
+Var
+ SDL_GameControllerGetTouchpadFinger : TSDL_GameControllerGetTouchpadFinger_func = Nil;
+{$else}
+
+function SDL_GameControllerGetTouchpadFinger(
+ gamecontroller: PSDL_GameController;
+ touchpad, finger: cint;
+ state: pcuint8;
+ x, y, pressure: pcfloat
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetTouchpadFinger' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Return whether a game controller has a particular sensor.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasSensor_func = function(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasSensor : TSDL_GameControllerHasSensor_func = Nil;
+{$else}
+
+function SDL_GameControllerHasSensor(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasSensor' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set whether data reporting for a game controller sensor is enabled.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerSetSensorEnabled_func = function(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType; enabled: TSDL_bool): cint; cdecl;
+Var
+ SDL_GameControllerSetSensorEnabled : TSDL_GameControllerSetSensorEnabled_func = Nil;
+{$else}
+
+function SDL_GameControllerSetSensorEnabled(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType; enabled: TSDL_bool): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerSetSensorEnabled' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether sensor data reporting is enabled for a game controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerIsSensorEnabled_func = function(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerIsSensorEnabled : TSDL_GameControllerIsSensorEnabled_func = Nil;
+{$else}
+
+function SDL_GameControllerIsSensorEnabled(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerIsSensorEnabled' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the data rate (number of events per second) of
+ * a game controller sensor.
+ *
+ * Returns the data rate, or 0.0 if the data rate is not available.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetSensorDataRate_func = function(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): cfloat; cdecl;
+Var
+ SDL_GameControllerGetSensorDataRate : TSDL_GameControllerGetSensorDataRate_func = Nil;
+{$else}
+
+function SDL_GameControllerGetSensorDataRate(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetSensorDataRate' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current state of a game controller sensor.
+ *
+ * The number of values and interpretation of the data is sensor dependent.
+ * See sdlsensor.inc for the details for each type of sensor.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetSensorData_func = function(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType; data: pcfloat; num_values: cint): cint; cdecl;
+Var
+ SDL_GameControllerGetSensorData : TSDL_GameControllerGetSensorData_func = Nil;
+{$else}
+
+function SDL_GameControllerGetSensorData(gamecontroller: PSDL_GameController; senstype: TSDL_SensorType; data: pcfloat; num_values: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetSensorData' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current state of a game controller sensor with the timestamp of the
+ * last update.
+ *
+ * The number of values and interpretation of the data is sensor dependent.
+ * See SDL_sensor.h for the details for each type of sensor.
+ *
+ * \param gamecontroller The controller to query
+ * \param type The type of sensor to query
+ * \param timestamp A pointer filled with the timestamp in microseconds of the
+ * current sensor reading if available, or 0 if not
+ * \param data A pointer filled with the current sensor state
+ * \param num_values The number of values to write to data
+ * \return 0 or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.26.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetSensorDataWithTimestamp_func = function(
+ gamecontroller: PSDL_GameController;
+ senstype: TSDL_SensorType;
+ timestamp: pcuint64;
+ data: pcfloat;
+ num_values: cint
+ ): cint; cdecl;
+Var
+ SDL_GameControllerGetSensorDataWithTimestamp : TSDL_GameControllerGetSensorDataWithTimestamp_func = Nil;
+{$else}
+
+function SDL_GameControllerGetSensorDataWithTimestamp(
+ gamecontroller: PSDL_GameController;
+ senstype: TSDL_SensorType;
+ timestamp: pcuint64;
+ data: pcfloat;
+ num_values: cint
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetSensorDataWithTimestamp' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a game controller has rumble support.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasRumble_func = function(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasRumble : TSDL_GameControllerHasRumble_func = Nil;
+{$else}
+
+function SDL_GameControllerHasRumble(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasRumble' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Start a rumble effect on a game controller.
+ *
+ * Each call to this function cancels any previous rumble effect, and calling
+ * it with 0 intensity stops any rumbling.
+ *
+ * Returns 0, or -1 if rumble isn't supported on this controller.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerRumble_func = function(
+ gamecontroller: PSDL_GameController;
+ low_frequency_rumble, high_frequency_rumble: cuint16;
+ duration_ms: cuint32
+ ): cint; cdecl;
+
+Var
+ SDL_GameControllerRumble : TSDL_GameControllerRumble_func = Nil;
+{$else}
+
+function SDL_GameControllerRumble(
+ gamecontroller: PSDL_GameController;
+ low_frequency_rumble, high_frequency_rumble: cuint16;
+ duration_ms: cuint32
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerRumble' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a game controller has rumble support on triggers.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasRumbleTriggers_func = function(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasRumbleTriggers : TSDL_GameControllerHasRumbleTriggers_func = Nil;
+{$else}
+
+function SDL_GameControllerHasRumbleTriggers(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasRumbleTriggers' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Start a rumble effect in the game controller's triggers.
+ *
+ * Each call to this function cancels any previous trigger rumble effect, and
+ * calling it with 0 intensity stops any rumbling.
+ *
+ * Note that this is rumbling of the _triggers_ and not the game controller as
+ * a whole. This is currently only supported on Xbox One controllers. If you
+ * want the (more common) whole-controller rumble, use
+ * SDL_GameControllerRumble() instead.
+ *
+ * Returns 0, or -1 if trigger rumble isn't supported on this controller
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerRumbleTriggers_func = function(
+ gamecontroller: PSDL_GameController;
+ left_rumble, right_rumble: cuint16;
+ duration_ms: cuint32
+ ): cint; cdecl;
+
+Var
+ SDL_GameControllerRumbleTriggers : TSDL_GameControllerRumbleTriggers_func = Nil;
+{$else}
+
+function SDL_GameControllerRumbleTriggers(
+ gamecontroller: PSDL_GameController;
+ left_rumble, right_rumble: cuint16;
+ duration_ms: cuint32
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerRumbleTriggers' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a game controller has an LED.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerHasLED_func = function(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+Var
+ SDL_GameControllerHasLED : TSDL_GameControllerHasLED_func = Nil;
+{$else}
+
+function SDL_GameControllerHasLED(gamecontroller: PSDL_GameController): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerHasLED' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Update a game controller's LED color.
+ *
+ * Returns 0, or -1 if this controller does not have a modifiable LED.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerSetLED_func = function(gamecontroller: PSDL_GameController; red, green, blue: cuint8): cint; cdecl;
+Var
+ SDL_GameControllerSetLED : TSDL_GameControllerSetLED_func = Nil;
+{$else}
+
+function SDL_GameControllerSetLED(gamecontroller: PSDL_GameController; red, green, blue: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerSetLED' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Send a controller-specific effect packet.
+ *
+ * Returns 0, or -1 if this controller or driver does not
+ * support effect packets.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerSendEffect_func = function(gamecontroller: PSDL_GameController; data: Pointer; size: cint): cint; cdecl;
+Var
+ SDL_GameControllerSendEffect : TSDL_GameControllerSendEffect_func = Nil;
+{$else}
+
+function SDL_GameControllerSendEffect(gamecontroller: PSDL_GameController; data: Pointer; size: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerSendEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Close a controller previously opened with SDL_GameControllerOpen().
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+procedure SDL_GameControllerClose(gamecontroller: PSDL_GameController) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerClose' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Return the sfSymbolsName for a given axis on a game controller
+ * on Apple platforms.
+ *
+ * Returns the sfSymbolsName, or NIL if the name can't be found.
+ * Do _not_ pass this string to SDL_free().
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetAppleSFSymbolsNameForAxis_func = function(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerGetAppleSFSymbolsNameForAxis : TSDL_GameControllerGetAppleSFSymbolsNameForAxis_func = Nil;
+{$else}
+
+function SDL_GameControllerGetAppleSFSymbolsNameForAxis(gamecontroller: PSDL_GameController; axis: TSDL_GameControllerAxis): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetAppleSFSymbolsNameForAxis' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Return the sfSymbolsName for a given button on a game controller
+ * on Apple platforms.
+ *
+ * Returns the sfSymbolsName, or NIL if the name can't be found.
+ * Do _not_ pass this string to SDL_free().
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GameControllerGetAppleSFSymbolsNameForButton_func = function(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): PAnsiChar; cdecl;
+Var
+ SDL_GameControllerGetAppleSFSymbolsNameForButton : TSDL_GameControllerGetAppleSFSymbolsNameForButton_func = Nil;
+{$else}
+
+function SDL_GameControllerGetAppleSFSymbolsNameForButton(gamecontroller: PSDL_GameController; button: TSDL_GameControllerButton): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GameControllerGetAppleSFSymbolsNameForButton' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+function SDL_GameControllerAddMappingsFromFile(Const FilePath:PAnsiChar):cint32;
diff --git a/units/sdl2_for_pascal/sdlgesture.inc b/units/sdl2_for_pascal/sdlgesture.inc
new file mode 100644
index 0000000..d170932
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlgesture.inc
@@ -0,0 +1,104 @@
+//from "sdl_gesture.h"
+
+type
+ PPSDL_GestureID = ^PSDL_GestureID;
+ PSDL_GestureID = ^TSDL_GestureID;
+ TSDL_GestureID = type cint64;
+
+ {* Function prototypes *}
+
+ {/**
+ * Begin recording a gesture on a specified touch device or all touch devices.
+ *
+ * If the parameter `touchId` is -1 (i.e., all devices), this function will
+ * always return 1, regardless of whether there actually are any devices.
+ *
+ * \param touchId the touch device id, or -1 for all touch devices
+ * \returns 1 on success or 0 if the specified device could not be found.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetTouchDevice
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RecordGesture_func = function(touchId: TSDL_TouchID): cint; cdecl;
+Var
+ SDL_RecordGesture : TSDL_RecordGesture_func = Nil;
+{$else}
+
+function SDL_RecordGesture(touchId: TSDL_TouchID): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RecordGesture' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Save all currently loaded Dollar Gesture templates.
+ *
+ * \param dst a SDL_RWops to save to
+ * \returns the number of saved templates on success or 0 on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadDollarTemplates
+ * \sa SDL_SaveDollarTemplate
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SaveAllDollarTemplates_func = function(dst: PSDL_RWops): cint; cdecl;
+Var
+ SDL_SaveAllDollarTemplates : TSDL_SaveAllDollarTemplates_func = Nil;
+{$else}
+
+function SDL_SaveAllDollarTemplates(dst: PSDL_RWops): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SaveAllDollarTemplates' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Save a currently loaded Dollar Gesture template.
+ *
+ * \param gestureId a gesture id
+ * \param dst a SDL_RWops to save to
+ * \returns 1 on success or 0 on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadDollarTemplates
+ * \sa SDL_SaveAllDollarTemplates
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SaveDollarTemplate_func = function(gestureId: TSDL_GestureID; dst: PSDL_RWops): cint; cdecl;
+Var
+ SDL_SaveDollarTemplate : TSDL_SaveDollarTemplate_func = Nil;
+{$else}
+
+function SDL_SaveDollarTemplate(gestureId: TSDL_GestureID; dst: PSDL_RWops): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SaveDollarTemplate' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+ {**
+ * Load Dollar Gesture templates from a file.
+ *
+ * \param touchId a touch id
+ * \param src a SDL_RWops to load from
+ * \returns the number of loaded templates on success or a negative error code
+ * (or 0) on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_SaveAllDollarTemplates
+ * \sa SDL_SaveDollarTemplate
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadDollarTemplates_func = function(touchId: TSDL_TouchID; src: PSDL_RWops): cint; cdecl;
+Var
+ SDL_LoadDollarTemplates : TSDL_LoadDollarTemplates_func = Nil;
+{$else}
+
+function SDL_LoadDollarTemplates(touchId: TSDL_TouchID; src: PSDL_RWops): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadDollarTemplates' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlguid.inc b/units/sdl2_for_pascal/sdlguid.inc
new file mode 100644
index 0000000..5ce96d1
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlguid.inc
@@ -0,0 +1,76 @@
+{**
+ * \file SDL_guid.h
+ *
+ * Include file for handling ::SDL_GUID values.
+ *}
+
+{**
+ * An SDL_GUID is a 128-bit identifier for an input device that
+ * identifies that device across runs of SDL programs on the same
+ * platform. If the device is detached and then re-attached to a
+ * different port, or if the base system is rebooted, the device
+ * should still report the same GUID.
+ *
+ * GUIDs are as precise as possible but are not guaranteed to
+ * distinguish physically distinct but equivalent devices. For
+ * example, two game controllers from the same vendor with the same
+ * product ID and revision may have the same GUID.
+ *
+ * GUIDs may be platform-dependent (i.e., the same device may report
+ * different GUIDs on different operating systems).
+ *}
+type
+ PPSDL_GUID = ^PSDL_GUID;
+ PSDL_GUID = ^TSDL_GUID;
+ TSDL_GUID = record
+ data: array[0..15] of cuint8;
+ end;
+
+ {**
+ * Get an ASCII string representation for a given ::SDL_GUID.
+ *
+ * You should supply at least 33 bytes for pszGUID.
+ *
+ * \param guid the ::SDL_GUID you wish to convert to string
+ * \param pszGUID buffer in which to write the ASCII string
+ * \param cbGUID the size of pszGUID
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GUIDFromString
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GUIDToString_proc = procedure(guid: TSDL_GUID; pszGUID: PAnsiChar; cbGUID: cint); cdecl;
+Var
+ SDL_GUIDToString : TSDL_GUIDToString_proc = Nil;
+{$else}
+
+procedure SDL_GUIDToString(guid: TSDL_GUID; pszGUID: PAnsiChar; cbGUID: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GUIDToString' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Convert a GUID string into a ::SDL_GUID structure.
+ *
+ * Performs no error checking. If this function is given a string containing
+ * an invalid GUID, the function will silently succeed, but the GUID generated
+ * will not be useful.
+ *
+ * \param pchGUID string containing an ASCII representation of a GUID
+ * \returns a ::SDL_GUID structure.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GUIDToString
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GUIDFromString_func = function(const pchGUID: PAnsiChar): TSDL_GUID; cdecl;
+Var
+ SDL_GUIDFromString : TSDL_GUIDFromString_func = Nil;
+{$else}
+
+function SDL_GUIDFromString(const pchGUID: PAnsiChar): TSDL_GUID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GUIDFromString' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlhaptic.inc b/units/sdl2_for_pascal/sdlhaptic.inc
new file mode 100644
index 0000000..edab451
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlhaptic.inc
@@ -0,0 +1,1540 @@
+//from "sdl_haptic.h"
+
+{**
+ *
+ * The SDL Haptic subsystem allows you to control haptic (force feedback)
+ * devices.
+ *
+ * The basic usage is as follows:
+ * - Initialize the Subsystem (::SDL_INIT_HAPTIC).
+ * - Open a Haptic Device.
+ * - SDL_HapticOpen() to open from index.
+ * - SDL_HapticOpenFromJoystick() to open from an existing joystick.
+ * - Create an effect (::SDL_HapticEffect).
+ * - Upload the effect with SDL_HapticNewEffect().
+ * - Run the effect with SDL_HapticRunEffect().
+ * - (optional) Free the effect with SDL_HapticDestroyEffect().
+ * - Close the haptic device with SDL_HapticClose().
+ *
+ * Simple rumble example:
+ *
+ * SDL_Haptic *haptic;
+ *
+ * // Open the device
+ * haptic = SDL_HapticOpen( 0 );
+ * if (haptic == NULL)
+ * return -1;
+ *
+ * // Initialize simple rumble
+ * if (SDL_HapticRumbleInit( haptic ) != 0)
+ * return -1;
+ *
+ * // Play effect at 50% strength for 2 seconds
+ * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0)
+ * return -1;
+ * SDL_Delay( 2000 );
+ *
+ * // Clean up
+ * SDL_HapticClose( haptic );
+ *
+ *
+ * Complete example:
+ *
+ * int test_haptic( SDL_Joystick * joystick )
+ * SDL_Haptic *haptic;
+ * SDL_HapticEffect effect;
+ * int effect_id;
+ *
+ * // Open the device
+ * haptic = SDL_HapticOpenFromJoystick( joystick );
+ * if (haptic == NULL) return -1; // Most likely joystick isn't haptic
+ *
+ * // See if it can do sine waves
+ * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0)
+ * SDL_HapticClose(haptic); // No sine effect
+ * return -1;
+ *
+ *
+ * // Create the effect
+ * memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default
+ * effect.type = SDL_HAPTIC_SINE;
+ * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
+ * effect.periodic.direction.dir[0] = 18000; // Force comes from south
+ * effect.periodic.period = 1000; // 1000 ms
+ * effect.periodic.magnitude = 20000; // 20000/32767 strength
+ * effect.periodic.length = 5000; // 5 seconds long
+ * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength
+ * effect.periodic.fade_length = 1000; // Takes 1 second to fade away
+ *
+ * // Upload the effect
+ * effect_id = SDL_HapticNewEffect( haptic, &effect );
+ *
+ * // Test the effect
+ * SDL_HapticRunEffect( haptic, effect_id, 1 );
+ * SDL_Delay( 5000); // Wait for the effect to finish
+ *
+ * // We destroy the effect, although closing the device also does this
+ * SDL_HapticDestroyEffect( haptic, effect_id );
+ *
+ * // Close the device
+ * SDL_HapticClose(haptic);
+ *
+ * return 0; // Success
+ *}
+
+ {**
+ * SDL_Haptic
+ *
+ * The haptic structure used to identify an SDL haptic.
+ *
+ * SDL_HapticOpen
+ * SDL_HapticOpenFromJoystick
+ * SDL_HapticClose
+ *}
+type
+ PPSDL_Haptic = ^PSDL_Haptic;
+ PSDL_Haptic = type Pointer;
+
+ {**
+ * Haptic features
+ *
+ * Different haptic features a device can have.
+ *}
+
+ {**
+ * Haptic effects
+ *}
+
+ {**
+ * Constant effect supported.
+ *
+ * Constant haptic effect.
+ *
+ * SDL_HapticCondition
+ *}
+const
+ SDL_HAPTIC_CONSTANT = (1 shl 0);
+
+ {**
+ * Sine wave effect supported.
+ *
+ * Periodic haptic effect that simulates sine waves.
+ *
+ * SDL_HapticPeriodic
+ *}
+const
+ SDL_HAPTIC_SINE = (1 shl 1);
+
+ {**
+ * Square wave effect supported.
+ *
+ * Periodic haptic effect that simulates square waves.
+ *
+ * SDL_HapticPeriodic
+ *}
+const
+ SDL_HAPTIC_LEFTRIGHT = (1 shl 2);
+
+ { !!! FIXME: put this back when we have more bits in 2.1 }
+ { #define SDL_HAPTIC_SQUARE (1<<2) }
+ SDL_HAPTIC_SQUARE = (1 shl 2); // SDL2-For-Pascal: Out-commented in C code.
+ // Why not keeping it for
+ // compatibility here?
+
+ {**
+ * Triangle wave effect supported.
+ *
+ * Periodic haptic effect that simulates triangular waves.
+ *
+ * SDL_HapticPeriodic
+ *}
+const
+ SDL_HAPTIC_TRIANGLE = (1 shl 3);
+
+ {**
+ * Sawtoothup wave effect supported.
+ *
+ * Periodic haptic effect that simulates saw tooth up waves.
+ *
+ * SDL_HapticPeriodic
+ *}
+const
+ SDL_HAPTIC_SAWTOOTHUP = (1 shl 4);
+
+ {**
+ * Sawtoothdown wave effect supported.
+ *
+ * Periodic haptic effect that simulates saw tooth down waves.
+ *
+ * SDL_HapticPeriodic
+ *}
+const
+ SDL_HAPTIC_SAWTOOTHDOWN = (1 shl 5);
+
+ {**
+ * Ramp effect supported.
+ *
+ * Ramp haptic effect.
+ *
+ * SDL_HapticRamp
+ *}
+const
+ SDL_HAPTIC_RAMP = (1 shl 6);
+
+ {**
+ * Spring effect supported - uses axes position.
+ *
+ * Condition haptic effect that simulates a spring. Effect is based on the
+ * axes position.
+ *
+ * SDL_HapticCondition
+ *}
+const
+ SDL_HAPTIC_SPRING = (1 shl 7);
+
+ {**
+ * Damper effect supported - uses axes velocity.
+ *
+ * Condition haptic effect that simulates dampening. Effect is based on the
+ * axes velocity.
+ *
+ * SDL_HapticCondition
+ *}
+const
+ SDL_HAPTIC_DAMPER = (1 shl 8);
+
+ {**
+ * Inertia effect supported - uses axes acceleration.
+ *
+ * Condition haptic effect that simulates inertia. Effect is based on the axes
+ * acceleration.
+ *
+ * SDL_HapticCondition
+ *}
+const
+ SDL_HAPTIC_INERTIA = (1 shl 9);
+
+ {**
+ * Friction effect supported - uses axes movement.
+ *
+ * Condition haptic effect that simulates friction. Effect is based on the
+ * axes movement.
+ *
+ * SDL_HapticCondition
+ *}
+const
+ SDL_HAPTIC_FRICTION = (1 shl 10);
+
+ {**
+ * Custom effect is supported.
+ *
+ * User defined custom haptic effect.
+ *}
+const
+ SDL_HAPTIC_CUSTOM = (1 shl 11);
+
+ {*Haptic effects*}
+
+ {* These last few are features the device has, not effects *}
+
+ {**
+ * Device can set global gain.
+ *
+ * Device supports setting the global gain.
+ *
+ * SDL_HapticSetGain
+ *}
+const
+ SDL_HAPTIC_GAIN = (1 shl 12);
+
+ {**
+ * Device can set autocenter.
+ *
+ * Device supports setting autocenter.
+ *
+ * SDL_HapticSetAutocenter
+ *}
+const
+ SDL_HAPTIC_AUTOCENTER = (1 shl 13);
+
+ {**
+ * Device can be queried for effect status.
+ *
+ * Device can be queried for effect status.
+ *
+ * SDL_HapticGetEffectStatus
+ *}
+const
+ SDL_HAPTIC_STATUS = (1 shl 14);
+
+ {**
+ * Device can be paused.
+ *
+ * SDL_HapticPause
+ * SDL_HapticUnpause
+ *}
+const
+ SDL_HAPTIC_PAUSE = (1 shl 15);
+
+ {**
+ * Direction encodings
+ *}
+
+ {**
+ * Uses polar coordinates for the direction.
+ *
+ * SDL_HapticDirection
+ *}
+const
+ SDL_HAPTIC_POLAR = 0;
+
+ {**
+ * Uses cartesian coordinates for the direction.
+ *
+ * SDL_HapticDirection
+ *}
+const
+ SDL_HAPTIC_CARTESIAN = 1;
+
+ {**
+ * Uses spherical coordinates for the direction.
+ *
+ * SDL_HapticDirection
+ *}
+const
+ SDL_HAPTIC_SPHERICAL = 2;
+
+ {**
+ * \brief Use this value to play an effect on the steering wheel axis. This
+ * provides better compatibility across platforms and devices as SDL will guess
+ * the correct axis.
+ * \sa SDL_HapticDirection
+ *}
+const
+ SDL_HAPTIC_STEERING_AXIS = 3;
+
+ {*
+ * Misc defines.
+ *}
+
+ {**
+ * Used to play a device an infinite number of times.
+ *
+ * SDL_HapticRunEffect
+ *}
+const
+ SDL_HAPTIC_INFINITY = 4294967295; // C: 4294967295U
+
+ {**
+ * Structure that represents a haptic direction.
+ *
+ * Directions can be specified by:
+ * - SDL_HAPTIC_POLAR : Specified by polar coordinates.
+ * - SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates.
+ * - SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates.
+ *
+ * Cardinal directions of the haptic device are relative to the positioning
+ * of the device. North is considered to be away from the user.
+ *
+ * The following diagram represents the cardinal directions:
+ *
+ .--.
+ |__| .-------.
+ |=.| |.-----.|
+ |--| || ||
+ | | |'-----'|
+ |__|~')_____('
+ [ COMPUTER ]
+
+
+ North (0,-1)
+ ^
+ |
+ |
+ (1,0) West <----[ HAPTIC ]----> East (-1,0)
+ |
+ |
+ v
+ South (0,1)
+
+
+ [ USER ]
+ \|||/
+ (o o)
+ ---ooO-(_)-Ooo---
+
+ *
+ * If type is SDL_HAPTIC_POLAR, direction is encoded by hundredths of a
+ * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses
+ * the first dir parameter. The cardinal directions would be:
+ * - North: 0 (0 degrees)
+ * - East: 9000 (90 degrees)
+ * - South: 18000 (180 degrees)
+ * - West: 27000 (270 degrees)
+ *
+ * If type is SDL_HAPTIC_CARTESIAN, direction is encoded by three positions
+ * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses
+ * the first three dir parameters. The cardinal directions would be:
+ * - North: 0,-1, 0
+ * - East: -1, 0, 0
+ * - South: 0, 1, 0
+ * - West: 1, 0, 0
+ *
+ * The Z axis represents the height of the effect if supported, otherwise
+ * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you
+ * can use any multiple you want, only the direction matters.
+ *
+ * If type is SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations.
+ * The first two dir parameters are used. The dir parameters are as
+ * follows (all values are in hundredths of degrees):
+ * - Degrees from (1, 0) rotated towards (0, 1).
+ * - Degrees towards (0, 0, 1) (device needs at least 3 axes).
+ *
+ *
+ * Example of force coming from the south with all encodings (force coming
+ * from the south means the user will have to pull the stick to counteract):
+ *
+ * SDL_HapticDirection direction;
+ *
+ * // Cartesian directions
+ * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding.
+ * direction.dir[0] = 0; // X position
+ * direction.dir[1] = 1; // Y position
+ * // Assuming the device has 2 axes, we don't need to specify third parameter.
+ *
+ * // Polar directions
+ * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
+ * direction.dir[0] = 18000; // Polar only uses first parameter
+ *
+ * // Spherical coordinates
+ * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding
+ * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters.
+ *
+ *
+ * SDL_HAPTIC_POLAR
+ * SDL_HAPTIC_CARTESIAN
+ * SDL_HAPTIC_SPHERICAL
+ * SDL_HapticEffect
+ * SDL_HapticNumAxes
+ *}
+type
+ PPSDL_HapticDirection = ^PSDL_HapticDirection;
+ PSDL_HapticDirection = ^TSDL_HapticDirection;
+ TSDL_HapticDirection = record
+ type_: cuint8; {**< The type of encoding. *}
+ dir: array[0..2] of cint32; {**< The encoded direction. *}
+ end;
+
+ {**
+ * A structure containing a template for a Constant effect.
+ *
+ * The struct is exclusive to the ::SDL_HAPTIC_CONSTANT effect.
+ *
+ * A constant effect applies a constant force in the specified direction
+ * to the joystick.
+ *
+ * SDL_HAPTIC_CONSTANT
+ * SDL_HapticEffect
+ *}
+type
+ PPSDL_HapticConstant = ^PSDL_HapticConstant;
+ PSDL_HapticConstant = ^TSDL_HapticConstant;
+ TSDL_HapticConstant = record
+ {* Header *}
+ type_: cuint16; {**< SDL_HAPTIC_CONSTANT *}
+ direction: TSDL_HapticDirection; {**< Direction of the effect. *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect. *}
+ delay: cuint16; {**< Delay before starting the effect. *}
+
+ {* Trigger *}
+ button: cuint16; {**< Button that triggers the effect. *}
+ interval: cuint16; {**< How soon it can be triggered again after button. *}
+
+ {* Constant *}
+ level: cint16; {**< Strength of the constant effect. *}
+
+ {* Envelope *}
+ attack_length: cuint16; {**< Duration of the attack. *}
+ attack_level: cuint16; {**< Level at the start of the attack. *}
+ fade_length: cuint16; {**< Duration of the fade. *}
+ fade_level: cuint16; {**< Level at the end of the fade. *}
+ end;
+
+ {**
+ * A structure containing a template for a Periodic effect.
+ *
+ * The struct handles the following effects:
+ * - SDL_HAPTIC_SINE
+ * - SDL_HAPTIC_SQUARE
+ * - SDL_HAPTIC_TRIANGLE
+ * - SDL_HAPTIC_SAWTOOTHUP
+ * - SDL_HAPTIC_SAWTOOTHDOWN
+ *
+ * A periodic effect consists in a wave-shaped effect that repeats itself
+ * over time. The type determines the shape of the wave and the parameters
+ * determine the dimensions of the wave.
+ *
+ * Phase is given by hundredth of a cycle meaning that giving the phase a value
+ * of 9000 will displace it 25% of its period. Here are sample values:
+ * - 0: No phase displacement.
+ * - 9000: Displaced 25% of its period.
+ * - 18000: Displaced 50% of its period.
+ * - 27000: Displaced 75% of its period.
+ * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred.
+ *
+ * Examples:
+ *
+ SDL_HAPTIC_SINE
+ __ __ __ __
+ / \ / \ / \ /
+ / \__/ \__/ \__/
+
+ SDL_HAPTIC_SQUARE
+ __ __ __ __ __
+ | | | | | | | | | |
+ | |__| |__| |__| |__| |
+
+ SDL_HAPTIC_TRIANGLE
+ /\ /\ /\ /\ /\
+ / \ / \ / \ / \ /
+ / \/ \/ \/ \/
+
+ SDL_HAPTIC_SAWTOOTHUP
+ /| /| /| /| /| /| /|
+ / | / | / | / | / | / | / |
+ / |/ |/ |/ |/ |/ |/ |
+
+ SDL_HAPTIC_SAWTOOTHDOWN
+ \ |\ |\ |\ |\ |\ |\ |
+ \ | \ | \ | \ | \ | \ | \ |
+ \| \| \| \| \| \| \|
+
+ *
+ * SDL_HAPTIC_SINE
+ * SDL_HAPTIC_SQUARE
+ * SDL_HAPTIC_TRIANGLE
+ * SDL_HAPTIC_SAWTOOTHUP
+ * SDL_HAPTIC_SAWTOOTHDOWN
+ * SDL_HapticEffect
+ *}
+type
+ PPSDL_HapticPeriodic = ^PSDL_HapticPeriodic;
+ PSDL_HapticPeriodic = ^TSDL_HapticPeriodic;
+ TSDL_HapticPeriodic = record
+ { Header *}
+ type_: cuint16; {**< SDL_HAPTIC_SINE, SDL_HAPTIC_SQUARE,
+ SDL_HAPTIC_TRIANGLE, SDL_HAPTIC_SAWTOOTHUP or
+ SDL_HAPTIC_SAWTOOTHDOWN *}
+ direction: TSDL_HapticDirection; {**< Direction of the effect. *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect. *}
+ delay: cuint16; {**< Delay before starting the effect. *}
+
+ {* Trigger *}
+ button: cuint16; {**< Button that triggers the effect. *}
+ interval: cuint16; {**< How soon it can be triggered again after button. *}
+
+ {* Periodic *}
+ period: cuint16; {**< Period of the wave. *}
+ magnitude: cint16; {**< Peak value. *}
+ offset: cint16; {**< Mean value of the wave. *}
+ phase: cuint16; {**< Horizontal shift given by hundredth of a cycle. *}
+
+ {* Envelope *}
+ attack_length: cuint16; {**< Duration of the attack. *}
+ attack_level: cuint16; {**< Level at the start of the attack. *}
+ fade_length: cuint16; {**< Duration of the fade. *}
+ fade_level: cuint16; {**< Level at the end of the fade. *}
+ end;
+
+ {**
+ * A structure containing a template for a Condition effect.
+ *
+ * The struct handles the following effects:
+ * - SDL_HAPTIC_SPRING: Effect based on axes position.
+ * - SDL_HAPTIC_DAMPER: Effect based on axes velocity.
+ * - SDL_HAPTIC_INERTIA: Effect based on axes acceleration.
+ * - SDL_HAPTIC_FRICTION: Effect based on axes movement.
+ *
+ * Direction is handled by condition internals instead of a direction member.
+ * The condition effect specific members have three parameters. The first
+ * refers to the X axis, the second refers to the Y axis and the third
+ * refers to the Z axis. The right terms refer to the positive side of the
+ * axis and the left terms refer to the negative side of the axis. Please
+ * refer to the ::SDL_HapticDirection diagram for which side is positive and
+ * which is negative.
+ *
+ * SDL_HapticDirection
+ * SDL_HAPTIC_SPRING
+ * SDL_HAPTIC_DAMPER
+ * SDL_HAPTIC_INERTIA
+ * SDL_HAPTIC_FRICTION
+ * SDL_HapticEffect
+ *}
+type
+ PPSDL_HapticCondition = ^PSDL_HapticCondition;
+ PSDL_HapticCondition = ^TSDL_HapticCondition;
+ TSDL_HapticCondition = record
+ {* Header *}
+ type_: cuint16; {**< SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER,
+ SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION *}
+ direction: TSDL_HapticDirection; {**< Direction of the effect - Not used ATM. *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect. *}
+ delay: cuint16; {**< Delay before starting the effect. *}
+
+ {* Trigger *}
+ button: cuint16; {**< Button that triggers the effect. *}
+ interval: cuint16; {**< How soon it can be triggered again after button. *}
+
+ {* Condition *}
+ right_sat: array[0..2] of cuint16; {**< Level when joystick is to the positive side. *}
+ left_sat: array[0..2] of cuint16; {**< Level when joystick is to the negative side. *}
+ right_coeff: array[0..2] of cint16;{**< How fast to increase the force towards the positive side. *}
+ left_coeff: array[0..2] of cint16; {**< How fast to increase the force towards the negative side. *}
+ deadband: array[0..2] of cuint16; {**< Size of the dead zone. *}
+ center: array[0..2] of cint16; {**< Position of the dead zone. *}
+ end;
+
+ {**
+ * A structure containing a template for a Ramp effect.
+ *
+ * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect.
+ *
+ * The ramp effect starts at start strength and ends at end strength.
+ * It augments in linear fashion. If you use attack and fade with a ramp
+ * the effects get added to the ramp effect making the effect become
+ * quadratic instead of linear.
+ *
+ * SDL_HAPTIC_RAMP
+ * SDL_HapticEffect
+ *}
+type
+ PPSDL_HapticRamp = ^PSDL_HapticRamp;
+ PSDL_HapticRamp = ^TSDL_HapticRamp;
+ TSDL_HapticRamp = record
+ {* Header *}
+ type_: cuint16; {**< SDL_HAPTIC_RAMP *}
+ direction: TSDL_HapticDirection; {**< Direction of the effect. *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect. *}
+ delay: cuint16; {**< Delay before starting the effect. *}
+
+ {* Trigger *}
+ button: cuint16; {**< Button that triggers the effect. *}
+ interval: cuint16; {**< How soon it can be triggered again after button. *}
+
+ {* Ramp *}
+ start: cint16; {**< Beginning strength level. *}
+ end_: cint16; {**< Ending strength level. *}
+
+ {* Envelope *}
+ attack_length: cuint16; {**< Duration of the attack. *}
+ attack_level: cuint16; {**< Level at the start of the attack. *}
+ fade_length: cuint16; {**< Duration of the fade. *}
+ fade_level: cuint16; {**< Level at the end of the fade. *}
+ end;
+
+ {**
+ * \brief A structure containing a template for a Left/Right effect.
+ *
+ * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect.
+ *
+ * The Left/Right effect is used to explicitly control the large and small
+ * motors, commonly found in modern game controllers. The small (right) motor
+ * is high frequency, and the large (left) motor is low frequency.
+ *
+ * \sa SDL_HAPTIC_LEFTRIGHT
+ * \sa SDL_HapticEffect
+ *}
+type
+ TSDL_HapticLeftRight = record
+ {* Header *}
+ type_: cuint16; {**< ::SDL_HAPTIC_LEFTRIGHT *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect in milliseconds. *}
+
+ {* Rumble *}
+ large_magnitude: cuint16; {**< Control of the large controller motor. *}
+ small_magnitude: cuint16; {**< Control of the small controller motor. *}
+ end;
+
+ {**
+ * A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect.
+ *
+ * A custom force feedback effect is much like a periodic effect, where the
+ * application can define its exact shape. You will have to allocate the
+ * data yourself. Data should consist of channels * samples Uint16 samples.
+ *
+ * If channels is one, the effect is rotated using the defined direction.
+ * Otherwise it uses the samples in data for the different axes.
+ *
+ * SDL_HAPTIC_CUSTOM
+ * SDL_HapticEffect
+ *}
+type
+ PPSDL_HapticCustom = ^PSDL_HapticCustom;
+ PSDL_HapticCustom = ^TSDL_HapticCustom;
+ TSDL_HapticCustom = record
+ {* Header *}
+ type_: cuint16; {**< SDL_HAPTIC_CUSTOM *}
+ direction: TSDL_HapticDirection; {**< Direction of the effect. *}
+
+ {* Replay *}
+ length: cuint32; {**< Duration of the effect. *}
+ delay: cuint16; {**< Delay before starting the effect. *}
+
+ {* Trigger *}
+ button: cuint16; {**< Button that triggers the effect. *}
+ interval: cuint16; {**< How soon it can be triggered again after button. *}
+
+ {* Custom *}
+ channels: cuint8; {**< Axes to use, minimum of one. *}
+ period: cuint16; {**< Sample periods. *}
+ samples: cuint16; {**< Amount of samples. *}
+ data: pcuint16; {**< Should contain channels*samples items. *}
+
+ {* Envelope *}
+ attack_length: cuint16; {**< Duration of the attack. *}
+ attack_level: cuint16; {**< Level at the start of the attack. *}
+ fade_length: cuint16; {**< Duration of the fade. *}
+ fade_level: cuint16; {**< Level at the end of the fade. *}
+ end;
+
+ {**
+ * The generic template for any haptic effect.
+ *
+ * All values max at 32767 (0x7FFF). Signed values also can be negative.
+ * Time values unless specified otherwise are in milliseconds.
+ *
+ * You can also pass SDL_HAPTIC_INFINITY to length instead of a 0-32767
+ * value. Neither delay, interval, attack_length nor fade_length support
+ * SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends.
+ *
+ * Additionally, the SDL_HAPTIC_RAMP effect does not support a duration of
+ * SDL_HAPTIC_INFINITY.
+ *
+ * Button triggers may not be supported on all devices, it is advised to not
+ * use them if possible. Buttons start at index 1 instead of index 0 like
+ * the joystick.
+ *
+ * If both attack_length and fade_level are 0, the envelope is not used,
+ * otherwise both values are used.
+ *
+ * Common parts:
+ *
+ * // Replay - All effects have this
+ * Uint32 length; // Duration of effect (ms).
+ * Uint16 delay; // Delay before starting effect.
+ *
+ * // Trigger - All effects have this
+ * Uint16 button; // Button that triggers effect.
+ * Uint16 interval; // How soon before effect can be triggered again.
+ *
+ * // Envelope - All effects except condition effects have this
+ * Uint16 attack_length; // Duration of the attack (ms).
+ * Uint16 attack_level; // Level at the start of the attack.
+ * Uint16 fade_length; // Duration of the fade out (ms).
+ * Uint16 fade_level; // Level at the end of the fade.
+ *
+ *
+ *
+ * Here we have an example of a constant effect evolution in time:
+ *
+ Strength
+ ^
+ |
+ | effect level --> _________________
+ | / \
+ | / \
+ | / \
+ | / \
+ | attack_level --> | \
+ | | | <--- fade_level
+ |
+ +--------------------------------------------------> Time
+ [--] [---]
+ attack_length fade_length
+
+ [------------------][-----------------------]
+ delay length
+
+ *
+ * Note either the attack_level or the fade_level may be above the actual
+ * effect level.
+ *
+ * SDL_HapticConstant
+ * SDL_HapticPeriodic
+ * SDL_HapticCondition
+ * SDL_HapticRamp
+ * SDL_HapticCustom
+ *}
+type
+ PPSDL_HapticEffect = ^PSDL_HapticEffect;
+ PSDL_HapticEffect = ^TSDL_HapticEffect;
+ TSDL_HapticEffect = record
+ case cint of
+ {* Common for all force feedback effects *}
+ 0: (type_: cuint16); {**< Effect type. *}
+ 1: (constant: TSDL_HapticConstant;); {**< Constant effect. *}
+ 2: (periodic: TSDL_HapticPeriodic;); {**< Periodic effect. *}
+ 3: (condition: TSDL_HapticCondition;); {**< Condition effect. *}
+ 4: (ramp: TSDL_HapticRamp;); {**< Ramp effect. *}
+ 5: (leftright: TSDL_HapticLeftRight;); {**< Custom effect. *}
+ 6: (custom: TSDL_HapticCustom;); {**< Custom effect. *}
+ end;
+
+ {* Function prototypes *}
+
+ {**
+ * Count the number of haptic devices attached to the system.
+ *
+ * \returns the number of haptic devices detected on the system or a negative
+ * error code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticName
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_NumHaptics: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_NumHaptics' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Get the implementation dependent name of a haptic device.
+ *
+ * This can be called before any joysticks are opened. If no name can be
+ * found, this function returns NULL.
+ *
+ * \param device_index index of the device to query.
+ * \returns the name of the device or NULL on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_NumHaptics
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticName_func = function(device_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_HapticName : TSDL_HapticName_func = Nil;
+{$else}
+
+function SDL_HapticName(device_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticName' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Open a haptic device for use.
+ *
+ * The index passed as an argument refers to the N'th haptic device on this
+ * system.
+ *
+ * When opening a haptic device, its gain will be set to maximum and
+ * autocenter will be disabled. To modify these values use SDL_HapticSetGain()
+ * and SDL_HapticSetAutocenter().
+ *
+ * \param device_index index of the device to open
+ * \returns the device identifier or NULL on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticClose
+ * \sa SDL_HapticIndex
+ * \sa SDL_HapticOpenFromJoystick
+ * \sa SDL_HapticOpenFromMouse
+ * \sa SDL_HapticPause
+ * \sa SDL_HapticSetAutocenter
+ * \sa SDL_HapticSetGain
+ * \sa SDL_HapticStopAll
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticOpen_func = function(device_index: cint): PSDL_Haptic; cdecl;
+Var
+ SDL_HapticOpen : TSDL_HapticOpen_func = Nil;
+{$else}
+
+function SDL_HapticOpen(device_index: cint): PSDL_Haptic; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticOpen' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Check if the haptic device at the designated index has been opened.
+ *
+ * \param device_index the index of the device to query
+ * \returns 1 if it has been opened, 0 if it hasn't or on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticIndex
+ * \sa SDL_HapticOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticOpened_func = function(device_index: cint): cint; cdecl;
+Var
+ SDL_HapticOpened : TSDL_HapticOpened_func = Nil;
+{$else}
+
+function SDL_HapticOpened(device_index: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticOpened' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the index of a haptic device.
+ *
+ * \param haptic the SDL_Haptic device to query
+ * \returns the index of the specified haptic device or a negative error code
+ * on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpen
+ * \sa SDL_HapticOpened
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticIndex_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticIndex : TSDL_HapticIndex_func = Nil;
+{$else}
+
+function SDL_HapticIndex(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Query whether or not the current mouse has haptic capabilities.
+ *
+ * \returns SDL_TRUE if the mouse is haptic or SDL_FALSE if it isn't.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpenFromMouse
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_MouseIsHaptic: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MouseInHaptic' {$ENDIF} {$ENDIF};
+
+ {**
+ * Try to open a haptic device from the current mouse.
+ *
+ * \returns the haptic device identifier or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpen
+ * \sa SDL_MouseIsHaptic
+ *}
+function SDL_HapticOpenFromMouse: PSDL_Haptic; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticOpenFromMouse' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Query if a joystick has haptic features.
+ *
+ * \param joystick the SDL_Joystick to test for haptic capabilities
+ * \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a
+ * negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpenFromJoystick
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickIsHaptic_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickIsHaptic : TSDL_JoystickIsHaptic_func = Nil;
+{$else}
+
+function SDL_JoystickIsHaptic(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickIsHaptic' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Open a haptic device for use from a joystick device.
+ *
+ * You must still close the haptic device separately. It will not be closed
+ * with the joystick.
+ *
+ * When opened from a joystick you should first close the haptic device before
+ * closing the joystick device. If not, on some implementations the haptic
+ * device will also get unallocated and you'll be unable to use force feedback
+ * on that device.
+ *
+ * \param joystick the SDL_Joystick to create a haptic device from
+ * \returns a valid haptic device identifier on success or NULL on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticClose
+ * \sa SDL_HapticOpen
+ * \sa SDL_JoystickIsHaptic
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticOpenFromJoystick_func = function(joystick: PSDL_Joystick): PSDL_Haptic; cdecl;
+Var
+ SDL_HapticOpenFromJoystick : TSDL_HapticOpenFromJoystick_func = Nil;
+{$else}
+
+function SDL_HapticOpenFromJoystick(joystick: PSDL_Joystick): PSDL_Haptic; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticOpenFromJoystick' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Close a haptic device previously opened with SDL_HapticOpen().
+ *
+ * \param haptic the SDL_Haptic device to close
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticClose_proc = procedure(haptic: PSDL_Haptic); cdecl;
+Var
+ SDL_HapticClose : TSDL_HapticClose_proc = Nil;
+{$else}
+
+procedure SDL_HapticClose(haptic: PSDL_Haptic); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticClose' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the number of effects a haptic device can store.
+ *
+ * On some platforms this isn't fully supported, and therefore is an
+ * approximation. Always check to see if your created effect was actually
+ * created and do not rely solely on SDL_HapticNumEffects().
+ *
+ * \param haptic the SDL_Haptic device to query
+ * \returns the number of effects the haptic device can store or a negative
+ * error code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticNumEffectsPlaying
+ * \sa SDL_HapticQuery
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticNumEffects_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticNumEffects : TSDL_HapticNumEffects_func = Nil;
+{$else}
+
+function SDL_HapticNumEffects(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticNumEffects' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the number of effects a haptic device can play at the same time.
+ *
+ * This is not supported on all platforms, but will always return a value.
+ *
+ * \param haptic the SDL_Haptic device to query maximum playing effects
+ * \returns the number of effects the haptic device can play at the same time
+ * or a negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticNumEffects
+ * \sa SDL_HapticQuery
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticNumEffectsPlaying_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticNumEffectsPlaying : TSDL_HapticNumEffectsPlaying_func = Nil;
+{$else}
+
+function SDL_HapticNumEffectsPlaying(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticNumEffectsPlaying' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the haptic device's supported features in bitwise manner.
+ *
+ * \param haptic the SDL_Haptic device to query
+ * \returns a list of supported haptic features in bitwise manner (OR'd), or 0
+ * on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticEffectSupported
+ * \sa SDL_HapticNumEffects
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticQuery_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticQuery : TSDL_HapticQuery_func = Nil;
+{$else}
+
+function SDL_HapticQuery(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticQuery' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the number of haptic axes the device has.
+ *
+ * The number of haptic axes might be useful if working with the
+ * SDL_HapticDirection effect.
+ *
+ * \param haptic the SDL_Haptic device to query
+ * \returns the number of axes on success or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticNumAxes_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticNumAxes : TSDL_HapticNumAxes_func = Nil;
+{$else}
+
+function SDL_HapticNumAxes(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticNumAxes' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Check to see if an effect is supported by a haptic device.
+ *
+ * \param haptic the SDL_Haptic device to query
+ * \param effect the desired effect to query
+ * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a
+ * negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticNewEffect
+ * \sa SDL_HapticQuery
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticEffectSupported_func = function(haptic: PSDL_Haptic; effect: PSDL_HapticEffect): cint; cdecl;
+Var
+ SDL_HapticEffectSupported : TSDL_HapticEffectSupported_func = Nil;
+{$else}
+
+function SDL_HapticEffectSupported(haptic: PSDL_Haptic; effect: PSDL_HapticEffect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticEffectSupported' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Create a new haptic effect on a specified device.
+ *
+ * \param haptic an SDL_Haptic device to create the effect on
+ * \param effect an SDL_HapticEffect structure containing the properties of
+ * the effect to create
+ * \returns the ID of the effect on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticDestroyEffect
+ * \sa SDL_HapticRunEffect
+ * \sa SDL_HapticUpdateEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticNewEffect_func = function(haptic: PSDL_Haptic; effect: PSDL_HapticEffect): cint; cdecl;
+Var
+ SDL_HapticNewEffect : TSDL_HapticNewEffect_func = Nil;
+{$else}
+
+function SDL_HapticNewEffect(haptic: PSDL_Haptic; effect: PSDL_HapticEffect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticNewEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Update the properties of an effect.
+ *
+ * Can be used dynamically, although behavior when dynamically changing
+ * direction may be strange. Specifically the effect may re-upload itself and
+ * start playing from the start. You also cannot change the type either when
+ * running SDL_HapticUpdateEffect().
+ *
+ * \param haptic the SDL_Haptic device that has the effect
+ * \param effect the identifier of the effect to update
+ * \param data an SDL_HapticEffect structure containing the new effect
+ * properties to use
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticDestroyEffect
+ * \sa SDL_HapticNewEffect
+ * \sa SDL_HapticRunEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticUpdateEffect_func = function(haptic: PSDL_Haptic; effect: cint; data: PSDL_HapticEffect): cint; cdecl;
+Var
+ SDL_HapticUpdateEffect : TSDL_HapticUpdateEffect_func = Nil;
+{$else}
+
+function SDL_HapticUpdateEffect(haptic: PSDL_Haptic; effect: cint; data: PSDL_HapticEffect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticUpdateEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Run the haptic effect on its associated haptic device.
+ *
+ * To repeat the effect over and over indefinitely, set `iterations` to
+ * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make
+ * one instance of the effect last indefinitely (so the effect does not fade),
+ * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY`
+ * instead.
+ *
+ * \param haptic the SDL_Haptic device to run the effect on
+ * \param effect the ID of the haptic effect to run
+ * \param iterations the number of iterations to run the effect; use
+ * `SDL_HAPTIC_INFINITY` to repeat forever
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticDestroyEffect
+ * \sa SDL_HapticGetEffectStatus
+ * \sa SDL_HapticStopEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticRunEffect_func = function(haptic: PSDL_Haptic; effect: cint; iterations: cuint32): cint; cdecl;
+Var
+ SDL_HapticRunEffect : TSDL_HapticRunEffect_func = Nil;
+{$else}
+
+function SDL_HapticRunEffect(haptic: PSDL_Haptic; effect: cint; iterations: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticRunEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Stop the haptic effect on its associated haptic device.
+ *
+ * *
+ *
+ * \param haptic the SDL_Haptic device to stop the effect on
+ * \param effect the ID of the haptic effect to stop
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticDestroyEffect
+ * \sa SDL_HapticRunEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticStopEffect_func = function(haptic: PSDL_Haptic; effect: cint): cint; cdecl;
+Var
+ SDL_HapticStopEffect : TSDL_HapticStopEffect_func = Nil;
+{$else}
+
+function SDL_HapticStopEffect(haptic: PSDL_Haptic; effect: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticStopEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Destroy a haptic effect on the device.
+ *
+ * This will stop the effect if it's running. Effects are automatically
+ * destroyed when the device is closed.
+ *
+ * \param haptic the SDL_Haptic device to destroy the effect on
+ * \param effect the ID of the haptic effect to destroy
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticNewEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticDestroyEffect_proc = procedure(haptic: PSDL_Haptic; effect: cint); cdecl;
+Var
+ SDL_HapticDestroyEffect : TSDL_HapticDestroyEffect_proc = Nil;
+{$else}
+
+procedure SDL_HapticDestroyEffect(haptic: PSDL_Haptic; effect: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticDestroyEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the status of the current effect on the specified haptic device.
+ *
+ * Device must support the SDL_HAPTIC_STATUS feature.
+ *
+ * \param haptic the SDL_Haptic device to query for the effect status on
+ * \param effect the ID of the haptic effect to query its status
+ * \returns 0 if it isn't playing, 1 if it is playing, or a negative error
+ * code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticRunEffect
+ * \sa SDL_HapticStopEffect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticGetEffectStatus_func = function(haptic: PSDL_Haptic; effect: cint): cint; cdecl;
+Var
+ SDL_HapticGetEffectStatus : TSDL_HapticGetEffectStatus_func = Nil;
+{$else}
+
+function SDL_HapticGetEffectStatus(haptic: PSDL_Haptic; effect: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticGetEffectStatus' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the global gain of the specified haptic device.
+ *
+ * Device must support the SDL_HAPTIC_GAIN feature.
+ *
+ * The user may specify the maximum gain by setting the environment variable
+ * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to
+ * SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the
+ * maximum.
+ *
+ * \param haptic the SDL_Haptic device to set the gain on
+ * \param gain value to set the gain to, should be between 0 and 100 (0 - 100)
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticQuery
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticSetGain_func = function(haptic: PSDL_Haptic; gain: cint): cint; cdecl;
+Var
+ SDL_HapticSetGain : TSDL_HapticSetGain_func = Nil;
+{$else}
+
+function SDL_HapticSetGain(haptic: PSDL_Haptic; gain: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticSetGain' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the global autocenter of the device.
+ *
+ * Autocenter should be between 0 and 100. Setting it to 0 will disable
+ * autocentering.
+ *
+ * Device must support the SDL_HAPTIC_AUTOCENTER feature.
+ *
+ * \param haptic the SDL_Haptic device to set autocentering on
+ * \param autocenter value to set autocenter to (0-100)
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticQuery
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticSetAutocenter_func = function(haptic: PSDL_Haptic; autocenter: cint): cint; cdecl;
+Var
+ SDL_HapticSetAutocenter : TSDL_HapticSetAutocenter_func = Nil;
+{$else}
+
+function SDL_HapticSetAutocenter(haptic: PSDL_Haptic; autocenter: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticSetAutocenter' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Pause a haptic device.
+ *
+ * Device must support the `SDL_HAPTIC_PAUSE` feature. Call
+ * SDL_HapticUnpause() to resume playback.
+ *
+ * Do not modify the effects nor add new ones while the device is paused. That
+ * can cause all sorts of weird errors.
+ *
+ * \param haptic the SDL_Haptic device to pause
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticUnpause
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticPause_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticPause : TSDL_HapticPause_func = Nil;
+{$else}
+
+function SDL_HapticPause(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticPause' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Unpause a haptic device.
+ *
+ * Call to unpause after SDL_HapticPause().
+ *
+ * \param haptic the SDL_Haptic device to unpause
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticPause
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticUnpause_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticUnpause : TSDL_HapticUnpause_func = Nil;
+{$else}
+
+function SDL_HapticUnpause(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticUnPause' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Stop all the currently playing effects on a haptic device.
+ *
+ * \param haptic the SDL_Haptic device to stop
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticStopAll_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticStopAll : TSDL_HapticStopAll_func = Nil;
+{$else}
+
+function SDL_HapticStopAll(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticStopAll' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Check whether rumble is supported on a haptic device.
+ *
+ * \param haptic haptic device to check for rumble support
+ * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a
+ * negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticRumbleInit
+ * \sa SDL_HapticRumblePlay
+ * \sa SDL_HapticRumbleStop
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticRumbleSupported_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticRumbleSupported : TSDL_HapticRumbleSupported_func = Nil;
+{$else}
+
+function SDL_HapticRumbleSupported(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticRumbleSupported' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Initialize a haptic device for simple rumble playback.
+ *
+ * \param haptic the haptic device to initialize for simple rumble playback
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticOpen
+ * \sa SDL_HapticRumblePlay
+ * \sa SDL_HapticRumbleStop
+ * \sa SDL_HapticRumbleSupported
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticRumbleInit_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticRumbleInit : TSDL_HapticRumbleInit_func = Nil;
+{$else}
+
+function SDL_HapticRumbleInit(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticRumbleInit' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Run a simple rumble effect on a haptic device.
+ *
+ * \param haptic the haptic device to play the rumble effect on
+ * \param strength strength of the rumble to play as a 0-1 float value
+ * \param length length of the rumble to play in milliseconds
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticRumbleInit
+ * \sa SDL_HapticRumbleStop
+ * \sa SDL_HapticRumbleSupported
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticRumblePlay_func = function(haptic: PSDL_Haptic; strength: cfloat; length: cuint32): cint; cdecl;
+Var
+ SDL_HapticRumblePlay : TSDL_HapticRumblePlay_func = Nil;
+{$else}
+
+function SDL_HapticRumblePlay(haptic: PSDL_Haptic; strength: cfloat; length: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticRumblePlay' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Stop the simple rumble on a haptic device.
+ *
+ * \param haptic the haptic device to stop the rumble effect on
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HapticRumbleInit
+ * \sa SDL_HapticRumblePlay
+ * \sa SDL_HapticRumbleSupported
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HapticRumbleStop_func = function(haptic: PSDL_Haptic): cint; cdecl;
+Var
+ SDL_HapticRumbleStop : TSDL_HapticRumbleStop_func = Nil;
+{$else}
+
+function SDL_HapticRumbleStop(haptic: PSDL_Haptic): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HapticRumbleStop' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlhidapi.inc b/units/sdl2_for_pascal/sdlhidapi.inc
new file mode 100644
index 0000000..79d9107
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlhidapi.inc
@@ -0,0 +1,429 @@
+// from SDL_hidapi.h
+
+(**
+ * Header file for SDL HIDAPI functions.
+ *
+ * This is an adaptation of the original HIDAPI interface by Alan Ott,
+ * and includes source code licensed under the following BSD license:
+ *
+ Copyright (c) 2010, Alan Ott, Signal 11 Software
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Signal 11 Software nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ *
+ * If you would like a version of SDL without this code, you can build SDL
+ * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for example
+ * on iOS or tvOS to avoid a dependency on the CoreBluetooth framework.
+ *)
+
+type
+ (**
+ * \brief A handle representing an open HID device.
+ *)
+ PSDL_hid_device = type Pointer;
+
+ PSDL_hid_device_info = ^TSDL_hid_device_info;
+
+ (**
+ * \brief Information about a connected HID device
+ *)
+ TSDL_hid_device_info = record
+ (** Platform-specific device path *)
+ path: PAnsiChar;
+ (** Device Vendor ID *)
+ vendor_id: pcushort;
+ (** Device Product ID *)
+ product_id: pcushort;
+ (** Serial Number *)
+ serial_number: pcwchar_t;
+ (** Device Release Number in binary-coded decimal, also known as Device Version Number *)
+ release_number: cushort;
+ (** Manufacturer String *)
+ manufacturer_string: pcwchar_t;
+ (** Product string *)
+ product_string: pcwchar_t;
+ (** Usage Page for this Device/Interface (Windows/Mac only). *)
+ usage_page: cushort;
+ (** Usage for this Device/Interface (Windows/Mac only). *)
+ usage: cushort;
+ (**
+ * The USB interface which this logical device represents.
+ * Valid on both Linux implementations in all cases.
+ * Valid on the Windows implementation only if the device
+ * contains more than one interface.
+ *)
+ interface_number: cint;
+
+ (**
+ * Additional information about the USB interface.
+ * Valid on libusb and Android implementations.
+ *)
+ interface_class: cint;
+ interface_subclass: cint;
+ interface_protocol: cint;
+
+ (** Pointer to the next device *)
+ next: PSDL_hid_device_info;
+ end;
+
+(**
+ * Initialize the HIDAPI library.
+ *
+ * This function initializes the HIDAPI library. Calling it is not strictly
+ * necessary, as it will be called automatically by SDL_hid_enumerate() and
+ * any of the SDL_hid_open_*() functions if it is needed. This function should
+ * be called at the beginning of execution however, if there is a chance of
+ * HIDAPI handles being opened by different threads simultaneously.
+ *
+ * Each call to this function should have a matching call to SDL_hid_exit()
+ *
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_hid_exit
+ *) {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_hid_init(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_init' {$ENDIF} {$ENDIF};
+
+(**
+ * Finalize the HIDAPI library.
+ *
+ * This function frees all of the static data associated with HIDAPI. It
+ * should be called at the end of execution to avoid memory leaks.
+ *
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_hid_init
+ *)
+function SDL_hid_exit(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_exit' {$ENDIF} {$ENDIF};
+
+(**
+ * Check to see if devices may have been added or removed.
+ *
+ * Enumerating the HID devices is an expensive operation, so you can call this
+ * to see if there have been any system device changes since the last call to
+ * this function. A change in the counter returned doesn't necessarily mean
+ * that anything has changed, but you can call SDL_hid_enumerate() to get an
+ * updated device list.
+ *
+ * Calling this function for the first time may cause a thread or other system
+ * resource to be allocated to track device change notifications.
+ *
+ * \returns a change counter that is incremented with each potential device
+ * change, or 0 if device change detection isn't available.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_hid_enumerate
+ *)
+function SDL_hid_device_change_count(): cUint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_device_change_count' {$ENDIF} {$ENDIF};
+
+(**
+ * Enumerate the HID Devices.
+ *
+ * This function returns a linked list of all the HID devices attached to the
+ * system which match vendor_id and product_id. If `vendor_id` is set to 0
+ * then any vendor matches. If `product_id` is set to 0 then any product
+ * matches. If `vendor_id` and `product_id` are both set to 0, then all HID
+ * devices will be returned.
+ *
+ * \param vendor_id The Vendor ID (VID) of the types of device to open.
+ * \param product_id The Product ID (PID) of the types of device to open.
+ * \returns a pointer to a linked list of type SDL_hid_device_info, containing
+ * information about the HID devices attached to the system, or NIL
+ * in the case of failure. Free this linked list by calling
+ * SDL_hid_free_enumeration().
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_hid_device_change_count
+ *)
+function SDL_hid_enumerate(vendor_id, product_id: cushort): PSDL_hid_device_info; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_enumerate' {$ENDIF} {$ENDIF};
+
+(**
+ * Free an enumeration Linked List
+ *
+ * This function frees a linked list created by SDL_hid_enumerate().
+ *
+ * \param devs Pointer to a list of struct_device returned from
+ * SDL_hid_enumerate().
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+procedure SDL_hid_free_enumeration(devs: PSDL_hid_device_info); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_free_enumeration' {$ENDIF} {$ENDIF};
+
+(**
+ * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally
+ * a serial number.
+ *
+ * If `serial_number` is NULL, the first device with the specified VID and PID
+ * is opened.
+ *
+ * \param vendor_id The Vendor ID (VID) of the device to open.
+ * \param product_id The Product ID (PID) of the device to open.
+ * \param serial_number The Serial Number of the device to open
+ * (optionally NIL).
+ * \returns a pointer to a SDL_hid_device object on success or NIL on
+ * failure.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_open(vendor_id, product_id: cushort; serial_number: pcwchar_t): PSDL_hid_device; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_open' {$ENDIF} {$ENDIF};
+
+(**
+ * Open a HID device by its path name.
+ *
+ * The path name be determined by calling SDL_hid_enumerate(), or a
+ * platform-specific path name can be used (eg: /dev/hidraw0 on Linux).
+ *
+ * \param path The path name of the device to open
+ * \returns a pointer to a SDL_hid_device object on success
+ * or NIL on failure.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_open_path(path: PAnsiChar; bExclusive: cuint): PSDL_hid_device; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_open_path' {$ENDIF} {$ENDIF};
+
+(**
+ * Write an Output report to a HID device.
+ *
+ * The first byte of `data` must contain the Report ID. For devices which only
+ * support a single report, this must be set to 0x0. The remaining bytes
+ * contain the report data. Since the Report ID is mandatory, calls to
+ * SDL_hid_write() will always contain one more byte than the report contains.
+ * For example, if a hid report is 16 bytes long, 17 bytes must be passed to
+ * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report),
+ * followed by the report data (16 bytes). In this example, the length passed
+ * in would be 17.
+ *
+ * SDL_hid_write() will send the data on the first OUT endpoint, if one
+ * exists. If it does not, it will send the data through the Control Endpoint
+ * (Endpoint 0).
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param data The data to send, including the report number as the first
+ * byte.
+ * \param length The length in bytes of the data to send.
+ * \returns the actual number of bytes written and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_write(dev: PSDL_hid_device; data: pcUint8; length: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_write' {$ENDIF} {$ENDIF};
+
+(**
+ * Read an Input report from a HID device with timeout.
+ *
+ * Input reports are returned to the host through the INTERRUPT IN endpoint.
+ * The first byte will contain the Report number if the device uses numbered
+ * reports.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param data A buffer to put the read data into.
+ * \param length The number of bytes to read. For devices with multiple
+ * reports, make sure to read an extra byte for the report
+ * number.
+ * \param milliseconds timeout in milliseconds or -1 for blocking wait.
+ * \returns the actual number of bytes read and -1 on error. If no packet was
+ * available to be read within the timeout period, this function
+ * returns 0.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_read_timeout(dev: PSDL_hid_device; data: pcUint8; length: csize_t; milliseconds: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_read_timeout' {$ENDIF} {$ENDIF};
+
+(**
+ * Read an Input report from a HID device.
+ *
+ * Input reports are returned to the host through the INTERRUPT IN endpoint.
+ * The first byte will contain the Report number if the device uses numbered
+ * reports.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param data A buffer to put the read data into.
+ * \param length The number of bytes to read. For devices with multiple
+ * reports, make sure to read an extra byte for the report
+ * number.
+ * \returns the actual number of bytes read and -1 on error. If no packet was
+ * available to be read and the handle is in non-blocking mode, this
+ * function returns 0.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_read(dev: PSDL_hid_device; data: pcUint8; length: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_read' {$ENDIF} {$ENDIF};
+
+(**
+ * Set the device handle to be non-blocking.
+ *
+ * In non-blocking mode calls to SDL_hid_read() will return immediately with a
+ * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read()
+ * will wait (block) until there is data to read before returning.
+ *
+ * Nonblocking can be turned on and off at any time.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param nonblock enable or not the nonblocking reads - 1 to enable
+ * nonblocking - 0 to disable nonblocking.
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_set_nonblocking(dev: PSDL_hid_device; nonblock: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_set_nonblocking' {$ENDIF} {$ENDIF};
+
+(**
+ * Send a Feature report to the device.
+ *
+ * Feature reports are sent over the Control endpoint as a Set_Report
+ * transfer. The first byte of `data` must contain the Report ID. For devices
+ * which only support a single report, this must be set to 0x0. The remaining
+ * bytes contain the report data. Since the Report ID is mandatory, calls to
+ * SDL_hid_send_feature_report() will always contain one more byte than the
+ * report contains. For example, if a hid report is 16 bytes long, 17 bytes
+ * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for
+ * devices which do not use numbered reports), followed by the report data (16
+ * bytes). In this example, the length passed in would be 17.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param data The data to send, including the report number as the first
+ * byte.
+ * \param length The length in bytes of the data to send, including the report
+ * number.
+ * \returns the actual number of bytes written and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_send_feature_report(dev: PSDL_hid_device; data: pcUint8; length: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_send_feature_report' {$ENDIF} {$ENDIF};
+
+(**
+ * Get a feature report from a HID device.
+ *
+ * Set the first byte of `data` to the Report ID of the report to be read.
+ * Make sure to allow space for this extra byte in `data`. Upon return, the
+ * first byte will still contain the Report ID, and the report data will start
+ * in data[1].
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param data A buffer to put the read data into, including the Report ID.
+ * Set the first byte of `data` to the Report ID of the report to
+ * be read, or set it to zero if your device does not use numbered
+ * reports.
+ * \param length The number of bytes to read, including an extra byte for the
+ * report ID. The buffer can be longer than the actual report.
+ * \returns the number of bytes read plus one for the report ID (which is
+ * still in the first byte), or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_get_feature_report(dev: PSDL_hid_device; data: pcUint8; length: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_get_feature_report' {$ENDIF} {$ENDIF};
+
+(**
+ * Close a HID device.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+procedure SDL_hid_close(dev: PSDL_hid_device); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_close' {$ENDIF} {$ENDIF};
+
+(**
+ * Get The Manufacturer String from a HID device.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param string A wide string buffer to put the data into.
+ * \param maxlen The length of the buffer in multiples of wchar_t.
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_get_manufacturer_string(dev: PSDL_hid_device; str: pcwchar_t; maxlen: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_get_manufacturer_string' {$ENDIF} {$ENDIF};
+
+(**
+ * Get The Product String from a HID device.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param string A wide string buffer to put the data into.
+ * \param maxlen The length of the buffer in multiples of wchar_t.
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_get_product_string(dev: PSDL_hid_device; str: pcwchar_t; maxlen: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_get_product_string' {$ENDIF} {$ENDIF};
+
+(**
+ * Get The Serial Number String from a HID device.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param string A wide string buffer to put the data into.
+ * \param maxlen The length of the buffer in multiples of wchar_t.
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_get_serial_number_string(dev: PSDL_hid_device; str: pcwchar_t; maxlen: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_get_serial_number_string' {$ENDIF} {$ENDIF};
+
+(**
+ * Get a string from a HID device, based on its string index.
+ *
+ * \param dev A device handle returned from SDL_hid_open().
+ * \param string_index The index of the string to get.
+ * \param string A wide string buffer to put the data into.
+ * \param maxlen The length of the buffer in multiples of wchar_t.
+ * \returns 0 on success and -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+function SDL_hid_get_indexed_string(dev: PSDL_hid_device; string_index: cint; str: pcwchar_t; maxlen: csize_t): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_get_indexed_string' {$ENDIF} {$ENDIF};
+
+(**
+ * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers
+ *
+ * \param active SDL_TRUE to start the scan, SDL_FALSE to stop the scan
+ *
+ * \since This function is available since SDL 2.0.18.
+ *)
+procedure SDL_hid_ble_scan(active: TSDL_bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_hid_ble_scan' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlhints.inc b/units/sdl2_for_pascal/sdlhints.inc
new file mode 100644
index 0000000..3f3128b
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlhints.inc
@@ -0,0 +1,2588 @@
+// from "SDL_hints.h"
+
+{**
+ * \file SDL_hints.h
+ *
+ * Official documentation for SDL configuration variables
+ *
+ * This file contains functions to set and get configuration hints,
+ * as well as listing each of them alphabetically.
+ *
+ * The convention for naming hints is SDL_HINT_X, where "SDL_X" is
+ * the environment variable that can be used to override the default.
+ *
+ * In general these hints are just that - they may or may not be
+ * supported or applicable on any given platform, but they provide
+ * a way for an application or user to give the library a hint as
+ * to how they would like the library to work.
+ *}
+
+const
+
+{/**
+ * \brief Override for SDL_GetDisplayUsableBounds()
+ *
+ * If set, this hint will override the expected results for
+ * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want
+ * to do this, but this allows an embedded system to request that some of the
+ * screen be reserved for other uses when paired with a well-behaved
+ * application.
+ *
+ * The contents of this hint must be 4 comma-separated integers, the first
+ * is the bounds x, then y, width and height, in that order.
+ */}
+SDL_HINT_DISPLAY_USABLE_BOUNDS = 'SDL_DISPLAY_USABLE_BOUNDS';
+
+{/**
+ * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
+ *
+ * The variable can be set to the following values:
+ * "0" - Do not scan for Steam Controllers
+ * "1" - Scan for Steam Controllers (the default)
+ *
+ * The default value is "1". This hint must be set before initializing the joystick subsystem.
+ */}
+SDL_HINT_ENABLE_STEAM_CONTROLLERS = 'SDL_ENABLE_STEAM_CONTROLLERS';
+
+{/**
+ * \brief A variable controlling whether SDL logs all events pushed onto its internal queue.
+ *
+ * This variable can be set to the following values:
+ *
+ * "0" - Don't log any events (default)
+ * "1" - Log all events except mouse and finger motion, which are pretty spammy.
+ * "2" - Log all events.
+ *
+ * This is generally meant to be used to debug SDL itself, but can be useful
+ * for application developers that need better visibility into what is going
+ * on in the event queue. Logged events are sent through SDL_Log(), which
+ * means by default they appear on stdout on most platforms or maybe
+ * OutputDebugString() on Windows, and can be funneled by the app with
+ * SDL_LogSetOutputFunction(), etc.
+ *
+ * This hint can be toggled on and off at runtime, if you only need to log
+ * events for a small subset of program execution.
+ */}
+SDL_HINT_EVENT_LOGGING = 'SDL_EVENT_LOGGING';
+
+{**
+ * \brief A variable controlling whether raising the window should be done more forcefully
+ *
+ * This variable can be set to the following values:
+ * "0" - No forcing (the default)
+ * "1" - Extra level of forcing
+ *
+ * At present, this is only an issue under MS Windows, which makes it nearly impossible to
+ * programmatically move a window to the foreground, for "security" reasons. See
+ * http://stackoverflow.com/a/34414846 for a discussion.
+ *}
+SDL_HINT_FORCE_RAISEWINDOW = 'SDL_HINT_FORCE_RAISEWINDOW';
+
+{/**
+ * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface.
+ *
+ * SDL can try to accelerate the SDL screen surface by using streaming
+ * textures with a 3D rendering engine. This variable controls whether and
+ * how this is done.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable 3D acceleration
+ * "1" - Enable 3D acceleration, using the default renderer.
+ * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.)
+ *
+ * By default SDL tries to make a best guess for each platform whether
+ * to use acceleration or not.
+ */}
+SDL_HINT_FRAMEBUFFER_ACCELERATION = 'SDL_FRAMEBUFFER_ACCELERATION';
+
+{/**
+ * \brief Determines whether SDL enforces that DRM master is required in order
+ * to initialize the KMSDRM video backend.
+ *
+ * The DRM subsystem has a concept of a "DRM master" which is a DRM client that
+ * has the ability to set planes, set cursor, etc. When SDL is DRM master, it
+ * can draw to the screen using the SDL rendering APIs. Without DRM master, SDL
+ * is still able to process input and query attributes of attached displays,
+ * but it cannot change display state or draw to the screen directly.
+ *
+ * In some cases, it can be useful to have the KMSDRM backend even if it cannot
+ * be used for rendering. An app may want to use SDL for input processing while
+ * using another rendering API (such as an MMAL overlay on Raspberry Pi) or
+ * using its own code to render to DRM overlays that SDL doesn't support.
+ *
+ * This hint must be set before initializing the video subsystem.
+ *
+ * This variable can be set to the following values:
+ * "0" - SDL will allow usage of the KMSDRM backend without DRM master
+ * "1" - SDL will require DRM master to use the KMSDRM backend (default)
+ */}
+SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER = 'SDL_KMSDRM_REQUIRE_DRM_MASTER';
+
+{/**
+ * \brief A variable controlling whether the 2D render API is compatible or efficient.
+ *
+ * This variable can be set to the following values:
+ *
+ * "0" - Don't use batching to make rendering more efficient.
+ * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls.
+ *
+ * Up to SDL 2.0.9, the render API would draw immediately when requested. Now
+ * it batches up draw requests and sends them all to the GPU only when forced
+ * to (during SDL_RenderPresent, when changing render targets, by updating a
+ * texture that the batch needs, etc). This is significantly more efficient,
+ * but it can cause problems for apps that expect to render on top of the
+ * render API's output. As such, SDL will disable batching if a specific
+ * render backend is requested (since this might indicate that the app is
+ * planning to use the underlying graphics API directly). This hint can
+ * be used to explicitly request batching in this instance. It is a contract
+ * that you will either never use the underlying graphics API directly, or
+ * if you do, you will call SDL_RenderFlush() before you do so any current
+ * batch goes to the GPU before your work begins. Not following this contract
+ * will result in undefined behavior.
+ */}
+SDL_HINT_RENDER_BATCHING = 'SDL_RENDER_BATCHING';
+
+{/**
+ * \brief A variable specifying which render driver to use.
+ *
+ * If the application doesn't pick a specific renderer to use, this variable
+ * specifies the name of the preferred renderer. If the preferred renderer
+ * can't be initialized, the normal default renderer is used.
+ *
+ * This variable is case insensitive and can be set to the following values:
+ * "direct3d"
+ * "opengl"
+ * "opengles2"
+ * "opengles"
+ * "software"
+ *
+ * The default varies by platform, but it's the first one in the list that
+ * is available on the current platform.
+ */}
+SDL_HINT_RENDER_DRIVER = 'SDL_RENDER_DRIVER';
+
+{/**
+ * \brief A variable controlling how the 2D render API renders lines
+ *
+ * This variable can be set to the following values:
+ * "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20)
+ * "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points)
+ * "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20)
+ * "3" - Use the driver geometry API (correct, draws thicker diagonal lines)
+ *
+ * This variable should be set when the renderer is created.
+ */}
+SDL_HINT_RENDER_LINE_METHOD = 'SDL_RENDER_LINE_METHOD';
+
+{/**
+ * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize.
+ *
+ * This variable can be set to the following values:
+ * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen
+ * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen
+ *
+ * By default letterbox is used
+ */}
+SDL_HINT_RENDER_LOGICAL_SIZE_MODE = 'SDL_RENDER_LOGICAL_SIZE_MODE';
+
+{/**
+ * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable shaders
+ * "1" - Enable shaders
+ *
+ * By default shaders are used if OpenGL supports them.
+ */}
+SDL_HINT_RENDER_OPENGL_SHADERS = 'SDL_RENDER_OPENGL_SHADERS';
+
+{/**
+ * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations.
+ *
+ * This variable can be set to the following values:
+ * "0" - Thread-safety is not enabled (faster)
+ * "1" - Thread-safety is enabled
+ *
+ * By default the Direct3D device is created with thread-safety disabled.
+ */}
+SDL_HINT_RENDER_DIRECT3D_THREADSAFE = 'SDL_RENDER_DIRECT3D_THREADSAFE';
+
+{/**
+ * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer.
+ *
+ * This variable does not have any effect on the Direct3D 9 based renderer.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable Debug Layer use
+ * "1" - Enable Debug Layer use
+ *
+ * By default, SDL does not use Direct3D Debug Layer.
+ */}
+SDL_HINT_RENDER_DIRECT3D11_DEBUG = 'SDL_RENDER_DIRECT3D11_DEBUG';
+
+{/**
+ * \brief A variable controlling the scaling quality
+ *
+ * This variable can be set to the following values:
+ * "0" or "nearest" - Nearest pixel sampling
+ * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D)
+ * "2" or "best" - Currently this is the same as "linear"
+ *
+ * By default nearest pixel sampling is used
+ */}
+SDL_HINT_RENDER_SCALE_QUALITY = 'SDL_RENDER_SCALE_QUALITY';
+
+{/**
+ * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable vsync
+ * "1" - Enable vsync
+ *
+ * By default SDL does not sync screen surface updates with vertical refresh.
+ */}
+SDL_HINT_RENDER_VSYNC = 'SDL_RENDER_VSYNC';
+
+{**
+ * \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS
+ *
+ * This variable can be set to the following values:
+ * "0" - It will be using VSYNC as defined in the main flag. Default
+ * "1" - If VSYNC was previously enabled, then it will disable VSYNC if doesn't reach enough speed
+ *
+ * By default SDL does not enable the automatic VSYNC
+ *}
+SDL_HINT_PS2_DYNAMIC_VSYNC = 'SDL_PS2_DYNAMIC_VSYNC';
+
+{/**
+ * \brief A variable controlling whether the screensaver is enabled.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable screensaver
+ * "1" - Enable screensaver
+ *
+ * By default SDL will disable the screensaver.
+ */}
+SDL_HINT_VIDEO_ALLOW_SCREENSAVER = 'SDL_VIDEO_ALLOW_SCREENSAVER';
+
+{/**
+ * \brief Tell the video driver that we only want a double buffer.
+ *
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that
+ * wastes no CPU time on waiting for vsync after issuing a flip, but
+ * introduces a frame of latency. On the other hand, using a double buffer
+ * scheme instead is recommended for cases where low latency is an important
+ * factor because we save a whole frame of latency.
+ * We do so by waiting for vsync immediately after issuing a flip, usually just
+ * after eglSwapBuffers call in the backend's *_SwapWindow function.
+ *
+ * Since it's driver-specific, it's only supported where possible and
+ * implemented. Currently supported the following drivers:
+ *
+ * - KMSDRM (kmsdrm)
+ * - Raspberry Pi (raspberrypi)
+ */}
+SDL_HINT_VIDEO_DOUBLE_BUFFER = 'SDL_VIDEO_DOUBLE_BUFFER';
+
+{/**
+ * \brief A variable controlling whether the EGL window is allowed to be
+ * composited as transparent, rather than opaque.
+ *
+ * Most window systems will always render windows opaque, even if the surface
+ * format has an alpha channel. This is not always true, however, so by default
+ * SDL will try to enforce opaque composition. To override this behavior, you
+ * can set this hint to "1".
+ */}
+SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY = 'SDL_VIDEO_EGL_ALLOW_TRANSPARENCY';
+
+{/**
+ * \brief A variable controlling whether the graphics context is externally managed.
+ *
+ * This variable can be set to the following values:
+ * "0" - SDL will manage graphics contexts that are attached to windows.
+ * "1" - Disable graphics context management on windows.
+ *
+ * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the
+ * context will be automatically saved and restored when pausing the application. Additionally, some
+ * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this
+ * behavior, which is desireable when the application manages the graphics context, such as
+ * an externally managed OpenGL context or attaching a Vulkan surface to the window.
+ */}
+SDL_HINT_VIDEO_EXTERNAL_CONTEXT = 'SDL_VIDEO_EXTERNAL_CONTEXT';
+
+{/**
+ * \brief A variable controlling whether the libdecor Wayland backend is allowed to be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - libdecor use is disabled.
+ * "1" - libdecor use is enabled (default).
+ *
+ * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable.
+ */}
+SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR = 'SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR';
+
+{**
+ * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations.
+ *
+ * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is
+ * available. (Note that, by default, libdecor will use xdg-decoration itself if available).
+ *
+ * This variable can be set to the following values:
+ * "0" - libdecor is enabled only if server-side decorations are unavailable.
+ * "1" - libdecor is always enabled if available.
+ *
+ * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable.
+ *}
+SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR = 'SDL_VIDEO_WAYLAND_PREFER_LIBDECOR';
+
+{**
+ * \brief A variable controlling whether video mode emulation is enabled under Wayland.
+ *
+ * When this hint is set, a standard set of emulated CVT video modes will be exposed for use by the application.
+ * If it is disabled, the only modes exposed will be the logical desktop size and, in the case of a scaled
+ * desktop, the native display resolution.
+ *
+ * This variable can be set to the following values:
+ * "0" - Video mode emulation is disabled.
+ * "1" - Video mode emulation is enabled.
+ *
+ * By default video mode emulation is enabled.
+ *}
+SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION = 'SDL_VIDEO_WAYLAND_MODE_EMULATION';
+
+{**
+ * \brief Enable or disable mouse pointer warp emulation, needed by some older games.
+ *
+ * When this hint is set, any SDL will emulate mouse warps using relative mouse mode.
+ * This is required for some older games (such as Source engine games), which warp the
+ * mouse to the centre of the screen rather than using relative mouse motion. Note that
+ * relative mouse mode may have different mouse acceleration behaviour than pointer warps.
+ *
+ * This variable can be set to the following values:
+ * "0" - All mouse warps fail, as mouse warping is not available under Wayland.
+ * "1" - Some mouse warps will be emulated by forcing relative mouse mode.
+ *
+ * If not set, this is automatically enabled unless an application uses
+ * relative mouse mode directly.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP = 'SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP';
+
+{/**
+ * \brief Specify an "activity name" for screensaver inhibition.
+ *
+ * Some platforms, notably Linux desktops, list the applications which are
+ * inhibiting the screensaver or other power-saving features.
+ *
+ * This hint lets you specify the "activity name" sent to the OS when
+ * SDL_DisableScreenSaver() is used (or the screensaver is automatically
+ * disabled). The contents of this hint are used when the screensaver is
+ * disabled. You should use a string that describes what your program is doing
+ * (and, therefore, why the screensaver is disabled). For example, "Playing a
+ * game" or "Watching a video".
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "Playing a game" or something similar.
+ *
+ * On targets where this is not supported, this hint does nothing.
+ */}
+SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME = 'SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME';
+
+{/**
+ * \brief A variable controlling whether X11 should use GLX or EGL by default
+ *
+ * This variable can be set to the following values:
+ * "0" - Use GLX
+ * "1" - Use EGL
+ *
+ * By default SDL will use GLX when both are present.
+ */}
+SDL_HINT_VIDEO_X11_FORCE_EGL = 'SDL_VIDEO_X11_FORCE_EGL';
+
+{/**
+ * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
+ * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
+ *
+ * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
+ *
+ */}
+SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR = 'SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR';
+
+{/**
+ * \brief A variable forcing the visual ID chosen for new X11 windows
+ *
+ */}
+SDL_HINT_VIDEO_X11_WINDOW_VISUALID = 'SDL_VIDEO_X11_WINDOW_VISUALID';
+
+{/**
+ * \brief A variable controlling whether the X11 VidMode extension should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable XVidMode
+ * "1" - Enable XVidMode
+ *
+ * By default SDL will use XVidMode if it is available.
+ */}
+SDL_HINT_VIDEO_X11_XVIDMODE = 'SDL_VIDEO_X11_XVIDMODE';
+
+{/**
+ * \brief A variable controlling whether the X11 Xinerama extension should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable Xinerama
+ * "1" - Enable Xinerama
+ *
+ * By default SDL will use Xinerama if it is available.
+ */}
+SDL_HINT_VIDEO_X11_XINERAMA = 'SDL_VIDEO_X11_XINERAMA';
+
+{/**
+ * \brief A variable controlling whether the X11 XRandR extension should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable XRandR
+ * "1" - Enable XRandR
+ *
+ * By default SDL will not use XRandR because of window manager issues.
+ */}
+SDL_HINT_VIDEO_X11_XRANDR = 'SDL_VIDEO_X11_XRANDR';
+
+{/**
+ * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported.
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable _NET_WM_PING
+ * "1" - Enable _NET_WM_PING
+ *
+ * By default SDL will use _NET_WM_PING, but for applications that know they
+ * will not always be able to respond to ping requests in a timely manner they can
+ * turn it off to avoid the window manager thinking the app is hung.
+ * The hint is checked in CreateWindow.
+ */}
+SDL_HINT_VIDEO_X11_NET_WM_PING = 'SDL_VIDEO_X11_NET_WM_PING';
+
+{/**
+ * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden
+ *
+ * This variable can be set to the following values:
+ * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc)
+ * "1" - The window frame is interactive when the cursor is hidden
+ *
+ * By default SDL will allow interaction with the window frame when the cursor is hidden
+ */}
+SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN = 'SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN';
+
+{/**
+* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called
+*
+* This variable can be set to the following values:
+* "0" - The window is activated when the SDL_ShowWindow function is called
+* "1" - The window is not activated when the SDL_ShowWindow function is called
+*
+* By default SDL will activate the window when the SDL_ShowWindow function is called
+*/}
+SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN = 'SDL_WINDOW_NO_ACTIVATION_WHEN_SHOWN';
+
+{/**
+ * \brief A variable controlling whether the windows message loop is processed by SDL
+ *
+ * This variable can be set to the following values:
+ * "0" - The window message loop is not run
+ * "1" - The window message loop is processed in SDL_PumpEvents()
+ *
+ * By default SDL will process the windows message loop
+ */}
+SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP = 'SDL_WINDOWS_ENABLE_MESSAGELOOP';
+
+{/**
+ * \brief Force SDL to use Critical Sections for mutexes on Windows.
+ * On Windows 7 and newer, Slim Reader/Writer Locks are available.
+ * They offer better performance, allocate no kernel ressources and
+ * use less memory. SDL will fall back to Critical Sections on older
+ * OS versions or if forced to by this hint.
+ *
+ * This variable can be set to the following values:
+ * "0" - Use SRW Locks when available. If not, fall back to Critical Sections. (default)
+ * "1" - Force the use of Critical Sections in all cases.
+ *
+ */}
+SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS = 'SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS';
+
+{/**
+ * \brief Force SDL to use Kernel Semaphores on Windows.
+ * Kernel Semaphores are inter-process and require a context
+ * switch on every interaction. On Windows 8 and newer, the
+ * WaitOnAddress API is available. Using that and atomics to
+ * implement semaphores increases performance.
+ * SDL will fall back to Kernel Objects on older OS versions
+ * or if forced to by this hint.
+ *
+ * This variable can be set to the following values:
+ * "0" - Use Atomics and WaitOnAddress API when available. If not, fall back to Kernel Objects. (default)
+ * "1" - Force the use of Kernel Objects in all cases.
+ *
+ */}
+SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL = 'SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL';
+
+{/**
+ * \brief A variable to specify custom icon resource id from RC file on Windows platform
+ */}
+SDL_HINT_WINDOWS_INTRESOURCE_ICON = 'SDL_WINDOWS_INTRESOURCE_ICON';
+SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL = 'SDL_WINDOWS_INTRESOURCE_ICON_SMALL';
+
+{/**
+ * \brief Use the D3D9Ex API introduced in Windows Vista, instead of normal D3D9.
+ * Direct3D 9Ex contains changes to state management that can eliminate device
+ * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may require
+ * some changes to your application to cope with the new behavior, so this
+ * is disabled by default.
+ *
+ * This hint must be set before initializing the video subsystem.
+ *
+ * For more information on Direct3D 9Ex, see:
+ * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex
+ * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements
+ *
+ * This variable can be set to the following values:
+ * "0" - Use the original Direct3D 9 API (default)
+ * "1" - Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex is unavailable)
+ *
+ */}
+SDL_HINT_WINDOWS_USE_D3D9EX = 'SDL_WINDOWS_USE_D3D9EX';
+
+{**
+ * \brief Controls whether SDL will declare the process to be DPI aware.
+ *
+ * This hint must be set before initializing the video subsystem.
+ *
+ * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with
+ * a DPI scale factor.
+ *
+ * This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext)
+ * and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel
+ * even on high-DPI displays.
+ *
+ * For more information, see:
+ * https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
+ *
+ * This variable can be set to the following values:
+ * "" - Do not change the DPI awareness (default).
+ * "unaware" - Declare the process as DPI unaware. (Windows 8.1 and later).
+ * "system" - Request system DPI awareness. (Vista and later).
+ * "permonitor" - Request per-monitor DPI awareness. (Windows 8.1 and later).
+ * "permonitorv2" - Request per-monitor V2 DPI awareness. (Windows 10, version 1607 and later).
+ * The most visible difference from "permonitor" is that window title bar will be scaled
+ * to the visually correct size when dragging between monitors with different scale factors.
+ * This is the preferred DPI awareness level.
+ *
+ * If the requested DPI awareness is not available on the currently running OS, SDL will try to request the best
+ * available match.
+ *}
+SDL_HINT_WINDOWS_DPI_AWARENESS = 'SDL_WINDOWS_DPI_AWARENESS';
+
+{**
+ * \brief Uses DPI-scaled points as the SDL coordinate system on Windows.
+ *
+ * This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere.
+ * This means windows will be appropriately sized, even when created on high-DPI displays with scaling.
+ *
+ * e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings,
+ * will create a window with an 800x600 client area (in pixels).
+ *
+ * Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary),
+ * and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows.
+ *
+ * This variable can be set to the following values:
+ * "0" - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging
+ * between monitors with different scale factors (unless this is performed by
+ * Windows itself, which is the case when the process is DPI unaware).
+ * "1" - SDL coordinates are in DPI-scaled points. Automatically resize windows as needed on
+ * displays with non-100% scale factors.
+ *}
+SDL_HINT_WINDOWS_DPI_SCALING = 'SDL_WINDOWS_DPI_SCALING';
+
+{/**
+ * \brief A variable controlling whether grabbing input grabs the keyboard
+ *
+ * This variable can be set to the following values:
+ * "0" - Grab will affect only the mouse
+ * "1" - Grab will affect mouse and keyboard
+ *
+ * By default SDL will not grab the keyboard so system shortcuts still work.
+ */}
+SDL_HINT_GRAB_KEYBOARD = 'SDL_GRAB_KEYBOARD';
+
+{**
+ * \brief A variable containing a list of devices to ignore in SDL_hid_enumerate()
+ *
+ * For example, to ignore the Shanwan DS3 controller and any Valve controller, you might
+ * have the string "0x2563/0x0523,0x28de/0x0000".
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_HIDAPI_IGNORE_DEVICES = 'SDL_HIDAPI_IGNORE_DEVICES';
+
+{**
+ * \brief A variable controlling whether the mouse is captured while mouse buttons are pressed
+ *
+ * This variable can be set to the following values:
+ * "0" - The mouse is not captured while mouse buttons are pressed
+ * "1" - The mouse is captured while mouse buttons are pressed
+ *
+ * By default the mouse is captured while mouse buttons are pressed so if the mouse is dragged
+ * outside the window, the application continues to receive mouse events until the button is
+ * released.
+ *}
+SDL_HINT_MOUSE_AUTO_CAPTURE = 'SDL_MOUSE_AUTO_CAPTURE';
+
+{/**
+ * \brief A variable setting the double click radius, in pixels.
+ */}
+SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS = 'SDL_MOUSE_DOUBLE_CLICK_RADIUS';
+
+{/**
+ * \brief A variable setting the double click time, in milliseconds.
+ */}
+SDL_HINT_MOUSE_DOUBLE_CLICK_TIME = 'SDL_MOUSE_DOUBLE_CLICK_TIME';
+
+{/**
+ * \brief Allow mouse click events when clicking to focus an SDL window
+ *
+ * This variable can be set to the following values:
+ * "0" - Ignore mouse clicks that activate a window
+ * "1" - Generate events for mouse clicks that activate a window
+ *
+ * By default SDL will ignore mouse clicks that activate a window
+ */}
+SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH = 'SDL_MOUSE_FOCUS_CLICKTHROUGH';
+
+{/**
+ * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
+ */}
+SDL_HINT_MOUSE_NORMAL_SPEED_SCALE = 'SDL_MOUSE_NORMAL_SPEED_SCALE';
+
+{**
+ * \brief A variable controlling whether relative mouse mode constrains the mouse to the center of the window
+ *
+ * This variable can be set to the following values:
+ * "0" - Relative mouse mode constrains the mouse to the window
+ * "1" - Relative mouse mode constrains the mouse to the center of the window
+ *
+ * Constraining to the center of the window works better for FPS games and when the
+ * application is running over RDP. Constraining to the whole window works better
+ * for 2D games and increases the chance that the mouse will be in the correct
+ * position when using high DPI mice.
+ *
+ * By default SDL will constrain the mouse to the center of the window
+ *}
+SDL_HINT_MOUSE_RELATIVE_MODE_CENTER = 'SDL_MOUSE_RELATIVE_MODE_CENTER';
+
+{/**
+ * \brief A variable controlling whether relative mouse mode is implemented using mouse warping
+ *
+ * This variable can be set to the following values:
+ * "0" - Relative mouse mode uses raw input
+ * "1" - Relative mouse mode uses mouse warping
+ *
+ * By default SDL will use raw input for relative mouse mode
+ */}
+SDL_HINT_MOUSE_RELATIVE_MODE_WARP = 'SDL_MOUSE_RELATIVE_MODE_WARP';
+
+{/**
+ * \brief A variable controlling whether relative mouse motion is affected by renderer scaling
+ *
+ * This variable can be set to the following values:
+ * "0" - Relative motion is unaffected by DPI or renderer's logical size
+ * "1" - Relative motion is scaled according to DPI scaling and logical size
+ *
+ * By default relative mouse deltas are affected by DPI and renderer scaling
+ */}
+SDL_HINT_MOUSE_RELATIVE_SCALING = 'SDL_MOUSE_RELATIVE_SCALING';
+
+{/**
+ * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode
+ */}
+SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE = 'SDL_MOUSE_RELATIVE_SPEED_SCALE';
+
+{**
+ * \brief A variable controlling whether the system mouse acceleration curve is used for relative mouse motion.
+ *
+ * This variable can be set to the following values:
+ * "0" - Relative mouse motion will be unscaled (the default)
+ * "1" - Relative mouse motion will be scaled using the system mouse acceleration curve.
+ *
+ * If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will override the system speed scale.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE = 'SDL_MOUSE_RELATIVE_SYSTEM_SCALE';
+
+{**
+ * \brief A variable controlling whether a motion event should be generated for mouse warping in relative mode.
+ *
+ * This variable can be set to the following values:
+ * "0" - Warping the mouse will not generate a motion event in relative mode
+ * "1" - Warping the mouse will generate a motion event in relative mode
+ *
+ * By default warping the mouse will not generate motion events in relative mode. This avoids the application having to filter out large relative motion due to warping.
+ *}
+SDL_HINT_MOUSE_RELATIVE_WARP_MOTION = 'SDL_MOUSE_RELATIVE_WARP_MOTION';
+
+{/**
+ * \brief A variable controlling whether mouse events should generate synthetic touch events
+ *
+ * This variable can be set to the following values:
+ * "0" - Mouse events will not generate touch events (default for desktop platforms)
+ * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS)
+ */}
+SDL_HINT_MOUSE_TOUCH_EVENTS = 'SDL_MOUSE_TOUCH_EVENTS';
+
+{/**
+ * \brief Controls how the fact chunk affects the loading of a WAVE file.
+ *
+ * The fact chunk stores information about the number of samples of a WAVE
+ * file. The Standards Update from Microsoft notes that this value can be used
+ * to 'determine the length of the data in seconds'. This is especially useful
+ * for compressed formats (for which this is a mandatory chunk) if they produce
+ * multiple sample frames per block and truncating the block is not allowed.
+ * The fact chunk can exactly specify how many sample frames there should be
+ * in this case.
+ *
+ * Unfortunately, most application seem to ignore the fact chunk and so SDL
+ * ignores it by default as well.
+ *
+ * This variable can be set to the following values:
+ *
+ * "truncate" - Use the number of samples to truncate the wave data if
+ * the fact chunk is present and valid
+ * "strict" - Like "truncate", but raise an error if the fact chunk
+ * is invalid, not present for non-PCM formats, or if the
+ * data chunk doesn't have that many samples
+ * "ignorezero" - Like "truncate", but ignore fact chunk if the number of
+ * samples is zero
+ * "ignore" - Ignore fact chunk entirely (default)
+ */}
+SDL_HINT_WAVE_FACT_CHUNK = 'SDL_WAVE_FACT_CHUNK';
+
+{/**
+ * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file.
+ *
+ * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE
+ * file) is not always reliable. In case the size is wrong, it's possible to
+ * just ignore it and step through the chunks until a fixed limit is reached.
+ *
+ * Note that files that have trailing data unrelated to the WAVE file or
+ * corrupt files may slow down the loading process without a reliable boundary.
+ * By default, SDL stops after 10000 chunks to prevent wasting time. Use the
+ * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value.
+ *
+ * This variable can be set to the following values:
+ *
+ * "force" - Always use the RIFF chunk size as a boundary for the chunk search
+ * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default)
+ * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB
+ * "maximum" - Search for chunks until the end of file (not recommended)
+ */}
+SDL_HINT_WAVE_RIFF_CHUNK_SIZE = 'SDL_WAVE_RIFF_CHUNK_SIZE';
+
+{/**
+ * \brief Controls how a truncated WAVE file is handled.
+ *
+ * A WAVE file is considered truncated if any of the chunks are incomplete or
+ * the data chunk size is not a multiple of the block size. By default, SDL
+ * decodes until the first incomplete block, as most applications seem to do.
+ *
+ * This variable can be set to the following values:
+ *
+ * "verystrict" - Raise an error if the file is truncated
+ * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored
+ * "dropframe" - Decode until the first incomplete sample frame
+ * "dropblock" - Decode until the first incomplete block (default)
+ */}
+SDL_HINT_WAVE_TRUNCATION = 'SDL_WAVE_TRUNCATION';
+
+{/**
+ * \brief Minimize your SDL_Window if it loses key focus when in Fullscreen mode. Defaults to true.
+ *
+ */}
+SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS = 'SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS';
+
+{/**
+ * \brief A variable controlling whether the idle timer is disabled on iOS.
+ *
+ * When an iOS app does not receive touches for some time, the screen is
+ * dimmed automatically. For games where the accelerometer is the only input
+ * this is problematic. This functionality can be disabled by setting this
+ * hint.
+ *
+ * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver()
+ * accomplish the same thing on iOS. They should be preferred over this hint.
+ *
+ * This variable can be set to the following values:
+ * "0" - Enable idle timer
+ * "1" - Disable idle timer
+ */}
+SDL_HINT_IDLE_TIMER_DISABLED = 'SDL_IOS_IDLE_TIMER_DISABLED';
+
+{/**
+ * \brief A variable controlling what driver to use for OpenGL ES contexts.
+ *
+ * On some platforms, currently Windows and X11, OpenGL drivers may support
+ * creating contexts with an OpenGL ES profile. By default SDL uses these
+ * profiles, when available, otherwise it attempts to load an OpenGL ES
+ * library, e.g. that provided by the ANGLE project. This variable controls
+ * whether SDL follows this default behaviour or will always load an
+ * OpenGL ES library.
+ *
+ * Circumstances where this is useful include
+ * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE,
+ * or emulator, e.g. those from ARM, Imagination or Qualcomm.
+ * - Resolving OpenGL ES function addresses at link time by linking with
+ * the OpenGL ES library instead of querying them at run time with
+ * SDL_GL_GetProcAddress().
+ *
+ * Caution: for an application to work with the default behaviour across
+ * different OpenGL drivers it must query the OpenGL ES function
+ * addresses at run time using SDL_GL_GetProcAddress().
+ *
+ * This variable is ignored on most platforms because OpenGL ES is native
+ * or not supported.
+ *
+ * This variable can be set to the following values:
+ * "0" - Use ES profile of OpenGL, if available. (Default when not set.)
+ * "1" - Load OpenGL ES library using the default library names.
+ *
+ */}
+SDL_HINT_OPENGL_ES_DRIVER = 'SDL_OPENGL_ES_DRIVER';
+
+{/**
+ * \brief A variable controlling which orientations are allowed on iOS.
+ *
+ * In some circumstances it is necessary to be able to explicitly control
+ * which UI orientations are allowed.
+ *
+ * This variable is a space delimited list of the following values:
+ * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown"
+ */}
+SDL_HINT_ORIENTATIONS = 'SDL_IOS_ORIENTATIONS';
+
+{/**
+ * \brief A variable controlling the use of a sentinel event when polling the event queue
+ *
+ * This variable can be set to the following values:
+ * "0" - Disable poll sentinels
+ * "1" - Enable poll sentinels
+ *
+ * When polling for events, SDL_PumpEvents is used to gather new events from devices.
+ * If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will
+ * become stuck until the new events stop.
+ * This is most noticable when moving a high frequency mouse.
+ *
+ * By default, poll sentinels are enabled.
+ */}
+SDL_HINT_POLL_SENTINEL = 'SDL_POLL_SENTINEL';
+
+{/**
+ * \brief Override for SDL_GetPreferredLocales()
+ *
+ * If set, this will be favored over anything the OS might report for the
+ * user's preferred locales. Changing this hint at runtime will not generate
+ * a SDL_LOCALECHANGED event (but if you can change the hint, you can push
+ * your own event, if you want).
+ *
+ * The format of this hint is a comma-separated list of language and locale,
+ * combined with an underscore, as is a common format: "en_GB". Locale is
+ * optional: "en". So you might have a list like this: "en_GB,jp,es_PT"
+ */}
+SDL_HINT_PREFERRED_LOCALES = 'SDL_PREFERRED_LOCALES';
+
+{/**
+ * \brief A variable describing the content orientation on QtWayland-based platforms.
+ *
+ * On QtWayland platforms, windows are rotated client-side to allow for custom
+ * transitions. In order to correctly position overlays (e.g. volume bar) and
+ * gestures (e.g. events view, close/minimize gestures), the system needs to
+ * know in which orientation the application is currently drawing its contents.
+ *
+ * This does not cause the window to be rotated or resized, the application
+ * needs to take care of drawing the content in the right orientation (the
+ * framebuffer is always in portrait mode).
+ *
+ * This variable can be one of the following values:
+ * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape"
+ */}
+SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION = 'SDL_QTWAYLAND_CONTENT_ORIENTATION';
+
+{/**
+ * \brief Flags to set on QtWayland windows to integrate with the native window manager.
+ *
+ * On QtWayland platforms, this hint controls the flags to set on the windows.
+ * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures.
+ *
+ * This variable is a space-separated list of the following values (empty = no flags):
+ * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager"
+ */}
+SDL_HINT_QTWAYLAND_WINDOW_FLAGS = 'SDL_QTWAYLAND_WINDOW_FLAGS';
+
+{**
+ * \brief Specify an application name.
+ *
+ * This hint lets you specify the application name sent to the OS when
+ * required. For example, this will often appear in volume control applets for
+ * audio streams, and in lists of applications which are inhibiting the
+ * screensaver. You should use a string that describes your program ("My Game
+ * 2: The Revenge")
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: probably the application's name or "SDL Application" if SDL
+ * doesn't have any better information.
+ *
+ * Note that, for audio streams, this can be overridden with
+ * SDL_HINT_AUDIO_DEVICE_APP_NAME.
+ *
+ * On targets where this is not supported, this hint does nothing.
+ *}
+SDL_HINT_APP_NAME = 'SDL_APP_NAME';
+
+{/**
+ * \brief A variable controlling whether controllers used with the Apple TV
+ * generate UI events.
+ *
+ * When UI events are generated by controller input, the app will be
+ * backgrounded when the Apple TV remote's menu button is pressed, and when the
+ * pause or B buttons on gamepads are pressed.
+ *
+ * More information about properly making use of controllers for the Apple TV
+ * can be found here:
+ * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
+ *
+ * This variable can be set to the following values:
+ * "0" - Controller input does not generate UI events (the default).
+ * "1" - Controller input generates UI events.
+ */}
+SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS = 'SDL_APPLE_TV_CONTROLLER_UI_EVENTS';
+
+{/**
+ * \brief A variable controlling whether the Apple TV remote's joystick axes
+ * will automatically match the rotation of the remote.
+ *
+ * This variable can be set to the following values:
+ * "0" - Remote orientation does not affect joystick axes (the default).
+ * "1" - Joystick axes are based on the orientation of the remote.
+ */}
+SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION = 'SDL_APPLE_TV_REMOTE_ALLOW_ROTATION';
+
+{/**
+ * \brief A variable controlling whether the Android / iOS built-in
+ * accelerometer should be listed as a joystick device, rather than listing
+ * actual joysticks only.
+ *
+ * This variable can be set to the following values:
+ * "0" - List only real joysticks and accept input from them
+ * "1" - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
+ */}
+SDL_HINT_ACCELEROMETER_AS_JOYSTICK = 'SDL_ACCELEROMETER_AS_JOYSTICK';
+
+{/**
+ * \brief Specify the behavior of Alt+Tab while the keyboard is grabbed.
+ *
+ * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed
+ * and your window is full-screen. This prevents the user from getting stuck in
+ * your application if you've enabled keyboard grab.
+ *
+ * The variable can be set to the following values:
+ * "0" - SDL will not handle Alt+Tab. Your application is responsible
+ for handling Alt+Tab while the keyboard is grabbed.
+ * "1" - SDL will minimize your window when Alt+Tab is pressed (default)
+*/}
+SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED = 'SDL_ALLOW_ALT_TAB_WHILE_GRABBED';
+
+{/**
+ * \brief A variable controlling the audio category on iOS and Mac OS X
+ *
+ * This variable can be set to the following values:
+ *
+ * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default)
+ * "playback" - Use the AVAudioSessionCategoryPlayback category
+ *
+ * For more information, see Apple's documentation:
+ * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html
+ */}
+SDL_HINT_AUDIO_CATEGORY = 'SDL_AUDIO_CATEGORY';
+
+{/**
+ * \brief Specify an application name for an audio device.
+ *
+ * Some audio backends (such as PulseAudio) allow you to describe your audio
+ * stream. Among other things, this description might show up in a system
+ * control panel that lets the user adjust the volume on specific audio
+ * streams instead of using one giant master volume slider.
+ *
+ * This hints lets you transmit that information to the OS. The contents of
+ * this hint are used while opening an audio device. You should use a string
+ * that describes your program ("My Game 2: The Revenge")
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: this will be the name set with SDL_HINT_APP_NAME, if that hint is
+ * set. Otherwise, it'll probably the application's name or "SDL Application"
+ * if SDL doesn't have any better information.
+ *
+ * On targets where this is not supported, this hint does nothing.
+ *}
+SDL_HINT_AUDIO_DEVICE_APP_NAME = 'SDL_AUDIO_DEVICE_APP_NAME';
+
+{/**
+ * \brief Specify an application name for an audio device.
+ *
+ * Some audio backends (such as PulseAudio) allow you to describe your audio
+ * stream. Among other things, this description might show up in a system
+ * control panel that lets the user adjust the volume on specific audio
+ * streams instead of using one giant master volume slider.
+ *
+ * This hints lets you transmit that information to the OS. The contents of
+ * this hint are used while opening an audio device. You should use a string
+ * that describes your what your program is playing ("audio stream" is
+ * probably sufficient in many cases, but this could be useful for something
+ * like "team chat" if you have a headset playing VoIP audio separately).
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "audio stream" or something similar.
+ *
+ * On targets where this is not supported, this hint does nothing.
+ */}
+SDL_HINT_AUDIO_DEVICE_STREAM_NAME = 'SDL_AUDIO_DEVICE_STREAM_NAME';
+
+{/**
+ * \brief Specify an application role for an audio device.
+ *
+ * Some audio backends (such as Pipewire) allow you to describe the role of
+ * your audio stream. Among other things, this description might show up in
+ * a system control panel or software for displaying and manipulating media
+ * playback/capture graphs.
+ *
+ * This hints lets you transmit that information to the OS. The contents of
+ * this hint are used while opening an audio device. You should use a string
+ * that describes your what your program is playing (Game, Music, Movie,
+ * etc...).
+ *
+ * Setting this to "" or leaving it unset will have SDL use a reasonable
+ * default: "Game" or something similar.
+ *
+ * On targets where this is not supported, this hint does nothing.
+ */}
+SDL_HINT_AUDIO_DEVICE_STREAM_ROLE = 'SDL_AUDIO_DEVICE_STREAM_ROLE';
+
+{/**
+ * \brief A variable that causes SDL to not ignore audio "monitors"
+ *
+ * This is currently only used for PulseAudio and ignored elsewhere.
+ *
+ * By default, SDL ignores audio devices that aren't associated with physical
+ * hardware. Changing this hint to "1" will expose anything SDL sees that
+ * appears to be an audio source or sink. This will add "devices" to the list
+ * that the user probably doesn't want or need, but it can be useful in
+ * scenarios where you want to hook up SDL to some sort of virtual device,
+ * etc.
+ *
+ * The default value is "0". This hint must be set before SDL_Init().
+ *
+ * This hint is available since SDL 2.0.16. Before then, virtual devices are
+ * always ignored.
+ */}
+SDL_HINT_AUDIO_INCLUDE_MONITORS = 'SDL_AUDIO_INCLUDE_MONITORS';
+
+{/**
+ * \brief A variable controlling speed/quality tradeoff of audio resampling.
+ *
+ * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ )
+ * to handle audio resampling. There are different resampling modes available
+ * that produce different levels of quality, using more CPU.
+ *
+ * If this hint isn't specified to a valid setting, or libsamplerate isn't
+ * available, SDL will use the default, internal resampling algorithm.
+ *
+ * Note that this is currently only applicable to resampling audio that is
+ * being written to a device for playback or audio being read from a device
+ * for capture. SDL_AudioCVT always uses the default resampler (although this
+ * might change for SDL 2.1).
+ *
+ * This hint is currently only checked at audio subsystem initialization.
+ *
+ * This variable can be set to the following values:
+ *
+ * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast)
+ * "1" or "fast" - Use fast, slightly higher quality resampling, if available
+ * "2" or "medium" - Use medium quality resampling, if available
+ * "3" or "best" - Use high quality resampling, if available
+ */}
+SDL_HINT_AUDIO_RESAMPLING_MODE = 'SDL_AUDIO_RESAMPLING_MODE';
+
+{**
+ * \brief A variable controlling whether SDL updates joystick state when getting input events
+ *
+ * This variable can be set to the following values:
+ *
+ * "0" - You'll call SDL_JoystickUpdate() manually
+ * "1" - SDL will automatically call SDL_JoystickUpdate() (default)
+ *
+ * This hint can be toggled on and off at runtime.
+ */}
+SDL_HINT_AUTO_UPDATE_JOYSTICKS = 'SDL_AUTO_UPDATE_JOYSTICKS';
+
+{/**
+ * \brief A variable controlling whether SDL updates sensor state when getting input events
+ *
+ * This variable can be set to the following values:
+ *
+ * "0" - You'll call SDL_SensorUpdate() manually
+ * "1" - SDL will automatically call SDL_SensorUpdate() (default)
+ *
+ * This hint can be toggled on and off at runtime.
+ */}
+SDL_HINT_AUTO_UPDATE_SENSORS = 'SDL_AUTO_UPDATE_SENSORS';
+
+{/**
+ * \brief Mark X11 windows as override-redirect.
+ *
+ * If set, this _might_ increase framerate at the expense of the desktop
+ * not working as expected. Override-redirect windows aren't noticed by the
+ * window manager at all.
+ *
+ * You should probably only use this for fullscreen windows, and you probably
+ * shouldn't even use it for that. But it's here if you want to try!
+ */}
+SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT = 'SDL_X11_FORCE_OVERRIDE_REDIRECT';
+
+{**
+ * \brief A variable that forces X11 windows to create as a custom type.
+ *
+ * This is currently only used for X11 and ignored elsewhere.
+ *
+ * During SDL_CreateWindow, SDL uses the _NET_WM_WINDOW_TYPE X11 property
+ * to report to the window manager the type of window it wants to create.
+ * This might be set to various things if SDL_WINDOW_TOOLTIP or
+ * SDL_WINDOW_POPUP_MENU, etc, were specified. For "normal" windows that
+ * haven't set a specific type, this hint can be used to specify a custom
+ * type. For example, a dock window might set this to
+ * "_NET_WM_WINDOW_TYPE_DOCK".
+ *
+ * If not set or set to "", this hint is ignored. This hint must be set
+ * before the SDL_CreateWindow() call that it is intended to affect.
+ *
+ *}
+SDL_HINT_X11_WINDOW_TYPE = 'SDL_X11_WINDOW_TYPE';
+
+{/**
+ * \brief A variable that lets you disable the detection and use of Xinput gamepad devices
+ *
+ * The variable can be set to the following values:
+ * "0" - Disable XInput timer (only uses direct input)
+ * "1" - Enable XInput timer (the default)
+ */}
+SDL_HINT_XINPUT_ENABLED = 'SDL_XINPUT_ENABLED';
+
+{**
+ * \brief A variable that lets you disable the detection and use of DirectInput gamepad devices
+ *
+ * The variable can be set to the following values:
+ * "0" - Disable DirectInput detection (only uses XInput)
+ * "1" - Enable DirectInput detection (the default)
+ *}
+SDL_HINT_DIRECTINPUT_ENABLED = 'SDL_DIRECTINPUT_ENABLED';
+
+{**
+ * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices.
+ *
+ * This hint is for backwards compatibility only and will be removed in SDL 2.1
+ *
+ * The default value is "0". This hint must be set before SDL_Init()
+ *}
+SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING = 'SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING';
+
+{/**
+ * \brief A variable that lets you manually hint extra gamecontroller db entries
+ *
+ * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h
+ *
+ * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER)
+ * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping()
+ */}
+SDL_HINT_GAMECONTROLLERCONFIG = 'SDL_GAMECONTROLLERCONFIG';
+
+{/**
+ * \brief A variable that lets you provide a file with extra gamecontroller db entries.
+ *
+ * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h
+ *
+ * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER)
+ * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping()
+ */}
+SDL_HINT_GAMECONTROLLERCONFIG_FILE = 'SDL_GAMECONTROLLERCONFIG_FILE';
+
+{/**
+ * \brief A variable that overrides the automatic controller type detection
+ *
+ * The variable should be comma separated entries, in the form: VID/PID=type
+ *
+ * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd
+ *
+ * The type should be one of:
+ * Xbox360
+ * XboxOne
+ * PS3
+ * PS4
+ * PS5
+ * SwitchPro
+ *
+ * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER)
+ */}
+SDL_HINT_GAMECONTROLLERTYPE = 'SDL_GAMECONTROLLERTYPE';
+
+{/**
+ * \brief A variable containing a list of devices to skip when scanning for game controllers.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs
+ * in hexadecimal form, e.g.
+ *
+ * 0xAAAA/0xBBBB,0xCCCC/0xDDDD
+ *
+ * The variable can also take the form of @file, in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ */}
+SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES = 'SDL_GAMECONTROLLER_IGNORE_DEVICES';
+
+{/**
+ * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable.
+ *
+ * The format of the string is a comma separated list of USB VID/PID pairs
+ * in hexadecimal form, e.g.
+ *
+ * 0xAAAA/0xBBBB,0xCCCC/0xDDDD
+ *
+ * The variable can also take the form of @file, in which case the named
+ * file will be loaded and interpreted as the value of the variable.
+ */}
+SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT = 'SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT';
+
+{/**
+ * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout.
+ *
+ * For example, on Nintendo Switch controllers, normally you'd get:
+ *
+ * (Y)
+ * (X) (B)
+ * (A)
+ *
+ * but if this hint is set, you'll get:
+ *
+ * (X)
+ * (Y) (A)
+ * (B)
+ *
+ * The variable can be set to the following values:
+ * "0" - Report the face buttons by position, as though they were on an Xbox controller.
+ * "1" - Report the face buttons by label instead of position
+ *
+ * The default value is "1". This hint may be set at any time.
+ */}
+SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS = 'SDL_GAMECONTROLLER_USE_BUTTON_LABELS';
+
+{/**
+ * \brief A variable controlling whether the home indicator bar on iPhone X
+ * should be hidden.
+ *
+ * This variable can be set to the following values:
+ * "0" - The indicator bar is not hidden (default for windowed applications)
+ * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications)
+ * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications)
+ */}
+SDL_HINT_IOS_HIDE_HOME_INDICATOR = 'SDL_IOS_HIDE_HOME_INDICATOR';
+
+{/**
+ * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
+ *
+ * The variable can be set to the following values:
+ * "0" - Disable joystick & gamecontroller input events when the
+ * application is in the background.
+ * "1" - Enable joystick & gamecontroller input events when the
+ * application is in the backgroumd.
+ *
+ * The default value is "0". This hint may be set at any time.
+ */}
+SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS = 'SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS';
+
+{/**
+ * \brief A comma separated list of devices to open as joysticks
+ *
+ * This variable is currently only used by the Linux joystick driver.
+ *}
+SDL_HINT_JOYSTICK_DEVICE = 'SDL_JOYSTICK_DEVICE';
+
+{**
+ * \brief A variable controlling whether "low_frequency_rumble" and "high_frequency_rumble" is used to implement
+ * the GameCube controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2)
+ * this is useful for applications that need full compatibility for things like ADSR envelopes.
+ * Stop is implemented by setting "low_frequency_rumble" to "0" and "high_frequency_rumble" ">0"
+ * Rumble is both at any arbitrary value,
+ * StopHard is implemented by setting both "low_frequency_rumble" and "high_frequency_rumble" to "0"
+ *
+ * This variable can be set to the following values:
+ * "0" - Normal rumble behavior is behavior is used (default)
+ * "1" - Proper GameCube controller rumble behavior is used
+ *
+ *}
+SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE = 'SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI joystick drivers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI drivers are not used
+ * "1" - HIDAPI drivers are used (the default)
+ *
+ * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below.
+ */}
+SDL_HINT_JOYSTICK_HIDAPI = 'SDL_JOYSTICK_HIDAPI';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE = 'SDL_JOYSTICK_HIDAPI_GAMECUBE';
+
+{/**
+ * \brief A variable controlling whether Switch Joy-Cons should be treated the same as Switch Pro Controllers when using the HIDAPI driver.
+ *
+ * This variable can be set to the following values:
+ * "0" - basic Joy-Con support with no analog input (the default)
+ * "1" - Joy-Cons treated as half full Pro Controllers with analog inputs and sensors
+ *
+ * This does not combine Joy-Cons into a single controller. That's up to the user.
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS = 'SDL_JOYSTICK_HIDAPI_JOY_CONS';
+
+{**
+ * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver
+ *
+ * This variable can be set to the following values:
+ * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad
+ * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default)
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS = 'SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS';
+
+{**
+ * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be in vertical mode when using the HIDAPI driver
+ *
+ * This variable can be set to the following values:
+ * "0" - Left and right Joy-Con controllers will not be in vertical mode (the default)
+ * "1" - Left and right Joy-Con controllers will be in vertical mode
+ *
+ * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER).
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS = 'SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_LUNA = 'SDL_JOYSTICK_HIDAPI_LUNA';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for Nintendo Online classic controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC = 'SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for NVIDIA SHIELD controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_SHIELD = 'SDL_JOYSTICK_HIDAPI_SHIELD';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for PS3 controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI on macOS, and "0" on other platforms.
+ *
+ * It is not possible to use this driver on Windows, due to limitations in the default drivers
+ * installed. See https://github.com/ViGEm/DsHidMini for an alternative driver on Windows.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_PS3 = 'SDL_JOYSTICK_HIDAPI_PS3';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_PS4 = 'SDL_JOYSTICK_HIDAPI_PS4';
+
+{/**
+ * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver.
+ *
+ * This variable can be set to the following values:
+ * "0" - extended reports are not enabled (the default)
+ * "1" - extended reports
+ *
+ * Extended input reports allow rumble on Bluetooth PS4 controllers, but
+ * break DirectInput handling for applications that don't use SDL.
+ *
+ * Once extended reports are enabled, they can not be disabled without
+ * power cycling the controller.
+ *
+ * For compatibility with applications written for versions of SDL prior
+ * to the introduction of PS5 controller support, this value will also
+ * control the state of extended reports on PS5 controllers when the
+ * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE hint is not explicitly set.
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE = 'SDL_JOYSTICK_HIDAPI_PS4_RUMBLE';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for PS5 controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_PS5 = 'SDL_JOYSTICK_HIDAPI_PS5';
+
+{/**
+ * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a PS5 controller.
+ *
+ * This variable can be set to the following values:
+ * "0" - player LEDs are not enabled
+ * "1" - player LEDs are enabled (the default)
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED = 'SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED';
+
+{/**
+ * \brief A variable controlling whether extended input reports should be used for PS5 controllers when using the HIDAPI driver.
+ *
+ * This variable can be set to the following values:
+ * "0" - extended reports are not enabled (the default)
+ * "1" - extended reports
+ *
+ * Extended input reports allow rumble on Bluetooth PS5 controllers, but
+ * break DirectInput handling for applications that don't use SDL.
+ *
+ * Once extended reports are enabled, they can not be disabled without
+ * power cycling the controller.
+ *
+ * For compatibility with applications written for versions of SDL prior
+ * to the introduction of PS5 controller support, this value defaults to
+ * the value of SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE.
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE = 'SDL_JOYSTICK_HIDAPI_PS5_RUMBLE';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for Google Stadia controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_STADIA = 'SDL_JOYSTICK_HIDAPI_STADIA';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for Steam Controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used for Steam Controllers, which requires Bluetooth access
+ * and may prompt the user for permission on iOS and Android.
+ *
+ * The default is "0"
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_STEAM = 'SDL_JOYSTICK_HIDAPI_STEAM';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_SWITCH = 'SDL_JOYSTICK_HIDAPI_SWITCH';
+
+{/**
+ * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch controller is opened
+ *
+ * This variable can be set to the following values:
+ * "0" - home button LED is turned off
+ * "1" - home button LED is turned on
+ *
+ * By default the Home button LED state is not changed.
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED = 'SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED';
+
+{**
+ * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Joy-Con controller is opened
+ *
+ * This variable can be set to the following values:
+ * "0" - home button LED is turned off
+ * "1" - home button LED is turned on
+ *
+ * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED = 'SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED';
+
+{**
+ * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Nintendo Switch controller.
+ *
+ * This variable can be set to the following values:
+ * "0" - player LEDs are not enabled
+ * "1" - player LEDs are enabled (the default)
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED = 'SDL_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for Nintendo Wii and Wii U controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * This driver doesn't work with the dolphinbar, so the default is SDL_FALSE for now.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_WII = 'SDL_JOYSTICK_HIDAPI_WII';
+
+{**
+ * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Wii controller.
+ *
+ * This variable can be set to the following values:
+ * "0" - player LEDs are not enabled
+ * "1" - player LEDs are enabled (the default)
+ *
+ * This hiny is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED = 'SDL_JOYSTICK_HIDAPI_WII_PLAYER_LED';
+
+{/**
+ * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI
+ */}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX = 'SDL_JOYSTICK_HIDAPI_XBOX';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for XBox 360 controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 = 'SDL_JOYSTICK_HIDAPI_XBOX_360';
+
+{**
+ * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with an Xbox 360 controller.
+ *
+ * This variable can be set to the following values:
+ * "0" - player LEDs are not enabled
+ * "1" - player LEDs are enabled (the default)
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED = 'SDL_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for XBox 360 wireless controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX_360.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS = 'SDL_JOYSTICK_HIDAPI_XBOX_360_WIRELESS';
+
+{**
+ * \brief A variable controlling whether the HIDAPI driver for XBox One controllers should be used.
+ *
+ * This variable can be set to the following values:
+ * "0" - HIDAPI driver is not used
+ * "1" - HIDAPI driver is used
+ *
+ * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE = 'SDL_JOYSTICK_HIDAPI_XBOX_ONE';
+
+{**
+ * \brief A variable controlling whether the Home button LED should be turned on when an Xbox One controller is opened
+ *
+ * This variable can be set to the following values:
+ * "0" - home button LED is turned off
+ * "1" - home button LED is turned on
+ *
+ * By default the Home button LED state is not changed. This hint can also
+ * be set to a floating point value between 0.0 and 1.0 which controls
+ * the brightness of the Home button LED. The default brightness is 0.4.
+ *
+ * This hint is available since SDL 2.26.0.
+ *}
+SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED = 'SDL_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED';
+
+{/**
+ * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices.
+ *
+ * This variable can be set to the following values:
+ * "0" - RAWINPUT drivers are not used
+ * "1" - RAWINPUT drivers are used (the default)
+ *
+ */}
+SDL_HINT_JOYSTICK_RAWINPUT = 'SDL_JOYSTICK_RAWINPUT';
+
+{/**
+ * \brief A variable controlling whether the RAWINPUT driver should pull correlated data from XInput.
+ *
+ * This variable can be set to the following values:
+ * "0" - RAWINPUT driver will only use data from raw input APIs
+ * "1" - RAWINPUT driver will also pull data from XInput, providing
+ * better trigger axes, guide button presses, and rumble support
+ * for Xbox controllers
+ *
+ * The default is "1". This hint applies to any joysticks opened after setting the hint.
+ */}
+SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT = 'SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT';
+
+{**
+ * \brief A variable controlling whether the ROG Chakram mice should show up as joysticks
+ *
+ * This variable can be set to the following values:
+ * "0" - ROG Chakram mice do not show up as joysticks (the default)
+ * "1" - ROG Chakram mice show up as joysticks
+ *}
+SDL_HINT_JOYSTICK_ROG_CHAKRAM = 'SDL_JOYSTICK_ROG_CHAKRAM';
+
+{/**
+ * \brief A variable controlling whether a separate thread should be used
+ * for handling joystick detection and raw input messages on Windows
+ *
+ * This variable can be set to the following values:
+ * "0" - A separate thread is not used (the default)
+ * "1" - A separate thread is used for handling raw input messages
+ *
+ */}
+SDL_HINT_JOYSTICK_THREAD = 'SDL_JOYSTICK_THREAD';
+
+{/**
+ * \brief If set to 0 then never set the top most bit on a SDL Window, even if the video mode expects it.
+ * This is a debugging aid for developers and not expected to be used by end users. The default is "1"
+ *
+ * This variable can be set to the following values:
+ * "0" - don't allow topmost
+ * "1" - allow topmost
+ */}
+SDL_HINT_ALLOW_TOPMOST = 'SDL_ALLOW_TOPMOST';
+
+{/**
+ * \brief A variable that controls the timer resolution, in milliseconds.
+ *
+ * The higher resolution the timer, the more frequently the CPU services
+ * timer interrupts, and the more precise delays are, but this takes up
+ * power and CPU time. This hint is only used on Windows 7 and earlier.
+ *
+ * See this blog post for more information:
+ * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/
+ *
+ * If this variable is set to "0", the system timer resolution is not set.
+ *
+ * The default value is "1". This hint may be set at any time.
+ */}
+SDL_HINT_TIMER_RESOLUTION = 'SDL_TIMER_RESOLUTION';
+
+{/**
+ * \brief Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime.
+ *
+ * On some platforms, like Linux, a realtime priority thread may be subject to restrictions
+ * that require special handling by the application. This hint exists to let SDL know that
+ * the app is prepared to handle said restrictions.
+ *
+ * On Linux, SDL will apply the following configuration to any thread that becomes realtime:
+ * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy,
+ * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit.
+ * * Exceeding this limit will result in the kernel sending SIGKILL to the app,
+ * * Refer to the man pages for more information.
+ *
+ * This variable can be set to the following values:
+ * "0" - default platform specific behaviour
+ * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy
+ */}
+SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL = 'SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL';
+
+{/**
+* \brief A string specifying additional information to use with SDL_SetThreadPriority.
+*
+* By default SDL_SetThreadPriority will make appropriate system changes in order to
+* apply a thread priority. For example on systems using pthreads the scheduler policy
+* is changed automatically to a policy that works well with a given priority.
+* Code which has specific requirements can override SDL's default behavior with this hint.
+*
+* pthread hint values are "current", "other", "fifo" and "rr".
+* Currently no other platform hint values are defined but may be in the future.
+*
+* \note On Linux, the kernel may send SIGKILL to realtime tasks which exceed the distro
+* configured execution budget for rtkit. This budget can be queried through RLIMIT_RTTIME
+* after calling SDL_SetThreadPriority().
+*/}
+SDL_HINT_THREAD_PRIORITY_POLICY = 'SDL_THREAD_PRIORITY_POLICY';
+
+{/**
+ * \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size
+ *
+ * Use this hint in case you need to set SDL's threads stack size to other than the default.
+ * This is specially useful if you build SDL against a non glibc libc library (such as musl) which
+ * provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
+ * Support for this hint is currently available only in the pthread, Windows, and PSP backend.
+ */}
+SDL_HINT_THREAD_STACK_SIZE = 'SDL_THREAD_STACK_SIZE';
+
+{/**
+ * \brief A variable controlling whether touch events should generate synthetic mouse events
+ *
+ * This variable can be set to the following values:
+ * "0" - Touch events will not generate mouse events
+ * "1" - Touch events will generate mouse events
+ *
+ * By default SDL will generate mouse events for touch events
+ */}
+SDL_HINT_TOUCH_MOUSE_EVENTS = 'SDL_TOUCH_MOUSE_EVENTS';
+
+{**
+ * \brief A variable controlling which touchpad should generate synthetic mouse events
+ *
+ * This variable can be set to the following values:
+ * "0" - Only front touchpad should generate mouse events. Default
+ * "1" - Only back touchpad should generate mouse events.
+ * "2" - Both touchpads should generate mouse events.
+ *
+ * By default SDL will generate mouse events for all touch devices
+ *}
+SDL_HINT_VITA_TOUCH_MOUSE_DEVICE = 'SDL_HINT_VITA_TOUCH_MOUSE_DEVICE';
+
+{/**
+ * \brief A variable controlling whether the Android / tvOS remotes
+ * should be listed as joystick devices, instead of sending keyboard events.
+ *
+ * This variable can be set to the following values:
+ * "0" - Remotes send enter/escape/arrow key events
+ * "1" - Remotes are available as 2 axis, 2 button joysticks (the default).
+ */}
+SDL_HINT_TV_REMOTE_AS_JOYSTICK = 'SDL_TV_REMOTE_AS_JOYSTICK';
+
+{/**
+ * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
+ */}
+SDL_HINT_VIDEO_HIGHDPI_DISABLED = 'SDL_VIDEO_HIGHDPI_DISABLED';
+
+{**
+ * \brief A variable controlling whether joysticks on Linux will always treat 'hat' axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking whether they may be analog.
+ *
+ * This variable can be set to the following values:
+ * "0" - Only map hat axis inputs to digital hat outputs if the input axes appear to actually be digital (the default)
+ * "1" - Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as digital hats
+ *}
+SDL_HINT_LINUX_DIGITAL_HATS = 'SDL_LINUX_DIGITAL_HATS';
+
+{**
+ * \brief A variable controlling whether digital hats on Linux will apply deadzones to their underlying input axes or use unfiltered values.
+ *
+ * This variable can be set to the following values:
+ * "0" - Return digital hat values based on unfiltered input axis values
+ * "1" - Return digital hat values with deadzones on the input axes taken into account (the default)
+ *}
+SDL_HINT_LINUX_HAT_DEADZONES = 'SDL_LINUX_HAT_DEADZONES';
+
+{/**
+ * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux
+ *
+ * This variable can be set to the following values:
+ * "0" - Use /dev/input/event*
+ * "1" - Use /dev/input/js*
+ *
+ * By default the /dev/input/event* interfaces are used
+ */}
+SDL_HINT_LINUX_JOYSTICK_CLASSIC = 'SDL_LINUX_JOYSTICK_CLASSIC';
+
+{/**
+ * \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values.
+ *
+ * This variable can be set to the following values:
+ * "0" - Return unfiltered joystick axis values (the default)
+ * "1" - Return axis values with deadzones taken into account
+ */}
+SDL_HINT_LINUX_JOYSTICK_DEADZONES = 'SDL_LINUX_JOYSTICK_DEADZONES';
+
+{/**
+ * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac
+ *
+ * If present, holding ctrl while left clicking will generate a right click
+ * event when on Mac.
+ */}
+SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK = 'SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK';
+
+{**
+ * \brief A variable controlling whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing
+ *
+ * This variable can be set to the following values:
+ * "0" - Dispatching OpenGL context updates will block the dispatching thread until the main thread finishes processing (default).
+ * "1" - Dispatching OpenGL context updates will allow the dispatching thread to continue execution.
+ *
+ * Generally you want the default, but if you have OpenGL code in a background thread on a Mac, and the main thread
+ * hangs because it's waiting for that background thread, but that background thread is also hanging because it's
+ * waiting for the main thread to do an update, this might fix your issue.
+ *
+ * This hint only applies to macOS.
+ *
+ * This hint is available since SDL 2.24.0.
+ *}
+SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH = 'SDL_MAC_OPENGL_ASYNC_DISPATCH';
+
+{/**
+ * \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries
+ *
+ * SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It
+ * can use two different sets of binaries, those compiled by the user from source
+ * or those provided by the Chrome browser. In the later case, these binaries require
+ * that SDL loads a DLL providing the shader compiler.
+ *
+ * This variable can be set to the following values:
+ * "d3dcompiler_46.dll" - default, best for Vista or later.
+ * "d3dcompiler_43.dll" - for XP support.
+ * "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries.
+ *
+ */}
+SDL_HINT_VIDEO_WIN_D3DCOMPILER = 'SDL_VIDEO_WIN_D3DCOMPILER';
+
+{/**
+ * \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
+ *
+ * If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has
+ * SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly
+ * created SDL_Window:
+ *
+ * 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is
+ * needed for example when sharing an OpenGL context across multiple windows.
+ *
+ * 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for
+ * OpenGL rendering.
+ *
+ * This variable can be set to the following values:
+ * The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should
+ * share a pixel format with.
+ */}
+SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT = 'SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT';
+
+{**
+ * \brief When calling SDL_CreateWindowFrom(), make the window compatible with OpenGL.
+ *
+ * This variable can be set to the following values:
+ * "0" - Don't add any graphics flags to the SDL_WindowFlags
+ * "1" - Add SDL_WINDOW_OPENGL to the SDL_WindowFlags
+ *
+ * By default SDL will not make the foreign window compatible with OpenGL.
+ *}
+SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL = 'SDL_VIDEO_FOREIGN_WINDOW_OPENGL';
+
+{**
+ * \brief When calling SDL_CreateWindowFrom(), make the window compatible with Vulkan.
+ *
+ * This variable can be set to the following values:
+ * "0" - Don't add any graphics flags to the SDL_WindowFlags
+ * "1" - Add SDL_WINDOW_VULKAN to the SDL_WindowFlags
+ *
+ * By default SDL will not make the foreign window compatible with Vulkan.
+ *}
+SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN = 'SDL_VIDEO_FOREIGN_WINDOW_VULKAN';
+
+{/**
+ * \brief A URL to a WinRT app's privacy policy
+ *
+ * All network-enabled WinRT apps must make a privacy policy available to its
+ * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be
+ * be available in the Windows Settings charm, as accessed from within the app.
+ * SDL provides code to add a URL-based link there, which can point to the app's
+ * privacy policy.
+ *
+ * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL
+ * before calling any SDL_Init() functions. The contents of the hint should
+ * be a valid URL. For example, "http://www.example.com".
+ *
+ * The default value is "", which will prevent SDL from adding a privacy policy
+ * link to the Settings charm. This hint should only be set during app init.
+ *
+ * The label text of an app's "Privacy Policy" link may be customized via another
+ * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL.
+ *
+ * Please note that on Windows Phone, Microsoft does not provide standard UI
+ * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL
+ * will not get used on that platform. Network-enabled phone apps should display
+ * their privacy policy through some other, in-app means.
+ */}
+SDL_HINT_WINRT_PRIVACY_POLICY_URL = 'SDL_WINRT_PRIVACY_POLICY_URL';
+
+{/**
+ * \brief Label text for a WinRT app's privacy policy link
+ *
+ * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT,
+ * Microsoft mandates that this policy be available via the Windows Settings charm.
+ * SDL provides code to add a link there, with its label text being set via the
+ * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL.
+ *
+ * Please note that a privacy policy's contents are not set via this hint. A separate
+ * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the
+ * policy.
+ *
+ * The contents of this hint should be encoded as a UTF8 string.
+ *
+ * The default value is "Privacy Policy". This hint should only be set during app
+ * initialization, preferably before any calls to SDL_Init().
+ *
+ * For additional information on linking to a privacy policy, see the documentation for
+ * SDL_HINT_WINRT_PRIVACY_POLICY_URL.
+ */}
+SDL_HINT_WINRT_PRIVACY_POLICY_LABEL = 'SDL_WINRT_PRIVACY_POLICY_LABEL';
+
+{/**
+ * \brief Allows back-button-press events on Windows Phone to be marked as handled
+ *
+ * Windows Phone devices typically feature a Back button. When pressed,
+ * the OS will emit back-button-press events, which apps are expected to
+ * handle in an appropriate manner. If apps do not explicitly mark these
+ * events as 'Handled', then the OS will invoke its default behavior for
+ * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to
+ * terminate the app (and attempt to switch to the previous app, or to the
+ * device's home screen).
+ *
+ * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL
+ * to mark back-button-press events as Handled, if and when one is sent to
+ * the app.
+ *
+ * Internally, Windows Phone sends back button events as parameters to
+ * special back-button-press callback functions. Apps that need to respond
+ * to back-button-press events are expected to register one or more
+ * callback functions for such, shortly after being launched (during the
+ * app's initialization phase). After the back button is pressed, the OS
+ * will invoke these callbacks. If the app's callback(s) do not explicitly
+ * mark the event as handled by the time they return, or if the app never
+ * registers one of these callback, the OS will consider the event
+ * un-handled, and it will apply its default back button behavior (terminate
+ * the app).
+ *
+ * SDL registers its own back-button-press callback with the Windows Phone
+ * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN
+ * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which
+ * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON.
+ * If the hint's value is set to "1", the back button event's Handled
+ * property will get set to 'true'. If the hint's value is set to something
+ * else, or if it is unset, SDL will leave the event's Handled property
+ * alone. (By default, the OS sets this property to 'false', to note.)
+ *
+ * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a
+ * back button is pressed, or can set it in direct-response to a back button
+ * being pressed.
+ *
+ * In order to get notified when a back button is pressed, SDL apps should
+ * register a callback function with SDL_AddEventWatch(), and have it listen
+ * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK.
+ * (Alternatively, SDL_KEYUP events can be listened-for. Listening for
+ * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON
+ * set by such a callback, will be applied to the OS' current
+ * back-button-press event.
+ *
+ * More details on back button behavior in Windows Phone apps can be found
+ * at the following page, on Microsoft's developer site:
+ * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx
+ */}
+SDL_HINT_WINRT_HANDLE_BACK_BUTTON = 'SDL_WINRT_HANDLE_BACK_BUTTON';
+
+{/**
+ * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X.
+ *
+ * This hint only applies to Mac OS X.
+ *
+ * The variable can be set to the following values:
+ * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and
+ * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen"
+ * button on their titlebars).
+ * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and
+ * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen"
+ * button on their titlebars).
+ *
+ * The default value is "1". Spaces are disabled regardless of this hint if
+ * the OS isn't at least Mac OS X Lion (10.7). This hint must be set before
+ * any windows are created.
+ */}
+SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES = 'SDL_VIDEO_MAC_FULLSCREEN_SPACES';
+
+{/**
+ * \brief When set don't force the SDL app to become a foreground process
+ *
+ * This hint only applies to Mac OS X.
+ *
+ */}
+SDL_HINT_MAC_BACKGROUND_APP = 'SDL_MAC_BACKGROUND_APP';
+
+{/**
+ * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc.
+ *
+ * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION.
+ *
+ * If both hints were set then SDL_RWFromFile() will look into expansion files
+ * after a given relative path was not found in the internal storage and assets.
+ *
+ * By default this hint is not set and the APK expansion files are not searched.
+ */}
+SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION = 'SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION';
+
+{/**
+ * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc.
+ *
+ * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION.
+ *
+ * If both hints were set then SDL_RWFromFile() will look into expansion files
+ * after a given relative path was not found in the internal storage and assets.
+ *
+ * By default this hint is not set and the APK expansion files are not searched.
+ */}
+SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION = 'SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION';
+
+{/**
+ * \brief A variable to control whether the event loop will block itself when the app is paused.
+ *
+ * The variable can be set to the following values:
+ * "0" - Non blocking.
+ * "1" - Blocking. (default)
+ *
+ * The value should be set before SDL is initialized.
+ */}
+SDL_HINT_ANDROID_BLOCK_ON_PAUSE = 'SDL_ANDROID_BLOCK_ON_PAUSE';
+
+{/**
+ * \brief A variable to control whether SDL will pause audio in background
+ * (Requires SDL_ANDROID_BLOCK_ON_PAUSE as "Non blocking")
+ *
+ * The variable can be set to the following values:
+ * "0" - Non paused.
+ * "1" - Paused. (default)
+ *
+ * The value should be set before SDL is initialized.
+ */}
+SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO = 'SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO';
+
+{/**
+ * \brief A variable to control whether we trap the Android back button to handle it manually.
+ * This is necessary for the right mouse button to work on some Android devices, or
+ * to be able to trap the back button for use in your code reliably. If set to true,
+ * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of
+ * SDL_SCANCODE_AC_BACK.
+ *
+ * The variable can be set to the following values:
+ * "0" - Back button will be handled as usual for system. (default)
+ * "1" - Back button will be trapped, allowing you to handle the key press
+ * manually. (This will also let right mouse click work on systems
+ * where the right mouse button functions as back.)
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */}
+SDL_HINT_ANDROID_TRAP_BACK_BUTTON = 'SDL_ANDROID_TRAP_BACK_BUTTON';
+
+{/**
+ * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events.
+ *
+ * The variable can be set to the following values:
+ * "0" - SDL_TEXTEDITING events are sent, and it is the application's
+ * responsibility to render the text from these events and
+ * differentiate it somehow from committed text. (default)
+ * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent,
+ * and text that is being composed will be rendered in its own UI.
+ */}
+SDL_HINT_IME_INTERNAL_EDITING = 'SDL_IME_INTERNAL_EDITING';
+
+{/**
+ * \brief A variable to control whether certain IMEs should show native UI components (such as the Candidate List) instead of suppressing them.
+ *
+ * The variable can be set to the following values:
+ * "0" - Native UI components are not display. (default)
+ * "1" - Native UI components are displayed.
+ */}
+SDL_HINT_IME_SHOW_UI = 'SDL_IME_SHOW_UI';
+
+{**
+ * \brief A variable to control if extended IME text support is enabled.
+ * If enabled then SDL_TextEditingExtEvent will be issued if the text would be truncated otherwise.
+ * Additionally SDL_TextInputEvent will be dispatched multiple times so that it is not truncated.
+ *
+ * The variable can be set to the following values:
+ * "0" - Legacy behavior. Text can be truncated, no heap allocations. (default)
+ * "1" - Modern behavior.
+ *}
+SDL_HINT_IME_SUPPORT_EXTENDED_TEXT = 'SDL_IME_SUPPORT_EXTENDED_TEXT';
+
+{/**
+ * \brief A variable to control whether mouse and touch events are to be treated together or separately
+ *
+ * The variable can be set to the following values:
+ * "0" - Mouse events will be handled as touch events, and touch will raise fake mouse
+ * events. This is the behaviour of SDL <= 2.0.3. (default)
+ * "1" - Mouse events will be handled separately from pure touch events.
+ *
+ * NOTE: This hint is no longer supported on SDL >= 2.0.10.
+ * Use SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS
+ * for generating synthetic touch/mouse events.
+ */}
+SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH = 'SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH'
+ deprecated 'This hint is no longer supported on SDL >= 2.0.10. Use SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS instead.';
+
+{/**
+ * \brief Disable giving back control to the browser automatically
+ * when running with asyncify
+ *
+ * With -s ASYNCIFY, SDL2 calls emscripten_sleep during operations
+ * such as refreshing the screen or polling events.
+ *
+ * This hint only applies to the emscripten platform
+ *
+ * The variable can be set to the following values:
+ * "0" - Disable emscripten_sleep calls (if you give back browser control manually or use asyncify for other purposes)
+ * "1" - Enable emscripten_sleep calls (the default)
+ */}
+SDL_HINT_EMSCRIPTEN_ASYNCIFY = 'SDL_EMSCRIPTEN_ASYNCIFY';
+
+{/**
+ * \brief override the binding element for keyboard inputs for Emscripten builds
+ *
+ * This hint only applies to the emscripten platform
+ *
+ * The variable can be one of
+ * "#window" - The javascript window object (this is the default)
+ * "#document" - The javascript document object
+ * "#screen" - the javascript window.screen object
+ * "#canvas" - the WebGL canvas element
+ * any other string without a leading # sign applies to the element on the page with that ID.
+ */}
+SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT = 'SDL_EMSCRIPTEN_KEYBOARD_ELEMENT';
+
+{/**
+ * \brief Tell SDL not to catch the SIGINT or SIGTERM signals.
+ *
+ * This hint only applies to Unix-like platforms.
+ *
+ * The variable can be set to the following values:
+ * "0" - SDL will install a SIGINT and SIGTERM handler, and when it
+ * catches a signal, convert it into an SDL_QUIT event.
+ * "1" - SDL will not install a signal handler at all.
+ */}
+SDL_HINT_NO_SIGNAL_HANDLERS = 'SDL_NO_SIGNAL_HANDLERS';
+
+{**
+ * \brief A variable that decides whether to send SDL_QUIT when closing the final window.
+ *
+ * By default, SDL sends an SDL_QUIT event when there is only one window
+ * and it receives an SDL_WINDOWEVENT_CLOSE event, under the assumption most
+ * apps would also take the loss of this window as a signal to terminate the
+ * program.
+ *
+ * However, it's not unreasonable in some cases to have the program continue
+ * to live on, perhaps to create new windows later.
+ *
+ * Changing this hint to "0" will cause SDL to not send an SDL_QUIT event
+ * when the final window is requesting to close. Note that in this case,
+ * there are still other legitimate reasons one might get an SDL_QUIT
+ * event: choosing "Quit" from the macOS menu bar, sending a SIGINT (ctrl-c)
+ * on Unix, etc.
+ *
+ * The default value is "1". This hint can be changed at any time.
+ *
+ * This hint is available since SDL 2.0.22. Before then, you always get
+ * an SDL_QUIT event when closing the final window.
+ *}
+SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE = 'SDL_QUIT_ON_LAST_WINDOW_CLOSE';
+
+{/**
+ * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows.
+ *
+ * The variable can be set to the following values:
+ * "0" - SDL will generate a window-close event when it sees Alt+F4.
+ * "1" - SDL will only do normal key handling for Alt+F4.
+ */}
+SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 = 'SDL_WINDOWS_NO_CLOSE_ON_ALT_F4';
+
+{/**
+ * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs.
+ *
+ * The bitmap header version 4 is required for proper alpha channel support and
+ * SDL will use it when required. Should this not be desired, this hint can
+ * force the use of the 40 byte header version which is supported everywhere.
+ *
+ * The variable can be set to the following values:
+ * "0" - Surfaces with a colorkey or an alpha channel are saved to a
+ * 32-bit BMP file with an alpha mask. SDL will use the bitmap
+ * header version 4 and set the alpha mask accordingly.
+ * "1" - Surfaces with a colorkey or an alpha channel are saved to a
+ * 32-bit BMP file without an alpha mask. The alpha channel data
+ * will be in the file, but applications are going to ignore it.
+ *
+ * The default value is "0".
+ */}
+SDL_HINT_BMP_SAVE_LEGACY_FORMAT = 'SDL_BMP_SAVE_LEGACY_FORMAT';
+
+{/**
+ * \brief Tell SDL not to name threads on Windows.
+ *
+ * The variable can be set to the following values:
+ * "0" - SDL will raise the 0x406D1388 Exception to name threads.
+ * This is the default behavior of SDL <= 2.0.4. (default)
+ * "1" - SDL will not raise this exception, and threads will be unnamed.
+ * For .NET languages this is required when running under a debugger.
+ */}
+SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING = 'SDL_WINDOWS_DISABLE_THREAD_NAMING';
+
+{/**
+ * \brief A variable to control whether the return key on the soft keyboard
+ * should hide the soft keyboard on Android and iOS.
+ *
+ * The variable can be set to the following values:
+ * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default)
+ * "1" - The return key will hide the keyboard.
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */}
+SDL_HINT_RETURN_KEY_HIDES_IME = 'SDL_RETURN_KEY_HIDES_IME';
+
+{/**
+ * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI
+ *
+ * Also known as Z-order. The variable can take a negative or positive value.
+ * The default is 10000.
+ */}
+SDL_HINT_RPI_VIDEO_LAYER = 'SDL_RPI_VIDEO_LAYER';
+
+{**
+ * \brief A variable that decides what audio backend to use.
+ *
+ * By default, SDL will try all available audio backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app
+ * or user to force a specific target, such as "alsa" if, say, you are
+ * on PulseAudio but want to try talking to the lower level instead.
+ *
+ * This functionality has existed since SDL 2.0.0 (indeed, before that)
+ * but before 2.0.22 this was an environment variable only. In 2.0.22,
+ * it was upgraded to a full SDL hint, so you can set the environment
+ * variable as usual or programatically set the hint with SDL_SetHint,
+ * which won't propagate to child processes.
+ *
+ * The default value is unset, in which case SDL will try to figure out
+ * the best audio backend on your behalf. This hint needs to be set
+ * before SDL_Init() is called to be useful.
+ *
+ * This hint is available since SDL 2.0.22. Before then, you could set
+ * the environment variable to get the same effect.
+ *}
+SDL_HINT_AUDIODRIVER = 'SDL_AUDIODRIVER';
+
+{**
+ * \brief A variable that decides what video backend to use.
+ *
+ * By default, SDL will try all available video backends in a reasonable
+ * order until it finds one that can work, but this hint allows the app
+ * or user to force a specific target, such as "x11" if, say, you are
+ * on Wayland but want to try talking to the X server instead.
+ *
+ * This functionality has existed since SDL 2.0.0 (indeed, before that)
+ * but before 2.0.22 this was an environment variable only. In 2.0.22,
+ * it was upgraded to a full SDL hint, so you can set the environment
+ * variable as usual or programatically set the hint with SDL_SetHint,
+ * which won't propagate to child processes.
+ *
+ * The default value is unset, in which case SDL will try to figure out
+ * the best video backend on your behalf. This hint needs to be set
+ * before SDL_Init() is called to be useful.
+ *
+ * This hint is available since SDL 2.0.22. Before then, you could set
+ * the environment variable to get the same effect.
+ *}
+SDL_HINT_VIDEODRIVER = 'SDL_VIDEODRIVER';
+
+{**
+ * \brief A variable that decides what KMSDRM device to use.
+ *
+ * Internally, SDL might open something like "/dev/dri/cardNN" to
+ * access KMSDRM functionality, where "NN" is a device index number.
+ *
+ * SDL makes a guess at the best index to use (usually zero), but the
+ * app or user can set this hint to a number between 0 and 99 to
+ * force selection.
+ *
+ * This hint is available since SDL 2.24.0.
+ *}
+SDL_HINT_KMSDRM_DEVICE_INDEX = 'SDL_KMSDRM_DEVICE_INDEX';
+
+{**
+ * \brief A variable that treats trackpads as touch devices.
+ *
+ * On macOS (and possibly other platforms in the future), SDL will report
+ * touches on a trackpad as mouse input, which is generally what users
+ * expect from this device; however, these are often actually full
+ * multitouch-capable touch devices, so it might be preferable to some apps
+ * to treat them as such.
+ *
+ * Setting this hint to true will make the trackpad input report as a
+ * multitouch device instead of a mouse. The default is false.
+ *
+ * Note that most platforms don't support this hint. As of 2.24.0, it
+ * only supports MacBooks' trackpads on macOS. Others may follow later.
+ *
+ * This hint is checked during SDL_Init and can not be changed after.
+ *
+ * This hint is available since SDL 2.24.0.
+ *}
+SDL_HINT_TRACKPAD_IS_TOUCH_ONLY = 'SDL_TRACKPAD_IS_TOUCH_ONLY';
+
+{/**
+ * \brief An enumeration of hint priorities
+ */}
+type
+ PPSDL_HintPriority = ^PSDL_HintPriority;
+ PSDL_HintPriority = ^TSDL_HintPriority;
+ TSDL_HintPriority = type Integer;
+
+const
+ SDL_HINT_DEFAULT = TSDL_HintPriority(0);
+ SDL_HINT_NORMAL = TSDL_HintPriority(1);
+ SDL_HINT_OVERRIDE = TSDL_HintPriority(2);
+
+{/**
+ * \brief Set a hint with a specific priority
+ *
+ * The priority controls the behavior when setting a hint that already
+ * has a value. Hints will replace existing hints of their priority and
+ * lower. Environment variables are considered to have override priority.
+ *
+ * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetHintWithPriority_func = function(const name: PAnsiChar; const value: PAnsiChar; priority: TSDL_HintPriority): TSDL_Bool; cdecl;
+Var
+ SDL_SetHintWithPriority : TSDL_SetHintWithPriority_func = Nil;
+{$else}
+
+function SDL_SetHintWithPriority(const name: PAnsiChar; const value: PAnsiChar; priority: TSDL_HintPriority): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetHintWithPriority' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * \brief Set a hint with normal priority
+ *
+ * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetHint_func = function(const name: PAnsiChar; const value: PAnsiChar): TSDL_Bool; cdecl;
+Var
+ SDL_SetHint : TSDL_SetHint_func = Nil;
+{$else}
+
+function SDL_SetHint(const name: PAnsiChar; const value: PAnsiChar): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetHint' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Reset a hint to the default value.
+ *
+ * This will reset a hint to the value of the environment variable,
+ * or NIL if the environment isn't set. Callbacks will be called normally
+ * with this change.
+ *
+ * \param name the hint to set
+ * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ResetHint_func = function(const name: PAnsiChar): TSDL_Bool; cdecl;
+Var
+ SDL_ResetHint : TSDL_ResetHint_func = Nil;
+{$else}
+
+function SDL_ResetHint(const name: PAnsiChar): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResetHint' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Reset all hints to the default values.
+ *
+ * This will reset all hints to the value of the associated environment
+ * variable, or NIL if the environment isn't set. Callbacks will be called
+ * normally with this change.
+ *
+ * \since This function is available since SDL 2.26.0.
+ *
+ * \sa SDL_GetHint
+ * \sa SDL_SetHint
+ * \sa SDL_ResetHint
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ResetHints_proc = procedure(); cdecl;
+Var
+ SDL_ResetHints : TSDL_ResetHints_proc = Nil;
+{$else}
+
+procedure SDL_ResetHints(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResetHints' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * \brief Get a hint
+ *
+ * \return The string value of a hint variable.
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetHint_func = function(const name: PAnsiChar): PAnsiChar; cdecl;
+Var
+ SDL_GetHint : TSDL_GetHint_func = Nil;
+{$else}
+
+function SDL_GetHint(const name: PAnsiChar): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetHint' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * \brief Get a hint
+ *
+ * \return The boolean value of a hint variable.
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetHintBoolean_func = function(const name: PAnsiChar; default_value: TSDL_Bool): TSDL_Bool; cdecl;
+Var
+ SDL_GetHintBoolean : TSDL_GetHintBoolean_func = Nil;
+{$else}
+
+function SDL_GetHintBoolean(const name: PAnsiChar; default_value: TSDL_Bool): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetHintBoolean' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * \brief Add a function to watch a particular hint
+ *
+ * \param name The hint to watch
+ * \param callback The function to call when the hint value changes
+ * \param userdata A pointer to pass to the callback function
+ */}
+type
+ PPSDL_HintCallback = ^PSDL_HintCallback;
+ PSDL_HintCallback = ^TSDL_HintCallback;
+ TSDL_HintCallback = procedure(userdata: Pointer; const name: PAnsiChar; const oldValue: PAnsiChar; const newValue: PAnsiChar); cdecl;
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AddHintCallback_proc = procedure(const name: PAnsiChar; callback: TSDL_HintCallback; userdata: Pointer); cdecl;
+Var
+ SDL_AddHintCallback : TSDL_AddHintCallback_proc = Nil;
+{$else}
+
+procedure SDL_AddHintCallback(const name: PAnsiChar; callback: TSDL_HintCallback; userdata: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AddHintCallback' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * \brief Remove a function watching a particular hint
+ *
+ * \param name The hint being watched
+ * \param callback The function being called when the hint value changes
+ * \param userdata A pointer being passed to the callback function
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DelHintCallback_proc = procedure(const name: PAnsiChar; callback: TSDL_HintCallback; userdata: Pointer); cdecl;
+Var
+ SDL_DelHintCallback : TSDL_DelHintCallback_proc = Nil;
+{$else}
+
+procedure SDL_DelHintCallback(const name: PAnsiChar; callback: TSDL_HintCallback; userdata: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DelHintCallback' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Clear all hints.
+ *
+ * This function is automatically called during SDL_Quit(), and deletes all
+ * callbacks without calling them and frees all memory associated with hints.
+ * If you're calling this from application code you probably want to call
+ * SDL_ResetHints() instead.
+ *
+ * This function will be removed from the API the next time we rev the ABI.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_ResetHints
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ClearHints_proc = procedure(); cdecl;
+Var
+ SDL_ClearHints : TSDL_ClearHints_proc = Nil;
+{$else}
+
+procedure SDL_ClearHints(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearHints' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdljoystick.inc b/units/sdl2_for_pascal/sdljoystick.inc
new file mode 100644
index 0000000..1baf9b7
--- /dev/null
+++ b/units/sdl2_for_pascal/sdljoystick.inc
@@ -0,0 +1,1541 @@
+{**
+ * \file SDL_joystick.h
+ *
+ * Include file for SDL joystick event handling
+ *
+ * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick
+ * behind a device_index changing as joysticks are plugged and unplugged.
+ *
+ * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted
+ * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in.
+ *
+ * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of
+ * the device (a X360 wired controller for example). This identifier is platform dependent.
+ *
+ *
+ *}
+
+ {**
+ * \file SDL_joystick.h
+ *
+ * In order to use these functions, SDL_Init() must have been called
+ * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system
+ * for joysticks, and load appropriate drivers.
+ *
+ * If you would like to receive joystick updates while the application
+ * is in the background, you should set the following hint before calling
+ * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
+ *}
+
+type
+ {* The joystick structure used to identify an SDL joystick *}
+ PPSDL_Joystick = ^PSDL_Joystick;
+ PSDL_Joystick = type Pointer;
+
+ {* A structure that encodes the stable unique id for a joystick device *}
+ PPSDL_JoystickGUID = ^PSDL_JoystickGUID;
+ PSDL_JoystickGUID = ^TSDL_JoystickGUID;
+ TSDL_JoystickGUID = type TSDL_GUID;
+
+ {**
+ * This is a unique ID for a joystick for the time it is connected to the system,
+ * and is never reused for the lifetime of the application. If the joystick is
+ * disconnected and reconnected, it will get a new ID.
+ *
+ * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
+ *}
+ PPSDL_JoystickID = ^PSDL_JoystickID;
+ PSDL_JoystickID = ^TSDL_JoystickID;
+ TSDL_JoystickID = type cint32;
+
+type
+ PPSDL_JoystickType = ^PSDL_JoystickType;
+ PSDL_JoystickType = ^TSDL_JoystickType;
+ TSDL_JoystickType = type Integer;
+
+const
+ SDL_JOYSTICK_TYPE_UNKNOWN = TSDL_JoystickType(0);
+ SDL_JOYSTICK_TYPE_GAMECONTROLLER = TSDL_JoystickType(1);
+ SDL_JOYSTICK_TYPE_WHEEL = TSDL_JoystickType(2);
+ SDL_JOYSTICK_TYPE_ARCADE_STICK = TSDL_JoystickType(3);
+ SDL_JOYSTICK_TYPE_FLIGHT_STICK = TSDL_JoystickType(4);
+ SDL_JOYSTICK_TYPE_DANCE_PAD = TSDL_JoystickType(5);
+ SDL_JOYSTICK_TYPE_GUITAR = TSDL_JoystickType(6);
+ SDL_JOYSTICK_TYPE_DRUM_KIT = TSDL_JoystickType(7);
+ SDL_JOYSTICK_TYPE_ARCADE_PAD = TSDL_JoystickType(8);
+ SDL_JOYSTICK_TYPE_THROTTLE = TSDL_JoystickType(9);
+
+type
+ PPSDL_JoystickPowerLevel = ^PSDL_JoystickPowerLevel;
+ PSDL_JoystickPowerLevel = ^TSDL_JoystickPowerLevel;
+ TSDL_JoystickPowerLevel = type Integer;
+
+const
+ SDL_JOYSTICK_POWER_UNKNOWN = TSDL_JoystickPowerLevel(-1);
+ SDL_JOYSTICK_POWER_EMPTY = TSDL_JoystickPowerLevel(0); {* <= 5% *}
+ SDL_JOYSTICK_POWER_LOW = TSDL_JoystickPowerLevel(1); {* <= 20% *}
+ SDL_JOYSTICK_POWER_MEDIUM = TSDL_JoystickPowerLevel(2); {* <= 70% *}
+ SDL_JOYSTICK_POWER_FULL = TSDL_JoystickPowerLevel(3); {* <= 100% *}
+ SDL_JOYSTICK_POWER_WIRED = TSDL_JoystickPowerLevel(4);
+ SDL_JOYSTICK_POWER_MAX = TSDL_JoystickPowerLevel(5);
+
+ {* Set max recognized G-force from accelerometer
+ See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed
+ *}
+const
+ SDL_IPHONE_MAX_GFORCE = 5.0;
+
+{* Function prototypes *}
+
+{**
+ * Locking for multi-threaded access to the joystick API
+ *
+ * If you are using the joystick API or handling events from multiple threads
+ * you should use these locking functions to protect access to the joysticks.
+ *
+ * In particular, you are guaranteed that the joystick list won't change, so
+ * the API functions that take a joystick index will be valid, and joystick
+ * and game controller events will not be delivered.
+ *
+ * As of SDL 2.26.0, you can take the joystick lock around reinitializing the
+ * joystick subsystem, to prevent other threads from seeing joysticks in an
+ * uninitialized state. However, all open joysticks will be closed and SDL
+ * functions called with them will fail.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockJoysticks_proc = procedure(); cdecl;
+Var
+ SDL_LockJoysticks : TSDL_LockJoysticks_proc = Nil;
+{$else}
+
+procedure SDL_LockJoysticks(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockJoysticks' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Unlocking for multi-threaded access to the joystick API
+ *
+ * If you are using the joystick API or handling events from multiple threads
+ * you should use these locking functions to protect access to the joysticks.
+ *
+ * In particular, you are guaranteed that the joystick list won't change, so
+ * the API functions that take a joystick index will be valid, and joystick
+ * and game controller events will not be delivered.
+ *
+ * \since This function is available since SDL 2.0.7.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnlockJoysticks_proc = procedure(); cdecl;
+Var
+ SDL_UnlockJoysticks : TSDL_UnlockJoysticks_proc = Nil;
+{$else}
+
+procedure SDL_UnlockJoysticks(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockJoysticks' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Count the number of joysticks attached to the system.
+ *
+ * \returns the number of attached joysticks on success or a negative error
+ * code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickName
+ * \sa SDL_JoystickPath
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_NumJoysticks_func = function(): cint; cdecl;
+Var
+ SDL_NumJoysticks : TSDL_NumJoysticks_func = Nil;
+{$else}
+
+function SDL_NumJoysticks(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_NumJoysticks' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the implementation dependent name of a joystick.
+ *
+ * This can be called before any joysticks are opened.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system)
+ * \returns the name of the selected joystick. If no name can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickName
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickNameForIndex_func = function(device_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_JoystickNameForIndex : TSDL_JoystickNameForIndex_func = Nil;
+{$else}
+
+function SDL_JoystickNameForIndex(device_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickNameForIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the implementation dependent path of a joystick.
+ *
+ * This can be called before any joysticks are opened.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system)
+ * \returns the path of the selected joystick. If no path can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_JoystickPath
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickPathForIndex_func = function(device_index: cint): PAnsiChar; cdecl;
+Var
+ SDL_JoystickPathForIndex : TSDL_JoystickPathForIndex_func = Nil;
+{$else}
+
+function SDL_JoystickPathForIndex(device_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickPathForIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the player index of a joystick, or -1 if it's not available This can be
+ * called before any joysticks are opened.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDevicePlayerIndex_func = function(device_index: cint): cint; cdecl;
+Var
+ SDL_JoystickGetDevicePlayerIndex : TSDL_JoystickGetDevicePlayerIndex_func = Nil;
+{$else}
+
+function SDL_JoystickGetDevicePlayerIndex(device_index: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDevicePlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Return the GUID for the joystick at this index
+ * This can be called before any joysticks are opened.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceGUID_func = function(device_index: cint): TSDL_JoystickGUID; cdecl;
+Var
+ SDL_JoystickGetDeviceGUID : TSDL_JoystickGetDeviceGUID_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceGUID(device_index: cint): TSDL_JoystickGUID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceGUID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB vendor ID of a joystick, if available.
+ *
+ * This can be called before any joysticks are opened. If the vendor ID isn't
+ * available this function returns 0.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system
+ * \returns the USB vendor ID of the selected joystick. If called on an
+ * invalid index, this function returns zero
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceVendor_func = function(device_index: cint): cuint16; cdecl;
+Var
+ SDL_JoystickGetDeviceVendor : TSDL_JoystickGetDeviceVendor_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceVendor(device_index: cint): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceVendor' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB product ID of a joystick, if available.
+ *
+ * This can be called before any joysticks are opened. If the product ID isn't
+ * available this function returns 0.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system
+ * \returns the USB product ID of the selected joystick. If called on an
+ * invalid index, this function returns zero
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceProduct_func = function(device_index: cint): cuint16; cdecl;
+Var
+ SDL_JoystickGetDeviceProduct : TSDL_JoystickGetDeviceProduct_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceProduct(device_index: cint): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceProduct' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the product version of a joystick, if available.
+ *
+ * This can be called before any joysticks are opened. If the product version
+ * isn't available this function returns 0.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system
+ * \returns the product version of the selected joystick. If called on an
+ * invalid index, this function returns zero
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceProductVersion_func = function(device_index: cint): cuint16; cdecl;
+Var
+ SDL_JoystickGetDeviceProductVersion : TSDL_JoystickGetDeviceProductVersion_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceProductVersion(device_index: cint): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceProductVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the type of a joystick, if available.
+ *
+ * This can be called before any joysticks are opened.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system
+ * \returns the SDL_JoystickType of the selected joystick. If called on an
+ * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN`
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceType_func = function(device_index: cint): TSDL_JoystickType; cdecl;
+Var
+ SDL_JoystickGetDeviceType : TSDL_JoystickGetDeviceType_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceType(device_index: cint): TSDL_JoystickType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceType' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the instance ID of a joystick.
+ *
+ * This can be called before any joysticks are opened. If the index is out of
+ * range, this function will return -1.
+ *
+ * \param device_index the index of the joystick to query (the N'th joystick
+ * on the system
+ * \returns the instance id of the selected joystick. If called on an invalid
+ * index, this function returns zero
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetDeviceInstanceID_func = function(device_index: cint): TSDL_JoystickID; cdecl;
+Var
+ SDL_JoystickGetDeviceInstanceID : TSDL_JoystickGetDeviceInstanceID_func = Nil;
+{$else}
+
+function SDL_JoystickGetDeviceInstanceID(device_index: cint): TSDL_JoystickID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetDeviceInstanceID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Open a joystick for use.
+ *
+ * The `device_index` argument refers to the N'th joystick presently
+ * recognized by SDL on the system. It is **NOT** the same as the instance ID
+ * used to identify the joystick in future events. See
+ * SDL_JoystickInstanceID() for more details about instance IDs.
+ *
+ * The joystick subsystem must be initialized before a joystick can be opened
+ * for use.
+ *
+ * \param device_index the index of the joystick to query
+ * \returns a joystick identifier or NULL if an error occurred; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickClose
+ * \sa SDL_JoystickInstanceID
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickOpen_func = function(device_index: cint): PSDL_Joystick; cdecl;
+
+Var
+ SDL_JoystickOpen : TSDL_JoystickOpen_func = Nil;
+{$else}
+
+function SDL_JoystickOpen(device_index: cint): PSDL_Joystick; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickOpen' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the SDL_Joystick associated with an instance id.
+ *
+ * \param instance_id the instance id to get the SDL_Joystick for
+ * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickFromInstanceID_func = function(instance_id: TSDL_JoystickID): PSDL_Joystick; cdecl;
+Var
+ SDL_JoystickFromInstanceID : TSDL_JoystickFromInstanceID_func = Nil;
+{$else}
+
+function SDL_JoystickFromInstanceID(instance_id: TSDL_JoystickID): PSDL_Joystick; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickFromInstanceID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the SDL_Joystick associated with a player index.
+ *
+ * \param player_index the player index to get the SDL_Joystick for
+ * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.12.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickFromPlayerIndex_func = function(player_index: cint): PSDL_Joystick; cdecl;
+Var
+ SDL_JoystickFromPlayerIndex : TSDL_JoystickFromPlayerIndex_func = Nil;
+{$else}
+
+function SDL_JoystickFromPlayerIndex(player_index: cint): PSDL_Joystick; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickFromPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Attach a new virtual joystick.
+ *
+ * \returns the joystick's device index, or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickAttachVirtual_func = function(type_: TSDL_JoystickType; naxes: cint; nbuttons: cint; nhats: cint): cint; cdecl;
+Var
+ SDL_JoystickAttachVirtual : TSDL_JoystickAttachVirtual_func = Nil;
+{$else}
+
+function SDL_JoystickAttachVirtual(type_: TSDL_JoystickType; naxes: cint; nbuttons: cint; nhats: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickAttachVirtual' {$ENDIF} {$ENDIF};
+{$endif}
+
+type
+ {**
+ * The structure that defines an extended virtual joystick description
+ *
+ * The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx()
+ * All other elements of this structure are optional and can be left 0.
+ *
+ * \sa SDL_JoystickAttachVirtualEx
+ *}
+ TUpdateProc = procedure(userdata: Pointer); cdecl;
+ TSetPlayerIndexProc = procedure(userdata: Pointer; player_index: cint); cdecl;
+ TRumbleFunc = function(userdata: Pointer; low_frequency_rumble: cuint16; high_frequency_rumble: cuint16): cint; cdecl;
+ TRumbleTriggersFunc = function(userdata: Pointer; left_rumble: cuint16; right_rumble: cuint16): cint; cdecl;
+ TSetLEDFunc = function(userdata: Pointer; red: cuint8; green: cuint8; blue: cuint8): cint; cdecl;
+ TSendEffectFunc = function(userdata: Pointer; const data: Pointer; size: cint): cint; cdecl;
+
+ PPSDL_VirtualJoystickDesc = ^PSDL_VirtualJoystickDesc;
+ PSDL_VirtualJoystickDesc = ^TSDL_VirtualJoystickDesc;
+ TSDL_VirtualJoystickDesc = record
+ version: cuint16; {**< `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` *}
+ type_: cuint16; {**< `SDL_JoystickType` }
+ naxes: cuint16; {**< the number of axes on this joystick *}
+ nbuttons: cuint16; {**< the number of buttons on this joystick *}
+ nhats: cuint16; {**< the number of hats on this joystick *}
+ vendor_id: cuint16; {**< the USB vendor ID of this joystick *}
+ product_id: cuint16; {**< the USB product ID of this joystick *}
+ padding: cuint16; {**< unused *}
+ button_mask: cuint16; {**< A mask of which buttons are valid for this controller
+ e.g. (1 << SDL_CONTROLLER_BUTTON_A) *}
+ axis_mask: cuint32; {**< A mask of which axes are valid for this controller
+ e.g. (1 << SDL_CONTROLLER_AXIS_LEFTX) *}
+ name: PAnsiChar; {**< the name of the joystick *}
+
+ userdata: Pointer; {**< User data pointer passed to callbacks *}
+ Update: TUpdateProc; {**< Called when the joystick state should be updated *}
+ SetPlayerIndex: TSetPlayerIndexProc; {**< Called when the player index is set *}
+ Rumble: TRumbleFunc; {**< Implements SDL_JoystickRumble() *}
+ RumbleTriggers: TRumbleTriggersFunc; {**< Implements SDL_JoystickRumbleTriggers() *}
+ SetLED: TSetLEDFunc; {**< Implements SDL_JoystickSetLED() *}
+ SendEffect: TSendEffectFunc; {**< Implements SDL_JoystickSendEffect() *}
+ end;
+
+{**
+ * \brief The current version of the SDL_VirtualJoystickDesc structure
+ *}
+const
+ SDL_VIRTUAL_JOYSTICK_DESC_VERSION = 1;
+
+{/**
+ * Attach a new virtual joystick with extended properties.
+ *
+ * \returns the joystick's device index, or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.24.0.
+ */}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickAttachVirtualEx_func = function(const desc: PSDL_VirtualJoystickDesc): cint; cdecl;
+Var
+ SDL_JoystickAttachVirtualEx : TSDL_JoystickAttachVirtualEx_func = Nil;
+{$else}
+
+function SDL_JoystickAttachVirtualEx(const desc: PSDL_VirtualJoystickDesc): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickAttachVirtualEx' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Detach a virtual joystick.
+ *
+ * \param device_index a value previously returned from
+ * SDL_JoystickAttachVirtual()
+ * \returns 0 on success, or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickDetachVirtual_func = function(device_index: cint): cint; cdecl;
+Var
+ SDL_JoystickDetachVirtual : TSDL_JoystickDetachVirtual_func = Nil;
+{$else}
+
+function SDL_JoystickDetachVirtual(device_index: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickDetachVirtual' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether or not the joystick at a given device index is virtual.
+ *
+ * \param device_index a joystick device index.
+ * \returns SDL_TRUE if the joystick is virtual, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickIsVirtual_func = function(device_index: cint): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickIsVirtual : TSDL_JoystickIsVirtual_func = Nil;
+{$else}
+
+function SDL_JoystickIsVirtual(device_index: cint): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickIsVirtual' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set values on an opened, virtual-joystick's axis.
+ *
+ * Please note that values set here will not be applied until the next call to
+ * SDL_JoystickUpdate, which can either be called directly, or can be called
+ * indirectly through various other SDL APIs, including, but not limited to
+ * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
+ * SDL_WaitEvent.
+ *
+ * Note that when sending trigger axes, you should scale the value to the full
+ * range of Sint16. For example, a trigger at rest would have the value of
+ * `SDL_JOYSTICK_AXIS_MIN`.
+ *
+ * \param joystick the virtual joystick on which to set state.
+ * \param axis the specific axis on the virtual joystick to set.
+ * \param value the new value for the specified axis.
+ * \returns 0 on success, -1 on error.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSetVirtualAxis_func = function(joystick: PSDL_Joystick; axis: cint; value: cint16): cint; cdecl;
+Var
+ SDL_JoystickSetVirtualAxis : TSDL_JoystickSetVirtualAxis_func = Nil;
+{$else}
+
+function SDL_JoystickSetVirtualAxis(joystick: PSDL_Joystick; axis: cint; value: cint16): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSetVirtualAxis' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set values on an opened, virtual-joystick's button.
+ *
+ * Please note that values set here will not be applied until the next call to
+ * SDL_JoystickUpdate, which can either be called directly, or can be called
+ * indirectly through various other SDL APIs, including, but not limited to
+ * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
+ * SDL_WaitEvent.
+ *
+ * \param joystick the virtual joystick on which to set state.
+ * \param button the specific button on the virtual joystick to set.
+ * \param value the new value for the specified button.
+ * \returns 0 on success, -1 on error.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSetVirtualButton_func = function(joystick: PSDL_Joystick; button: cint; value: cuint8): cint; cdecl;
+Var
+ SDL_JoystickSetVirtualButton : TSDL_JoystickSetVirtualButton_func = Nil;
+{$else}
+
+function SDL_JoystickSetVirtualButton(joystick: PSDL_Joystick; button: cint; value: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSetVirtualButton' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set values on an opened, virtual-joystick's hat.
+ *
+ * Please note that values set here will not be applied until the next call to
+ * SDL_JoystickUpdate, which can either be called directly, or can be called
+ * indirectly through various other SDL APIs, including, but not limited to
+ * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
+ * SDL_WaitEvent.
+ *
+ * \param joystick the virtual joystick on which to set state.
+ * \param hat the specific hat on the virtual joystick to set.
+ * \param value the new value for the specified hat.
+ * \returns 0 on success, -1 on error.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSetVirtualHat_func = function(joystick: PSDL_Joystick; hat: cint; value: cuint8): cint; cdecl;
+Var
+ SDL_JoystickSetVirtualHat : TSDL_JoystickSetVirtualHat_func = Nil;
+{$else}
+
+function SDL_JoystickSetVirtualHat(joystick: PSDL_Joystick; hat: cint; value: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSetVirtualHat' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the implementation dependent name of a joystick.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the name of the selected joystick. If no name can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickNameForIndex
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickName_func = function(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+Var
+ SDL_JoystickName : TSDL_JoystickName_func = Nil;
+{$else}
+
+function SDL_JoystickName(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the implementation dependent path of a joystick.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the path of the selected joystick. If no path can be found, this
+ * function returns NULL; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_JoystickPathForIndex
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickPath_func = function(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+Var
+ SDL_JoystickPath : TSDL_JoystickPath_func = Nil;
+{$else}
+
+function SDL_JoystickPath(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickPath' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the player index of an opened joystick.
+ *
+ * For XInput controllers this returns the XInput user index. Many joysticks
+ * will not be able to supply this information.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the player index, or -1 if it's not available.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetPlayerIndex_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickGetPlayerIndex : TSDL_JoystickGetPlayerIndex_func = Nil;
+{$else}
+
+function SDL_JoystickGetPlayerIndex(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set the player index of an opened joystick.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \param player_index Player index to assign to this joystick, or -1 to clear
+ * the player index and turn off player LEDs.
+ *
+ * \since This function is available since SDL 2.0.12.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSetPlayerIndex_proc = procedure(joystick: PSDL_Joystick; player_index: cint); cdecl;
+Var
+ SDL_JoystickSetPlayerIndex : TSDL_JoystickSetPlayerIndex_proc = Nil;
+{$else}
+
+procedure SDL_JoystickSetPlayerIndex(joystick: PSDL_Joystick; player_index: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSetPlayerIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the implementation-dependent GUID for the joystick.
+ *
+ * This function requires an open joystick.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the GUID of the given joystick. If called on an invalid index,
+ * this function returns a zero GUID; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetDeviceGUID
+ * \sa SDL_JoystickGetGUIDString
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetGUID_func = function(joystick: PSDL_Joystick): TSDL_JoystickGUID; cdecl;
+Var
+ SDL_JoystickGetGUID : TSDL_JoystickGetGUID_func = Nil;
+{$else}
+
+function SDL_JoystickGetGUID(joystick: PSDL_Joystick): TSDL_JoystickGUID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetGUID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB vendor ID of an opened joystick, if available.
+ *
+ * If the vendor ID isn't available this function returns 0.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the USB vendor ID of the selected joystick, or 0 if unavailable.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetVendor_func = function(joystick: PSDL_Joystick): cuint16; cdecl;
+Var
+ SDL_JoystickGetVendor : TSDL_JoystickGetVendor_func = Nil;
+{$else}
+
+function SDL_JoystickGetVendor(joystick: PSDL_Joystick): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetVendor' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the USB product ID of an opened joystick, if available.
+ *
+ * If the product ID isn't available this function returns 0.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the USB product ID of the selected joystick, or 0 if unavailable.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetProduct_func = function(joystick: PSDL_Joystick): cuint16; cdecl;
+Var
+ SDL_JoystickGetProduct : TSDL_JoystickGetProduct_func = Nil;
+{$else}
+
+function SDL_JoystickGetProduct(joystick: PSDL_Joystick): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetProduct' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the product version of an opened joystick, if available.
+ *
+ * If the product version isn't available this function returns 0.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the product version of the selected joystick, or 0 if unavailable.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetProductVersion_func = function(joystick: PSDL_Joystick): cuint16; cdecl;
+Var
+ SDL_JoystickGetProductVersion : TSDL_JoystickGetProductVersion_func = Nil;
+{$else}
+
+function SDL_JoystickGetProductVersion(joystick: PSDL_Joystick): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetProductVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the firmware version of an opened joystick, if available.
+ *
+ * If the firmware version isn't available this function returns 0.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the firmware version of the selected joystick, or 0 if
+ * unavailable.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetFirmwareVersion_func = function(joystick: PSDL_Joystick): cuint16; cdecl;
+Var
+ SDL_JoystickGetFirmwareVersion : TSDL_JoystickGetFirmwareVersion_func = Nil;
+{$else}
+
+function SDL_JoystickGetFirmwareVersion(joystick: PSDL_Joystick): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetFirmwareVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the serial number of an opened joystick, if available.
+ *
+ * Returns the serial number of the joystick, or NULL if it is not available.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the serial number of the selected joystick, or NULL if
+ * unavailable.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetSerial_func = function(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+Var
+ SDL_JoystickGetSerial : TSDL_JoystickGetSerial_func = Nil;
+{$else}
+
+function SDL_JoystickGetSerial(joystick: PSDL_Joystick): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetSerial' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the type of an opened joystick.
+ *
+ * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen()
+ * \returns the SDL_JoystickType of the selected joystick.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetType_func = function(joystick: PSDL_Joystick): TSDL_JoystickType; cdecl;
+Var
+ SDL_JoystickGetType : TSDL_JoystickGetType_func = Nil;
+{$else}
+
+function SDL_JoystickGetType(joystick: PSDL_Joystick): TSDL_JoystickType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetType' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get an ASCII string representation for a given SDL_JoystickGUID.
+ *
+ * You should supply at least 33 bytes for pszGUID.
+ *
+ * \param guid the SDL_JoystickGUID you wish to convert to string
+ * \param pszGUID buffer in which to write the ASCII string
+ * \param cbGUID the size of pszGUID
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetDeviceGUID
+ * \sa SDL_JoystickGetGUID
+ * \sa SDL_JoystickGetGUIDFromString
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetGUIDString_proc = procedure(guid: TSDL_JoystickGUID; pszGUID: PAnsiChar; cbGUID: cint); cdecl;
+Var
+ SDL_JoystickGetGUIDString : TSDL_JoystickGetGUIDString_proc = Nil;
+{$else}
+
+procedure SDL_JoystickGetGUIDString(guid: TSDL_JoystickGUID; pszGUID: PAnsiChar; cbGUID: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetGUIDString' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Convert a GUID string into a SDL_JoystickGUID structure.
+ *
+ * Performs no error checking. If this function is given a string containing
+ * an invalid GUID, the function will silently succeed, but the GUID generated
+ * will not be useful.
+ *
+ * \param pchGUID string containing an ASCII representation of a GUID
+ * \returns a SDL_JoystickGUID structure.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetGUIDString
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetGUIDFromString_func = function(const pchGUID: PAnsiChar): TSDL_JoystickGUID; cdecl;
+Var
+ SDL_JoystickGetGUIDFromString : TSDL_JoystickGetGUIDFromString_func = Nil;
+{$else}
+
+function SDL_JoystickGetGUIDFromString(const pchGUID: PAnsiChar): TSDL_JoystickGUID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetGUIDFromString' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the device information encoded in a SDL_JoystickGUID structure
+ *
+ * \param guid the SDL_JoystickGUID you wish to get info about
+ * \param vendor A pointer filled in with the device VID, or 0 if not
+ * available
+ * \param product A pointer filled in with the device PID, or 0 if not
+ * available
+ * \param version A pointer filled in with the device version, or 0 if not
+ * available
+ * \param crc16 A pointer filled in with a CRC used to distinguish different
+ * products with the same VID/PID, or 0 if not available
+ *
+ * \since This function is available since SDL 2.26.0.
+ *
+ * \sa SDL_JoystickGetDeviceGUID
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetJoystickGUIDInfo_proc = procedure(guid: TSDL_JoystickGUID; vendor: pcuint16; product: pcuint16; version: pcuint16; crc16: pcuint16); cdecl;
+Var
+ SDL_GetJoystickGUIDInfo : TSDL_GetJoystickGUIDInfo_proc = Nil;
+{$else}
+
+procedure SDL_GetJoystickGUIDInfo(guid: TSDL_JoystickGUID; vendor: pcuint16; product: pcuint16; version: pcuint16; crc16: pcuint16); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickGUIDInfo' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the status of a specified joystick.
+ *
+ * \param joystick the joystick to query
+ * \returns SDL_TRUE if the joystick has been opened, SDL_FALSE if it has not;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickClose
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetAttached_func = function(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickGetAttached : TSDL_JoystickGetAttached_func = Nil;
+{$else}
+
+function SDL_JoystickGetAttached(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetAttached' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the instance ID of an opened joystick.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \returns the instance ID of the specified joystick on success or a negative
+ * error code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickInstanceID_func = function(joystick: PSDL_Joystick): TSDL_JoystickID; cdecl;
+Var
+ SDL_JoystickInstanceID : TSDL_JoystickInstanceID_func = Nil;
+{$else}
+
+function SDL_JoystickInstanceID(joystick: PSDL_Joystick): TSDL_JoystickID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickInstanceID' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of general axis controls on a joystick.
+ *
+ * Often, the directional pad on a game controller will either look like 4
+ * separate buttons or a POV hat, and not axes, but all of this is up to the
+ * device and platform.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \returns the number of axis controls/number of axes on success or a
+ * negative error code on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetAxis
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickNumAxes_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickNumAxes : TSDL_JoystickNumAxes_func = Nil;
+{$else}
+
+function SDL_JoystickNumAxes(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickNumAxes' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of trackballs on a joystick.
+ *
+ * Joystick trackballs have only relative motion events associated with them
+ * and their state cannot be polled.
+ *
+ * Most joysticks do not have trackballs.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \returns the number of trackballs on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetBall
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickNumBalls_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickNumBalls : TSDL_JoystickNumBalls_func = Nil;
+{$else}
+
+function SDL_JoystickNumBalls(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickNumBalls' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of POV hats on a joystick.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \returns the number of POV hats on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetHat
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickNumHats_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickNumHats : TSDL_JoystickNumHats_func = Nil;
+{$else}
+
+function SDL_JoystickNumHats(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickNumHats' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the number of buttons on a joystick.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \returns the number of buttons on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickGetButton
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickNumButtons_func = function(joystick: PSDL_Joystick): cint; cdecl;
+Var
+ SDL_JoystickNumButtons : TSDL_JoystickNumButtons_func = Nil;
+{$else}
+
+function SDL_JoystickNumButtons(joystick: PSDL_Joystick): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickNumButtons' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Update the current state of the open joysticks.
+ *
+ * This is called automatically by the event loop if any joystick events are
+ * enabled.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickEventState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickUpdate_proc = procedure(); cdecl;
+Var
+ SDL_JoystickUpdate : TSDL_JoystickUpdate_proc = Nil;
+{$else}
+
+procedure SDL_JoystickUpdate(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickUpdate' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Enable/disable joystick event polling.
+ *
+ * If joystick events are disabled, you must call SDL_JoystickUpdate()
+ * yourself and manually check the state of the joystick when you want
+ * joystick information.
+ *
+ * It is recommended that you leave joystick event handling enabled.
+ *
+ * **WARNING**: Calling this function may delete all events currently in SDL's
+ * event queue.
+ *
+ * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE`
+ * \returns 1 if enabled, 0 if disabled, or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * If `state` is `SDL_QUERY` then the current state is returned,
+ * otherwise the new processing state is returned.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GameControllerEventState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickEventState_func = function(state: cint): cint; cdecl;
+Var
+ SDL_JoystickEventState : TSDL_JoystickEventState_func = Nil;
+{$else}
+
+function SDL_JoystickEventState(state: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickEventState' {$ENDIF} {$ENDIF};
+{$endif}
+
+const
+ SDL_JOYSTICK_AXIS_MAX = 32767;
+ SDL_JOYSTICK_AXIS_MIN = -32768;
+
+{**
+ * Get the current state of an axis control on a joystick.
+ *
+ * SDL makes no promises about what part of the joystick any given axis refers
+ * to. Your game should have some sort of configuration UI to let users
+ * specify what each axis should be bound to. Alternately, SDL's higher-level
+ * Game Controller API makes a great effort to apply order to this lower-level
+ * interface, so you know that a specific axis is the "left thumb stick," etc.
+ *
+ * The value returned by SDL_JoystickGetAxis() is a signed integer (-32768 to
+ * 32767) representing the current position of the axis. It may be necessary
+ * to impose certain tolerances on these values to account for jitter.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \param axis the axis to query; the axis indices start at index 0
+ * \returns a 16-bit signed integer representing the current position of the
+ * axis or 0 on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickNumAxes
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetAxis_func = function(joystick: PSDL_Joystick; axis: cint): cint16; cdecl;
+Var
+ SDL_JoystickGetAxis : TSDL_JoystickGetAxis_func = Nil;
+{$else}
+
+function SDL_JoystickGetAxis(joystick: PSDL_Joystick; axis: cint): cint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetAxis' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the initial state of an axis control on a joystick.
+ *
+ * The state is a value ranging from -32768 to 32767.
+ *
+ * The axis indices start at index 0.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \param axis the axis to query; the axis indices start at index 0
+ * \param state Upon return, the initial value is supplied here.
+ * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not.
+ *
+ * \since This function is available since SDL 2.0.6.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetAxisInitialState_func = function(joystick: PSDL_Joystick; axis: cint; state: pcint16): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickGetAxisInitialState : TSDL_JoystickGetAxisInitialState_func = Nil;
+{$else}
+
+function SDL_JoystickGetAxisInitialState(joystick: PSDL_Joystick; axis: cint; state: pcint16): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetAxisInitialState' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Hat positions
+ *}
+const
+ SDL_HAT_CENTERED = $00;
+ SDL_HAT_UP = $01;
+ SDL_HAT_RIGHT = $02;
+ SDL_HAT_DOWN = $04;
+ SDL_HAT_LEFT = $08;
+ SDL_HAT_RIGHTUP = SDL_HAT_RIGHT or SDL_HAT_UP;
+ SDL_HAT_RIGHTDOWN = SDL_HAT_RIGHT or SDL_HAT_DOWN;
+ SDL_HAT_LEFTUP = SDL_HAT_LEFT or SDL_HAT_UP;
+ SDL_HAT_LEFTDOWN = SDL_HAT_LEFT or SDL_HAT_DOWN;
+
+{**
+ * Get the current state of a POV hat on a joystick.
+ *
+ * The returned value will be one of the following positions:
+ *
+ * - `SDL_HAT_CENTERED`
+ * - `SDL_HAT_UP`
+ * - `SDL_HAT_RIGHT`
+ * - `SDL_HAT_DOWN`
+ * - `SDL_HAT_LEFT`
+ * - `SDL_HAT_RIGHTUP`
+ * - `SDL_HAT_RIGHTDOWN`
+ * - `SDL_HAT_LEFTUP`
+ * - `SDL_HAT_LEFTDOWN`
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \param hat the hat index to get the state from; indices start at index 0
+ * \returns the current hat position.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickNumHats
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetHat_func = function(joystick: PSDL_Joystick; hat: cint): cuint8; cdecl;
+Var
+ SDL_JoystickGetHat : TSDL_JoystickGetHat_func = Nil;
+{$else}
+
+function SDL_JoystickGetHat(joystick: PSDL_Joystick; hat: cint): cuint8; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetHat' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the ball axis change since the last poll.
+ *
+ * Trackballs can only return relative motion since the last call to
+ * SDL_JoystickGetBall(), these motion deltas are placed into `dx` and `dy`.
+ *
+ * Most joysticks do not have trackballs.
+ *
+ * \param joystick the SDL_Joystick to query
+ * \param ball the ball index to query; ball indices start at index 0
+ * \param dx stores the difference in the x axis position since the last poll
+ * \param dy stores the difference in the y axis position since the last poll
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickNumBalls
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetBall_func = function(joystick: PSDL_Joystick; ball: cint; dx: pcint; dy: pcint): cint; cdecl;
+Var
+ SDL_JoystickGetBall : TSDL_JoystickGetBall_func = Nil;
+{$else}
+
+function SDL_JoystickGetBall(joystick: PSDL_Joystick; ball: cint; dx: pcint; dy: pcint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetBall' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current state of a button on a joystick.
+ *
+ * \param joystick an SDL_Joystick structure containing joystick information
+ * \param button the button index to get the state from; indices start at
+ * index 0
+ * \returns 1 if the specified button is pressed, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickNumButtons
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickGetButton_func = function(joystick: PSDL_Joystick; button: cint): cuint8; cdecl;
+Var
+ SDL_JoystickGetButton : TSDL_JoystickGetButton_func = Nil;
+{$else}
+
+function SDL_JoystickGetButton(joystick: PSDL_Joystick; button: cint): cuint8; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickGetButton' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Start a rumble effect.
+ *
+ * Each call to this function cancels any previous rumble effect, and calling
+ * it with 0 intensity stops any rumbling.
+ *
+ * \param joystick The joystick to vibrate
+ * \param low_frequency_rumble The intensity of the low frequency (left)
+ * rumble motor, from 0 to 0xFFFF
+ * \param high_frequency_rumble The intensity of the high frequency (right)
+ * rumble motor, from 0 to 0xFFFF
+ * \param duration_ms The duration of the rumble effect, in milliseconds
+ * \returns 0, or -1 if rumble isn't supported on this joystick
+ *
+ * \since This function is available since SDL 2.0.9.
+ *
+ * \sa SDL_JoystickHasRumble
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickRumble_func = function(joystick: PSDL_Joystick; low_frequency_rumble: cuint16; high_frequency_rumble: cuint16; duration_ms: cuint32): cint; cdecl;
+Var
+ SDL_JoystickRumble : TSDL_JoystickRumble_func = Nil;
+{$else}
+
+function SDL_JoystickRumble(joystick: PSDL_Joystick; low_frequency_rumble: cuint16; high_frequency_rumble: cuint16; duration_ms: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickRumble' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Start a rumble effect in the joystick's triggers
+ *
+ * Each call to this function cancels any previous trigger rumble effect, and
+ * calling it with 0 intensity stops any rumbling.
+ *
+ * Note that this is rumbling of the _triggers_ and not the game controller as
+ * a whole. This is currently only supported on Xbox One controllers. If you
+ * want the (more common) whole-controller rumble, use SDL_JoystickRumble()
+ * instead.
+ *
+ * \param joystick The joystick to vibrate
+ * \param left_rumble The intensity of the left trigger rumble motor, from 0
+ * to 0xFFFF
+ * \param right_rumble The intensity of the right trigger rumble motor, from 0
+ * to 0xFFFF
+ * \param duration_ms The duration of the rumble effect, in milliseconds
+ * \returns 0, or -1 if trigger rumble isn't supported on this joystick
+ *
+ * \since This function is available since SDL 2.0.14.
+ *
+ * \sa SDL_JoystickHasRumbleTriggers
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickRumbleTriggers_func = function(joystick: PSDL_Joystick; left_rumble: cuint16; right_rumble: cuint16; duration_ms: cuint32): cint; cdecl;
+Var
+ SDL_JoystickRumbleTriggers : TSDL_JoystickRumbleTriggers_func = Nil;
+{$else}
+
+function SDL_JoystickRumbleTriggers(joystick: PSDL_Joystick; left_rumble: cuint16; right_rumble: cuint16; duration_ms: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickRumbleTriggers' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a joystick has an LED.
+ *
+ * An example of a joystick LED is the light on the back of a PlayStation 4's
+ * DualShock 4 controller.
+ *
+ * \param joystick The joystick to query
+ * \return SDL_TRUE if the joystick has a modifiable LED, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickHasLED_func = function(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickHasLED : TSDL_JoystickHasLED_func = Nil;
+{$else}
+
+function SDL_JoystickHasLED(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickHasLED' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a joystick has rumble support.
+ *
+ * \param joystick The joystick to query
+ * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_JoystickRumble
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickHasRumble_func = function(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickHasRumble : TSDL_JoystickHasRumble_func = Nil;
+{$else}
+
+function SDL_JoystickHasRumble(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickHasRumble' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Query whether a joystick has rumble support on triggers.
+ *
+ * \param joystick The joystick to query
+ * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *
+ * \sa SDL_JoystickRumbleTriggers
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickHasRumbleTriggers_func = function(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+Var
+ SDL_JoystickHasRumbleTriggers : TSDL_JoystickHasRumbleTriggers_func = Nil;
+{$else}
+
+function SDL_JoystickHasRumbleTriggers(joystick: PSDL_Joystick): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickHasRumbleTriggers' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+{**
+ * Update a joystick's LED color.
+ *
+ * An example of a joystick LED is the light on the back of a PlayStation 4's
+ * DualShock 4 controller.
+ *
+ * \param joystick The joystick to update
+ * \param red The intensity of the red LED
+ * \param green The intensity of the green LED
+ * \param blue The intensity of the blue LED
+ * \returns 0 on success, -1 if this joystick does not have a modifiable LED
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSetLED_func = function(joystick: PSDL_Joystick; red: cuint8; green: cuint8; blue: cuint8): cint; cdecl;
+Var
+ SDL_JoystickSetLED : TSDL_JoystickSetLED_func = Nil;
+{$else}
+
+function SDL_JoystickSetLED(joystick: PSDL_Joystick; red: cuint8; green: cuint8; blue: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSetLED' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Send a joystick specific effect packet
+ *
+ * \param joystick The joystick to affect
+ * \param data The data to send to the joystick
+ * \param size The size of the data to send to the joystick
+ * \returns 0, or -1 if this joystick or driver doesn't support effect packets
+ *
+ * \since This function is available since SDL 2.0.16.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickSendEffect_func = function(joystick: PSDL_Joystick; const data: Pointer; size: cint): cint; cdecl;
+Var
+ SDL_JoystickSendEffect : TSDL_JoystickSendEffect_func = Nil;
+{$else}
+
+function SDL_JoystickSendEffect(joystick: PSDL_Joystick; const data: Pointer; size: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickSendEffect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Close a joystick previously opened with SDL_JoystickOpen().
+ *
+ * \param joystick The joystick device to close
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_JoystickOpen
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickClose_proc = procedure(joystick: PSDL_Joystick); cdecl;
+Var
+ SDL_JoystickClose : TSDL_JoystickClose_proc = Nil;
+{$else}
+
+procedure SDL_JoystickClose(joystick: PSDL_Joystick); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickClose' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the battery level of a joystick as SDL_JoystickPowerLevel.
+ *
+ * \param joystick the SDL_Joystick to query
+ * \returns the current battery level as SDL_JoystickPowerLevel on success or
+ * `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown
+ *
+ * \since This function is available since SDL 2.0.4.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_JoystickCurrentPowerLevel_func = function(joystick: PSDL_Joystick): TSDL_JoystickPowerLevel; cdecl;
+Var
+ SDL_JoystickCurrentPowerLevel : TSDL_JoystickCurrentPowerLevel_func = Nil;
+{$else}
+
+function SDL_JoystickCurrentPowerLevel(joystick: PSDL_Joystick): TSDL_JoystickPowerLevel; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickCurrentPowerLevel' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlkeyboard.inc b/units/sdl2_for_pascal/sdlkeyboard.inc
new file mode 100644
index 0000000..4ca62e5
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlkeyboard.inc
@@ -0,0 +1,474 @@
+//from "sdl_keyboard.h"
+
+{*
+ * \file SDL_keyboard.h
+ *
+ * Include file for SDL keyboard event handling
+ }
+
+type
+ { SDL2-for-Pascal:
+ - Is this type used/needed anywhere?
+ - It doesn't seem to be part of sdl_keyboard.h
+ - If not, should be commented out or deleted }
+ PPKeyStateArr = ^PKeyStateArr;
+ PKeyStateArr = ^TKeyStateArr;
+ TKeyStateArr = array[0..65000] of cuint8;
+
+ {*
+ * \brief The SDL keysym structure, used in key events.
+ *
+ * \note If you are looking for translated character input, see the:: SDL_TEXTINPUT event.
+ }
+ PPSDL_Keysym = ^PSDL_Keysym;
+ PSDL_Keysym = ^TSDL_Keysym;
+ TSDL_Keysym = record
+ scancode: TSDL_ScanCode; // SDL physical key code - see SDL_Scancode for details
+ sym: TSDL_KeyCode; // SDL virtual key code - see SDL_Keycode for details
+ mod_: cuint16; // current key modifiers
+ unicode: cuint32; // (deprecated) use SDL_TextInputEvent instead
+ end;
+
+{ Function prototypes }
+
+{*
+ * Query the window which currently has keyboard focus.
+ *
+ * \returns the window with keyboard focus.
+ *
+ * \since This function is available since SDL 2.0.0.
+ }
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetKeyboardFocus_func = function : PSDL_Window; cdecl;
+ Var
+ SDL_GetKeyboardFocus : TSDL_GetKeyboardFocus_func = Nil;
+ {$else}
+ function SDL_GetKeyboardFocus: PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardFocus' {$ENDIF} {$ENDIF};
+ {$endif}
+{*
+ * Get a snapshot of the current state of the keyboard.
+ *
+ * The pointer returned is a pointer to an internal SDL array. It will be
+ * valid for the whole lifetime of the application and should not be freed by
+ * the caller.
+ *
+ * A array element with a value of 1 means that the key is pressed and a value
+ * of 0 means that it is not. Indexes into this array are obtained by using
+ * SDL_Scancode values.
+ *
+ * Use SDL_PumpEvents() to update the state array.
+ *
+ * This function gives you the current state after all events have been
+ * processed, so if a key or button has been pressed and released before you
+ * process events, then the pressed state will never show up in the
+ * SDL_GetKeyboardState() calls.
+ *
+ * Note: This function doesn't take into account whether shift has been
+ * pressed or not.
+ *
+ * \param numkeys if non-nil, receives the length of the returned array
+ * \returns a pointer to an array of key states.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_PumpEvents
+ * \sa SDL_ResetKeyboard
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetKeyboardState_func = function(numkeys: pcint): pcuint8; cdecl;
+Var
+ SDL_GetKeyboardState : TSDL_GetKeyboardState_func = Nil;
+{$else}
+
+function SDL_GetKeyboardState(numkeys: pcint): pcuint8; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardState' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Clear the state of the keyboard
+ *
+ * This function will generate key up events for all pressed keys.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GetKeyboardState
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ResetKeyboard_proc =procedure ; cdecl;
+Var
+ SDL_ResetKeyboard : TSDL_ResetKeyboard_proc = Nil;
+{$else}
+procedure SDL_ResetKeyboard; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResetKeyboard' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Get the current key modifier state for the keyboard.
+ *
+ * \returns an OR'd combination of the modifier keys for the keyboard. See
+ * SDL_Keymod for details.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyboardState
+ * \sa SDL_SetModState
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetModState_func = function : TSDL_Keymod; cdecl;
+Var
+ SDL_GetModState : TSDL_GetModState_func = Nil;
+{$else}
+function SDL_GetModState: TSDL_Keymod; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetModState' {$ENDIF} {$ENDIF};
+ {$endif}
+{*
+ * Set the current key modifier state for the keyboard.
+ *
+ * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose
+ * modifier key states on your application. Simply pass your desired modifier
+ * states into `modstate`. This value may be a bitwise, OR'd combination of
+ * SDL_Keymod values.
+ *
+ * This does not change the keyboard state, only the key modifier flags that
+ * SDL reports.
+ *
+ * \param modstate the desired SDL_Keymod for the keyboard
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetModState
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetModState_proc = procedure(modstate: TSDL_Keymod); cdecl;
+Var
+ SDL_SetModState : TSDL_SetModState_proc = Nil;
+{$else}
+
+procedure SDL_SetModState(modstate: TSDL_Keymod); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetModState' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the key code corresponding to the given scancode according to the
+ * current keyboard layout.
+ *
+ * See SDL_Keycode for details.
+ *
+ * \param scancode the desired SDL_Scancode to query
+ * \returns the SDL_Keycode that corresponds to the given SDL_Scancode.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyName
+ * \sa SDL_GetScancodeFromKey
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetKeyFromScancode_func = function(scancode: TSDL_Scancode): TSDL_Keycode; cdecl;
+Var
+ SDL_GetKeyFromScancode : TSDL_GetKeyFromScancode_func = Nil;
+{$else}
+
+function SDL_GetKeyFromScancode(scancode: TSDL_Scancode): TSDL_Keycode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromScancode' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get the scancode corresponding to the given key code according to the
+ * current keyboard layout.
+ *
+ * See SDL_Scancode for details.
+ *
+ * \param key the desired SDL_Keycode to query
+ * \returns the SDL_Scancode that corresponds to the given SDL_Keycode.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyFromScancode
+ * \sa SDL_GetScancodeName
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetScancodeFromKey_func = function(key: TSDL_Keycode): TSDL_Scancode; cdecl;
+Var
+ SDL_GetScancodeFromKey : TSDL_GetScancodeFromKey_func = Nil;
+{$else}
+
+function SDL_GetScancodeFromKey(key: TSDL_Keycode): TSDL_Scancode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromKey' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get a human-readable name for a scancode.
+ *
+ * See SDL_Scancode for details.
+ *
+ * **Warning**: The returned name is by design not stable across platforms,
+ * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left
+ * Windows" under Microsoft Windows, and some scancodes like
+ * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even
+ * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and
+ * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore
+ * unsuitable for creating a stable cross-platform two-way mapping between
+ * strings and scancodes.
+ *
+ * \param scancode the desired SDL_Scancode to query
+ * \returns a pointer to the name for the scancode. If the scancode doesn't
+ * have a name this function returns an empty string ("").
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetScancodeFromKey
+ * \sa SDL_GetScancodeFromName
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetScancodeName_func = function(scancode: TSDL_Scancode): PAnsiChar; cdecl;
+Var
+ SDL_GetScancodeName : TSDL_GetScancodeName_func = Nil;
+{$else}
+
+function SDL_GetScancodeName(scancode: TSDL_Scancode): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get a scancode from a human-readable name.
+ *
+ * \param name the human-readable scancode name
+ * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't
+ * recognized; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyFromName
+ * \sa SDL_GetScancodeFromKey
+ * \sa SDL_GetScancodeName
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetScancodeFromName_func = function(name: PAnsiChar): TSDL_Scancode; cdecl;
+Var
+ SDL_GetScancodeFromName : TSDL_GetScancodeFromName_func = Nil;
+{$else}
+
+function SDL_GetScancodeFromName(name: PAnsiChar): TSDL_Scancode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get a human-readable name for a key.
+ *
+ * See SDL_Scancode and SDL_Keycode for details.
+ *
+ * \param key the desired SDL_Keycode to query
+ * \returns a pointer to a UTF-8 string that stays valid at least until the
+ * next call to this function. If you need it around any longer, you
+ * must copy it. If the key doesn't have a name, this function
+ * returns an empty string ("").
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyFromName
+ * \sa SDL_GetKeyFromScancode
+ * \sa SDL_GetScancodeFromKey
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetKeyName_func = function(key: TSDL_Keycode): PAnsiChar; cdecl;
+Var
+ SDL_GetKeyName : TSDL_GetKeyName_func = Nil;
+{$else}
+
+function SDL_GetKeyName(key: TSDL_Keycode): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Get a key code from a human-readable name.
+ *
+ * \param name the human-readable key name
+ * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetKeyFromScancode
+ * \sa SDL_GetKeyName
+ * \sa SDL_GetScancodeFromName
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetKeyFromName_func = function(name: PAnsiChar): TSDL_Keycode; cdecl;
+Var
+ SDL_GetKeyFromName : TSDL_GetKeyFromName_func = Nil;
+{$else}
+
+function SDL_GetKeyFromName(name: PAnsiChar): TSDL_Keycode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Start accepting Unicode text input events.
+ *
+ * This function will start accepting Unicode text input events in the focused
+ * SDL window, and start emitting SDL_TextInputEvent (SDL_TEXTINPUT) and
+ * SDL_TextEditingEvent (SDL_TEXTEDITING) events. Please use this function in
+ * pair with SDL_StopTextInput().
+ *
+ * On some platforms using this function activates the screen keyboard.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_SetTextInputRect
+ * \sa SDL_StopTextInput
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_StartTextInput_proc =procedure ; cdecl;
+Var
+ SDL_StartTextInput : TSDL_StartTextInput_proc = Nil;
+{$else}
+procedure SDL_StartTextInput; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StartTextInput' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Check whether or not Unicode text input events are enabled.
+ *
+ * \returns SDL_TRUE if text input events are enabled else SDL_FALSE.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_StartTextInput
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsTextInputActive_func = function : TSDL_bool; cdecl;
+Var
+ SDL_IsTextInputActive : TSDL_IsTextInputActive_func = Nil;
+{$else}
+function SDL_IsTextInputActive: TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsTextInputActive' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Stop receiving any text input events.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_StartTextInput
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_StopTextInput_proc =procedure ; cdecl;
+Var
+ SDL_StopTextInput : TSDL_StopTextInput_proc = Nil;
+{$else}
+procedure SDL_StopTextInput; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StopTextInput' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Dismiss the composition window/IME without disabling the subsystem.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *
+ * \sa SDL_StartTextInput
+ * \sa SDL_StopTextInput
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ClearComposition_proc = procedure ; cdecl;
+Var
+ SDL_ClearComposition : TSDL_ClearComposition_proc = Nil;
+{$else}
+procedure SDL_ClearComposition; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearComposition' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Returns if an IME Composite or Candidate window is currently shown.
+ *
+ * \since This function is available since SDL 2.0.22.
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsTextInputShown_func = function : TSDL_bool; cdecl;
+Var
+ SDL_IsTextInputShown : TSDL_IsTextInputShown_func = Nil;
+{$else}
+function SDL_IsTextInputShown: TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsTextInputShown' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Set the rectangle used to type Unicode text inputs.
+ *
+ * To start text input in a given location, this function is intended to be
+ * called before SDL_StartTextInput, although some platforms support moving
+ * the rectangle even while text input (and a composition) is active.
+ *
+ * Note: If you want to use the system native IME window, try setting hint
+ * **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you
+ * any feedback.
+ *
+ * \param rect the SDL_Rect structure representing the rectangle to receive
+ * text (ignored if nil)
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_StartTextInput
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetTextInputRect_proc = procedure(rect: PSDL_Rect); cdecl;
+Var
+ SDL_SetTextInputRect : TSDL_SetTextInputRect_proc = Nil;
+{$else}
+
+procedure SDL_SetTextInputRect(rect: PSDL_Rect); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextInputRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Check whether the platform has screen keyboard support.
+ *
+ * \returns SDL_TRUE if the platform has some screen keyboard support or
+ * SDL_FALSE if not.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_StartTextInput
+ * \sa SDL_IsScreenKeyboardShown
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasScreenKeyboardSupport_func = function : TSDL_bool; cdecl;
+Var
+ SDL_HasScreenKeyboardSupport : TSDL_HasScreenKeyboardSupport_func = Nil;
+{$else}
+function SDL_HasScreenKeyboardSupport: TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasScreenKeyboardSupport' {$ENDIF} {$ENDIF};
+{$endif}
+{*
+ * Check whether the screen keyboard is shown for given window.
+ *
+ * \param window the window for which screen keyboard should be queried
+ * \returns SDL_TRUE if screen keyboard is shown or SDL_FALSE if not.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_HasScreenKeyboardSupport
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsScreenKeyboardShown_func = function(window: PSDL_Window): TSDL_bool; cdecl;
+Var
+ SDL_IsScreenKeyboardShown : TSDL_IsScreenKeyboardShown_func = Nil;
+{$else}
+
+function SDL_IsScreenKeyboardShown(window: PSDL_Window): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsScreenKeyboardShown' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlkeycode.inc b/units/sdl2_for_pascal/sdlkeycode.inc
new file mode 100644
index 0000000..6f67637
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlkeycode.inc
@@ -0,0 +1,320 @@
+//from "sdl_keycode.h"
+
+ {**
+ * The SDL virtual key representation.
+ *
+ * Values of this type are used to represent keyboard keys using the current
+ * layout of the keyboard. These values include Unicode values representing
+ * the unmodified character that would be generated by pressing the key, or
+ * an SDLK_* constant for those keys that do not generate characters.
+ *
+ * A special exception is the number keys at the top of the keyboard which
+ * always map to SDLK_0...SDLK_9, regardless of layout.
+ *}
+type
+ PPSDL_KeyCode = ^PSDL_KeyCode;
+ PSDL_KeyCode = ^TSDL_KeyCode;
+ TSDL_KeyCode = type cint32;
+
+const
+ SDLK_SCANCODE_MASK = 1 shl 30;
+ //#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
+ //SDL2-for-Pascal: Not translated, see comment about this macro below.
+
+ SDLK_UNKNOWN = TSDL_KeyCode(0);
+
+ SDLK_RETURN = TSDL_KeyCode(#13); // C: '\r'
+ SDLK_ESCAPE = TSDL_KeyCode(#27); // C: '\x1B'
+ SDLK_BACKSPACE = TSDL_KeyCode(#8); // C: '\b'
+ SDLK_TAB = TSDL_KeyCode(#9); // C: '\t'
+ SDLK_SPACE = TSDL_KeyCode(' ');
+ SDLK_EXCLAIM = TSDL_KeyCode('!');
+ SDLK_QUOTEDBL = TSDL_KeyCode('"');
+ SDLK_HASH = TSDL_KeyCode('#');
+ SDLK_PERCENT = TSDL_KeyCode('%');
+ SDLK_DOLLAR = TSDL_KeyCode('$');
+ SDLK_AMPERSAND = TSDL_KeyCode('&');
+ SDLK_QUOTE = TSDL_KeyCode('''');
+ SDLK_LEFTPAREN = TSDL_KeyCode('(');
+ SDLK_RIGHTPAREN = TSDL_KeyCode(')');
+ SDLK_ASTERISK = TSDL_KeyCode('*');
+ SDLK_PLUS = TSDL_KeyCode('+');
+ SDLK_COMMA = TSDL_KeyCode(',');
+ SDLK_MINUS = TSDL_KeyCode('-');
+ SDLK_PERIOD = TSDL_KeyCode('.');
+ SDLK_SLASH = TSDL_KeyCode('/');
+ SDLK_0 = TSDL_KeyCode('0');
+ SDLK_1 = TSDL_KeyCode('1');
+ SDLK_2 = TSDL_KeyCode('2');
+ SDLK_3 = TSDL_KeyCode('3');
+ SDLK_4 = TSDL_KeyCode('4');
+ SDLK_5 = TSDL_KeyCode('5');
+ SDLK_6 = TSDL_KeyCode('6');
+ SDLK_7 = TSDL_KeyCode('7');
+ SDLK_8 = TSDL_KeyCode('8');
+ SDLK_9 = TSDL_KeyCode('9');
+ SDLK_COLON = TSDL_KeyCode(':');
+ SDLK_SEMICOLON = TSDL_KeyCode(';');
+ SDLK_LESS = TSDL_KeyCode('<');
+ SDLK_EQUALS = TSDL_KeyCode('=');
+ SDLK_GREATER = TSDL_KeyCode('>');
+ SDLK_QUESTION = TSDL_KeyCode('?');
+ SDLK_AT = TSDL_KeyCode('@');
+ {*
+ Skip uppercase letters
+ *}
+ SDLK_LEFTBRACKET = TSDL_KeyCode('[');
+ SDLK_BACKSLASH = TSDL_KeyCode('\'); // C: '\\'
+ SDLK_RIGHTBRACKET = TSDL_KeyCode(']');
+ SDLK_CARET = TSDL_KeyCode('^');
+ SDLK_UNDERSCORE = TSDL_KeyCode('_');
+ SDLK_BACKQUOTE = TSDL_KeyCode('`');
+ SDLK_a = TSDL_KeyCode('a');
+ SDLK_b = TSDL_KeyCode('b');
+ SDLK_c = TSDL_KeyCode('c');
+ SDLK_d = TSDL_KeyCode('d');
+ SDLK_e = TSDL_KeyCode('e');
+ SDLK_f = TSDL_KeyCode('f');
+ SDLK_g = TSDL_KeyCode('g');
+ SDLK_h = TSDL_KeyCode('h');
+ SDLK_i = TSDL_KeyCode('i');
+ SDLK_j = TSDL_KeyCode('j');
+ SDLK_k = TSDL_KeyCode('k');
+ SDLK_l = TSDL_KeyCode('l');
+ SDLK_m = TSDL_KeyCode('m');
+ SDLK_n = TSDL_KeyCode('n');
+ SDLK_o = TSDL_KeyCode('o');
+ SDLK_p = TSDL_KeyCode('p');
+ SDLK_q = TSDL_KeyCode('q');
+ SDLK_r = TSDL_KeyCode('r');
+ SDLK_s = TSDL_KeyCode('s');
+ SDLK_t = TSDL_KeyCode('t');
+ SDLK_u = TSDL_KeyCode('u');
+ SDLK_v = TSDL_KeyCode('v');
+ SDLK_w = TSDL_KeyCode('w');
+ SDLK_x = TSDL_KeyCode('x');
+ SDLK_y = TSDL_KeyCode('y');
+ SDLK_z = TSDL_KeyCode('z');
+
+ {SDL2-for-Pascal: In C the following scancodes are or'd by a macro:
+ SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
+
+ We convert the scancodes directly by:
+ TSDL_KeyCode(X or SDLK_SCANCODE_MASK); }
+
+ SDLK_CAPSLOCK = TSDL_KeyCode(SDL_SCANCODE_CAPSLOCK or SDLK_SCANCODE_MASK);
+
+ SDLK_F1 = TSDL_KeyCode(SDL_SCANCODE_F1 or SDLK_SCANCODE_MASK);
+ SDLK_F2 = TSDL_KeyCode(SDL_SCANCODE_F2 or SDLK_SCANCODE_MASK);
+ SDLK_F3 = TSDL_KeyCode(SDL_SCANCODE_F3 or SDLK_SCANCODE_MASK);
+ SDLK_F4 = TSDL_KeyCode(SDL_SCANCODE_F4 or SDLK_SCANCODE_MASK);
+ SDLK_F5 = TSDL_KeyCode(SDL_SCANCODE_F5 or SDLK_SCANCODE_MASK);
+ SDLK_F6 = TSDL_KeyCode(SDL_SCANCODE_F6 or SDLK_SCANCODE_MASK);
+ SDLK_F7 = TSDL_KeyCode(SDL_SCANCODE_F7 or SDLK_SCANCODE_MASK);
+ SDLK_F8 = TSDL_KeyCode(SDL_SCANCODE_F8 or SDLK_SCANCODE_MASK);
+ SDLK_F9 = TSDL_KeyCode(SDL_SCANCODE_F9 or SDLK_SCANCODE_MASK);
+ SDLK_F10 = TSDL_KeyCode(SDL_SCANCODE_F10 or SDLK_SCANCODE_MASK);
+ SDLK_F11 = TSDL_KeyCode(SDL_SCANCODE_F11 or SDLK_SCANCODE_MASK);
+ SDLK_F12 = TSDL_KeyCode(SDL_SCANCODE_F12 or SDLK_SCANCODE_MASK);
+
+ SDLK_PRINTSCREEN = TSDL_KeyCode(SDL_SCANCODE_PRINTSCREEN or SDLK_SCANCODE_MASK);
+ SDLK_SCROLLLOCK = TSDL_KeyCode(SDL_SCANCODE_SCROLLLOCK or SDLK_SCANCODE_MASK);
+ SDLK_PAUSE = TSDL_KeyCode(SDL_SCANCODE_PAUSE or SDLK_SCANCODE_MASK);
+ SDLK_INSERT = TSDL_KeyCode(SDL_SCANCODE_INSERT or SDLK_SCANCODE_MASK);
+ SDLK_HOME = TSDL_KeyCode(SDL_SCANCODE_HOME or SDLK_SCANCODE_MASK);
+ SDLK_PAGEUP = TSDL_KeyCode(SDL_SCANCODE_PAGEUP or SDLK_SCANCODE_MASK);
+ SDLK_DELETE = TSDL_KeyCode(#127); // C: '\x7F'
+ SDLK_END = TSDL_KeyCode(SDL_SCANCODE_END or SDLK_SCANCODE_MASK);
+ SDLK_PAGEDOWN = TSDL_KeyCode(SDL_SCANCODE_PAGEDOWN or SDLK_SCANCODE_MASK);
+ SDLK_RIGHT = TSDL_KeyCode(SDL_SCANCODE_RIGHT or SDLK_SCANCODE_MASK);
+ SDLK_LEFT = TSDL_KeyCode(SDL_SCANCODE_LEFT or SDLK_SCANCODE_MASK);
+ SDLK_DOWN = TSDL_KeyCode(SDL_SCANCODE_DOWN or SDLK_SCANCODE_MASK);
+ SDLK_UP = TSDL_KeyCode(SDL_SCANCODE_UP or SDLK_SCANCODE_MASK);
+
+ SDLK_NUMLOCKCLEAR = TSDL_KeyCode(SDL_SCANCODE_NUMLOCKCLEAR or SDLK_SCANCODE_MASK);
+ SDLK_KP_DIVIDE = TSDL_KeyCode(SDL_SCANCODE_KP_DIVIDE or SDLK_SCANCODE_MASK);
+ SDLK_KP_MULTIPLY = TSDL_KeyCode(SDL_SCANCODE_KP_MULTIPLY or SDLK_SCANCODE_MASK);
+ SDLK_KP_MINUS = TSDL_KeyCode(SDL_SCANCODE_KP_MINUS or SDLK_SCANCODE_MASK);
+ SDLK_KP_PLUS = TSDL_KeyCode(SDL_SCANCODE_KP_PLUS or SDLK_SCANCODE_MASK);
+ SDLK_KP_ENTER = TSDL_KeyCode(SDL_SCANCODE_KP_ENTER or SDLK_SCANCODE_MASK);
+ SDLK_KP_1 = TSDL_KeyCode(SDL_SCANCODE_KP_1 or SDLK_SCANCODE_MASK);
+ SDLK_KP_2 = TSDL_KeyCode(SDL_SCANCODE_KP_2 or SDLK_SCANCODE_MASK);
+ SDLK_KP_3 = TSDL_KeyCode(SDL_SCANCODE_KP_3 or SDLK_SCANCODE_MASK);
+ SDLK_KP_4 = TSDL_KeyCode(SDL_SCANCODE_KP_4 or SDLK_SCANCODE_MASK);
+ SDLK_KP_5 = TSDL_KeyCode(SDL_SCANCODE_KP_5 or SDLK_SCANCODE_MASK);
+ SDLK_KP_6 = TSDL_KeyCode(SDL_SCANCODE_KP_6 or SDLK_SCANCODE_MASK);
+ SDLK_KP_7 = TSDL_KeyCode(SDL_SCANCODE_KP_7 or SDLK_SCANCODE_MASK);
+ SDLK_KP_8 = TSDL_KeyCode(SDL_SCANCODE_KP_8 or SDLK_SCANCODE_MASK);
+ SDLK_KP_9 = TSDL_KeyCode(SDL_SCANCODE_KP_9 or SDLK_SCANCODE_MASK);
+ SDLK_KP_0 = TSDL_KeyCode(SDL_SCANCODE_KP_0 or SDLK_SCANCODE_MASK);
+ SDLK_KP_PERIOD = TSDL_KeyCode(SDL_SCANCODE_KP_PERIOD or SDLK_SCANCODE_MASK);
+
+ SDLK_APPLICATION = TSDL_KeyCode(SDL_SCANCODE_APPLICATION or SDLK_SCANCODE_MASK);
+ SDLK_POWER = TSDL_KeyCode(SDL_SCANCODE_POWER or SDLK_SCANCODE_MASK);
+ SDLK_KP_EQUALS = TSDL_KeyCode(SDL_SCANCODE_KP_EQUALS or SDLK_SCANCODE_MASK);
+ SDLK_F13 = TSDL_KeyCode(SDL_SCANCODE_F13 or SDLK_SCANCODE_MASK);
+ SDLK_F14 = TSDL_KeyCode(SDL_SCANCODE_F14 or SDLK_SCANCODE_MASK);
+ SDLK_F15 = TSDL_KeyCode(SDL_SCANCODE_F15 or SDLK_SCANCODE_MASK);
+ SDLK_F16 = TSDL_KeyCode(SDL_SCANCODE_F16 or SDLK_SCANCODE_MASK);
+ SDLK_F17 = TSDL_KeyCode(SDL_SCANCODE_F17 or SDLK_SCANCODE_MASK);
+ SDLK_F18 = TSDL_KeyCode(SDL_SCANCODE_F18 or SDLK_SCANCODE_MASK);
+ SDLK_F19 = TSDL_KeyCode(SDL_SCANCODE_F19 or SDLK_SCANCODE_MASK);
+ SDLK_F20 = TSDL_KeyCode(SDL_SCANCODE_F20 or SDLK_SCANCODE_MASK);
+ SDLK_F21 = TSDL_KeyCode(SDL_SCANCODE_F21 or SDLK_SCANCODE_MASK);
+ SDLK_F22 = TSDL_KeyCode(SDL_SCANCODE_F22 or SDLK_SCANCODE_MASK);
+ SDLK_F23 = TSDL_KeyCode(SDL_SCANCODE_F23 or SDLK_SCANCODE_MASK);
+ SDLK_F24 = TSDL_KeyCode(SDL_SCANCODE_F24 or SDLK_SCANCODE_MASK);
+ SDLK_EXECUTE = TSDL_KeyCode(SDL_SCANCODE_EXECUTE or SDLK_SCANCODE_MASK);
+ SDLK_HELP = TSDL_KeyCode(SDL_SCANCODE_HELP or SDLK_SCANCODE_MASK);
+ SDLK_MENU = TSDL_KeyCode(SDL_SCANCODE_MENU or SDLK_SCANCODE_MASK);
+ SDLK_SELECT = TSDL_KeyCode(SDL_SCANCODE_SELECT or SDLK_SCANCODE_MASK);
+ SDLK_STOP = TSDL_KeyCode(SDL_SCANCODE_STOP or SDLK_SCANCODE_MASK);
+ SDLK_AGAIN = TSDL_KeyCode(SDL_SCANCODE_AGAIN or SDLK_SCANCODE_MASK);
+ SDLK_UNDO = TSDL_KeyCode(SDL_SCANCODE_UNDO or SDLK_SCANCODE_MASK);
+ SDLK_CUT = TSDL_KeyCode(SDL_SCANCODE_CUT or SDLK_SCANCODE_MASK);
+ SDLK_COPY = TSDL_KeyCode(SDL_SCANCODE_COPY or SDLK_SCANCODE_MASK);
+ SDLK_PASTE = TSDL_KeyCode(SDL_SCANCODE_PASTE or SDLK_SCANCODE_MASK);
+ SDLK_FIND = TSDL_KeyCode(SDL_SCANCODE_FIND or SDLK_SCANCODE_MASK);
+ SDLK_MUTE = TSDL_KeyCode(SDL_SCANCODE_MUTE or SDLK_SCANCODE_MASK);
+ SDLK_VOLUMEUP = TSDL_KeyCode(SDL_SCANCODE_VOLUMEUP or SDLK_SCANCODE_MASK);
+ SDLK_VOLUMEDOWN = TSDL_KeyCode(SDL_SCANCODE_VOLUMEDOWN or SDLK_SCANCODE_MASK);
+ SDLK_KP_COMMA = TSDL_KeyCode(SDL_SCANCODE_KP_COMMA or SDLK_SCANCODE_MASK);
+ SDLK_KP_EQUALSAS400 = TSDL_KeyCode(SDL_SCANCODE_KP_EQUALSAS400 or SDLK_SCANCODE_MASK);
+
+ SDLK_ALTERASE = TSDL_KeyCode(SDL_SCANCODE_ALTERASE or SDLK_SCANCODE_MASK);
+ SDLK_SYSREQ = TSDL_KeyCode(SDL_SCANCODE_SYSREQ or SDLK_SCANCODE_MASK);
+ SDLK_CANCEL = TSDL_KeyCode(SDL_SCANCODE_CANCEL or SDLK_SCANCODE_MASK);
+ SDLK_CLEAR = TSDL_KeyCode(SDL_SCANCODE_CLEAR or SDLK_SCANCODE_MASK);
+ SDLK_PRIOR = TSDL_KeyCode(SDL_SCANCODE_PRIOR or SDLK_SCANCODE_MASK);
+ SDLK_RETURN2 = TSDL_KeyCode(SDL_SCANCODE_RETURN2 or SDLK_SCANCODE_MASK);
+ SDLK_SEPARATOR = TSDL_KeyCode(SDL_SCANCODE_SEPARATOR or SDLK_SCANCODE_MASK);
+ SDLK_OUT = TSDL_KeyCode(SDL_SCANCODE_OUT or SDLK_SCANCODE_MASK);
+ SDLK_OPER = TSDL_KeyCode(SDL_SCANCODE_OPER or SDLK_SCANCODE_MASK);
+ SDLK_CLEARAGAIN = TSDL_KeyCode(SDL_SCANCODE_CLEARAGAIN or SDLK_SCANCODE_MASK);
+ SDLK_CRSEL = TSDL_KeyCode(SDL_SCANCODE_CRSEL or SDLK_SCANCODE_MASK);
+ SDLK_EXSEL = TSDL_KeyCode(SDL_SCANCODE_EXSEL or SDLK_SCANCODE_MASK);
+
+ SDLK_KP_00 = TSDL_KeyCode(SDL_SCANCODE_KP_00 or SDLK_SCANCODE_MASK);
+ SDLK_KP_000 = TSDL_KeyCode(SDL_SCANCODE_KP_000 or SDLK_SCANCODE_MASK);
+ SDLK_THOUSANDSSEPARATOR = TSDL_KeyCode(SDL_SCANCODE_THOUSANDSSEPARATOR or SDLK_SCANCODE_MASK);
+ SDLK_DECIMALSEPARATOR = TSDL_KeyCode(SDL_SCANCODE_DECIMALSEPARATOR or SDLK_SCANCODE_MASK);
+ SDLK_CURRENCYUNIT = TSDL_KeyCode(SDL_SCANCODE_CURRENCYUNIT or SDLK_SCANCODE_MASK);
+ SDLK_CURRENCYSUBUNIT = TSDL_KeyCode(SDL_SCANCODE_CURRENCYSUBUNIT or SDLK_SCANCODE_MASK);
+ SDLK_KP_LEFTPAREN = TSDL_KeyCode(SDL_SCANCODE_KP_LEFTPAREN or SDLK_SCANCODE_MASK);
+ SDLK_KP_RIGHTPAREN = TSDL_KeyCode(SDL_SCANCODE_KP_RIGHTPAREN or SDLK_SCANCODE_MASK);
+ SDLK_KP_LEFTBRACE = TSDL_KeyCode(SDL_SCANCODE_KP_LEFTBRACE or SDLK_SCANCODE_MASK);
+ SDLK_KP_RIGHTBRACE = TSDL_KeyCode(SDL_SCANCODE_KP_RIGHTBRACE or SDLK_SCANCODE_MASK);
+ SDLK_KP_TAB = TSDL_KeyCode(SDL_SCANCODE_KP_TAB or SDLK_SCANCODE_MASK);
+ SDLK_KP_BACKSPACE = TSDL_KeyCode(SDL_SCANCODE_KP_BACKSPACE or SDLK_SCANCODE_MASK);
+ SDLK_KP_A = TSDL_KeyCode(SDL_SCANCODE_KP_A or SDLK_SCANCODE_MASK);
+ SDLK_KP_B = TSDL_KeyCode(SDL_SCANCODE_KP_B or SDLK_SCANCODE_MASK);
+ SDLK_KP_C = TSDL_KeyCode(SDL_SCANCODE_KP_C or SDLK_SCANCODE_MASK);
+ SDLK_KP_D = TSDL_KeyCode(SDL_SCANCODE_KP_D or SDLK_SCANCODE_MASK);
+ SDLK_KP_E = TSDL_KeyCode(SDL_SCANCODE_KP_E or SDLK_SCANCODE_MASK);
+ SDLK_KP_F = TSDL_KeyCode(SDL_SCANCODE_KP_F or SDLK_SCANCODE_MASK);
+ SDLK_KP_XOR = TSDL_KeyCode(SDL_SCANCODE_KP_XOR or SDLK_SCANCODE_MASK);
+ SDLK_KP_POWER = TSDL_KeyCode(SDL_SCANCODE_KP_POWER or SDLK_SCANCODE_MASK);
+ SDLK_KP_PERCENT = TSDL_KeyCode(SDL_SCANCODE_KP_PERCENT or SDLK_SCANCODE_MASK);
+ SDLK_KP_LESS = TSDL_KeyCode(SDL_SCANCODE_KP_LESS or SDLK_SCANCODE_MASK);
+ SDLK_KP_GREATER = TSDL_KeyCode(SDL_SCANCODE_KP_GREATER or SDLK_SCANCODE_MASK);
+ SDLK_KP_AMPERSAND = TSDL_KeyCode(SDL_SCANCODE_KP_AMPERSAND or SDLK_SCANCODE_MASK);
+ SDLK_KP_DBLAMPERSAND = TSDL_KeyCode(SDL_SCANCODE_KP_DBLAMPERSAND or SDLK_SCANCODE_MASK);
+ SDLK_KP_VERTICALBAR = TSDL_KeyCode(SDL_SCANCODE_KP_VERTICALBAR or SDLK_SCANCODE_MASK);
+ SDLK_KP_DBLVERTICALBAR = TSDL_KeyCode(SDL_SCANCODE_KP_DBLVERTICALBAR or SDLK_SCANCODE_MASK);
+ SDLK_KP_COLON = TSDL_KeyCode(SDL_SCANCODE_KP_COLON or SDLK_SCANCODE_MASK);
+ SDLK_KP_HASH = TSDL_KeyCode(SDL_SCANCODE_KP_HASH or SDLK_SCANCODE_MASK);
+ SDLK_KP_SPACE = TSDL_KeyCode(SDL_SCANCODE_KP_SPACE or SDLK_SCANCODE_MASK);
+ SDLK_KP_AT = TSDL_KeyCode(SDL_SCANCODE_KP_AT or SDLK_SCANCODE_MASK);
+ SDLK_KP_EXCLAM = TSDL_KeyCode(SDL_SCANCODE_KP_EXCLAM or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMSTORE = TSDL_KeyCode(SDL_SCANCODE_KP_MEMSTORE or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMRECALL = TSDL_KeyCode(SDL_SCANCODE_KP_MEMRECALL or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMCLEAR = TSDL_KeyCode(SDL_SCANCODE_KP_MEMCLEAR or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMADD = TSDL_KeyCode(SDL_SCANCODE_KP_MEMADD or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMSUBTRACT = TSDL_KeyCode(SDL_SCANCODE_KP_MEMSUBTRACT or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMMULTIPLY = TSDL_KeyCode(SDL_SCANCODE_KP_MEMMULTIPLY or SDLK_SCANCODE_MASK);
+ SDLK_KP_MEMDIVIDE = TSDL_KeyCode(SDL_SCANCODE_KP_MEMDIVIDE or SDLK_SCANCODE_MASK);
+ SDLK_KP_PLUSMINUS = TSDL_KeyCode(SDL_SCANCODE_KP_PLUSMINUS or SDLK_SCANCODE_MASK);
+ SDLK_KP_CLEAR = TSDL_KeyCode(SDL_SCANCODE_KP_CLEAR or SDLK_SCANCODE_MASK);
+ SDLK_KP_CLEARENTRY = TSDL_KeyCode(SDL_SCANCODE_KP_CLEARENTRY or SDLK_SCANCODE_MASK);
+ SDLK_KP_BINARY = TSDL_KeyCode(SDL_SCANCODE_KP_BINARY or SDLK_SCANCODE_MASK);
+ SDLK_KP_OCTAL = TSDL_KeyCode(SDL_SCANCODE_KP_OCTAL or SDLK_SCANCODE_MASK);
+ SDLK_KP_DECIMAL = TSDL_KeyCode(SDL_SCANCODE_KP_DECIMAL or SDLK_SCANCODE_MASK);
+ SDLK_KP_HEXADECIMAL = TSDL_KeyCode(SDL_SCANCODE_KP_HEXADECIMAL or SDLK_SCANCODE_MASK);
+
+ SDLK_LCTRL = TSDL_KeyCode(SDL_SCANCODE_LCTRL or SDLK_SCANCODE_MASK);
+ SDLK_LSHIFT = TSDL_KeyCode(SDL_SCANCODE_LSHIFT or SDLK_SCANCODE_MASK);
+ SDLK_LALT = TSDL_KeyCode(SDL_SCANCODE_LALT or SDLK_SCANCODE_MASK);
+ SDLK_LGUI = TSDL_KeyCode(SDL_SCANCODE_LGUI or SDLK_SCANCODE_MASK);
+ SDLK_RCTRL = TSDL_KeyCode(SDL_SCANCODE_RCTRL or SDLK_SCANCODE_MASK);
+ SDLK_RSHIFT = TSDL_KeyCode(SDL_SCANCODE_RSHIFT or SDLK_SCANCODE_MASK);
+ SDLK_RALT = TSDL_KeyCode(SDL_SCANCODE_RALT or SDLK_SCANCODE_MASK);
+ SDLK_RGUI = TSDL_KeyCode(SDL_SCANCODE_RGUI or SDLK_SCANCODE_MASK);
+
+ SDLK_MODE = TSDL_KeyCode(SDL_SCANCODE_MODE or SDLK_SCANCODE_MASK);
+
+ SDLK_AUDIONEXT = TSDL_KeyCode(SDL_SCANCODE_AUDIONEXT or SDLK_SCANCODE_MASK);
+ SDLK_AUDIOPREV = TSDL_KeyCode(SDL_SCANCODE_AUDIOPREV or SDLK_SCANCODE_MASK);
+ SDLK_AUDIOSTOP = TSDL_KeyCode(SDL_SCANCODE_AUDIOSTOP or SDLK_SCANCODE_MASK);
+ SDLK_AUDIOPLAY = TSDL_KeyCode(SDL_SCANCODE_AUDIOPLAY or SDLK_SCANCODE_MASK);
+ SDLK_AUDIOMUTE = TSDL_KeyCode(SDL_SCANCODE_AUDIOMUTE or SDLK_SCANCODE_MASK);
+ SDLK_MEDIASELECT = TSDL_KeyCode(SDL_SCANCODE_MEDIASELECT or SDLK_SCANCODE_MASK);
+ SDLK_WWW = TSDL_KeyCode(SDL_SCANCODE_WWW or SDLK_SCANCODE_MASK);
+ SDLK_MAIL = TSDL_KeyCode(SDL_SCANCODE_MAIL or SDLK_SCANCODE_MASK);
+ SDLK_CALCULATOR = TSDL_KeyCode(SDL_SCANCODE_CALCULATOR or SDLK_SCANCODE_MASK);
+ SDLK_COMPUTER = TSDL_KeyCode(SDL_SCANCODE_COMPUTER or SDLK_SCANCODE_MASK);
+ SDLK_AC_SEARCH = TSDL_KeyCode(SDL_SCANCODE_AC_SEARCH or SDLK_SCANCODE_MASK);
+ SDLK_AC_HOME = TSDL_KeyCode(SDL_SCANCODE_AC_HOME or SDLK_SCANCODE_MASK);
+ SDLK_AC_BACK = TSDL_KeyCode(SDL_SCANCODE_AC_BACK or SDLK_SCANCODE_MASK);
+ SDLK_AC_FORWARD = TSDL_KeyCode(SDL_SCANCODE_AC_FORWARD or SDLK_SCANCODE_MASK);
+ SDLK_AC_STOP = TSDL_KeyCode(SDL_SCANCODE_AC_STOP or SDLK_SCANCODE_MASK);
+ SDLK_AC_REFRESH = TSDL_KeyCode(SDL_SCANCODE_AC_REFRESH or SDLK_SCANCODE_MASK);
+ SDLK_AC_BOOKMARKS = TSDL_KeyCode(SDL_SCANCODE_AC_BOOKMARKS or SDLK_SCANCODE_MASK);
+
+ SDLK_BRIGHTNESSDOWN = TSDL_KeyCode(SDL_SCANCODE_BRIGHTNESSDOWN or SDLK_SCANCODE_MASK);
+ SDLK_BRIGHTNESSUP = TSDL_KeyCode(SDL_SCANCODE_BRIGHTNESSUP or SDLK_SCANCODE_MASK);
+ SDLK_DISPLAYSWITCH = TSDL_KeyCode(SDL_SCANCODE_DISPLAYSWITCH or SDLK_SCANCODE_MASK);
+ SDLK_KBDILLUMTOGGLE = TSDL_KeyCode(SDL_SCANCODE_KBDILLUMTOGGLE or SDLK_SCANCODE_MASK);
+ SDLK_KBDILLUMDOWN = TSDL_KeyCode(SDL_SCANCODE_KBDILLUMDOWN or SDLK_SCANCODE_MASK);
+ SDLK_KBDILLUMUP = TSDL_KeyCode(SDL_SCANCODE_KBDILLUMUP or SDLK_SCANCODE_MASK);
+ SDLK_EJECT = TSDL_KeyCode(SDL_SCANCODE_EJECT or SDLK_SCANCODE_MASK);
+ SDLK_SLEEP = TSDL_KeyCode(SDL_SCANCODE_SLEEP or SDLK_SCANCODE_MASK);
+ SDLK_APP1 = TSDL_KeyCode(SDL_SCANCODE_APP1 or SDLK_SCANCODE_MASK);
+ SDLK_APP2 = TSDL_KeyCode(SDL_SCANCODE_APP2 or SDLK_SCANCODE_MASK);
+
+ SDLK_AUDIOREWIND = TSDL_KeyCode(SDL_SCANCODE_AUDIOREWIND or SDLK_SCANCODE_MASK);
+ SDLK_AUDIOFASTFORWARD = TSDL_KeyCode(SDL_SCANCODE_AUDIOFASTFORWARD or SDLK_SCANCODE_MASK);
+
+ SDLK_SOFTLEFT = TSDL_KeyCode(SDL_SCANCODE_SOFTLEFT or SDLK_SCANCODE_MASK);
+ SDLK_SOFTRIGHT = TSDL_KeyCode(SDL_SCANCODE_SOFTRIGHT or SDLK_SCANCODE_MASK);
+ SDLK_CALL = TSDL_KeyCode(SDL_SCANCODE_CALL or SDLK_SCANCODE_MASK);
+ SDLK_ENDCALL = TSDL_KeyCode(SDL_SCANCODE_ENDCALL or SDLK_SCANCODE_MASK);
+
+ {**
+ * Enumeration of valid key mods (possibly OR'd together).
+ *}
+type
+ PPSDL_KeyMod = ^PSDL_KeyMod;
+ PSDL_KeyMod = ^TSDL_KeyMod;
+ TSDL_KeyMod = type cint;
+
+const
+ KMOD_NONE = TSDL_KeyMod($0000);
+ KMOD_LSHIFT = TSDL_KeyMod($0001);
+ KMOD_RSHIFT = TSDL_KeyMod($0002);
+ KMOD_LCTRL = TSDL_KeyMod($0040);
+ KMOD_RCTRL = TSDL_KeyMod($0080);
+ KMOD_LALT = TSDL_KeyMod($0100);
+ KMOD_RALT = TSDL_KeyMod($0200);
+ KMOD_LGUI = TSDL_KeyMod($0400);
+ KMOD_RGUI = TSDL_KeyMod($0800);
+ KMOD_NUM = TSDL_KeyMod($1000);
+ KMOD_CAPS = TSDL_KeyMod($2000);
+ KMOD_MODE = TSDL_KeyMod($4000);
+ KMOD_SCROLL = TSDL_KeyMod($8000);
+
+ KMOD_CTRL = KMOD_LCTRL or KMOD_RCTRL;
+ KMOD_SHIFT = KMOD_LSHIFT or KMOD_RSHIFT;
+ KMOD_ALT = KMOD_LALT or KMOD_RALT;
+ KMOD_GUI = KMOD_LGUI or KMOD_RGUI;
+
+ KMOD_RESERVED = KMOD_SCROLL; {* This is for source-level compatibility with SDL 2.0.0. *}
diff --git a/units/sdl2_for_pascal/sdlloadso.inc b/units/sdl2_for_pascal/sdlloadso.inc
new file mode 100644
index 0000000..c80fe46
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlloadso.inc
@@ -0,0 +1,98 @@
+//from sdl_loadso.h
+
+{*
+ * \file SDL_loadso.h
+ *
+ * System dependent library loading routines
+ *
+ * Some things to keep in mind:
+ * \li These functions only work on C function names. Other languages may
+ * have name mangling and intrinsic language support that varies from
+ * compiler to compiler.
+ * \li Make sure you declare your function pointers with the same calling
+ * convention as the actual library function. Your code will crash
+ * mysteriously if you do not do this.
+ * \li Avoid namespace collisions. If you load a symbol from the library,
+ * it is not defined whether or not it goes into the global symbol
+ * namespace for the application. If it does and it conflicts with
+ * symbols in your code or other shared libraries, you will not get
+ * the results you expect.:)
+ }
+
+{*
+ * Dynamically load a shared object.
+ *
+ * \param sofile a system-dependent name of the object file
+ * \returns an opaque pointer to the object handle or nil if there was an
+ * error; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadFunction
+ * \sa SDL_UnloadObject
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadObject_func = function(sofile: PAnsiChar): Pointer; cdecl;
+Var
+ SDL_LoadObject : TSDL_LoadObject_func = Nil;
+{$else}
+
+function SDL_LoadObject(sofile: PAnsiChar): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadObject' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Look up the address of the named function in a shared object.
+ *
+ * This function pointer is no longer valid after calling SDL_UnloadObject().
+ *
+ * This function can only look up C function names. Other languages may have
+ * name mangling and intrinsic language support that varies from compiler to
+ * compiler.
+ *
+ * Make sure you declare your function pointers with the same calling
+ * convention as the actual library function. Your code will crash
+ * mysteriously if you do not do this.
+ *
+ * If the requested function doesn't exist, nil is returned.
+ *
+ * \param handle a valid shared object handle returned by SDL_LoadObject()
+ * \param name the name of the function to look up
+ * \returns a pointer to the function or nil if there was an error; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadObject
+ * \sa SDL_UnloadObject
+ }
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_LoadFunctions_func = function (handle: Pointer; name: PAnsiChar): Pointer; cdecl;
+ Var
+ SDL_LoadFunction : TSDL_LoadFunctions_func = Nil;
+ {$else}
+function SDL_LoadFunction(handle: Pointer; name: PAnsiChar): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadFunction' {$ENDIF} {$ENDIF};
+ {$endif}
+{*
+ * Unload a shared object from memory.
+ *
+ * \param handle a valid shared object handle returned by SDL_LoadObject()
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_LoadFunction
+ * \sa SDL_LoadObject
+ }
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnloadObject_proc = procedure(handle: Pointer); cdecl;
+Var
+ SDL_UnloadObject : TSDL_UnloadObject_proc = Nil;
+{$else}
+
+procedure SDL_UnloadObject(handle: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnloadObject' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdllocale.inc b/units/sdl2_for_pascal/sdllocale.inc
new file mode 100644
index 0000000..68007c9
--- /dev/null
+++ b/units/sdl2_for_pascal/sdllocale.inc
@@ -0,0 +1,58 @@
+// based on SDL_locale.h
+
+type
+ PPSDL_Locale = ^PSDL_Locale;
+ PSDL_Locale = ^TSDL_Locale;
+ TSDL_Locale = record
+ // A language name, like 'en' for English.
+ language: PAnsiChar;
+ // A country, like 'US' for America. Can be NIL.
+ country: PAnsiChar;
+ end;
+
+{**
+ * \brief Report the user's preferred locale.
+ *
+ * This returns an array of SDL_Locale structs, the final item zeroed out.
+ * When the caller is done with this array, it should call SDL_free() on
+ * the returned value; all the memory involved is allocated in a single
+ * block, so a single SDL_free() will suffice.
+ *
+ * Returned language strings are in the format xx, where 'xx' is an ISO-639
+ * language specifier (such as 'en' for English, 'de' for German, etc).
+ * Country strings are in the format YY, where 'YY' is an ISO-3166 country
+ * code (such as "US" for the United States, 'CA' for Canada, etc). Country
+ * might be NULL if there's no specific guidance on them (so you might get
+ * ( 'en', 'US' ) for American English, but ( 'en', NIL ) means "English
+ * language, generically"). Language strings are never NIL, except to
+ * terminate the array.
+ *
+ * Please note that not all of these strings are 2 characters; some are
+ * three or more.
+ *
+ * The returned list of locales are in the order of the user's preference.
+ * For example, a German citizen that is fluent in US English and knows
+ * enough Japanese to navigate around Tokyo might have a list like:
+ * [ 'de', 'en_US', 'jp', NIL ]. Someone from England might prefer British
+ * English (where "color" is spelled "colour", etc), but will settle for
+ * anything like it: [ 'en_GB', 'en', NIL ].
+ *
+ * This function returns NIL on error, including when the platform does not
+ * supply this information at all.
+ *
+ * This might be a "slow" call that has to query the operating system. It's
+ * best to ask for this once and save the results. However, this list can
+ * change, usually because the user has changed a system preference outside
+ * of your program; SDL will send an SDL_LOCALECHANGED event in this case,
+ * if possible, and you can call this function again to get an updated copy
+ * of preferred locales.
+ *
+ * \return array of locales, terminated with a locale with a NIL language
+ * field. Will return NIL on error.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GetPreferredLocales(): PSDL_Locale; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPreferredLocales' {$ENDIF} {$ENDIF};
+ {$endif}
diff --git a/units/sdl2_for_pascal/sdllog.inc b/units/sdl2_for_pascal/sdllog.inc
new file mode 100644
index 0000000..aa60cca
--- /dev/null
+++ b/units/sdl2_for_pascal/sdllog.inc
@@ -0,0 +1,280 @@
+
+//since the array of const in delphi is not C compatible:
+{$IFDEF FPC}
+
+{**
+ * \brief The maximum size of a log message
+ *
+ * Messages longer than the maximum size will be truncated
+ *}
+const
+ SDL_MAX_LOG_MESSAGE = 4096;
+
+{**
+ * \brief The predefined log categories
+ *
+ * By default the application category is enabled at the INFO level,
+ * the assert category is enabled at the WARN level, test is enabled
+ * at the VERBOSE level and all other categories are enabled at the
+ * CRITICAL level.
+ *}
+type
+ PPSDL_LogCategory = ^PSDL_LogCategory;
+ PSDL_LogCategory = ^TSDL_LogCategory;
+ TSDL_LogCategory = type cint;
+
+const
+ SDL_LOG_CATEGORY_APPLICATION = TSDL_LogCategory(0);
+ SDL_LOG_CATEGORY_ERROR = TSDL_LogCategory(1);
+ SDL_LOG_CATEGORY_ASSERT = TSDL_LogCategory(2);
+ SDL_LOG_CATEGORY_SYSTEM = TSDL_LogCategory(3);
+ SDL_LOG_CATEGORY_AUDIO = TSDL_LogCategory(4);
+ SDL_LOG_CATEGORY_VIDEO = TSDL_LogCategory(5);
+ SDL_LOG_CATEGORY_RENDER = TSDL_LogCategory(6);
+ SDL_LOG_CATEGORY_INPUT = TSDL_LogCategory(7);
+ SDL_LOG_CATEGORY_TEST = TSDL_LogCategory(8);
+
+ {* Reserved for future SDL library use *}
+ SDL_LOG_CATEGORY_RESERVED1 = TSDL_LogCategory(9);
+ SDL_LOG_CATEGORY_RESERVED2 = TSDL_LogCategory(10);
+ SDL_LOG_CATEGORY_RESERVED3 = TSDL_LogCategory(11);
+ SDL_LOG_CATEGORY_RESERVED4 = TSDL_LogCategory(12);
+ SDL_LOG_CATEGORY_RESERVED5 = TSDL_LogCategory(13);
+ SDL_LOG_CATEGORY_RESERVED6 = TSDL_LogCategory(14);
+ SDL_LOG_CATEGORY_RESERVED7 = TSDL_LogCategory(15);
+ SDL_LOG_CATEGORY_RESERVED8 = TSDL_LogCategory(16);
+ SDL_LOG_CATEGORY_RESERVED9 = TSDL_LogCategory(17);
+ SDL_LOG_CATEGORY_RESERVED10 = TSDL_LogCategory(18);
+
+ {* Beyond this point is reserved for application use *}
+ SDL_LOG_CATEGORY_CUSTOM = TSDL_LogCategory(19);
+
+{**
+ * \brief The predefined log priorities
+ *}
+type
+ PPSDL_LogPriority = ^PSDL_LogPriority;
+ PSDL_LogPriority = ^TSDL_LogPriority;
+ TSDL_LogPriority = type cint32;
+const
+ SDL_LOG_PRIORITY_VERBOSE = TSDL_LogPriority(1);
+ SDL_LOG_PRIORITY_DEBUG = TSDL_LogPriority(2);
+ SDL_LOG_PRIORITY_INFO = TSDL_LogPriority(3);
+ SDL_LOG_PRIORITY_WARN = TSDL_LogPriority(4);
+ SDL_LOG_PRIORITY_ERROR = TSDL_LogPriority(5);
+ SDL_LOG_PRIORITY_CRITICAL = TSDL_LogPriority(6);
+ SDL_NUM_LOG_PRIORITIES = TSDL_LogPriority(7);
+
+{**
+ * \brief Set the priority of all log categories
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogSetAllPriority_proc = procedure(priority: TSDL_LogPriority); cdecl;
+Var
+ SDL_LogSetAllPriority : TSDL_LogSetAllPriority_proc = Nil;
+{$else}
+
+procedure SDL_LogSetAllPriority(priority: TSDL_LogPriority); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetAllPriority' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Set the priority of a particular log category
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogSetPriority_proc = procedure(category: TSDL_LogCategory; priority: TSDL_LogPriority); cdecl;
+Var
+ SDL_LogSetPriority : TSDL_LogSetPriority_proc = Nil;
+{$else}
+
+procedure SDL_LogSetPriority(category: TSDL_LogCategory; priority: TSDL_LogPriority); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetPriority' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the priority of a particular log category
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogGetPriority_func = function(category: TSDL_LogCategory): TSDL_LogPriority; cdecl;
+Var
+ SDL_LogGetPriority : TSDL_LogGetPriority_func = Nil;
+{$else}
+
+function SDL_LogGetPriority(category: TSDL_LogCategory): TSDL_LogPriority; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogGetPriority' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Reset all priorities to default.
+ *
+ * \note This is called in SDL_Quit().
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogResetPriorities_proc = procedure(); cdecl;
+Var
+ SDL_LogResetPriorities : TSDL_LogResetPriorities_proc = Nil;
+{$else}
+
+procedure SDL_LogResetPriorities(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogResetPriorities' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Log_proc = procedure(const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_Log : TSDL_Log_proc = Nil;
+{$else}
+
+procedure SDL_Log(const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Log' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_VERBOSE
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogVerbose_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogVerbose : TSDL_LogVerbose_proc = Nil;
+{$else}
+
+procedure SDL_LogVerbose(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogVerbose' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_DEBUG
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogDebug_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogDebug : TSDL_LogDebug_proc = Nil;
+{$else}
+
+procedure SDL_LogDebug(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogDebug' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_INFO
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogInfo_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogInfo : TSDL_LogInfo_proc = Nil;
+{$else}
+
+procedure SDL_LogInfo(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogInfo' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_WARN
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogWarn_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogWarn : TSDL_LogWarn_proc = Nil;
+{$else}
+
+procedure SDL_LogWarn(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogWarn' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_ERROR
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogError_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogError : TSDL_LogError_proc = Nil;
+{$else}
+
+procedure SDL_LogError(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogError' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with SDL_LOG_PRIORITY_CRITICAL
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogCritical_proc = procedure(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogCritical : TSDL_LogCritical_proc = Nil;
+{$else}
+
+procedure SDL_LogCritical(category: TSDL_LogCategory; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogCritical' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with the specified category and priority.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogMessage_proc = procedure(category: TSDL_LogCategory; priority: TSDL_LogPriority; const fmt: PAnsiChar; pars: array of const); cdecl;
+Var
+ SDL_LogMessage : TSDL_LogMessage_proc = Nil;
+{$else}
+
+procedure SDL_LogMessage(category: TSDL_LogCategory; priority: TSDL_LogPriority; const fmt: PAnsiChar; pars: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogMessage' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Log a message with the specified category and priority.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LogMessageV_proc = procedure(category: TSDL_LogCategory; priority: TSDL_LogPriority; const fmt: PAnsiChar; ap: array of const); cdecl;
+Var
+ SDL_LogMessageV : TSDL_LogMessageV_proc = Nil;
+{$else}
+
+procedure SDL_LogMessageV(category: TSDL_LogCategory; priority: TSDL_LogPriority; const fmt: PAnsiChar; ap: array of const); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogMessageV' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief The prototype for the log output function
+ *}
+type
+ PPSDL_LogOutputFunction = ^PSDL_LogOutputFunction;
+ PSDL_LogOutputFunction = ^TSDL_LogOutputFunction;
+ TSDL_LogOutputFunction = procedure(
+ userdata: Pointer;
+ category: TSDL_LogCategory;
+ priority: TSDL_LogPriority;
+ const msg: PAnsiChar); cdecl;
+
+{**
+ * \brief Get the current log output function.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ // TODO: Portieren
+ {$else}
+procedure SDL_LogGetOutputFunction(callback: PSDL_LogOutputFunction; userdata: PPointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogGetOutputFunction' {$ENDIF} {$ENDIF};
+
+{**
+ * \brief This function allows you to replace the default log output
+ * function with one of your own.
+ *}
+procedure SDL_LogSetOutputFunction(callback: TSDL_LogOutputFunction; userdata: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetOutputFunction' {$ENDIF} {$ENDIF};
+ {$ENDIF}
+{$ENDIF}
diff --git a/units/sdl2_for_pascal/sdlmessagebox.inc b/units/sdl2_for_pascal/sdlmessagebox.inc
new file mode 100644
index 0000000..e380f3d
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlmessagebox.inc
@@ -0,0 +1,140 @@
+//from "sdl_messagebox.h"
+
+{**
+ * SDL_MessageBox flags. If supported will display warning icon, etc.
+ *}
+type
+ PPSDL_MessageBoxFlags = ^PSDL_MessageBoxFlags;
+ PSDL_MessageBoxFlags = ^TSDL_MessageBoxFlags;
+ TSDL_MessageBoxFlags = type cuint32;
+
+const
+ SDL_MESSAGEBOX_ERROR = TSDL_MessageBoxFlags($00000010); {**< error dialog *}
+ SDL_MESSAGEBOX_WARNING = TSDL_MessageBoxFlags($00000020); {**< warning dialog *}
+ SDL_MESSAGEBOX_INFORMATION = TSDL_MessageBoxFlags($00000040); {**< informational dialog *}
+ SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = TSDL_MessageBoxFlags($00000080); {/**< buttons placed left to right */}
+ SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = TSDL_MessageBoxFlags($00000100); {/**< buttons placed right to left */}
+
+{**
+ * Flags for SDL_MessageBoxButtonData.
+ *}
+type
+ PPSDL_MessageBoxButtonFlags = ^PSDL_MessageBoxButtonFlags;
+ PSDL_MessageBoxButtonFlags = ^TSDL_MessageBoxButtonFlags;
+ TSDL_MessageBoxButtonFlags = type cuint32;
+
+const
+ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = TSDL_MessageBoxButtonFlags($00000001); {**< Marks the default button when return is hit *}
+ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = TSDL_MessageBoxButtonFlags($00000002); {**< Marks the default button when escape is hit *}
+
+
+{**
+ * Individual button data.
+ *}
+type
+ PPSDL_MessageBoxButtonData = ^PSDL_MessageBoxButtonData;
+ PSDL_MessageBoxButtonData = ^TSDL_MessageBoxButtonData;
+ TSDL_MessageBoxButtonData = record
+ flags: TSDL_MessageBoxButtonFlags; {**< ::SDL_MessageBoxButtonFlags *}
+ buttonid: cint; {**< User defined button id (value returned via SDL_ShowMessageBox) *}
+ text: PAnsiChar; {**< The UTF-8 button text *}
+ end;
+
+{**
+ * RGB value used in a message box color scheme
+ *}
+type
+ PPSDL_MessageBoxColor = ^PSDL_MessageBoxColor;
+ PSDL_MessageBoxColor = ^TSDL_MessageBoxColor;
+ TSDL_MessageBoxColor = record
+ r, g, b: cuint8;
+ end;
+
+ PPSDL_MessageBoxColorType = ^PSDL_MessageBoxColorType;
+ PSDL_MessageBoxColorType = ^TSDL_MessageBoxColorType;
+ TSDL_MessageBoxColorType = type Word;
+
+const
+ SDL_MESSAGEBOX_COLOR_BACKGROUND = TSDL_MessageBoxColorType(0);
+ SDL_MESSAGEBOX_COLOR_TEXT = TSDL_MessageBoxColorType(1);
+ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER = TSDL_MessageBoxColorType(2);
+ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND = TSDL_MessageBoxColorType(3);
+ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED = TSDL_MessageBoxColorType(4);
+ SDL_MESSAGEBOX_COLOR_MAX = TSDL_MessageBoxColorType(5);
+
+ {**
+ * A set of colors to use for message box dialogs
+ *}
+type
+ PPSDL_MessageBoxColorScheme = ^PSDL_MessageBoxColorScheme;
+ PSDL_MessageBoxColorScheme = ^TSDL_MessageBoxColorScheme;
+ TSDL_MessageBoxColorScheme = record
+ colors: array[0..SDL_MESSAGEBOX_COLOR_MAX-1] of TSDL_MessageBoxColor;
+ end;
+
+ {**
+ * MessageBox structure containing title, text, window, etc.
+ *}
+type
+ PPSDL_MessageBoxData = ^PSDL_MessageBoxData;
+ PSDL_MessageBoxData = ^TSDL_MessageBoxData;
+ TSDL_MessageBoxData = record
+ flags: TSDL_MessageBoxFlags; {**< SDL_MessageBoxFlags *}
+ window: PSDL_Window; {**< Parent window, can be NULL *}
+ title: PAnsiChar; {**< UTF-8 title *}
+ _message: PAnsiChar; {**< UTF-8 message text *}
+
+ numbuttons: cint;
+ buttons: PSDL_MessageBoxButtonData;
+
+ colorScheme: PSDL_MessageBoxColorScheme; {**< SDL_MessageBoxColorScheme, can be NULL to use system settings *}
+ end;
+
+{**
+ * Create a modal message box.
+ *
+ * messageboxdata The SDL_MessageBoxData structure with title, text, etc.
+ * buttonid The pointer to which user id of hit button should be copied.
+ *
+ * -1 on error, otherwise 0 and buttonid contains user id of button
+ * hit or -1 if dialog was closed.
+ *
+ * This function should be called on the thread that created the parent
+ * window, or on the main thread if the messagebox has no parent. It will
+ * block execution of that thread until the user clicks a button or
+ * closes the messagebox.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ShowMessageBox_func = function(messageboxdata: PSDL_MessageBoxData; buttonid: pcint): cint; cdecl;
+Var
+ SDL_ShowMessageBox : TSDL_ShowMessageBox_func = Nil;
+{$else}
+
+function SDL_ShowMessageBox(messageboxdata: PSDL_MessageBoxData; buttonid: pcint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowMessageBox' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Create a simple modal message box
+ *
+ * flags SDL_MessageBoxFlags
+ * title UTF-8 title text
+ * message UTF-8 message text
+ * window The parent window, or NULL for no parent
+ *
+ * 0 on success, -1 on error
+ *
+ * SDL_ShowMessageBox
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ShowSimpleMessageBox_func = function(flags: TSDL_MessageBoxFlags; title: PAnsiChar; _message: PAnsiChar; window: PSDL_Window): cint; cdecl;
+Var
+ SDL_ShowSimpleMessageBox : TSDL_ShowSimpleMessageBox_func = Nil;
+{$else}
+
+function SDL_ShowSimpleMessageBox(flags: TSDL_MessageBoxFlags; title: PAnsiChar; _message: PAnsiChar; window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowSimpleMessageBox' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlmisc.inc b/units/sdl2_for_pascal/sdlmisc.inc
new file mode 100644
index 0000000..1726027
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlmisc.inc
@@ -0,0 +1,33 @@
+// based on SDL_misc.h
+
+{**
+ * \brief Open an URL / URI in the browser or other
+ *
+ * Open a URL in a separate, system-provided application. How this works will
+ * vary wildly depending on the platform. This will likely launch what
+ * makes sense to handle a specific URL's protocol (a web browser for http://,
+ * etc), but it might also be able to launch file managers for directories
+ * and other things.
+ *
+ * What happens when you open a URL varies wildly as well: your game window
+ * may lose focus (and may or may not lose focus if your game was fullscreen
+ * or grabbing input at the time). On mobile devices, your app will likely
+ * move to the background or your process might be paused. Any given platform
+ * may or may not handle a given URL.
+ *
+ * If this is unimplemented (or simply unavailable) for a platform, this will
+ * fail with an error. A successful result does not mean the URL loaded, just
+ * that we launched something to handle it (or at least believe we did).
+ *
+ * All this to say: this function can be useful, but you should definitely
+ * test it on every platform you target.
+ *
+ * \param url A valid URL to open.
+ * \return 0 on success, or -1 on error.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_OpenURL(const url: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenURL' {$ENDIF} {$ENDIF};
+ {$endif}
diff --git a/units/sdl2_for_pascal/sdlmouse.inc b/units/sdl2_for_pascal/sdlmouse.inc
new file mode 100644
index 0000000..e646cca
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlmouse.inc
@@ -0,0 +1,561 @@
+//from "sdl_mouse.h"
+
+type
+ PPSDL_Cursor = ^PSDL_Cursor;
+ PSDL_Cursor = type Pointer; {**< Implementation dependent *}
+
+{**
+* Cursor types for SDL_CreateSystemCursor.
+*}
+type
+ PPSDL_SystemCursor = ^PSDL_SystemCursor;
+ PSDL_SystemCursor = ^TSDL_SystemCursor;
+ TSDL_SystemCursor = type Integer;
+
+const
+ SDL_SYSTEM_CURSOR_ARROW = TSDL_SystemCursor(0); // Arrow
+ SDL_SYSTEM_CURSOR_IBEAM = TSDL_SystemCursor(1); // I-beam
+ SDL_SYSTEM_CURSOR_WAIT = TSDL_SystemCursor(2); // Wait
+ SDL_SYSTEM_CURSOR_CROSSHAIR = TSDL_SystemCursor(3); // Crosshair
+ SDL_SYSTEM_CURSOR_WAITARROW = TSDL_SystemCursor(4); // Small wait cursor (or Wait if not available)
+ SDL_SYSTEM_CURSOR_SIZENWSE = TSDL_SystemCursor(5); // Double arrow pointing northwest and southeast
+ SDL_SYSTEM_CURSOR_SIZENESW = TSDL_SystemCursor(6); // Double arrow pointing northeast and southwest
+ SDL_SYSTEM_CURSOR_SIZEWE = TSDL_SystemCursor(7); // Double arrow pointing west and east
+ SDL_SYSTEM_CURSOR_SIZENS = TSDL_SystemCursor(8); // Double arrow pointing north and south
+ SDL_SYSTEM_CURSOR_SIZEALL = TSDL_SystemCursor(9); // Four pointed arrow pointing north, south, east, and west
+ SDL_SYSTEM_CURSOR_NO = TSDL_SystemCursor(10); // Slashed circle or crossbones
+ SDL_SYSTEM_CURSOR_HAND = TSDL_SystemCursor(11); // Hand
+ SDL_NUM_SYSTEM_CURSORS = TSDL_SystemCursor(12);
+
+type
+ PPSDL_MouseWheelDirection = ^PSDL_MouseWheelDirection;
+ PSDL_MouseWheelDirection = ^TSDL_MouseWheelDirection;
+ TSDL_MouseWheelDirection = type Integer;
+
+const
+ SDL_MOUSEWHEEL_NORMAL = TSDL_MouseWheelDirection(0); {**< The scroll direction is normal *}
+ SDL_MOUSEWHEEL_FLIPPED = TSDL_MouseWheelDirection(1); {**< The scroll direction is flipped / natural *}
+
+ {* Function prototypes *}
+
+ {**
+ * Get the window which currently has mouse focus.
+ *
+ * \returns the window with mouse focus.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GetMouseFocus: PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMouseFocus' {$ENDIF}{$ENDIF};
+ {$endif}
+ {**
+ * Retrieve the current state of the mouse.
+ *
+ * The current button state is returned as a button bitmask, which can be
+ * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the
+ * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the
+ * mouse cursor position relative to the focus window. You can pass NULL for
+ * either `x` or `y`.
+ *
+ * \param x the x coordinate of the mouse cursor position relative to the
+ * focus window
+ * \param y the y coordinate of the mouse cursor position relative to the
+ * focus window
+ * \returns a 32-bit button bitmask of the current button state.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetGlobalMouseState
+ * \sa SDL_GetRelativeMouseState
+ * \sa SDL_PumpEvents
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetMouseState_func = function(x: pcint; y: pcint): cuint32; cdecl;
+Var
+ SDL_GetMouseState : TSDL_GetMouseState_func = Nil;
+{$else}
+
+function SDL_GetMouseState(x: pcint; y: pcint): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMouseState' {$ENDIF}{$ENDIF};
+{$endif}
+
+
+ {**
+ * Get the current state of the mouse in relation to the desktop.
+ *
+ * This works similarly to SDL_GetMouseState(), but the coordinates will be
+ * reported relative to the top-left of the desktop. This can be useful if you
+ * need to track the mouse outside of a specific window and SDL_CaptureMouse()
+ * doesn't fit your needs. For example, it could be useful if you need to
+ * track the mouse while dragging a window, where coordinates relative to a
+ * window might not be in sync at all times.
+ *
+ * Note: SDL_GetMouseState() returns the mouse position as SDL understands it
+ * from the last pump of the event queue. This function, however, queries the
+ * OS for the current mouse position, and as such, might be a slightly less
+ * efficient function. Unless you know what you're doing and have a good
+ * reason to use this function, you probably want SDL_GetMouseState() instead.
+ *
+ * \param x filled in with the current X coord relative to the desktop; can be
+ * NULL
+ * \param y filled in with the current Y coord relative to the desktop; can be
+ * NULL
+ * \returns the current button state as a bitmask which can be tested using
+ * the SDL_BUTTON(X) macros.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_CaptureMouse
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetGlobalMouseState_func = function(x, y: pcint32): cuint32; cdecl;
+Var
+ SDL_GetGlobalMouseState : TSDL_GetGlobalMouseState_func = Nil;
+{$else}
+
+function SDL_GetGlobalMouseState(x, y: pcint32): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetGlobalMouseState' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Retrieve the relative state of the mouse.
+ *
+ * The current button state is returned as a button bitmask, which can be
+ * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the
+ * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the
+ * mouse deltas since the last call to SDL_GetRelativeMouseState() or since
+ * event initialization. You can pass NULL for either `x` or `y`.
+ *
+ * \param x a pointer filled with the last recorded x coordinate of the mouse
+ * \param y a pointer filled with the last recorded y coordinate of the mouse
+ * \returns a 32-bit button bitmask of the relative button state.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetMouseState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRelativeMouseState_func = function(x: pcint; y: pcint): cuint32; cdecl;
+Var
+ SDL_GetRelativeMouseState : TSDL_GetRelativeMouseState_func = Nil;
+{$else}
+
+function SDL_GetRelativeMouseState(x: pcint; y: pcint): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRelativeMouseState' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Move the mouse cursor to the given position within the window.
+ *
+ * This function generates a mouse motion event if relative mode is not
+ * enabled. If relative mode is enabled, you can force mouse events for the
+ * warp by setting the SDL_HINT_MOUSE_RELATIVE_WARP_MOTION hint.
+ *
+ * Note that this function will appear to succeed, but not actually move the
+ * mouse when used over Microsoft Remote Desktop.
+ *
+ * \param window the window to move the mouse into, or NULL for the current
+ * mouse focus
+ * \param x the x coordinate within the window
+ * \param y the y coordinate within the window
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_WarpMouseGlobal
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WarpMouseInWindow_proc = procedure(window: PSDL_Window; x: cint; y: cint); cdecl;
+Var
+ SDL_WarpMouseInWindow : TSDL_WarpMouseInWindow_proc = Nil;
+{$else}
+
+procedure SDL_WarpMouseInWindow(window: PSDL_Window; x: cint; y: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WarpMouseInWindow' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Move the mouse to the given position in global screen space.
+ *
+ * This function generates a mouse motion event.
+ *
+ * A failure of this function usually means that it is unsupported by a
+ * platform.
+ *
+ * Note that this function will appear to succeed, but not actually move the
+ * mouse when used over Microsoft Remote Desktop.
+ *
+ * \param x the x coordinate
+ * \param y the y coordinate
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_WarpMouseInWindow
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WarpMouseGlobal_func = function(x, y: cint): cint; cdecl;
+Var
+ SDL_WarpMouseGlobal : TSDL_WarpMouseGlobal_func = Nil;
+{$else}
+
+function SDL_WarpMouseGlobal(x, y: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WarpMouseGlobal' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Set relative mouse mode.
+ *
+ * While the mouse is in relative mode, the cursor is hidden, and the driver
+ * will try to report continuous motion in the current window. Only relative
+ * motion events will be delivered, the mouse position will not change.
+ *
+ * Note that this function will not be able to provide continuous relative
+ * motion when used over Microsoft Remote Desktop, instead motion is limited
+ * to the bounds of the screen.
+ *
+ * This function will flush any pending mouse motion.
+ *
+ * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * If relative mode is not supported, this returns -1.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetRelativeMouseMode
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetRelativeMouseMode_func = function(enabled: TSDL_Bool): cint; cdecl;
+Var
+ SDL_SetRelativeMouseMode : TSDL_SetRelativeMouseMode_func = Nil;
+{$else}
+
+function SDL_SetRelativeMouseMode(enabled: TSDL_Bool): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetRelativeMouseMode' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Capture the mouse and to track input outside an SDL window.
+ *
+ * Capturing enables your app to obtain mouse events globally, instead of just
+ * within your window. Not all video targets support this function. When
+ * capturing is enabled, the current window will get all mouse events, but
+ * unlike relative mode, no change is made to the cursor and it is not
+ * restrained to your window.
+ *
+ * This function may also deny mouse input to other windows--both those in
+ * your application and others on the system--so you should use this function
+ * sparingly, and in small bursts. For example, you might want to track the
+ * mouse while the user is dragging something, until the user releases a mouse
+ * button. It is not recommended that you capture the mouse for long periods
+ * of time, such as the entire time your app is running. For that, you should
+ * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowGrab(), depending
+ * on your goals.
+ *
+ * While captured, mouse events still report coordinates relative to the
+ * current (foreground) window, but those coordinates may be outside the
+ * bounds of the window (including negative values). Capturing is only allowed
+ * for the foreground window. If the window loses focus while capturing, the
+ * capture will be disabled automatically.
+ *
+ * While capturing is enabled, the current window will have the
+ * `SDL_WINDOW_MOUSE_CAPTURE` flag set.
+ *
+ * Please note that as of SDL 2.0.22, SDL will attempt to "auto capture" the
+ * mouse while the user is pressing a button; this is to try and make mouse
+ * behavior more consistent between platforms, and deal with the common case
+ * of a user dragging the mouse outside of the window. This means that if you
+ * are calling SDL_CaptureMouse() only to deal with this situation, you no
+ * longer have to (although it is safe to do so). If this causes problems for
+ * your app, you can disable auto capture by setting the
+ * `SDL_HINT_MOUSE_AUTO_CAPTURE` hint to zero.
+ *
+ * \param enabled SDL_TRUE to enable capturing, SDL_FALSE to disable.
+ * \returns 0 on success or -1 if not supported; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *
+ * \sa SDL_GetGlobalMouseState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CaptureMouse_func = function(enabled: TSDL_Bool): cint; cdecl;
+Var
+ SDL_CaptureMouse : TSDL_CaptureMouse_func = Nil;
+{$else}
+
+ function SDL_CaptureMouse(enabled: TSDL_Bool): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CaptureMouse' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Query whether relative mouse mode is enabled.
+ *
+ * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_SetRelativeMouseMode
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GetRelativeMouseMode: TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRelativeMouseMode' {$ENDIF}{$ENDIF};
+ {$endif}
+ {**
+ * Create a cursor using the specified bitmap data and mask (in MSB format).
+ *
+ * `mask` has to be in MSB (Most Significant Bit) format.
+ *
+ * The cursor width (`w`) must be a multiple of 8 bits.
+ *
+ * The cursor is created in black and white according to the following:
+ *
+ * - data=0, mask=1: white
+ * - data=1, mask=1: black
+ * - data=0, mask=0: transparent
+ * - data=1, mask=0: inverted color if possible, black if not.
+ *
+ * Cursors created with this function must be freed with SDL_FreeCursor().
+ *
+ * If you want to have a color cursor, or create your cursor from an
+ * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can
+ * hide the cursor and draw your own as part of your game's rendering, but it
+ * will be bound to the framerate.
+ *
+ * Also, since SDL 2.0.0, SDL_CreateSystemCursor() is available, which
+ * provides twelve readily available system cursors to pick from.
+ *
+ * \param data the color value for each pixel of the cursor
+ * \param mask the mask value for each pixel of the cursor
+ * \param w the width of the cursor
+ * \param h the height of the cursor
+ * \param hot_x the X-axis location of the upper left corner of the cursor
+ * relative to the actual mouse position
+ * \param hot_y the Y-axis location of the upper left corner of the cursor
+ * relative to the actual mouse position
+ * \returns a new cursor with the specified parameters on success or NULL on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_FreeCursor
+ * \sa SDL_SetCursor
+ * \sa SDL_ShowCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateCursor_func = function(
+ const data: pcuint8;
+ const mask: pcuint8;
+ w: cint; h: cint;
+ hot_x: cint; hot_y: cint): PSDL_Cursor; cdecl;
+Var
+ SDL_CreateCursor : TSDL_CreateCursor_func = Nil;
+{$else}
+
+function SDL_CreateCursor(
+ const data: pcuint8;
+ const mask: pcuint8;
+ w: cint; h: cint;
+ hot_x: cint; hot_y: cint): PSDL_Cursor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Create a color cursor.
+ *
+ * \param surface an SDL_Surface structure representing the cursor image
+ * \param hot_x the x position of the cursor hot spot
+ * \param hot_y the y position of the cursor hot spot
+ * \returns the new cursor on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateCursor
+ * \sa SDL_FreeCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateColorCursor_func = function(
+ surface: PSDL_Surface;
+ hot_x: cint;
+ hot_y: cint): PSDL_Cursor; cdecl;
+Var
+ SDL_CreateColorCursor : TSDL_CreateColorCursor_func = Nil;
+{$else}
+
+function SDL_CreateColorCursor(
+ surface: PSDL_Surface;
+ hot_x: cint;
+ hot_y: cint): PSDL_Cursor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateColorCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Create a system cursor.
+ *
+ * \param id an SDL_SystemCursor enum value
+ * \returns a cursor on success or NULL on failure; call SDL_GetError() for
+ * more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_FreeCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateSystemCursor_func = function(id: TSDL_SystemCursor): PSDL_Cursor; cdecl;
+Var
+ SDL_CreateSystemCursor : TSDL_CreateSystemCursor_func = Nil;
+{$else}
+
+function SDL_CreateSystemCursor(id: TSDL_SystemCursor): PSDL_Cursor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateSystemCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Set the active cursor.
+ *
+ * This function sets the currently active cursor to the specified one. If the
+ * cursor is currently visible, the change will be immediately represented on
+ * the display. SDL_SetCursor(NULL) can be used to force cursor redraw, if
+ * this is desired for any reason.
+ *
+ * \param cursor a cursor to make active
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateCursor
+ * \sa SDL_GetCursor
+ * \sa SDL_ShowCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetCursor_proc = procedure(cursor: PSDL_Cursor); cdecl;
+Var
+ SDL_SetCursor : TSDL_SetCursor_proc = Nil;
+{$else}
+
+procedure SDL_SetCursor(cursor: PSDL_Cursor); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Get the active cursor.
+ *
+ * This function returns a pointer to the current cursor which is owned by the
+ * library. It is not necessary to free the cursor with SDL_FreeCursor().
+ *
+ * \returns the active cursor or NULL if there is no mouse.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_SetCursor
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GetCursor: PSDL_Cursor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCursor' {$ENDIF}{$ENDIF};
+
+ {**
+ * Get the default cursor.
+ *
+ * \returns the default cursor on success or NULL on failure.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateSystemCursor
+ *}
+function SDL_GetDefaultCursor: PSDL_Cursor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDefaultCursor' {$ENDIF}{$ENDIF};
+ {$endif}
+ {**
+ * Free a previously-created cursor.
+ *
+ * Use this function to free cursor resources created with SDL_CreateCursor(),
+ * SDL_CreateColorCursor() or SDL_CreateSystemCursor().
+ *
+ * \param cursor the cursor to free
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateColorCursor
+ * \sa SDL_CreateCursor
+ * \sa SDL_CreateSystemCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeCursor_proc = procedure(cursor: PSDL_Cursor); cdecl;
+Var
+ SDL_FreeCursor : TSDL_FreeCursor_proc = Nil;
+{$else}
+
+procedure SDL_FreeCursor(cursor: PSDL_Cursor); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Toggle whether or not the cursor is shown.
+ *
+ * The cursor starts off displayed but can be turned off. Passing `SDL_ENABLE`
+ * displays the cursor and passing `SDL_DISABLE` hides it.
+ *
+ * The current state of the mouse cursor can be queried by passing
+ * `SDL_QUERY`; either `SDL_DISABLE` or `SDL_ENABLE` will be returned.
+ *
+ * \param toggle `SDL_ENABLE` to show the cursor, `SDL_DISABLE` to hide it,
+ * `SDL_QUERY` to query the current state without changing it.
+ * \returns `SDL_ENABLE` if the cursor is shown, or `SDL_DISABLE` if the
+ * cursor is hidden, or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateCursor
+ * \sa SDL_SetCursor
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ShowCursor_func = function(toggle: cint): cint; cdecl;
+Var
+ SDL_ShowCursor : TSDL_ShowCursor_func = Nil;
+{$else}
+
+function SDL_ShowCursor(toggle: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowCursor' {$ENDIF}{$ENDIF};
+{$endif}
+
+{**
+ * Used as a mask when testing buttons in buttonstate.
+ * - Button 1: Left mouse button
+ * - Button 2: Middle mouse button
+ * - Button 3: Right mouse button
+ *}
+function SDL_Button(X: cint): cint; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF}
+const
+ SDL_BUTTON_LEFT = 1;
+ SDL_BUTTON_MIDDLE = 2;
+ SDL_BUTTON_RIGHT = 3;
+ SDL_BUTTON_X1 = 4;
+ SDL_BUTTON_X2 = 5;
+ { Pascal Conv.: For better performance instead of using the
+ SDL_Button(X) macro, the following defines are
+ implemented directly. }
+ SDL_BUTTON_LMASK = 1 shl ((SDL_BUTTON_LEFT) - 1);
+ SDL_BUTTON_MMASK = 1 shl ((SDL_BUTTON_MIDDLE) - 1);
+ SDL_BUTTON_RMASK = 1 shl ((SDL_BUTTON_RIGHT) - 1);
+ SDL_BUTTON_X1MASK = 1 shl ((SDL_BUTTON_X1) - 1);
+ SDL_BUTTON_X2MASK = 1 shl ((SDL_BUTTON_X2) - 1);
diff --git a/units/sdl2_for_pascal/sdlmutex.inc b/units/sdl2_for_pascal/sdlmutex.inc
new file mode 100644
index 0000000..a689418
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlmutex.inc
@@ -0,0 +1,501 @@
+// based on "sdl_mutex.h"
+
+const
+ {**
+ * Synchronization functions which can time out return this value
+ * if they time out.
+ *}
+ SDL_MUTEX_TIMEDOUT = 1;
+
+ {**
+ * This is the timeout value which corresponds to never time out.
+ *}
+ SDL_MUTEX_MAXWAIT = Not cuint32(0);
+
+ { -- Mutex functions -- }
+type
+ { The SDL mutex structure, defined in SDL_sysmutex.c }
+ PPSDL_Mutex = ^PSDL_Mutex;
+ PSDL_Mutex = Type Pointer;
+
+{**
+ * Create a new mutex.
+ *
+ * All newly-created mutexes begin in the _unlocked_ state.
+ *
+ * Calls to SDL_LockMutex() will not return while the mutex is locked by
+ * another thread. See SDL_TryLockMutex() to attempt to lock without blocking.
+ *
+ * SDL mutexes are reentrant.
+ *
+ * \returns the initialized and unlocked mutex or NIL on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_CreateMutex_func = function (): PSDL_Mutex; cdecl;
+ Var
+ SDL_CreateMutex : TSDL_CreateMutex_func = Nil;
+ {$else}
+ function SDL_CreateMutex: PSDL_Mutex; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateMutex' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Lock the mutex.
+ *
+ * This will block until the mutex is available, which is to say it is in the
+ * unlocked state and the OS has chosen the caller as the next thread to lock
+ * it. Of all threads waiting to lock the mutex, only one may do so at a time.
+ *
+ * It is legal for the owning thread to lock an already-locked mutex. It must
+ * unlock it the same number of times before it is actually made available for
+ * other threads in the system (this is known as a "recursive mutex").
+ *
+ * \param mutex the mutex to lock
+ * \return 0, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockMutex_func = function(mutex: PSDL_Mutex): cint; cdecl;
+Var
+ SDL_LockMutex : TSDL_LockMutex_func = Nil;
+{$else}
+
+function SDL_LockMutex(mutex: PSDL_Mutex): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockMutex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{ SDL2-for-Pascal: SDL_mutexP macro ignored; no benefit for the Pascal units }
+//C: #define SDL_mutexP(m) SDL_UnlockMutex(m)
+
+{**
+ * Try to lock a mutex without blocking.
+ *
+ * This works just like SDL_LockMutex(), but if the mutex is not available,
+ * this function returns SDL_MUTEX_TIMEDOUT immediately.
+ *
+ * This technique is useful if you need exclusive access to a resource but
+ * don't want to wait for it, and will return to it to try again later.
+ *
+ * \param mutex the mutex to try to lock
+ * \returns 0, SDL_MUTEX_TIMEDOUT, or -1 on error; call SDL_GetError() for
+ * more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_TryLockMutex_func = function(mutex: PSDL_Mutex): cint; cdecl;
+Var
+ SDL_TryLockMutex : TSDL_TryLockMutex_func = Nil;
+{$else}
+
+function SDL_TryLockMutex(mutex: PSDL_Mutex): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TryLockMutex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Unlock the mutex.
+ *
+ * It is legal for the owning thread to lock an already-locked mutex. It must
+ * unlock it the same number of times before it is actually made available for
+ * other threads in the system (this is known as a "recursive mutex").
+ *
+ * It is an error to unlock a mutex that has not been locked by the current
+ * thread, and doing so results in undefined behavior.
+ *
+ * It is also an error to unlock a mutex that isn't locked at all.
+ *
+ * \param mutex the mutex to unlock.
+ * \returns 0, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnlockMutex_func = function(mutex: PSDL_Mutex): cint; cdecl;
+Var
+ SDL_UnlockMutex : TSDL_UnlockMutex_func = Nil;
+{$else}
+
+function SDL_UnlockMutex(mutex: PSDL_Mutex): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockMutex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{ SDL2-for-Pascal: SDL_mutexV macro ignored; no benefit for the Pascal units }
+//C: #define SDL_mutexV(m) SDL_UnlockMutex(m)
+
+{**
+ * Destroy a mutex created with SDL_CreateMutex().
+ *
+ * This function must be called on any mutex that is no longer needed. Failure
+ * to destroy a mutex will result in a system memory or resource leak. While
+ * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt
+ * to destroy a locked mutex, and may result in undefined behavior depending
+ * on the platform.
+ *
+ * \param mutex the mutex to destroy
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DestroyMutex_proc = procedure(mutex: PSDL_Mutex); cdecl;
+Var
+ SDL_DestroyMutex : TSDL_DestroyMutex_proc = Nil;
+{$else}
+
+procedure SDL_DestroyMutex(mutex: PSDL_Mutex); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyMutex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ { -- Semaphore functions -- }
+type
+ { The SDL semaphore structure, defined in SDL_sem.c }
+ PPSDL_Sem = ^PSDL_Sem;
+ PSDL_Sem = Type Pointer;
+
+{**
+ * Create a semaphore.
+ *
+ * This function creates a new semaphore and initializes it with the provided
+ * initial value. Each wait operation on the semaphore will atomically
+ * decrement the semaphore value and potentially block if the semaphore value
+ * is 0. Each post operation will atomically increment the semaphore value and
+ * wake waiting threads and allow them to retry the wait operation.
+ *
+ * \param initial_value the starting value of the semaphore
+ * \returns a new semaphore or NIL on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateSemaphore_func = function(initial_value: cuint32): PSDL_sem; cdecl;
+Var
+ SDL_CreateSemaphore : TSDL_CreateSemaphore_func = Nil;
+{$else}
+
+function SDL_CreateSemaphore(initial_value: cuint32): PSDL_sem; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateSemaphore' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Destroy a semaphore.
+ *
+ * It is not safe to destroy a semaphore if there are threads currently
+ * waiting on it.
+ *
+ * \param sem the semaphore to destroy
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DestroySemaphore_proc = procedure(sem: PSDL_Sem); cdecl;
+Var
+ SDL_DestroySemaphore : TSDL_DestroySemaphore_proc = Nil;
+{$else}
+
+procedure SDL_DestroySemaphore(sem: PSDL_Sem); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroySemaphore' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Wait until a semaphore has a positive value and then decrements it.
+ *
+ * This function suspends the calling thread until either the semaphore
+ * pointed to by `sem` has a positive value or the call is interrupted by a
+ * signal or error. If the call is successful it will atomically decrement the
+ * semaphore value.
+ *
+ * This function is the equivalent of calling SDL_SemWaitTimeout() with a time
+ * length of SDL_MUTEX_MAXWAIT.
+ *
+ * \param sem the semaphore wait on
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SemWait_func = function(sem: PSDL_Sem): cint; cdecl;
+Var
+ SDL_SemWait : TSDL_SemWait_func = Nil;
+{$else}
+
+function SDL_SemWait(sem: PSDL_Sem): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemWait' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * See if a semaphore has a positive value and decrement it if it does.
+ *
+ * This function checks to see if the semaphore pointed to by `sem` has a
+ * positive value and atomically decrements the semaphore value if it does. If
+ * the semaphore doesn't have a positive value, the function immediately
+ * returns SDL_MUTEX_TIMEDOUT.
+ *
+ * \param sem the semaphore to wait on
+ * \returns 0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait would
+ * block, or a negative error code on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SemTryWait_func = function(sem: PSDL_Sem): cint; cdecl;
+Var
+ SDL_SemTryWait : TSDL_SemTryWait_func = Nil;
+{$else}
+
+function SDL_SemTryWait(sem: PSDL_Sem): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemTryWait' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Wait until a semaphore has a positive value and then decrements it.
+ *
+ * This function suspends the calling thread until either the semaphore
+ * pointed to by `sem` has a positive value, the call is interrupted by a
+ * signal or error, or the specified time has elapsed. If the call is
+ * successful it will atomically decrement the semaphore value.
+ *
+ * \param sem the semaphore to wait on
+ * \param ms the length of the timeout, in milliseconds
+ * \returns 0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not
+ * succeed in the allotted time, or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SemWaitTimeout_func = function(sem: PSDL_Sem; ms: cuint32): cint; cdecl;
+Var
+ SDL_SemWaitTimeout : TSDL_SemWaitTimeout_func = Nil;
+{$else}
+
+function SDL_SemWaitTimeout(sem: PSDL_Sem; ms: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemWaitTimeout' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Atomically increment a semaphore's value and wake waiting threads.
+ *
+ * \param sem the semaphore to increment
+ * \returns 0 on success or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SemPost_func = function(sem: PSDL_Sem): cint; cdecl;
+Var
+ SDL_SemPost : TSDL_SemPost_func = Nil;
+{$else}
+
+function SDL_SemPost(sem: PSDL_Sem): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemPost' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the current value of a semaphore.
+ *
+ * \param sem the semaphore to query
+ * \returns the current value of the semaphore.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SemValue_func = function(sem: PSDL_Sem): cuint32; cdecl;
+Var
+ SDL_SemValue : TSDL_SemValue_func = Nil;
+{$else}
+
+function SDL_SemValue(sem: PSDL_Sem): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemValue' {$ENDIF} {$ENDIF};
+{$endif}
+
+ { -- Condition variable functions -- }
+type
+ { The SDL condition variable structure, defined in SDL_cond.c }
+ PPSDL_Cond = ^PSDL_Cond;
+
+ {**
+ * The condition variable type.
+ *
+ * Typical use of condition variables:
+ *
+ * Thread A:
+ * SDL_LockMutex(lock);
+ * while ( not condition )
+ * begin
+ * SDL_CondWait(cond, lock);
+ * end;
+ * SDL_UnlockMutex(lock);
+ *
+ * Thread B:
+ * SDL_LockMutex(lock);
+ * ...
+ * condition := true;
+ * ...
+ * SDL_CondSignal(cond);
+ * SDL_UnlockMutex(lock);
+ *
+ * There is some discussion whether to signal the condition variable
+ * with the mutex locked or not. There is some potential performance
+ * benefit to unlocking first on some platforms, but there are some
+ * potential race conditions depending on how your code is structured.
+ *
+ * In general it's safer to signal the condition variable while the
+ * mutex is locked.
+ *}
+ PSDL_Cond = Type Pointer;
+
+{**
+ * Create a condition variable.
+ *
+ * \returns a new condition variable or NIL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_CreateCond_func = function (): PSDL_Cond; cdecl;
+ Var
+ SDL_CreateCond : TSDL_CreateCond_func = Nil;
+ {$else}
+ function SDL_CreateCond: PSDL_Cond; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateCond' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Destroy a condition variable.
+ *
+ * \param cond the condition variable to destroy
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DestroyCond_proc = procedure(cond: PSDL_Cond); cdecl;
+Var
+ SDL_DestroyCond : TSDL_DestroyCond_proc = Nil;
+{$else}
+
+procedure SDL_DestroyCond(cond: PSDL_Cond); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyCond' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Restart one of the threads that are waiting on the condition variable.
+ *
+ * \param cond the condition variable to signal
+ * \returns 0 on success or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CondSignal_func = function(cond: PSDL_Cond): cint; cdecl;
+Var
+ SDL_CondSignal : TSDL_CondSignal_func = Nil;
+{$else}
+
+function SDL_CondSignal(cond: PSDL_Cond): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondSignal' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Restart all threads that are waiting on the condition variable.
+ *
+ * \param cond the condition variable to signal
+ * \returns 0 on success or a negative error code on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CondBroadcast_func = function(cond: PSDL_Cond): cint; cdecl;
+Var
+ SDL_CondBroadcast : TSDL_CondBroadcast_func = Nil;
+{$else}
+
+function SDL_CondBroadcast(cond: PSDL_Cond): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondBroadcast' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Wait until a condition variable is signaled.
+ *
+ * This function unlocks the specified `mutex` and waits for another thread to
+ * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable
+ * `cond`. Once the condition variable is signaled, the mutex is re-locked and
+ * the function returns.
+ *
+ * The mutex must be locked before calling this function.
+ *
+ * This function is the equivalent of calling SDL_CondWaitTimeout() with a
+ * time length of SDL_MUTEX_MAXWAIT.
+ *
+ * \param cond the condition variable to wait on
+ * \param mutex the mutex used to coordinate thread access
+ * \returns 0 when it is signaled or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CondWait_func = function(cond: PSDL_Cond; mutex: PSDL_Mutex): cint; cdecl;
+Var
+ SDL_CondWait : TSDL_CondWait_func = Nil;
+{$else}
+
+function SDL_CondWait(cond: PSDL_Cond; mutex: PSDL_Mutex): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondWait' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Wait until a condition variable is signaled or a certain time has passed.
+ *
+ * This function unlocks the specified `mutex` and waits for another thread to
+ * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable
+ * `cond`, or for the specified time to elapse. Once the condition variable is
+ * signaled or the time elapsed, the mutex is re-locked and the function
+ * returns.
+ *
+ * The mutex must be locked before calling this function.
+ *
+ * \param cond the condition variable to wait on
+ * \param mutex the mutex used to coordinate thread access
+ * \param ms the maximum time to wait, in milliseconds, or SDL_MUTEX_MAXWAIT
+ * to wait indefinitely
+ * \returns 0 if the condition variable is signaled, SDL_MUTEX_TIMEDOUT if
+ * the condition is not signaled in the allotted time, or a negative
+ * error code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CondWaitTimeout_func = function(cond: PSDL_Cond; mutex: PSDL_Mutex; ms: cuint32): cint; cdecl;
+Var
+ SDL_CondWaitTimeout : TSDL_CondWaitTimeout_func = Nil;
+{$else}
+
+function SDL_CondWaitTimeout(cond: PSDL_Cond; mutex: PSDL_Mutex; ms: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondWaitTimeout' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlpixels.inc b/units/sdl2_for_pascal/sdlpixels.inc
new file mode 100644
index 0000000..8e8fc2a
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlpixels.inc
@@ -0,0 +1,919 @@
+// based on "sdl_pixels.h" (2.0.14, WIP)
+
+{**
+ * \file SDL_pixels.h
+ *
+ * Header for the enumerated pixel format definitions.
+ *}
+
+{**
+ * Transparency definitions
+ *
+ * These define alpha as the opacity of a surface.
+ *}
+
+const
+ SDL_ALPHA_OPAQUE = 255;
+ SDL_ALPHA_TRANSPARENT = 0;
+
+{** Pixel type. *}
+type
+ PPSDL_PixelType = ^PSDL_PixelType;
+ PSDL_PixelType = ^TSDL_PixelType;
+ TSDL_PixelType = type cuint;
+
+const
+ SDL_PIXELTYPE_UNKNOWN = TSDL_PixelType(0);
+ SDL_PIXELTYPE_INDEX1 = TSDL_PixelType(1);
+ SDL_PIXELTYPE_INDEX4 = TSDL_PixelType(2);
+ SDL_PIXELTYPE_INDEX8 = TSDL_PixelType(3);
+ SDL_PIXELTYPE_PACKED8 = TSDL_PixelType(4);
+ SDL_PIXELTYPE_PACKED16 = TSDL_PixelType(5);
+ SDL_PIXELTYPE_PACKED32 = TSDL_PixelType(6);
+ SDL_PIXELTYPE_ARRAYU8 = TSDL_PixelType(7);
+ SDL_PIXELTYPE_ARRAYU16 = TSDL_PixelType(8);
+ SDL_PIXELTYPE_ARRAYU32 = TSDL_PixelType(9);
+ SDL_PIXELTYPE_ARRAYF16 = TSDL_PixelType(10);
+ SDL_PIXELTYPE_ARRAYF32 = TSDL_PixelType(11);
+
+{** Bitmap pixel order, high bit -> low bit. *}
+type
+ PPSDL_BitmapOrder = ^PSDL_BitmapOrder;
+ PSDL_BitmapOrder = ^TSDL_BitmapOrder;
+ TSDL_BitmapOrder = type cuint32;
+
+const
+ SDL_BITMAPORDER_NONE = TSDL_BitmapOrder(0);
+ SDL_BITMAPORDER_4321 = TSDL_BitmapOrder(1);
+ SDL_BITMAPORDER_1234 = TSDL_BitmapOrder(2);
+
+{** Packed component order, high bit -> low bit. *}
+type
+ PPSDL_PackOrder = ^PSDL_PackOrder;
+ PSDL_PackOrder = ^TSDL_PackOrder;
+ TSDL_PackOrder = type cuint32;
+
+const
+ SDL_PACKEDORDER_NONE = TSDL_PackOrder(0);
+ SDL_PACKEDORDER_XRGB = TSDL_PackOrder(1);
+ SDL_PACKEDORDER_RGBX = TSDL_PackOrder(2);
+ SDL_PACKEDORDER_ARGB = TSDL_PackOrder(3);
+ SDL_PACKEDORDER_RGBA = TSDL_PackOrder(4);
+ SDL_PACKEDORDER_XBGR = TSDL_PackOrder(5);
+ SDL_PACKEDORDER_BGRX = TSDL_PackOrder(6);
+ SDL_PACKEDORDER_ABGR = TSDL_PackOrder(7);
+ SDL_PACKEDORDER_BGRA = TSDL_PackOrder(8);
+
+{** Array component order, low byte -> high byte. *}
+type
+ PPSDL_ArrayOrder = ^PSDL_ArrayOrder;
+ PSDL_ArrayOrder = ^TSDL_ArrayOrder;
+ TSDL_ArrayOrder = type cuint32;
+
+const
+ SDL_ARRAYORDER_NONE = TSDL_ArrayOrder(0);
+ SDL_ARRAYORDER_RGB = TSDL_ArrayOrder(1);
+ SDL_ARRAYORDER_RGBA = TSDL_ArrayOrder(2);
+ SDL_ARRAYORDER_ARGB = TSDL_ArrayOrder(3);
+ SDL_ARRAYORDER_BGR = TSDL_ArrayOrder(4);
+ SDL_ARRAYORDER_BGRA = TSDL_ArrayOrder(5);
+ SDL_ARRAYORDER_ABGR = TSDL_ArrayOrder(6);
+
+{** Packed component layout. *}
+type
+ PPSDL_PackedLayout = ^PSDL_PackedLayout;
+ PSDL_PackedLayout = ^TSDL_PackedLayout;
+ TSDL_PackedLayout = type cuint32;
+
+const
+ SDL_PACKEDLAYOUT_NONE = TSDL_PackedLayout(0);
+ SDL_PACKEDLAYOUT_332 = TSDL_PackedLayout(1);
+ SDL_PACKEDLAYOUT_4444 = TSDL_PackedLayout(2);
+ SDL_PACKEDLAYOUT_1555 = TSDL_PackedLayout(3);
+ SDL_PACKEDLAYOUT_5551 = TSDL_PackedLayout(4);
+ SDL_PACKEDLAYOUT_565 = TSDL_PackedLayout(5);
+ SDL_PACKEDLAYOUT_8888 = TSDL_PackedLayout(6);
+ SDL_PACKEDLAYOUT_2101010 = TSDL_PackedLayout(7);
+ SDL_PACKEDLAYOUT_1010102 = TSDL_PackedLayout(8);
+
+{
+SDL2-for-Pascal: The SDL_DEFINE_PIXELFOURCC macro is replaced
+ by another macro, the SDL_FOURCC macro (in SDL_stdinc.h).
+
+ The original C SDL_FOURCC macro:
+ #define SDL_FOURCC(A, B, C, D) \
+ ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24))
+
+ In Pascal it is cleaner to implement this directly as a
+ constant instead of a function. So we do, e. g.:
+
+ SDL_PIXELFORMAT_YV12 = (cuint32('Y') ) or
+ (cuint32('V') shl 8) or
+ (cuint32('1') shl 16) or
+ (cuint32('2') shl 24);
+
+ In the future it may be desirable to have a Pascal function.
+ The prototype could look like this:
+ function SDL_DEFINE_PIXELFOURCC(A,B,C,D: Variant): Variant;
+}
+
+{
+SDL2-for-Pascal: The SDL_DEFINE_PIXELFORMAT macro returns the underlying
+ pixel format based on five arguments.
+
+ The original C macro:
+ #define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
+ ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
+ ((bits) << 8) | ((bytes) << 0))
+
+ This C implementation could be replaced by a Pascal function,
+ but from a performance stand point this will be slower.
+ Therefore we decided to keep it as it has been implemented
+ before by the original binding authors and translate
+ every pixel format constant by the very same expression:
+
+ SDL_PIXELFORMAT_[...] = (1 shl 28) or
+ (SDL_PIXELTYPE_[...] shl 24) or
+ (SDL_BITMAPORDER_[...] shl 20) or
+ ([...] shl 16) or
+ ([...] shl 8) or
+ ([...] shl 0);
+
+ In the future it may be desirable to have a Pascal function.
+ The prototype could look like this:
+ function SDL_DEFINE_PIXELFORMAT(type, order, layour, bit, bytes: cuint32): Result;
+}
+
+function SDL_PIXELFLAG(X: cuint32): cuint32;
+function SDL_PIXELTYPE(X: cuint32): cuint32;
+function SDL_PIXELORDER(X: cuint32): cuint32;
+function SDL_PIXELLAYOUT(X: cuint32): cuint32;
+function SDL_BITSPERPIXEL(X: cuint32): cuint32;
+
+{
+SDL2-for-Pascal: Is it worth translating these macros as they seem to be used
+ by SDL2 internally only?
+
+#define SDL_BYTESPERPIXEL(X) \
+ (SDL_ISPIXELFORMAT_FOURCC(X) ? \
+ ((((X) == SDL_PIXELFORMAT_YUY2) || \
+ ((X) == SDL_PIXELFORMAT_UYVY) || \
+ ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
+
+#define SDL_ISPIXELFORMAT_INDEXED(format) \
+ (!SDL_ISPIXELFORMAT_FOURCC(format) && \
+ ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8)))
+
+#define SDL_ISPIXELFORMAT_PACKED(format) \
+ (!SDL_ISPIXELFORMAT_FOURCC(format) && \
+ ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32)))
+
+#define SDL_ISPIXELFORMAT_ARRAY(format) \
+ (!SDL_ISPIXELFORMAT_FOURCC(format) && \
+ ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32)))
+
+#define SDL_ISPIXELFORMAT_ALPHA(format) \
+ ((SDL_ISPIXELFORMAT_PACKED(format) && \
+ ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \
+ (SDL_ISPIXELFORMAT_ARRAY(format) && \
+ ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \
+ (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \
+ (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \
+ (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA))))
+}
+
+{* The flag is set to 1 because 0x1? is not in the printable ASCII range *}
+function SDL_ISPIXELFORMAT_FOURCC(format: Variant): Boolean;
+
+{* Note: If you modify this list, update SDL_GetPixelFormatName() *}
+const
+ SDL_PIXELFORMAT_UNKNOWN = 0;
+ SDL_PIXELFORMAT_INDEX1LSB = (1 shl 28) or
+ (SDL_PIXELTYPE_INDEX1 shl 24) or
+ (SDL_BITMAPORDER_4321 shl 20) or
+ (0 shl 16) or
+ (1 shl 8) or
+ (0 shl 0);
+
+ SDL_PIXELFORMAT_INDEX1MSB = (1 shl 28) or
+ (SDL_PIXELTYPE_INDEX1 shl 24) or
+ (SDL_BITMAPORDER_1234 shl 20) or
+ (0 shl 16) or
+ (1 shl 8) or
+ (0 shl 0);
+
+ SDL_PIXELFORMAT_INDEX4LSB = (1 shl 28) or
+ (SDL_PIXELTYPE_INDEX4 shl 24) or
+ (SDL_BITMAPORDER_4321 shl 20) or
+ (0 shl 16) or
+ (4 shl 8) or
+ (0 shl 0);
+
+ SDL_PIXELFORMAT_INDEX4MSB = (1 shl 28) or
+ (SDL_PIXELTYPE_INDEX4 shl 24) or
+ (SDL_BITMAPORDER_1234 shl 20) or
+ (0 shl 16) or
+ (4 shl 8) or
+ (0 shl 0);
+
+ SDL_PIXELFORMAT_INDEX8 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED8 shl 24) or
+ (0 shl 20) or
+ (0 shl 16) or
+ (8 shl 8) or
+ (1 shl 0);
+
+ SDL_PIXELFORMAT_RGB332 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED8 shl 24) or
+ (SDL_PACKEDORDER_XRGB shl 20) or
+ (SDL_PACKEDLAYOUT_332 shl 16) or
+ (8 shl 8) or
+ (1 shl 0);
+
+ SDL_PIXELFORMAT_RGB444 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_XRGB shl 20) or
+ (SDL_PACKEDLAYOUT_4444 shl 16) or
+ (12 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_RGB555 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_XRGB shl 20) or
+ (SDL_PACKEDLAYOUT_1555 shl 16) or
+ (15 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_BGR555 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_XBGR shl 20) or
+ (SDL_PACKEDLAYOUT_1555 shl 16) or
+ (15 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_ARGB4444 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_ARGB shl 20) or
+ (SDL_PACKEDLAYOUT_4444 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_RGBA4444 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_RGBA shl 20) or
+ (SDL_PACKEDLAYOUT_4444 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_ABGR4444 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_ABGR shl 20) or
+ (SDL_PACKEDLAYOUT_4444 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_BGRA4444 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_BGRA shl 20) or
+ (SDL_PACKEDLAYOUT_4444 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_ARGB1555 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_ARGB shl 20) or
+ (SDL_PACKEDLAYOUT_1555 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_RGBA5551 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_RGBA shl 20) or
+ (SDL_PACKEDLAYOUT_5551 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_ABGR1555 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_ABGR shl 20) or
+ (SDL_PACKEDLAYOUT_1555 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_BGRA5551 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_BGRA shl 20) or
+ (SDL_PACKEDLAYOUT_5551 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_RGB565 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_XRGB shl 20) or
+ (SDL_PACKEDLAYOUT_565 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_BGR565 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED16 shl 24) or
+ (SDL_PACKEDORDER_XBGR shl 20) or
+ (SDL_PACKEDLAYOUT_1555 shl 16) or
+ (16 shl 8) or
+ (2 shl 0);
+
+ SDL_PIXELFORMAT_RGB24 = (1 shl 28) or
+ (SDL_PIXELTYPE_ARRAYU8 shl 24) or
+ (SDL_ARRAYORDER_RGB shl 20) or
+ (0 shl 16) or
+ (24 shl 8) or
+ (3 shl 0);
+
+ SDL_PIXELFORMAT_BGR24 = (1 shl 28) or
+ (SDL_PIXELTYPE_ARRAYU8 shl 24) or
+ (SDL_ARRAYORDER_BGR shl 20) or
+ (0 shl 16) or
+ (24 shl 8) or
+ (3 shl 0);
+
+ SDL_PIXELFORMAT_RGB888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_XRGB shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (24 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_RGBX8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_RGBX shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (24 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_BGR888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_XBGR shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (24 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_BGRX8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_BGRX shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (24 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_ARGB8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_ARGB shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (32 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_RGBA8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_RGBA shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (32 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_ABGR8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_ABGR shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (32 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_BGRA8888 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_RGBX shl 20) or
+ (SDL_PACKEDLAYOUT_8888 shl 16) or
+ (32 shl 8) or
+ (4 shl 0);
+
+ SDL_PIXELFORMAT_ARGB2101010 = (1 shl 28) or
+ (SDL_PIXELTYPE_PACKED32 shl 24) or
+ (SDL_PACKEDORDER_ARGB shl 20) or
+ (SDL_PACKEDLAYOUT_2101010 shl 16)or
+ (32 shl 8) or
+ (4 shl 0);
+
+ (* Aliases for RGBA byte arrays of color data, for the current platform *)
+ {$IFDEF FPC}
+ {$IF DEFINED(ENDIAN_LITTLE)}
+ SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888;
+ SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888;
+ SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888;
+ SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888;
+ {$ELSEIF DEFINED(ENDIAN_BIG)}
+ SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888;
+ SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888;
+ SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888;
+ SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888;
+ {$ELSE}
+ {$FATAL Cannot determine endianness.}
+ {$IFEND}
+ {$ENDIF}
+
+ {**< Planar mode: Y + V + U (3 planes) *}
+ SDL_PIXELFORMAT_YV12 = (cuint32('Y') ) or
+ (cuint32('V') shl 8) or
+ (cuint32('1') shl 16) or
+ (cuint32('2') shl 24);
+ {**< Planar mode: Y + U + V (3 planes) *}
+ SDL_PIXELFORMAT_IYUV = (cuint32('I') ) or
+ (cuint32('Y') shl 8) or
+ (cuint32('U') shl 16) or
+ (cuint32('V') shl 24);
+ {**< Packed mode: Y0+U0+Y1+V0 (1 plane) *}
+ SDL_PIXELFORMAT_YUY2 = (cuint32('Y') ) or
+ (cuint32('U') shl 8) or
+ (cuint32('Y') shl 16) or
+ (cuint32('2') shl 24);
+ {**< Packed mode: U0+Y0+V0+Y1 (1 plane) *}
+ SDL_PIXELFORMAT_UYVY = (cuint32('U') ) or
+ (cuint32('Y') shl 8) or
+ (cuint32('V') shl 16) or
+ (cuint32('Y') shl 24);
+ {**< Packed mode: Y0+V0+Y1+U0 (1 plane) *}
+ SDL_PIXELFORMAT_YVYU = (cuint32('Y') ) or
+ (cuint32('V') shl 8) or
+ (cuint32('Y') shl 16) or
+ (cuint32('U') shl 24);
+ {**< Planar mode: Y + U/V interleaved (2 planes) *}
+ SDL_PIXELFORMAT_NV12 = (cuint32('N') ) or
+ (cuint32('V') shl 8) or
+ (cuint32('1') shl 16) or
+ (cuint32('2') shl 24);
+ {**< Planar mode: Y + V/U interleaved (2 planes) *}
+ SDL_PIXELFORMAT_NV21 = (cuint32('N') ) or
+ (cuint32('V') shl 8) or
+ (cuint32('2') shl 16) or
+ (cuint32('1') shl 24);
+ {**< Android video texture format *}
+ SDL_PIXELFORMAT_EXTERMAL_OES
+ = (cuint32('O') ) or
+ (cuint32('E') shl 8) or
+ (cuint32('S') shl 16) or
+ (cuint32(' ') shl 24);
+
+type
+
+ {**
+ * The bits of this structure can be directly reinterpreted as an integer-packed
+ * color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888
+ * on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems).
+ *}
+ PPSDL_Color = ^PSDL_Color;
+ PSDL_Color = ^TSDL_Color;
+ TSDL_Color = record
+ r: cuint8;
+ g: cuint8;
+ b: cuint8;
+ a: cuint8;
+ end;
+
+ PPSDL_Colour = ^PSDL_Colour;
+ PSDL_Colour = ^TSDL_Colour;
+ TSDL_Colour = TSDL_Color;
+
+ PPSDL_Palette = ^PSDL_Palette;
+ PSDL_Palette = ^TSDL_Palette;
+ TSDL_Palette = record
+ ncolors: cint;
+ colors: PSDL_Color;
+ version: cuint32;
+ refcount: cint;
+ end;
+
+ {**
+ * Everything in the pixel format structure is read-only.
+ *}
+ PPSDL_PixelFormat = ^PSDL_PixelFormat;
+ PSDL_PixelFormat = ^TSDL_PixelFormat;
+ TSDL_PixelFormat = record
+ format: cuint32;
+ palette: PSDL_Palette;
+ BitsPerPixel: cuint8;
+ BytesPerPixel: cuint8;
+ padding: array[0..1] of cuint8;
+ Rmask: cuint32;
+ Gmask: cuint32;
+ Bmask: cuint32;
+ Amask: cuint32;
+ Rloss: cuint8;
+ Gloss: cuint8;
+ Bloss: cuint8;
+ Aloss: cuint8;
+ Rshift: cuint8;
+ Gshift: cuint8;
+ Bshift: cuint8;
+ Ashift: cuint8;
+ refcount: cint;
+ next: PSDL_PixelFormat;
+ end;
+
+{**
+ * Get the human readable name of a pixel format.
+ *
+ * \param format the pixel format to query
+ * \returns the human readable name of the specified pixel format or
+ * `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPixelFormatName_func = function(format: cuint32): PAnsiChar; cdecl;
+Var
+ SDL_GetPixelFormatName : TSDL_GetPixelFormatName_func = Nil;
+{$else}
+
+function SDL_GetPixelFormatName(format: cuint32): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPixelFormatName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Convert one of the enumerated pixel formats to a bpp value and RGBA masks.
+ *
+ * \param format one of the SDL_PixelFormatEnum values
+ * \param bpp a bits per pixel value; usually 15, 16, or 32
+ * \param Rmask a pointer filled in with the red mask for the format
+ * \param Gmask a pointer filled in with the green mask for the format
+ * \param Bmask a pointer filled in with the blue mask for the format
+ * \param Amask a pointer filled in with the alpha mask for the format
+ * \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't
+ * possible; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_MasksToPixelFormatEnum
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_PixelFormatEnumToMasks_func = function(format: cuint32; bpp: pcint;
+ Rmask: pcuint32; Gmask: pcuint32; Bmask: pcuint32; Amask: pcuint32): TSDL_Bool; cdecl;
+Var
+ SDL_PixelFormatEnumToMasks : TSDL_PixelFormatEnumToMasks_func = Nil;
+{$else}
+
+function SDL_PixelFormatEnumToMasks(format: cuint32; bpp: pcint;
+ Rmask: pcuint32; Gmask: pcuint32; Bmask: pcuint32; Amask: pcuint32): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PixelFormatEnumToMasks' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Convert a bpp value and RGBA masks to an enumerated pixel format.
+ *
+ * This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't
+ * possible.
+ *
+ * \param bpp a bits per pixel value; usually 15, 16, or 32
+ * \param Rmask the red mask for the format
+ * \param Gmask the green mask for the format
+ * \param Bmask the blue mask for the format
+ * \param Amask the alpha mask for the format
+ * \returns one of the SDL_PixelFormatEnum values
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_PixelFormatEnumToMasks
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MasksToPixelFormatEnum_func = function(bpp: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): cuint32; cdecl;
+Var
+ SDL_MasksToPixelFormatEnum : TSDL_MasksToPixelFormatEnum_func = Nil;
+{$else}
+
+function SDL_MasksToPixelFormatEnum(bpp: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MasksToPixelFormatEnum' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Create an SDL_PixelFormat structure corresponding to a pixel format.
+ *
+ * Returned structure may come from a shared global cache (i.e. not newly
+ * allocated), and hence should not be modified, especially the palette. Weird
+ * errors such as `Blit combination not supported` may occur.
+ *
+ * \param pixel_format one of the SDL_PixelFormatEnum values
+ * \returns the new SDL_PixelFormat structure or NULL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_FreeFormat
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AllocFormat_func = function(pixel_format: cuint32): PSDL_PixelFormat; cdecl;
+Var
+ SDL_AllocFormat : TSDL_AllocFormat_func = Nil;
+{$else}
+
+function SDL_AllocFormat(pixel_format: cuint32): PSDL_PixelFormat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AllocFormat' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Free an SDL_PixelFormat structure allocated by SDL_AllocFormat().
+ *
+ * \param format the SDL_PixelFormat structure to free
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AllocFormat
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeFormat_proc = procedure(format: PSDL_PixelFormat); cdecl;
+Var
+ SDL_FreeFormat : TSDL_FreeFormat_proc = Nil;
+{$else}
+
+procedure SDL_FreeFormat(format: PSDL_PixelFormat); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeFormat' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Create a palette structure with the specified number of color entries.
+ *
+ * The palette entries are initialized to white.
+ *
+ * \param ncolors represents the number of color entries in the color palette
+ * \returns a new SDL_Palette structure on success or NULL on failure (e.g. if
+ * there wasn't enough memory); call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_FreePalette
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AllocPalette_func = function(ncolors: cint): PSDL_Palette; cdecl;
+Var
+ SDL_AllocPalette : TSDL_AllocPalette_func = Nil;
+{$else}
+
+function SDL_AllocPalette(ncolors: cint): PSDL_Palette; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AllocPalette' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set the palette for a pixel format structure.
+ *
+ * \param format the SDL_PixelFormat structure that will use the palette
+ * \param palette the SDL_Palette structure that will be used
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AllocPalette
+ * \sa SDL_FreePalette
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetPixelFormatPalette_func = function(format: PSDL_PixelFormat; palette: PSDL_Palette): cint; cdecl;
+Var
+ SDL_SetPixelFormatPalette : TSDL_SetPixelFormatPalette_func = Nil;
+{$else}
+
+function SDL_SetPixelFormatPalette(format: PSDL_PixelFormat; palette: PSDL_Palette): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetPixelFormatPalette' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set a range of colors in a palette.
+ *
+ * \param palette the SDL_Palette structure to modify
+ * \param colors an array of SDL_Color structures to copy into the palette
+ * \param firstcolor the index of the first palette entry to modify
+ * \param ncolors the number of entries to modify
+ * \returns 0 on success or a negative error code if not all of the colors
+ * could be set; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AllocPalette
+ * \sa SDL_CreateRGBSurface
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetPaletteColors_func = function(palette: PSDL_Palette; const colors: PSDL_Color; firstcolor: cint; ncolors: cint): cint; cdecl;
+Var
+ SDL_SetPaletteColors : TSDL_SetPaletteColors_func = Nil;
+{$else}
+
+function SDL_SetPaletteColors(palette: PSDL_Palette; const colors: PSDL_Color; firstcolor: cint; ncolors: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetPaletteColors' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Free a palette created with SDL_AllocPalette().
+ *
+ * \param palette the SDL_Palette structure to be freed
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AllocPalette
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreePalette_proc = procedure(palette: PSDL_Palette); cdecl;
+Var
+ SDL_FreePalette : TSDL_FreePalette_proc = Nil;
+{$else}
+
+procedure SDL_FreePalette(palette: PSDL_Palette); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreePalette' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Map an RGB triple to an opaque pixel value for a given pixel format.
+ *
+ * This function maps the RGB color value to the specified pixel format and
+ * returns the pixel value best approximating the given RGB color value for
+ * the given pixel format.
+ *
+ * If the format has a palette (8-bit) the index of the closest matching color
+ * in the palette will be returned.
+ *
+ * If the specified pixel format has an alpha component it will be returned as
+ * all 1 bits (fully opaque).
+ *
+ * If the pixel format bpp (color depth) is less than 32-bpp then the unused
+ * upper bits of the return value can safely be ignored (e.g., with a 16-bpp
+ * format the return value can be assigned to a Uint16, and similarly a Uint8
+ * for an 8-bpp format).
+ *
+ * \param format an SDL_PixelFormat structure describing the pixel format
+ * \param r the red component of the pixel in the range 0-255
+ * \param g the green component of the pixel in the range 0-255
+ * \param b the blue component of the pixel in the range 0-255
+ * \returns a pixel value
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetRGB
+ * \sa SDL_GetRGBA
+ * \sa SDL_MapRGBA
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MapRGB_func = function(const format: PSDL_PixelFormat; r: cuint8; g: cuint8; b: cuint8): cuint32; cdecl;
+Var
+ SDL_MapRGB : TSDL_MapRGB_func = Nil;
+{$else}
+
+function SDL_MapRGB(const format: PSDL_PixelFormat; r: cuint8; g: cuint8; b: cuint8): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MapRGB' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Map an RGBA quadruple to a pixel value for a given pixel format.
+ *
+ * This function maps the RGBA color value to the specified pixel format and
+ * returns the pixel value best approximating the given RGBA color value for
+ * the given pixel format.
+ *
+ * If the specified pixel format has no alpha component the alpha value will
+ * be ignored (as it will be in formats with a palette).
+ *
+ * If the format has a palette (8-bit) the index of the closest matching color
+ * in the palette will be returned.
+ *
+ * If the pixel format bpp (color depth) is less than 32-bpp then the unused
+ * upper bits of the return value can safely be ignored (e.g., with a 16-bpp
+ * format the return value can be assigned to a Uint16, and similarly a Uint8
+ * for an 8-bpp format).
+ *
+ * \param format an SDL_PixelFormat structure describing the format of the
+ * pixel
+ * \param r the red component of the pixel in the range 0-255
+ * \param g the green component of the pixel in the range 0-255
+ * \param b the blue component of the pixel in the range 0-255
+ * \param a the alpha component of the pixel in the range 0-255
+ * \returns a pixel value
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetRGB
+ * \sa SDL_GetRGBA
+ * \sa SDL_MapRGB
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MapRGBA_func = function(const format: PSDL_PixelFormat; r: cuint8; g: cuint8; b: cuint8; a: cuint8): cuint32; cdecl;
+Var
+ SDL_MapRGBA : TSDL_MapRGBA_func = Nil;
+{$else}
+
+function SDL_MapRGBA(const format: PSDL_PixelFormat; r: cuint8; g: cuint8; b: cuint8; a: cuint8): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MapRGBA' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get RGB values from a pixel in the specified format.
+ *
+ * This function uses the entire 8-bit [0..255] range when converting color
+ * components from pixel formats with less than 8-bits per RGB component
+ * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff,
+ * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]).
+ *
+ * \param pixel a pixel value
+ * \param format an SDL_PixelFormat structure describing the format of the
+ * pixel
+ * \param r a pointer filled in with the red component
+ * \param g a pointer filled in with the green component
+ * \param b a pointer filled in with the blue component
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetRGBA
+ * \sa SDL_MapRGB
+ * \sa SDL_MapRGBA
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRGB_proc = procedure(pixel: cuint32; const format: PSDL_PixelFormat; r: pcuint8; g: pcuint8; b: pcuint8); cdecl;
+Var
+ SDL_GetRGB : TSDL_GetRGB_proc = Nil;
+{$else}
+
+procedure SDL_GetRGB(pixel: cuint32; const format: PSDL_PixelFormat; r: pcuint8; g: pcuint8; b: pcuint8); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRGB' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get RGBA values from a pixel in the specified format.
+ *
+ * This function uses the entire 8-bit [0..255] range when converting color
+ * components from pixel formats with less than 8-bits per RGB component
+ * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff,
+ * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]).
+ *
+ * If the surface has no alpha component, the alpha will be returned as 0xff
+ * (100% opaque).
+ *
+ * \param pixel a pixel value
+ * \param format an SDL_PixelFormat structure describing the format of the
+ * pixel
+ * \param r a pointer filled in with the red component
+ * \param g a pointer filled in with the green component
+ * \param b a pointer filled in with the blue component
+ * \param a a pointer filled in with the alpha component
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetRGB
+ * \sa SDL_MapRGB
+ * \sa SDL_MapRGBA
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRGBA_proc = procedure(pixel: cuint32; const format: PSDL_PixelFormat; r: pcuint8; g: pcuint8; b: pcuint8; a: pcuint8); cdecl;
+Var
+ SDL_GetRGBA : TSDL_GetRGBA_proc = Nil;
+{$else}
+
+procedure SDL_GetRGBA(pixel: cuint32; const format: PSDL_PixelFormat; r: pcuint8; g: pcuint8; b: pcuint8; a: pcuint8); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRGBA' {$ENDIF} {$ENDIF};
+{$endif}
+
+{/**
+ * Calculate a 256 entry gamma ramp for a gamma value.
+ *
+ * \param gamma a gamma value where 0.0 is black and 1.0 is identity
+ * \param ramp an array of 256 values filled in with the gamma ramp
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_SetWindowGammaRamp
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CalculateGammaRamp_proc = procedure(gamma: cfloat; ramp: pcuint16); cdecl;
+Var
+ SDL_CalculateGammaRamp : TSDL_CalculateGammaRamp_proc = Nil;
+{$else}
+
+procedure SDL_CalculateGammaRamp(gamma: cfloat; ramp: pcuint16); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CalculateGammaRamp' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlplatform.inc b/units/sdl2_for_pascal/sdlplatform.inc
new file mode 100644
index 0000000..d3554d2
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlplatform.inc
@@ -0,0 +1,21 @@
+// based on "sdl_platform.h" (2.0.14)
+
+{**
+ * \file SDL_platform.h
+ *
+ * Try to get a standard set of platform defines.
+ *}
+
+{**
+ * Gets the name of the platform.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPlatform_func = function (): PAnsiChar; cdecl;
+Var
+ SDL_GetPlatform : TSDL_GetPlatform_func = Nil;
+{$else}
+function SDL_GetPlatform: PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPlatform' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlpower.inc b/units/sdl2_for_pascal/sdlpower.inc
new file mode 100644
index 0000000..9b7da80
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlpower.inc
@@ -0,0 +1,43 @@
+// based on "sdl_power.h" (2.0.14)
+
+{**
+ * \file SDL_power.h
+ *
+ * Header for the SDL power management routines.
+ *}
+
+ {**
+ * The basic state for the system's power supply.
+ *}
+type
+ PPSDL_PowerState = ^PSDL_PowerState;
+ PSDL_PowerState = ^TSDL_PowerState;
+ TSDL_PowerState = (SDL_POWERSTATE_UNKNOWN, {**< cannot determine power status *}
+ SDL_POWERSTATE_ON_BATTERY, {**< Not plugged in, running on the battery *}
+ SDL_POWERSTATE_NO_BATTERY, {**< Plugged in, no battery available *}
+ SDL_POWERSTATE_CHARGING, {**< Plugged in, charging battery *}
+ SDL_POWERSTATE_CHARGED); {**< Plugged in, battery charged *}
+
+ {**
+ * \brief Get the current power supply details.
+ *
+ * \param secs Seconds of battery life left. You can pass a NULL here if
+ * you don't care. Will return -1 if we can't determine a
+ * value, or we're not running on a battery.
+ *
+ * \param pct Percentage of battery life left, between 0 and 100. You can
+ * pass a NULL here if you don't care. Will return -1 if we
+ * can't determine a value, or we're not running on a battery.
+ *
+ * \return The state of the battery (if any).
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPowerInfo_func = function(secs: pcint; pct: pcint): TSDL_PowerState; cdecl;
+Var
+ SDL_GetPowerInfo : TSDL_GetPowerInfo_func = Nil;
+{$else}
+
+function SDL_GetPowerInfo(secs: pcint; pct: pcint): TSDL_PowerState; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPowerInfo' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlrect.inc b/units/sdl2_for_pascal/sdlrect.inc
new file mode 100644
index 0000000..11be274
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlrect.inc
@@ -0,0 +1,308 @@
+// based on "sdl_rect.h" (2.24.0)
+
+{**
+ * \file SDL_rect.h
+ *
+ * Header file for SDL_rect definition and management functions.
+ *}
+
+type
+ {**
+ * \brief The structure that defines a point (integer)
+ *
+ * \sa SDL_EnclosePoints
+ * \sa SDL_PointInRect
+ *}
+ PPSDL_Point = ^PSDL_Point;
+ PSDL_Point = ^TSDL_Point;
+ TSDL_Point = record
+ x: cint;
+ y: cint;
+ end;
+
+ {**
+ * \brief The structure that defines a point (floating point)
+ *
+ * \sa SDL_EnclosePoints
+ * \sa SDL_PointInRect
+ *}
+ PPSDL_FPoint = ^PSDL_FPoint;
+ PSDL_FPoint = ^TSDL_FPoint;
+ TSDL_FPoint = record
+ x: cfloat;
+ y: cfloat;
+ end;
+
+ {**
+ * \brief A rectangle, with the origin at the upper left (integer).
+ *
+ * \sa SDL_RectEmpty
+ * \sa SDL_RectEquals
+ * \sa SDL_HasIntersection
+ * \sa SDL_IntersectRect
+ * \sa SDL_UnionRect
+ * \sa SDL_EnclosePoints
+ *}
+ PPSDL_Rect = ^PSDL_Rect;
+ PSDL_Rect = ^TSDL_Rect;
+ TSDL_Rect = record
+ x,y: cint;
+ w,h: cint;
+ end;
+
+ {**
+ * A rectangle, with the origin at the upper left. (floating point)
+ *}
+ PPSDL_FRect = ^PSDL_FRect;
+ PSDL_FRect = ^TSDL_FRect;
+ TSDL_FRect = record
+ x,y: cfloat;
+ w,h: cfloat;
+ end;
+
+{**
+ * Returns true if point resides inside a rectangle.
+ *}
+function SDL_PointInRect(const p: PSDL_Point; const r: PSDL_Rect): Boolean; Inline;
+
+{**
+ * Returns true if the rectangle has no area.
+ *}
+function SDL_RectEmpty(const r: PSDL_Rect): Boolean; inline;
+
+{**
+ * Returns true if the two rectangles are equal.
+ *}
+function SDL_RectEquals(const a, b: PSDL_Rect): Boolean; inline;
+
+{**
+ * Determine whether two rectangles intersect.
+ *
+ * SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasIntersection_func = function(const a, b: PSDL_Rect): TSDL_Bool; cdecl;
+Var
+ SDL_HasIntersection : TSDL_HasIntersection_func = Nil;
+{$else}
+
+function SDL_HasIntersection(const a, b: PSDL_Rect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasIntersection' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the intersection of two rectangles.
+ *
+ * SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IntersectRect_func = function(const A, B: PSDL_Rect; result: PSDL_Rect): TSDL_Bool; cdecl;
+Var
+ SDL_IntersectRect : TSDL_IntersectRect_func = Nil;
+{$else}
+
+function SDL_IntersectRect(const A, B: PSDL_Rect; result: PSDL_Rect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the union of two rectangles.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnionRect_proc = procedure(const A, B: PSDL_Rect; result: PSDL_Rect); cdecl;
+Var
+ SDL_UnionRect : TSDL_UnionRect_proc = Nil;
+{$else}
+
+procedure SDL_UnionRect(const A, B: PSDL_Rect; result: PSDL_Rect); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnionRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate a minimal rectangle enclosing a set of points
+ *
+ * SDL_TRUE if any points were within the clipping rect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_EnclosePoints_func = function(const points: PSDL_Point; count: cint; const clip: PSDL_Rect; result: PSDL_Rect): TSDL_Bool; cdecl;
+Var
+ SDL_EnclosePoints : TSDL_EnclosePoints_func = Nil;
+{$else}
+
+function SDL_EnclosePoints(const points: PSDL_Point; count: cint; const clip: PSDL_Rect; result: PSDL_Rect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EnclosePoints' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the intersection of a rectangle and line segment.
+ *
+ * SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IntersectRectAndLine_func = function(const rect: PSDL_Rect; X1, Y1, X2, Y2: pcint): TSDL_Bool; cdecl;
+Var
+ SDL_IntersectRectAndLine : TSDL_IntersectRectAndLine_func = Nil;
+{$else}
+
+function SDL_IntersectRectAndLine(const rect: PSDL_Rect; X1, Y1, X2, Y2: pcint): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectRectAndLine' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Returns true if point resides inside a rectangle.
+ *}
+function SDL_PointInFRect(const p: PSDL_FPoint; const r: PSDL_FRect): Boolean; Inline;
+
+{**
+ * Returns true if the rectangle has no area.
+ *}
+function SDL_FRectEmpty(const r: PSDL_FRect): Boolean; inline;
+
+{**
+ * Returns true if the two rectangles are equal, within some given epsilon.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+function SDL_FRectEqualsEpsilon(const a, b: PSDL_FRect; const epsilon: cfloat): Boolean; Inline;
+
+{**
+ * Returns true if the two rectangles are equal, using a default epsilon.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+function SDL_FRectEquals(const a, b: PSDL_FRect): Boolean; Inline;
+
+{**
+ * Determine whether two rectangles intersect with float precision.
+ *
+ * If either pointer is NIL the function will return SDL_FALSE.
+ *
+ * \param A an SDL_FRect structure representing the first rectangle
+ * \param B an SDL_FRect structure representing the second rectangle
+ * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *
+ * \sa SDL_IntersectRect
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasIntersectionF_func = function(const a, b: PSDL_FRect): TSDL_Bool; cdecl;
+Var
+ SDL_HasIntersectionF : TSDL_HasIntersectionF_func = Nil;
+{$else}
+
+function SDL_HasIntersectionF(const a, b: PSDL_FRect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasIntersectionF' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the intersection of two rectangles with float precision.
+ *
+ * If `result` is NIL then this function will return SDL_FALSE.
+ *
+ * \param A an SDL_FRect structure representing the first rectangle
+ * \param B an SDL_FRect structure representing the second rectangle
+ * \param result an SDL_FRect structure filled in with the intersection of
+ * rectangles `A` and `B`
+ * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *
+ * \sa SDL_HasIntersectionF
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IntersectFRect_func = function(const a, b: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+Var
+ SDL_IntersectFRect : TSDL_IntersectFRect_func = Nil;
+{$else}
+
+function SDL_IntersectFRect(const a, b: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectFRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the union of two rectangles with float precision.
+ *
+ * \param A an SDL_FRect structure representing the first rectangle
+ * \param B an SDL_FRect structure representing the second rectangle
+ * \param result an SDL_FRect structure filled in with the union of rectangles
+ * `A` and `B`
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnionFRect_func = function(const a, b: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+Var
+ SDL_UnionFRect : TSDL_UnionFRect_func = Nil;
+{$else}
+
+function SDL_UnionFRect(const a, b: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnionFRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate a minimal rectangle enclosing a set of points with float
+ * precision.
+ *
+ * If `clip` is not NIL then only points inside of the clipping rectangle
+ * are considered.
+ *
+ * \param points an array of SDL_FPoint structures representing points to be
+ * enclosed
+ * \param count the number of structures in the `points` array
+ * \param clip an SDL_FRect used for clipping or NIL to enclose all points
+ * \param result an SDL_FRect structure filled in with the minimal enclosing
+ * rectangle
+ * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
+ * points were outside of the clipping rectangle.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_EncloseFPoints_func = function(const points: PSDL_FPoint; count: cint; const clip: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+Var
+ SDL_EncloseFPoints : TSDL_EncloseFPoints_func = Nil;
+{$else}
+
+function SDL_EncloseFPoints(const points: PSDL_FPoint; count: cint; const clip: PSDL_FRect; result: PSDL_FRect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EncloseFPoints' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Calculate the intersection of a rectangle and line segment with float
+ * precision.
+ *
+ * This function is used to clip a line segment to a rectangle. A line segment
+ * contained entirely within the rectangle or that does not intersect will
+ * remain unchanged. A line segment that crosses the rectangle at either or
+ * both ends will be clipped to the boundary of the rectangle and the new
+ * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
+ *
+ * \param rect an SDL_FRect structure representing the rectangle to intersect
+ * \param X1 a pointer to the starting X-coordinate of the line
+ * \param Y1 a pointer to the starting Y-coordinate of the line
+ * \param X2 a pointer to the ending X-coordinate of the line
+ * \param Y2 a pointer to the ending Y-coordinate of the line
+ * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IntersectFRectAndLine_func = function(const rect: PSDL_FRect; X1, Y1, X2, Y2: pcfloat): TSDL_Bool; cdecl;
+Var
+ SDL_IntersectFRectAndLine : TSDL_IntersectFRectAndLine_func = Nil;
+{$else}
+
+function SDL_IntersectFRectAndLine(const rect: PSDL_FRect; X1, Y1, X2, Y2: pcfloat): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectFRectAndLine' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlrenderer.inc b/units/sdl2_for_pascal/sdlrenderer.inc
new file mode 100644
index 0000000..fdd0690
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlrenderer.inc
@@ -0,0 +1,1316 @@
+//from "sdl_renderer.h"
+
+ {**
+ * Flags used when creating a rendering context
+ *}
+const
+ SDL_RENDERER_SOFTWARE = $00000001; {**< The renderer is a software fallback *}
+ SDL_RENDERER_ACCELERATED = $00000002; {**< The renderer uses hardware
+ acceleration *}
+ SDL_RENDERER_PRESENTVSYNC = $00000004; {**< Present is synchronized
+ with the refresh rate *}
+ SDL_RENDERER_TARGETTEXTURE = $00000008; {**< The renderer supports
+ rendering to texture *}
+
+type
+ PPSDL_RendererFlags = ^PSDL_RendererFlags;
+ PSDL_RendererFlags = ^TSDL_RendererFlags;
+ TSDL_RendererFlags = Word;
+
+ {**
+ * Information on the capabilities of a render driver or context.
+ *}
+ PPSDL_RendererInfo = ^PSDL_RendererInfo;
+ PSDL_RendererInfo = ^TSDL_RendererInfo;
+ TSDL_RendererInfo = record
+ name: PAnsiChar; {**< The name of the renderer *}
+ flags: cuint32; {**< Supported ::SDL_RendererFlags *}
+ num_texture_formats: cuint32; {**< The number of available texture formats *}
+ texture_formats: array[0..15] of cuint32; {**< The available texture formats *}
+ max_texture_width: cint32; {**< The maximimum texture width *}
+ max_texture_height: cint32; {**< The maximimum texture height *}
+ end;
+
+ PPSDL_Vertex = ^PSDL_Vertex;
+ PSDL_Vertex = ^TSDL_Vertex;
+ TSDL_Vertex = record
+ position: TSDL_FPoint;
+ color: TSDL_Color;
+ tex_coord: TSDL_FPoint;
+ end;
+
+{**
+ * The scaling mode for a texture.
+ *}
+ PPSDL_ScaleMode = ^PSDL_ScaleMode;
+ PSDL_ScaleMode = ^TSDL_ScaleMode;
+ TSDL_ScaleMode = type cint;
+
+const
+ SDL_ScaleModeNearest = TSDL_ScaleMode(0); {**< nearest pixel sampling *}
+ SDL_ScaleModeLinear = TSDL_ScaleMode(1); {**< linear filtering *}
+ SDL_ScaleModeBest = TSDL_ScaleMode(2); {**< anisotropic filtering *}
+
+ {**
+ * The access pattern allowed for a texture.
+ *}
+type
+ PPSDL_TextureAccess = ^PSDL_TextureAccess;
+ PSDL_TextureAccess = ^TSDL_TextureAccess;
+ TSDL_TextureAccess = type cint;
+
+const
+ SDL_TEXTUREACCESS_STATIC = 0; {**< Changes rarely, not lockable *}
+ SDL_TEXTUREACCESS_STREAMING = 1; {**< Changes frequently, lockable *}
+ SDL_TEXTUREACCESS_TARGET = 2; {**< Texture can be used as a render target *}
+
+type
+ {**
+ * The texture channel modulation used in SDL_RenderCopy().
+ *}
+ PPSDL_TextureModulate = ^PSDL_TextureModulate;
+ PSDL_TextureModulate = ^TSDL_TextureModulate;
+ TSDL_TextureModulate = type cint;
+
+const
+ SDL_TEXTUREMODULATE_NONE = TSDL_TextureModulate(0); {**< No modulation *}
+ SDL_TEXTUREMODULATE_COLOR = TSDL_TextureModulate(1); {**< srcC = srcC * color *}
+ SDL_TEXTUREMODULATE_ALPHA = TSDL_TextureModulate(2); {**< srcA = srcA * alpha *}
+
+type
+ {**
+ * Flip constants for SDL_RenderCopyEx
+ *}
+ PPSDL_RenderFlip = ^PSDL_RenderFlip;
+ PSDL_RenderFlip = ^TSDL_RenderFlip;
+ TSDL_RenderFlip = type cint;
+
+const
+ SDL_FLIP_NONE = TSDL_RenderFlip($0); {**< Do not flip *}
+ SDL_FLIP_HORIZONTAL = TSDL_RenderFlip($1); {**< flip horizontally *}
+ SDL_FLIP_VERTICAL = TSDL_RenderFlip($2); {**< flip vertically *}
+
+type
+ {**
+ * A structure representing rendering state
+ *}
+
+ PPSDL_Renderer = ^PSDL_Renderer;
+ PSDL_Renderer = type Pointer;
+
+ {**
+ * An efficient driver-specific representation of pixel data
+ *}
+ PPSDL_Texture = ^PSDL_Texture;
+ PSDL_Texture = type Pointer;
+
+ {* Function prototypes *}
+
+ {**
+ * Get the number of 2D rendering drivers available for the current
+ * display.
+ *
+ * A render driver is a set of code that handles rendering and texture
+ * management on a particular display. Normally there is only one, but
+ * some drivers may have several available with different capabilities.
+ *
+ * SDL_GetRenderDriverInfo()
+ * SDL_CreateRenderer()
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_GetNumRenderDrivers: cint32 cdecl;
+external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumRenderDrivers' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get information about a specific 2D rendering driver for the current
+ * display.
+ *
+ * index The index of the driver to query information about.
+ * info A pointer to an SDL_RendererInfo struct to be filled with
+ * information on the rendering driver.
+ *
+ * 0 on success, -1 if the index was out of range.
+ *
+ * SDL_CreateRenderer()
+ *}
+function SDL_GetRenderDriverInfo(index: cint32; info: PSDL_RendererInfo): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRenderDriverInfo' {$ENDIF} {$ENDIF};
+
+ {**
+ * Create a window and default renderer
+ *
+ * width The width of the window
+ * height The height of the window
+ * window_flags The flags used to create the window
+ * window A pointer filled with the window, or NULL on error
+ * renderer A pointer filled with the renderer, or NULL on error
+ *
+ * 0 on success, or -1 on error
+ *}
+function SDL_CreateWindowAndRenderer(width: cint32; height: cint32; window_flags: cuint32; window: PPSDL_Window; renderer: PPSDL_Renderer): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateWindowAndRenderer' {$ENDIF} {$ENDIF};
+
+ {**
+ * Create a 2D rendering context for a window.
+ *
+ * window The window where rendering is displayed.
+ * index The index of the rendering driver to initialize, or -1 to
+ * initialize the first one supporting the requested flags.
+ * flags ::SDL_RendererFlags.
+ *
+ * A valid rendering context or NULL if there was an error.
+ *
+ * SDL_CreateSoftwareRenderer()
+ * SDL_GetRendererInfo()
+ * SDL_DestroyRenderer()
+ *}
+function SDL_CreateRenderer(window: PSDL_Window; index: cint32; flags: cuint32): PSDL_Renderer cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateRenderer' {$ENDIF} {$ENDIF};
+
+ {**
+ * Create a 2D software rendering context for a surface.
+ *
+ * surface The surface where rendering is done.
+ *
+ * A valid rendering context or NULL if there was an error.
+ *
+ * SDL_CreateRenderer()
+ * SDL_DestroyRenderer()
+ *}
+function SDL_CreateSoftwareRenderer(surface: PSDL_Surface): PSDL_Renderer cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateSoftwareRenderer' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the renderer associated with a window.
+ *}
+function SDL_GetRenderer(window: PSDL_Window): PSDL_Renderer cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRenderer' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the window associated with a renderer.
+ *}
+function SDL_RenderGetWindow(renderer: PSDL_Renderer): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetWindow' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get information about a rendering context.
+ *}
+function SDL_GetRendererInfo(renderer: PSDL_Renderer; info: PSDL_RendererInfo): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRendererInfo' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the output size of a rendering context.
+ *}
+function SDL_GetRendererOutputSize(renderer: PSDL_Renderer; w: pcint; h: pcint): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRendererOutputSize' {$ENDIF} {$ENDIF};
+
+ {**
+ * Create a texture for a rendering context.
+ *
+ * renderer The renderer.
+ * format The format of the texture.
+ * access One of the enumerated values in ::SDL_TextureAccess.
+ * w The width of the texture in pixels.
+ * h The height of the texture in pixels.
+ *
+ * The created texture is returned, or 0 if no rendering context was
+ * active, the format was unsupported, or the width or height were out
+ * of range.
+ *
+ * SDL_QueryTexture()
+ * SDL_UpdateTexture()
+ * SDL_DestroyTexture()
+ *}
+function SDL_CreateTexture(renderer: PSDL_Renderer; format: cuint32; access: cint32; w: cint32; h: cint32): PSDL_Texture cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateTexture' {$ENDIF} {$ENDIF};
+
+ {**
+ * Create a texture from an existing surface.
+ *
+ * renderer The renderer.
+ * surface The surface containing pixel data used to fill the texture.
+ *
+ * The created texture is returned, or 0 on error.
+ *
+ * The surface is not modified or freed by this function.
+ *
+ * SDL_QueryTexture()
+ * SDL_DestroyTexture()
+ *}
+function SDL_CreateTextureFromSurface(renderer: PSDL_Renderer; surface: PSDL_Surface): PSDL_Texture cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateTextureFromSurface' {$ENDIF} {$ENDIF};
+
+ {**
+ * Query the attributes of a texture
+ *
+ * texture A texture to be queried.
+ * format A pointer filled in with the raw format of the texture. The
+ * actual format may differ, but pixel transfers will use this
+ * format.
+ * access A pointer filled in with the actual access to the texture.
+ * w A pointer filled in with the width of the texture in pixels.
+ * h A pointer filled in with the height of the texture in pixels.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *}
+function SDL_QueryTexture(texture: PSDL_Texture; format: pcuint32; access: pcint; w: pcint; h: pcint): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_QueryTexture' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set an additional color value used in render copy operations.
+ *
+ * texture The texture to update.
+ * r The red color value multiplied into copy operations.
+ * g The green color value multiplied into copy operations.
+ * b The blue color value multiplied into copy operations.
+ *
+ * 0 on success, or -1 if the texture is not valid or color modulation
+ * is not supported.
+ *
+ * SDL_GetTextureColorMod()
+ *}
+function SDL_SetTextureColorMod(texture: PSDL_Texture; r: cuint8; g: cuint8; b: cuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextureColorMod' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the additional color value used in render copy operations.
+ *
+ * texture The texture to query.
+ * r A pointer filled in with the current red color value.
+ * g A pointer filled in with the current green color value.
+ * b A pointer filled in with the current blue color value.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *
+ * SDL_SetTextureColorMod()
+ *}
+function SDL_GetTextureColorMod(texture: PSDL_Texture; r: pcuint8; g: pcuint8; b: pcuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextureColorMod' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set an additional alpha value used in render copy operations.
+ *
+ * texture The texture to update.
+ * alpha The alpha value multiplied into copy operations.
+ *
+ * 0 on success, or -1 if the texture is not valid or alpha modulation
+ * is not supported.
+ *
+ * SDL_GetTextureAlphaMod()
+ *}
+function SDL_SetTextureAlphaMod(texture: PSDL_Texture; alpha: cuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextureAlphaMod' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the additional alpha value used in render copy operations.
+ *
+ * texture The texture to query.
+ * alpha A pointer filled in with the current alpha value.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *
+ * SDL_SetTextureAlphaMod()
+ *}
+function SDL_GetTextureAlphaMod(texture: PSDL_Texture; alpha: pcuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextureAlphaMod' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set the blend mode used for texture copy operations.
+ *
+ * texture The texture to update.
+ * blendMode ::SDL_BlendMode to use for texture blending.
+ *
+ * 0 on success, or -1 if the texture is not valid or the blend mode is
+ * not supported.
+ *
+ * If the blend mode is not supported, the closest supported mode is
+ * chosen.
+ *
+ * SDL_GetTextureBlendMode()
+ *}
+function SDL_SetTextureBlendMode(texture: PSDL_Texture; blendMode: TSDL_BlendMode): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextureBlendMode' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the blend mode used for texture copy operations.
+ *
+ * texture The texture to query.
+ * blendMode A pointer filled in with the current blend mode.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *
+ * SDL_SetTextureBlendMode()
+ *}
+function SDL_GetTextureBlendMode(texture: PSDL_Texture; blendMode: PSDL_BlendMode): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextureBlendMode' {$ENDIF} {$ENDIF};
+
+{**
+ * Set the scale mode used for texture scale operations.
+ * If the scale mode is not supported, the closest supported mode is chosen.
+ *}
+function SDL_SetTextureScaleMode(texture: PSDL_Texture; scaleMode: TSDL_ScaleMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextureScaleMode' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the scale mode used for texture scale operations.
+ *}
+function SDL_GetTextureScaleMode(texture: PSDL_Texture; scaleMode: PSDL_ScaleMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextureScaleMode' {$ENDIF} {$ENDIF};
+
+{**
+ * Associate a user-specified pointer with a texture.
+ *}
+function SDL_SetTextureUserData(texture: PSDL_Texture; userdata: Pointer): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextureUserData' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the user-specified pointer associated with a texture.
+ *}
+function SDL_GetTextureUserData(texture: PSDL_Texture): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextureUserData' {$ENDIF} {$ENDIF};
+
+ {**
+ * Update the given texture rectangle with new pixel data.
+ *
+ * texture The texture to update
+ * rect A pointer to the rectangle of pixels to update, or NULL to
+ * update the entire texture.
+ * pixels The raw pixel data.
+ * pitch The number of bytes between rows of pixel data.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *
+ * This is a fairly slow function.
+ *}
+function SDL_UpdateTexture(texture: PSDL_Texture; rect: PSDL_Rect; pixels: Pointer; pitch: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateTexture' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Lock a portion of the texture for write-only pixel access.
+ *
+ * texture The texture to lock for access, which was created with
+ * SDL_TEXTUREACCESS_STREAMING.
+ * rect A pointer to the rectangle to lock for access. If the rect
+ * is NULL, the entire texture will be locked.
+ * pixels This is filled in with a pointer to the locked pixels,
+ * appropriately offset by the locked area.
+ * pitch This is filled in with the pitch of the locked pixels.
+ *
+ * 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING.
+ *
+ * SDL_UnlockTexture()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockTexture_func = function(texture: PSDL_Texture; const rect: PSDL_Rect; pixels: PPointer; pitch: pcint): cint; cdecl;
+Var
+ SDL_LockTexture : TSDL_LockTexture_func = Nil;
+{$else}
+
+function SDL_LockTexture(texture: PSDL_Texture; const rect: PSDL_Rect; pixels: PPointer; pitch: pcint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockTexture' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Lock a portion of the texture for write-only pixel access.
+ * Expose it as a SDL surface.
+ *
+ * \param texture The texture to lock for access, which was created with
+ * ::SDL_TEXTUREACCESS_STREAMING.
+ * \param rect A pointer to the rectangle to lock for access. If the rect
+ * is NULL, the entire texture will be locked.
+ * \param surface This is filled in with a SDL surface representing the locked area
+ * Surface is freed internally after calling SDL_UnlockTexture or SDL_DestroyTexture.
+ *
+ * \return 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING.
+ *
+ * \sa SDL_UnlockTexture()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockTextureToSurface_func = function(texture: PSDL_Texture; const rect: PSDL_Rect; surface: PPSDL_Surface): cint; cdecl;
+Var
+ SDL_LockTextureToSurface : TSDL_LockTextureToSurface_func = Nil;
+{$else}
+
+function SDL_LockTextureToSurface(texture: PSDL_Texture; const rect: PSDL_Rect; surface: PPSDL_Surface): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockTextureToSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Unlock a texture, uploading the changes to video memory, if needed.
+ *
+ * SDL_LockTexture()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+procedure SDL_UnlockTexture(texture: PSDL_Texture) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockTexture' {$ENDIF} {$ENDIF};
+
+ {**
+ * Determines whether a window supports the use of render targets
+ *
+ * renderer The renderer that will be checked
+ *
+ * SDL_TRUE if supported, SDL_FALSE if not.
+ *}
+function SDL_RenderTargetSupported(renderer: PSDL_Renderer): Boolean cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderTargetSupported' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set a texture as the current rendering target.
+ *
+ * renderer The renderer.
+ * texture The targeted texture, which must be created with the SDL_TEXTUREACCESS_TARGET flag, or NULL for the default render target
+ *
+ * 0 on success, or -1 on error
+ *
+ * SDL_GetRenderTarget()
+ *}
+function SDL_SetRenderTarget(renderer: PSDL_Renderer; texture: PSDL_Texture): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetRenderTarget' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the current render target or NULL for the default render target.
+ *
+ * The current render target
+ *
+ * SDL_SetRenderTarget()
+ *}
+function SDL_GetRenderTarget(renderer: PSDL_Renderer): PSDL_Texture cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRenderTarget' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set device independent resolution for rendering
+ *
+ * renderer The renderer for which resolution should be set.
+ * w The width of the logical resolution
+ * h The height of the logical resolution
+ *
+ * This function uses the viewport and scaling functionality to allow a fixed logical
+ * resolution for rendering, regardless of the actual output resolution. If the actual
+ * output resolution doesn't have the same aspect ratio the output rendering will be
+ * centered within the output display.
+ *
+ * If the output display is a window, mouse events in the window will be filtered
+ * and scaled so they seem to arrive within the logical resolution.
+ *
+ * If this function results in scaling or subpixel drawing by the
+ * rendering backend, it will be handled using the appropriate
+ * quality hints.
+ *
+ * SDL_RenderGetLogicalSize()
+ * SDL_RenderSetScale()
+ * SDL_RenderSetViewport()
+ *}
+function SDL_RenderSetLogicalSize(renderer: PSDL_Renderer; w: cint32; h: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetLogicalSize' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get device independent resolution for rendering
+ *
+ * renderer The renderer from which resolution should be queried.
+ * w A pointer filled with the width of the logical resolution
+ * h A pointer filled with the height of the logical resolution
+ *
+ * SDL_RenderSetLogicalSize()
+ *}
+procedure SDL_RenderGetLogicalSize(renderer: PSDL_Renderer; w: pcint; h: pcint) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetLogicalSize' {$ENDIF} {$ENDIF};
+
+{**
+ * \brief Set whether to force integer scales for resolution-independent rendering
+ *
+ * \param renderer The renderer for which integer scaling should be set.
+ * \param enable Enable or disable integer scaling
+ *
+ * This function restricts the logical viewport to integer values - that is, when
+ * a resolution is between two multiples of a logical size, the viewport size is
+ * rounded down to the lower multiple.
+ *
+ * \sa SDL_RenderSetLogicalSize()
+ *}
+function SDL_RenderSetIntegerScale(renderer: PSDL_Renderer; enable : TSDL_bool): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetIntegerScale' {$ENDIF} {$ENDIF};
+
+{**
+ * \brief Get whether integer scales are forced for resolution-independent rendering
+ *
+ * \param renderer The renderer from which integer scaling should be queried.
+ *
+ * \sa SDL_RenderSetIntegerScale()
+ *}
+function SDL_RenderGetIntegerScale(renderer: PSDL_Renderer): TSDL_bool cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetIntegerScale' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set the drawing area for rendering on the current target.
+ *
+ * renderer The renderer for which the drawing area should be set.
+ * rect The rectangle representing the drawing area, or NULL to set the viewport to the entire target.
+ *
+ * The x,y of the viewport rect represents the origin for rendering.
+ *
+ * 0 on success, or -1 on error
+ *
+ * If the window associated with the renderer is resized, the viewport is automatically reset.
+ *
+ * SDL_RenderGetViewport()
+ * SDL_RenderSetLogicalSize()
+ *}
+function SDL_RenderSetViewport(renderer: PSDL_Renderer; const rect: PSDL_Rect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetViewport' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the drawing area for the current target.
+ *
+ * SDL_RenderSetViewport()
+ *}
+procedure SDL_RenderGetViewport(renderer: PSDL_Renderer; rect: PSDL_Rect) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetViewport' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set the clip rectangle for the current target.
+ *
+ * renderer The renderer for which clip rectangle should be set.
+ * rect A pointer to the rectangle to set as the clip rectangle, or
+ * NULL to disable clipping.
+ *
+ * 0 on success, or -1 on error
+ *
+ * SDL_RenderGetClipRect()
+ *}
+function SDL_RenderSetClipRect(renderer: PSDL_Renderer; rect: PSDL_Rect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetClipRect' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the clip rectangle for the current target.
+ *
+ * renderer The renderer from which clip rectangle should be queried.
+ * rect A pointer filled in with the current clip rectangle, or
+ * an empty rectangle if clipping is disabled.
+ *
+ * SDL_RenderSetClipRect()
+ *}
+procedure SDL_RenderGetClipRect(renderer: PSDL_Renderer; rect: PSDL_Rect) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetClipRect' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * \brief Get whether clipping is enabled on the given renderer.
+ *
+ * \param renderer The renderer from which clip state should be queried.
+ *
+ * \sa SDL_RenderGetClipRect()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderIsClipEnabled_func = function(renderer: PSDL_Renderer): TSDL_Bool; cdecl;
+Var
+ SDL_RenderIsClipEnabled : TSDL_RenderIsClipEnabled_func = Nil;
+{$else}
+
+function SDL_RenderIsClipEnabled(renderer: PSDL_Renderer): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderIsClipEnabled' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the drawing scale for rendering on the current target.
+ *
+ * renderer The renderer for which the drawing scale should be set.
+ * scaleX The horizontal scaling factor
+ * scaleY The vertical scaling factor
+ *
+ * The drawing coordinates are scaled by the x/y scaling factors
+ * before they are used by the renderer. This allows resolution
+ * independent drawing with a single coordinate system.
+ *
+ * If this results in scaling or subpixel drawing by the
+ * rendering backend, it will be handled using the appropriate
+ * quality hints. For best results use integer scaling factors.
+ *
+ * SDL_RenderGetScale()
+ * SDL_RenderSetLogicalSize()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderSetScale(renderer: PSDL_Renderer; scaleX: cfloat; scaleY: cfloat): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetScale' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the drawing scale for the current target.
+ *
+ * renderer The renderer from which drawing scale should be queried.
+ * scaleX A pointer filled in with the horizontal scaling factor
+ * scaleY A pointer filled in with the vertical scaling factor
+ *
+ * SDL_RenderSetScale()
+ *}
+procedure SDL_RenderGetScale(renderer: PSDL_Renderer; scaleX: pcfloat; scaleY: pcfloat) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetScale' {$ENDIF} {$ENDIF};
+
+{**
+ * Get logical coordinates of point in renderer when given real coordinates of
+ * point in window. Logical coordinates will differ from real coordinates when
+ * render is scaled and logical renderer size set.
+ *}
+procedure SDL_RenderWindowToLogical(renderer: PSDL_Renderer; windowX, windowY: cint; logicalX, logicalY: PSingle); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderWindowToLogical' {$ENDIF} {$ENDIF};
+
+{**
+ * Get real coordinates of point in window when given logical coordinates of
+ * point in renderer. Logical coordinates will differ from real coordinate
+ * when render is scaled and logical renderer size set.
+ *}
+procedure SDL_RenderLogicalToWindow(renderer: PSDL_Renderer; logicalX, logicalY: Single; windowX, windowY: Pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderLogicalToWindow' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set the color used for drawing operations (Rect, Line and Clear).
+ *
+ * renderer The renderer for which drawing color should be set.
+ * r The red value used to draw on the rendering target.
+ * g The green value used to draw on the rendering target.
+ * b The blue value used to draw on the rendering target.
+ * a The alpha value used to draw on the rendering target, usually
+ * SDL_ALPHA_OPAQUE (255).
+ *
+ * 0 on success, or -1 on error
+ *}
+function SDL_SetRenderDrawColor(renderer: PSDL_Renderer; r: cuint8; g: cuint8; b: cuint8; a: cuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetRenderDrawColor' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the color used for drawing operations (Rect, Line and Clear).
+ *
+ * renderer The renderer from which drawing color should be queried.
+ * r A pointer to the red value used to draw on the rendering target.
+ * g A pointer to the green value used to draw on the rendering target.
+ * b A pointer to the blue value used to draw on the rendering target.
+ * a A pointer to the alpha value used to draw on the rendering target,
+ * usually SDL_ALPHA_OPAQUE (255).
+ *
+ * 0 on success, or -1 on error
+ *}
+function SDL_GetRenderDrawColor(renderer: PSDL_Renderer; r: pcuint8; g: pcuint8; b: pcuint8; a: pcuint8): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRenderDrawColor' {$ENDIF} {$ENDIF};
+
+ {**
+ * Set the blend mode used for drawing operations (Fill and Line).
+ *
+ * renderer The renderer for which blend mode should be set.
+ * blendMode SDL_BlendMode to use for blending.
+ *
+ * 0 on success, or -1 on error
+ *
+ * If the blend mode is not supported, the closest supported mode is
+ * chosen.
+ *
+ * SDL_GetRenderDrawBlendMode()
+ *}
+function SDL_SetRenderDrawBlendMode(renderer: PSDL_Renderer; blendMode: TSDL_BlendMode): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetRenderDrawBlendMode' {$ENDIF} {$ENDIF};
+
+ {**
+ * Get the blend mode used for drawing operations.
+ *
+ * renderer The renderer from which blend mode should be queried.
+ * blendMode A pointer filled in with the current blend mode.
+ *
+ * 0 on success, or -1 on error
+ *
+ * SDL_SetRenderDrawBlendMode()
+ *}
+function SDL_GetRenderDrawBlendMode(renderer: PSDL_Renderer; blendMode: PSDL_BlendMode): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRenderDrawBlendMode' {$ENDIF} {$ENDIF};
+
+ {**
+ * Clear the current rendering target with the drawing color
+ *
+ * This function clears the entire rendering target, ignoring the viewport.
+ *
+ * 0 on success, or -1 on error
+ *}
+function SDL_RenderClear(renderer: PSDL_Renderer): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderClear' {$ENDIF} {$ENDIF};
+
+ {**
+ * Draw a point on the current rendering target.
+ *
+ * renderer The renderer which should draw a point.
+ * x The x coordinate of the point.
+ * y The y coordinate of the point.
+ *
+ * 0 on success, or -1 on error
+ *}
+function SDL_RenderDrawPoint(renderer: PSDL_Renderer; x: cint32; y: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawPoint' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw a point on the current rendering target.
+ *
+ * renderer The renderer which should draw a point.
+ * x The x coordinate of the point.
+ * y The y coordinate of the point.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawPointF_func = function(renderer: PSDL_Renderer; x, y: single): cint32 cdecl;
+Var
+ SDL_RenderDrawPointF : TSDL_RenderDrawPointF_func = Nil;
+{$else}
+
+function SDL_RenderDrawPointF(renderer: PSDL_Renderer; x, y: single): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawPointF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Draw multiple points on the current rendering target.
+ *
+ * renderer The renderer which should draw multiple points.
+ * points The points to draw
+ * count The number of points to draw
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderDrawPoints(renderer: PSDL_Renderer; points: PSDL_Point; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawPoints' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw multiple points on the current rendering target.
+ *
+ * renderer The renderer which should draw multiple points.
+ * points The points to draw
+ * count The number of points to draw
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawPointsF_func = function(renderer: PSDL_Renderer; points: PSDL_FPoint; count: cint32): cint32 cdecl;
+Var
+ SDL_RenderDrawPointsF : TSDL_RenderDrawPointsF_func = Nil;
+{$else}
+
+function SDL_RenderDrawPointsF(renderer: PSDL_Renderer; points: PSDL_FPoint; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawPointsF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Draw a line on the current rendering target.
+ *
+ * renderer The renderer which should draw a line.
+ * x1 The x coordinate of the start point.
+ * y1 The y coordinate of the start point.
+ * x2 The x coordinate of the end point.
+ * y2 The y coordinate of the end point.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderDrawLine(renderer: PSDL_Renderer; x1: cint32; y1: cint32; x2: cint32; y2: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawLine' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw a line on the current rendering target.
+ *
+ * renderer The renderer which should draw a line.
+ * x1 The x coordinate of the start point.
+ * y1 The y coordinate of the start point.
+ * x2 The x coordinate of the end point.
+ * y2 The y coordinate of the end point.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawLineF_func = function(renderer: PSDL_Renderer; x1, y1, x2, y2: single): cint32 cdecl;
+Var
+ SDL_RenderDrawLineF : TSDL_RenderDrawLineF_func = Nil;
+{$else}
+
+function SDL_RenderDrawLineF(renderer: PSDL_Renderer; x1, y1, x2, y2: single): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawLineF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Draw a series of connected lines on the current rendering target.
+ *
+ * \param renderer The renderer which should draw multiple lines.
+ * \param points The points along the lines
+ * \param count The number of points, drawing count-1 lines
+ *
+ * \return 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderDrawLines(renderer: PSDL_Renderer; points: PSDL_Point; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawLines' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw a series of connected lines on the current rendering target.
+ *
+ * renderer The renderer which should draw multiple lines.
+ * points The points along the lines
+ * count The number of points, drawing count-1 lines
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawLinesF_func = function(renderer: PSDL_Renderer; points: PSDL_FPoint; count: cint32): cint32 cdecl;
+Var
+ SDL_RenderDrawLinesF : TSDL_RenderDrawLinesF_func = Nil;
+{$else}
+
+function SDL_RenderDrawLinesF(renderer: PSDL_Renderer; points: PSDL_FPoint; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawLinesF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Draw a rectangle on the current rendering target.
+ *
+ * renderer The renderer which should draw a rectangle.
+ * rect A pointer to the destination rectangle, or NULL to outline the entire rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderDrawRect(renderer: PSDL_Renderer; rect: PSDL_Rect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawRect' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw a rectangle on the current rendering target.
+ *
+ * renderer The renderer which should draw a rectangle.
+ * rect A pointer to the destination rectangle, or NULL to outline the entire rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawRectF_func = function(renderer: PSDL_Renderer; rect: PSDL_FRect): cint32 cdecl;
+Var
+ SDL_RenderDrawRectF : TSDL_RenderDrawRectF_func = Nil;
+{$else}
+
+function SDL_RenderDrawRectF(renderer: PSDL_Renderer; rect: PSDL_FRect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawRectF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Draw some number of rectangles on the current rendering target.
+ *
+ * renderer The renderer which should draw multiple rectangles.
+ * rects A pointer to an array of destination rectangles.
+ * count The number of rectangles.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderDrawRects(renderer: PSDL_Renderer; rects: PSDL_Rect; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawRects' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Draw some number of rectangles on the current rendering target.
+ *
+ * renderer The renderer which should draw multiple rectangles.
+ * rects A pointer to an array of destination rectangles.
+ * count The number of rectangles.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderDrawRectsF_func = function(renderer: PSDL_Renderer; rects: PSDL_FRect; count: cint32): cint32 cdecl;
+Var
+ SDL_RenderDrawRectsF : TSDL_RenderDrawRectsF_func = Nil;
+{$else}
+
+function SDL_RenderDrawRectsF(renderer: PSDL_Renderer; rects: PSDL_FRect; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderDrawRectsF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill a rectangle on the current rendering target with the drawing color.
+ *
+ * renderer The renderer which should fill a rectangle.
+ * rect A pointer to the destination rectangle, or NULL for the entire
+ * rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderFillRect(renderer: PSDL_Renderer; rect: PSDL_Rect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderFillRect' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Fill a rectangle on the current rendering target with the drawing color.
+ *
+ * renderer The renderer which should fill a rectangle.
+ * rect A pointer to the destination rectangle, or NULL for the entire rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderFillRectF_func = function(renderer: PSDL_Renderer; rect: PSDL_FRect): cint32 cdecl;
+Var
+ SDL_RenderFillRectF : TSDL_RenderFillRectF_func = Nil;
+{$else}
+
+function SDL_RenderFillRectF(renderer: PSDL_Renderer; rect: PSDL_FRect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderFillRectF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill some number of rectangles on the current rendering target with the drawing color.
+ *
+ * renderer The renderer which should fill multiple rectangles.
+ * rects A pointer to an array of destination rectangles.
+ * count The number of rectangles.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderFillRects(renderer: PSDL_Renderer; rects: PSDL_Rect; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderFillRects' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Fill some number of rectangles on the current rendering target with the drawing color.
+ *
+ * renderer The renderer which should fill multiple rectangles.
+ * rects A pointer to an array of destination rectangles.
+ * count The number of rectangles.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderFillRectsF_func = function(renderer: PSDL_Renderer; rects: PSDL_FRect; count: cint32): cint32 cdecl;
+Var
+ SDL_RenderFillRectsF : TSDL_RenderFillRectsF_func = Nil;
+{$else}
+
+function SDL_RenderFillRectsF(renderer: PSDL_Renderer; rects: PSDL_FRect; count: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderFillRectsF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Copy a portion of the texture to the current rendering target.
+ *
+ * renderer The renderer which should copy parts of a texture.
+ * texture The source texture.
+ * srcrect A pointer to the source rectangle, or NULL for the entire
+ * texture.
+ * dstrect A pointer to the destination rectangle, or NULL for the
+ * entire rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderCopy(renderer: PSDL_Renderer; texture: PSDL_Texture; srcrect: PSDL_Rect; dstrect: PSDL_Rect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderCopy' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Copy a portion of the texture to the current rendering target.
+ *
+ * renderer The renderer which should copy parts of a texture.
+ * texture The source texture.
+ * srcrect A pointer to the source rectangle, or NIL for the entire texture.
+ * dstrect A pointer to the destination rectangle, or NIL for the entire rendering target.
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderCopyF_func = function(renderer: PSDL_Renderer; texture: PSDL_Texture; srcrect: PSDL_Rect; dstrect: PSDL_FRect): cint32 cdecl;
+Var
+ SDL_RenderCopyF : TSDL_RenderCopyF_func = Nil;
+{$else}
+
+function SDL_RenderCopyF(renderer: PSDL_Renderer; texture: PSDL_Texture; srcrect: PSDL_Rect; dstrect: PSDL_FRect): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderCopyF' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center
+ *
+ * renderer The renderer which should copy parts of a texture.
+ * texture The source texture.
+ * srcrect A pointer to the source rectangle, or NULL for the entire
+ * texture.
+ * dstrect A pointer to the destination rectangle, or NULL for the
+ * entire rendering target.
+ * angle An angle in degrees that indicates the rotation that will be applied to dstrect
+ * center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done aroud dstrect.w/2, dstrect.h/2)
+ * flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture
+ *
+ * 0 on success, or -1 on error
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderCopyEx(renderer: PSDL_Renderer; texture: PSDL_Texture; const srcrect: PSDL_Rect; dstrect: PSDL_Rect; angle: cdouble; center: PSDL_Point; flip: TSDL_RenderFlip): cint32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderCopyEx' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center
+ *
+ * renderer The renderer which should copy parts of a texture.
+ * texture The source texture.
+ * srcrect A pointer to the source rectangle, or NIL for the entire texture.
+ * dstrect A pointer to the destination rectangle, or NIL for the entire rendering target.
+ * angle An angle in degrees that indicates the rotation that will be applied to dstrect, rotating it in a clockwise direction
+ * center A pointer to a point indicating the point around which dstrect will be rotated (if NIL, rotation will be done around dstrect.w/2, dstrect.h/2).
+ * flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture
+ *
+ * 0 on success, or -1 on error
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderCopyExF_func = function(renderer: PSDL_Renderer; texture: PSDL_Texture; const srcrect: PSDL_Rect; dstrect: PSDL_FRect; angle: cdouble; center: PSDL_FPoint; flip: TSDL_RenderFlip): cint32 cdecl;
+Var
+ SDL_RenderCopyExF : TSDL_RenderCopyExF_func = Nil;
+{$else}
+
+function SDL_RenderCopyExF(renderer: PSDL_Renderer; texture: PSDL_Texture; const srcrect: PSDL_Rect; dstrect: PSDL_FRect; angle: cdouble; center: PSDL_FPoint; flip: TSDL_RenderFlip): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderCopyExF' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Render a list of triangles, optionally using a texture and indices into the
+ * vertex array. Color and alpha modulation is done per vertex.
+ * SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderGeometry(
+ renderer: PSDL_Renderer;
+ texture: PSDL_Texture;
+ Const vertices: PSDL_Vertex; num_vertices: cint;
+ Const indices: Pcint; num_indices: cint
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGeometry' {$ENDIF} {$ENDIF};
+
+{**
+ * Render a list of triangles, optionally using a texture and indices into the
+ * vertex arrays. Color and alpha modulation is done per vertex.
+ * SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored.
+ *}
+function SDL_RenderGeometryRaw(
+ renderer: PSDL_Renderer;
+ texture: PSDL_Texture;
+ Const xy: PSingle; xy_stride: cint;
+ Const color: PSDL_Color; color_stride: cint;
+ Const uv: PSingle; uv_stride: cint;
+ num_vertices: cint;
+ Const indices: Pointer; num_indices, size_indices: cint
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGeometryRaw' {$ENDIF} {$ENDIF};
+
+ {**
+ * Read pixels from the current rendering target.
+ *
+ * renderer The renderer from which pixels should be read.
+ * rect A pointer to the rectangle to read, or NULL for the entire
+ * render target.
+ * format The desired format of the pixel data, or 0 to use the format
+ * of the rendering target
+ * pixels A pointer to be filled in with the pixel data
+ * pitch The pitch of the pixels parameter.
+ *
+ * 0 on success, or -1 if pixel reading is not supported.
+ *
+ * This is a very slow operation, and should not be used frequently.
+ *}
+function SDL_RenderReadPixels(renderer: PSDL_Renderer; rect: PSDL_Rect; format: cuint32; pixels: Pointer; pitch: cint32): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderReadPixels' {$ENDIF} {$ENDIF};
+
+ {**
+ * Update the screen with rendering performed.
+ *}
+procedure SDL_RenderPresent(renderer: PSDL_Renderer) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderPresent' {$ENDIF} {$ENDIF};
+
+ {**
+ * Destroy the specified texture.
+ *
+ * SDL_CreateTexture()
+ * SDL_CreateTextureFromSurface()
+ *}
+procedure SDL_DestroyTexture(texture: PSDL_Texture) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyTexture' {$ENDIF} {$ENDIF};
+
+ {**
+ * Destroy the rendering context for a window and free associated
+ * textures.
+ *
+ * SDL_CreateRenderer()
+ *}
+procedure SDL_DestroyRenderer(renderer: PSDL_Renderer) cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyRenderer' {$ENDIF} {$ENDIF};
+
+{**
+ * Force the rendering context to flush any pending commands to the underlying
+ * rendering API.
+ *
+ * You do not need to (and in fact, shouldn't) call this function unless you
+ * are planning to call into OpenGL/Direct3D/Metal/whatever directly in
+ * addition to using an SDL_Renderer.
+ *
+ * This is for a very-specific case: if you are using SDL's render API, you
+ * asked for a specific renderer backend (OpenGL, Direct3D, etc), you set
+ * SDL_HINT_RENDER_BATCHING to "1", and you plan to make OpenGL/D3D/whatever
+ * calls in addition to SDL render API calls. If all of this applies, you
+ * should call SDL_RenderFlush() between calls to SDL's render API and the
+ * low-level API you're using in cooperation.
+ *
+ * In all other cases, you can ignore this function. This is only here to get
+ * maximum performance out of a specific situation. In all other cases, SDL
+ * will do the right thing, perhaps at a performance loss.
+ *
+ * This function is first available in SDL 2.0.10, and is not needed in 2.0.9
+ * and earlier, as earlier versions did not queue rendering commands at all,
+ * instead flushing them to the OS immediately.
+ *}
+function SDL_RenderFlush(renderer: PSDL_Renderer): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderFlush' {$ENDIF} {$ENDIF};
+
+ {**
+ * Bind the texture to the current OpenGL/ES/ES2 context for use with
+ * OpenGL instructions.
+ *
+ * texture The SDL texture to bind
+ * texw A pointer to a float that will be filled with the texture width
+ * texh A pointer to a float that will be filled with the texture height
+ *
+ * 0 on success, or -1 if the operation is not supported
+ *}
+function SDL_GL_BindTexture(texture: PSDL_Texture; texw: pcfloat; texh: pcfloat): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_BindTexture' {$ENDIF} {$ENDIF};
+
+ {**
+ * Unbind a texture from the current OpenGL/ES/ES2 context.
+ *
+ * texture The SDL texture to unbind
+ *
+ * 0 on success, or -1 if the operation is not supported
+ *}
+function SDL_GL_UnbindTexture(texture: PSDL_Texture): cint32 cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_UnbindTexture' {$ENDIF} {$ENDIF};
+ {$endif}
+{**
+ * Get the CAMetalLayer associated with the given Metal renderer.
+ *
+ * This function returns a raw Pointer, so SDL doesn't have to include Metal's headers,
+ * but it can be safely cast to a pointer to `CAMetalLayer`.
+ *
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderGetMetalLayer_func = function(renderer: PSDL_Renderer): Pointer; cdecl;
+Var
+ SDL_RenderGetMetalLayer : TSDL_RenderGetMetalLayer_func = Nil;
+{$else}
+
+function SDL_RenderGetMetalLayer(renderer: PSDL_Renderer): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetMetalLayer' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the Metal command encoder for the current frame
+ *
+ * This function returns a raw Pointer, so SDL doesn't have to include Metal's headers,
+ * but it can be safely cast to an `id`.
+ *
+ * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give
+ * SDL a drawable to render to, which might happen if the window is
+ * hidden/minimized/offscreen. This doesn't apply to command encoders for
+ * render targets, just the window's backbacker. Check your return values!
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderGetMetalCommandEncoder_func = function(renderer: PSDL_Renderer): Pointer; cdecl;
+Var
+ SDL_RenderGetMetalCommandEncoder : TSDL_RenderGetMetalCommandEncoder_func = Nil;
+{$else}
+
+function SDL_RenderGetMetalCommandEncoder(renderer: PSDL_Renderer): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderGetMetalCommandEncoder' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Toggle VSync of the given renderer.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_RenderSetVSync(renderer: PSDL_Renderer; vsync: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RenderSetVSync' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Update a rectangle within a planar YV12 or IYUV texture with new pixel data.
+ *
+ * texture The texture to update
+ * rect A pointer to the rectangle of pixels to update, or NULL to update the entire texture.
+ * Yplane The raw pixel data for the Y plane.
+ * Ypitch The number of bytes between rows of pixel data for the Y plane.
+ * Uplane The raw pixel data for the U plane.
+ * Upitch The number of bytes between rows of pixel data for the U plane.
+ * Vplane The raw pixel data for the V plane.
+ * Vpitch The number of bytes between rows of pixel data for the V plane.
+ *
+ * 0 on success, or -1 if the texture is not valid.
+ *
+ * You can use SDL_UpdateTexture() as long as your pixel data is
+ * a contiguous block of Y and U/V planes in the proper order, but
+ * this function is available if your pixel data is not contiguous.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UpdateYUVTexture_func = function(texture: PSDL_Texture; rect: PSDL_Rect; Yplane: pcuint8; Ypitch: cint32; Uplane: pcuint8; UPitch: cint32; Vplane: pcuint8; VPitch: cint32):cint32;
+ cdecl;
+Var
+ SDL_UpdateYUVTexture : TSDL_UpdateYUVTexture_func = Nil;
+{$else}
+
+function SDL_UpdateYUVTexture(texture: PSDL_Texture; rect: PSDL_Rect; Yplane: pcuint8; Ypitch: cint32; Uplane: pcuint8; UPitch: cint32; Vplane: pcuint8; VPitch: cint32):cint32;
+ cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateYUVTexture' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Update a rectangle within a planar NV12 or NV21 texture with new pixels.
+ *
+ * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous
+ * block of NV12/21 planes in the proper order, but this function is available
+ * if your pixel data is not contiguous.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+function SDL_UpdateNVTexture(
+ texture: PSDL_Texture;
+ Const rect: PSDL_Rect;
+ Const Yplane: Pcuint8; Ypitch: cint;
+ Const UVplane: Pcuint8; UVpitch: cint
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateNVTexture' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlrwops.inc b/units/sdl2_for_pascal/sdlrwops.inc
new file mode 100644
index 0000000..43ab845
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlrwops.inc
@@ -0,0 +1,503 @@
+//based on "sdl_rwops" (2.0.14)
+
+{**
+ * \file SDL_rwops.h
+ *
+ * This file provides a general interface for SDL to read and write
+ * data streams. It can easily be extended to files, memory, etc.
+ *}
+
+const
+ {* RWops Types *}
+ SDL_RWOPS_UNKNOWN = 0; {* Unknown stream type *}
+ SDL_RWOPS_WINFILE = 1; {* Win32 file *}
+ SDL_RWOPS_STDFILE = 2; {* Stdio file *}
+ SDL_RWOPS_JNIFILE = 3; {* Android asset *}
+ SDL_RWOPS_MEMORY = 4; {* Memory stream *}
+ SDL_RWOPS_MEMORY_RO = 5; {* Read-Only memory stream *}
+
+type
+ PPSDL_RWops = ^PSDL_RWops;
+ PSDL_RWops = ^TSDL_RWops;
+
+ {**
+ * This is the read/write operation structure -- very basic.
+ *}
+
+ {**
+ * Return the size of the file in this rwops, or -1 if unknown
+ *}
+ TSize = function(context: PSDL_RWops): cint64; {$IFNDEF GPC} cdecl; {$ENDIF}
+
+ {**
+ * Seek to offset relative to whence, one of stdio's whence values:
+ * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END
+ *
+ * the final offset in the data stream, or -1 on error.
+ *}
+ TSeek = function(context: PSDL_RWops; offset: cint64; whence: cint): cint64; {$IFNDEF GPC} cdecl; {$ENDIF}
+
+ {**
+ * Read up to maxnum objects each of size size from the data
+ * stream to the area pointed at by ptr.
+ *
+ * the number of objects read, or 0 at error or end of file.
+ *}
+ TRead = function(context: PSDL_RWops; ptr: Pointer; size: csize_t; maxnum: csize_t): csize_t; {$IFNDEF GPC} cdecl; {$ENDIF}
+
+ {**
+ * Write exactly num objects each of size size from the area
+ * pointed at by ptr to data stream.
+ *
+ * the number of objects written, or 0 at error or end of file.
+ *}
+ TWrite = function(context: PSDL_RWops; const ptr: Pointer; size: csize_t; num: csize_t): csize_t; {$IFNDEF GPC} cdecl; {$ENDIF}
+
+ {**
+ * Close and free an allocated SDL_RWops structure.
+ *
+ * 0 if successful or -1 on write error when flushing data.
+ *}
+ TClose = function(context: PSDL_RWops): cint; {$IFNDEF GPC} cdecl; {$ENDIF}
+
+ // (2.0.14) Outdated decl., kept commented just in case.
+ {TAndroidIO = record
+ fileNameRef: Pointer;
+ inputStreamRef: Pointer;
+ readableByteChannelRef: Pointer;
+ readMethod: Pointer;
+ assetFileDescriptorRef: Pointer;
+ position: LongInt;
+ size: LongInt;
+ offset: LongInt;
+ fd: cint32;
+ end;}
+
+ TAndroidIO = record
+ asset: Pointer;
+ end;
+
+ TWindowsIOBuffer = record
+ data: Pointer;
+ size: csize_t;
+ left: csize_t;
+ end;
+
+ TWindowsIO = record
+ append: TSDL_Bool;
+ h: Pointer;
+ buffer: TWindowsIOBuffer;
+ end;
+
+ TStdio = record
+ autoclose: TSDL_Bool;
+ fp: file; // Is this appropriate? C FILE --> Pascal file
+ end;
+
+ TMem = record
+ base: pcuint8;
+ here: pcuint8;
+ stop: pcuint8;
+ end;
+
+ TUnknown = record
+ data1: Pointer;
+ data2: Pointer;
+ end;
+
+ TSDL_RWops = packed record
+ size: TSize;
+ seek: TSeek;
+ read: TRead;
+ write: TWrite;
+ close: TClose;
+
+ _type: cuint32;
+
+ case hidden: cint of
+ {$IFDEF ANDROID}
+ 0: (androidio: TAndroidIO);
+ {$ENDIF}
+ {$IFDEF WINDOWS}
+ 0: (windowsio: TWindowsIO);
+ {$ENDIF}
+ 1: (stdio: TStdio);
+ 2: (mem: TMem);
+ 3: (unknown: TUnknown);
+ end;
+
+{**
+ * RWFrom functions
+ *
+ * Functions to create SDL_RWops structures from various data streams.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWFromFile_func = function(const _file: PAnsiChar; const mode: PAnsiChar): PSDL_RWops; cdecl;
+Var
+ SDL_RWFromFile : TSDL_RWFromFile_func = Nil;
+{$else}
+
+function SDL_RWFromFile(const _file: PAnsiChar; const mode: PAnsiChar): PSDL_RWops; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromFile' {$ENDIF} {$ENDIF};
+{$endif}
+
+{function SDL_RWFromFP(fp: file; autoclose: TSDL_Bool): PSDL_RWops; cdecl;
+ external SDL_LibName;} //don't know if this works
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWFromFP_func = function(fp: Pointer; autoclose: TSDL_Bool): PSDL_RWops; cdecl;
+Var
+ SDL_RWFromFP : TSDL_RWFromFP_func = Nil;
+{$else}
+
+function SDL_RWFromFP(fp: Pointer; autoclose: TSDL_Bool): PSDL_RWops; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromFP' {$ENDIF} {$ENDIF};
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWFromMem_func = function(mem: Pointer; size: cint): PSDL_RWops; cdecl;
+Var
+ SDL_RWFromMem : TSDL_RWFromMem_func = Nil;
+{$else}
+
+function SDL_RWFromMem(mem: Pointer; size: cint): PSDL_RWops; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromMem' {$ENDIF} {$ENDIF};
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWFromConstMem_func = function(const mem: Pointer; size: cint): PSDL_RWops; cdecl;
+Var
+ SDL_RWFromConstMem : TSDL_RWFromConstMem_func = Nil;
+{$else}
+
+function SDL_RWFromConstMem(const mem: Pointer; size: cint): PSDL_RWops; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromConstMem' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*RWFrom functions*}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AllocRW_func =function : PSDL_RWops; cdecl;
+Var
+ SDL_AllocRW : TSDL_AllocRW_func = Nil;
+{$else}
+function SDL_AllocRW: PSDL_RWops; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AllocRW' {$ENDIF} {$ENDIF};
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeRW_proc = procedure(area: PSDL_RWops); cdecl;
+Var
+ SDL_FreeRW : TSDL_FreeRW_proc = Nil;
+{$else}
+
+procedure SDL_FreeRW(area: PSDL_RWops); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeRW' {$ENDIF} {$ENDIF};
+{$endif}
+
+const
+ RW_SEEK_SET = 0; {**< Seek from the beginning of data *}
+ RW_SEEK_CUR = 1; {**< Seek relative to current read point *}
+ RW_SEEK_END = 2; {**< Seek relative to the end of data *}
+
+{**
+ * Return the size of the file in this rwops, or -1 if unknown
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWsize_func = function(context: PSDL_RWops): cint64; cdecl;
+Var
+ SDL_RWsize : TSDL_RWsize_func = Nil;
+{$else}
+
+function SDL_RWsize(context: PSDL_RWops): cint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWsize' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Seek to \c offset relative to \c whence, one of stdio's whence values:
+ * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END
+ *
+ * \return the final offset in the data stream, or -1 on error.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWseek_func = function(context: PSDL_RWops; offset: cint64; whence: cint): cint64; cdecl;
+Var
+ SDL_RWseek : TSDL_RWseek_func = Nil;
+{$else}
+
+function SDL_RWseek(context: PSDL_RWops; offset: cint64; whence: cint): cint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_RWseek' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Return the current offset in the data stream, or -1 on error.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWtell_func = function(context: PSDL_RWops): cint64; cdecl;
+Var
+ SDL_RWtell : TSDL_RWtell_func = Nil;
+{$else}
+
+function SDL_RWtell(context: PSDL_RWops): cint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWtell' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Read up to \c maxnum objects each of size \c size from the data
+ * stream to the area pointed at by \c ptr.
+ *
+ * \return the number of objects read, or 0 at error or end of file.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWread_func = function(context: PSDL_RWops; ptr: Pointer; size: csize_t; n: csize_t): csize_t; cdecl;
+Var
+ SDL_RWread : TSDL_RWread_func = Nil;
+{$else}
+
+function SDL_RWread(context: PSDL_RWops; ptr: Pointer; size: csize_t; n: csize_t): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWread' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Write exactly \c num objects each of size \c size from the area
+ * pointed at by \c ptr to data stream.
+ *
+ * \return the number of objects written, or 0 at error or end of file.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWwrite_func = function(context: PSDL_RWops; ptr: Pointer; size: csize_t; n: csize_t): csize_t; cdecl;
+Var
+ SDL_RWwrite : TSDL_RWwrite_func = Nil;
+{$else}
+
+function SDL_RWwrite(context: PSDL_RWops; ptr: Pointer; size: csize_t; n: csize_t): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWwrite' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Close and free an allocated SDL_RWops structure.
+ *
+ * \return 0 if successful or -1 on write error when flushing data.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RWclose_func = function(context: PSDL_RWops): cint; cdecl;
+Var
+ SDL_RWclose : TSDL_RWclose_func = Nil;
+{$else}
+
+function SDL_RWclose(context: PSDL_RWops): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWclose' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Load all the data from an SDL data stream.
+ *
+ * The data is allocated with a zero byte at the end (null terminated)
+ *
+ * If \c datasize is not NULL, it is filled with the size of the data read.
+ *
+ * If \c freesrc is non-zero, the stream will be closed after being read.
+ *
+ * The data should be freed with SDL_free().
+ *
+ * \return the data, or NULL if there was an error.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadFile_RW_func = function(src: PSDL_RWops; datasize: pcsize_t; freesrc: cint): Pointer; cdecl;
+Var
+ SDL_LoadFile_RW : TSDL_LoadFile_RW_func = Nil;
+{$else}
+
+function SDL_LoadFile_RW(src: PSDL_RWops; datasize: pcsize_t; freesrc: cint): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadFile_RW' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Load an entire file.
+ *
+ * The data is allocated with a zero byte at the end (null terminated)
+ *
+ * If \c datasize is not NULL, it is filled with the size of the data read.
+ *
+ * If \c freesrc is non-zero, the stream will be closed after being read.
+ *
+ * The data should be freed with SDL_free().
+ *
+ * \return the data, or NULL if there was an error.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadFile_func = function(file_: PAnsiChar; datasize: pcsize_t): Pointer; cdecl;
+Var
+ SDL_LoadFile : TSDL_LoadFile_func = Nil;
+{$else}
+
+function SDL_LoadFile(file_: PAnsiChar; datasize: pcsize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadFile' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Read endian functions
+ *
+ * Read an item of the specified endianness and return in native format.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadU8_func = function(src: PSDL_RWops): cuint8; cdecl;
+Var
+ SDL_ReadU8 : TSDL_ReadU8_func = Nil;
+{$else}
+
+function SDL_ReadU8(src: PSDL_RWops): cuint8; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadU8' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadLE16_func = function(src: PSDL_RWops): cuint16; cdecl;
+Var
+ SDL_ReadLE16 : TSDL_ReadLE16_func = Nil;
+{$else}
+
+function SDL_ReadLE16(src: PSDL_RWops): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE16' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadBE16_func = function(src: PSDL_RWops): cuint16; cdecl;
+Var
+ SDL_ReadBE16 : TSDL_ReadBE16_func = Nil;
+{$else}
+
+function SDL_ReadBE16(src: PSDL_RWops): cuint16; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE16' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadLE32_func = function(src: PSDL_RWops): cuint32; cdecl;
+Var
+ SDL_ReadLE32 : TSDL_ReadLE32_func = Nil;
+{$else}
+
+function SDL_ReadLE32(src: PSDL_RWops): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE32' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadBE32_func = function(src: PSDL_RWops): cuint32; cdecl;
+Var
+ SDL_ReadBE32 : TSDL_ReadBE32_func = Nil;
+{$else}
+
+function SDL_ReadBE32(src: PSDL_RWops): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE32' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadLE64_func = function(src: PSDL_RWops): cuint64; cdecl;
+Var
+ SDL_ReadLE64 : TSDL_ReadLE64_func = Nil;
+{$else}
+
+function SDL_ReadLE64(src: PSDL_RWops): cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE64' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ReadBE64_func = function(src: PSDL_RWops): cuint64; cdecl;
+Var
+ SDL_ReadBE64 : TSDL_ReadBE64_func = Nil;
+{$else}
+
+function SDL_ReadBE64(src: PSDL_RWops): cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE64' {$ENDIF} {$ENDIF};
+{$endif}
+{ Read endian functions }
+
+{**
+ * Write endian functions
+ *
+ * Write an item of native format to the specified endianness.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteU8_func = function(dst: PSDL_RWops; value: cuint8): csize_t; cdecl;
+Var
+ SDL_WriteU8 : TSDL_WriteU8_func = Nil;
+{$else}
+
+function SDL_WriteU8(dst: PSDL_RWops; value: cuint8): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteU8' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteLE16_func = function(dst: PSDL_RWops; value: cuint16): csize_t; cdecl;
+Var
+ SDL_WriteLE16 : TSDL_WriteLE16_func = Nil;
+{$else}
+
+function SDL_WriteLE16(dst: PSDL_RWops; value: cuint16): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE16' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteBE16_func = function(dst: PSDL_RWops; value: cuint16): csize_t; cdecl;
+Var
+ SDL_WriteBE16 : TSDL_WriteBE16_func = Nil;
+{$else}
+
+function SDL_WriteBE16(dst: PSDL_RWops; value: cuint16): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE16' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteLE32_func = function(dst: PSDL_RWops; value: cuint32): csize_t; cdecl;
+Var
+ SDL_WriteLE32 : TSDL_WriteLE32_func = Nil;
+{$else}
+
+function SDL_WriteLE32(dst: PSDL_RWops; value: cuint32): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE32' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteBE32_func = function(dst: PSDL_RWops; value: cuint32): csize_t; cdecl;
+Var
+ SDL_WriteBE32 : TSDL_WriteBE32_func = Nil;
+{$else}
+
+function SDL_WriteBE32(dst: PSDL_RWops; value: cuint32): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE32' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteLE64_func = function(dst: PSDL_RWops; value: cuint64): csize_t; cdecl;
+Var
+ SDL_WriteLE64 : TSDL_WriteLE64_func = Nil;
+{$else}
+
+function SDL_WriteLE64(dst: PSDL_RWops; value: cuint64): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE64' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WriteBE64_func = function(dst: PSDL_RWops; value: cuint64): csize_t; cdecl;
+Var
+ SDL_WriteBE64 : TSDL_WriteBE64_func = Nil;
+{$else}
+
+function SDL_WriteBE64(dst: PSDL_RWops; value: cuint64): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE64' {$ENDIF} {$ENDIF};
+{$endif}
+{ Write endian functions }
diff --git a/units/sdl2_for_pascal/sdlscancode.inc b/units/sdl2_for_pascal/sdlscancode.inc
new file mode 100644
index 0000000..13aafe9
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlscancode.inc
@@ -0,0 +1,394 @@
+//from "sdl_scancode.h"
+
+ {**
+ * The SDL keyboard scancode representation.
+ *
+ * Values of this type are used to represent keyboard keys, among other places
+ * in the SDL_Keysym.scancode key.keysym.scancode \endlink field of the
+ * SDL_Event structure.
+ *
+ * The values in this enumeration are based on the USB usage page standard:
+ * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
+ *}
+type
+ PPSDL_ScanCode = ^PSDL_ScanCode;
+ PSDL_ScanCode = ^TSDL_ScanCode;
+ TSDL_ScanCode = type cint;
+
+const
+ SDL_SCANCODE_UNKNOWN = TSDL_ScanCode(0);
+
+ {**
+ * Usage page $07
+ *
+ * These values are from usage page $07 (USB keyboard page).
+ *}
+
+ SDL_SCANCODE_A = TSDL_ScanCode(4);
+ SDL_SCANCODE_B = TSDL_ScanCode(5);
+ SDL_SCANCODE_C = TSDL_ScanCode(6);
+ SDL_SCANCODE_D = TSDL_ScanCode(7);
+ SDL_SCANCODE_E = TSDL_ScanCode(8);
+ SDL_SCANCODE_F = TSDL_ScanCode(9);
+ SDL_SCANCODE_G = TSDL_ScanCode(10);
+ SDL_SCANCODE_H = TSDL_ScanCode(11);
+ SDL_SCANCODE_I = TSDL_ScanCode(12);
+ SDL_SCANCODE_J = TSDL_ScanCode(13);
+ SDL_SCANCODE_K = TSDL_ScanCode(14);
+ SDL_SCANCODE_L = TSDL_ScanCode(15);
+ SDL_SCANCODE_M = TSDL_ScanCode(16);
+ SDL_SCANCODE_N = TSDL_ScanCode(17);
+ SDL_SCANCODE_O = TSDL_ScanCode(18);
+ SDL_SCANCODE_P = TSDL_ScanCode(19);
+ SDL_SCANCODE_Q = TSDL_ScanCode(20);
+ SDL_SCANCODE_R = TSDL_ScanCode(21);
+ SDL_SCANCODE_S = TSDL_ScanCode(22);
+ SDL_SCANCODE_T = TSDL_ScanCode(23);
+ SDL_SCANCODE_U = TSDL_ScanCode(24);
+ SDL_SCANCODE_V = TSDL_ScanCode(25);
+ SDL_SCANCODE_W = TSDL_ScanCode(26);
+ SDL_SCANCODE_X = TSDL_ScanCode(27);
+ SDL_SCANCODE_Y = TSDL_ScanCode(28);
+ SDL_SCANCODE_Z = TSDL_ScanCode(29);
+
+ SDL_SCANCODE_1 = TSDL_ScanCode(30);
+ SDL_SCANCODE_2 = TSDL_ScanCode(31);
+ SDL_SCANCODE_3 = TSDL_ScanCode(32);
+ SDL_SCANCODE_4 = TSDL_ScanCode(33);
+ SDL_SCANCODE_5 = TSDL_ScanCode(34);
+ SDL_SCANCODE_6 = TSDL_ScanCode(35);
+ SDL_SCANCODE_7 = TSDL_ScanCode(36);
+ SDL_SCANCODE_8 = TSDL_ScanCode(37);
+ SDL_SCANCODE_9 = TSDL_ScanCode(38);
+ SDL_SCANCODE_0 = TSDL_ScanCode(39);
+
+ SDL_SCANCODE_RETURN = TSDL_ScanCode(40);
+ SDL_SCANCODE_ESCAPE = TSDL_ScanCode(41);
+ SDL_SCANCODE_BACKSPACE = TSDL_ScanCode(42);
+ SDL_SCANCODE_TAB = TSDL_ScanCode(43);
+ SDL_SCANCODE_SPACE = TSDL_ScanCode(44);
+
+ SDL_SCANCODE_MINUS = TSDL_ScanCode(45);
+ SDL_SCANCODE_EQUALS = TSDL_ScanCode(46);
+ SDL_SCANCODE_LEFTBRACKET = TSDL_ScanCode(47);
+ SDL_SCANCODE_RIGHTBRACKET = TSDL_ScanCode(48);
+ SDL_SCANCODE_BACKSLASH = TSDL_ScanCode(49); {**< Located at the lower left of the return
+ * key on ISO keyboards and at the right end
+ * of the QWERTY row on ANSI keyboards.
+ * Produces REVERSE SOLIDUS (backslash) and
+ * VERTICAL LINE in a US layout; REVERSE
+ * SOLIDUS and VERTICAL LINE in a UK Mac
+ * layout; NUMBER SIGN and TILDE in a UK
+ * Windows layout; DOLLAR SIGN and POUND SIGN
+ * in a Swiss German layout; NUMBER SIGN and
+ * APOSTROPHE in a German layout; GRAVE
+ * ACCENT and POUND SIGN in a French Mac
+ * layout; and ASTERISK and MICRO SIGN in a
+ * French Windows layout.
+ *}
+ SDL_SCANCODE_NONUSHASH = TSDL_ScanCode(50); {**< ISO USB keyboards actually use this code
+ * instead of 49 for the same key; but all
+ * OSes I've seen treat the two codes
+ * identically. So; as an implementor; unless
+ * your keyboard generates both of those
+ * codes and your OS treats them differently;
+ * you should generate SDL_SCANCODE_BACKSLASH
+ * instead of this code. As a user; you
+ * should not rely on this code because SDL
+ * will never generate it with most (all?)
+ * keyboards.
+ *}
+ SDL_SCANCODE_SEMICOLON = TSDL_ScanCode(51);
+ SDL_SCANCODE_APOSTROPHE = TSDL_ScanCode(52);
+ SDL_SCANCODE_GRAVE = TSDL_ScanCode(53); {**< Located in the top left corner (on both ANSI
+ * and ISO keyboards). Produces GRAVE ACCENT and
+ * TILDE in a US Windows layout and in US and UK
+ * Mac layouts on ANSI keyboards; GRAVE ACCENT
+ * and NOT SIGN in a UK Windows layout; SECTION
+ * SIGN and PLUS-MINUS SIGN in US and UK Mac
+ * layouts on ISO keyboards; SECTION SIGN and
+ * DEGREE SIGN in a Swiss German layout (Mac:
+ * only on ISO keyboards); CIRCUMFLEX ACCENT and
+ * DEGREE SIGN in a German layout (Mac: only on
+ * ISO keyboards); SUPERSCRIPT TWO and TILDE in a
+ * French Windows layout; COMMERCIAL AT and
+ * NUMBER SIGN in a French Mac layout on ISO
+ * keyboards; and LESS-THAN SIGN and GREATER-THAN
+ * SIGN in a Swiss German; German; or French Mac
+ * layout on ANSI keyboards.
+ *}
+ SDL_SCANCODE_COMMA = TSDL_ScanCode(54);
+ SDL_SCANCODE_PERIOD = TSDL_ScanCode(55);
+ SDL_SCANCODE_SLASH = TSDL_ScanCode(56);
+
+ SDL_SCANCODE_CAPSLOCK = TSDL_ScanCode(57);
+
+ SDL_SCANCODE_F1 = TSDL_ScanCode(58);
+ SDL_SCANCODE_F2 = TSDL_ScanCode(59);
+ SDL_SCANCODE_F3 = TSDL_ScanCode(60);
+ SDL_SCANCODE_F4 = TSDL_ScanCode(61);
+ SDL_SCANCODE_F5 = TSDL_ScanCode(62);
+ SDL_SCANCODE_F6 = TSDL_ScanCode(63);
+ SDL_SCANCODE_F7 = TSDL_ScanCode(64);
+ SDL_SCANCODE_F8 = TSDL_ScanCode(65);
+ SDL_SCANCODE_F9 = TSDL_ScanCode(66);
+ SDL_SCANCODE_F10 = TSDL_ScanCode(67);
+ SDL_SCANCODE_F11 = TSDL_ScanCode(68);
+ SDL_SCANCODE_F12 = TSDL_ScanCode(69);
+
+ SDL_SCANCODE_PRINTSCREEN = TSDL_ScanCode(70);
+ SDL_SCANCODE_SCROLLLOCK = TSDL_ScanCode(71);
+ SDL_SCANCODE_PAUSE = TSDL_ScanCode(72);
+ SDL_SCANCODE_INSERT = TSDL_ScanCode(73); {**< insert on PC; help on some Mac keyboards (but
+ does send code 73; not 117) *}
+ SDL_SCANCODE_HOME = TSDL_ScanCode(74);
+ SDL_SCANCODE_PAGEUP = TSDL_ScanCode(75);
+ SDL_SCANCODE_DELETE = TSDL_ScanCode(76);
+ SDL_SCANCODE_END = TSDL_ScanCode(77);
+ SDL_SCANCODE_PAGEDOWN = TSDL_ScanCode(78);
+ SDL_SCANCODE_RIGHT = TSDL_ScanCode(79);
+ SDL_SCANCODE_LEFT = TSDL_ScanCode(80);
+ SDL_SCANCODE_DOWN = TSDL_ScanCode(81);
+ SDL_SCANCODE_UP = TSDL_ScanCode(82);
+
+ SDL_SCANCODE_NUMLOCKCLEAR = TSDL_ScanCode(83); {**< num lock on PC; clear on Mac keyboards
+ *}
+ SDL_SCANCODE_KP_DIVIDE = TSDL_ScanCode(84);
+ SDL_SCANCODE_KP_MULTIPLY = TSDL_ScanCode(85);
+ SDL_SCANCODE_KP_MINUS = TSDL_ScanCode(86);
+ SDL_SCANCODE_KP_PLUS = TSDL_ScanCode(87);
+ SDL_SCANCODE_KP_ENTER = TSDL_ScanCode(88);
+ SDL_SCANCODE_KP_1 = TSDL_ScanCode(89);
+ SDL_SCANCODE_KP_2 = TSDL_ScanCode(90);
+ SDL_SCANCODE_KP_3 = TSDL_ScanCode(91);
+ SDL_SCANCODE_KP_4 = TSDL_ScanCode(92);
+ SDL_SCANCODE_KP_5 = TSDL_ScanCode(93);
+ SDL_SCANCODE_KP_6 = TSDL_ScanCode(94);
+ SDL_SCANCODE_KP_7 = TSDL_ScanCode(95);
+ SDL_SCANCODE_KP_8 = TSDL_ScanCode(96);
+ SDL_SCANCODE_KP_9 = TSDL_ScanCode(97);
+ SDL_SCANCODE_KP_0 = TSDL_ScanCode(98);
+ SDL_SCANCODE_KP_PERIOD = TSDL_ScanCode(99);
+
+ SDL_SCANCODE_NONUSBACKSLASH = TSDL_ScanCode(100); {**< This is the additional key that ISO
+ * keyboards have over ANSI ones;
+ * located between left shift and Y.
+ * Produces GRAVE ACCENT and TILDE in a
+ * US or UK Mac layout; REVERSE SOLIDUS
+ * (backslash) and VERTICAL LINE in a
+ * US or UK Windows layout; and
+ * LESS-THAN SIGN and GREATER-THAN SIGN
+ * in a Swiss German; German; or French
+ * layout. *}
+ SDL_SCANCODE_APPLICATION = TSDL_ScanCode(101); {**< windows contextual menu; compose *}
+ SDL_SCANCODE_POWER = TSDL_ScanCode(102); {**< The USB document says this is a status flag;
+ * not a physical key - but some Mac keyboards
+ * do have a power key. *}
+ SDL_SCANCODE_KP_EQUALS = TSDL_ScanCode(103);
+ SDL_SCANCODE_F13 = TSDL_ScanCode(104);
+ SDL_SCANCODE_F14 = TSDL_ScanCode(105);
+ SDL_SCANCODE_F15 = TSDL_ScanCode(106);
+ SDL_SCANCODE_F16 = TSDL_ScanCode(107);
+ SDL_SCANCODE_F17 = TSDL_ScanCode(108);
+ SDL_SCANCODE_F18 = TSDL_ScanCode(109);
+ SDL_SCANCODE_F19 = TSDL_ScanCode(110);
+ SDL_SCANCODE_F20 = TSDL_ScanCode(111);
+ SDL_SCANCODE_F21 = TSDL_ScanCode(112);
+ SDL_SCANCODE_F22 = TSDL_ScanCode(113);
+ SDL_SCANCODE_F23 = TSDL_ScanCode(114);
+ SDL_SCANCODE_F24 = TSDL_ScanCode(115);
+ SDL_SCANCODE_EXECUTE = TSDL_ScanCode(116);
+ SDL_SCANCODE_HELP = TSDL_ScanCode(117); { AL Integrated Help Center }
+ SDL_SCANCODE_MENU = TSDL_ScanCode(118); { Menu (show menu) }
+ SDL_SCANCODE_SELECT = TSDL_ScanCode(119);
+ SDL_SCANCODE_STOP = TSDL_ScanCode(120); { AC Stop }
+ SDL_SCANCODE_AGAIN = TSDL_ScanCode(121); { AC Redo/Repeat }
+ SDL_SCANCODE_UNDO = TSDL_ScanCode(122); { AC Undo }
+ SDL_SCANCODE_CUT = TSDL_ScanCode(123); { AC Cut }
+ SDL_SCANCODE_COPY = TSDL_ScanCode(124); { AC Copy }
+ SDL_SCANCODE_PASTE = TSDL_ScanCode(125); { AC Paste }
+ SDL_SCANCODE_FIND = TSDL_ScanCode(126); { AC Find }
+ SDL_SCANCODE_MUTE = TSDL_ScanCode(127);
+ SDL_SCANCODE_VOLUMEUP = TSDL_ScanCode(128);
+ SDL_SCANCODE_VOLUMEDOWN = TSDL_ScanCode(129);
+ {* not sure whether there's a reason to enable these *}
+ {* SDL_SCANCODE_LOCKINGCAPSLOCK = 130; *}
+ {* SDL_SCANCODE_LOCKINGNUMLOCK = 131; *}
+ {* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132; *}
+ SDL_SCANCODE_KP_COMMA = TSDL_ScanCode(133);
+ SDL_SCANCODE_KP_EQUALSAS400 = TSDL_ScanCode(134);
+
+ SDL_SCANCODE_INTERNATIONAL1 = TSDL_ScanCode(135); {**< used on Asian keyboards; see
+ footnotes in USB doc *}
+ SDL_SCANCODE_INTERNATIONAL2 = TSDL_ScanCode(136);
+ SDL_SCANCODE_INTERNATIONAL3 = TSDL_ScanCode(137); {**< Yen *}
+ SDL_SCANCODE_INTERNATIONAL4 = TSDL_ScanCode(138);
+ SDL_SCANCODE_INTERNATIONAL5 = TSDL_ScanCode(139);
+ SDL_SCANCODE_INTERNATIONAL6 = TSDL_ScanCode(140);
+ SDL_SCANCODE_INTERNATIONAL7 = TSDL_ScanCode(141);
+ SDL_SCANCODE_INTERNATIONAL8 = TSDL_ScanCode(142);
+ SDL_SCANCODE_INTERNATIONAL9 = TSDL_ScanCode(143);
+ SDL_SCANCODE_LANG1 = TSDL_ScanCode(144); {**< Hangul/English toggle *}
+ SDL_SCANCODE_LANG2 = TSDL_ScanCode(145); {**< Hanja conversion *}
+ SDL_SCANCODE_LANG3 = TSDL_ScanCode(146); {**< Katakana *}
+ SDL_SCANCODE_LANG4 = TSDL_ScanCode(147); {**< Hiragana *}
+ SDL_SCANCODE_LANG5 = TSDL_ScanCode(148); {**< Zenkaku/Hankaku *}
+ SDL_SCANCODE_LANG6 = TSDL_ScanCode(149); {**< reserved *}
+ SDL_SCANCODE_LANG7 = TSDL_ScanCode(150); {**< reserved *}
+ SDL_SCANCODE_LANG8 = TSDL_ScanCode(151); {**< reserved *}
+ SDL_SCANCODE_LANG9 = TSDL_ScanCode(152); {**< reserved *}
+
+ SDL_SCANCODE_ALTERASE = TSDL_ScanCode(153); {**< Erase-Eaze *}
+ SDL_SCANCODE_SYSREQ = TSDL_ScanCode(154);
+ SDL_SCANCODE_CANCEL = TSDL_ScanCode(155); { AC Cancel }
+ SDL_SCANCODE_CLEAR = TSDL_ScanCode(156);
+ SDL_SCANCODE_PRIOR = TSDL_ScanCode(157);
+ SDL_SCANCODE_RETURN2 = TSDL_ScanCode(158);
+ SDL_SCANCODE_SEPARATOR = TSDL_ScanCode(159);
+ SDL_SCANCODE_OUT = TSDL_ScanCode(160);
+ SDL_SCANCODE_OPER = TSDL_ScanCode(161);
+ SDL_SCANCODE_CLEARAGAIN = TSDL_ScanCode(162);
+ SDL_SCANCODE_CRSEL = TSDL_ScanCode(163);
+ SDL_SCANCODE_EXSEL = TSDL_ScanCode(164);
+
+ SDL_SCANCODE_KP_00 = TSDL_ScanCode(176);
+ SDL_SCANCODE_KP_000 = TSDL_ScanCode(177);
+ SDL_SCANCODE_THOUSANDSSEPARATOR = TSDL_ScanCode(178);
+ SDL_SCANCODE_DECIMALSEPARATOR = TSDL_ScanCode(179);
+ SDL_SCANCODE_CURRENCYUNIT = TSDL_ScanCode(180);
+ SDL_SCANCODE_CURRENCYSUBUNIT = TSDL_ScanCode(181);
+ SDL_SCANCODE_KP_LEFTPAREN = TSDL_ScanCode(182);
+ SDL_SCANCODE_KP_RIGHTPAREN = TSDL_ScanCode(183);
+ SDL_SCANCODE_KP_LEFTBRACE = TSDL_ScanCode(184);
+ SDL_SCANCODE_KP_RIGHTBRACE = TSDL_ScanCode(185);
+ SDL_SCANCODE_KP_TAB = TSDL_ScanCode(186);
+ SDL_SCANCODE_KP_BACKSPACE = TSDL_ScanCode(187);
+ SDL_SCANCODE_KP_A = TSDL_ScanCode(188);
+ SDL_SCANCODE_KP_B = TSDL_ScanCode(189);
+ SDL_SCANCODE_KP_C = TSDL_ScanCode(190);
+ SDL_SCANCODE_KP_D = TSDL_ScanCode(191);
+ SDL_SCANCODE_KP_E = TSDL_ScanCode(192);
+ SDL_SCANCODE_KP_F = TSDL_ScanCode(193);
+ SDL_SCANCODE_KP_XOR = TSDL_ScanCode(194);
+ SDL_SCANCODE_KP_POWER = TSDL_ScanCode(195);
+ SDL_SCANCODE_KP_PERCENT = TSDL_ScanCode(196);
+ SDL_SCANCODE_KP_LESS = TSDL_ScanCode(197);
+ SDL_SCANCODE_KP_GREATER = TSDL_ScanCode(198);
+ SDL_SCANCODE_KP_AMPERSAND = TSDL_ScanCode(199);
+ SDL_SCANCODE_KP_DBLAMPERSAND = TSDL_ScanCode(200);
+ SDL_SCANCODE_KP_VERTICALBAR = TSDL_ScanCode(201);
+ SDL_SCANCODE_KP_DBLVERTICALBAR = TSDL_ScanCode(202);
+ SDL_SCANCODE_KP_COLON = TSDL_ScanCode(203);
+ SDL_SCANCODE_KP_HASH = TSDL_ScanCode(204);
+ SDL_SCANCODE_KP_SPACE = TSDL_ScanCode(205);
+ SDL_SCANCODE_KP_AT = TSDL_ScanCode(206);
+ SDL_SCANCODE_KP_EXCLAM = TSDL_ScanCode(207);
+ SDL_SCANCODE_KP_MEMSTORE = TSDL_ScanCode(208);
+ SDL_SCANCODE_KP_MEMRECALL = TSDL_ScanCode(209);
+ SDL_SCANCODE_KP_MEMCLEAR = TSDL_ScanCode(210);
+ SDL_SCANCODE_KP_MEMADD = TSDL_ScanCode(211);
+ SDL_SCANCODE_KP_MEMSUBTRACT = TSDL_ScanCode(212);
+ SDL_SCANCODE_KP_MEMMULTIPLY = TSDL_ScanCode(213);
+ SDL_SCANCODE_KP_MEMDIVIDE = TSDL_ScanCode(214);
+ SDL_SCANCODE_KP_PLUSMINUS = TSDL_ScanCode(215);
+ SDL_SCANCODE_KP_CLEAR = TSDL_ScanCode(216);
+ SDL_SCANCODE_KP_CLEARENTRY = TSDL_ScanCode(217);
+ SDL_SCANCODE_KP_BINARY = TSDL_ScanCode(218);
+ SDL_SCANCODE_KP_OCTAL = TSDL_ScanCode(219);
+ SDL_SCANCODE_KP_DECIMAL = TSDL_ScanCode(220);
+ SDL_SCANCODE_KP_HEXADECIMAL = TSDL_ScanCode(221);
+
+ SDL_SCANCODE_LCTRL = TSDL_ScanCode(224);
+ SDL_SCANCODE_LSHIFT = TSDL_ScanCode(225);
+ SDL_SCANCODE_LALT = TSDL_ScanCode(226); {**< alt; option *}
+ SDL_SCANCODE_LGUI = TSDL_ScanCode(227); {**< windows; command (apple); meta *}
+ SDL_SCANCODE_RCTRL = TSDL_ScanCode(228);
+ SDL_SCANCODE_RSHIFT = TSDL_ScanCode(229);
+ SDL_SCANCODE_RALT = TSDL_ScanCode(230); {**< alt gr; option *}
+ SDL_SCANCODE_RGUI = TSDL_ScanCode(231); {**< windows; command (apple); meta *}
+
+ SDL_SCANCODE_MODE = TSDL_ScanCode(257); {**< I'm not sure if this is really not covered
+ * by any of the above; but since there's a
+ * special KMOD_MODE for it I'm adding it here
+ *}
+
+ {**
+ * \name Usage page 0x0C
+ *
+ * These values are mapped from usage page 0x0C (USB consumer page).
+ * See https://usb.org/sites/default/files/hut1_2.pdf
+ *
+ * There are way more keys in the spec than we can represent in the
+ * current scancode range, so pick the ones that commonly come up in
+ * real world usage.
+ */ These values are mapped from usage page $0C (USB consumer page).
+ *}
+
+ SDL_SCANCODE_AUDIONEXT = TSDL_ScanCode(258);
+ SDL_SCANCODE_AUDIOPREV = TSDL_ScanCode(259);
+ SDL_SCANCODE_AUDIOSTOP = TSDL_ScanCode(260);
+ SDL_SCANCODE_AUDIOPLAY = TSDL_ScanCode(261);
+ SDL_SCANCODE_AUDIOMUTE = TSDL_ScanCode(262);
+ SDL_SCANCODE_MEDIASELECT = TSDL_ScanCode(263);
+ SDL_SCANCODE_WWW = TSDL_ScanCode(264);
+ SDL_SCANCODE_MAIL = TSDL_ScanCode(265);
+ SDL_SCANCODE_CALCULATOR = TSDL_ScanCode(266);
+ SDL_SCANCODE_COMPUTER = TSDL_ScanCode(267);
+ SDL_SCANCODE_AC_SEARCH = TSDL_ScanCode(268);
+ SDL_SCANCODE_AC_HOME = TSDL_ScanCode(269);
+ SDL_SCANCODE_AC_BACK = TSDL_ScanCode(270);
+ SDL_SCANCODE_AC_FORWARD = TSDL_ScanCode(271);
+ SDL_SCANCODE_AC_STOP = TSDL_ScanCode(272);
+ SDL_SCANCODE_AC_REFRESH = TSDL_ScanCode(273);
+ SDL_SCANCODE_AC_BOOKMARKS = TSDL_ScanCode(274);
+
+ {**
+ * Walther keys
+ *
+ * These are values that Christian Walther added (for mac keyboard?).
+ *}
+
+ SDL_SCANCODE_BRIGHTNESSDOWN = TSDL_ScanCode(275);
+ SDL_SCANCODE_BRIGHTNESSUP = TSDL_ScanCode(276);
+ SDL_SCANCODE_DISPLAYSWITCH = TSDL_ScanCode(277); {**< display mirroring/dual display
+ switch; video mode switch *}
+ SDL_SCANCODE_KBDILLUMTOGGLE = TSDL_ScanCode(278);
+ SDL_SCANCODE_KBDILLUMDOWN = TSDL_ScanCode(279);
+ SDL_SCANCODE_KBDILLUMUP = TSDL_ScanCode(280);
+ SDL_SCANCODE_EJECT = TSDL_ScanCode(281);
+ SDL_SCANCODE_SLEEP = TSDL_ScanCode(282); { SC System Sleep }
+
+ SDL_SCANCODE_APP1 = TSDL_ScanCode(283);
+ SDL_SCANCODE_APP2 = TSDL_ScanCode(284);
+
+ {**
+ * \name Usage page 0x0C (additional media keys)
+ *
+ * These values are mapped from usage page 0x0C (USB consumer page).
+ *}
+
+ SDL_SCANCODE_AUDIOREWIND = TSDL_ScanCode(285);
+ SDL_SCANCODE_AUDIOFASTFORWARD = TSDL_ScanCode(286);
+
+ {**
+ * \name Mobile keys
+ *
+ * These are values that are often used on mobile phones.
+ *}
+
+ SDL_SCANCODE_SOFTLEFT = TSDL_ScanCode(287); {**< Usually situated below the display on phones and
+ used as a multi-function feature key for selecting
+ a software defined function shown on the bottom left
+ of the display. *}
+ SDL_SCANCODE_SOFTRIGHT = TSDL_ScanCode(288); {**< Usually situated below the display on phones and
+ used as a multi-function feature key for selecting
+ a software defined function shown on the bottom right
+ of the display. *}
+ SDL_SCANCODE_CALL = TSDL_ScanCode(289); {**< Used for accepting phone calls. *}
+ SDL_SCANCODE_ENDCALL = TSDL_ScanCode(290); {**< Used for rejecting phone calls. *}
+
+ {* Add any other keys here. *}
+
+ SDL_NUM_SCANCODES = TSDL_ScanCode(512); {**< not a key, just marks the number of scancodes
+ for array bounds *}
+
diff --git a/units/sdl2_for_pascal/sdlsensor.inc b/units/sdl2_for_pascal/sdlsensor.inc
new file mode 100644
index 0000000..652e467
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlsensor.inc
@@ -0,0 +1,298 @@
+// based on SDL_sensor.h
+
+
+{**
+ * \brief SDL_sensor.h
+ *
+ * In order to use these functions, SDL_Init() must have been called
+ * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system
+ * for sensors, and load appropriate drivers.
+ *}
+type
+ PPSDL_Sensor = ^PSDL_Sensor;
+ PSDL_Sensor = type Pointer;
+
+{**
+ * This is a unique ID for a sensor for the time it is connected to the system,
+ * and is never reused for the lifetime of the application.
+ *
+ * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
+ *}
+type
+ PPSDL_SensorID = ^PSDL_SensorID;
+ PSDL_SensorID = ^TSDL_SensorID;
+ TSDL_SensorID = type cint32;
+
+{**
+ * The different sensors defined by SDL
+ *
+ * Additional sensors may be available, using platform dependent semantics.
+ *
+ * Hare are the additional Android sensors:
+ * https://developer.android.com/reference/android/hardware/SensorEvent.html#values
+ *}
+type
+ PPSDL_SensorType = ^PSDL_SensorType;
+ PSDL_SensorType = ^TSDL_SensorType;
+ TSDL_SensorType = type cint;
+
+const
+ SDL_SENSOR_INVALID = TSDL_SensorType(-1); {**< Returned for an invalid sensor *}
+ SDL_SENSOR_UNKNOWN = TSDL_SensorType(0); {**< Unknown sensor type *}
+ SDL_SENSOR_ACCEL = TSDL_SensorType(1); {**< Accelerometer *}
+ SDL_SENSOR_GYRO = TSDL_SensorType(2); {**< Gyroscope *}
+ SDL_SENSOR_ACCEL_L = TSDL_SensorType(3); {**< Accelerometer for left Joy-Con controller and Wii nunchuk *}
+ SDL_SENSOR_GYRO_L = TSDL_SensorType(4); {**< Gyroscope for left Joy-Con controller *}
+ SDL_SENSOR_ACCEL_R = TSDL_SensorType(5); {**< Accelerometer for right Joy-Con controller *}
+ SDL_SENSOR_GYRO_R = TSDL_SensorType(6); {**< Gyroscope for right Joy-Con controller *}
+
+{**
+ * Accelerometer sensor
+ *
+ * The accelerometer returns the current acceleration in SI meters per
+ * second squared. This measurement includes the force of gravity, so
+ * a device at rest will have an value of SDL_STANDARD_GRAVITY away
+ * from the center of the earth.
+ *
+ * values[0]: Acceleration on the x axis
+ * values[1]: Acceleration on the y axis
+ * values[2]: Acceleration on the z axis
+ *
+ * For phones held in portrait mode and game controllers held in front of you,
+ * the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ *
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ *}
+const
+ SDL_STANDARD_GRAVITY = 9.80665;
+
+{**
+ * Gyroscope sensor
+ *
+ * The gyroscope returns the current rate of rotation in radians per second.
+ * The rotation is positive in the counter-clockwise direction. That is,
+ * an observer looking from a positive location on one of the axes would
+ * see positive rotation on that axis when it appeared to be rotating
+ * counter-clockwise.
+ *
+ * values[0]: Angular speed around the x axis (pitch)
+ * values[1]: Angular speed around the y axis (yaw)
+ * values[2]: Angular speed around the z axis (roll)
+ *
+ * For phones held in portrait mode and game controllers held in front of you,
+ * the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ *
+ * The axis data is not changed when the phone or controller is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ *}
+
+{--- Function prototypes ---}
+
+{**
+ * Locking for multi-threaded access to the sensor API
+ *
+ * If you are using the sensor API or handling events from multiple threads
+ * you should use these locking functions to protect access to the sensors.
+ *
+ * In particular, you are guaranteed that the sensor list won't change, so
+ * the API functions that take a sensor index will be valid, and sensor
+ * events will not be delivered.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *} {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+procedure SDL_LockSensors(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockSensors' {$ENDIF} {$ENDIF};
+procedure SDL_UnlockSensors(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockSensors' {$ENDIF} {$ENDIF};
+
+{**
+ * Count the number of sensors attached to the system right now.
+ *
+ * \returns the number of sensors detected.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_NumSensors(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_NumSensors' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the implementation dependent name of a sensor.
+ *
+ * \param device_index The sensor to obtain name from
+ * \returns the sensor name, or NIL if `device_index` is out of range.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetDeviceName(device_index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetDeviceName' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the type of a sensor.
+ *
+ * \param device_index The sensor to get the type from
+ * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `device_index` is
+ * out of range.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetDeviceType(device_index: cint): TSDL_SensorType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetDeviceType' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the platform dependent type of a sensor.
+ *
+ * \param device_index The sensor to check
+ * \returns the sensor platform dependent type, or -1 if `device_index` is out
+ * of range.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetDeviceNonPortableType(device_index: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetDeviceNonPortableType' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the instance ID of a sensor.
+ *
+ * \param device_index The sensor to get instance id from
+ * \returns the sensor instance ID, or -1 if `device_index` is out of range.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetDeviceInstanceID(device_index: cint): TSDL_SensorID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetDeviceInstanceID' {$ENDIF} {$ENDIF};
+
+{**
+ * Open a sensor for use.
+ *
+ * \param device_index The sensor to open
+ * \returns an SDL_Sensor sensor object, or NIL if an error occurred.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorOpen(device_index: cint): PSDL_Sensor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorOpen' {$ENDIF} {$ENDIF};
+
+{**
+ * Return the SDL_Sensor associated with an instance id.
+ *
+ * \param instance_id The sensor from instance id
+ * \returns an SDL_Sensor object.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorFromInstanceID(instance_id: TSDL_SensorID): PSDL_Sensor; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorFromInstanceID' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the implementation dependent name of a sensor
+ *
+ * \param sensor The SDL_Sensor object
+ * \returns the sensor name, or NIL if `sensor` is NIL.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetName(sensor: PSDL_Sensor): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetName' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the type of a sensor.
+ *
+ * \param sensor The SDL_Sensor object to inspect
+ * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID`
+ * if `sensor` is NIL.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetType(sensor: PSDL_Sensor): TSDL_SensorType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetType' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the platform dependent type of a sensor.
+ *
+ * \param sensor The SDL_Sensor object to inspect
+ * \returns the sensor platform dependent type, or -1 if `sensor` is NIL.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetNonPortableType(sensor: PSDL_Sensor): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetNonPortableType' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the instance ID of a sensor.
+ *
+ * \param sensor The SDL_Sensor object to inspect
+ * \returns the sensor instance ID, or -1 if `sensor` is NIL.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetInstanceID(sensor: PSDL_Sensor): TSDL_SensorID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetInstanceID' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the current state of an opened sensor.
+ *
+ * The number of values and interpretation of the data is sensor dependent.
+ *
+ * \param sensor The SDL_Sensor object to query
+ * \param data A pointer filled with the current sensor state
+ * \param num_values The number of values to write to data
+ * \returns 0 or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+function SDL_SensorGetData(sensor: PSDL_Sensor; data: pcfloat; num_values: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetData' {$ENDIF} {$ENDIF};
+
+{**
+ * Get the current state of an opened sensor with the timestamp of the last
+ * update.
+ *
+ * The number of values and interpretation of the data is sensor dependent.
+ *
+ * \param sensor The SDL_Sensor object to query
+ * \param timestamp A pointer filled with the timestamp in microseconds of the
+ * current sensor reading if available, or 0 if not
+ * \param data A pointer filled with the current sensor state
+ * \param num_values The number of values to write to data
+ * \returns 0 or -1 if an error occurred.
+ *
+ * \since This function is available since SDL 2.26.0.
+ *}
+function SDL_SensorGetDataWithTimestamp(sensor: PSDL_Sensor; timestamp: pcuint64; data: pcfloat; num_values: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorGetDataWithTimestamp' {$ENDIF} {$ENDIF};
+
+{**
+ * Close a sensor previously opened with SDL_SensorOpen().
+ *
+ * \param sensor The SDL_Sensor object to close
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+procedure SDL_SensorClose(sensor: PSDL_Sensor); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorClose' {$ENDIF} {$ENDIF};
+
+{**
+ * Update the current state of the open sensors.
+ *
+ * This is called automatically by the event loop if sensor events are
+ * enabled.
+ *
+ * This needs to be called from the thread that initialized the sensor
+ * subsystem.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+procedure SDL_SensorUpdate(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SensorUpdate' {$ENDIF} {$ENDIF};
+ {$endif}
diff --git a/units/sdl2_for_pascal/sdlshape.inc b/units/sdl2_for_pascal/sdlshape.inc
new file mode 100644
index 0000000..7f15aa7
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlshape.inc
@@ -0,0 +1,161 @@
+// from "sdl_shape.h"
+
+{** SDL_shape.h
+ *
+ * Header file for the shaped window API.
+ *}
+const
+ SDL_NONSHAPEABLE_WINDOW = -1;
+ SDL_INVALID_SHAPE_ARGUMENT = -2;
+ SDL_WINDOW_LACKS_SHAPE = -3;
+
+{**
+ * Create a window that can be shaped with the specified position, dimensions,
+ * and flags.
+ *
+ * \param title The title of the window, in UTF-8 encoding.
+ * \param x The x position of the window, SDL_WINDOWPOS_CENTERED,
+ * or SDL_WINDOWPOS_UNDEFINED.
+ * \param y The y position of the window, SDL_WINDOWPOS_CENTERED,
+ * or SDL_WINDOWPOS_UNDEFINED.
+ * \param w The width of the window.
+ * \param h The height of the window.
+ * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with
+ * any of the following: SDL_WINDOW_OPENGL,
+ * SDL_WINDOW_INPUT_GRABBED, SDL_WINDOW_HIDDEN,
+ * SDL_WINDOW_RESIZABLE, SDL_WINDOW_MAXIMIZED,
+ * SDL_WINDOW_MINIMIZED.
+ * SDL_WINDOW_BORDERLESS is always set,
+ * and SDL_WINDOW_FULLSCREEN is always unset.
+ * \return the window created, or NIL if window creation failed.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_DestroyWindow
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateShapedWindow_func = function(title: PAnsiChar; x: cuint; y: cuint; w: cuint; h: cuint; flags: cuint32): PSDL_Window; cdecl;
+Var
+ SDL_CreateShapedWindow : TSDL_CreateShapedWindow_func = Nil;
+{$else}
+
+function SDL_CreateShapedWindow(title: PAnsiChar; x: cuint; y: cuint; w: cuint; h: cuint; flags: cuint32): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateShapedWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Return whether the given window is a shaped window.
+ *
+ * \param window The window to query for being shaped.
+ * \return SDL_TRUE if the window is a window that can be shaped,
+ * SDL_FALSE if the window is unshaped or NIL.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateShapedWindow
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsShapedWindow_func = function(window: PSDL_Window): TSDL_Bool; cdecl;
+Var
+ SDL_IsShapedWindow : TSDL_IsShapedWindow_func = Nil;
+{$else}
+
+function SDL_IsShapedWindow(window: PSDL_Window): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsShapedWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+type
+ {** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. *}
+ PPWindowShapeMode = ^PWindowShapeMode;
+ PWindowShapeMode = ^TWindowShapeMode;
+ TWindowShapeMode = type Integer;
+
+const
+ {** \brief The default mode, a binarized alpha cutoff of 1. *}
+ ShapeModeDefault = TWindowShapeMode(0);
+ {** \brief A binarized alpha cutoff with a given integer value. *}
+ ShapeModeBinarizeAlpha = TWindowShapeMode(1);
+ {** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. *}
+ ShapeModeReverseBinarizeAlpha = TWindowShapeMode(2);
+ {** \brief A color key is applied. *}
+ ShapeModeColorKey = TWindowShapeMode(3);
+
+function SDL_SHAPEMODEALPHA(mode: TWindowShapeMode): Boolean;
+
+type
+ {** A union containing parameters for shaped windows. *}
+ PPSDL_WindowShapeParams = ^PSDL_WindowShapeParams;
+ PSDL_WindowShapeParams = ^TSDL_WindowShapeParams;
+ TSDL_WindowShapeParams = record
+ case cint of
+ {** a cutoff alpha value for binarization of the window shape's alpha channel. *}
+ 0: (binarizationCutoff: cuint8;);
+ 1: (colorKey: TSDL_Color;);
+ end;
+
+ {** A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. *}
+ PPSDL_WindowShapeMode = ^PSDL_WindowShapeMode;
+ PSDL_WindowShapeMode = ^TSDL_WindowShapeMode;
+ TSDL_WindowShapeMode = record
+ {** The mode of these window-shape parameters. *}
+ mode: TWindowShapeMode;
+ {** Window-shape parameters. *}
+ parameters: TSDL_WindowShapeParams;
+ end;
+
+{**
+ * Set the shape and parameters of a shaped window.
+ *
+ * \param window The shaped window whose parameters should be set.
+ * \param shape A surface encoding the desired shape for the window.
+ * \param shape_mode The parameters to set for the shaped window.
+ * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape
+ * argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does
+ * not reference a valid shaped window.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_WindowShapeMode
+ * \sa SDL_GetShapedWindowMode
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowShape_func = function(window: PSDL_Window; shape: PSDL_Surface; shape_mode: PSDL_WindowShapeMode): cint; cdecl;
+Var
+ SDL_SetWindowShape : TSDL_SetWindowShape_func = Nil;
+{$else}
+
+function SDL_SetWindowShape(window: PSDL_Window; shape: PSDL_Surface; shape_mode: PSDL_WindowShapeMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowShape' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the shape parameters of a shaped window.
+ *
+ * \param window The shaped window whose parameters should be retrieved.
+ * \param shape_mode An empty shape-mode structure to fill, or NIL to check
+ * whether the window has a shape.
+ * \return 0 if the window has a shape and, provided shape_mode was not NIL,
+ * shape_mode has been filled with the mode data,
+ * SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped
+ * window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a
+ * shapeable window currently lacking a shape.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_WindowShapeMode
+ * \sa SDL_SetWindowShape
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetShapedWindowMode_func = function(window: PSDL_Window; shape_mode: PSDL_WindowShapeMode): cint; cdecl;
+Var
+ SDL_GetShapedWindowMode : TSDL_GetShapedWindowMode_func = Nil;
+{$else}
+
+function SDL_GetShapedWindowMode(window: PSDL_Window; shape_mode: PSDL_WindowShapeMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetShapedWindowMode' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlstdinc.inc b/units/sdl2_for_pascal/sdlstdinc.inc
new file mode 100644
index 0000000..b00bf9b
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlstdinc.inc
@@ -0,0 +1,1249 @@
+//types from SDL_stdinc.h
+
+{ SDL-For-Pascal: A lot of the functions are missing. Some functions are useless
+ if working with Pascal (e. g. memory management functions),
+ others could be useful (e. g. math functions).
+
+ TODO: Investigate header file and translate potentially useful functions. }
+
+type
+ PPSDL_Bool = ^PSDL_Bool;
+ PSDL_Bool = ^TSDL_Bool;
+ TSDL_Bool = cbool;
+
+const
+ SDL_FALSE = TSDL_Bool(0);
+ SDL_TRUE = TSDL_Bool(1);
+
+ SDL_MAX_SINT8 = High(cint8);
+ SDL_MIN_SINT8 = Low(cint8);
+
+ SDL_MAX_UINT8 = High(cuint8);
+ SDL_MIN_UINT8 = Low(cuint8);
+
+ SDL_MAX_SINT16 = High(cint16);
+ SDL_MIN_SINT16 = Low(cint16);
+
+ SDL_MAX_UINT16 = High(cuint16);
+ SDL_MIN_UINT16 = Low(cuint16);
+
+ SDL_MAX_SINT32 = High(cint32);
+ SDL_MIN_SINT32 = Low(cint32);
+
+ SDL_MAX_UINT32 = High(cuint32);
+ SDL_MIN_UINT32 = Low(cuint32);
+
+ {$IFDEF Has_Int64}
+ SDL_MAX_SINT64 = High(cint64);
+ SDL_MIN_SINT64 = Low(cint64);
+
+ SDL_MAX_UINT64 = High(cuint64);
+ SDL_MIN_UINT64 = Low(cuint64);
+ {$ELSE}
+ SDL_MAX_SINT64: cuint64 = (hi: SDL_MAX_SINT32; lo: SDL_MAX_UINT32);
+ SDL_MIN_SINT64: cuint64 = (hi: SDL_MIN_SINT32; lo: 0);
+
+ SDL_MAX_UINT64: cuint64 = (hi: SDL_MAX_UINT32; lo: SDL_MAX_UINT32);
+ SDL_MIN_UINT64: cuint64 = (hi: 0; lo: 0);
+ {$ENDIF}
+
+ SDL_FLT_EPSILON = cfloat(1.1920928955078125e-07);
+
+type
+ PPSDL_malloc_func = ^PSDL_malloc_func;
+ PSDL_malloc_func = ^TSDL_malloc_func;
+ TSDL_malloc_func = function(size: csize_t): Pointer; cdecl;
+
+ PPSDL_calloc_func = ^PSDL_calloc_func;
+ PSDL_calloc_func = ^TSDL_calloc_func;
+ TSDL_calloc_func = function(nmemb, size: csize_t): Pointer; cdecl;
+
+ PPSDL_realloc_func = ^PSDL_realloc_func;
+ PSDL_realloc_func = ^TSDL_realloc_func;
+ TSDL_realloc_func = function(mem: Pointer; size: csize_t): Pointer; cdecl;
+
+ PPSDL_free_func = ^PSDL_free_func;
+ PSDL_free_func = ^TSDL_free_func;
+ TSDL_free_func = procedure(mem: Pointer); cdecl;
+
+{**
+ * Get the original set of SDL memory functions
+ *
+ * \since This function is available since SDL 2.24.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetOriginalMemoryFunctions_proc = procedure (
+ malloc_func: PSDL_malloc_func;
+ calloc_func: PSDL_calloc_func;
+ realloc_func: PSDL_realloc_func;
+ free_func: PSDL_free_func
+); cdecl;
+Var
+ SDL_GetOriginalMemoryFunctions : TSDL_GetOriginalMemoryFunctions_proc = Nil;
+
+{$else}
+procedure SDL_GetOriginalMemoryFunctions(
+ malloc_func: PSDL_malloc_func;
+ calloc_func: PSDL_calloc_func;
+ realloc_func: PSDL_realloc_func;
+ free_func: PSDL_free_func
+); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetOriginalMemoryFunctions' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Get the current set of SDL memory functions
+ *
+ * \since This function is available since SDL 2.0.7.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetMemoryFunctions_proc = procedure (
+ malloc_func: PSDL_malloc_func;
+ calloc_func: PSDL_calloc_func;
+ realloc_func: PSDL_realloc_func;
+ free_func: PSDL_free_func
+); cdecl;
+Var
+ SDL_GetMemoryFunctions : TSDL_GetMemoryFunctions_proc = Nil;
+{$else}
+procedure SDL_GetMemoryFunctions(
+ malloc_func: PSDL_malloc_func;
+ calloc_func: PSDL_calloc_func;
+ realloc_func: PSDL_realloc_func;
+ free_func: PSDL_free_func
+); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMemoryFunctions' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Replace SDL's memory allocation functions with a custom set
+ *
+ * \since This function is available since SDL 2.0.7.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetMemoryFunctions_func = function (
+ malloc_func: TSDL_malloc_func;
+ calloc_func: TSDL_calloc_func;
+ realloc_func: TSDL_realloc_func;
+ free_func: TSDL_free_func
+): cint; cdecl;
+
+Var
+ SDL_SetMemoryFunctions : TSDL_SetMemoryFunctions_func = Nil;
+{$else}
+function SDL_SetMemoryFunctions(
+ malloc_func: TSDL_malloc_func;
+ calloc_func: TSDL_calloc_func;
+ realloc_func: TSDL_realloc_func;
+ free_func: TSDL_free_func
+): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetMemoryFunctions' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Get the number of outstanding (unfreed) allocations
+ *
+ * \since This function is available since SDL 2.0.7.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumAllocations_func = function(): cint; cdecl;
+Var
+ SDL_GetNumAllocations : TSDL_GetNumAllocations_func = Nil;
+{$else}
+
+function SDL_GetNumAllocations(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumAllocations' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Allocate a block of memory. The memory is *not* initialized.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Var
+ SDL_malloc : TSDL_malloc_func = Nil;
+{$else}
+
+function SDL_malloc(size: csize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_malloc' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Allocate a block of memory that can fit an array of nmemb elements, each of given size.
+ * The memory is initialized by setting every byte to 0.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Var
+ SDL_calloc : TSDL_calloc_func = Nil;
+{$else}
+
+function SDL_calloc(nmemb, size: csize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_calloc' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Resize a block of memory allocated previously with SDL_malloc() or SDL_calloc().
+ *
+ * The returned pointer may or may not be the same as the original pointer.
+ * If the new size is larger than the old size, any new memory will *not* be initialized.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Var
+ SDL_realloc : TSDL_realloc_func = Nil;
+{$else}
+
+function SDL_realloc(mem: Pointer; size: csize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_realloc' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Free memory returned by functions like SDL_GetBasePath(), SDL_GetPrefPath(), etc.
+ *
+ * Calling SDL_free() on the same pointer twice is undefined behaviour and may cause
+ * your program to crash or behave in unexpected ways.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_free_proc = procedure(mem: Pointer); cdecl;
+Var
+ SDL_free : TSDL_free_proc = Nil;
+{$else}
+
+procedure SDL_free(mem: Pointer); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_free' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+
+{*** --- Character functions --- ***
+
+SDL2-for-Pascal: All comments are added by us and not found in the include file.}
+
+
+(**
+ * Check if the provided ASCII character is an alphabetic character (a letter).
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isalpha_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isalpha : TSDL_isalpha_func = Nil;
+{$else}
+
+function SDL_isalpha(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isalpha' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is an alphanumeric character.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isalnum_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isalnum : TSDL_isalnum_func = Nil;
+{$else}
+
+function SDL_isalnum(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isalnum' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a blank character (a space or a tab).
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isblank_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isblank : TSDL_isblank_func = Nil;
+{$else}
+
+function SDL_isblank(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isblank' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a control character.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iscntrl_func = function(x: cint):cint; cdecl;
+Var
+ SDL_iscntrl : TSDL_iscntrl_func = Nil;
+{$else}
+
+function SDL_iscntrl(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_iscntrl' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a decimal digit.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isdigit_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isdigit : TSDL_isdigit_func = Nil;
+{$else}
+
+function SDL_isdigit(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isdigit' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a hexadecimal digit.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isxdigit_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isxdigit : TSDL_isxdigit_func = Nil;
+{$else}
+
+function SDL_isxdigit(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isxdigit' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is any printable character
+ * which is not a space or an alphanumeric character.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ispunct_func = function(x: cint):cint; cdecl;
+Var
+ SDL_ispunct : TSDL_ispunct_func = Nil;
+{$else}
+
+function SDL_ispunct(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ispunct' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a whitespace character.
+ * This set includes the following characters: space,
+ * form feed (FF), newline/line feed (LF), carriage return (CR),
+ * horizontal tab (HT), vertical tab (VT).
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isspace_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isspace : TSDL_isspace_func = Nil;
+{$else}
+
+function SDL_isspace(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isspace' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is an uppercase letter.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.12.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isupper_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isupper : TSDL_isupper_func = Nil;
+{$else}
+
+function SDL_isupper(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isupper' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a lowercase letter.
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.12.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_islower_func = function(x: cint):cint; cdecl;
+Var
+ SDL_islower : TSDL_islower_func = Nil;
+{$else}
+
+function SDL_islower(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_islower' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a printable character (including space).
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isprint_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isprint : TSDL_isprint_func = Nil;
+{$else}
+
+function SDL_isprint(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isprint' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Check if the provided ASCII character is a printable character (excluding space).
+ *
+ * \returns 1 if the check passes, 0 otherwise.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_isgraph_func = function(x: cint):cint; cdecl;
+Var
+ SDL_isgraph : TSDL_isgraph_func = Nil;
+{$else}
+
+function SDL_isgraph(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_isgraph' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * If the given ASCII character is a lowercase letter, converts it to uppercase.
+ * Otherwise returns the original value.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_toupper_func = function(x: cint):cint; cdecl;
+Var
+ SDL_toupper : TSDL_toupper_func = Nil;
+{$else}
+
+function SDL_toupper(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_toupper' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * If the given ASCII character is an uppercase letter, converts it to lowercase.
+ * Otherwise returns the original value.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_tolower_func = function(x: cint):cint; cdecl;
+Var
+ SDL_tolower : TSDL_tolower_func = Nil;
+{$else}
+
+function SDL_tolower(x: cint):cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_tolower' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+
+(*** --- Math functions --- ***)
+
+
+(**
+ * Calculate the arc cosine of x;
+ * that is, the value (in radians) whose cosine equals x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_acos_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_acos : TSDL_acos_func = Nil;
+{$else}
+
+function SDL_acos(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_acos' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc cosine of x;
+ * that is, the value (in radians) whose cosine equals x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_acosf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_acosf : TSDL_acosf_func = Nil;
+{$else}
+
+function SDL_acosf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_acosf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc sine of x;
+ * that is, the value (in radians) whose sine equals x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_asin_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_asin : TSDL_asin_func = Nil;
+{$else}
+
+function SDL_asin(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_asin' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc sine of x;
+ * that is, the value (in radians) whose sine equals x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_asinf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_asinf : TSDL_asinf_func = Nil;
+{$else}
+
+function SDL_asinf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_asinf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc tangent of x;
+ * that is, the value (in radians) whose tangent equals x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_atan_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_atan : TSDL_atan_func = Nil;
+{$else}
+
+function SDL_atan(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_atan' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc tangent of x;
+ * that is, the value (in radians) whose tangent equals x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_atanf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_atanf : TSDL_atanf_func = Nil;
+{$else}
+
+function SDL_atanf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_atanf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc tangent of y/x, using the signs of the two arguments
+ * to determine the quadrant of the result.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_atan2_func = function(y, x: cdouble): cdouble; cdecl;
+Var
+ SDL_atan2 : TSDL_atan2_func = Nil;
+{$else}
+
+function SDL_atan2(y, x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_atan2' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the arc tangent of y/x, using the signs of the two arguments
+ * to determine the quadrant of the result.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_atan2f_func = function(y, x: cfloat): cfloat; cdecl;
+Var
+ SDL_atan2f : TSDL_atan2f_func = Nil;
+{$else}
+
+function SDL_atan2f(y, x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_atan2f' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the smallest integral value that is not less than x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ceil_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_ceil : TSDL_ceil_func = Nil;
+{$else}
+
+function SDL_ceil(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ceil' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the smallest integral value that is not less than x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ceilf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_ceilf : TSDL_ceilf_func = Nil;
+{$else}
+
+function SDL_ceilf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ceilf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Return a number whose absolute value matches that of x,
+ * but the sign matches that of y.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_copysign_func = function(x, y: cdouble): cdouble; cdecl;
+Var
+ SDL_copysign : TSDL_copysign_func = Nil;
+{$else}
+
+function SDL_copysign(x, y: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_copysign' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Return a number whose absolute value matches that of x,
+ * but the sign matches that of y.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_copysignf_func = function(x, y: cfloat): cfloat; cdecl;
+Var
+ SDL_copysignf : TSDL_copysignf_func = Nil;
+{$else}
+
+function SDL_copysignf(x, y: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_copysignf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the cosine of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_cos_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_cos : TSDL_cos_func = Nil;
+{$else}
+
+function SDL_cos(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_cos' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the cosine of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_cosf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_cosf : TSDL_cosf_func = Nil;
+{$else}
+
+function SDL_cosf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_cosf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the value of e (the base of natural logarithms)
+ * raised to the power of x.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_exp_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_exp : TSDL_exp_func = Nil;
+{$else}
+
+function SDL_exp(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_exp' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the value of e (the base of natural logarithms)
+ * raised to the power of x.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_expf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_expf : TSDL_expf_func = Nil;
+{$else}
+
+function SDL_expf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_expf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the absolute value of x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_fabs_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_fabs : TSDL_fabs_func = Nil;
+{$else}
+
+function SDL_fabs(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_fabs' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the absolute value of x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_fabsf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_fabsf : TSDL_fabsf_func = Nil;
+{$else}
+
+function SDL_fabsf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_fabsf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the largest integral value that is not greater than x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_floor_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_floor : TSDL_floor_func = Nil;
+{$else}
+
+function SDL_floor(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_floor' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the largest integral value that is not greater than x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_floorf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_floorf : TSDL_floorf_func = Nil;
+{$else}
+
+function SDL_floorf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_floorf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the floating-point remainder of dividing x by y.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_fmod_func = function(x, y: cdouble): cdouble; cdecl;
+Var
+ SDL_fmod : TSDL_fmod_func = Nil;
+{$else}
+
+function SDL_fmod(x, y: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_fmod' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the floating-point remainder of dividing x by y.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_fmodf_func = function(x, y: cfloat): cfloat; cdecl;
+Var
+ SDL_fmodf : TSDL_fmodf_func = Nil;
+{$else}
+
+function SDL_fmodf(x, y: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_fmodf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the natural logarithm of x.
+ *
+ * \since This function is available since SDL 2.0.4.
+
+ SDL2-for-Pascal: ATTENTION: The original C name of this function is SDL_log,
+ but since Pascal names are case-insensitive, it is in conflict with SDL_Log (logging function).
+ Hence we decided to rename it.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_nlog_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_nlog : TSDL_nlog_func = Nil;
+{$else}
+
+function SDL_nlog(x: cdouble): cdouble; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_log' {$ELSE} 'SDL_log' {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the natural logarithm of x.
+ *
+ * \since This function is available since SDL 2.0.8.
+
+ SDL2-for-Pascal: ATTENTION: The original C name of this function is SDL_logf,
+ but to be consistent with the renamed SDL_log function (see comment of SDL_nlog
+ for details), we decided to rename it.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_nlogf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_nlogf : TSDL_nlogf_func = Nil;
+{$else}
+
+function SDL_nlogf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName
+ name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_logf' {$ELSE} 'SDL_logf' {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the base 10 logarithm of x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_log10_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_log10 : TSDL_log10_func = Nil;
+{$else}
+
+function SDL_log10(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_log10' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the base 10 logarithm of x.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_log10f_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_log10f : TSDL_log10f_func = Nil;
+{$else}
+
+function SDL_log10f(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_log10f' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integer, away from zero.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_lround_func = function(x: cdouble): clong; cdecl;
+Var
+ SDL_lround : TSDL_lround_func = Nil;
+{$else}
+
+function SDL_lround(x: cdouble): clong; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_lround' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integer, away from zero.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_lroundf_func = function(x: cfloat): clong; cdecl;
+Var
+ SDL_lroundf : TSDL_lroundf_func = Nil;
+{$else}
+
+function SDL_lroundf(x: cfloat): clong; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_lroundf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the value of x raised to the power of y.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_pow_func = function(x, y: cdouble): cdouble; cdecl;
+Var
+ SDL_pow : TSDL_pow_func = Nil;
+{$else}
+
+function SDL_pow(x, y: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_pow' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the value of x raised to the power of y.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_powf_func = function(x, y: cfloat): cfloat; cdecl;
+Var
+ SDL_powf : TSDL_powf_func = Nil;
+{$else}
+
+function SDL_powf(x, y: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_powf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integral value, away from zero.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_round_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_round : TSDL_round_func = Nil;
+{$else}
+
+function SDL_round(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_round' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integral value, away from zero.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_roundf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_roundf : TSDL_roundf_func = Nil;
+{$else}
+
+function SDL_roundf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_roundf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate x multiplied by the floating-point radix to the power of n.
+ * On most systems, the radix is 2, making this equivalent to x*(2**n).
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_scalbn_func = function(x: cdouble; n: cint): cdouble; cdecl;
+Var
+ SDL_scalbn : TSDL_scalbn_func = Nil;
+{$else}
+
+function SDL_scalbn(x: cdouble; n: cint): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_scalbn' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate x multiplied by the floating-point radix to the power of n.
+ * On most systems, the radix is 2, making this equivalent to x*(2**n).
+ *
+ * \since This function is available since SDL 2.0.8.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_scalbnf_func = function(x: cfloat; n: cint): cfloat; cdecl;
+Var
+ SDL_scalbnf : TSDL_scalbnf_func = Nil;
+{$else}
+
+function SDL_scalbnf(x: cfloat; n: cint): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_scalbnf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the sine of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_sin_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_sin : TSDL_sin_func = Nil;
+{$else}
+
+function SDL_sin(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_sin' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the sine of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_sinf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_sinf : TSDL_sinf_func = Nil;
+{$else}
+
+function SDL_sinf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_sinf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the non-negative square root of x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_sqrt_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_sqrt : TSDL_sqrt_func = Nil;
+{$else}
+
+function SDL_sqrt(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_sqrt' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the non-negative square root of x.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_sqrtf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_sqrtf : TSDL_sqrtf_func = Nil;
+{$else}
+
+function SDL_sqrtf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_sqrtf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the tangent of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_tan_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_tan : TSDL_tan_func = Nil;
+{$else}
+
+function SDL_tan(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_tan' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Calculate the tangent of x, where x is given in radians.
+ *
+ * \since This function is available since SDL 2.0.4.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_tanf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_tanf : TSDL_tanf_func = Nil;
+{$else}
+
+function SDL_tanf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_tanf' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integral value, towards zero.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_trunc_func = function(x: cdouble): cdouble; cdecl;
+Var
+ SDL_trunc : TSDL_trunc_func = Nil;
+{$else}
+
+function SDL_trunc(x: cdouble): cdouble; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_trunc' {$ENDIF} {$ENDIF};
+{$endif}
+
+(**
+ * Round to nearest integral value, towards zero.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_truncf_func = function(x: cfloat): cfloat; cdecl;
+Var
+ SDL_truncf : TSDL_truncf_func = Nil;
+{$else}
+
+function SDL_truncf(x: cfloat): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_truncf' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+
+(*** --- iconv functions --- ***)
+
+
+(**
+ * This function converts a string between encodings in one pass, returning a
+ * string that must be freed with SDL_free(), or NIL on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iconv_string_func = function(Const tocode, fromcode, inbuf: PAnsiChar; inbytesleft: csize_t): PAnsiChar; cdecl;
+Var
+ SDL_iconv_string : TSDL_iconv_string_func = Nil;
+{$else}
+
+function SDL_iconv_string(Const tocode, fromcode, inbuf: PAnsiChar; inbytesleft: csize_t): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_iconv_string' {$ENDIF} {$ENDIF};
+{$endif}
+
+// These are macros in the original C headers, we will reimplement them as simple Pascal functions.
+function SDL_iconv_utf8_locale(Const str: PAnsiChar): PAnsiChar; cdecl;
+function SDL_iconv_utf8_ucs2(Const str: PAnsiChar): pcUint16; cdecl;
+function SDL_iconv_utf8_ucs4(Const str: PAnsiChar): pcUint32; cdecl;
+
+(* The SDL implementation of iconv() returns these error codes *)
+const
+ SDL_ICONV_ERROR = csize_t(-1);
+ SDL_ICONV_E2BIG = csize_t(-2);
+ SDL_ICONV_EILSEQ = csize_t(-3);
+ SDL_ICONV_EINVAL = csize_t(-4);
+
+type
+ PSDL_iconv = type Pointer;
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iconv_open_func = function(Const tocode, fromcode: PAnsiChar): PSDL_iconv; cdecl;
+Var
+ SDL_iconv_open : TSDL_iconv_open_func = Nil;
+{$else}
+
+function SDL_iconv_open(Const tocode, fromcode: PAnsiChar): PSDL_iconv; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_iconv_open' {$ENDIF} {$ENDIF};
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iconv_close_func = function(cd: PSDL_iconv): cint; cdecl;
+Var
+ SDL_iconv_close : TSDL_iconv_close_func = Nil;
+{$else}
+
+function SDL_iconv_close(cd: PSDL_iconv): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_iconv_close' {$ENDIF} {$ENDIF};
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iconv_func = function(cd: PSDL_iconv; Const inbuf: PPAnsiChar; inbytesleft: pcsize_t; outbuf: PPAnsiChar; outbytesleft: pcsize_t): csize_t; cdecl;
+Var
+ SDL_iconv : TSDL_iconv_func = Nil;
+{$else}
+
+function SDL_iconv(cd: PSDL_iconv; Const inbuf: PPAnsiChar; inbytesleft: pcsize_t; outbuf: PPAnsiChar; outbytesleft: pcsize_t): csize_t; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_iconv' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlsurface.inc b/units/sdl2_for_pascal/sdlsurface.inc
new file mode 100644
index 0000000..6c320fa
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlsurface.inc
@@ -0,0 +1,853 @@
+//from "sdl_surface.h"
+
+const
+ {**
+ * Surface flags
+ *
+ * These are the currently supported flags for the ::SDL_surface.
+ *
+ * Used internally (read-only).
+ *}
+
+ SDL_SWSURFACE = 0; {**< Just here for compatibility *}
+ SDL_PREALLOC = $00000001; {**< Surface uses preallocated memory *}
+ SDL_RLEACCEL = $00000002; {**< Surface is RLE encoded *}
+ SDL_DONTFREE = $00000004; {**< Surface is referenced internally *}
+ SDL_SIMD_ALIGNED = $00000008; {**< Surface uses aligned memory *}
+
+type
+ {**
+ * A collection of pixels used in software blitting.
+ *
+ * This structure should be treated as read-only, except for \c pixels,
+ * which, if not NULL, contains the raw pixel data for the surface.
+ *}
+ PPSDL_BlitMap = ^PSDL_BlitMap;
+ PSDL_BlitMap = type Pointer;
+
+ PPSDL_Surface = ^PSDL_Surface;
+ PSDL_Surface = ^TSDL_Surface;
+ TSDL_Surface = record
+ flags: cuint32; {**< Read-only *}
+ format: PSDL_PixelFormat; {**< Read-only *}
+ w, h: cint; {**< Read-only *}
+ pitch: cint; {**< Read-only *}
+ pixels: Pointer; {**< Read-write *}
+
+ {** Application data associated with the surface *}
+ userdata: Pointer; {**< Read-write *}
+
+ {** information needed for surfaces requiring locks *}
+ locked: cint; {**< Read-only *}
+ //lock_data: Pointer; {**< Read-only *} // field gone in or before 2.0.14?
+
+ {** list of BlitMap that hold a reference to this surface *}
+ list_blitmap: Pointer; {**< Private *}
+
+ {** clipping information *}
+ clip_rect: TSDL_Rect; {**< Read-only *}
+
+ {** info for fast blit mapping to other surfaces *}
+ map: PSDL_BlitMap; {**< Private *}
+
+ {** Reference count -- used when freeing surface *}
+ refcount: cint; {**< Read-mostly *}
+ end;
+
+// Evaluates to true if the surface needs to be locked before access.
+function SDL_MUSTLOCK(Const S:PSDL_Surface):Boolean;
+
+type
+ {**
+ * The type of function used for surface blitting functions.
+ *}
+ PPSDL_Blit = ^PSDL_Blit;
+ PSDL_Blit = ^TSDL_Blit;
+ TSDL_Blit = function(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint;
+
+type
+ {**
+ * \brief The formula used for converting between YUV and RGB
+ *}
+ TSDL_YUV_CONVERSION_MODE = type Integer;
+
+const
+ SDL_YUV_CONVERSION_JPEG = TSDL_YUV_CONVERSION_MODE(0); {**< Full range JPEG *}
+ SDL_YUV_CONVERSION_BT601 = TSDL_YUV_CONVERSION_MODE(1); {**< BT.601 (the default) *}
+ SDL_YUV_CONVERSION_BT709 = TSDL_YUV_CONVERSION_MODE(2); {**< BT.709 *}
+ SDL_YUV_CONVERSION_AUTOMATIC = TSDL_YUV_CONVERSION_MODE(3); {**< BT.601 for SD content, BT.709 for HD content *}
+
+ {**
+ * Allocate and free an RGB surface.
+ *
+ * If the depth is 4 or 8 bits, an empty palette is allocated for the surface.
+ * If the depth is greater than 8 bits, the pixel format is set using the
+ * flags '[RGB]mask'.
+ *
+ * If the function runs out of memory, it will return NULL.
+ *
+ * \param flags The \c flags are obsolete and should be set to 0.
+ * \param width The width in pixels of the surface to create.
+ * \param height The height in pixels of the surface to create.
+ * \param depth The depth in bits of the surface to create.
+ * \param Rmask The red mask of the surface to create.
+ * \param Gmask The green mask of the surface to create.
+ * \param Bmask The blue mask of the surface to create.
+ * \param Amask The alpha mask of the surface to create.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateRGBSurface_func = function(flags: cuint32; width: cint; height: cint; depth: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): PSDL_Surface; cdecl;
+Var
+ SDL_CreateRGBSurface : TSDL_CreateRGBSurface_func = Nil;
+{$else}
+
+function SDL_CreateRGBSurface(flags: cuint32; width: cint; height: cint; depth: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateRGBSurface' {$ENDIF} {$ENDIF};
+{$endif}
+{* !!! FIXME for 2.1: why does this ask for depth? Format provides that. *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateRGBSurfaceWithFormat_func = function(flags: cuint32; width, height, depth: cint; format: cuint32):PSDL_Surface; cdecl;
+Var
+ SDL_CreateRGBSurfaceWithFormat : TSDL_CreateRGBSurfaceWithFormat_func = Nil;
+{$else}
+
+function SDL_CreateRGBSurfaceWithFormat(flags: cuint32; width, height, depth: cint; format: cuint32):PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateRGBSurfaceWithFormat' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateRGBSurfaceFrom_func = function(pixels: Pointer; width: cint; height: cint; depth: cint; pitch: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): PSDL_Surface; cdecl;
+Var
+ SDL_CreateRGBSurfaceFrom : TSDL_CreateRGBSurfaceFrom_func = Nil;
+{$else}
+
+function SDL_CreateRGBSurfaceFrom(pixels: Pointer; width: cint; height: cint; depth: cint; pitch: cint; Rmask: cuint32; Gmask: cuint32; Bmask: cuint32; Amask: cuint32): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateRGBSurfaceFrom' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateRGBSurfaceWithFormatFrom_func = function(pixels: Pointer; width, height, depth, pitch: cint; format: cuint32):PSDL_Surface; cdecl;
+Var
+ SDL_CreateRGBSurfaceWithFormatFrom : TSDL_CreateRGBSurfaceWithFormatFrom_func = Nil;
+{$else}
+
+function SDL_CreateRGBSurfaceWithFormatFrom(pixels: Pointer; width, height, depth, pitch: cint; format: cuint32):PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateRGBSurfaceWithFormatFrom' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FreeSurface_proc = procedure(surface: PSDL_Surface); cdecl;
+Var
+ SDL_FreeSurface : TSDL_FreeSurface_proc = Nil;
+{$else}
+
+procedure SDL_FreeSurface(surface: PSDL_Surface); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the palette used by a surface.
+ *
+ * 0, or -1 if the surface format doesn't use a palette.
+ *
+ * A single palette can be shared with many surfaces.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetSurfacePalette_func = function(surface: PSDL_Surface; palette: PSDL_Palette): cint; cdecl;
+Var
+ SDL_SetSurfacePalette : TSDL_SetSurfacePalette_func = Nil;
+{$else}
+
+function SDL_SetSurfacePalette(surface: PSDL_Surface; palette: PSDL_Palette): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetSurfacePalette' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Sets up a surface for directly accessing the pixels.
+ *
+ * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write
+ * to and read from surface.pixels, using the pixel format stored in
+ * surface.format. Once you are done accessing the surface, you should
+ * use SDL_UnlockSurface() to release it.
+ *
+ * Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates
+ * to 0, then you can read and write to the surface at any time, and the
+ * pixel format of the surface will not change.
+ *
+ * No operating system or library calls should be made between lock/unlock
+ * pairs, as critical system locks may be held during this time.
+ *
+ * SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked.
+ *
+ * SDL_UnlockSurface()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LockSurface_func = function(surface: PSDL_Surface): cint; cdecl;
+Var
+ SDL_LockSurface : TSDL_LockSurface_func = Nil;
+{$else}
+
+function SDL_LockSurface(surface: PSDL_Surface): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {** SDL_LockSurface() *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UnlockSurface_proc = procedure(surface: PSDL_Surface); cdecl;
+Var
+ SDL_UnlockSurface : TSDL_UnlockSurface_proc = Nil;
+{$else}
+
+procedure SDL_UnlockSurface(surface: PSDL_Surface); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Load a surface from a seekable SDL data stream (memory or file).
+ *
+ * If freesrc is non-zero, the stream will be closed after being read.
+ *
+ * The new surface should be freed with SDL_FreeSurface().
+ *
+ * the new surface, or NULL if there was an error.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LoadBMP_RW_func = function(src: PSDL_RWops; freesrc: cint): PSDL_Surface; cdecl;
+Var
+ SDL_LoadBMP_RW : TSDL_LoadBMP_RW_func = Nil;
+{$else}
+
+function SDL_LoadBMP_RW(src: PSDL_RWops; freesrc: cint): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadBMP_RW' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Load a surface from a file.
+ *
+ * Convenience macro.
+ *}
+
+function SDL_LoadBMP(_file: PAnsiChar): PSDL_Surface;
+
+ {**
+ * Save a surface to a seekable SDL data stream (memory or file).
+ *
+ * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the
+ * BMP directly. Other RGB formats with 8-bit or higher get converted to a
+ * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit
+ * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are
+ * not supported.
+ *
+ * If \c freedst is non-zero, the stream will be closed after being written.
+ *
+ * \return 0 if successful or -1 if there was an error.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SaveBMP_RW_func = function(surface: PSDL_Surface; dst: PSDL_RWops; freedst: cint): cint; cdecl;
+Var
+ SDL_SaveBMP_RW : TSDL_SaveBMP_RW_func = Nil;
+{$else}
+
+function SDL_SaveBMP_RW(surface: PSDL_Surface; dst: PSDL_RWops; freedst: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SaveBMP_RW' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Save a surface to a file.
+ *
+ * Convenience macro.
+ *}
+{ TODO : Check: Why AnsiString instead of PAnsiChar used here? Compare SDL_LoadBMP macro. }
+function SDL_SaveBMP(const surface: PSDL_Surface; const filename:AnsiString): cint;
+
+ {**
+ * Sets the RLE acceleration hint for a surface.
+ *
+ * 0 on success, or -1 if the surface is not valid
+ *
+ * If RLE is enabled, colorkey and alpha blending blits are much faster,
+ * but the surface must be locked before directly accessing the pixels.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetSurfaceRLE_func = function(surface: PSDL_Surface; flag: cint): cint; cdecl;
+Var
+ SDL_SetSurfaceRLE : TSDL_SetSurfaceRLE_func = Nil;
+{$else}
+
+function SDL_SetSurfaceRLE(surface: PSDL_Surface; flag: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetSurfaceRLE' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Returns whether the surface is RLE enabled
+ *
+ * \return SDL_TRUE if the surface is RLE enabled, or SDL_FALSE if the surface is NULL or not RLE enabled
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasSurfaceRLE_func = function(surface: PSDL_Surface): TSDL_Bool; cdecl;
+Var
+ SDL_HasSurfaceRLE : TSDL_HasSurfaceRLE_func = Nil;
+{$else}
+
+ function SDL_HasSurfaceRLE(surface: PSDL_Surface): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSurfaceRLE' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Sets the color key (transparent pixel) in a blittable surface.
+ *
+ * surface The surface to update
+ * flag Non-zero to enable colorkey and 0 to disable colorkey
+ * key The transparent pixel in the native surface format
+ *
+ * 0 on success, or -1 if the surface is not valid
+ *
+ * You can pass SDL_RLEACCEL to enable RLE accelerated blits.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetColorKey_func = function(surface: PSDL_Surface; flag: cint; key: cuint32): cint; cdecl;
+Var
+ SDL_SetColorKey : TSDL_SetColorKey_func = Nil;
+{$else}
+
+function SDL_SetColorKey(surface: PSDL_Surface; flag: cint; key: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetColorKey' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Returns whether the surface has a color key
+ *
+ * \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasColorKey_func = function(surface: PSDL_Surface): TSDL_Bool; cdecl;
+Var
+ SDL_HasColorKey : TSDL_HasColorKey_func = Nil;
+{$else}
+
+function SDL_HasColorKey(surface: PSDL_Surface): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasColorKey' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Gets the color key (transparent pixel) in a blittable surface.
+ *
+ * surface The surface to update
+ * key A pointer filled in with the transparent pixel in the native
+ * surface format
+ *
+ * 0 on success, or -1 if the surface is not valid or colorkey is not
+ * enabled.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetColorKey_func = function(surface: PSDL_Surface; key: pcuint32): cint; cdecl;
+Var
+ SDL_GetColorKey : TSDL_GetColorKey_func = Nil;
+{$else}
+
+function SDL_GetColorKey(surface: PSDL_Surface; key: pcuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetColorKey' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set an additional color value used in blit operations.
+ *
+ * surface The surface to update.
+ * r The red color value multiplied into blit operations.
+ * g The green color value multiplied into blit operations.
+ * b The blue color value multiplied into blit operations.
+ *
+ * 0 on success, or -1 if the surface is not valid.
+ *
+ * SDL_GetSurfaceColorMod()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetSurfaceColorMod_func = function(surface: PSDL_Surface; r: cuint8; g: cuint8; b: cuint8): cint; cdecl;
+Var
+ SDL_SetSurfaceColorMod : TSDL_SetSurfaceColorMod_func = Nil;
+{$else}
+
+function SDL_SetSurfaceColorMod(surface: PSDL_Surface; r: cuint8; g: cuint8; b: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetSurfaceColorMod' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the additional color value used in blit operations.
+ *
+ * surface The surface to query.
+ * r A pointer filled in with the current red color value.
+ * g A pointer filled in with the current green color value.
+ * b A pointer filled in with the current blue color value.
+ *
+ * 0 on success, or -1 if the surface is not valid.
+ *
+ * SDL_SetSurfaceColorMod()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetSurfaceColorMod_func = function(surface: PSDL_Surface; r: pcuint8; g: pcuint8; b: pcuint8): cint; cdecl;
+Var
+ SDL_GetSurfaceColorMod : TSDL_GetSurfaceColorMod_func = Nil;
+{$else}
+
+function SDL_GetSurfaceColorMod(surface: PSDL_Surface; r: pcuint8; g: pcuint8; b: pcuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSurfaceColorMod' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set an additional alpha value used in blit operations.
+ *
+ * surface The surface to update.
+ * alpha The alpha value multiplied into blit operations.
+ *
+ * 0 on success, or -1 if the surface is not valid.
+ *
+ * SDL_GetSurfaceAlphaMod()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetSurfaceAlphaMod_func = function(surface: PSDL_Surface; alpha: cuint8): cint; cdecl;
+Var
+ SDL_SetSurfaceAlphaMod : TSDL_SetSurfaceAlphaMod_func = Nil;
+{$else}
+
+function SDL_SetSurfaceAlphaMod(surface: PSDL_Surface; alpha: cuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetSurfaceAlphaMod' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the additional alpha value used in blit operations.
+ *
+ * surface The surface to query.
+ * alpha A pointer filled in with the current alpha value.
+ *
+ * 0 on success, or -1 if the surface is not valid.
+ *
+ * SDL_SetSurfaceAlphaMod()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetSurfaceAlphaMod_func = function(surface: PSDL_Surface; alpha: pcuint8): cint; cdecl;
+Var
+ SDL_GetSurfaceAlphaMod : TSDL_GetSurfaceAlphaMod_func = Nil;
+{$else}
+
+function SDL_GetSurfaceAlphaMod(surface: PSDL_Surface; alpha: pcuint8): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSurfaceAlphaMod' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the blend mode used for blit operations.
+ *
+ * surface The surface to update.
+ * blendMode ::SDL_BlendMode to use for blit blending.
+ *
+ * 0 on success, or -1 if the parameters are not valid.
+ *
+ * SDL_GetSurfaceBlendMode()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetSurfaceBlendMode_func = function(surface: PSDL_Surface; blendMode: TSDL_BlendMode): cint; cdecl;
+Var
+ SDL_SetSurfaceBlendMode : TSDL_SetSurfaceBlendMode_func = Nil;
+{$else}
+
+function SDL_SetSurfaceBlendMode(surface: PSDL_Surface; blendMode: TSDL_BlendMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetSurfaceBlendMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the blend mode used for blit operations.
+ *
+ * surface The surface to query.
+ * blendMode A pointer filled in with the current blend mode.
+ *
+ * 0 on success, or -1 if the surface is not valid.
+ *
+ * SDL_SetSurfaceBlendMode()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetSurfaceBlendMode_func = function(surface: PSDL_Surface; blendMode: PSDL_BlendMode): cint; cdecl;
+Var
+ SDL_GetSurfaceBlendMode : TSDL_GetSurfaceBlendMode_func = Nil;
+{$else}
+
+function SDL_GetSurfaceBlendMode(surface: PSDL_Surface; blendMode: PSDL_BlendMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSurfaceBlendMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Sets the clipping rectangle for the destination surface in a blit.
+ *
+ * If the clip rectangle is NULL, clipping will be disabled.
+ *
+ * If the clip rectangle doesn't intersect the surface, the function will
+ * return SDL_FALSE and blits will be completely clipped. Otherwise the
+ * function returns SDL_TRUE and blits to the surface will be clipped to
+ * the intersection of the surface area and the clipping rectangle.
+ *
+ * Note that blits are automatically clipped to the edges of the source
+ * and destination surfaces.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetClipRect_func = function(surface: PSDL_Surface; const rect: PSDL_Rect): TSDL_Bool; cdecl;
+Var
+ SDL_SetClipRect : TSDL_SetClipRect_func = Nil;
+{$else}
+
+function SDL_SetClipRect(surface: PSDL_Surface; const rect: PSDL_Rect): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetClipRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Gets the clipping rectangle for the destination surface in a blit.
+ *
+ * rect must be a pointer to a valid rectangle which will be filled
+ * with the correct values.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetClipRect_proc = procedure(surface: PSDL_Surface; rect: PSDL_Rect); cdecl;
+Var
+ SDL_GetClipRect : TSDL_GetClipRect_proc = Nil;
+{$else}
+
+procedure SDL_GetClipRect(surface: PSDL_Surface; rect: PSDL_Rect); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetClipRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+{*
+ * Creates a new surface identical to the existing surface
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DuplicateSurface_func = function(surface: PSDL_Surface): PSDL_Surface; cdecl;
+Var
+ SDL_DuplicateSurface : TSDL_DuplicateSurface_func = Nil;
+{$else}
+
+function SDL_DuplicateSurface(surface: PSDL_Surface): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DuplicateSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Creates a new surface of the specified format, and then copies and maps
+ * the given surface to it so the blit of the converted surface will be as
+ * fast as possible. If this function fails, it returns NULL.
+ *
+ * The flags parameter is passed to SDL_CreateRGBSurface() and has those
+ * semantics. You can also pass SDL_RLEACCEL in the flags parameter and
+ * SDL will try to RLE accelerate colorkey and alpha blits in the resulting
+ * surface.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ConvertSurface_func = function(src: PSDL_Surface; const fmt: PSDL_PixelFormat; flags: cuint32): PSDL_Surface; cdecl;
+Var
+ SDL_ConvertSurface : TSDL_ConvertSurface_func = Nil;
+{$else}
+
+function SDL_ConvertSurface(src: PSDL_Surface; const fmt: PSDL_PixelFormat; flags: cuint32): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertSurface' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ConvertSurfaceFormat_func = function(src: PSDL_Surface; pixel_format: cuint32; flags: cuint32): PSDL_Surface; cdecl;
+Var
+ SDL_ConvertSurfaceFormat : TSDL_ConvertSurfaceFormat_func = Nil;
+{$else}
+
+function SDL_ConvertSurfaceFormat(src: PSDL_Surface; pixel_format: cuint32; flags: cuint32): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertSurfaceFormat' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Copy a block of pixels of one format to another format
+ *
+ * 0 on success, or -1 if there was an error
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ConvertPixels_func = function(width: cint; height: cint; src_format: cuint32; const src: Pointer; src_pitch: cint; dst_format: cuint32; dst: Pointer; dst_pitch: cint): cint; cdecl;
+Var
+ SDL_ConvertPixels : TSDL_ConvertPixels_func = Nil;
+{$else}
+
+function SDL_ConvertPixels(width: cint; height: cint; src_format: cuint32; const src: Pointer; src_pitch: cint; dst_format: cuint32; dst: Pointer; dst_pitch: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertPixels' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Performs a fast fill of the given rectangle with color.
+ *
+ * If rect is NULL, the whole surface will be filled with color.
+ *
+ * The color should be a pixel of the format used by the surface, and
+ * can be generated by the SDL_MapRGB() function.
+ *
+ * 0 on success, or -1 on error.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FillRect_func = function(dst: PSDL_Surface; const rect: PSDL_Rect; color: cuint32): cint; cdecl;
+Var
+ SDL_FillRect : TSDL_FillRect_func = Nil;
+{$else}
+
+function SDL_FillRect(dst: PSDL_Surface; const rect: PSDL_Rect; color: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FillRect' {$ENDIF} {$ENDIF};
+{$endif}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FillRects_func = function(dst: PSDL_Surface; const rects: PSDL_Rect; count: cint; color: cuint32): cint; cdecl;
+Var
+ SDL_FillRects : TSDL_FillRects_func = Nil;
+{$else}
+
+function SDL_FillRects(dst: PSDL_Surface; const rects: PSDL_Rect; count: cint; color: cuint32): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FillRects' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Performs a fast blit from the source surface to the destination surface.
+ *
+ * This assumes that the source and destination rectangles are
+ * the same size. If either \c srcrect or \c dstrect are NULL, the entire
+ * surface ( src or dst) is copied. The final blit rectangles are saved
+ * in srcrect and dstrect after all clipping is performed.
+ *
+ * If the blit is successful, it returns 0, otherwise it returns -1.
+ *
+ * The blit function should not be called on a locked surface.
+ *
+ * The blit semantics for surfaces with and without alpha and colorkey
+ * are defined as follows:
+ *
+ RGBA->RGB:
+ SDL_SRCALPHA set:
+ alpha-blend (using alpha-channel).
+ SDL_SRCCOLORKEY ignored.
+ SDL_SRCALPHA not set:
+ copy RGB.
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ RGB values of the source colour key, ignoring alpha in the
+ comparison.
+
+ RGB->RGBA:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source per-surface alpha value);
+ set destination alpha to opaque.
+ SDL_SRCALPHA not set:
+ copy RGB, set destination alpha to source per-surface alpha value.
+ both:
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ source colour key.
+
+ RGBA->RGBA:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source alpha channel) the RGB values;
+ leave destination alpha untouched. [Note: is this correct?]
+ SDL_SRCCOLORKEY ignored.
+ SDL_SRCALPHA not set:
+ copy all of RGBA to the destination.
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ RGB values of the source colour key, ignoring alpha in the
+ comparison.
+
+ RGB->RGB:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source per-surface alpha value).
+ SDL_SRCALPHA not set:
+ copy RGB.
+ both:
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ source colour key.r
+ *
+ * You should call SDL_BlitSurface() unless you know exactly how SDL
+ * blitting works internally and how to use the other blit functions.
+ *}
+
+(* SDL_surface.h uses #define to change all SDL_BlitSurface() calls into SDL_UpperBlit() calls. *
+ * Since Pascal macro support is very limited, we workaround by outright pointing SDL_BlitSurface() to SDL_UpperBlit(). *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_BlitSurface_func = function(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_BlitSurface : TSDL_BlitSurface_func = Nil;
+{$else}
+
+function SDL_BlitSurface(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_UpperBlit' {$ELSE} 'SDL_UpperBlit' {$IFEND};
+{$endif}
+
+
+ {**
+ * This is the public blit function, SDL_BlitSurface(), and it performs
+ * rectangle validation and clipping before passing it to SDL_LowerBlit()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UpperBlit_func = function(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_UpperBlit : TSDL_UpperBlit_func = Nil;
+{$else}
+
+function SDL_UpperBlit(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpperBlit' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * This is a semi-private blit function and it performs low-level surface
+ * blitting only.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LowerBlit_func = function(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_LowerBlit : TSDL_LowerBlit_func = Nil;
+{$else}
+
+function SDL_LowerBlit(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LowerBlit' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Perform a fast, low quality, stretch blit between two surfaces of the
+ * same pixel format.
+ *
+ * This function uses a static buffer, and is not thread-safe.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SoftStretch_func = function(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; const dstrect: PSDL_Surface): cint; cdecl;
+Var
+ SDL_SoftStretch : TSDL_SoftStretch_func = Nil;
+{$else}
+
+function SDL_SoftStretch(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; const dstrect: PSDL_Surface): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SoftStretch' {$ENDIF} {$ENDIF};
+{$endif}
+
+(* SDL_surface.h uses #define to change all SDL_BlitSurfaceScaled() calls into SDL_UpperBlitScaled() calls. *
+ * Since Pascal macro support is very limited, we workaround by outright pointing SDL_BlitSurfaceScaled() to SDL_UpperBlitScaled(). *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_BlitSurfaceScaled_func = function(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_BlitSurfaceScaled : TSDL_BlitSurfaceScaled_func = Nil;
+{$else}
+
+function SDL_BlitSurfaceScaled(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName name {$IF DEFINED(DELPHI) AND DEFINED(MACOS)} '_SDL_UpperBlitScaled' {$ELSE} 'SDL_UpperBlitScaled' {$IFEND};
+{$endif}
+
+ {**
+ * This is the public scaled blit function, SDL_BlitScaled(), and it performs
+ * rectangle validation and clipping before passing it to SDL_LowerBlitScaled()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UpperBlitScaled_func = function(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_UpperBlitScaled : TSDL_UpperBlitScaled_func = Nil;
+{$else}
+
+function SDL_UpperBlitScaled(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpperBlitScaled' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * This is a semi-private blit function and it performs low-level surface
+ * scaled blitting only.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LowerBlitScaled_func = function(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_LowerBlitScaled : TSDL_LowerBlitScaled_func = Nil;
+{$else}
+
+function SDL_LowerBlitScaled(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LowerBlitScaled' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Set the YUV conversion mode
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetYUVConversionMode_proc = procedure(mode: TSDL_YUV_CONVERSION_MODE); cdecl;
+Var
+ SDL_SetYUVConversionMode : TSDL_SetYUVConversionMode_proc = Nil;
+{$else}
+
+procedure SDL_SetYUVConversionMode(mode: TSDL_YUV_CONVERSION_MODE); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetYUVConversionMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the YUV conversion mode
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetYUVConversionMode_func = function : TSDL_YUV_CONVERSION_MODE; cdecl;
+Var
+ SDL_GetYUVConversionMode : TSDL_GetYUVConversionMode_func = Nil;
+{$else}
+function SDL_GetYUVConversionMode: TSDL_YUV_CONVERSION_MODE; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetYUVConversionMode' {$ENDIF} {$ENDIF};
+{$endif}
+{**
+ * \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetYUVConversionModeForResolution_func = function(width: cint; height: cint): TSDL_YUV_CONVERSION_MODE; cdecl;
+Var
+ SDL_GetYUVConversionModeForResolution : TSDL_GetYUVConversionModeForResolution_func = Nil;
+{$else}
+
+function SDL_GetYUVConversionModeForResolution(width: cint; height: cint): TSDL_YUV_CONVERSION_MODE; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetYUVConversionModeForResolution' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlsystem.inc b/units/sdl2_for_pascal/sdlsystem.inc
new file mode 100644
index 0000000..7bcc6f0
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlsystem.inc
@@ -0,0 +1,756 @@
+// from "SDL_system.h"
+
+(* Platform specific functions for Windows *)
+{$IF DEFINED(WIN32) OR DEFINED(WIN64)}
+type
+ PPSDL_WindowsMessageHook = ^PSDL_WindowsMessageHook;
+ PSDL_WindowsMessageHook = ^TSDL_WindowsMessageHook;
+ TSDL_WindowsMessageHook = procedure(userdata, hWnd: Pointer; mesage: cuint; wParam: cuint64; lParam: cint64); cdecl;
+
+{**
+ * Set a callback for every Windows message, run before TranslateMessage().
+ *
+ * \param callback The SDL_WindowsMessageHook function to call.
+ * \param userdata a pointer to pass to every iteration of `callback`
+ *
+ * \since This function is available since SDL 2.0.4.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowsMessageHook_proc = procedure(callback: TSDL_WindowsMessageHook; userdata: Pointer); cdecl;
+Var
+ SDL_SetWindowsMessageHook : TSDL_SetWindowsMessageHook_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowsMessageHook(callback: TSDL_WindowsMessageHook; userdata: Pointer); cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the D3D9 adapter index that matches the specified display index.
+ *
+ * The returned adapter index can be passed to `IDirect3D9::CreateDevice` and
+ * controls on which monitor a full screen application will appear.
+ *
+ * \param displayIndex the display index for which to get the D3D9 adapter
+ * index
+ * \returns the D3D9 adapter index on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.1.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Direct3D9GetAdapterIndex_func = function(displayIndex:cint):cint; cdecl;
+Var
+ SDL_Direct3D9GetAdapterIndex : TSDL_Direct3D9GetAdapterIndex_func = Nil;
+{$else}
+
+function SDL_Direct3D9GetAdapterIndex(displayIndex:cint):cint; cdecl;
+ external SDL_LibName;
+{$endif}
+
+type
+ PIDirect3DDevice9 = type Pointer;
+ PID3D11Device = type Pointer;
+ PID3D12Device = type Pointer;
+
+{**
+ * Get the D3D9 device associated with a renderer.
+ *
+ * Once you are done using the device, you should release it to avoid a
+ * resource leak.
+ *
+ * \param renderer the renderer from which to get the associated D3D device
+ * \returns the D3D9 device associated with given renderer or NIL if it is
+ * not a D3D9 renderer; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.1.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderGetD3D9Device_func = function(renderer:PSDL_Renderer):PIDirect3DDevice9; cdecl;
+Var
+ SDL_RenderGetD3D9Device : TSDL_RenderGetD3D9Device_func = Nil;
+{$else}
+
+function SDL_RenderGetD3D9Device(renderer:PSDL_Renderer):PIDirect3DDevice9; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the D3D11 device associated with a renderer.
+ *
+ * Once you are done using the device, you should release it to avoid a
+ * resource leak.
+ *
+ * \param renderer the renderer from which to get the associated D3D11 device
+ * \returns the D3D11 device associated with given renderer or NIL if it is
+ * not a D3D11 renderer; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderGetD3D11Device_func = function(renderer:PSDL_Renderer):PID3D11Device; cdecl;
+Var
+ SDL_RenderGetD3D11Device : TSDL_RenderGetD3D11Device_func = Nil;
+{$else}
+
+function SDL_RenderGetD3D11Device(renderer:PSDL_Renderer):PID3D11Device; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the D3D12 device associated with a renderer.
+ *
+ * Once you are done using the device, you should release it to avoid a
+ * resource leak.
+ *
+ * \param renderer the renderer from which to get the associated D3D12 device
+ * \returns the D3D12 device associated with given renderer or NIL if it is
+ * not a D3D12 renderer; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RenderGetD3D12Device_func = function(renderer:PSDL_Renderer):PID3D12Device; cdecl;
+Var
+ SDL_RenderGetD3D12Device : TSDL_RenderGetD3D12Device_func = Nil;
+{$else}
+
+function SDL_RenderGetD3D12Device(renderer:PSDL_Renderer):PID3D12Device; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the DXGI Adapter and Output indices for the specified display index.
+ *
+ * The DXGI Adapter and Output indices can be passed to `EnumAdapters` and
+ * `EnumOutputs` respectively to get the objects required to create a DX10 or
+ * DX11 device and swap chain.
+ *
+ * Before SDL 2.0.4 this function did not return a value.
+ * Since SDL 2.0.4 it returns a TSDL_bool.
+ *
+ * \param displayIndex the display index for which to get both indices
+ * \param adapterIndex a pointer to be filled in with the adapter index
+ * \param outputIndex a pointer to be filled in with the output index
+ * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL 2.0.2.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DXGIGetOutputInfo_func = function(displayIndex: cint; adapterIndex, outputIndex: pcint): TSDL_Bool; cdecl;
+Var
+ SDL_DXGIGetOutputInfo : TSDL_DXGIGetOutputInfo_func = Nil;
+{$else}
+
+function SDL_DXGIGetOutputInfo(displayIndex: cint; adapterIndex, outputIndex: pcint): TSDL_Bool;
+ external SDL_LibName; cdecl;
+{$endif}
+{$ENDIF WIN32 OR WIN64}
+
+
+(* Platform specific functions for Linux *)
+{$IFDEF LINUX}
+{**
+ * Sets the UNIX nice value for a thread.
+ *
+ * This uses setpriority() if possible, and RealtimeKit if available.
+ *
+ * \param threadID the Unix thread ID to change priority of.
+ * \param priority The new, Unix-specific, priority value.
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LinuxSetThreadPriority_func = function(threadID: cint64; priority: cint): cint; cdecl;
+Var
+ SDL_LinuxSetThreadPriority : TSDL_LinuxSetThreadPriority_func = Nil;
+{$else}
+
+function SDL_LinuxSetThreadPriority(threadID: cint64; priority: cint): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Sets the priority (not nice level) and scheduling policy for a thread.
+ *
+ * This uses setpriority() if possible, and RealtimeKit if available.
+ *
+ * \param threadID The Unix thread ID to change priority of.
+ * \param sdlPriority The new TSDL_ThreadPriority value.
+ * \param schedPolicy The new scheduling policy (SCHED_FIFO, SCHED_RR,
+ * SCHED_OTHER, etc...)
+ * \returns 0 on success, or -1 on error.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_LinuxSetThreadPriorityAndPolicy_func = function(threadID: cint64; sdlPriority, schedPolicy: cint): cint; cdecl;
+Var
+ SDL_LinuxSetThreadPriorityAndPolicy : TSDL_LinuxSetThreadPriorityAndPolicy_func = Nil;
+{$else}
+
+function SDL_LinuxSetThreadPriorityAndPolicy(threadID: cint64; sdlPriority, schedPolicy: cint): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+{$ENDIF LINUX}
+
+
+(* Platform specific functions for iOS *)
+{$IFDEF __IPHONEOS__}
+type
+ PPSDL_iPhoneAnimationCallback = ^PSDL_iPhoneAnimationCallback;
+ PSDL_iPhoneAnimationCallback = ^TSDL_iPhoneAnimationCallback;
+ TSDL_iPhoneAnimationCallback = procedure(callbackParam: Pointer); cdecl;
+
+{**
+ * Use this function to set the animation callback on Apple iOS.
+ *
+ * This function is only available on Apple iOS.
+ *
+ * For more information see:
+ * https://github.com/libsdl-org/SDL/blob/main/docs/README-ios.md
+ *
+ * \param window the window for which the animation callback should be set
+ * \param interval the number of frames after which **callback** will be
+ * called
+ * \param callback the function to call for every frame.
+ * \param callbackParam a pointer that is passed to `callback`.
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_iPhoneSetEventPump
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iPhoneSetAnimationCallback_func = function(window: PSDL_Window; interval: cint; callback: TSDL_iPhoneAnimationCallback; callbackParam: Pointer); cdecl;
+Var
+ SDL_iPhoneSetAnimationCallback : TSDL_iPhoneSetAnimationCallback_func = Nil;
+{$else}
+
+function SDL_iPhoneSetAnimationCallback(window: PSDL_Window; interval: cint; callback: TSDL_iPhoneAnimationCallback; callbackParam: Pointer); cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Use this function to enable or disable the SDL event pump on Apple iOS.
+ *
+ * This function is only available on Apple iOS.
+ *
+ * \param enabled SDL_TRUE to enable the event pump, SDL_FALSE to disable it
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_iPhoneSetAnimationCallback
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_iPhoneSetEventPump_proc = procedure(enabled: TSDL_Bool); cdecl;
+Var
+ SDL_iPhoneSetEventPump : TSDL_iPhoneSetEventPump_proc = Nil;
+{$else}
+
+procedure SDL_iPhoneSetEventPump(enabled: TSDL_Bool); cdecl;
+ external SDL_LibName;
+{$endif}
+{$ENDIF __IPHONEOS__}
+
+
+(* Platform specific functions for Android *)
+{$IFDEF ANDROID}
+
+{**
+ * Get the Android Java Native Interface Environment of the current thread.
+ *
+ * This is the JNIEnv one needs to access the Java virtual machine from native
+ * code, and is needed for many Android APIs to be usable from Pascal.
+ *
+ * The prototype of the function in SDL's code actually declare a Pointer return
+ * type, even if the implementation returns a pointer to a JNIEnv. The
+ * rationale being that the SDL units can avoid using the JNI unit.
+ *
+ * \returns a pointer to Java native interface object (JNIEnv) to which the
+ * current thread is attached, or NIL on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AndroidGetActivity
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidGetJNIEnv_func = function(): Pointer; cdecl;
+Var
+ SDL_AndroidGetJNIEnv : TSDL_AndroidGetJNIEnv_func = Nil;
+{$else}
+
+function SDL_AndroidGetJNIEnv(): Pointer; cdecl;
+ external SDL_LibName;
+{$endif}
+
+(**
+ * Retrieve the Java instance of the Android activity class.
+ *
+ * The prototype of the function in SDL's code actually declares a Pointer
+ * return type, even if the implementation returns a JObject. The rationale
+ * being that the SDL units can avoid using the JNI unit.
+ *
+ * The JObject returned by the function is a local reference and must be
+ * released by the caller. See the PushLocalFrame() and PopLocalFrame() or
+ * DeleteLocalRef() functions of the Java native interface:
+ *
+ * https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
+ *
+ * \returns the jobject representing the instance of the Activity class of the
+ * Android application, or NIL on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AndroidGetJNIEnv
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidGetActivity_func = function(): Pointer; cdecl;
+Var
+ SDL_AndroidGetActivity : TSDL_AndroidGetActivity_func = Nil;
+{$else}
+
+function SDL_AndroidGetActivity(): Pointer; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Query Android API level of the current device.
+ *
+ * - API level 34: Android 14
+ * - API level 33: Android 13
+ * - API level 32: Android 12L
+ * - API level 31: Android 12
+ * - API level 30: Android 11
+ * - API level 29: Android 10
+ * - API level 28: Android 9 "Pie"
+ * - API level 27: Android 8.1 "Oreo"
+ * - API level 26: Android 8.0 "Oreo"
+ * - API level 25: Android 7.1 "Nougat"
+ * - API level 24: Android 7.0 "Nougat"
+ * - API level 23: Android 6.0 "Marshmallow"
+ * - API level 22: Android 5.1 "Lollipop"
+ * - API level 21: Android 5.0 "Lollipop"
+ * - API level 20: Android 4.4W "KitKat"
+ * - API level 19: Android 4.4 "KitKat"
+ * - API level 18: Android 4.3 "Jelly Bean"
+ * - API level 17: Android 4.2 "Jelly Bean"
+ * - API level 16: Android 4.1 "Jelly Bean"
+ * - API level 15: Android 4.0.3 "Ice Cream Sandwich"
+ * - API level 14: Android 4.0 "Ice Cream Sandwich"
+ * - API level 13: Android 3.2 "Honeycomb"
+ * - API level 12: Android 3.1 "Honeycomb"
+ * - API level 11: Android 3.0 "Honeycomb"
+ * - API level 10: Android 2.3.3 "Gingerbread"
+ *
+ * \returns the Android API level.
+ *
+ * \since This function is available since SDL 2.0.12.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetAndroidSDKVersion_func = function(): cint; cdecl;
+Var
+ SDL_GetAndroidSDKVersion : TSDL_GetAndroidSDKVersion_func = Nil;
+{$else}
+
+function SDL_GetAndroidSDKVersion(): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Query if the application is running on Android TV.
+ *
+ * \returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsAndroidTV_func = function(): TSDL_Bool; cdecl;
+Var
+ SDL_IsAndroidTV : TSDL_IsAndroidTV_func = Nil;
+{$else}
+
+function SDL_IsAndroidTV(): TSDL_Bool; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Query if the application is running on a Chromebook.
+ *
+ * \returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsChromebook_func = function(): TSDL_Bool; cdecl;
+Var
+ SDL_IsChromebook : TSDL_IsChromebook_func = Nil;
+{$else}
+
+function SDL_IsChromebook(): TSDL_Bool; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Query if the application is running on a Samsung DeX docking station.
+ *
+ * \returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsDeXMode_func = function(): TSDL_Bool; cdecl;
+Var
+ SDL_IsDeXMode : TSDL_IsDeXMode_func = Nil;
+{$else}
+
+function SDL_IsDeXMode(): TSDL_Bool; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Trigger the Android system back button behavior.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidBackButton_proc = procedure(); cdecl;
+Var
+ SDL_AndroidBackButton : TSDL_AndroidBackButton_proc = Nil;
+{$else}
+
+procedure SDL_AndroidBackButton(); cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ See the official Android developer guide for more information:
+ http://developer.android.com/guide/topics/data/data-storage.html
+*}
+const
+ SDL_ANDROID_EXTERNAL_STORAGE_READ = $01;
+ SDL_ANDROID_EXTERNAL_STORAGE_WRITE = $02;
+
+{**
+ * Get the path used for internal storage for this application.
+ *
+ * This path is unique to your application and cannot be written to by other
+ * applications.
+ *
+ * Your internal storage path is typically:
+ * `/data/data/your.app.package/files`.
+ *
+ * \returns the path used for internal storage or NIL on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AndroidGetExternalStorageState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidGetInternalStoragePath_func = function(): PAnsiChar; cdecl;
+Var
+ SDL_AndroidGetInternalStoragePath : TSDL_AndroidGetInternalStoragePath_func = Nil;
+{$else}
+
+function SDL_AndroidGetInternalStoragePath(): PAnsiChar; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the current state of external storage.
+ *
+ * The current state of external storage, a bitmask of these values:
+ * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`.
+ *
+ * If external storage is currently unavailable, this will return 0.
+ *
+ * \returns the current state of external storage on success or 0 on failure;
+ * call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AndroidGetExternalStoragePath
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidGetExternalStorageState_func = function(): cint; cdecl;
+Var
+ SDL_AndroidGetExternalStorageState : TSDL_AndroidGetExternalStorageState_func = Nil;
+{$else}
+
+function SDL_AndroidGetExternalStorageState(): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Get the path used for external storage for this application.
+ *
+ * This path is unique to your application, but is public and can be written
+ * to by other applications.
+ *
+ * Your external storage path is typically:
+ * `/storage/sdcard0/Android/data/your.app.package/files`.
+ *
+ * \returns the path used for external storage for this application on success
+ * or NIL on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_AndroidGetExternalStorageState
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidGetExternalStoragePath_func = function(): PAnsiChar; cdecl;
+Var
+ SDL_AndroidGetExternalStoragePath : TSDL_AndroidGetExternalStoragePath_func = Nil;
+{$else}
+
+function SDL_AndroidGetExternalStoragePath(): PAnsiChar; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Request permissions at runtime.
+ *
+ * This blocks the calling thread until the permission is granted or denied.
+ *
+ * For a full list of possible permission names, consult the Android docs:
+ * https://developer.android.com/reference/android/Manifest.permission
+ *
+ * \param permission The permission to request.
+ * \returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.14.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidRequestPermission_func = function(const permission: PAnsiChar): TSDL_Bool; cdecl;
+Var
+ SDL_AndroidRequestPermission : TSDL_AndroidRequestPermission_func = Nil;
+{$else}
+
+function SDL_AndroidRequestPermission(const permission: PAnsiChar): TSDL_Bool; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Shows an Android toast notification.
+ *
+ * Toasts are a sort of lightweight notification that are unique to Android.
+ *
+ * https://developer.android.com/guide/topics/ui/notifiers/toasts
+ *
+ * Shows toast in UI thread.
+ *
+ * For the `gravity` parameter, choose a value from here, or -1 if you don't
+ * have a preference:
+ *
+ * https://developer.android.com/reference/android/view/Gravity
+ *
+ * \param message text message to be shown
+ * \param duration 0=short, 1=long
+ * \param gravity where the notification should appear on the screen.
+ * \param xoffset set this parameter only when gravity >=0
+ * \param yoffset set this parameter only when gravity >=0
+ * \returns 0 if success, -1 if any error occurs.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidShowToast_func = function(const message: PAnsiChar; duration, gravity, xoffset, yoffset: cint): cint; cdecl;
+Var
+ SDL_AndroidShowToast : TSDL_AndroidShowToast_func = Nil;
+{$else}
+
+function SDL_AndroidShowToast(const message: PAnsiChar; duration, gravity, xoffset, yoffset: cint): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+
+{**
+ * Send a user command to SDLActivity.
+ *
+ * Override "boolean onUnhandledMessage(Message msg)" to handle the message.
+ *
+ * \param command user command that must be greater or equal to 0x8000
+ * \param param user parameter
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AndroidSendMessage_func = function(command: cUint32; param: cint): cint; cdecl;
+Var
+ SDL_AndroidSendMessage : TSDL_AndroidSendMessage_func = Nil;
+{$else}
+
+function SDL_AndroidSendMessage(command: cUint32; param: cint): cint; cdecl;
+ external SDL_LibName;
+{$endif}
+{$ENDIF ANDROID}
+
+
+(* Platform specific functions for WinRT *)
+{$IFDEF __WINRT__}
+Type
+ {** WinRT / Windows Phone path types *}
+ PPSDL_WinRT_Path = ^PSDL_WinRT_Path;
+ PSDL_WinRT_Path = ^TSDL_WinRT_Path;
+ TSDL_WinRT_Path = (
+ {** The installed app's root directory.
+ Files here are likely to be read-only. *}
+ SDL_WINRT_PATH_INSTALLED_LOCATION = 0,
+ {** The app's local data store. Files may be written here *}
+ SDL_WINRT_PATH_LOCAL_FOLDER = 1,
+ {** The app's roaming data store. Unsupported on Windows Phone.
+ Files written here may be copied to other machines via a network
+ connection.
+ *}
+ SDL_WINRT_PATH_ROAMING_FOLDER = 2,
+ {** The app's temporary data store. Unsupported on Windows Phone.
+ Files written here may be deleted at any time. *}
+ SDL_WINRT_PATH_TEMP_FOLDER = 3
+ );
+
+ TSDL_WinRT_DeviceFamily = (
+ {** Unknown family *}
+ SDL_WINRT_DEVICEFAMILY_UNKNOWN,
+ {** Desktop family *}
+ SDL_WINRT_DEVICEFAMILY_DESKTOP,
+ {** Mobile family (for example smartphone) *}
+ SDL_WINRT_DEVICEFAMILY_MOBILE,
+ {** XBox family *}
+ SDL_WINRT_DEVICEFAMILY_XBOX
+ );
+
+
+ {**
+ * \brief Retrieves a WinRT defined path on the local file system
+ *
+ * \note Documentation on most app-specific path types on WinRT
+ * can be found on MSDN, at the URL:
+ * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
+ *
+ * \param pathType The type of path to retrieve.
+ * \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL
+ * if the path is not available for any reason. Not all paths are
+ * available on all versions of Windows. This is especially true on
+ * Windows Phone. Check the documentation for the given
+ * SDL_WinRT_Path for more information on which path types are
+ * supported where.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WinRTGetFSPathUNICODE_func = function(pathT
+Var
+ SDL_WinRTGetFSPathUNICODE : TSDL_WinRTGetFSPathUNICODE_func = Nil;
+{$else}
+
+function SDL_WinRTGetFSPathUNICODE(pathType :TSDL_WinRT_Path):PWideChar;
+ cdecl; external SDL_LibName;
+{$endif}
+
+
+ {**
+ * \brief Retrieves a WinRT defined path on the local file system
+ *
+ * \note Documentation on most app-specific path types on WinRT
+ * can be found on MSDN, at the URL:
+ * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
+ *
+ * \param pathType The type of path to retrieve.
+ * \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL
+ * if the path is not available for any reason. Not all paths are
+ * available on all versions of Windows. This is especially true on
+ * Windows Phone. Check the documentation for the given
+ * SDL_WinRT_Path for more information on which path types are
+ * supported where.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WinRTGetFSPathUTF8_func = function(pathT
+Var
+ SDL_WinRTGetFSPathUTF8 : TSDL_WinRTGetFSPathUTF8_func = Nil;
+{$else}
+
+function SDL_WinRTGetFSPathUTF8(pathType :TSDL_WinRT_Path):PChar;
+ cdecl; external SDL_LibName;
+{$endif}
+
+
+{**
+ * Detects the device family of WinRT platform at runtime.
+ *
+ * \returns a value from the SDL_WinRT_DeviceFamily enum.
+ *
+ * \since This function is available since SDL 2.0.8.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WinRTGetDeviceFamily_func = function(): TS
+Var
+ SDL_WinRTGetDeviceFamily : TSDL_WinRTGetDeviceFamily_func = Nil;
+{$else}
+
+function SDL_WinRTGetDeviceFamily(): TSDL_WinRT_DeviceFamily;
+ cdecl; external SDL_LibName;
+{$endif}
+{$ENDIF __WINRT__}
+
+
+{**
+ * Query if the current device is a tablet.
+ *
+ * If SDL can't determine this, it will return SDL_FALSE.
+ *
+ * \returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsTablet_func = function(): TSDL_Bool; cdecl;
+Var
+ SDL_IsTablet : TSDL_IsTablet_func = Nil;
+{$else}
+
+function SDL_IsTablet(): TSDL_Bool; cdecl;
+ external SDL_LibName;
+{$endif}
+
+ {$ifdef SDL_RUNTIME_LOADING}
+// TODO: Portieren
+{$else}
+{ Functions used by iOS application delegates to notify SDL about state changes }
+procedure SDL_OnApplicationWillTerminate(); cdecl; external SDL_LibName;
+procedure SDL_OnApplicationDidReceiveMemoryWarning(); cdecl; external SDL_LibName;
+procedure SDL_OnApplicationWillResignActive(); cdecl; external SDL_LibName;
+procedure SDL_OnApplicationDidEnterBackground(); cdecl; external SDL_LibName;
+procedure SDL_OnApplicationWillEnterForeground(); cdecl; external SDL_LibName;
+procedure SDL_OnApplicationDidBecomeActive(); cdecl; external SDL_LibName;
+{$IFDEF __IPHONEOS__}
+procedure SDL_OnApplicationDidChangeStatusBarOrientation(); cdecl; external SDL_LibName;
+{$ENDIF}
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlsyswm.inc b/units/sdl2_for_pascal/sdlsyswm.inc
new file mode 100644
index 0000000..8d0755b
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlsyswm.inc
@@ -0,0 +1,369 @@
+// from sdl_syswm.h
+
+{**
+ * \brief SDL_syswm.h
+ *
+ * Your application has access to a special type of event ::SDL_SYSWMEVENT,
+ * which contains window-manager specific information and arrives whenever
+ * an unhandled window event occurs. This event is ignored by default, but
+ * you can enable it with SDL_EventState().
+ *}
+
+{$IFDEF WINDOWS}
+ {$DEFINE SDL_VIDEO_DRIVER_WINDOWS}
+{$ENDIF}
+
+{$IFDEF UNIX}
+ {$IF NOT (DEFINED(DARWIN) OR DEFINED(ANDROID))}
+ {$DEFINE SDL_VIDEO_DRIVER_X11}
+ {$IFEND}
+{$ENDIF}
+
+(*
+ * Disabled because FPC does not ship a DirectFB unit.
+ * If you have some working DirectFB bindings, feel welcome to enable this and check if it breaks anything.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_DIRECTFB}
+
+{$IFDEF DARWIN}
+ {$DEFINE SDL_VIDEO_DRIVER_COCOA}
+{$ENDIF}
+
+(*
+ * Disabled because it's a Mac-specific video driver and we have no means of testing it.
+ * If you own a Mac, feel welcome to enable this and check if it actually compiles and doesn't break anything.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_UIKIT}
+
+(*
+ * Disabled because FPC does not ship a Wayland unit.
+ * If you have some working Wayland bindings, feel welcome to enable this,
+ * check if it actually compiles and doesn't break anything.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_WAYLAND}
+
+(*
+ * Disabled because FPC does not ship a Mir unit.
+ * Also, support for Mir has been removed in SDL 2.0.10.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_MIR}
+
+(*
+ * Disabled because FPC does not support WinRT.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_WINRT}
+
+{$IFDEF ANDROID}
+ {$DEFINE SDL_VIDEO_DRIVER_ANDROID}
+{$ENDIF}
+
+(*
+ * Disabled because this is an embedded platform and we have no means of testing this.
+ * If you're actually working with Vivante, feel welcome to enable this
+ * and check if it compiles and works properly.
+ *)
+{$UNDEF SDL_VIDEO_DRIVER_VIVANTE}
+
+{$IFDEF OS2}
+ {$DEFINE SDL_VIDEO_DRIVER_OS2}
+{$ENDIF}
+
+{ SDL2-for-Pascal: Disabled because there are no FPC/Delphi units available. }
+{$UNDEF SDL_VIDEO_DRIVER_KMSDRM}
+
+{$IFDEF HAIKU}
+ {$DEFINE SDL_VIDEO_DRIVER_HAIKU}
+{$ENDIF}
+
+
+{**
+ * These are the various supported windowing subsystems
+ *}
+type
+ TSDL_SYSWM_TYPE = type cint;
+
+const
+ SDL_SYSWM_UNKNOWN = TSDL_SYSWM_TYPE(0);
+ SDL_SYSWM_WINDOWS = TSDL_SYSWM_TYPE(1);
+ SDL_SYSWM_X11 = TSDL_SYSWM_TYPE(2);
+ SDL_SYSWM_DIRECTFB = TSDL_SYSWM_TYPE(3);
+ SDL_SYSWM_COCOA = TSDL_SYSWM_TYPE(4);
+ SDL_SYSWM_UIKIT = TSDL_SYSWM_TYPE(5);
+ SDL_SYSWM_WAYLAND = TSDL_SYSWM_TYPE(6);
+ SDL_SYSWM_MIR = TSDL_SYSWM_TYPE(7); // * no longer available, left for API/ABI compatibility. Remove in 2.1! *
+ SDL_SYSWM_WINRT = TSDL_SYSWM_TYPE(8);
+ SDL_SYSWM_ANDROID = TSDL_SYSWM_TYPE(9);
+ SDL_SYSWM_VIVANTE = TSDL_SYSWM_TYPE(10);
+ SDL_SYSWM_OS2 = TSDL_SYSWM_TYPE(11);
+ SDL_SYSWM_HAIKU = TSDL_SYSWM_TYPE(12);
+ SDL_SYSWM_KMSDRM = TSDL_SYSWM_TYPE(13);
+ SDL_SYSWM_RISCOS = TSDL_SYSWM_TYPE(14);
+
+/// sdl_syswm.h uses anonymous structs, declared right in SDL_SysWMmsg and SDL_SysWMinfo.
+/// Since Pascal does not allow this, we workaround by introducing named types.
+type
+{$IFDEF SDL_VIDEO_DRIVER_WINDOWS}
+ __SYSWM_WINDOWS = record
+ hwnd: HWND; {**< The window for the message }
+ msg: UINT; {**< The type of message *}
+ wParam: WPARAM; {**< WORD message parameter *}
+ lParam: LPARAM; {**< LONG message parameter *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_X11}
+ __SYSWM_X11 = record
+ event: {$IFDEF FPC} TXEvent {$ELSE} XEvent {$ENDIF};
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_DIRECTFB}
+ __SYSWM_DIRECTFB = record
+ event: DFBEvent;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_COCOA}
+ __SYSWM_COCOA = record
+ (* No Cocoa window events yet *)
+ dummy: cint;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_UIKIT}
+ __SYSWM_UIKIT = record
+ (* No UIKit window events yet *)
+ dummy: cint;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_VIVANTE}
+ __SYSWM_VIVANTE = record
+ (* No Vivante window events yet *)
+ dummy: cint;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_OS2}
+ __SYSWM_OS2 = record
+ fFrame: Boolean; {**< TRUE if hwnd is a frame window *}
+ hwnd: HWND; {**< The window receiving the message *}
+ msg: ULONG; {**< The message identifier *}
+ mp1: MPARAM; {**< The first first message parameter *}
+ mp2: MPARAM; {**< The second first message parameter *}
+ end;
+{$ENDIF}
+
+{**
+ * The custom window manager information structure.
+ *
+ * When this structure is returned, it holds information about which
+ * low level system it is using, and will be one of SDL_SYSWM_TYPE.
+ *}
+
+{$IFDEF SDL_VIDEO_DRIVER_WINDOWS}
+ __WMINFO_WINDOWS = record
+ window: HWND; {**< The window handle *}
+ hdc: HDC; {**< The window device context *}
+ hinstance: HINST; {**< The instance handle *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_WINRT}
+ __WMINFO_WINRT = record
+ window: IInspectable; {**< The WinRT CoreWindow *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_X11}
+ __WMINFO_X11 = record
+ display: PDisplay; {**< The X11 display *}
+ window: TWindow; {**< The X11 window *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_DIRECTFB}
+ __WMINFO_DIRECTFB = record
+ dfb: IDirectFB; {**< The directfb main interface *}
+ window: IDirectFBWindow; {**< The directfb window handle *}
+ surface: IDirectFBSurface; {**< The directfb client surface *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_COCOA}
+ __WMINFO_COCOA = record
+ window: NSWindow; {* The Cocoa window *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_UIKIT}
+ __WMINFO_UIKIT = record
+ window: UIWindow; {* The UIKit window *}
+ framebuffer: GLuint; {* The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. *}
+ colorbuffer: GLuint; {* The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. *}
+ resolveFramebuffer: GLuint; {* The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_WAYLAND}
+ __WMINFO_WAYLAND = record
+ display: wl_display; {**< Wayland display *}
+ surface: wl_surface; {**< Wayland surface *}
+ shell_surface: Pointer; {**< DEPRECATED Wayland shell_surface (window manager handle) *}
+ egl_window: wl_egl_window; {**< Wayland EGL window (native window) *}
+ xdg_surface: xdg_surface; {**< Wayland xdg surface (window manager handle) *}
+ xdg_toplevel: xdg_toplevel; {**< Wayland xdg toplevel role *}
+ xdg_popup: xdg_popup; {**< Wayland xdg popup role *}
+ xdg_positioner: xdg_positioner; {**< Wayland xdg positioner, for popup *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_MIR} {* no longer available, left for API/ABI compatibility. Remove in 2.1! *}
+ __WMINFO_MIR = record
+ connection: PMirConnection; {**< Mir display server connection *}
+ surface: PMirSurface; {**< Mir surface *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_ANDROID}
+ __WMINFO_ANDROID = record
+ window: Pointer; // PANativeWindow;
+ surface: Pointer; // PEGLSurface;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_OS2}
+ __WMINFO_OS2 = record
+ hwnd: HWND; {**< The window handle *}
+ hwndFrame: HWND; {**< The frame window handle *}
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_VIVANTE}
+ __WMINFO_VIVANTE = record
+ display: EGLNativeDisplayType;
+ window: EGLNativeWindowType;
+ end;
+{$ENDIF}
+
+{$IFDEF SDL_VIDEO_DRIVER_KMSDRM}
+ __WMINFO_KMSDRM = record
+ dev_index: cint; {**< Device index (ex: the X in /dev/dri/cardX) *}
+ drm_fd: cint; {**< DRM FD (unavailable on Vulkan windows) *}
+ gbm_device: Pointer; // *gbm_dev {**< GBM device (unavailable on Vulkan windows) *}
+ end;
+{$ENDIF}
+
+
+
+
+{**
+ * The custom event structure.
+ *}
+ PPSDL_SysWMmsg = ^PSDL_SysWMmsg;
+ PSDL_SysWMmsg = ^TSDL_SysWMmsg;
+ TSDL_SysWMmsg = record
+ version: TSDL_version;
+ case subsystem: TSDL_SYSWM_TYPE of
+ {$IFDEF SDL_VIDEO_DRIVER_WINDOWS}
+ SDL_SYSWM_WINDOWS: (win: __SYSWM_WINDOWS);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_X11}
+ SDL_SYSWM_X11: (x11: __SYSWM_X11);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB}
+ SDL_SYSWM_DIRECTFB: (dfb: __SYSWM_DIRECTFB);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_COCOA}
+ SDL_SYSWM_COCOA: (cocoa: __SYSWM_COCOA);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_UIKIT}
+ SDL_SYSWM_UIKIT: (uikit: __SYSWM_UIKIT);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_VIVANTE}
+ SDL_SYSWM_VIVANTE: (vivante: __SYSWM_VIVANTE);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_OS2}
+ SDL_SYSWM_OS2: (os2: __SYSWM_OS2);
+ {$ENDIF}
+ SDL_SYSWM_UNKNOWN: (dummy: integer);
+ end;
+
+{**
+ * The custom window manager information structure.
+ *
+ * When this structure is returned, it holds information about which
+ * low level system it is using, and will be one of SDL_SYSWM_TYPE.
+ *}
+ PPSDL_SysWMinfo = ^PSDL_SysWMinfo;
+ PSDL_SysWMinfo = ^TSDL_SysWMinfo;
+ TSDL_SysWMinfo = record
+ version: TSDL_version;
+ case subsystem: TSDL_SYSWM_TYPE of
+ {$IFDEF SDL_VIDEO_DRIVER_WINDOWS}
+ SDL_SYSWM_WINDOWS: (win : __WMINFO_WINDOWS);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_WINRT}
+ SDL_SYSWM_WINRT: (winrt : __WMINFO_WINRT);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_X11}
+ SDL_SYSWM_X11: (x11 : __WMINFO_X11);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB}
+ SDL_SYSWM_DIRECTFB: (dfb : __WMINFO_DIRECTFB);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_COCOA}
+ SDL_SYSWM_COCOA: (cocoa : __WMINFO_COCOA);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_UIKIT}
+ SDL_SYSWM_UIKIT: (uikit : __WMINFO_UIKIT);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_WAYLAND}
+ SDL_SYSWM_WAYLAND: (wl : __WMINFO_WAYLAND);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_MIR}
+ SDL_SYSWM_MIR: (mir : __WMINFO_MIR);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_ANDROID}
+ SDL_SYSWM_ANDROID: (android: __WMINFO_ANDROID);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_VIVANTE}
+ SDL_SYSWM_VIVANTE: (vivante: __WMINFO_VIVANTE);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_OS2}
+ SDL_SYSWM_OS2: (os2: __WMINFO_OS2);
+ {$ENDIF}
+ {$IFDEF SDL_VIDEO_DRIVER_KMSDRM}
+ SDL_SYSWM_KMSDRM: (kmsdrm: __WMINFO_KMSDRM);
+ {$ENDIF}
+ (* Ensure this union is always 64 bytes (8 64-bit pointers) *)
+ SDL_SYSWM_UNKNOWN: (dummy: array[0..63] of Byte);
+ end;
+
+(**
+ * Get driver-specific information about a window.
+ *
+ * You must include SDL_syswm.h for the declaration of SDL_SysWMinfo.
+ *
+ * The caller must initialize the `info` structure's version by using
+ * `SDL_VERSION(&info.version)`, and then this function will fill in the rest
+ * of the structure with information about the given window.
+ *
+ * \param window the window about which information is being requested
+ * \param info an SDL_SysWMinfo structure filled in with window information
+ * \returns SDL_TRUE if the function is implemented and the `version` member
+ * of the `info` struct is valid, or SDL_FALSE if the information
+ * could not be retrieved; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *)
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowWMInfo_func = function(window: PSDL_Window; info: PSDL_SysWMinfo): TSDL_bool; cdecl;
+Var
+ SDL_GetWindowWMInfo : TSDL_GetWindowWMInfo_func = Nil;
+{$else}
+
+function SDL_GetWindowWMInfo(window: PSDL_Window; info: PSDL_SysWMinfo): TSDL_bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowWMInfo' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdlthread.inc b/units/sdl2_for_pascal/sdlthread.inc
new file mode 100644
index 0000000..05a15e7
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlthread.inc
@@ -0,0 +1,534 @@
+// based on "sdl_thread.h"
+
+{**
+ * \file SDL_thread.h
+ *
+ * Header for the SDL thread management routines.
+ *}
+
+{* The SDL thread structure, defined in SDL_thread.c *}
+type
+ PSDL_Thread = type Pointer;
+
+ {* The SDL thread ID *}
+ PPSDL_threadID = ^PSDL_threadID;
+ PSDL_threadID = ^TSDL_threadID;
+ TSDL_threadID = culong;
+
+ {* Thread local storage ID, 0 is the invalid ID *}
+ PPSDL_TLSID = ^PSDL_TLSID;
+ PSDL_TLSID = ^TSDL_TLSID;
+ TSDL_TLSID = cuint;
+
+ {**
+ * The SDL thread priority.
+ *
+ * SDL will make system changes as necessary in order to apply the thread priority.
+ * Code which attempts to control thread state related to priority should be aware
+ * that calling SDL_SetThreadPriority may alter such state.
+ * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior.
+ *
+ * \note On many systems you require special privileges to set high or time critical priority.
+ *}
+type
+ PPSDL_ThreadPriority = ^PSDL_ThreadPriority;
+ PSDL_ThreadPriority = ^TSDL_ThreadPriority;
+ TSDL_ThreadPriority = cint;
+
+const
+ SDL_THREAD_PRIORITY_LOW = TSDL_ThreadPriority(0);
+ SDL_THREAD_PRIORITY_NORMAL = TSDL_ThreadPriority(1);
+ SDL_THREAD_PRIORITY_HIGH = TSDL_ThreadPriority(2);
+ SDL_THREAD_PRIORITY_TIME_CRITICAL = TSDL_ThreadPriority(3);
+
+ {**
+ * The function passed to SDL_CreateThread().
+ *
+ * \param data what was passed as `data` to SDL_CreateThread()
+ * \returns a value that can be reported through SDL_WaitThread().
+ *}
+type
+ PPSDL_ThreadFunction = ^PSDL_ThreadFunction;
+ PSDL_ThreadFunction = ^TSDL_ThreadFunction;
+ TSDL_ThreadFunction = function(data: Pointer): cint; cdecl;
+
+{$IFDEF WINDOWS}
+ {**
+ * SDL_thread.h
+ *
+ * We compile SDL into a DLL. This means, that it's the DLL which
+ * creates a new thread for the calling process with the SDL_CreateThread()
+ * API. There is a problem with this, that only the RTL of the SDL.DLL will
+ * be initialized for those threads, and not the RTL of the calling
+ * application!
+ *
+ * To solve this, we make a little hack here.
+ *
+ * We'll always use the caller's _beginthread() and _endthread() APIs to
+ * start a new thread. This way, if it's the SDL.DLL which uses this API,
+ * then the RTL of SDL.DLL will be used to create the new thread, and if it's
+ * the application, then the RTL of the application will be used.
+ *
+ * So, in short:
+ * Always use the _beginthread() and _endthread() of the calling runtime
+ * library!
+ *}
+{$DEFINE SDL_PASSED_BEGINTHREAD_ENDTHREAD}
+
+type
+ { SDL2-for-Pascal: #todo : Needed? }
+ {$IFNDEF FPC}
+ {$IFNDEF DELPHI16UP}
+ TThreadID = Cardinal;
+ {$ENDIF}
+ {$ENDIF}
+
+ { SDL2-for-Pascal #todo : Explanation needed }
+ TpfnSDL_CurrentBeginThread = function(
+ SecurityAttributes: Pointer; StackSize: cuint; ThreadFunc: TThreadFunc;
+ Parameter: Pointer {arg}; CreationFlags: cuint; var ThreadId: TThreadID {threadID}): cuintptr_t; cdecl;
+
+ TpfnSDL_CurrentEndThread = procedure(code: cuint); cdecl;
+
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateThread_func = function(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer;
+ pfnBeginThread: TpfnSDL_CurrentBeginThread;
+ pfnEndThread: TpfnSDL_CurrentEndThread): PSDL_Thread; cdecl;
+Var
+ SDL_CreateThread : TSDL_CreateThread_func = Nil;
+{$else}
+
+function SDL_CreateThread(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer;
+ pfnBeginThread: TpfnSDL_CurrentBeginThread;
+ pfnEndThread: TpfnSDL_CurrentEndThread): PSDL_Thread; cdecl; overload;
+ external SDL_LibName;
+{$endif}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateThreadWithStackSize_func = function(fn: TSDL_ThreadFunction;
+ name: PAnsiChar; const stacksize: csize_t; data: Pointer;
+ pfnBeginThread: TpfnSDL_CurrentBeginThread;
+ pfnEndThread: TpfnSDL_CurrentEndThread): PSDL_Thread; cdecl;
+Var
+ SDL_CreateThreadWithStackSize : TSDL_CreateThreadWithStackSize_func = Nil;
+{$else}
+
+function SDL_CreateThreadWithStackSize(fn: TSDL_ThreadFunction;
+ name: PAnsiChar; const stacksize: csize_t; data: Pointer;
+ pfnBeginThread: TpfnSDL_CurrentBeginThread;
+ pfnEndThread: TpfnSDL_CurrentEndThread): PSDL_Thread; cdecl; overload;
+ external SDL_LibName;
+{$endif}
+
+{ SDL2-For-Pascal: #note : In the C header are two versions
+ of these macro functions. One for SDL's dynamic API and one without.
+ We can go with this for the moment. Improvement surely possible. }
+function SDL_CreateThread2(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer): PSDL_Thread; overload;
+
+function SDL_CreateThreadWithStackSize2(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ const stacksize: csize_t; data: Pointer): PSDL_Thread; overload;
+
+
+{ SDL2-For-Pascal: #todo :
+ The OS2 part of SDL_thread.h is not translated, yet.
+ The ELSE block is covering this right now. Not sure if the
+ OS2 platform switch is implemented in Delphi. }
+//{$ELSEIF OS2}
+//{*
+// * just like the windows case above: We compile SDL2
+// * into a dll with Watcom's runtime statically linked.
+// *}
+
+{ ... }
+
+{$ELSE}
+
+ {**
+ * Create a thread.
+ *
+ * Thread naming is a little complicated: Most systems have very small
+ * limits for the string length (BeOS has 32 bytes, Linux currently has 16,
+ * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
+ * have to see what happens with your system's debugger. The name should be
+ * UTF-8 (but using the naming limits of C identifiers is a better bet).
+ * There are no requirements for thread naming conventions, so long as the
+ * string is null-terminated UTF-8, but these guidelines are helpful in
+ * choosing a name:
+ *
+ * http://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ * If a system imposes requirements, SDL will try to munge the string for
+ * it (truncate, etc), but the original string contents will be available
+ * from SDL_GetThreadName().
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateThread_func = function(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer): PSDL_Thread; cdecl;
+Var
+ SDL_CreateThread : TSDL_CreateThread_func = Nil;
+{$else}
+
+function SDL_CreateThread(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ data: Pointer): PSDL_Thread; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateThread' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Create a new thread with a specific stack size.
+ *
+ * SDL makes an attempt to report `name` to the system, so that debuggers can
+ * display it. Not all platforms support this.
+ *
+ * Thread naming is a little complicated: Most systems have very small limits
+ * for the string length (Haiku has 32 bytes, Linux currently has 16, Visual
+ * C++ 6.0 has _nine_!), and possibly other arbitrary rules. You'll have to
+ * see what happens with your system's debugger. The name should be UTF-8 (but
+ * using the naming limits of C identifiers is a better bet). There are no
+ * requirements for thread naming conventions, so long as the string is
+ * null-terminated UTF-8, but these guidelines are helpful in choosing a name:
+ *
+ * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ * If a system imposes requirements, SDL will try to munge the string for it
+ * (truncate, etc), but the original string contents will be available from
+ * SDL_GetThreadName().
+ *
+ * The size (in bytes) of the new stack can be specified. Zero means "use the
+ * system default" which might be wildly different between platforms. x86
+ * Linux generally defaults to eight megabytes, an embedded device might be a
+ * few kilobytes instead. You generally need to specify a stack that is a
+ * multiple of the system's page size (in many cases, this is 4 kilobytes, but
+ * check your system documentation).
+ *
+ * In SDL 2.1, stack size will be folded into the original SDL_CreateThread
+ * function, but for backwards compatibility, this is currently a separate
+ * function.
+ *
+ * \param fn the SDL_ThreadFunction function to call in the new thread
+ * \param name the name of the thread
+ * \param stacksize the size, in bytes, to allocate for the new thread stack.
+ * \param data a pointer that is passed to `fn`
+ * \returns an opaque pointer to the new thread object on success, NULL if the
+ * new thread could not be created; call SDL_GetError() for more
+ * information.
+ *
+ * \since This function is available since SDL 2.0.9.
+ *
+ * \sa SDL_WaitThread
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateThreadWithStackSize_func = function(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ stacksize: csize_t; data: Pointer): PSDL_Thread; cdecl;
+Var
+ SDL_CreateThreadWithStackSize : TSDL_CreateThreadWithStackSize_func = Nil;
+{$else}
+
+function SDL_CreateThreadWithStackSize(fn: TSDL_ThreadFunction; name: PAnsiChar;
+ stacksize: csize_t; data: Pointer): PSDL_Thread; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateThreadWithStackSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+
+{$ENDIF}
+
+ {**
+ * Get the thread name as it was specified in SDL_CreateThread().
+ *
+ * This is internal memory, not to be freed by the caller, and remains valid
+ * until the specified thread is cleaned up by SDL_WaitThread().
+ *
+ * \param thread the thread to query
+ * \returns a pointer to a UTF-8 string that names the specified thread, or
+ * NULL if it doesn't have a name.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateThread
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetThreadName_func = function(thread: PSDL_Thread): PAnsiChar; cdecl;
+Var
+ SDL_GetThreadName : TSDL_GetThreadName_func = Nil;
+{$else}
+
+function SDL_GetThreadName(thread: PSDL_Thread): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetThreadName' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Get the thread identifier for the current thread.
+ *
+ * This thread identifier is as reported by the underlying operating system.
+ * If SDL is running on a platform that does not support threads the return
+ * value will always be zero.
+ *
+ * This function also returns a valid thread ID when called from the main
+ * thread.
+ *
+ * \returns the ID of the current thread.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_GetThreadID
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ThreadID_func = function (): TSDL_ThreadID; cdecl;
+Var
+ SDL_ThreadID : TSDL_ThreadID_func = Nil;
+{$else}
+function SDL_ThreadID: TSDL_ThreadID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ThreadID' {$ENDIF}{$ENDIF};
+{$endif}
+ {**
+ * Get the thread identifier for the specified thread.
+ *
+ * This thread identifier is as reported by the underlying operating system.
+ * If SDL is running on a platform that does not support threads the return
+ * value will always be zero.
+ *
+ * \param thread the thread to query
+ * \returns the ID of the specified thread, or the ID of the current thread if
+ * `thread` is NULL.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_ThreadID
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetThreadID_func = function(thread: PSDL_Thread): TSDL_ThreadID; cdecl;
+Var
+ SDL_GetThreadID : TSDL_GetThreadID_func = Nil;
+{$else}
+
+function SDL_GetThreadID(thread: PSDL_Thread): TSDL_ThreadID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetThreadID' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Set the priority for the current thread.
+ *
+ * Note that some platforms will not let you alter the priority (or at least,
+ * promote the thread to a higher priority) at all, and some require you to be
+ * an administrator account. Be prepared for this to fail.
+ *
+ * \param priority the SDL_ThreadPriority to set
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetThreadPriority_func = function(priority: TSDL_ThreadPriority): cint; cdecl;
+Var
+ SDL_SetThreadPriority : TSDL_SetThreadPriority_func = Nil;
+{$else}
+
+function SDL_SetThreadPriority(priority: TSDL_ThreadPriority): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetThreadPriority' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Wait for a thread to finish.
+ *
+ * Threads that haven't been detached will remain (as a "zombie") until this
+ * function cleans them up. Not doing so is a resource leak.
+ *
+ * Once a thread has been cleaned up through this function, the SDL_Thread
+ * that references it becomes invalid and should not be referenced again. As
+ * such, only one thread may call SDL_WaitThread() on another.
+ *
+ * The return code for the thread function is placed in the area pointed to by
+ * `status`, if `status` is not NULL.
+ *
+ * You may not wait on a thread that has been used in a call to
+ * SDL_DetachThread(). Use either that function or this one, but not both, or
+ * behavior is undefined.
+ *
+ * It is safe to pass a NULL thread to this function; it is a no-op.
+ *
+ * Note that the thread pointer is freed by this function and is not valid
+ * afterward.
+ *
+ * \param thread the SDL_Thread pointer that was returned from the
+ * SDL_CreateThread() call that started this thread
+ * \param status pointer to an integer that will receive the value returned
+ * from the thread function by its 'return', or NULL to not
+ * receive such value back.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_CreateThread
+ * \sa SDL_DetachThread
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_WaitThread_proc = procedure(thread: PSDL_Thread; status: pcint); cdecl;
+Var
+ SDL_WaitThread : TSDL_WaitThread_proc = Nil;
+{$else}
+
+procedure SDL_WaitThread(thread: PSDL_Thread; status: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitThread' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Let a thread clean up on exit without intervention.
+ *
+ * A thread may be "detached" to signify that it should not remain until
+ * another thread has called SDL_WaitThread() on it. Detaching a thread is
+ * useful for long-running threads that nothing needs to synchronize with or
+ * further manage. When a detached thread is done, it simply goes away.
+ *
+ * There is no way to recover the return code of a detached thread. If you
+ * need this, don't detach the thread and instead use SDL_WaitThread().
+ *
+ * Once a thread is detached, you should usually assume the SDL_Thread isn't
+ * safe to reference again, as it will become invalid immediately upon the
+ * detached thread's exit, instead of remaining until someone has called
+ * SDL_WaitThread() to finally clean it up. As such, don't detach the same
+ * thread more than once.
+ *
+ * If a thread has already exited when passed to SDL_DetachThread(), it will
+ * stop waiting for a call to SDL_WaitThread() and clean up immediately. It is
+ * not safe to detach a thread that might be used with SDL_WaitThread().
+ *
+ * You may not call SDL_WaitThread() on a thread that has been detached. Use
+ * either that function or this one, but not both, or behavior is undefined.
+ *
+ * It is safe to pass NULL to this function; it is a no-op.
+ *
+ * \param thread the SDL_Thread pointer that was returned from the
+ * SDL_CreateThread() call that started this thread
+ *
+ * \since This function is available since SDL 2.0.2.
+ *
+ * \sa SDL_CreateThread
+ * \sa SDL_WaitThread
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DetachThread_proc = procedure(thread:PSDL_Thread); cdecl;
+Var
+ SDL_DetachThread : TSDL_DetachThread_proc = Nil;
+{$else}
+
+procedure SDL_DetachThread(thread:PSDL_Thread); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DetachThread' {$ENDIF}{$ENDIF};
+{$endif}
+
+ {**
+ * Create a piece of thread-local storage.
+ *
+ * This creates an identifier that is globally visible to all threads but
+ * refers to data that is thread-specific.
+ *
+ * \returns the newly created thread local storage identifier or 0 on error.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_TLSGet
+ * \sa SDL_TLSSet
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_TLSCreate_func = function : TSDL_TLSID; cdecl;
+Var
+ SDL_TLSCreate : TSDL_TLSCreate_func = Nil;
+{$else}
+function SDL_TLSCreate: TSDL_TLSID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSCreate' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the current thread's value associated with a thread local storage ID.
+ *
+ * \param id the thread local storage ID
+ * \returns the value associated with the ID for the current thread or NULL if
+ * no value has been set; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_TLSCreate
+ * \sa SDL_TLSSet
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_TLSGet_func = function(id: TSDL_TLSID): Pointer; cdecl;
+Var
+ SDL_TLSGet : TSDL_TLSGet_func = Nil;
+{$else}
+
+function SDL_TLSGet(id: TSDL_TLSID): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSGet' {$ENDIF} {$ENDIF};
+{$endif}
+
+type
+ { SDL2-For-Pascal: This function pointer is introduced to specifiy the
+ destructor pointer in the SDL_TLSSet function
+ according to C headers.
+
+ The TTLSDestructor type itself is not defined
+ by the original SDL2 headers. }
+ TTLSDestructor = procedure(value: Pointer); cdecl;
+
+ {**
+ * Set the current thread's value associated with a thread local storage ID.
+ *
+ * The function prototype for `destructor` is:
+ *
+ * ```c
+ * void destructor(void *value)
+ * ```
+ *
+ * where its parameter `value` is what was passed as `value` to SDL_TLSSet().
+ *
+ * \param id the thread local storage ID
+ * \param value the value to associate with the ID for the current thread
+ * \param destructor a function called when the thread exits, to free the
+ * value
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.0.
+ *
+ * \sa SDL_TLSCreate
+ * \sa SDL_TLSGet
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_TLSSet_func = function(id: TSDL_TLSID; const value: Pointer; destructor_: TTLSDestructor): cint; cdecl;
+Var
+ SDL_TLSSet : TSDL_TLSSet_func = Nil;
+{$else}
+
+function SDL_TLSSet(id: TSDL_TLSID; const value: Pointer; destructor_: TTLSDestructor): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSSet' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Cleanup all TLS data for this thread.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_TLSCleanup_proc = procedure (); cdecl;
+Var
+ SDL_TLSCleanup : TSDL_TLSCleanup_proc = Nil;
+{$else}
+procedure SDL_TLSCleanup; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSCleanup' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdltimer.inc b/units/sdl2_for_pascal/sdltimer.inc
new file mode 100644
index 0000000..7fab232
--- /dev/null
+++ b/units/sdl2_for_pascal/sdltimer.inc
@@ -0,0 +1,141 @@
+// based on "sdl_timer.h" (2.0.14)
+
+{**
+ * Get the number of milliseconds since the SDL library initialization.
+ *
+ * This value wraps if the program runs for more than ~49 days.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetTicks_func = function : cuint32; cdecl;
+Var
+ SDL_GetTicks : TSDL_GetTicks_func = Nil;
+{$else}
+function SDL_GetTicks: cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTicks' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Get the number of milliseconds since SDL library initialization.
+ *
+ * Note that you should not use the SDL_TICKS_PASSED macro with values
+ * returned by this function, as that macro does clever math to compensate for
+ * the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit
+ * values from this function can be safely compared directly.
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetTicks64_func = function : cuint64; cdecl;
+ Var
+ SDL_GetTicks64 : TSDL_GetTicks64_func = Nil;
+ {$else}
+ function SDL_GetTicks64: cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTicks64' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * \brief Compare SDL ticks values, and return true if A has passed B
+ *
+ * e.g. if you want to wait 100 ms, you could do this:
+ * Uint32 timeout = SDL_GetTicks() + 100;
+ * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) [
+ * ... do work until timeout has elapsed
+ * ]
+ *}
+// #define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
+{ Type conversion unnecessary bc. types are declared in func. param. list! }
+function SDL_TICKS_PASSED(const A, B: cint32): Boolean;
+
+{**
+ * Get the current value of the high resolution counter
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetPerformanceCounter_func = function : cuint64; cdecl;
+ Var
+ SDL_GetPerformanceCounter : TSDL_GetPerformanceCounter_func = Nil;
+ {$else}
+function SDL_GetPerformanceCounter: cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPerformanceCounter' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Get the count per second of the high resolution counter
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetPerformanceFrequency_func = function : cuint64; cdecl;
+ Var
+ SDL_GetPerformanceFrequency : TSDL_GetPerformanceFrequency_func = Nil;
+ {$else}
+function SDL_GetPerformanceFrequency: cuint64; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPerformanceFrequency' {$ENDIF} {$ENDIF};
+ {$endif}
+
+{**
+ * Wait a specified number of milliseconds before returning.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_Delay_proc = procedure(ms: cuint32); cdecl;
+Var
+ SDL_Delay : TSDL_Delay_proc = Nil;
+{$else}
+
+procedure SDL_Delay(ms: cuint32); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Delay' {$ENDIF} {$ENDIF};
+{$endif}
+
+type
+ {**
+ * Function prototype for the timer callback function.
+ *
+ * The callback function is passed the current timer interval and returns
+ * the next timer interval. If the returned value is the same as the one
+ * passed in, the periodic alarm continues, otherwise a new alarm is
+ * scheduled. If the callback returns 0, the periodic alarm is cancelled.
+ *}
+ PPSDL_TimerCallback = ^PSDL_TimerCallback;
+ PSDL_TimerCallback = ^TSDL_TimerCallback;
+ TSDL_TimerCallback = function(interval: cuint32; param: Pointer): cuint32; cdecl;
+
+ {**
+ * Definition of the timer ID type.
+ *}
+ PPSDL_TimerID = ^PSDL_TimerID;
+ PSDL_TimerID = ^TSDL_TimerID;
+ TSDL_TimerID = cint;
+
+{**
+ * Add a new timer to the pool of timers already running.
+ *
+ * A timer ID, or NULL when an error occurs.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_AddTimer_func = function(interval: cuint32; callback: TSDL_TimerCallback; param: Pointer): TSDL_TimerID; cdecl;
+Var
+ SDL_AddTimer : TSDL_AddTimer_func = Nil;
+{$else}
+
+function SDL_AddTimer(interval: cuint32; callback: TSDL_TimerCallback; param: Pointer): TSDL_TimerID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AddTimer' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Remove a timer knowing its ID.
+ *
+ * A boolean value indicating success or failure.
+ *
+ * It is not safe to remove a timer multiple times.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RemoveTimer_func = function(id: TSDL_TimerID): Boolean; cdecl;
+Var
+ SDL_RemoveTimer : TSDL_RemoveTimer_func = Nil;
+{$else}
+
+function SDL_RemoveTimer(id: TSDL_TimerID): Boolean; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RemoveTimer' {$ENDIF} {$ENDIF};
+{$endif}
diff --git a/units/sdl2_for_pascal/sdltouch.inc b/units/sdl2_for_pascal/sdltouch.inc
new file mode 100644
index 0000000..c1e909f
--- /dev/null
+++ b/units/sdl2_for_pascal/sdltouch.inc
@@ -0,0 +1,128 @@
+//from "sdl_touch.h"
+
+type
+ PPSDL_TouchID = ^PSDL_TouchID;
+ PSDL_TouchID = ^TSDL_TouchID;
+ TSDL_TouchID = type cint64;
+
+ PPSDL_FingerID = ^PSDL_FingerID;
+ PSDL_FingerID = ^TSDL_FingerID;
+ TSDL_FingerID = type cint64;
+
+ PPSDL_TouchDeviceType = ^PSDL_TouchDeviceType;
+ PSDL_TouchDeviceType = ^TSDL_TouchDeviceType;
+ TSDL_TouchDeviceType = type cint;
+
+const
+ SDL_TOUCH_DEVICE_INVALID = TSDL_TouchDeviceType(-1);
+ SDL_TOUCH_DEVICE_DIRECT = TSDL_TouchDeviceType(0); {* touch screen with window-relative coordinates *}
+ SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE = TSDL_TouchDeviceType(1); {* trackpad with absolute device coordinates *}
+ SDL_TOUCH_DEVICE_INDIRECT_RELATIVE = TSDL_TouchDeviceType(2); {* trackpad with relative device coordinates *}
+
+type
+ PPSDL_Finger = ^PSDL_Finger;
+ PSDL_Finger = ^TSDL_Finger;
+ TSDL_Finger = record
+ id: TSDL_FingerID;
+ x: cfloat;
+ y: cfloat;
+ pressure: cfloat;
+ end;
+
+const
+ {* Used as the device ID for mouse events simulated with touch input *}
+ SDL_TOUCH_MOUSEID = cuint32(-1);
+ {* Used as the SDL_TouchID for touch events simulated with mouse input *}
+ SDL_MOUSE_TOUCHID = TSDL_TouchID(-1);
+
+ {* Function prototypes *}
+
+ {**
+ * Get the number of registered touch devices.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumTouchDevices_func = function(): cint; cdecl;
+Var
+ SDL_GetNumTouchDevices : TSDL_GetNumTouchDevices_func = Nil;
+{$else}
+
+function SDL_GetNumTouchDevices(): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumTouchDevices' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the touch ID with the given index, or 0 if the index is invalid.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetTouchDevice_func = function(index: cint): TSDL_TouchID; cdecl;
+Var
+ SDL_GetTouchDevice : TSDL_GetTouchDevice_func = Nil;
+{$else}
+
+function SDL_GetTouchDevice(index: cint): TSDL_TouchID; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDevice' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the touch device name as reported from the driver,
+ * or NIL if the index is invalid.
+ *
+ * \since This function is available since SDL 2.0.22.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetTouchName_func = function(index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetTouchName : TSDL_GetTouchName_func = Nil;
+{$else}
+
+function SDL_GetTouchName(index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchName' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the type of the given touch device.
+ *
+ * \since This function is available since SDL 2.0.10.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetTouchDeviceType_func = function(touchID: TSDL_TouchID): TSDL_TouchDeviceType; cdecl;
+Var
+ SDL_GetTouchDeviceType : TSDL_GetTouchDeviceType_func = Nil;
+{$else}
+
+function SDL_GetTouchDeviceType(touchID: TSDL_TouchID): TSDL_TouchDeviceType; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDeviceType' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the number of active fingers for a given touch device.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumTouchFingers_func = function(touchID: TSDL_TouchID): cint; cdecl;
+Var
+ SDL_GetNumTouchFingers : TSDL_GetNumTouchFingers_func = Nil;
+{$else}
+
+function SDL_GetNumTouchFingers(touchID: TSDL_TouchID): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumTouchFingers' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the finger object of the given touch, with the given index.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetTouchFinger_func = function(touchID: TSDL_TouchID; index: cint): PSDL_Finger; cdecl;
+Var
+ SDL_GetTouchFinger : TSDL_GetTouchFinger_func = Nil;
+{$else}
+
+function SDL_GetTouchFinger(touchID: TSDL_TouchID; index: cint): PSDL_Finger; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchFinger' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdltypes.inc b/units/sdl2_for_pascal/sdltypes.inc
new file mode 100644
index 0000000..85b30bc
--- /dev/null
+++ b/units/sdl2_for_pascal/sdltypes.inc
@@ -0,0 +1,10 @@
+//types from SDLtypes.h
+
+{**
+ * \file SDL_types.h
+ *
+ * \deprecated
+ *}
+
+{* DEPRECATED *}
+//#include "SDL_stdinc.h"
diff --git a/units/sdl2_for_pascal/sdlversion.inc b/units/sdl2_for_pascal/sdlversion.inc
new file mode 100644
index 0000000..1b25ed4
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlversion.inc
@@ -0,0 +1,149 @@
+// based on "sdl_version.h" (2.0.14)
+
+{**
+ * \file SDL_version.h
+ *
+ * This header defines the current SDL version.
+ *}
+
+ {**
+ * Information the version of SDL in use.
+ *
+ * Represents the library's version as three levels: major revision
+ * (increments with massive changes, additions, and enhancements),
+ * minor revision (increments with backwards-compatible changes to the
+ * major revision), and patchlevel (increments with fixes to the minor
+ * revision).
+ *
+ * SDL_VERSION
+ * SDL_GetVersion
+ *}
+type
+ PPSDL_Version = ^PSDL_Version;
+ PSDL_Version = ^TSDL_Version;
+ TSDL_Version = record
+ major, {**< major version *}
+ minor, {**< minor version *}
+ patch: cuint8; {**< update version *}
+ end;
+
+{*
+ Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+
+ Last updated when TSDL_FPoint and TSDL_FRect were added.
+*}
+const
+ SDL_MAJOR_VERSION = 2;
+ SDL_MINOR_VERSION = 0;
+ SDL_PATCHLEVEL = 10;
+
+{**
+ * Macro to determine SDL version program was compiled against.
+ *
+ * This macro fills in a SDL_version structure with the version of the
+ * library you compiled against. This is determined by what header the
+ * compiler uses. Note that if you dynamically linked the library, you might
+ * have a slightly newer or older version at runtime. That version can be
+ * determined with SDL_GetVersion(), which, unlike SDL_VERSION(),
+ * is not a macro.
+ *
+ * x An instance on TSDL_Version to fill with version data.
+ *
+ * SDL_version
+ * SDL_GetVersion
+ *}
+procedure SDL_VERSION(out x: TSDL_Version);
+
+{**
+ * This macro turns the version numbers into a numeric value:
+ *
+ * (1,2,3) -> (1203)
+ *
+ *
+ * This assumes that there will never be more than 100 patchlevels.
+ *}
+function SDL_VERSIONNUM(X,Y,Z: cuint8): Cardinal;
+
+{**
+ * This is the version number macro for the current SDL version.
+ *}
+function SDL_COMPILEDVERSION: Cardinal;
+
+{**
+ * This macro will evaluate to true if compiled with SDL at least X.Y.Z.
+ *}
+function SDL_VERSION_ATLEAST(X,Y,Z: cuint8): Boolean;
+
+{**
+ * Get the version of SDL that is linked against your program.
+ *
+ * If you are linking to SDL dynamically, then it is possible that the
+ * current version will be different than the version you compiled against.
+ * This function returns the current version, while SDL_VERSION() is a
+ * macro that tells you what version you compiled with.
+ *
+ *
+ * compiled: TSDL_Version;
+ * linked: TSDL_Version;
+ *
+ * SDL_VERSION(@compiled);
+ * SDL_GetVersion(@linked);
+ * WriteLn('We compiled against SDL version: ' +
+ * IntToStr(compiled.major) +
+ * IntToStr(compiled.minor) +
+ * IntToStr(compiled.patch));
+ * WriteLn('But we linked against SDL version:' +
+ * IntToStr(compiled.major) +
+ * IntToStr(compiled.minor) +
+ * IntToStr(compiled.patch));
+ *
+ *
+ * This function may be called safely at any time, even before SDL_Init().
+ *
+ * SDL_VERSION
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetVersion_proc = procedure(ver: PSDL_Version); cdecl;
+Var
+ SDL_GetVersion : TSDL_GetVersion_proc = Nil;
+{$else}
+
+procedure SDL_GetVersion(ver: PSDL_Version); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetVersion' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the code revision of SDL that is linked against your program.
+ *
+ * Returns an arbitrary string (a hash value) uniquely identifying the
+ * exact revision of the SDL library in use, and is only useful in comparing
+ * against other revisions. It is NOT an incrementing number.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRevision_func = function (): PAnsiChar; cdecl;
+Var
+ SDL_GetRevision : TSDL_GetRevision_func = Nil;
+{$else}
+function SDL_GetRevision: PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRevision' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the revision number of SDL that is linked against your program.
+ *
+ * Returns a number uniquely identifying the exact revision of the SDL
+ * library in use. It is an incrementing number based on commits to
+ * hg.libsdl.org.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRevisionNumber_func = function (): cint; cdecl;
+Var
+ SDL_GetRevisionNumber : TSDL_GetRevisionNumber_func = Nil;
+{$else}
+function SDL_GetRevisionNumber: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRevisionNumber' {$ENDIF} {$ENDIF};
+{$endif}
+
diff --git a/units/sdl2_for_pascal/sdlvideo.inc b/units/sdl2_for_pascal/sdlvideo.inc
new file mode 100644
index 0000000..bfda469
--- /dev/null
+++ b/units/sdl2_for_pascal/sdlvideo.inc
@@ -0,0 +1,2285 @@
+// from "sdl_video.h"
+
+
+type
+ PPSDL_Window = ^PSDL_Window;
+ PSDL_Window = type Pointer;
+
+ {**
+ * The structure that defines a display mode
+ *
+ * SDL_GetNumDisplayModes()
+ * SDL_GetDisplayMode()
+ * SDL_GetDesktopDisplayMode()
+ * SDL_GetCurrentDisplayMode()
+ * SDL_GetClosestDisplayMode()
+ * SDL_SetWindowDisplayMode()
+ * SDL_GetWindowDisplayMode()
+ *}
+ PPSDL_DisplayMode = ^PSDL_DisplayMode;
+ PSDL_DisplayMode = ^TSDL_DisplayMode;
+ TSDL_DisplayMode = record
+ format: cuint32; {**< pixel format *}
+ w: cint; {**< width *}
+ h: cint; {**< height *}
+ refresh_rate: cint; {**< refresh rate (or zero for unspecified) *}
+ driverdata: Pointer; {**< driver-specific data, initialize to 0 *}
+ end;
+
+{**
+ * The flags on a window
+ *
+ * SDL_GetWindowFlags()
+ *}
+type
+ PPSDL_WindowFlags = ^PSDL_WindowFlags;
+ PSDL_WindowFlags = ^TSDL_WindowFlags;
+ TSDL_WindowFlags = type cuint;
+
+const
+ SDL_WINDOW_FULLSCREEN = TSDL_WindowFlags($00000001); {**< fullscreen window *}
+ SDL_WINDOW_OPENGL = TSDL_WindowFlags($00000002); {**< window usable with OpenGL context *}
+ SDL_WINDOW_SHOWN = TSDL_WindowFlags($00000004); {**< window is visible *}
+ SDL_WINDOW_HIDDEN = TSDL_WindowFlags($00000008); {**< window is not visible *}
+ SDL_WINDOW_BORDERLESS = TSDL_WindowFlags($00000010); {**< no window decoration *}
+ SDL_WINDOW_RESIZABLE = TSDL_WindowFlags($00000020); {**< window can be resized *}
+ SDL_WINDOW_MINIMIZED = TSDL_WindowFlags($00000040); {**< window is minimized *}
+ SDL_WINDOW_MAXIMIZED = TSDL_WindowFlags($00000080); {**< window is maximized *}
+ SDL_WINDOW_MOUSE_GRABBED = TSDL_WindowFlags($00000100); {**< window has grabbed mouse input *}
+ SDL_WINDOW_INPUT_FOCUS = TSDL_WindowFlags($00000200); {**< window has input focus *}
+ SDL_WINDOW_MOUSE_FOCUS = TSDL_WindowFlags($00000400); {**< window has mouse focus *}
+ SDL_WINDOW_FULLSCREEN_DESKTOP = TSDL_WindowFlags(SDL_WINDOW_FULLSCREEN or $00001000);
+ SDL_WINDOW_FOREIGN = TSDL_WindowFlags($00000800); {**< window not created by SDL *}
+ SDL_WINDOW_ALLOW_HIGHDPI = TSDL_WindowFlags($00002000); {**< window should be created in high-DPI mode if supported.
+ On macOS NSHighResolutionCapable must be set true in the
+ application's Info.plist for this to have any effect. *}
+ SDL_WINDOW_MOUSE_CAPTURE = TSDL_WindowFlags($00004000); {**< window has mouse captured (unrelated to MOUSE_GRABBED) *}
+ SDL_WINDOW_ALWAYS_ON_TOP = TSDL_WindowFlags($00008000); {**< window should always be above others *}
+ SDL_WINDOW_SKIP_TASKBAR = TSDL_WindowFlags($00010000); {**< window should not be added to the taskbar *}
+ SDL_WINDOW_UTILITY = TSDL_WindowFlags($00020000); {**< window should be treated as a utility window *}
+ SDL_WINDOW_TOOLTIP = TSDL_WindowFlags($00040000); {**< window should be treated as a tooltip *}
+ SDL_WINDOW_POPUP_MENU = TSDL_WindowFlags($00080000); {**< window should be treated as a popup menu *}
+ SDL_WINDOW_KEYBOARD_GRABBED = TSDL_WindowFlags($00100000); {**< window has grabbed keyboard input *}
+ SDL_WINDOW_VULKAN = TSDL_WindowFlags($10000000); {**< window usable for Vulkan surface *}
+ SDL_WINDOW_METAL = TSDL_WindowFlags($20000000); {**< window usable for Metal view *}
+
+ SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED; {**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility *}
+
+ {**
+ * Used to indicate that you don't care what the window position is.
+ *}
+const SDL_WINDOWPOS_UNDEFINED_MASK = $1FFF0000;
+function SDL_WINDOWPOS_UNDEFINED_DISPLAY(X: Variant): Variant;
+const SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_MASK or 0;
+function SDL_WINDOWPOS_ISUNDEFINED(X: Variant): Variant;
+
+
+ {**
+ * Used to indicate that the window position should be centered.
+ *}
+const SDL_WINDOWPOS_CENTERED_MASK = $2FFF0000;
+function SDL_WINDOWPOS_CENTERED_DISPLAY(X: Variant): Variant;
+const SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_MASK or 0;
+function SDL_WINDOWPOS_ISCENTERED(X: Variant): Variant;
+
+ {**
+ * Event subtype for window events
+ *}
+type
+ PPSDL_WindowEventID = ^PSDL_WindowEventID;
+ PSDL_WindowEventID = ^TSDL_WindowEventID;
+ TSDL_WindowEventID = type cint;
+const
+ SDL_WINDOWEVENT_NONE = TSDL_WindowEventID(0); {**< Never used *}
+ SDL_WINDOWEVENT_SHOWN = TSDL_WindowEventID(1); {**< Window has been shown *}
+ SDL_WINDOWEVENT_HIDDEN = TSDL_WindowEventID(2); {**< Window has been hidden *}
+ SDL_WINDOWEVENT_EXPOSED = TSDL_WindowEventID(3); {**< Window has been exposed and should be redrawn *}
+ SDL_WINDOWEVENT_MOVED = TSDL_WindowEventID(4); {**< Window has been moved to data1; data2 *}
+ SDL_WINDOWEVENT_RESIZED = TSDL_WindowEventID(5); {**< Window has been resized to data1xdata2 *}
+ SDL_WINDOWEVENT_SIZE_CHANGED = TSDL_WindowEventID(6); {**< The window size has changed; either as a result of an API call or through the system or user changing the window size. *}
+ SDL_WINDOWEVENT_MINIMIZED = TSDL_WindowEventID(7); {**< Window has been minimized *}
+ SDL_WINDOWEVENT_MAXIMIZED = TSDL_WindowEventID(8); {**< Window has been maximized *}
+ SDL_WINDOWEVENT_RESTORED = TSDL_WindowEventID(9); {**< Window has been restored to normal size and position *}
+ SDL_WINDOWEVENT_ENTER = TSDL_WindowEventID(10); {**< Window has gained mouse focus *}
+ SDL_WINDOWEVENT_LEAVE = TSDL_WindowEventID(11); {**< Window has lost mouse focus *}
+ SDL_WINDOWEVENT_FOCUS_GAINED = TSDL_WindowEventID(12); {**< Window has gained keyboard focus *}
+ SDL_WINDOWEVENT_FOCUS_LOST = TSDL_WindowEventID(13); {**< Window has lost keyboard focus *}
+ SDL_WINDOWEVENT_CLOSE = TSDL_WindowEventID(14); {**< The window manager requests that the window be closed *}
+ SDL_WINDOWEVENT_TAKE_FOCUS = TSDL_WindowEventID(15); {**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) *}
+ SDL_WINDOWEVENT_HIT_TEST = TSDL_WindowEventID(16); {**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. *}
+ SDL_WINDOWEVENT_ICCPROF_CHANGED = TSDL_WindowEventID(17); {**< The ICC profile of the window's display has changed. *}
+ SDL_WINDOWEVENT_DISPLAY_CHANGED = TSDL_WindowEventID(18); {**< Window has been moved to display data1. *}
+
+{**
+ * \brief Event subtype for display events
+ *}
+type
+ PPSDL_DisplayEventID = ^PSDL_DisplayEventID;
+ PSDL_DisplayEventID = ^TSDL_DisplayEventID;
+ TSDL_DisplayEventID = type Integer;
+
+const
+ SDL_DISPLAYEVENT_NONE = TSDL_DisplayEventID(0); {**< Never used *}
+ SDL_DISPLAYEVENT_ORIENTATION = TSDL_DisplayEventID(1); {**< Display orientation has changed to data1 *}
+ SDL_DISPLAYEVENT_CONNECTED = TSDL_DisplayEventID(2); {**< Display has been added to the system *}
+ SDL_DISPLAYEVENT_DISCONNECTED = TSDL_DisplayEventID(3); {**< Display has been removed from the system *}
+
+type
+ PPSDL_DisplayOrientation = ^PSDL_DisplayOrientation;
+ PSDL_DisplayOrientation = ^TSDL_DisplayOrientation;
+ TSDL_DisplayOrientation = type Integer;
+
+const
+ SDL_ORIENTATION_UNKNOWN = TSDL_DisplayOrientation(0); {**< The display orientation can't be determined *}
+ SDL_ORIENTATION_LANDSCAPE = TSDL_DisplayOrientation(1); {**< The display is in landscape mode, with the right side up, relative to portrait mode *}
+ SDL_ORIENTATION_LANDSCAPE_FLIPPED = TSDL_DisplayOrientation(2); {**< The display is in landscape mode, with the left side up, relative to portrait mode *}
+ SDL_ORIENTATION_PORTRAIT = TSDL_DisplayOrientation(3); {**< The display is in portrait mode *}
+ SDL_ORIENTATION_PORTRAIT_FLIPPED = TSDL_DisplayOrientation(4); {**< The display is in portrait mode, upside down *}
+
+ {**
+ * \brief Window flash operation
+ *}
+type
+ PPSDL_FlashOperation = ^PSDL_FlashOperation;
+ PSDL_FlashOperation = ^TSDL_FlashOperation;
+ TSDL_FlashOperation = type Integer;
+
+const
+ SDL_FLASH_CANCEL = TSDL_FlashOperation(0); {**< Cancel any window flash state *}
+ SDL_FLASH_BRIEFLY = TSDL_FlashOperation(1); {**< Flash the window briefly to get attention *}
+ SDL_FLASH_UNTIL_FOCUSED = TSDL_FlashOperation(2); {**< Flash the window until it gets focus *}
+
+ {**
+ * An opaque handle to an OpenGL context.
+ *}
+type
+ PPSDL_GLContext = ^PSDL_GLContext;
+ PSDL_GLContext = ^TSDL_GLContext;
+ TSDL_GLContext = Pointer;
+
+ {**
+ * OpenGL configuration attributes
+ *}
+type
+ PPSDL_GLattr = ^PSDL_GLattr;
+ PSDL_GLattr = ^TSDL_GLattr;
+ TSDL_GLattr = type Integer;
+
+const
+ SDL_GL_RED_SIZE = TSDL_GLattr(0);
+ SDL_GL_GREEN_SIZE = TSDL_GLattr(1);
+ SDL_GL_BLUE_SIZE = TSDL_GLattr(2);
+ SDL_GL_ALPHA_SIZE = TSDL_GLattr(3);
+ SDL_GL_BUFFER_SIZE = TSDL_GLattr(4);
+ SDL_GL_DOUBLEBUFFER = TSDL_GLattr(5);
+ SDL_GL_DEPTH_SIZE = TSDL_GLattr(6);
+ SDL_GL_STENCIL_SIZE = TSDL_GLattr(7);
+ SDL_GL_ACCUM_RED_SIZE = TSDL_GLattr(8);
+ SDL_GL_ACCUM_GREEN_SIZE = TSDL_GLattr(9);
+ SDL_GL_ACCUM_BLUE_SIZE = TSDL_GLattr(10);
+ SDL_GL_ACCUM_ALPHA_SIZE = TSDL_GLattr(11);
+ SDL_GL_STEREO = TSDL_GLattr(12);
+ SDL_GL_MULTISAMPLEBUFFERS = TSDL_GLattr(13);
+ SDL_GL_MULTISAMPLESAMPLES = TSDL_GLattr(14);
+ SDL_GL_ACCELERATED_VISUAL = TSDL_GLattr(15);
+ SDL_GL_RETAINED_BACKING = TSDL_GLattr(16);
+ SDL_GL_CONTEXT_MAJOR_VERSION = TSDL_GLattr(17);
+ SDL_GL_CONTEXT_MINOR_VERSION = TSDL_GLattr(18);
+ SDL_GL_CONTEXT_EGL = TSDL_GLattr(19);
+ SDL_GL_CONTEXT_FLAGS = TSDL_GLattr(20);
+ SDL_GL_CONTEXT_PROFILE_MASK = TSDL_GLattr(21);
+ SDL_GL_SHARE_WITH_CURRENT_CONTEXT = TSDL_GLattr(22);
+ SDL_GL_FRAMEBUFFER_SRGB_CAPABLE = TSDL_GLattr(23);
+ SDL_GL_CONTEXT_RELEASE_BEHAVIOR = TSDL_GLattr(24);
+ SDL_GL_CONTEXT_RESET_NOTIFICATION = TSDL_GLattr(25);
+ SDL_GL_CONTEXT_NO_ERROR = TSDL_GLattr(26);
+ SDL_GL_FLOATBUFFERS = TSDL_GLattr(27);
+
+type
+ PPSDL_GLprofile = ^PSDL_GLprofile;
+ PSDL_GLprofile = ^TSDL_GLprofile;
+ TSDL_GLprofile = type Integer;
+
+const
+ SDL_GL_CONTEXT_PROFILE_CORE = TSDL_GLprofile($0001);
+ SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = TSDL_GLprofile($0002);
+ SDL_GL_CONTEXT_PROFILE_ES = TSDL_GLprofile($0004);
+
+type
+ PPSDL_GLcontextFlag = ^PSDL_GLcontextFlag;
+ PSDL_GLcontextFlag = ^TSDL_GLcontextFlag;
+ TSDL_GLcontextFlag = type Integer;
+
+const
+ SDL_GL_CONTEXT_DEBUG_FLAG = TSDL_GLcontextFlag($0001);
+ SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = TSDL_GLcontextFlag($0002);
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = TSDL_GLcontextFlag($0004);
+ SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = TSDL_GLcontextFlag($0008);
+
+type
+ PPSDL_GLcontextReleaseFlag = ^PSDL_GLcontextReleaseFlag;
+ PSDL_GLcontextReleaseFlag = ^TSDL_GLcontextReleaseFlag;
+ TSDL_GLcontextReleaseFlag = type Integer;
+
+const
+ SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = TSDL_GLcontextReleaseFlag($0000);
+ SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = TSDL_GLcontextReleaseFlag($0001);
+
+type
+ PPSDL_GLContextResetNotification = ^PSDL_GLContextResetNotification;
+ PSDL_GLContextResetNotification = ^TSDL_GLContextResetNotification;
+ TSDL_GLContextResetNotification = type Integer;
+
+const
+ SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = TSDL_GLContextResetNotification($0000);
+ SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = TSDL_GLContextResetNotification($0001);
+
+ {* Function prototypes *}
+
+ {**
+ * Get the number of video drivers compiled into SDL
+ *
+ * SDL_GetVideoDriver()
+ *}
+ {$ifdef SDL_RUNTIME_LOADING}
+ Type
+ TSDL_GetNumVideoDrivers_func =function : cint; cdecl;
+ Var
+ SDL_GetNumVideoDrivers : TSDL_GetNumVideoDrivers_func = Nil;
+ {$else}
+function SDL_GetNumVideoDrivers: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumVideoDrivers' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Get the name of a built in video driver.
+ *
+ * The video drivers are presented in the order in which they are
+ * normally checked during initialization.
+ *
+ * SDL_GetNumVideoDrivers()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetVideoDriver_func = function(index: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetVideoDriver : TSDL_GetVideoDriver_func = Nil;
+{$else}
+
+function SDL_GetVideoDriver(index: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetVideoDriver' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Initialize the video subsystem, optionally specifying a video driver.
+ *
+ * driver_name Initialize a specific driver by name, or nil for the
+ * default video driver.
+ *
+ * 0 on success, -1 on error
+ *
+ * This function initializes the video subsystem; setting up a connection
+ * to the window manager, etc, and determines the available display modes
+ * and pixel formats, but does not initialize a window or graphics mode.
+ *
+ * SDL_VideoQuit()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_VideoInit_func = function(const driver_name: PAnsiChar): cint; cdecl;
+Var
+ SDL_VideoInit : TSDL_VideoInit_func = Nil;
+{$else}
+
+function SDL_VideoInit(const driver_name: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_VideoInit' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Shuts down the video subsystem.
+ *
+ * function closes all windows, and restores the original video mode.
+ *
+ * SDL_VideoInit()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_VideoQuit_proc =Procedure ; cdecl;
+Var
+ SDL_VideoQuit : TSDL_VideoQuit_proc = Nil;
+{$else}
+procedure SDL_VideoQuit; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_VideoQuit' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Returns the name of the currently initialized video driver.
+ *
+ * The name of the current video driver or nil if no driver
+ * has been initialized
+ *
+ * SDL_GetNumVideoDrivers()
+ * SDL_GetVideoDriver()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetCurrentVideoDriver_func = function : PAnsiChar; cdecl;
+Var
+ SDL_GetCurrentVideoDriver : TSDL_GetCurrentVideoDriver_func = Nil;
+{$else}
+
+function SDL_GetCurrentVideoDriver: PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCurrentVideoDriver' {$ENDIF} {$ENDIF};
+{$endif}
+ {**
+ * Returns the number of available video displays.
+ *
+ * SDL_GetDisplayBounds()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumVideoDisplays_func =function : cint; cdecl;
+Var
+ SDL_GetNumVideoDisplays : TSDL_GetNumVideoDisplays_func = Nil;
+{$else}
+
+function SDL_GetNumVideoDisplays: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumVideoDisplays' {$ENDIF} {$ENDIF};
+{$endif}
+ {**
+ * Get the name of a display in UTF-8 encoding
+ *
+ * The name of a display, or nil for an invalid display index.
+ *
+ * SDL_GetNumVideoDisplays()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayName_func = function(displayIndex: cint): PAnsiChar; cdecl;
+Var
+ SDL_GetDisplayName : TSDL_GetDisplayName_func = Nil;
+{$else}
+
+function SDL_GetDisplayName(displayIndex: cint): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayName' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the desktop area represented by a display, with the primary
+ * display located at 0,0
+ *
+ * 0 on success, or -1 if the index is out of range.
+ *
+ * SDL_GetNumVideoDisplays()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayBounds_func = function(displayIndex: cint; rect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_GetDisplayBounds : TSDL_GetDisplayBounds_func = Nil;
+{$else}
+
+function SDL_GetDisplayBounds(displayIndex: cint; rect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayBounds' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the usable desktop area represented by a display, with the
+ * primary display located at 0,0
+ *
+ * This is the same area as SDL_GetDisplayBounds() reports, but with portions
+ * reserved by the system removed. For example, on Mac OS X, this subtracts
+ * the area occupied by the menu bar and dock.
+ *
+ * Setting a window to be fullscreen generally bypasses these unusable areas,
+ * so these are good guidelines for the maximum space available to a
+ * non-fullscreen window.
+ *
+ * \return 0 on success, or -1 if the index is out of range.
+ *
+ * \sa SDL_GetDisplayBounds()
+ * \sa SDL_GetNumVideoDisplays()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayUsableBounds_func = function(displayIndex: cint; rect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_GetDisplayUsableBounds : TSDL_GetDisplayUsableBounds_func = Nil;
+{$else}
+
+function SDL_GetDisplayUsableBounds(displayIndex: cint; rect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayUsableBounds' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Get the dots/pixels-per-inch for a display
+ *
+ * \note Diagonal, horizontal and vertical DPI can all be optionally
+ * returned if the parameter is non-NULL.
+ *
+ * \return 0 on success, or -1 if no DPI information is available or the index is out of range.
+ *
+ * \sa SDL_GetNumVideoDisplays()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayDPI_func = function(displayIndex: cint; ddpi, hdpi, vdpi: pcfloat): cint; cdecl;
+Var
+ SDL_GetDisplayDPI : TSDL_GetDisplayDPI_func = Nil;
+{$else}
+
+function SDL_GetDisplayDPI(displayIndex: cint; ddpi, hdpi, vdpi: pcfloat): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayDPI' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Get the orientation of a display
+ *
+ * \return The orientation of the display, or SDL_ORIENTATION_UNKNOWN if it isn't available.
+ *
+ * \sa SDL_GetNumVideoDisplays()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayOrientation_func = function(displayIndex: cint): TSDL_DisplayOrientation; cdecl;
+Var
+ SDL_GetDisplayOrientation : TSDL_GetDisplayOrientation_func = Nil;
+{$else}
+
+function SDL_GetDisplayOrientation(displayIndex: cint): TSDL_DisplayOrientation; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayOrientation' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Returns the number of available display modes.
+ *
+ * SDL_GetDisplayMode()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetNumDisplayModes_func = function(displayIndex: cint): cint; cdecl;
+Var
+ SDL_GetNumDisplayModes : TSDL_GetNumDisplayModes_func = Nil;
+{$else}
+
+function SDL_GetNumDisplayModes(displayIndex: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumDisplayModes' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill in information about a specific display mode.
+ *
+ * The display modes are sorted in this priority:
+ * bits per pixel -> more colors to fewer colors
+ * width -> largest to smallest
+ * height -> largest to smallest
+ * refresh rate -> highest to lowest
+ *
+ * SDL_GetNumDisplayModes()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDisplayMode_func = function(displayIndex: cint; modeIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+Var
+ SDL_GetDisplayMode : TSDL_GetDisplayMode_func = Nil;
+{$else}
+
+function SDL_GetDisplayMode(displayIndex: cint; modeIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDisplayMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill in information about the desktop display mode.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetDesktopDisplayMode_func = function(displayIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+Var
+ SDL_GetDesktopDisplayMode : TSDL_GetDesktopDisplayMode_func = Nil;
+{$else}
+
+function SDL_GetDesktopDisplayMode(displayIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDesktopDisplayMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill in information about the current display mode.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetCurrentDisplayMode_func = function(displayIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+Var
+ SDL_GetCurrentDisplayMode : TSDL_GetCurrentDisplayMode_func = Nil;
+{$else}
+
+function SDL_GetCurrentDisplayMode(displayIndex: cint; mode: PSDL_DisplayMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCurrentDisplayIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the closest match to the requested display mode.
+ *
+ * mode The desired display mode
+ * closest A pointer to a display mode to be filled in with the closest
+ * match of the available display modes.
+ *
+ * The passed in value closest, or nil if no matching video mode
+ * was available.
+ *
+ * The available display modes are scanned, and closest is filled in with the
+ * closest mode matching the requested mode and returned. The mode format and
+ * refresh_rate default to the desktop mode if they are 0. The modes are
+ * scanned with size being first priority, format being second priority, and
+ * finally checking the refresh_rate. If all the available modes are too
+ * small, then nil is returned.
+ *
+ * SDL_GetNumDisplayModes()
+ * SDL_GetDisplayMode()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetClosestDisplayMode_func = function(displayIndex: cint; const mode: PSDL_DisplayMode; closest: PSDL_DisplayMode): PSDL_DisplayMode; cdecl;
+Var
+ SDL_GetClosestDisplayMode : TSDL_GetClosestDisplayMode_func = Nil;
+{$else}
+
+function SDL_GetClosestDisplayMode(displayIndex: cint; const mode: PSDL_DisplayMode; closest: PSDL_DisplayMode): PSDL_DisplayMode; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetClosestDisplayMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the index of the display containing a point
+ *
+ * \param point the point to query
+ * \returns the index of the display containing the point or a negative error
+ * code on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GetDisplayBounds
+ * \sa SDL_GetNumVideoDisplays
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetPointDisplayIndex_func = function(const point: PSDL_Point): cint; cdecl;
+Var
+ SDL_GetPointDisplayIndex : TSDL_GetPointDisplayIndex_func = Nil;
+{$else}
+
+function SDL_GetPointDisplayIndex(const point: PSDL_Point): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPointDisplayIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the index of the display primarily containing a rect
+ *
+ * \param rect the rect to query
+ * \returns the index of the display entirely containing the rect or closest
+ * to the center of the rect on success or a negative error code on
+ * failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GetDisplayBounds
+ * \sa SDL_GetNumVideoDisplays
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetRectDisplayIndex_func = function(const rect: PSDL_Rect): cint; cdecl;
+Var
+ SDL_GetRectDisplayIndex : TSDL_GetRectDisplayIndex_func = Nil;
+{$else}
+
+function SDL_GetRectDisplayIndex(const rect: PSDL_Rect): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRectDisplayIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the display index associated with a window.
+ *
+ * the display index of the display containing the center of the
+ * window, or -1 on error.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowDisplayIndex_func = function(window: PSDL_Window): cint; cdecl;
+Var
+ SDL_GetWindowDisplayIndex : TSDL_GetWindowDisplayIndex_func = Nil;
+{$else}
+
+function SDL_GetWindowDisplayIndex(window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowDisplayIndex' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the display mode used when a fullscreen window is visible.
+ *
+ * By default the window's dimensions and the desktop format and refresh rate
+ * are used.
+ *
+ * mode The mode to use, or nil for the default mode.
+ *
+ * 0 on success, or -1 if setting the display mode failed.
+ *
+ * SDL_GetWindowDisplayMode()
+ * SDL_SetWindowFullscreen()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowDisplayMode_func = function(window: PSDL_Window; const mode: PSDL_DisplayMode): cint; cdecl;
+Var
+ SDL_SetWindowDisplayMode : TSDL_SetWindowDisplayMode_func = Nil;
+{$else}
+
+function SDL_SetWindowDisplayMode(window: PSDL_Window; const mode: PSDL_DisplayMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowDisplayMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Fill in information about the display mode used when a fullscreen
+ * window is visible.
+ *
+ * SDL_SetWindowDisplayMode()
+ * SDL_SetWindowFullscreen()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowDisplayMode_func = function(window: PSDL_Window; mode: PSDL_DisplayMode): cint; cdecl;
+Var
+ SDL_GetWindowDisplayMode : TSDL_GetWindowDisplayMode_func = Nil;
+{$else}
+
+function SDL_GetWindowDisplayMode(window: PSDL_Window; mode: PSDL_DisplayMode): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowDisplayMode' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Get the raw ICC profile data for the screen the window is currently on.
+ *
+ * Data returned should be freed with SDL_free().
+ *
+ * \param window the window to query
+ * \param size the size of the ICC profile
+ * \returns the raw ICC profile data on success or NIL on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.18.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowICCProfile_func = function(window: PSDL_Window; size: pcsize_t): Pointer; cdecl;
+Var
+ SDL_GetWindowICCProfile : TSDL_GetWindowICCProfile_func = Nil;
+{$else}
+
+function SDL_GetWindowICCProfile(window: PSDL_Window; size: pcsize_t): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowICCProfile' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the pixel format associated with the window.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowPixelFormat_func = function(window: PSDL_Window): cuint32; cdecl;
+Var
+ SDL_GetWindowPixelFormat : TSDL_GetWindowPixelFormat_func = Nil;
+{$else}
+
+function SDL_GetWindowPixelFormat(window: PSDL_Window): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowPixelFormat' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Create a window with the specified position, dimensions, and flags.
+ *
+ * \param title The title of the window, in UTF-8 encoding.
+ * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or
+ * ::SDL_WINDOWPOS_UNDEFINED.
+ * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or
+ * ::SDL_WINDOWPOS_UNDEFINED.
+ * \param w The width of the window, in screen coordinates.
+ * \param h The height of the window, in screen coordinates.
+ * \param flags The flags for the window, a mask of any of the following:
+ * ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL,
+ * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS,
+ * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED,
+ * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_INPUT_GRABBED,
+ * ::SDL_WINDOW_ALLOW_HIGHDPI, ::SDL_WINDOW_VULKAN.
+ *
+ * \return The created window, or NULL if window creation failed.
+ *
+ * If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size
+ * in pixels may differ from its size in screen coordinates on platforms with
+ * high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query
+ * the client area's size in screen coordinates, and SDL_GL_GetDrawableSize(),
+ * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to query the
+ * drawable size in pixels.
+ *
+ * If the window is created with any of the SDL_WINDOW_OPENGL or
+ * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
+ * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
+ * corresponding UnloadLibrary function is called by SDL_DestroyWindow().
+ *
+ * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver,
+ * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
+ *
+ * \note On non-Apple devices, SDL requires you to either not link to the
+ * Vulkan loader or link to a dynamic library version. This limitation
+ * may be removed in a future version of SDL.
+ *
+ * \sa SDL_DestroyWindow()
+ * \sa SDL_GL_LoadLibrary()
+ * \sa SDL_Vulkan_LoadLibrary()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateWindow_func = function(const title: PAnsiChar; x: cint; y: cint; w: cint; h: cint; flags: TSDL_WindowFlags): PSDL_Window; cdecl;
+Var
+ SDL_CreateWindow : TSDL_CreateWindow_func = Nil;
+{$else}
+
+function SDL_CreateWindow(const title: PAnsiChar; x: cint; y: cint; w: cint; h: cint; flags: TSDL_WindowFlags): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Create an SDL window from an existing native window.
+ *
+ * data A pointer to driver-dependent window creation data
+ *
+ * The id of the window created, or zero if window creation failed.
+ *
+ * SDL_DestroyWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_CreateWindowFrom_func = function(const data: Pointer): PSDL_Window; cdecl;
+Var
+ SDL_CreateWindowFrom : TSDL_CreateWindowFrom_func = Nil;
+{$else}
+
+function SDL_CreateWindowFrom(const data: Pointer): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateWindowFrom' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the numeric ID of a window, for logging purposes.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowID_func = function(window: PSDL_Window): cuint32; cdecl;
+Var
+ SDL_GetWindowID : TSDL_GetWindowID_func = Nil;
+{$else}
+
+function SDL_GetWindowID(window: PSDL_Window): cuint32; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowID' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a window from a stored ID, or nil if it doesn't exist.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowFromID_func = function(id: cuint32): PSDL_Window; cdecl;
+Var
+ SDL_GetWindowFromID : TSDL_GetWindowFromID_func = Nil;
+{$else}
+
+function SDL_GetWindowFromID(id: cuint32): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowFromID' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the window flags.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowFlags_func = function(window: PSDL_Window): TSDL_WindowFlags; cdecl;
+Var
+ SDL_GetWindowFlags : TSDL_GetWindowFlags_func = Nil;
+{$else}
+
+function SDL_GetWindowFlags(window: PSDL_Window): TSDL_WindowFlags; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowFlags' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the title of a window, in UTF-8 format.
+ *
+ * SDL_GetWindowTitle()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowTitle_proc = procedure(window: PSDL_Window; const title: PAnsiChar); cdecl;
+Var
+ SDL_SetWindowTitle : TSDL_SetWindowTitle_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowTitle(window: PSDL_Window; const title: PAnsiChar); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowTitle' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the title of a window, in UTF-8 format.
+ *
+ * SDL_SetWindowTitle()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowTitle_func = function(window: PSDL_Window): PAnsiChar; cdecl;
+Var
+ SDL_GetWindowTitle : TSDL_GetWindowTitle_func = Nil;
+{$else}
+
+function SDL_GetWindowTitle(window: PSDL_Window): PAnsiChar; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowTitle' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the icon for a window.
+ *
+ * icon The icon for the window.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowIcon_proc = procedure(window: PSDL_Window; icon: PSDL_Surface); cdecl;
+Var
+ SDL_SetWindowIcon : TSDL_SetWindowIcon_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowIcon(window: PSDL_Window; icon: PSDL_Surface); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowIcon' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Associate an arbitrary named pointer with a window.
+ *
+ * window The window to associate with the pointer.
+ * name The name of the pointer.
+ * userdata The associated pointer.
+ *
+ * The previous value associated with 'name'
+ *
+ * The name is case-sensitive.
+ *
+ * SDL_GetWindowData()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowData_func = function(window: PSDL_Window; const name: PAnsiChar; userdata: Pointer): Pointer; cdecl;
+Var
+ SDL_SetWindowData : TSDL_SetWindowData_func = Nil;
+{$else}
+
+function SDL_SetWindowData(window: PSDL_Window; const name: PAnsiChar; userdata: Pointer): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowData' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Retrieve the data pointer associated with a window.
+ *
+ * window The window to query.
+ * name The name of the pointer.
+ *
+ * The value associated with 'name'
+ *
+ * SDL_SetWindowData()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowData_func = function(window: PSDL_Window; const name: PAnsiChar): Pointer; cdecl;
+Var
+ SDL_GetWindowData : TSDL_GetWindowData_func = Nil;
+{$else}
+
+function SDL_GetWindowData(window: PSDL_Window; const name: PAnsiChar): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowData' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the position of a window.
+ *
+ * window The window to reposition.
+ * x The x coordinate of the window, SDL_WINDOWPOS_CENTERED, or
+ * SDL_WINDOWPOS_UNDEFINED.
+ * y The y coordinate of the window, SDL_WINDOWPOS_CENTERED, or
+ * SDL_WINDOWPOS_UNDEFINED.
+ *
+ * The window coordinate origin is the upper left of the display.
+ *
+ * SDL_GetWindowPosition()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowPosition_proc = procedure(window: PSDL_Window; x: cint; y: cint); cdecl;
+Var
+ SDL_SetWindowPosition : TSDL_SetWindowPosition_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowPosition(window: PSDL_Window; x: cint; y: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowPosition' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the position of a window.
+ *
+ * x Pointer to variable for storing the x position, may be nil
+ * y Pointer to variable for storing the y position, may be nil
+ *
+ * SDL_SetWindowPosition()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowPosition_proc = procedure(window: PSDL_Window; x: pcint; y: pcint); cdecl;
+Var
+ SDL_GetWindowPosition : TSDL_GetWindowPosition_proc = Nil;
+{$else}
+
+procedure SDL_GetWindowPosition(window: PSDL_Window; x: pcint; y: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowPosition' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the size of a window's client area.
+ *
+ * w The width of the window, must be >0
+ * h The height of the window, must be >0
+ *
+ * You can't change the size of a fullscreen window, it automatically
+ * matches the size of the display mode.
+ *
+ * SDL_GetWindowSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowSize_proc = procedure(window: PSDL_Window; w: cint; h: cint); cdecl;
+Var
+ SDL_SetWindowSize : TSDL_SetWindowSize_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowSize(window: PSDL_Window; w: cint; h: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the size of a window's client area.
+ *
+ * w Pointer to variable for storing the width, may be nil
+ * h Pointer to variable for storing the height, may be nil
+ *
+ * SDL_SetWindowSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowSize_proc = procedure(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+Var
+ SDL_GetWindowSize : TSDL_GetWindowSize_proc = Nil;
+{$else}
+
+procedure SDL_GetWindowSize(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Get the size of a window's borders (decorations) around the client area.
+ *
+ * \param window The window to query.
+ * \param top Pointer to variable for storing the size of the top border. NULL is permitted.
+ * \param left Pointer to variable for storing the size of the left border. NULL is permitted.
+ * \param bottom Pointer to variable for storing the size of the bottom border. NULL is permitted.
+ * \param right Pointer to variable for storing the size of the right border. NULL is permitted.
+ *
+ * \return 0 on success, or -1 if getting this information is not supported.
+ *
+ * \note if this function fails (returns -1), the size values will be
+ * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as
+ * if the window in question was borderless.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowBordersSize_func = function(window: PSDL_Window; top, left, bottom, right: pcint): cint; cdecl;
+Var
+ SDL_GetWindowBordersSize : TSDL_GetWindowBordersSize_func = Nil;
+{$else}
+
+function SDL_GetWindowBordersSize(window: PSDL_Window; top, left, bottom, right: pcint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowBordersSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the size of a window in pixels.
+ *
+ * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI
+ * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a
+ * platform with high-DPI support (Apple calls this "Retina"), and not
+ * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint.
+ *
+ * \param window the window from which the drawable size should be queried
+ * \param w a pointer to variable for storing the width in pixels, may be NIL
+ * \param h a pointer to variable for storing the height in pixels, may be
+ * NIL
+ *
+ * \since This function is available since SDL 2.26.0.
+ *
+ * \sa SDL_CreateWindow
+ * \sa SDL_GetWindowSize
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowSizeInPixels_proc = procedure(window: PSDL_Window; w, h: pcuint); cdecl;
+Var
+ SDL_GetWindowSizeInPixels : TSDL_GetWindowSizeInPixels_proc = Nil;
+{$else}
+
+procedure SDL_GetWindowSizeInPixels(window: PSDL_Window; w, h: pcuint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowSizeInPixels' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the minimum size of a window's client area.
+ *
+ * min_w The minimum width of the window, must be >0
+ * min_h The minimum height of the window, must be >0
+ *
+ * You can't change the minimum size of a fullscreen window, it
+ * automatically matches the size of the display mode.
+ *
+ * SDL_GetWindowMinimumSize()
+ * SDL_SetWindowMaximumSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowMinimumSize_proc = procedure(window: PSDL_Window; min_w: cint; min_h: cint); cdecl;
+Var
+ SDL_SetWindowMinimumSize : TSDL_SetWindowMinimumSize_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowMinimumSize(window: PSDL_Window; min_w: cint; min_h: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowMinimumSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the minimum size of a window's client area.
+ *
+ * w Pointer to variable for storing the minimum width, may be nil
+ * h Pointer to variable for storing the minimum height, may be nil
+ *
+ * SDL_GetWindowMaximumSize()
+ * SDL_SetWindowMinimumSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowMinimumSize_proc = procedure(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+Var
+ SDL_GetWindowMinimumSize : TSDL_GetWindowMinimumSize_proc = Nil;
+{$else}
+
+procedure SDL_GetWindowMinimumSize(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowMinimumSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the maximum size of a window's client area.
+ *
+ * max_w The maximum width of the window, must be >0
+ * max_h The maximum height of the window, must be >0
+ *
+ * You can't change the maximum size of a fullscreen window, it
+ * automatically matches the size of the display mode.
+ *
+ * SDL_GetWindowMaximumSize()
+ * SDL_SetWindowMinimumSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowMaximumSize_proc = procedure(window: PSDL_Window; max_w: cint; max_h: cint); cdecl;
+Var
+ SDL_SetWindowMaximumSize : TSDL_SetWindowMaximumSize_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowMaximumSize(window: PSDL_Window; max_w: cint; max_h: cint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowMaximumSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the maximum size of a window's client area.
+ *
+ * w Pointer to variable for storing the maximum width, may be nil
+ * h Pointer to variable for storing the maximum height, may be nil
+ *
+ * SDL_GetWindowMinimumSize()
+ * SDL_SetWindowMaximumSize()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowMaximumSize_proc = procedure(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+Var
+ SDL_GetWindowMaximumSize : TSDL_GetWindowMaximumSize_proc = Nil;
+{$else}
+
+procedure SDL_GetWindowMaximumSize(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowMaximumSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the border state of a window.
+ *
+ * This will add or remove the window's SDL_WINDOW_BORDERLESS flag and
+ * add or remove the border from the actual window. This is a no-op if the
+ * window's border already matches the requested state.
+ *
+ * window The window of which to change the border state.
+ * bordered SDL_FALSE to remove border, SDL_TRUE to add border.
+ *
+ * You can't change the border state of a fullscreen window.
+ *
+ * SDL_GetWindowFlags()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowBordered_proc = procedure(window: PSDL_Window; bordered: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowBordered : TSDL_SetWindowBordered_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowBordered(window: PSDL_Window; bordered: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowBordered' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Set the user-resizable state of a window.
+ *
+ * This will add or remove the window's SDL_WINDOW_RESIZABLE flag and
+ * allow/disallow user resizing of the window. This is a no-op if the
+ * window's resizable state already matches the requested state.
+ *
+ * \param window The window of which to change the resizable state.
+ * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow.
+ *
+ * \note You can't change the resizable state of a fullscreen window.
+ *
+ * \sa SDL_GetWindowFlags()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowResizable_proc = procedure(window: PSDL_Window; resizable: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowResizable : TSDL_SetWindowResizable_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowResizable(window: PSDL_Window; resizable: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowResizable' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set the window to always be above the others.
+ *
+ * This will add or remove the window's `SDL_WINDOW_ALWAYS_ON_TOP` flag. This
+ * will bring the window to the front and keep the window above the rest.
+ *
+ * \param window The window of which to change the always on top state
+ * \param on_top SDL_TRUE to set the window always on top, SDL_FALSE to
+ * disable
+ *
+ * \since This function is available since SDL 2.0.16.
+ *
+ * \sa SDL_GetWindowFlags
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowAlwaysOnTop_proc = procedure(window: PSDL_Window; on_top: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowAlwaysOnTop : TSDL_SetWindowAlwaysOnTop_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowAlwaysOnTop(window: PSDL_Window; on_top: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowAlwaysOnTop' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Show a window.
+ *
+ * SDL_HideWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_ShowWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_ShowWindow : TSDL_ShowWindow_proc = Nil;
+{$else}
+
+procedure SDL_ShowWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Hide a window.
+ *
+ * SDL_ShowWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HideWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_HideWindow : TSDL_HideWindow_proc = Nil;
+{$else}
+
+procedure SDL_HideWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HideWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Raise a window above other windows and set the input focus.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RaiseWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_RaiseWindow : TSDL_RaiseWindow_proc = Nil;
+{$else}
+
+procedure SDL_RaiseWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RaiseWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Make a window as large as possible.
+ *
+ * SDL_RestoreWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MaximizeWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_MaximizeWindow : TSDL_MaximizeWindow_proc = Nil;
+{$else}
+
+procedure SDL_MaximizeWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MaximizeWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Minimize a window to an iconic representation.
+ *
+ * SDL_RestoreWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_MinimizeWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_MinimizeWindow : TSDL_MinimizeWindow_proc = Nil;
+{$else}
+
+procedure SDL_MinimizeWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MinimizeWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Restore the size and position of a minimized or maximized window.
+ *
+ * SDL_MaximizeWindow()
+ * SDL_MinimizeWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_RestoreWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_RestoreWindow : TSDL_RestoreWindow_proc = Nil;
+{$else}
+
+procedure SDL_RestoreWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RestoreWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set a window's fullscreen state.
+ *
+ * 0 on success, or -1 if setting the display mode failed.
+ *
+ * SDL_SetWindowDisplayMode()
+ * SDL_GetWindowDisplayMode()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowFullscreen_func = function(window: PSDL_Window; flags: TSDL_WindowFlags): cint; cdecl;
+Var
+ SDL_SetWindowFullscreen : TSDL_SetWindowFullscreen_func = Nil;
+{$else}
+
+function SDL_SetWindowFullscreen(window: PSDL_Window; flags: TSDL_WindowFlags): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowFullscreen' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Return whether the window has a surface associated with it.
+ *
+ * \returns SDL_TRUE if there is a surface associated with the window, or
+ * SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_HasWindowSurface_func = function(window: PSDL_Window): TSDL_Bool; cdecl;
+Var
+ SDL_HasWindowSurface : TSDL_HasWindowSurface_func = Nil;
+{$else}
+
+function SDL_HasWindowSurface(window: PSDL_Window): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasWindowSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the SDL surface associated with the window.
+ *
+ * The window's framebuffer surface, or nil on error.
+ *
+ * A new surface will be created with the optimal format for the window,
+ * if necessary. This surface will be freed when the window is destroyed.
+ *
+ * You may not combine this with 3D or the rendering API on this window.
+ *
+ * SDL_UpdateWindowSurface()
+ * SDL_UpdateWindowSurfaceRects()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowSurface_func = function(window: PSDL_Window): PSDL_Surface; cdecl;
+Var
+ SDL_GetWindowSurface : TSDL_GetWindowSurface_func = Nil;
+{$else}
+
+function SDL_GetWindowSurface(window: PSDL_Window): PSDL_Surface; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Copy the window surface to the screen.
+ *
+ * 0 on success, or -1 on error.
+ *
+ * SDL_GetWindowSurface()
+ * SDL_UpdateWindowSurfaceRects()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UpdateWindowSurface_func = function(window: PSDL_Window): cint; cdecl;
+Var
+ SDL_UpdateWindowSurface : TSDL_UpdateWindowSurface_func = Nil;
+{$else}
+
+function SDL_UpdateWindowSurface(window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateWindowSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Copy a number of rectangles on the window surface to the screen.
+ *
+ * 0 on success, or -1 on error.
+ *
+ * SDL_GetWindowSurface()
+ * SDL_UpdateWindowSurfaceRect()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_UpdateWindowSurfaceRects_func = function(window: PSDL_Window; rects: PSDL_Rect; numrects: cint): cint; cdecl;
+Var
+ SDL_UpdateWindowSurfaceRects : TSDL_UpdateWindowSurfaceRects_func = Nil;
+{$else}
+
+function SDL_UpdateWindowSurfaceRects(window: PSDL_Window; rects: PSDL_Rect; numrects: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateWindowSurfaceRects' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Destroy the surface associated with the window.
+ *
+ * \param window the window to update
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ * \sa SDL_HasWindowSurface
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DestroyWindowSurface_func = function(window: PSDL_Window): cint; cdecl;
+Var
+ SDL_DestroyWindowSurface : TSDL_DestroyWindowSurface_func = Nil;
+{$else}
+
+function SDL_DestroyWindowSurface(window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyWindowSurface' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set a window's input grab mode.
+ *
+ * grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input.
+ *
+ * SDL_GetWindowGrab()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowGrab_proc = procedure(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowGrab : TSDL_SetWindowGrab_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowGrab(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a window's input grab mode.
+ *
+ * This returns SDL_TRUE if input is grabbed, and SDL_FALSE otherwise.
+ *
+ * SDL_SetWindowGrab()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowGrab_func = function(window: PSDL_Window): TSDL_Bool; cdecl;
+Var
+ SDL_GetWindowGrab : TSDL_GetWindowGrab_func = Nil;
+{$else}
+
+function SDL_GetWindowGrab(window: PSDL_Window): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * Set a window's keyboard grab mode.
+ *
+ * Keyboard grab enables capture of system keyboard shortcuts like Alt+Tab or
+ * the Meta/Super key. Note that not all system keyboard shortcuts can be
+ * captured by applications (one example is Ctrl+Alt+Del on Windows).
+ *
+ * This is primarily intended for specialized applications such as VNC clients
+ * or VM frontends. Normal games should not use keyboard grab.
+ *
+ * When keyboard grab is enabled, SDL will continue to handle Alt+Tab when the
+ * window is full-screen to ensure the user is not trapped in your
+ * application. If you have a custom keyboard shortcut to exit fullscreen
+ * mode, you may suppress this behavior with
+ * `SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED`.
+ *
+ * If the caller enables a grab while another window is currently grabbed, the
+ * other window loses its grab in favor of the caller's window.
+ *
+ * \param window The window for which the keyboard grab mode should be set.
+ * \param grabbed This is SDL_TRUE to grab keyboard, and SDL_FALSE to release.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *
+ * \sa SDL_GetWindowKeyboardGrab
+ * \sa SDL_SetWindowMouseGrab
+ * \sa SDL_SetWindowGrab
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowKeyboardGrab_proc = procedure(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowKeyboardGrab : TSDL_SetWindowKeyboardGrab_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowKeyboardGrab(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowKeyboardGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a window's keyboard grab mode.
+ *
+ * Returns SDL_TRUE if keyboard is grabbed, and SDL_FALSE otherwise.
+ *
+ * SDL_SetWindowKeyboardGrab()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowKeyboardGrab_func = function(window: PSDL_Window): TSDL_Bool; cdecl;
+Var
+ SDL_GetWindowKeyboardGrab : TSDL_GetWindowKeyboardGrab_func = Nil;
+{$else}
+
+function SDL_GetWindowKeyboardGrab(window: PSDL_Window): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowKeyboardGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set a window's mouse grab mode.
+ *
+ * window The window for which the mouse grab mode should be set.
+ * grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release.
+ *
+ * SDL_GetWindowMouseGrab()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowMouseGrab_proc = procedure(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+Var
+ SDL_SetWindowMouseGrab : TSDL_SetWindowMouseGrab_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowMouseGrab(window: PSDL_Window; grabbed: TSDL_Bool); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowMouseGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get a window's mouse grab mode.
+ *
+ * Returns SDL_TRUE if mouse is grabbed, and SDL_FALSE otherwise.
+ *
+ * SDL_SetWindowMouseGrab()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowMouseGrab_func = function(window: PSDL_Window): TSDL_Bool; cdecl;
+Var
+ SDL_GetWindowMouseGrab : TSDL_GetWindowMouseGrab_func = Nil;
+{$else}
+
+function SDL_GetWindowMouseGrab(window: PSDL_Window): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowMouseGrab' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Confines the cursor to the specified area of a window.
+ *
+ * window The window that will be associated with the barrier.
+ * rect A rectangle area in window-relative coordinates. If NULL the barrier for the specified window will be destroyed.
+ *
+ * SDL_GetWindowMouseRect()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowMouseRect_proc = procedure(window: PSDL_Window; rect: PSDL_Rect); cdecl;
+Var
+ SDL_SetWindowMouseRect : TSDL_SetWindowMouseRect_proc = Nil;
+{$else}
+
+procedure SDL_SetWindowMouseRect(window: PSDL_Window; rect: PSDL_Rect); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowMouseRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the mouse confinement rectangle of a window.
+ *
+ * Returns A pointer to the mouse confinement rectangle of a window, or NULL if there isn't one.
+ *
+ * SDL_SetWindowMouseRect()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowMouseRect_func = function(window: PSDL_Window): PSDL_Rect; cdecl;
+Var
+ SDL_GetWindowMouseRect : TSDL_GetWindowMouseRect_func = Nil;
+{$else}
+
+function SDL_GetWindowMouseRect(window: PSDL_Window): PSDL_Rect; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowMouseRect' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Get the window that currently has an input grab enabled.
+ *
+ * \return This returns the window if input is grabbed, and NULL otherwise.
+ *
+ * \sa SDL_SetWindowGrab()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetGrabbedWindow_func = function(): PSDL_Window; cdecl;
+Var
+ SDL_GetGrabbedWindow : TSDL_GetGrabbedWindow_func = Nil;
+{$else}
+
+function SDL_GetGrabbedWindow(): PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetGrabbedWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the brightness (gamma correction) for a window.
+ *
+ * 0 on success, or -1 if setting the brightness isn't supported.
+ *
+ * SDL_GetWindowBrightness()
+ * SDL_SetWindowGammaRamp()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowBrightness_func = function(window: PSDL_Window; brightness: cfloat): cint; cdecl;
+Var
+ SDL_SetWindowBrightness : TSDL_SetWindowBrightness_func = Nil;
+{$else}
+
+function SDL_SetWindowBrightness(window: PSDL_Window; brightness: cfloat): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowBrightness' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the brightness (gamma correction) for a window.
+ *
+ * The last brightness value passed to SDL_SetWindowBrightness()
+ *
+ * SDL_SetWindowBrightness()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowBrightness_func = function(window: PSDL_Window): cfloat; cdecl;
+Var
+ SDL_GetWindowBrightness : TSDL_GetWindowBrightness_func = Nil;
+{$else}
+
+function SDL_GetWindowBrightness(window: PSDL_Window): cfloat; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowBrightness' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Set the opacity for a window
+ *
+ * \param window The window which will be made transparent or opaque
+ * \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be
+ * clamped internally between 0.0f and 1.0f.
+ *
+ * \return 0 on success, or -1 if setting the opacity isn't supported.
+ *
+ * \sa SDL_GetWindowOpacity()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowOpacity_func = function(window: PSDL_Window; opacity: cfloat): cint; cdecl;
+Var
+ SDL_SetWindowOpacity : TSDL_SetWindowOpacity_func = Nil;
+{$else}
+
+function SDL_SetWindowOpacity(window: PSDL_Window; opacity: cfloat): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowOpacity' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Get the opacity of a window.
+ *
+ * If transparency isn't supported on this platform, opacity will be reported
+ * as 1.0f without error.
+ *
+ * \param window The window in question.
+ * \param out_opacity Opacity (0.0f - transparent, 1.0f - opaque)
+ *
+ * \return 0 on success, or -1 on error (invalid window, etc).
+ *
+ * \sa SDL_SetWindowOpacity()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowOpacity_func = function(window: PSDL_Window; out_opacity: pcfloat): cint; cdecl;
+Var
+ SDL_GetWindowOpacity : TSDL_GetWindowOpacity_func = Nil;
+{$else}
+
+function SDL_GetWindowOpacity(window: PSDL_Window; out_opacity: pcfloat): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowOpacity' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Sets the window as a modal for another window
+ *
+ * \param modal_window The window that should be modal
+ * \param parent_window The parent window
+ *
+ * \return 0 on success, or -1 otherwise.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowModalFor_func = function(modal_window, parent_window: PSDL_Window): cint; cdecl;
+Var
+ SDL_SetWindowModalFor : TSDL_SetWindowModalFor_func = Nil;
+{$else}
+
+function SDL_SetWindowModalFor(modal_window, parent_window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowModalFor' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * \brief Explicitly sets input focus to the window.
+ *
+ * You almost certainly want SDL_RaiseWindow() instead of this function. Use
+ * this with caution, as you might give focus to a window that's completely
+ * obscured by other windows.
+ *
+ * \param window The window that should get the input focus
+ *
+ * \return 0 on success, or -1 otherwise.
+ * \sa SDL_RaiseWindow()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowInputFocus_func = function(window: PSDL_Window): cint; cdecl;
+Var
+ SDL_SetWindowInputFocus : TSDL_SetWindowInputFocus_func = Nil;
+{$else}
+
+function SDL_SetWindowInputFocus(window: PSDL_Window): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowInputFocus' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the gamma ramp for a window.
+ *
+ * red The translation table for the red channel, or nil.
+ * green The translation table for the green channel, or nil.
+ * blue The translation table for the blue channel, or nil.
+ *
+ * 0 on success, or -1 if gamma ramps are unsupported.
+ *
+ * Set the gamma translation table for the red, green, and blue channels
+ * of the video hardware. Each table is an array of 256 16-bit quantities,
+ * representing a mapping between the input and output for that channel.
+ * The input is the index into the array, and the output is the 16-bit
+ * gamma value at that index, scaled to the output color precision.
+ *
+ * SDL_GetWindowGammaRamp()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowGammaRamp_func = function(window: PSDL_Window; const red: pcuint16; const green: pcuint16; const blue: pcuint16): cint; cdecl;
+Var
+ SDL_SetWindowGammaRamp : TSDL_SetWindowGammaRamp_func = Nil;
+{$else}
+
+function SDL_SetWindowGammaRamp(window: PSDL_Window; const red: pcuint16; const green: pcuint16; const blue: pcuint16): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowGammaRamp' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the gamma ramp for a window.
+ *
+ * red A pointer to a 256 element array of 16-bit quantities to hold
+ * the translation table for the red channel, or nil.
+ * green A pointer to a 256 element array of 16-bit quantities to hold
+ * the translation table for the green channel, or nil.
+ * blue A pointer to a 256 element array of 16-bit quantities to hold
+ * the translation table for the blue channel, or nil.
+ *
+ * 0 on success, or -1 if gamma ramps are unsupported.
+ *
+ * SDL_SetWindowGammaRamp()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GetWindowGammaRamp_func = function(window: PSDL_Window; red: pcuint16; green: pcuint16; blue: pcuint16): cint; cdecl;
+Var
+ SDL_GetWindowGammaRamp : TSDL_GetWindowGammaRamp_func = Nil;
+{$else}
+
+function SDL_GetWindowGammaRamp(window: PSDL_Window; red: pcuint16; green: pcuint16; blue: pcuint16): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowGammaRamp' {$ENDIF} {$ENDIF};
+{$endif}
+
+{**
+ * \brief Possible return values from the SDL_HitTest callback.
+ *
+ * \sa SDL_HitTest
+ *}
+type
+ PPSDL_HitTestResult = ^PSDL_HitTestResult;
+ PSDL_HitTestResult = ^TSDL_HitTestResult;
+ TSDL_HitTestResult = type Integer;
+
+const
+ SDL_HITTEST_NORMAL = TSDL_HitTestResult(0); {**< Region is normal. No special properties. *}
+ SDL_HITTEST_DRAGGABLE = TSDL_HitTestResult(1); {**< Region can drag entire window. *}
+ SDL_HITTEST_RESIZE_TOPLEFT = TSDL_HitTestResult(2);
+ SDL_HITTEST_RESIZE_TOP = TSDL_HitTestResult(3);
+ SDL_HITTEST_RESIZE_TOPRIGHT = TSDL_HitTestResult(4);
+ SDL_HITTEST_RESIZE_RIGHT = TSDL_HitTestResult(5);
+ SDL_HITTEST_RESIZE_BOTTOMRIGHT = TSDL_HitTestResult(6);
+ SDL_HITTEST_RESIZE_BOTTOM = TSDL_HitTestResult(7);
+ SDL_HITTEST_RESIZE_BOTTOMLEFT = TSDL_HitTestResult(8);
+ SDL_HITTEST_RESIZE_LEFT = TSDL_HitTestResult(9);
+
+ {**
+ * \brief Callback used for hit-testing.
+ *
+ * \sa SDL_SetWindowHitTest
+ *}
+type
+ PPSDL_HitTest = ^PSDL_HitTest;
+ PSDL_HitTest = ^TSDL_HitTest;
+ TSDL_HitTest = function(win: PSDL_Window; const area: PSDL_Point; data: Pointer): TSDL_HitTestResult; cdecl;
+
+ {**
+ * \brief Provide a callback that decides if a window region has special properties.
+ *
+ * Normally windows are dragged and resized by decorations provided by the
+ * system window manager (a title bar, borders, etc), but for some apps, it
+ * makes sense to drag them from somewhere else inside the window itself; for
+ * example, one might have a borderless window that wants to be draggable
+ * from any part, or simulate its own title bar, etc.
+ *
+ * This function lets the app provide a callback that designates pieces of
+ * a given window as special. This callback is run during event processing
+ * if we need to tell the OS to treat a region of the window specially; the
+ * use of this callback is known as "hit testing."
+ *
+ * Mouse input may not be delivered to your application if it is within
+ * a special area; the OS will often apply that input to moving the window or
+ * resizing the window and not deliver it to the application.
+ *
+ * Specifying NULL for a callback disables hit-testing. Hit-testing is
+ * disabled by default.
+ *
+ * Platforms that don't support this functionality will return -1
+ * unconditionally, even if you're attempting to disable hit-testing.
+ *
+ * Your callback may fire at any time, and its firing does not indicate any
+ * specific behavior (for example, on Windows, this certainly might fire
+ * when the OS is deciding whether to drag your window, but it fires for lots
+ * of other reasons, too, some unrelated to anything you probably care about
+ * _and when the mouse isn't actually at the location it is testing_).
+ * Since this can fire at any time, you should try to keep your callback
+ * efficient, devoid of allocations, etc.
+ *
+ * \param window The window to set hit-testing on.
+ * \param callback The callback to call when doing a hit-test.
+ * \param callback_data An app-defined void pointer passed to the callback.
+ * \return 0 on success, -1 on error (including unsupported).
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_SetWindowHitTest_func = function(window: PSDL_Window; callback: TSDL_HitTest; callback_data: Pointer): cint; cdecl;
+Var
+ SDL_SetWindowHitTest : TSDL_SetWindowHitTest_func = Nil;
+{$else}
+
+function SDL_SetWindowHitTest(window: PSDL_Window; callback: TSDL_HitTest; callback_data: Pointer): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowHitTest' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Request a window to demand attention from the user.
+ *
+ * \param window the window to be flashed
+ * \param operation the flash operation
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.0.16.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_FlashWindow_func = function(window: PSDL_Window; operation: TSDL_FlashOperation): cint; cdecl;
+Var
+ SDL_FlashWindow : TSDL_FlashWindow_func = Nil;
+{$else}
+
+function SDL_FlashWindow(window: PSDL_Window; operation: TSDL_FlashOperation): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlashWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Destroy a window.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DestroyWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_DestroyWindow : TSDL_DestroyWindow_proc = Nil;
+{$else}
+
+procedure SDL_DestroyWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Returns whether the screensaver is currently enabled (default on).
+ *
+ * SDL_EnableScreenSaver()
+ * SDL_DisableScreenSaver()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_IsScreenSaverEnabled_func = function : TSDL_Bool; cdecl;
+Var
+ SDL_IsScreenSaverEnabled : TSDL_IsScreenSaverEnabled_func = Nil;
+{$else}
+function SDL_IsScreenSaverEnabled: TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsScreenSaverEnabled' {$ENDIF} {$ENDIF};
+{$endif}
+ {**
+ * Allow the screen to be blanked by a screensaver
+ *
+ * SDL_IsScreenSaverEnabled()
+ * SDL_DisableScreenSaver()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_EnableScreenSaver_proc = procedure ; cdecl;
+Var
+ SDL_EnableScreenSaver : TSDL_EnableScreenSaver_proc = Nil;
+{$else}
+procedure SDL_EnableScreenSaver; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EnableScreenSaver' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Prevent the screen from being blanked by a screensaver
+ *
+ * SDL_IsScreenSaverEnabled()
+ * SDL_EnableScreenSaver()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_DisableScreenSaver_proc =procedure ; cdecl;
+Var
+ SDL_DisableScreenSaver : TSDL_DisableScreenSaver_proc = Nil;
+{$else}
+procedure SDL_DisableScreenSaver; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DisableScreenSaver' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * OpenGL support functions
+ *}
+
+ {**
+ * Dynamically load an OpenGL library.
+ *
+ * path The platform dependent OpenGL library name, or nil to open the
+ * default OpenGL library.
+ *
+ * 0 on success, or -1 if the library couldn't be loaded.
+ *
+ * This should be done after initializing the video driver, but before
+ * creating any OpenGL windows. If no OpenGL library is loaded, the default
+ * library will be loaded upon creation of the first OpenGL window.
+ *
+ * If you do this, you need to retrieve all of the GL functions used in
+ * your program from the dynamic library using SDL_GL_GetProcAddress().
+ *
+ * SDL_GL_GetProcAddress()
+ * SDL_GL_UnloadLibrary()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_LoadLibrary_func = function(const path: PAnsiChar): cint; cdecl;
+Var
+ SDL_GL_LoadLibrary : TSDL_GL_LoadLibrary_func = Nil;
+{$else}
+
+function SDL_GL_LoadLibrary(const path: PAnsiChar): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_LoadLibrary' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the address of an OpenGL function.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetProcAddress_func = function(const proc: PAnsiChar): Pointer; cdecl;
+Var
+ SDL_GL_GetProcAddress : TSDL_GL_GetProcAddress_func = Nil;
+{$else}
+
+function SDL_GL_GetProcAddress(const proc: PAnsiChar): Pointer; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetProcAddress' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary().
+ *
+ * SDL_GL_LoadLibrary()
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_UnloadLibrary_proc = procedure ; cdecl;
+Var
+ SDL_GL_UnloadLibrary : TSDL_GL_UnloadLibrary_proc = Nil;
+{$else}
+
+procedure SDL_GL_UnloadLibrary; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_UnloadLibrary' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Return true if an OpenGL extension is supported for the current
+ * context.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_ExtensionSupported_func = function(const extension: PAnsiChar): TSDL_Bool; cdecl;
+Var
+ SDL_GL_ExtensionSupported : TSDL_GL_ExtensionSupported_func = Nil;
+{$else}
+
+function SDL_GL_ExtensionSupported(const extension: PAnsiChar): TSDL_Bool; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_ExtensionSupported' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Reset all previously set OpenGL context attributes to their default values
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_ResetAttributes_proc = procedure(); cdecl;
+Var
+ SDL_GL_ResetAttributes : TSDL_GL_ResetAttributes_proc = Nil;
+{$else}
+
+procedure SDL_GL_ResetAttributes(); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_ResetAttributes' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set an OpenGL window attribute before window creation.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_SetAttribute_func = function(attr: TSDL_GLattr; value: cint): cint; cdecl;
+Var
+ SDL_GL_SetAttribute : TSDL_GL_SetAttribute_func = Nil;
+{$else}
+
+function SDL_GL_SetAttribute(attr: TSDL_GLattr; value: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_SetAttribute' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the actual value for an attribute from the current context.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetAttribute_func = function(attr: TSDL_GLattr; value: pcint): cint; cdecl;
+Var
+ SDL_GL_GetAttribute : TSDL_GL_GetAttribute_func = Nil;
+{$else}
+
+function SDL_GL_GetAttribute(attr: TSDL_GLattr; value: pcint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetAttribute' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Create an OpenGL context for use with an OpenGL window, and make it
+ * current.
+ *
+ * SDL_GL_DeleteContext()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_CreateContext_func = function(window: PSDL_Window): TSDL_GLContext; cdecl;
+Var
+ SDL_GL_CreateContext : TSDL_GL_CreateContext_func = Nil;
+{$else}
+
+function SDL_GL_CreateContext(window: PSDL_Window): TSDL_GLContext; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_CreateContext' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set up an OpenGL context for rendering into an OpenGL window.
+ *
+ * The context must have been created with a compatible window.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_MakeCurrent_func = function(window: PSDL_Window; context: TSDL_GLContext): cint; cdecl;
+Var
+ SDL_GL_MakeCurrent : TSDL_GL_MakeCurrent_func = Nil;
+{$else}
+
+function SDL_GL_MakeCurrent(window: PSDL_Window; context: TSDL_GLContext): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_MakeCurrent' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the currently active OpenGL window.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetCurrentWindow_func = function : PSDL_Window; cdecl;
+Var
+ SDL_GL_GetCurrentWindow : TSDL_GL_GetCurrentWindow_func = Nil;
+{$else}
+function SDL_GL_GetCurrentWindow: PSDL_Window; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetCurrentWindow' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Get the currently active OpenGL context.
+ *}
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetCurrentContext_func = function : TSDL_GLContext; cdecl;
+Var
+ SDL_GL_GetCurrentContext : TSDL_GL_GetCurrentContext_func = Nil;
+{$else}
+function SDL_GL_GetCurrentContext: TSDL_GLContext; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetCurrentContext' {$ENDIF} {$ENDIF};
+ {$endif}
+ {**
+ * Get the size of a window's underlying drawable in pixels (for use
+ * with glViewport).
+ *
+ * window Window from which the drawable size should be queried
+ * w Pointer to variable for storing the width in pixels, may be NULL
+ * h Pointer to variable for storing the height in pixels, may be NULL
+ *
+ * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI
+ * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a
+ * platform with high-DPI support (Apple calls this "Retina"), and not disabled
+ * by the SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
+ *
+ * SDL_GetWindowSize()
+ * SDL_CreateWindow()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetDrawableSize_proc = procedure(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+Var
+ SDL_GL_GetDrawableSize : TSDL_GL_GetDrawableSize_proc = Nil;
+{$else}
+
+procedure SDL_GL_GetDrawableSize(window: PSDL_Window; w: pcint; h: pcint); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetDrawableSize' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Set the swap interval for the current OpenGL context.
+ *
+ * interval 0 for immediate updates, 1 for updates synchronized with the
+ * vertical retrace. If the system supports it, you may
+ * specify -1 to allow late swaps to happen immediately
+ * instead of waiting for the next retrace.
+ *
+ * 0 on success, or -1 if setting the swap interval is not supported.
+ *
+ * SDL_GL_GetSwapInterval()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_SetSwapInterval_func = function(interval: cint): cint; cdecl;
+Var
+ SDL_GL_SetSwapInterval : TSDL_GL_SetSwapInterval_func = Nil;
+{$else}
+
+function SDL_GL_SetSwapInterval(interval: cint): cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_SetSwapInterval' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Get the swap interval for the current OpenGL context.
+ *
+ * 0 if there is no vertical retrace synchronization, 1 if the buffer
+ * swap is synchronized with the vertical retrace, and -1 if late
+ * swaps happen immediately instead of waiting for the next retrace.
+ * If the system can't determine the swap interval, or there isn't a
+ * valid current context, this will return 0 as a safe default.
+ *
+ * SDL_GL_SetSwapInterval()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_GetSwapInterval_func = function : cint; cdecl;
+Var
+ SDL_GL_GetSwapInterval : TSDL_GL_GetSwapInterval_func = Nil;
+{$else}
+function SDL_GL_GetSwapInterval: cint; cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_GetSwapInterval' {$ENDIF} {$ENDIF};
+{$endif}
+ {**
+ * Swap the OpenGL buffers for a window, if double-buffering is
+ * supported.
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_SwapWindow_proc = procedure(window: PSDL_Window); cdecl;
+Var
+ SDL_GL_SwapWindow : TSDL_GL_SwapWindow_proc = Nil;
+{$else}
+
+procedure SDL_GL_SwapWindow(window: PSDL_Window); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_SwapWindow' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {**
+ * Delete an OpenGL context.
+ *
+ * SDL_GL_CreateContext()
+ *}
+
+{$ifdef SDL_RUNTIME_LOADING}
+Type
+ TSDL_GL_DeleteContext_proc = procedure(context: TSDL_GLContext); cdecl;
+Var
+ SDL_GL_DeleteContext : TSDL_GL_DeleteContext_proc = Nil;
+{$else}
+
+procedure SDL_GL_DeleteContext(context: TSDL_GLContext); cdecl;
+ external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GL_DeleteContext' {$ENDIF} {$ENDIF};
+{$endif}
+
+ {*OpenGL support functions*}
diff --git a/units/uatomic_common.pas b/units/uatomic_common.pas
index c34089d..fa7de62 100644
--- a/units/uatomic_common.pas
+++ b/units/uatomic_common.pas
@@ -12,6 +12,11 @@
(* source file of the project. *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit uatomic_common;
{$MODE ObjFPC}{$H+}
@@ -21,7 +26,19 @@
{$I ../client/globaldefines.inc}
Uses
- Classes, SysUtils, ulogger, Graphics, ugraphics, uvectormath;
+ Classes, SysUtils, ulogger, uvectormath
+{$IFNDEF Server}
+ , Graphics, ugraphics
+{$ENDIF}
+ ;
+
+{$IFDEF Server}
+Type
+ TColor = LongWord;
+ TRGB = Record
+ r, g, b: Byte;
+ End;
+{$ENDIF}
Const
(*
@@ -140,9 +157,9 @@
ChunkManagerHeaderLen = 12; // uChunkmanager.pas HeaderLen = 12
FrameRate = 10; // Zeit in ms bis ein neues Frame berechnet wird
- UpdateRate = 40; // Zeit in ms bis die Clients wieder Aktualisiert werden
+ UpdateRate = 20; // Zeit in ms bis die Clients wieder Aktualisiert werden (50 FPS for smoother gameplay)
- SynchonizeTimeOut = 150; // Zeit in ms Kommt mehr als 150ms lang keine Heartbeat Message von allen Clients, dann wird eine Zwangspause eingeleitet.
+ SynchonizeTimeOut = 800; // Zeit in ms Kommt mehr als 800ms lang keine Heartbeat Message von allen Clients, dann wird eine Zwangspause eingeleitet. (Increased for older machines) (increased for online play over internet)
HeartBeatTime = 100; // Zeit in ms Muss Sinnigerweise << SynchonizeTimeOut sein.
AtomicActionDoubleTime = 200; // Zeit in ms die zwischen 2 Tastendrücken liegen muss damit sie als "Doppelte" erkannt werden.
@@ -246,7 +263,9 @@
* Diese Farben sind nur im Range 0..100
* Wenn sie als TColor genutzt werden sollen, müssen sie noch durch
*
- * Function AtomicPlayerColorToColor(aColor: TRGB): TColor;
+ * {$IFNDEF Server}
+Function AtomicPlayerColorToColor(aColor: TRGB): TColor;
+{$ENDIF}
*
*)
{$IFDEF Only3Player}
@@ -516,6 +535,8 @@
TKeySet = (
ks0 // Keyboard 0
, ks1 // Keyboard 1
+ , ksJoy1 // Joystick 1
+ , ksJoy2 // Joystick 2
);
TPlayer = Record
@@ -631,7 +652,9 @@
Function SchemeFromStream(Const Stream: TStream; Out Scheme: TScheme): Boolean;
Function GetDefaultScheme(): TScheme;
+{$IFNDEF Server}
Function AtomicPlayerColorToColor(aColor: TRGB): TColor;
+{$ENDIF}
{$IFNDEF Server} // Das nutzt auch der Launcher, also darf hier nicht auf Client geprüft werden sondern es muss nicht server sein ;)
Function AtomicDefaultKeys(Index: TKeySet): TKeys;
@@ -722,7 +745,10 @@
End;
{$ENDIF}
+{$IFNDEF Server}
+{$IFNDEF Server}
Function AtomicPlayerColorToColor(aColor: TRGB): TColor;
+{$ENDIF}
Var
r, g, b: integer;
Begin
@@ -731,6 +757,7 @@
b := min(255, round(aColor.b * 2.55));
result := Graphics.RGBToColor(r, g, b);
End;
+{$ENDIF}
Procedure SchemeToStream(Const Stream: TStream; Const Scheme: TScheme);
Begin
diff --git a/units/uatomic_field.pas b/units/uatomic_field.pas
index 3f6c38b..33bf09c 100644
--- a/units/uatomic_field.pas
+++ b/units/uatomic_field.pas
@@ -1,2305 +1,2447 @@
-(******************************************************************************)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* This file is part of FPC_Atomic *)
-(* *)
-(* See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(******************************************************************************)
-Unit uatomic_field;
-
-{$MODE ObjFPC}{$H+}
-
-Interface
-
-Uses
- Classes, SysUtils
-{$IFDEF Client}
- , uopengl_animation
- , uatomic
-{$ENDIF}
- , uatomic_common
-{$IFDEF Server}
- , ufifo, uvectormath
- , uai_types
-{$ENDIF}
-
- ;
-
-Type
-
-{$IFDEF Server}
- TIntFifo = specialize TBufferedFifo < Integer > ;
- TPointFifo = specialize TBufferedFifo < Tpoint > ;
- TPlaySoundEffectCallback = Procedure(PlayerIndex: integer; Effect: TSoundEffect) Of Object;
-{$ENDIF}
-
-{$IFDEF Client}
- TBrickAnimation = Record
- ani: TOpenGL_Animation;
- Active: Boolean;
- End;
-{$ENDIF}
-
- { TAtomicField }
-
- TAtomicField = Class
- private
-{$IFDEF Server}
- fBombsEnabled: Boolean;
- fBombs: Array[0..FieldWidth * FieldHeight - 1] Of TBombInfo; // Das Array ist eigentlich hoch Dynamisch, aber so allokieren wir nicht andauernd neuen Speicher
- fBombCount: Integer;
- fBombDetonateFifo: TIntFifo;
- fPowerUpClearFifo: TPointFifo;
- fPlaySoundEffect: TPlaySoundEffectCallback;
- fHurryIndex: integer; // Der Index in der HurryCoords Konstante, wenn Hurry Aktiv ist.
-{$ENDIF}
- fHasArrows: Boolean; // Wenn True, dann hat die Karte die Lustigen Pfeilchen auf denen die Bomben hin und her geschubst werden..
- fArrowDirs: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of integer; // Die Richtungen der "Pfeile" -1 = Aus, 0, 90, 180, 270 = Winkel
- fHasConveyors: Boolean; // Wenn True, dann hat die Karte diese Blauen Fließbänder auf denen Spieler und Bomben automatisch bewegt werden (geschwindigkeit via Settings einstellbar)
- fConveyorDirs: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of integer; // Die Richtungen der "Pfeile" -1 = Aus, 0, 90, 180, 270 = Winkel
- fHasHoles: Boolean; // Wenn True, dann hat die Karte die 4 Löcher, welche den Atomic im Gegenuhrzeigersinn hin und her beamen
- fHastrampolins: Boolean; // Wenn True, dann hat die Karte "trampoline"
- fHoles: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of boolean; // True, an dieser Stelle wird ein "Loch" gezeichnet
-{$IFDEF Client}
- fTrampStaticSprite, fHoleTex, fFieldTex, fBrickTex, fSolidTex: integer;
- fxBricks: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of TBrickAnimation;
- fxBrickAniTime: integer;
- fPreviewLines: Array[0..4] Of String;
- fTramp, fArrows, fConveyors: TOpenGL_Animation;
-{$ENDIF}
- fSoundFile: String;
- fHash: Uint64; // Wird beim laden der Karte berechnet, dient zur Identifizierung auf "Gleichheit"
- fField: TFieldBricks;
-{$IFDEF Client}
- Procedure RenderBlock(x, y: integer; Brick: TBrickData);
- Function OnxBrickOverflow(Sender: TObject): Boolean;
-{$ENDIF}
-{$IFDEF Server}
- (*
- * False, wenn der Strahl gestoppt wird und nicht mehr "weiter" Laufen darf
- *)
- Function Detonate(x, y: integer; TriggerPlayerindex, ColorIndex: integer; Flame: TFlame): Boolean;
- Function FielWalkable(x, y: integer; AlsoCheckPowerUps: Boolean): Boolean;
-{$ENDIF}
- public
- Name: String;
- Available: Boolean; // Wenn True, dann kann die Karte verwendet werden und Alle Spieler haben sie.
-{$IFDEF Server}
- StatisticCallback: TStatisticCallback;
- Property BombsEnabled: Boolean read fBombsEnabled;
-{$ENDIF}
- Property Hash: UInt64 read fHash; // Pseudo MD5Hash über alle Dateien der Karte
- Property Sound: String read fSoundFile;
- Constructor Create(
-{$IFDEF Server}
- PlaySoundEffectCallback: TPlaySoundEffectCallback;
- sStatisticCallback: TStatisticCallback
-{$ENDIF}
- ); virtual;
-
- Destructor Destroy(); override;
- Function loadFromDirectory(Dir: String
-{$IFDEF Client}
- ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
-{$ENDIF}
- ): Boolean;
-{$IFDEF Client}
- Procedure RenderPreview; virtual;
- Procedure Render(Const Atomics: TAtomics; PowerTexs: TPowerTexArray);
- Procedure ReadGameingData(Const Stream: TStream);
- Procedure Reset(); // Wie Initialize nur eben die Client version
-{$ENDIF}
-{$IFDEF Server}
- Procedure Initialize(Const Players: TPlayers; Const Scheme: TScheme); // Setzt die Spielerpositionen gleich mit
- Procedure AppendGamingData(Const Stream: TStream);
- Function HandleMovePlayer(Var Players: TPlayers; PlayerIndex: integer; ConveyorSpeed: TConveyorSpeed): Boolean; // True, wenn der Spieler gestorben ist.
- Procedure HandleActionPlayer(Var Player: TPlayer; PlayerIndex: integer);
- Procedure HandleBombs(Var Players: TPlayers; PreHurry: Boolean; ConveyorSpeed: TConveyorSpeed);
- Procedure HandlePlayerVsMap(Var Players: TPlayers; PlayerGetsPowerUp: TPlayerGetsPowerUpEvent);
- Procedure HandleFieldAnims;
- Procedure DisableAllBombs();
- Function GetAiInfo(Const Players: TPlayers; TeamPlay: Boolean): TaiInfo;
- Procedure IncHurry();
- Procedure KillPlayer(Var Players: TPlayers; Index: integer); // Ohne Punktewertung
- Procedure RepopulatePlayersCollectedPowerUps(Const Players: TPlayers; PlayerIndex: Integer);
- Procedure TelePortPlayer(Var Player: TPlayer);
-{$ENDIF}
- End;
-
- { TAtomicRandomField }
-
- TAtomicRandomField = Class(TAtomicField)
- private
-{$IFDEF Client}
- fPreviewGrid: Array[0..4, 0..4] Of Integer;
-{$ENDIF}
- public
-{$IFDEF Client}
- Procedure CreatePreview(Const Fields: Array Of TAtomicField);
- Procedure RenderPreview; override;
-{$ENDIF}
- End;
-
-Implementation
-
-Uses
- Graphics, IniFiles, md5
-{$IFDEF server}
- , math
-{$ENDIF}
-{$IFDEF Client}
- , uvectormath
- , dglOpenGL
- , uopengl_graphikengine
- , uopengl_spriteengine
- , ugraphics
-{$ENDIF}
- ;
-
-{$IFDEF server}
-Const
- (*
- * Beschreibt einen Weg von Links oben schneckenmäßig im Uhrzeigersinn bis nach innen rein, bis nur noch 5 Felder in der Mitte ügrig sind.
- *)
- HurryCoords: Array[0..159] Of Tpoint = (
- (x: 0; y: 0), (x: 1; y: 0), (x: 2; y: 0), (x: 3; y: 0), (x: 4; y: 0), (x: 5; y: 0), (x: 6; y: 0), (x: 7; y: 0), (x: 8; y: 0), (x: 9; y: 0), (x: 10; y: 0), (x: 11; y: 0), (x: 12; y: 0), (x: 13; y: 0), (x: 14; y: 0),
- (x: 14; y: 1), (x: 14; y: 2), (x: 14; y: 3), (x: 14; y: 4), (x: 14; y: 5), (x: 14; y: 6), (x: 14; y: 7), (x: 14; y: 8), (x: 14; y: 9), (x: 14; y: 10),
- (x: 13; y: 10), (x: 12; y: 10), (x: 11; y: 10), (x: 10; y: 10), (x: 9; y: 10), (x: 8; y: 10), (x: 7; y: 10), (x: 6; y: 10), (x: 5; y: 10), (x: 4; y: 10), (x: 3; y: 10), (x: 2; y: 10), (x: 1; y: 10), (x: 0; y: 10),
- (x: 0; y: 9), (x: 0; y: 8), (x: 0; y: 7), (x: 0; y: 6), (x: 0; y: 5), (x: 0; y: 4), (x: 0; y: 3), (x: 0; y: 2), (x: 0; y: 1),
- (x: 1; y: 1), (x: 2; y: 1), (x: 3; y: 1), (x: 4; y: 1), (x: 5; y: 1), (x: 6; y: 1), (x: 7; y: 1), (x: 8; y: 1), (x: 9; y: 1), (x: 10; y: 1), (x: 11; y: 1), (x: 12; y: 1), (x: 13; y: 1),
- (x: 13; y: 2), (x: 13; y: 3), (x: 13; y: 4), (x: 13; y: 5), (x: 13; y: 6), (x: 13; y: 7), (x: 13; y: 8), (x: 13; y: 9),
- (x: 12; y: 9), (x: 11; y: 9), (x: 10; y: 9), (x: 9; y: 9), (x: 8; y: 9), (x: 7; y: 9), (x: 6; y: 9), (x: 5; y: 9), (x: 4; y: 9), (x: 3; y: 9), (x: 2; y: 9), (x: 1; y: 9),
- (x: 1; y: 8), (x: 1; y: 7), (x: 1; y: 6), (x: 1; y: 5), (x: 1; y: 4), (x: 1; y: 3), (x: 1; y: 2),
- (x: 2; y: 2), (x: 3; y: 2), (x: 4; y: 2), (x: 5; y: 2), (x: 6; y: 2), (x: 7; y: 2), (x: 8; y: 2), (x: 9; y: 2), (x: 10; y: 2), (x: 11; y: 2), (x: 12; y: 2),
- (x: 12; y: 3), (x: 12; y: 4), (x: 12; y: 5), (x: 12; y: 6), (x: 12; y: 7), (x: 12; y: 8),
- (x: 11; y: 8), (x: 10; y: 8), (x: 9; y: 8), (x: 8; y: 8), (x: 7; y: 8), (x: 6; y: 8), (x: 5; y: 8), (x: 4; y: 8), (x: 3; y: 8), (x: 2; y: 8),
- (x: 2; y: 7), (x: 2; y: 6), (x: 2; y: 5), (x: 2; y: 4), (x: 2; y: 3),
- (x: 3; y: 3), (x: 4; y: 3), (x: 5; y: 3), (x: 6; y: 3), (x: 7; y: 3), (x: 8; y: 3), (x: 9; y: 3), (x: 10; y: 3), (x: 11; y: 3),
- (x: 11; y: 4), (x: 11; y: 5), (x: 11; y: 6), (x: 11; y: 7),
- (x: 10; y: 7), (x: 9; y: 7), (x: 8; y: 7), (x: 7; y: 7), (x: 6; y: 7), (x: 5; y: 7), (x: 4; y: 7), (x: 3; y: 7),
- (x: 3; y: 6), (x: 3; y: 5), (x: 3; y: 4),
- (x: 4; y: 4), (x: 5; y: 4), (x: 6; y: 4), (x: 7; y: 4), (x: 8; y: 4), (x: 9; y: 4), (x: 10; y: 4),
- (x: 10; y: 5), (x: 10; y: 6),
- (x: 9; y: 6), (x: 8; y: 6), (x: 7; y: 6), (x: 6; y: 6), (x: 5; y: 6), (x: 4; y: 6),
- (x: 4; y: 5)
- );
-{$ENDIF}
-
-{$IFDEF Client}
-
- { TAtomicRandomField }
-
-Procedure TAtomicRandomField.CreatePreview(Const Fields: Array Of TAtomicField);
-Var
- index, i, j: Integer;
-Begin
- // Irgend eine Hintergrund Graphik Wählen
- fFieldTex := Fields[random(Length(Fields))].fFieldTex;
- // Irgend welche Bricks / Solids nehmen
- For i := 0 To 4 Do Begin
- For j := 0 To 4 Do Begin
- index := random(Length(Fields));
- If ((i = 1) And (j = 1)) Or
- ((i = 3) And (j = 1)) Or
- ((i = 1) And (j = 3)) Or
- ((i = 3) And (j = 3)) Then Begin
- fPreviewGrid[i, j] := Fields[index].fSolidTex;
- End
- Else Begin
- fPreviewGrid[i, j] := Fields[index].fBrickTex;
- End;
- End;
- End;
- // Ein Paar Felder sollen auch "Leer" bleiben
- fPreviewGrid[0, 0] := 0;
- fPreviewGrid[1, 0] := 0;
- fPreviewGrid[0, 1] := 0;
- fPreviewGrid[0, 3] := 0;
- fPreviewGrid[1, 4] := 0;
-End;
-
-Procedure TAtomicRandomField.RenderPreview;
-
-Var
- j, i: Integer;
-Begin
- (*
- * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
- *)
- glColor3f(1, 1, 1);
- glpushmatrix();
- glTranslatef(0, 0, atomic_Map_Layer);
- RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
- For j := 0 To 4 Do Begin
- For i := 0 To 4 Do Begin
- If fPreviewGrid[i, j] = 0 Then Continue;
- glPushMatrix;
- glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, atomic_EPSILON);
- RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fPreviewGrid[i, j]);
- glPopMatrix;
- End;
- End;
- glpopmatrix();
-End;
-{$ENDIF}
-
-{ TAtomicField }
-
-// Die IDE Code vervollständigung killt manchmal den Korrekten Header, deswegen hier die "Kopiervorlage"
-//Constructor TAtomicField.Create(
-//{$IFDEF Server}
-// PlaySoundEffectCallback: TPlaySoundEffectCallback;
-// sStatisticCallback: TStatisticCallback
-//{$ENDIF}
-// );
-
-Constructor TAtomicField.Create(
-{$IFDEF Server}
- PlaySoundEffectCallback: TPlaySoundEffectCallback;
- sStatisticCallback: TStatisticCallback
-{$ENDIF}
- );
-Var
- i, j: integer;
-Begin
-{$IFDEF Client}
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- fxBricks[i, j].ani := Nil;
- End;
- End;
-{$ENDIF}
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- fArrowDirs[i, j] := -1;
- fConveyorDirs[i, j] := -1;
- fHoles[i, j] := false;
- End;
- End;
- // Die 4 Löcher
- fHoles[2, 2] := true;
- fHoles[12, 2] := true;
- fHoles[12, 8] := true;
- fHoles[2, 8] := true;
- // Alle nach Rechts
- fArrowDirs[2, 0] := 0;
- fArrowDirs[6, 0] := 0;
- fArrowDirs[10, 0] := 0;
- fArrowDirs[0, 2] := 0;
- fArrowDirs[4, 2] := 0;
- fArrowDirs[8, 2] := 0;
- fArrowDirs[12, 2] := 0;
- fArrowDirs[4, 4] := 0;
- fArrowDirs[0, 6] := 0;
- fArrowDirs[8, 6] := 0;
- fArrowDirs[12, 6] := 0;
- // Alle nach Oben
- fArrowDirs[2, 2] := 90;
- fArrowDirs[6, 2] := 90;
- fArrowDirs[10, 2] := 90;
- fArrowDirs[0, 4] := 90;
- fArrowDirs[2, 6] := 90;
- fArrowDirs[4, 6] := 90;
- fArrowDirs[10, 6] := 90;
- fArrowDirs[0, 8] := 90;
- fArrowDirs[2, 10] := 90;
- fArrowDirs[6, 10] := 90;
- fArrowDirs[10, 10] := 90;
- // Alle nach Links
- fArrowDirs[2, 4] := 180;
- fArrowDirs[10, 4] := 180;
- fArrowDirs[14, 4] := 180;
- fArrowDirs[6, 6] := 180;
- fArrowDirs[2, 8] := 180;
- fArrowDirs[6, 8] := 180;
- fArrowDirs[10, 8] := 180;
- fArrowDirs[14, 8] := 180;
- fArrowDirs[4, 10] := 180;
- fArrowDirs[8, 10] := 180;
- fArrowDirs[12, 10] := 180;
- // Alle nach unten
- fArrowDirs[4, 0] := 270;
- fArrowDirs[8, 0] := 270;
- fArrowDirs[12, 0] := 270;
- fArrowDirs[14, 2] := 270;
- fArrowDirs[6, 4] := 270;
- fArrowDirs[8, 4] := 270;
- fArrowDirs[12, 4] := 270;
- fArrowDirs[14, 6] := 270;
- fArrowDirs[4, 8] := 270;
- fArrowDirs[8, 8] := 270;
- fArrowDirs[12, 8] := 270;
- // Nach Rechts
- For i := 2 To 11 Do Begin
- fConveyorDirs[i, 2] := 0;
- End;
- // Nach Unten
- For j := 2 To 7 Do Begin
- fConveyorDirs[12, j] := 270;
- End;
- // Nach Links
- For i := 3 To 12 Do Begin
- fConveyorDirs[i, 8] := 180;
- End;
- // Nach oben
- For j := 3 To 8 Do Begin
- fConveyorDirs[2, j] := 90;
- End;
- Name := '';
- fHash := 0;
-{$IFDEF Server}
- StatisticCallback := sStatisticCallback;
- fPlaySoundEffect := PlaySoundEffectCallback;
- fBombCount := 0;
- fBombDetonateFifo := TIntFifo.create(128);
- fPowerUpClearFifo := TPointFifo.create(128);
-{$ENDIF}
-End;
-
-Destructor TAtomicField.Destroy;
-{$IFDEF Client}
-Var
- i, j: Integer;
-{$ENDIF}
-Begin
-{$IFDEF Client}
- For i := 0 To FieldWidth - 1 Do
- For j := 0 To FieldHeight - 1 Do
- If assigned(fxBricks[i, j].ani) Then fxBricks[i, j].ani.free;
-{$ENDIF}
-{$IFDEF Server}
- fBombDetonateFifo.free;
- fPowerUpClearFifo.free;
-{$ENDIF}
- Inherited Destroy;
-End;
-
-// Die IDE Code vervollständigung killt manchmal den Korrekten Header, deswegen hier die "Kopiervorlage"
-//Function TAtomicField.loadFromDirectory(Dir: String
-//{$IFDEF Client}
-// ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
-//{$ENDIF}
-// ): Boolean;
-
-Function TAtomicField.loadFromDirectory(Dir: String
-{$IFDEF Client}
- ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
-{$ENDIF}
- ): Boolean;
-Var
- tmphash: TMD5Digest;
-
- Procedure AppendHash;
- Var
- val: UInt64;
- i: Integer;
- Begin
- val := 0;
- For i := 0 To 7 Do Begin
- val := val Shl 8;
- val := val Or tmphash[i];
- End;
- fHash := fHash Xor val;
-
- val := 0;
- For i := 8 To 15 Do Begin
- val := val Shl 8;
- val := val Or tmphash[i];
- End;
- fHash := fHash Xor val;
- End;
-
-Var
- ini: TIniFile;
-{$IFDEF Client}
- i, j: Integer;
- xBrick: TOpenGL_Animation;
-{$ENDIF}
-Begin
- result := false;
-{$IFDEF Client}
- fArrows := aArrows;
- fConveyors := aConveyors;
- fTramp := aTramp;
- fTrampStaticSprite := aTrampStatic;
-{$ENDIF}
- fHash := 0;
- dir := IncludeTrailingPathDelimiter(dir);
-
- If Not FileExists(dir + 'brick.png') Then exit;
-{$IFDEF Client}
- fBrickTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(dir + 'brick.png', ColorToRGB(clfuchsia), smStretchHard);
-{$ENDIF}
- tmphash := MD5File(dir + 'brick.png');
- AppendHash;
-
- If Not FileExists(dir + 'field.png') Then exit;
-{$IFDEF Client}
- fFieldTex := OpenGL_GraphikEngine.LoadGraphik(dir + 'field.png', smStretchHard);
-{$ENDIF}
- tmphash := MD5File(dir + 'field.png');
- AppendHash;
-
- If Not FileExists(dir + 'info.txt') Then exit;
- ini := TIniFile.Create(dir + 'info.txt');
- name := ini.ReadString('General', 'Name', '');
- fHasArrows := ini.ReadBool('General', 'HasArrows', false);
- fHasConveyors := ini.ReadBool('General', 'HasConveyors', false);
- fHasHoles := ini.ReadBool('General', 'HasHoles', false);
- fHastrampolins := ini.ReadBool('General', 'Hastrampolins', false);
-
- // T
-{$IFDEF Client}
- For i := 0 To 4 Do Begin
- fPreviewLines[i] := ini.ReadString('Preview', 'Row' + inttostr(i + 1), '.....');
- End;
-{$ENDIF}
- ini.free;
- tmphash := MD5File(dir + 'info.txt');
- AppendHash;
- If name = '' Then exit; // Name ='' und Hash = 0 ist reserviert für das Random Field
-
- If Not FileExists(dir + 'solid.png') Then exit;
-{$IFDEF Client}
- fSolidTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(dir + 'solid.png', ColorToRGB(clfuchsia), smStretchHard);
- fHoleTex := aHohle;
-{$ENDIF}
- tmphash := MD5File(dir + 'solid.png');
- AppendHash;
-
- fSoundFile := Dir + 'sound.wav';
- If Not FileExists(fSoundFile) Then exit;
- tmphash := MD5File(fSoundFile);
- AppendHash;
-
- If Not FileExists(dir + 'xbrick.ani') Then exit;
-{$IFDEF Client}
- xBrick := TOpenGL_Animation.Create;
- xBrick.LoadFromFile(dir + 'xbrick.ani');
- For i := 0 To FieldWidth - 1 Do
- For j := 0 To FieldHeight - 1 Do Begin
- fxBricks[i, j].ani := TOpenGL_Animation.Create;
- fxBricks[i, j].ani.CloneFrom(xBrick);
- fxBricks[i, j].ani.Tag := i + j * FieldWidth;
- // TODO: Das Problem ist wenn der Server zu Langsam ist scheint das nicht zu gehen ...
- fxBricks[i, j].ani.OnAnimationOverflowEvent := @OnxBrickOverflow;
- fxBricks[i, j].Active := false;
- End;
- fxBrickAniTime := xBrick.Sprite[0].FrameCount * xBrick.Sprite[0].TimePerFrame;
- xBrick.Free;
-{$ENDIF}
- tmphash := MD5File(dir + 'xbrick.ani');
- AppendHash;
-
- result := true;
-End;
-
-{$IFDEF Server}
-
-Function TAtomicField.Detonate(x, y: integer; TriggerPlayerindex, ColorIndex: integer;
- Flame: TFlame): Boolean;
-Var
- i: Integer;
-Begin
- result := false;
- If (x < 0) Or (y < 0) Or (x > FieldWidth - 1) Or (y > FieldHeight - 1) Then exit;
- (*
- * Durch Analyse von: https://www.youtube.com/watch?v=qOtCVIMFJu0 bei sec 0.37
- * Flamen "überschreiben" sich gegenseitig
- * Powerups verbrennen sofort ohne Flamme
- *)
- result := true;
- Case fField[x, y].BrickData Of
- bdBlank: Begin
- If fField[x, y].PowerUp = puNone Then Begin
- fField[x, y].FlameColor := ColorIndex;
- fField[x, y].FlamePlayer := TriggerPlayerindex;
- If Not (fCross In fField[x, y].Flame) Then Begin // Sonst sieht es komisch aus ..
- fField[x, y].Flame := [Flame];
- End;
- fField[x, y].Counter := 0;
- End
- Else Begin
- fPowerUpClearFifo.Push(point(x, y));
- // fField[x, y].PowerUp := puNone; -- Das geht net, da sonst 2 Bombem hintereinander durch das Popup durchschießen können !
- result := false; // Egal wie der Strahl wird hier gestoppt !
- End;
- End;
- bdBrick: Begin
- If Not fField[x, y].Exploding Then Begin
- StatisticCallback(sBricksDestroyed);
- End;
- fField[x, y].Exploding := true;
- fField[x, y].ExplodingRenderFlag := true;
- // fField[x, y].BrickData := bdBlank; // der darf nicht Gleich weg genommen werden, da sonst 2 Bomben auch 2 Steine auf einmal wegsprengen !
- fField[x, y].Counter := 0;
- result := False;
- End;
- bdSolid: result := false; // Ein Nicht zerstörbarer Brick, der ist einfach ;)
- End;
- // Auslösen von Kettenreaktionen
- For i := 0 To fBombCount - 1 Do Begin
- If Not fBombs[i].Detonated Then Begin
- If (trunc(fBombs[i].Position.x) = x) And (trunc(fBombs[i].Position.y) = y) Then Begin
- // Derjenige der die Kettenreaktion auslöst, der bekommt den Kill
- fBombs[i].TriggerPlayerindex := TriggerPlayerindex;
- fBombDetonateFifo.push(i);
- End;
- End;
- End;
-End;
-
-(*
- * True, wenn man auf diese Koordinaten laufen kann
- * es Kann belegt sein von einer Bombe und oder einem Stein
- *)
-
-Function TAtomicField.FielWalkable(x, y: integer; AlsoCheckPowerUps: Boolean
- ): Boolean;
-Var
- i: Integer;
-Begin
- result := false;
- If (x < 0) Or (x > FieldWidth - 1) Or (y < 0) Or (y > FieldHeight - 1) Then exit;
- result := fField[x, y].BrickData = bdBlank;
- If Not result Then exit;
- If AlsoCheckPowerUps Then Begin
- result := fField[x, y].PowerUp = puNone;
- End;
- If Not result Then exit;
- // Prüfung auf Bomben, reicht das so schon ?
- For i := 0 To fBombCount - 1 Do Begin
- If (x = trunc(fBombs[i].Position.x)) And
- (y = trunc(fBombs[i].Position.y)) And
- (fBombs[i].MoveDir <> bmFly) Then Begin
- result := false;
- exit;
- End;
- End;
-End;
-
-Procedure TAtomicField.Initialize(Const Players: TPlayers; Const Scheme: TScheme
- );
- Function SetBlank(x, y: integer): Boolean;
- Begin
- result := false;
- If (x >= 0) And (x < FieldWidth) And (y >= 0) And (y < FieldHeight) Then Begin
- fField[x, y].BrickData := bdBlank;
- result := true;
- End;
- End;
-
- Function IsBlank(x, y: integer): boolean;
- Begin
- result := false;
- If (x >= 0) And (x < FieldWidth) And (y >= 0) And (y < FieldHeight) Then Begin
- result := fField[x, y].BrickData = bdBlank;
- End;
- End;
-
-Var
- px, py, i, j, maxpow: Integer;
- b: Boolean;
-Begin
-{$IFDEF Server}
- fBombCount := 0; // Sollte es je noch Bomben gegeben haben nu sind sie Platt ;)
- fBombsEnabled := true;
- fHurryIndex := -1;
-{$ENDIF}
- // Die Felder mit Elementen "Bevölkern"
- // 1. Brick / Solid / Blank
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- fField[i, j].Exploding := false;
- fField[i, j].ExplodingRenderFlag := false;
- fField[i, j].Counter := 0;
- fField[i, j].PowerUp := puNone;
- fField[i, j].Flame := [];
- fField[i, j].FlameColor := 0;
- fField[i, j].FlamePlayer := -1;
- fField[i, j].Tramp := false;
- fField[i, j].TrampRunning := false;
- fField[i, j].TrampOffset := random(256);
- Case Scheme.BrickData[i, j] Of
- bdSolid: fField[i, j].BrickData := bdSolid;
- bdBlank: fField[i, j].BrickData := bdBlank;
- bdBrick: Begin
- If Scheme.BrickDensity > random(100) Then Begin
- fField[i, j].BrickData := bdBrick;
- End
- Else Begin
- fField[i, j].BrickData := bdBlank;
- End;
- End;
- End;
- End;
- End;
- // 2. Die Spielerpositionen "Frei" Räumen
- For i := 0 To high(Players) Do Begin
- If Players[i].Info.Alive Then Begin
- SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y));
- SetBlank(trunc(Players[i].Info.Position.x) - 1, trunc(Players[i].Info.Position.y));
- SetBlank(trunc(Players[i].Info.Position.x) + 1, trunc(Players[i].Info.Position.y));
- SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y - 1));
- SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y + 1));
- End;
- End;
- // 2.5 Wenn die Karte Trampoline hat, dann verteilen wir diese nun
- If fHastrampolins Then Begin
- For i := 0 To FieldTrampCount - 1 Do Begin
- px := -1;
- While px = -1 Do Begin
- px := random(FieldWidth);
- py := random(FieldHeight);
- // Verhindern, dass Trampoline an Aktiven Spieler Positionen erstellt werden
- For j := 0 To high(Players) Do Begin
- If Players[j].Info.Alive Then Begin
- If (trunc(Players[j].Info.Position.x) = px) And
- (trunc(Players[j].Info.Position.x) = px) Then Begin
- px := -1;
- break;
- End;
- End;
- End;
- If (px <> -1) And fField[px, py].Tramp Then px := -1; // Sicherstellen, dass es auch wirklich FieldTrampCount werden !
- End;
- fField[px, py].Tramp := true;
- End;
- End;
- // 2.5 Wenn die Karte "löcher" hat, dann müssen die immer Frei bleiben, und mindestens 1 adjazentes Feld auch !
- If fHasHoles Then Begin
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- If fHoles[i, j] Then Begin
- SetBlank(i, j);
- If (Not IsBlank(i - 1, j)) And (Not IsBlank(i + 1, j))
- And (Not IsBlank(i, j - 1)) And (Not IsBlank(i, j + 1)) Then Begin
- b := false;
- While Not b Do Begin
- Case Random(4) Of
- 0: b := SetBlank(i - 1, j);
- 1: b := SetBlank(i + 1, j);
- 2: b := SetBlank(i, j - 1);
- 3: b := SetBlank(i, j + 1);
- End;
- End;
- End;
- End;
- End;
- End;
- End;
- // 3. Die PowerUps die Hinter den "Bricks" liegen
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- If fField[i, j].BrickData = bdBrick Then Begin // Nur Wo Wegsprengbare Steine sind, können Powerups drunder sein..
- (* Die Random Powerups sind "Abschaltbar" *)
- If Scheme.PowerUps[purandom].BornWith > 0 Then Begin
- maxpow := 15;
- End
- Else Begin
- maxpow := 14;
- End;
- Case random(maxpow) Of
- 0: fField[i, j].PowerUp := puNone;
- 1: fField[i, j].PowerUp := puExtraBomb;
- 2: fField[i, j].PowerUp := puLongerFlameLength;
- 3: fField[i, j].PowerUp := puDisease;
- 4: fField[i, j].PowerUp := puCanCick;
- 5: fField[i, j].PowerUp := puExtraSpeed;
- 6: fField[i, j].PowerUp := puCanPunch;
- 7: fField[i, j].PowerUp := puCanGrab;
- 8: fField[i, j].PowerUp := puCanSpooger;
- 9: fField[i, j].PowerUp := puGoldFlame;
- 10: fField[i, j].PowerUp := puTrigger;
- 11: fField[i, j].PowerUp := puCanJelly;
- 12: fField[i, j].PowerUp := puSuperBadDisease;
- 13: fField[i, j].PowerUp := puSlow;
- 14: fField[i, j].PowerUp := purandom;
- End;
- // TODO: das sollte ggf noch feiner Justiert werden ..
- If fField[i, j].PowerUp <> puNone Then Begin
- If Scheme.PowerUps[fField[i, j].PowerUp].Forbidden Then fField[i, j].PowerUp := puNone;
- End;
- End;
- End;
- End;
-End;
-
-Procedure TAtomicField.AppendGamingData(Const Stream: TStream);
-Var
- i, j: integer;
-Begin
- (*
- * Da auf jedem Feld immer nur 1 Ding Gerendert werden kann ist das hier recht Easy ;)
- *)
- stream.Write(fField, SizeOf(fField));
- // Sicherstellen, dass das ExplodingRenderFlag nur als Flanke raus geht (Also genau 1 mal gesetzt ist !)
- For i := 0 To high(fField) Do Begin
- For j := 0 To high(fField[i]) Do Begin
- fField[i, j].ExplodingRenderFlag := false;
- End;
- End;
-{$IFDEF Server}
- (*
- * Wir Kopieren nur die Gültigen Bomben raus
- *)
- stream.Write(fBombCount, SizeOf(fBombCount));
- For i := 0 To fBombCount - 1 Do Begin
- stream.Write(fBombs[i].ColorIndex, SizeOf(fBombs[i].ColorIndex));
- stream.Write(fBombs[i].Position, SizeOf(fBombs[i].Position));
- stream.Write(fBombs[i].Animation, SizeOf(fBombs[i].Animation));
- stream.Write(fBombs[i].AnimationOffset, SizeOf(fBombs[i].AnimationOffset));
- End;
-{$ENDIF}
-End;
-
-Function TAtomicField.HandleMovePlayer(Var Players: TPlayers; PlayerIndex: integer; ConveyorSpeed: TConveyorSpeed): Boolean;
-
- Function GetBombIndex(x, y: integer): integer;
- Var
- i: Integer;
- Begin
- result := -1;
- For i := 0 To fBombCount - 1 Do Begin
- If (trunc(fBombs[i].Position.x) = x) And
- (trunc(fBombs[i].Position.y) = y) And
- (fBombs[i].MoveDir <> bmFly) Then Begin // Fliegende Bomben haben keine Kollisionen !
- result := i;
- exit;
- End;
- End;
- End;
-
-Const
- Epsilon = 0.25; // Je Größer dieser Wert, desto mehr wird das Umlaufen der Ecken unterstützt (maximal wäre 0.5 möglich)
-Var
- s, dx, dy, cSpeed, commaparty, commapartx, rSpeed: Single;
- dxi, dyi, nx, ny, x, y, index: Integer;
-
-Begin
- result := false;
-
- If Players[PlayerIndex].Flying Then Begin
- s := Players[PlayerIndex].Info.Counter / AtomicTrampFlyTime;
- dx := Players[PlayerIndex].FlyTarget.x - Players[PlayerIndex].FlyStart.x;
- dy := Players[PlayerIndex].FlyTarget.y - Players[PlayerIndex].FlyStart.y;
- Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].FlyStart.x + dx * s;
- Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].FlyStart.y + dy * s - (FieldHeight * 3) * sin(pi * s); // Die Bogenhöhe beim Trampolin
- // Der Flug ist Beendet, sicherstellen, dass wir auf jeden Fall am Ziel angekommen sind.
- If Players[PlayerIndex].Info.Counter > AtomicTrampFlyTime Then Begin
- Players[PlayerIndex].Info.Position := Players[PlayerIndex].FlyTarget;
- Players[PlayerIndex].Flying := false;
- End;
- exit; // Während des Fluges hat der Spieler natürlich keine Kontrolle über sich ;)
- End;
-
- // Die Kick Animation -> da bewegen wir uns erst mal nicht ;)
- If (Players[PlayerIndex].Info.Animation = raKick) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimeKick - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
- If (Players[PlayerIndex].Info.Animation = raPup) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimePup - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
- If (Players[PlayerIndex].Info.Animation = raTeleport) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimeTeleport - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
-
- (*
- * Kickt der Spieler eine Bombe auf einem Laufband addieren sich die Geschwindigkeiten !
- *)
- cSpeed := 0;
- If fHasConveyors And (Not Players[PlayerIndex].Flying) Then Begin
- Case ConveyorSpeed Of
- csSlow: cSpeed := ConveyorSlowSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- csMiddle: cSpeed := ConveyorMiddleSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- csFast: cSpeed := ConveyorFastSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- End;
- x := trunc(Players[PlayerIndex].info.Position.x);
- y := trunc(Players[PlayerIndex].info.Position.y);
- If fConveyorDirs[x, y] <> -1 Then Begin // -- Aber nur wenn wir auch tatsächlich auf einem Laufband stehen..
- commapartx := (Players[PlayerIndex].info.Position.x - trunc(Players[PlayerIndex].info.Position.x));
- commaparty := (Players[PlayerIndex].info.Position.y - trunc(Players[PlayerIndex].info.Position.y));
- // Die Bombe befindet sich "ungefähr" in der Mitte
- dxi := 0;
- dyi := 0;
- Case fConveyorDirs[x, y] Of
- 0: dxi := 1;
- 90: dyi := -1;
- 180: dxi := -1;
- 270: dyi := 1;
- End;
- nx := x + dxi;
- ny := y + dyi;
- If Not FielWalkable(nx, ny, false) Then Begin // Das Laufband kann uns theoretisch auf ein Powerup drauf schieben, ob wir das nun wollen oder nicht ;)
- dxi := 0;
- dyi := 0;
- End;
- Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + dxi * cSpeed;
- Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + dyi * cSpeed;
- // Reinziehen der Bomben auf Ordentliche Koordinaten !
- If (commaparty <> 0.5) Then Begin
- If (dxi <> 0) Then Begin
- Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End
- Else Begin
- If Not (Players[PlayerIndex].MoveState In [msDown, msUp]) Then
- Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + (0.5 - commaparty) * cSpeed;
- End;
- End;
- If (commapartx <> 0.5) Then Begin
- If (dyi <> 0) Then Begin
- Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End
- Else Begin
- If Not (Players[PlayerIndex].MoveState In [msRight, msLeft]) Then
- Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + (0.5 - commapartx) * cSpeed;
- End;
- End;
- End;
- End;
- cSpeed := 0;
- rSpeed := Players[PlayerIndex].Powers.Speed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
-
- // Das Bewegen des Atomics anhand Seiner Daten
- Case Players[PlayerIndex].MoveState Of
- msStill: Players[PlayerIndex].Info.Animation := raStandStill;
- msRight: Begin
- Players[PlayerIndex].Info.Animation := raWalk;
- Players[PlayerIndex].Info.Direction := 0;
- Players[PlayerIndex].Info.Position.x := min(FieldWidth - 0.5, Players[PlayerIndex].Info.Position.x + rSpeed);
- commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
- commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
- If commaparty <> 0.5 Then Begin
- Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].Info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End;
- // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
- If commapartx > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(Players[PlayerIndex].Info.Position.x) + 1;
- y := trunc(Players[PlayerIndex].info.Position.y);
- If commaparty > 0.5 + Epsilon Then Begin
- y := y + 1;
- End;
- If Not FielWalkable(x, y, false) Then Begin
- index := GetBombIndex(x, y);
- // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
- If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
- If FielWalkable(x + 1, y, true) Then Begin // Kann die Bombe sich bewegen ?
- If fBombs[index].MoveDir <> bmRight Then Begin
- fPlaySoundEffect(PlayerIndex, seBombKick);
- Players[PlayerIndex].Info.Animation := raKick;
- Players[PlayerIndex].Info.Counter := 0;
- fBombs[index].MoveDir := bmRight;
- fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
- fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
- End;
- End
- Else Begin
- If fBombs[index].MoveDir <> bmNone Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
- End;
- End
- Else Begin
- If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
- End;
- End;
- End;
- End;
- msLeft: Begin
- Players[PlayerIndex].Info.Animation := raWalk;
- Players[PlayerIndex].Info.Direction := 180;
- Players[PlayerIndex].Info.Position.x := max(0.5, Players[PlayerIndex].Info.Position.x - rSpeed);
- commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
- commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
- If commaparty <> 0.5 Then Begin
- Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].Info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End;
- // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
- If commapartx < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(Players[PlayerIndex].Info.Position.x) - 1;
- y := trunc(Players[PlayerIndex].info.Position.y);
- If commaparty > 0.5 + Epsilon Then Begin
- y := y + 1;
- End;
- If Not FielWalkable(x, y, false) Then Begin
- index := GetBombIndex(x, y);
- // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
- If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
- If FielWalkable(x - 1, y, true) Then Begin // Kann die Bombe sich bewegen ?
- If fBombs[index].MoveDir <> bmLeft Then Begin
- fPlaySoundEffect(PlayerIndex, seBombKick);
- Players[PlayerIndex].Info.Animation := raKick;
- Players[PlayerIndex].Info.Counter := 0;
- fBombs[index].MoveDir := bmLeft;
- fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
- fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
- End;
- End
- Else Begin
- If fBombs[index].MoveDir <> bmNone Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
- End;
- End
- Else Begin
- If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
- End;
- End;
- End;
- End;
- msUp: Begin
- Players[PlayerIndex].Info.Animation := raWalk;
- Players[PlayerIndex].Info.Direction := 90;
- Players[PlayerIndex].Info.Position.y := max(0.5, Players[PlayerIndex].Info.Position.y - rSpeed);
- commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
- commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
- If commapartx <> 0.5 Then Begin
- Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].Info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End;
- // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
- If commaparty < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(Players[PlayerIndex].Info.Position.x);
- y := trunc(Players[PlayerIndex].info.Position.y) - 1;
- If commapartx > 0.5 + Epsilon Then Begin
- x := x + 1;
- End;
- If Not FielWalkable(x, y, false) Then Begin
- index := GetBombIndex(x, y);
- // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
- If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
- If FielWalkable(x, y - 1, true) Then Begin // Kann die Bombe sich bewegen ?
- If fBombs[index].MoveDir <> bmUp Then Begin
- fPlaySoundEffect(PlayerIndex, seBombKick);
- Players[PlayerIndex].Info.Animation := raKick;
- Players[PlayerIndex].Info.Counter := 0;
- fBombs[index].MoveDir := bmUp;
- fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
- fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
- End;
- End
- Else Begin
- If fBombs[index].MoveDir <> bmNone Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
- End;
- End
- Else Begin
- If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
- End;
- End;
- End;
- End;
- msDown: Begin
- Players[PlayerIndex].Info.Animation := raWalk;
- Players[PlayerIndex].Info.Direction := 270;
- Players[PlayerIndex].Info.Position.y := min(FieldHeight - 0.5, Players[PlayerIndex].Info.Position.y + rSpeed);
- commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
- commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
- If commapartx <> 0.5 Then Begin
- Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].Info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End;
- // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
- If commaparty > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(Players[PlayerIndex].Info.Position.x);
- y := trunc(Players[PlayerIndex].info.Position.y) + 1;
- If commapartx > 0.5 + Epsilon Then Begin
- x := x + 1;
- End;
- If Not FielWalkable(x, y, false) Then Begin
- index := GetBombIndex(x, y);
- // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
- If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
- If FielWalkable(x, y + 1, true) Then Begin // Kann die Bombe sich bewegen ?
- If fBombs[index].MoveDir <> bmDown Then Begin
- fPlaySoundEffect(PlayerIndex, seBombKick);
- Players[PlayerIndex].Info.Animation := raKick;
- Players[PlayerIndex].Info.Counter := 0;
- fBombs[index].MoveDir := bmDown;
- fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
- fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
- End;
- End
- Else Begin
- If fBombs[index].MoveDir <> bmNone Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
- End;
- End
- Else Begin
- If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombStop);
- fBombs[index].MoveDir := bmNone;
- fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
- fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
- End;
- Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
- End;
- End;
- End;
- End;
- End;
- // evtl. ist der Spieler ja "eingesperrt"
- x := trunc(Players[PlayerIndex].Info.Position.x);
- y := trunc(Players[PlayerIndex].info.Position.y);
- If (Not FielWalkable(x - 1, y, false)) And
- (Not FielWalkable(x + 1, y, false)) And
- (Not FielWalkable(x, y - 1, false)) And
- (Not FielWalkable(x, y + 1, false)) And
- (Players[PlayerIndex].info.Animation <> raLockedIn) Then Begin
- Players[PlayerIndex].info.Animation := raLockedIn;
- Players[PlayerIndex].info.Value := random(65536);
- Players[PlayerIndex].info.Counter := 0;
- End;
- result := fField[x, y].BrickData = bdSolid;
-End;
-
-Procedure TAtomicField.HandleActionPlayer(Var Player: TPlayer;
- PlayerIndex: integer);
-
- Function PlaceBombOn(aX, aY: Single): Boolean;
- Var
- i: Integer;
- Begin
- result := false;
- // Darf der Spieler überhaupt noch Bomben legen =
- If player.Powers.AvailableBombs <= 0 Then exit;
- // Liegt auf dem Feld schon eine Bombe ?
- For i := 0 To fBombCount - 1 Do Begin
- If (trunc(fBombs[i].Position.x) = trunc(ax)) And
- (trunc(fBombs[i].Position.y) = trunc(ay)) Then exit;
- End;
- // Es darf keine Bombe auf ein Loch gelegt werden !
- If fHasHoles And fHoles[trunc(ax), trunc(ay)] Then exit;
- fBombs[fBombCount].ColorIndex := player.info.ColorIndex;
- fBombs[fBombCount].Position.x := trunc(ax) + 0.5;
- fBombs[fBombCount].Position.y := trunc(ay) + 0.5;
- If player.Powers.TriggerBomb > 0 Then Begin
- fBombs[fBombCount].Animation := baTimeTriggered;
- player.Powers.TriggerBomb := player.Powers.TriggerBomb - 1;
- End
- Else Begin
- If dDudBombs In player.Disease Then Begin
- fBombs[fBombCount].Animation := baDud;
- fBombs[fBombCount].DudTime := AtomicBombDudTimeMin + random(AtomicBombDudTimeMax - AtomicBombDudTimeMin);
- End
- Else Begin
- fBombs[fBombCount].Animation := baNormal;
- End;
- End;
- fBombs[fBombCount].AnimationOffset := random(65536);
- fBombs[fBombCount].PlayerIndex := PlayerIndex;
- fBombs[fBombCount].TriggerPlayerindex := -1; // Force a exception, should be set during triggering !
- fBombs[fBombCount].Lifetime := 0;
- fBombs[fBombCount].FireLen := player.Powers.FlameLen;
- fBombs[fBombCount].Jelly := false; // Das wird vom "Kickenden" Spieler übernommen
- fBombs[fBombCount].MoveDir := bmNone;
- fBombs[fBombCount].Speed := player.Powers.Speed;
- inc(fBombCount);
- player.Powers.AvailableBombs := player.Powers.AvailableBombs - 1;
- result := true;
- If fBombCount > high(fBombs) Then Begin
- log('TAtomicField.HandleActionPlayer: bomb overflow', llfatal);
- exit;
- End;
- End;
-
-Var
- bx, by, x, y, dx, dy, i: Integer;
- handled: Boolean;
-Begin
- If Player.Flying Then exit; // Im Flug darf der Spieler natürlich nichts machen ;)
- Case player.Action Of
- aaFirstDouble: Begin
- (* Jeder Doppelt action geht eine Einfach Aktion vorraus ! *)
- player.Action := aaFirst;
- HandleActionPlayer(Player, PlayerIndex);
- // Ab jetzt können die Doppelt Aktionen richtig ausgewertet werden
- If player.Powers.CanSpooger Then Begin // Die Fähigkeit Viele auf einen Schlag zu legen
- dx := 0;
- dy := 0;
- Case (trunc(player.info.Direction) Div 90) Of
- 0: dx := 1;
- 1: dy := -1;
- 2: dx := -1;
- 3: dy := 1;
- End;
- x := trunc(player.Info.Position.x);
- y := trunc(player.Info.Position.y);
- For i := 1 To player.Powers.AvailableBombs Do Begin
- If Not FielWalkable(x + i * dx, y + i * dy, true) {And (i <> 1)} Then exit;
- If fHasHoles Then Begin // An Löchern ist auch schluss mit dem "Spoogen"
- If fHoles[x + i * dx, y + i * dy] Then exit;
- End;
- If fHastrampolins Then Begin // Auf Trampoline kann ebenfalls keine Bombe gelegt werden
- If fField[x + i * dx, y + i * dy].Tramp Then exit;
- End;
- If PlaceBombOn(x + i * dx + 0.5, y + i * dy + 0.5) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombDrop);
- StatisticCallback(sBombsDropped);
- End;
- End;
- End;
- If Player.Powers.CanGrabBombs Then Begin
- // Gibt es eine Bombe zum Graben ?
- x := trunc(player.Info.Position.x);
- y := trunc(player.Info.Position.y);
- For i := 0 To high(fBombs) Do Begin
- If fBombs[i].MoveDir = bmFly Then Continue; // Fliegende Bomben dürfen nicht gegriffen werden.
- bx := trunc(fBombs[i].Position.x);
- by := trunc(fBombs[i].Position.y);
- If (x = bx) And (y = by) Then Begin
- dx := 0;
- dy := 0;
- Case (trunc(player.info.Direction) Div 90) Of
- 0: dx := 1;
- 1: dy := -1;
- 2: dx := -1;
- 3: dy := 1;
- End;
- fBombs[i].FlyStart := v2(bx + 0.5, by + 0.5);
- fBombs[i].FlyTarget := v2(bx + 0.5 + 3 * dx, by + 0.5 + 3 * dy);
- fBombs[i].MoveDir := bmFly;
- fBombs[i].FlyTime := 0;
- fBombs[i].FlyFinTime := AtomicBombBigFlyTime;
- fPlaySoundEffect(PlayerIndex, seBombGrab);
- Player.Info.Animation := raPup;
- Player.Info.Counter := 0;
- break;
- End;
- End;
- End;
- End;
- aaFirst: Begin
- If PlaceBombOn(trunc(player.Info.Position.x) + 0.5, trunc(player.Info.Position.y) + 0.5) Then Begin
- fPlaySoundEffect(PlayerIndex, seBombDrop);
- StatisticCallback(sBombsDropped);
- End;
- End;
- aaSecond: Begin
- handled := false; // This flag allows to trigger bombs while walking = more responsive ;)
- // Punch = Laufen gegen eine Bombe und dann Second Key ;)
- If Player.Powers.CanPunchBombs And (Player.MoveState <> msStill) Then Begin
- x := trunc(player.Info.Position.x);
- y := trunc(player.Info.Position.y);
- dx := 0;
- dy := 0;
- Case (trunc(player.info.Direction) Div 90) Of
- 0: dx := 1;
- 1: dy := -1;
- 2: dx := -1;
- 3: dy := 1;
- End;
- For i := 0 To high(fBombs) Do Begin
- If fBombs[i].MoveDir = bmFly Then Continue; // Fliegende Bomben dürfen nicht gepuncht werden.
- bx := trunc(fBombs[i].Position.x);
- by := trunc(fBombs[i].Position.y);
- If (x + dx = bx) And (y + dy = by) Then Begin
- fBombs[i].FlyStart := v2(bx + 0.5, by + 0.5);
- fBombs[i].FlyTarget := v2(bx + 0.5 + 3 * dx, by + 0.5 + 3 * dy);
- fBombs[i].MoveDir := bmFly;
- fBombs[i].FlyTime := 0;
- fBombs[i].FlyFinTime := AtomicBombBigFlyTime;
- fBombs[i].Lifetime := 0; // Reset Bomb timer when punch
- fPlaySoundEffect(PlayerIndex, seBombPunch);
- Player.Info.Animation := raPunch;
- Player.Info.Counter := 0;
- handled := true;
- break;
- End;
- End;
- End;
- If Not handled Then Begin
- (*
- * Zünden der eigenen Time Triggered Bomben, das geht irgendwie immer ...
- *)
- For i := 0 To fBombCount - 1 Do Begin
- If (fBombs[i].PlayerIndex = PlayerIndex) And (fBombs[i].Animation = baTimeTriggered) And (fBombs[i].MoveDir <> bmFly) Then Begin
- fBombs[i].Animation := baNormal;
- fBombs[i].Lifetime := AtomicBombDetonateTime;
- End;
- End;
- End;
- End;
- End;
-End;
-
-Procedure TAtomicField.HandleBombs(Var Players: TPlayers; PreHurry: Boolean; ConveyorSpeed: TConveyorSpeed);
-Type
- TDir = (DirUp, DirDown, DirLeft, DirRight);
-
- Function BlockedByHole(x, y: integer): Boolean; // Gillt nur für Bomben, wenn diese sich bewegen, deswegen extra
- Begin
- If fHasHoles Then Begin
- result := fHoles[x, y];
- End
- Else Begin
- result := false;
- End;
- End;
-
- Function BlockedByTramp(x, y: integer): Boolean; // Gillt nur für Bomben, wenn diese sich bewegen, deswegen extra
- Begin
- If fHastrampolins Then Begin
- result := fField[x, y].Tramp;
- End
- Else Begin
- result := false;
- End;
- End;
-
- Function BlockedByPlayer(x, y: integer): Boolean;
- Var
- i: Integer;
- Begin
- result := false;
- For i := 0 To high(Players) Do Begin
- If (Players[i].Info.Alive) And (Not Players[i].Info.Dying) Then Begin
- If (trunc(Players[i].Info.Position.x) = x) And
- (trunc(Players[i].Info.Position.y) = y) Then Begin
- result := true;
- break;
- End;
- End;
- End;
- End;
-
- Function DirToMoveDir(aDir: integer): TBombMoveDir;
- Begin
- result := bmNone;
- Case aDir Of
- 0: result := bmRight;
- 90: result := bmUp;
- 180: result := bmLeft;
- 270: result := bmDown;
- End;
- End;
-
- Procedure AddEndFlame(x, y, TriggerPlayerindex: integer);
- Begin
- (*
- * So überschreibt jeder Spieler ggf. einen Anderen, es sieht so aus als
- * ob TAtomicField.Detonate das auch so macht, wenn nicht, muss das If mit rein !
- *)
- //If fField[x, y].Flame = [] Then Begin
- fField[x, y].FlamePlayer := TriggerPlayerindex;
- //End;
- fField[x, y].Flame := fField[x, y].Flame + [fend];
- End;
-
-Var
- dxi, dyi, nx, ny, x, y, i: Integer;
- index, j, dir: Integer;
- dirs: Set Of TDir;
- p: TPoint;
- cSpeed, rSpeed, commapartx, commaparty: Single;
- BombExplodeSound: Array[0..Length(PlayerColors) - 1] Of Boolean;
- dx, dy, s: Single;
- mdir: TBombMoveDir;
-Begin
- If Not fBombsEnabled Then exit; // Bomben dürfen nicht mehr gezündet werden !
- fBombDetonateFifo.Clear;
- fPowerUpClearFifo.Clear;
- For i := 0 To fBombCount - 1 Do Begin
- rSpeed := fBombs[i].Speed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- fBombs[i].Lifetime := fBombs[i].Lifetime + FrameRate; // Countdown bis zur Detonation
- fBombs[i].detonated := false;
- // Die Bombe bewegt
- If fHasArrows And (fBombs[i].MoveDir In [bmDown, bmLeft, bmUp, bmRight]) Then Begin
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y);
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- // Die Bombe befindet sich "ungefähr" in der Mitte
- If (abs(commapartx - 0.5) <= rSpeed) And (abs(commaparty - 0.5) <= rSpeed) Then Begin
- dir := fArrowDirs[x, y];
- mdir := DirToMoveDir(dir);
- If (dir <> -1) And (mdir <> fBombs[i].MoveDir) Then Begin
- fBombs[i].MoveDir := mdir;
- fBombs[i].Position.x := x + 0.5;
- fBombs[i].Position.y := y + 0.5;
- // TODO: hier prüfen ob die Bombe weiter in dir gewünschte Richtung kann, wenn nicht Stop
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombBounce);
- End;
- End;
- End;
- If fHasConveyors And (fBombs[i].MoveDir In [bmNone, bmDown, bmLeft, bmUp, bmRight]) Then Begin
- cSpeed := 0; // -- Fehler
- Case ConveyorSpeed Of
- csSlow: cSpeed := ConveyorSlowSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- csMiddle: cSpeed := ConveyorMiddleSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- csFast: cSpeed := ConveyorFastSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
- End;
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y);
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- // Die Bombe befindet sich "ungefähr" in der Mitte
- dxi := 0;
- dyi := 0;
- Case fConveyorDirs[x, y] Of
- 0: dxi := 1;
- 90: dyi := -1;
- 180: dxi := -1;
- 270: dyi := 1;
- End;
- nx := x + dxi;
- ny := y + dyi;
- If Not FielWalkable(nx, ny, true) Then Begin
- dxi := 0;
- dyi := 0;
- End;
- fBombs[i].Position.x := fBombs[i].Position.x + dxi * cSpeed;
- fBombs[i].Position.y := fBombs[i].Position.y + dyi * cSpeed;
- // Reinziehen der Bomben auf Ordentliche Koordinaten !
- If (commaparty <> 0.5) Then Begin
- If (dxi <> 0) Then Begin
- fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End
- Else Begin
- fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * cSpeed;
- End;
- End;
- If (commapartx <> 0.5) Then Begin
- If (dyi <> 0) Then Begin
- fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End
- Else Begin
- fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * cSpeed;
- End;
- End;
- End;
- Case fBombs[i].MoveDir Of
- bmFly: Begin
- fBombs[i].Lifetime := fBombs[i].Lifetime - FrameRate; // Countdown bis zur Detonation wieder Rückgängig machen
- fBombs[i].FlyTime := fBombs[i].FlyTime + FrameRate;
- s := fBombs[i].FlyTime / fBombs[i].FlyFinTime;
- dx := fBombs[i].FlyTarget.x - fBombs[i].FlyStart.x;
- dy := fBombs[i].FlyTarget.y - fBombs[i].FlyStart.y;
- If dy = 0 Then Begin
- // Die Bombe "Fliegt" Waagrecht
- fBombs[i].Position.x := fBombs[i].FlyStart.x + dx * s;
- fBombs[i].Position.y := fBombs[i].FlyStart.y - 1.5 * sin(pi * s); // Die Bogenhöhe beim Werfen
- End
- Else Begin
- // Die Bombe fliegt Senkrecht
- fBombs[i].Position.y := fBombs[i].FlyStart.y + dy * s;
- End;
- // Hier muss ein Mod der Position rein !
- If fBombs[i].Position.x < 0 Then fBombs[i].Position.x := fBombs[i].Position.x + FieldWidth - 1;
- If fBombs[i].Position.x >= FieldWidth Then fBombs[i].Position.x := fBombs[i].Position.x - FieldWidth;
- If dy <> 0 Then Begin
- If fBombs[i].Position.y < 0 Then fBombs[i].Position.y := fBombs[i].Position.y + FieldHeight - 1;
- If fBombs[i].Position.y >= FieldHeight Then fBombs[i].Position.y := fBombs[i].Position.y - FieldHeight;
- End;
- If fBombs[i].FlyTime >= fBombs[i].FlyFinTime Then Begin
- fBombs[i].Position := fBombs[i].FlyTarget;
- // Hier muss ein Mod der Position rein !
- If fBombs[i].Position.x < 0 Then fBombs[i].Position.x := fBombs[i].Position.x + FieldWidth - 1;
- If fBombs[i].Position.x >= FieldWidth Then fBombs[i].Position.x := fBombs[i].Position.x - FieldWidth;
- If fBombs[i].Position.y < 0 Then fBombs[i].Position.y := fBombs[i].Position.y + FieldHeight - 1;
- If fBombs[i].Position.y >= FieldHeight Then fBombs[i].Position.y := fBombs[i].Position.y - FieldHeight;
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y);
- If FielWalkable(x, y, true) And (Not BlockedByHole(x, y)) And (Not BlockedBytramp(x, y)) Then Begin
- // 1. Das Feld darf belegt werden -> Fertig
- fBombs[i].MoveDir := bmNone;
- End
- Else Begin
- // 2. Das Feld ist belegt, wir starten ein Bouncing
- dx := 0;
- dy := 0;
- Case random(4) Of
- 0: dx := 1;
- 1: dy := -1;
- 2: dx := -1;
- 3: dy := 1;
- End;
- fBombs[i].FlyStart := v2(x + 0.5, y + 0.5);
- fBombs[i].FlyTarget := v2(x + 0.5 + dx, y + 0.5 + dy);
- fBombs[i].FlyTime := 0;
- fBombs[i].FlyFinTime := AtomicBombSmallFlyTime;
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombBounce);
- End;
- End;
- End;
- bmNone: Begin // Nix zu tun
- End;
- bmRight: Begin
- fBombs[i].Position.x := fBombs[i].Position.x + rSpeed;
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- If commaparty <> 0.5 Then Begin // Reinziehen der Bomben auf Ordentliche Koordinaten !
- fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End;
- If commapartx > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(fBombs[i].Position.x) + 1;
- y := trunc(fBombs[i].Position.y);
- If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
- fBombs[i].Position.x := trunc(fBombs[i].Position.x) + 0.5;
- If fBombs[i].Jelly Then Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
- fBombs[i].MoveDir := bmLeft;
- If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
- End
- Else Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
- fBombs[i].MoveDir := bmNone;
- If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
- End;
- End;
- End;
- End;
- bmLeft: Begin
- fBombs[i].Position.x := fBombs[i].Position.x - rSpeed;
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- If commaparty <> 0.5 Then Begin // Reinziehen der Bomben auf Ordentliche Koordinaten !
- fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
- End;
- If commapartx < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(fBombs[i].Position.x) - 1;
- y := trunc(fBombs[i].Position.y);
- If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
- fBombs[i].Position.x := trunc(fBombs[i].Position.x) + 0.5;
- If fBombs[i].Jelly Then Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
- fBombs[i].MoveDir := bmRight;
- If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
- End
- Else Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
- fBombs[i].MoveDir := bmNone;
- If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
- End;
- End;
- End;
- End;
- bmUp: Begin
- fBombs[i].Position.y := fBombs[i].Position.y - rSpeed;
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- If commapartx <> 0.5 Then Begin
- fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End;
- If commaparty < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y) - 1;
- If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
- fBombs[i].Position.y := trunc(fBombs[i].Position.y) + 0.5;
- If fBombs[i].Jelly Then Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
- fBombs[i].MoveDir := bmDown;
- If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
- End
- Else Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
- fBombs[i].MoveDir := bmNone;
- If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
- End;
- End;
- End;
- End;
- bmDown: Begin
- fBombs[i].Position.y := fBombs[i].Position.y + rSpeed;
- commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
- commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
- If commapartx <> 0.5 Then Begin
- fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
- End;
- If commaparty > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y) + 1;
- If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
- fBombs[i].Position.y := trunc(fBombs[i].Position.y) + 0.5;
- If fBombs[i].Jelly Then Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
- fBombs[i].MoveDir := bmUp;
- If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
- End
- Else Begin
- fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
- fBombs[i].MoveDir := bmNone;
- If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
- End;
- End;
- End;
- End;
- End;
- Case fBombs[i].Animation Of
- baNormal, baWobble: Begin
- If fBombs[i].Lifetime >= AtomicBombDetonateTime Then Begin
- fBombs[i].TriggerPlayerindex := fBombs[i].PlayerIndex;
- fBombDetonateFifo.Push(i);
- End;
- End;
- baTimeTriggered: Begin
- If fBombs[i].Lifetime >= AtomicTimeTriggeredBombTimeOut Then Begin
- fBombs[i].Animation := baNormal;
- fBombs[i].Lifetime := 0;
- End;
- End;
- baDud: Begin
- If fBombs[i].Lifetime >= fBombs[i].DudTime Then Begin
- fBombs[i].Animation := baNormal;
- fBombs[i].Lifetime := 0;
- End;
- End;
- End;
- // Trifft eine Bombe auf ein bereits Explodierendes Feld geht sie auf jeden Fall auch hoch
- // (dass kann nur bei sich bewegenden Bomben passieren, da die Liegenden in Detonate schon berücksichtigt werden.)
- x := trunc(fBombs[i].Position.x);
- y := trunc(fBombs[i].Position.y);
- If (y > 0) And (fBombs[i].MoveDir <> bmFly) Then Begin // Eine Fliegende Bombe kann Negative Koordinaten kriegen
- If (fField[x, y].Flame <> []) Then Begin
- fBombs[i].Position.x := x + 0.5;
- fBombs[i].Position.y := y + 0.5;
- fBombs[i].TriggerPlayerindex := fField[x, y].FlamePlayer;
- fBombDetonateFifo.Push(i);
- End;
- End;
- (*
- * Die Bombe muss explodieren bevor sie unter dem Stein begraben wird !
- *)
- If PreHurry Then Begin
- If (fHurryIndex + 1 >= 0) And (fHurryIndex + 1 <= high(HurryCoords)) Then Begin
- p := HurryCoords[fHurryIndex + 1];
- If (x = p.x) And (y = p.y) Then Begin
- fBombs[i].Position.x := x + 0.5;
- fBombs[i].Position.y := y + 0.5;
- fBombs[i].TriggerPlayerindex := fBombs[i].PlayerIndex;
- fBombDetonateFifo.Push(i);
- End;
- End;
- End;
- End;
-
- // Alle Bombem die Hochgehen sollen ab arbeiten
- While Not fBombDetonateFifo.isempty Do Begin
- index := fBombDetonateFifo.Pop;
- If fBombs[index].Detonated Then Continue;
- fBombs[index].Detonated := true;
- (*
- * Die Bombe wurde gezündet, der Spieler darf wieder eine Neue Legen
- *)
- Players[fBombs[index].PlayerIndex].Powers.AvailableBombs := Players[fBombs[index].PlayerIndex].Powers.AvailableBombs + 1;
- x := trunc(fBombs[index].Position.x);
- y := trunc(fBombs[index].Position.y);
- If fField[x, y].BrickData = bdSolid Then continue; // Die Bombe Explodiert auf einem Festen Brick -> dann richtet sie keinen Schaden an
- If fField[x, y].BrickData = bdBrick Then Begin // Die Bombe explodiert auf einem Brick, den macht sie kaputt, aber nichts weiter ..
- Detonate(x, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fCross);
- Continue;
- End
- Else Begin
- Detonate(x, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fCross);
- End;
- dirs := [DirUp, DirDown, DirLeft, DirRight];
- For i := 1 To fBombs[index].FireLen Do Begin
- If DirUp In dirs Then Begin
- If (Not Detonate(x, y - i, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fup)) Then Begin
- dirs := dirs - [DirUp];
- AddEndFlame(x, y - i + 1, fBombs[index].TriggerPlayerindex);
- End;
- If (i = fBombs[index].FireLen) And (y - i >= 0) Then Begin
- AddEndFlame(x, y - i, fBombs[index].TriggerPlayerindex);
- End;
- End;
- If Dirdown In dirs Then Begin
- If (Not Detonate(x, y + i, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fdown)) Then Begin
- dirs := dirs - [Dirdown];
- AddEndFlame(x, y + i - 1, fBombs[index].TriggerPlayerindex);
- End;
- If (i = fBombs[index].FireLen) And (y + i < FieldHeight) Then Begin
- AddEndFlame(x, y + i, fBombs[index].TriggerPlayerindex);
- End;
- End;
- If DirLeft In dirs Then Begin
- If (Not Detonate(x - i, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fleft)) Then Begin
- dirs := dirs - [DirLeft];
- AddEndFlame(x - i + 1, y, fBombs[index].TriggerPlayerindex);
- End;
- If (i = fBombs[index].FireLen) And (x - i > 0) Then Begin
- AddEndFlame(x - i, y, fBombs[index].TriggerPlayerindex);
- End;
- End;
- If DirRight In dirs Then Begin
- If (Not Detonate(x + i, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fright)) Then Begin
- dirs := dirs - [DirRight];
- AddEndFlame(x + i - 1, y, fBombs[index].TriggerPlayerindex);
- End;
- If (i = fBombs[index].FireLen) And (x + i < FieldWidth) Then Begin
- AddEndFlame(x + i, y, fBombs[index].TriggerPlayerindex);
- End;
- End;
- End;
- End;
-
- (*
- * Entfernen aller Gezündeter Bomben
- *)
- For i := 0 To high(BombExplodeSound) Do Begin // Merken welchen Spielern wir den Explode Sound senden sollen
- BombExplodeSound[i] := false;
- End;
- For i := fBombCount - 1 Downto 0 Do Begin
- If fBombs[i].Detonated Then Begin
- BombExplodeSound[fBombs[i].PlayerIndex] := true;
- For j := i To fBombCount - 2 Do Begin
- fBombs[j] := fBombs[j + 1];
- End;
- Dec(fBombCount);
- End;
- End;
- // So hört ein Spieler Pro Massen Explusion immer nur einen Sound !
- For i := 0 To high(BombExplodeSound) Do Begin
- If BombExplodeSound[i] Then Begin
- fPlaySoundEffect(i, seBombExplode);
- End;
- End;
-
- (*
- * Entfernen aller explodierten Powerups
- *)
- While Not fPowerUpClearFifo.isempty Do Begin
- p := fPowerUpClearFifo.Pop;
- If fField[p.x, p.y].PowerUp <> puNone Then Begin
- StatisticCallback(sPowerUpDestroyed);
- End;
- fField[p.x, p.y].PowerUp := puNone;
- End;
-End;
-
-Procedure TAtomicField.HandlePlayerVsMap(Var Players: TPlayers;
- PlayerGetsPowerUp: TPlayerGetsPowerUpEvent);
-
-// Gemäß: https://www.youtube.com/watch?v=fO9HhzhEloE (bei 6:00) sieht es aber so aus,
-// das die Atomics in einem "Range" von +-2 wieder Runter kommen
-Const
- TrampRange = 2;
-Var
- nx, ny, x, y, i: integer;
-Begin
- For i := 0 To high(Players) Do Begin
- If (Not Players[i].Info.Alive) Or (Players[i].Info.Dying) Or (Players[i].Flying) Then Continue;
- x := trunc(Players[i].Info.Position.x);
- y := trunc(Players[i].Info.Position.y);
- // Die Kollision Spieler gegen PowerUp
- If fField[x, y].PowerUp <> puNone Then Begin
- PlayerGetsPowerUp(Players[i], i, fField[x, y].PowerUp);
- fField[x, y].PowerUp := puNone;
- End;
- // Die Kollision gegen ein Loch
- If fHasHoles And fHoles[x, y] Then Begin
- If (Not Players[i].IsInHohle) Then Begin // Flanke generieren ;)
- Players[i].IsInHohle := true;
- Players[i].Info.Animation := raTeleport;
- Players[i].Info.Counter := 0;
- Players[i].Info.Position.x := x + 0.5;
- Players[i].Info.Position.y := y + 0.5;
- fPlaySoundEffect(i, seWrapHohle);
- End;
- End
- Else Begin
- Players[i].IsInHohle := false;
- End;
- If fHastrampolins And fField[x, y].Tramp Then Begin
- fPlaySoundEffect(i, seTrampoline);
- // Triggern der Animation der Karte
- fField[x, y].TrampRunning := true;
- fField[x, y].Counter := 0;
- // Triggern des "Fliegens" des Spielers
- // 1. Neue ZielKoordinate bestimmen
- nx := -1;
- While nx = -1 Do Begin
- // So können die Atomics einfach "irgendwo" wieder landen
- // nx := random(FieldWidth);
- // ny := Random(FieldHeight);
- nx := min(FieldWidth - 1, max(0, x + random(TrampRange * 2 + 1) - TrampRange));
- ny := min(FieldHeight - 1, max(0, y + random(TrampRange * 2 + 1) - TrampRange));
- // Das Ziel Feld muss Leer sein = Kein Stein oder Tramp
- If (fField[nx, ny].BrickData <> bdBlank)
- Or (fField[nx, ny].Tramp) Then Begin
- nx := -1;
- End;
- // Das gibt es eigentlich nicht, aber auf Löchern landen ist auch verboten!
- If fHasHoles Then Begin
- If fHoles[nx, ny] Then
- nx := -1;
- End;
- End;
- Players[i].Flying := true;
- Players[i].Info.Counter := 0;
- Players[i].FlyStart := Players[i].Info.Position;
- Players[i].FlyTarget := v2(nx + 0.5, ny + 0.5);
- End;
- // Die Kollision Spieler gegen eine Flamme
- If fField[x, y].Flame <> [] Then Begin
- // TODO: Während eines Teleport vorgangs ist der Spieler unsterblich -> Klären ob das wirklich gewollt ist..
- If (Not Players[i].Info.Dying) And (Players[i].Info.Animation <> raTeleport) Then Begin
- If i = fField[x, y].FlamePlayer Then Begin
- // Selfkill
- Players[fField[x, y].FlamePlayer].Kills := Players[fField[x, y].FlamePlayer].Kills - 1;
- End
- Else Begin
- // Echter Kill ;)
- Players[fField[x, y].FlamePlayer].Kills := Players[fField[x, y].FlamePlayer].Kills + 1;
- End;
- fPlaySoundEffect(i, seAtomicDie);
- fPlaySoundEffect(i, seOtherPlayerDied);
- StatisticCallback(sPlayerDeaths);
- KillPlayer(Players, i);
- End;
- End;
- End;
-End;
-
-Procedure TAtomicField.HandleFieldAnims;
-Var
- i, j: Integer;
-Begin
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- (*
- * Der Counter läuft pauschal immer mit, und läuft alle 60s über, alles was den Counter braucht setzt ihn auf 0 zurück
- *)
- fField[i, j].Counter := (fField[i, j].Counter + FrameRate) Mod 60000;
- If fField[i, j].Exploding Then Begin
- (*
- * Dauert es zu lange, bis Brickdate auf bdBlank gesetzt wird
- * dann sieht das Optisch doof aus (nur bei Synchronisationsthemen
- * Geht es zu schnell (oder eben so schnell wie jetzt, dann kann der Spieler)
- * viel zu Früh auf die Felder laufen, das macht er aber auf eigenes Risiko, da
- * hier natürlich ein PowerUp liegt, dass er noch nicht sieht ;)
- *)
- If fField[i, j].Counter >= 2 * UpdateRate Then Begin
- fField[i, j].BrickData := bdBlank;
- End;
- If fField[i, j].Counter >= BrickExplodeTime Then Begin
- // Die Explosionsanimation gibt es in nur 2 Fällen
- fField[i, j].Exploding := false;
- End;
- End;
- If fField[i, j].Flame <> [] Then Begin
- If fField[i, j].Counter >= FlameTime Then Begin
- // Die Explusionsanimation gibt es in nur 2 Fällen
- fField[i, j].Flame := [];
- End;
- End;
- If fField[i, j].TrampRunning Then Begin
- If fField[i, j].Counter >= AtomicTrampFlyTime Then Begin
- fField[i, j].TrampRunning := false;
- End;
- End;
- End;
- End;
-End;
-
-Procedure TAtomicField.DisableAllBombs;
-Begin
- fBombsEnabled := false;
-End;
-
-Function TAtomicField.GetAiInfo(Const Players: TPlayers; TeamPlay: Boolean): TaiInfo;
-Var
- i, j: Integer;
-Begin
- result.Teamplay := TeamPlay;
- For i := 0 To high(Players) Do Begin
- result.PlayerInfos[i].Team := Players[i].Team;
- result.PlayerInfos[i].Position.x := Players[i].Info.Position.x;
- result.PlayerInfos[i].Position.y := Players[i].Info.Position.y;
- result.PlayerInfos[i].Alive := Players[i].Info.Alive And (Not Players[i].Info.Dying);
- result.PlayerInfos[i].Flying := Players[i].Flying;
- result.PlayerInfos[i].FlameLength := Players[i].Powers.FlameLen;
- result.PlayerInfos[i].Speed := Players[i].Powers.Speed;
- result.PlayerInfos[i].IsIll := Players[i].Disease <> [];
- result.PlayerInfos[i].Abilities := 0;
- If Players[i].Powers.CanKickBombs Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanKick;
- End;
- If Players[i].Powers.CanSpooger Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanSpoog;
- End;
- If Players[i].Powers.CanPunchBombs Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanPunch;
- End;
- If Players[i].Powers.CanGrabBombs Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanGrab;
- End;
- If Players[i].Powers.TriggerBomb > 0 Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanTrigger;
- End;
- If Players[i].Powers.JellyBombs Then Begin
- result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanJelly;
- End;
- If dNoBombs In Players[i].Disease Then Begin
- result.PlayerInfos[i].AvailableBombs := 0;
- End
- Else Begin
- result.PlayerInfos[i].AvailableBombs := Players[i].Powers.AvailableBombs;
- End;
- End;
- // Im Debug Modus die Oberen "Tot" schalten
- For i := high(Players) + 1 To 9 Do Begin
- result.PlayerInfos[i].Alive := false;
- End;
- // Field
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- Case fField[i, j].BrickData Of
- bdSolid: result.Field[i, j] := fSolid;
- bdBrick: result.Field[i, j] := fBrick;
- bdBlank: Begin
- If fField[i, j].Flame <> [] Then Begin
- result.Field[i, j] := fFlame;
- End
- Else Begin
- Case fField[i, j].PowerUp Of
- puNone: Begin
- result.Field[i, j] := fBlank;
- If fHasHoles Then Begin
- If fHoles[i, j] Then Begin
- result.Field[i, j] := fHole;
- End;
- End;
- If fHastrampolins Then Begin
- If fField[i, j].Tramp Then Begin
- result.Field[i, j] := fTramp;
- End;
- End;
- If fHasConveyors Then Begin
- Case fConveyorDirs[i, j] Of
- 0: result.Field[i, j] := fConveyorRight;
- 90: result.Field[i, j] := fConveyorUp;
- 180: result.Field[i, j] := fConveyorLeft;
- 270: result.Field[i, j] := fConveyorDown;
- End;
- End;
- If fHasArrows Then Begin
- Case fArrowDirs[i, j] Of
- 0: result.Field[i, j] := fArrowRight;
- 90: result.Field[i, j] := fArrowUp;
- 180: result.Field[i, j] := fArrowLeft;
- 270: result.Field[i, j] := fArrowDown;
- End;
- End;
- End;
- puExtraBomb: result.Field[i, j] := fExtraBomb;
- puLongerFlameLength: result.Field[i, j] := fLongerFlame;
- puCanCick: result.Field[i, j] := fKick;
- puExtraSpeed: result.Field[i, j] := fExtraSpeed;
- puCanSpooger: result.Field[i, j] := fSpooger;
- puCanPunch: result.Field[i, j] := fPunch;
- puCanGrab: result.Field[i, j] := fGrab;
- puGoldFlame: result.Field[i, j] := fGoldflame;
- puTrigger: result.Field[i, j] := fTrigger;
- puCanJelly: result.Field[i, j] := fJelly;
- // Ab hier Krankheiten oder "schlechtes"
- puDisease: result.Field[i, j] := fBadDisease;
- puSuperBadDisease: result.Field[i, j] := fBadDisease;
- puSlow: result.Field[i, j] := fSlow;
- // Zufall, ...
- purandom: result.Field[i, j] := fRandom;
- End;
- End;
- End;
- End;
- End;
- End;
- // Bombs
- result.BombsCount := fBombCount;
- setlength(result.Bombs, fBombCount);
- For i := 0 To result.BombsCount - 1 Do Begin
- result.Bombs[i].Position.x := fBombs[i].Position.x;
- result.Bombs[i].Position.y := fBombs[i].Position.y;
- // Das kann nur bei "Fliegenden" Bombem vor kommen, fangen wir aber dennoch mal ab ;)
- If result.Bombs[i].Position.x < 0 Then result.Bombs[i].Position.x := result.Bombs[i].Position.x + FieldWidth - 1;
- If result.Bombs[i].Position.x >= FieldWidth Then result.Bombs[i].Position.x := result.Bombs[i].Position.x - FieldWidth;
- If result.Bombs[i].Position.y < 0 Then result.Bombs[i].Position.y := result.Bombs[i].Position.y + FieldHeight - 1;
- If result.Bombs[i].Position.y >= FieldWidth Then result.Bombs[i].Position.y := result.Bombs[i].Position.y - FieldHeight;
- result.Bombs[i].FlameLength := fBombs[i].FireLen;
- result.Bombs[i].Flying := fBombs[i].MoveDir = bmFly;
- result.Bombs[i].Owner := fBombs[i].PlayerIndex;
- result.Bombs[i].ManualTrigger := fBombs[i].Animation = baTimeTriggered;
- result.Bombs[i].Jelly := fBombs[i].Jelly;
- result.Bombs[i].DudBomb := fBombs[i].Animation = baDud;
- result.Bombs[i].Lifetime := fBombs[i].Lifetime;
- End;
-End;
-
-Procedure TAtomicField.IncHurry;
-Var
- p: TPoint;
-Begin
- inc(fHurryIndex);
- If (fHurryIndex < 0) Or (fHurryIndex > high(HurryCoords)) Then exit; // Komisch ..
- p := HurryCoords[fHurryIndex];
- // Set the Solid Brick
- fField[p.x, p.y].BrickData := bdSolid;
- // Reset everything else
- fField[p.x, p.y].Exploding := false;
- fField[p.x, p.y].ExplodingRenderFlag := false;
- fField[p.x, p.y].PowerUp := puNone;
- fField[p.x, p.y].Flame := [];
- fField[p.x, p.y].Tramp := false;
- fField[p.x, p.y].TrampRunning := false;
- fField[p.x, p.y].Counter := 0;
-End;
-
-Procedure TAtomicField.KillPlayer(Var Players: TPlayers; Index: integer);
-Begin
- Players[Index].MoveState := msStill; // Zum Sterben halten wir an ;)
- Players[Index].Info.Animation := raDie;
- Players[Index].Info.Value := Random(65536); // Eine Zufällige Todesanimation wählen
- Players[Index].Info.Dying := true;
- Players[Index].Info.Direction := 0;
- Players[Index].Info.Counter := 0;
-End;
-
-Procedure TAtomicField.RepopulatePlayersCollectedPowerUps(
- Const Players: TPlayers; PlayerIndex: Integer);
-Var
- pu: TPowerUps;
- cnt, i, OverflowProtect, j: Integer;
- x, y: Int64;
- b, noHole: Boolean;
-Begin
- log('TServer.RepopulatePlayersCollectedPowerUps', lltrace);
- For pu In TPowerUps Do Begin
- If pu = puNone Then Continue;
- (*
- * Bei "Fähigkeiten" begrenzen wir das ganze auf maximal 1
- *)
- cnt := Players[PlayerIndex].PowerUpCounter[pu];
- If pu In [puCanCick, puCanSpooger, puCanPunch, puCanGrab, puGoldFlame, puCanJelly] Then Begin
- cnt := min(cnt, 1);
- End;
- For i := 0 To cnt - 1 Do Begin
- OverflowProtect := 0;
- While (OverflowProtect < FieldWidth * FieldHeight) Do Begin
- x := Random(FieldWidth);
- y := Random(FieldHeight);
- // Das Feld ist Prinzipiel mal "Frei"
- noHole := true;
- If fHasHoles Then Begin // Auf Löchern dürfen keine PowerUps erzeugt werden
- If fHoles[x, y] Then noHole := false;
- End;
- If (fField[x, y].BrickData = bdBlank) And (fField[x, y].Flame = []) And (fField[x, y].PowerUp = puNone) And noHole Then Begin
- b := true;
- // Verhindern dass ein Powerup da generiert wird wo ein Spieler Steht.
- For j := 0 To high(Players) Do Begin
- If Not Players[j].Info.Alive Then Continue;
- If Players[j].Flying Then Continue;
- If (x = trunc(Players[j].Info.Position.x)) And
- (y = trunc(Players[j].Info.Position.y)) Then Begin
- b := false;
- break;
- End;
- End;
- // Verhindern, das ein Powerup da generiert wird wo eine Bombe liegt
- If b Then Begin
- For j := 0 To fBombCount - 1 Do Begin
- If fBombs[j].MoveDir = bmFly Then Continue;
- If (x = trunc(fBombs[j].Position.x)) And
- (x = trunc(fBombs[j].Position.x)) Then Begin
- b := false;
- break;
- End;
- End;
- End;
- // Wie haben eine Feld gefunden, das belegt werden kann ;)
- If b Then Begin
- fField[x, y].PowerUp := pu;
- OverflowProtect := FieldWidth * FieldHeight; // Aus der While Sauber Raus gehen..
- End;
- End;
- inc(OverflowProtect);
- End;
- End;
- End;
- LogLeave;
-End;
-
-Procedure TAtomicField.TelePortPlayer(Var Player: TPlayer);
-Var
- x, y: Integer;
-Begin
- (*
- * Den Spieler im Gegenuhrzegeigersinn auf der Karte drehen
- *)
- x := trunc(Player.Info.Position.x);
- y := trunc(Player.Info.Position.y);
- If x = 2 Then Begin
- If y = 2 Then Begin
- Player.Info.Position.y := 8.5;
- End
- Else Begin
- Player.Info.Position.x := 12.5;
- End;
- End
- Else Begin
- If y = 2 Then Begin
- Player.Info.Position.x := 2.5;
- End
- Else Begin
- Player.Info.Position.y := 2.5;
- End;
- End;
-End;
-
-{$ENDIF}
-
-{$IFDEF Client}
-
-Procedure TAtomicField.RenderBlock(x, y: integer; Brick: TBrickData);
-Begin
- If Brick = bdBlank Then exit;
- glPushMatrix;
- glTranslatef(Fieldxoff + x * FieldBlockWidth, FieldyOff + y * FieldBlockHeight, 0);
- If Brick = bdSolid Then Begin
- RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fSolidTex);
- End
- Else Begin
- RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fBrickTex);
- End;
- glPopMatrix;
-End;
-
-Function TAtomicField.OnxBrickOverflow(Sender: TObject): Boolean;
-Var
- index, x, y: integer;
-Begin
- index := TOpenGL_Animation(sender).Tag;
- x := index Mod FieldWidth;
- y := index Div FieldWidth;
- fxBricks[x, y].Active := false;
- result := false; // Do not loop the animation !
-End;
-
-Procedure TAtomicField.RenderPreview;
-Var
- j, i: Integer;
-Begin
- (*
- * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
- *)
- glColor3f(1, 1, 1);
- glpushmatrix();
- glTranslatef(0, 0, atomic_Map_Layer);
- RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
- glTranslatef(0, 0, atomic_EPSILON);
- For j := 0 To 4 Do Begin
- For i := 0 To 4 Do Begin
- Case fPreviewLines[j][i + 1] Of
- '.': RenderBlock(i, j, bdBlank);
- ':': RenderBlock(i, j, bdBrick);
- '#': RenderBlock(i, j, bdSolid);
- End;
- End;
- End;
- glpopmatrix();
-End;
-
-Procedure TAtomicField.Render(Const Atomics: TAtomics; PowerTexs: TPowerTexArray
- );
-
- Procedure RenderArrow(x, y: integer);
- Begin
- If fArrowDirs[x, y] <> -1 Then Begin
- glPushMatrix;
- glTranslatef(Fieldxoff + x * FieldBlockWidth + 10, FieldyOff + y * FieldBlockHeight + 15, atomic_EPSILON);
- fArrows.Render(fArrowDirs[x, y]);
- glPopMatrix;
- End;
- End;
-
- Procedure RenderConveyor(x, y: integer);
- Begin
- If fConveyorDirs[x, y] <> -1 Then Begin
- glPushMatrix;
- glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
- fConveyors.Render(fConveyorDirs[x, y]);
- glPopMatrix;
- End;
- End;
-
- Procedure RenderHohle(x, y: integer);
- Begin
- If fholes[x, y] Then Begin
- glPushMatrix;
- glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
- RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fHoleTex);
- glPopMatrix;
- End;
- End;
-
- Procedure RenderTramp(x, y: integer);
- Begin
- If fField[x, y].Tramp Then Begin
- glPushMatrix;
- glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
- If fField[x, y].TrampRunning Then Begin
- fTramp.AnimationOffset := fField[x, y].TrampOffset;
- fTramp.Render(fConveyorDirs[x, y]);
- End
- Else Begin
- OpenGL_SpriteEngine.RenderSprite(fTrampStaticSprite);
- End;
- glPopMatrix;
- End;
- End;
-
-Var
- i, j: Integer;
- FlameAni: TOpenGL_Animation;
- FlameAngle: integer;
-Begin
- glColor3f(1, 1, 1);
- glpushmatrix();
- glTranslatef(0, 0, atomic_Map_Layer);
- RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
- // Alle Blöcke, Flammen Powerups etc ...
- glpushmatrix();
- glTranslatef(0, 0, atomic_EPSILON);
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- // Rendern der Brickdaten
- If fxBricks[i, j].Active Then Begin // Soll gerade die "Explode" Animation laufen ??
- glPushMatrix;
- glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
- fxBricks[i, j].Ani.Render(0);
- glPopMatrix;
- End
- Else Begin
- If fField[i, j].BrickData <> bdBlank Then Begin
- RenderBlock(i, j, fField[i, j].BrickData);
- End
- Else Begin
- // Rendern der Flamen
- If fField[i, j].Flame <> [] Then Begin
- // Wählen der Richtigen Animation
- If fCross In fField[i, j].Flame Then Begin
- FlameAni := Atomics[fField[i, j].FlameColor].FlameCross;
- End
- Else Begin
- If fend In fField[i, j].Flame Then Begin
- FlameAni := Atomics[fField[i, j].FlameColor].FlameEnd;
- End
- Else Begin
- FlameAni := Atomics[fField[i, j].FlameColor].FlameMiddle;
- End;
- End;
- FlameAngle := 0;
- If fup In fField[i, j].Flame Then FlameAngle := 90;
- If fleft In fField[i, j].Flame Then FlameAngle := 180;
- If fdown In fField[i, j].Flame Then FlameAngle := 270;
- glPushMatrix;
- glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
- FlameAni.Render(FlameAngle);
- glPopMatrix;
- End
- Else Begin
- // Render der Powerups
- If fField[i, j].PowerUp <> puNone Then Begin
- glPushMatrix;
- glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
- RenderQuad(v2(20, 18), 40, 36, 0, PowerTexs[fField[i, j].PowerUp]);
- glPopMatrix;
- End
- Else Begin
- // Es ist einfach nichts auf der Kachel, ggf ist dann ja ein Pfeil oder ein Laufband zu sehen ..
- If fHasArrows Then Begin
- RenderArrow(i, j);
- End;
- If fHasConveyors Then Begin
- RenderConveyor(i, j);
- End;
- If fHasHoles Then Begin
- RenderHohle(i, j);
- End;
- If fHastrampolins Then Begin
- RenderTramp(i, j);
- End;
- End;
- End;
- End;
- End;
- End;
- End;
- glpopmatrix();
- glpopmatrix();
-End;
-
-Procedure TAtomicField.ReadGameingData(Const Stream: TStream);
-
-Var
- i, j: Integer;
-Begin
- (*
- * Da auf jedem Feld immer nur 1 Ding Gerendert werden kann ist das hier recht Easy ;)
- *)
- Stream.Read(fField, sizeof(fField));
- // GGF Starten einer Brick Explosion Animation
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- (*
- * Das ist ein Bischen Tricky da wir keinen direkten Event bekommen
- * nur die Information dass die Explosionsanimation laufen soll
- * und einen Counter wie Lange sie schon läuft..
- *)
- If fField[i, j].ExplodingRenderFlag Then Begin
- fxBricks[i, j].ani.ResetAnimation();
- fxBricks[i, j].Active := true;
- End;
- End;
- End;
-End;
-
-Procedure TAtomicField.Reset;
-Var
- i, j: Integer;
-Begin
- For i := 0 To FieldWidth - 1 Do Begin
- For j := 0 To FieldHeight - 1 Do Begin
- fxBricks[i, j].Active := false;
- End;
- End;
-End;
-
-{$ENDIF}
-
-End.
-
+(******************************************************************************)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit uatomic_field;
+
+{$MODE ObjFPC}{$H+}
+
+Interface
+
+Uses
+ Classes, SysUtils
+{$IFDEF Client}
+ , uopengl_animation
+ , uatomic
+{$ENDIF}
+ , uatomic_common
+{$IFDEF Server}
+ , ufifo, uvectormath
+ , uai_types
+{$ENDIF}
+
+ ;
+
+Type
+
+{$IFDEF Server}
+ TIntFifo = specialize TBufferedFifo < Integer > ;
+ TPointFifo = specialize TBufferedFifo < Tpoint > ;
+ TPlaySoundEffectCallback = Procedure(PlayerIndex: integer; Effect: TSoundEffect) Of Object;
+{$ENDIF}
+
+{$IFDEF Client}
+ TBrickAnimation = Record
+ ani: TOpenGL_Animation;
+ Active: Boolean;
+ End;
+{$ENDIF}
+
+ { TAtomicField }
+
+ TAtomicField = Class
+ private
+{$IFDEF Server}
+ fBombsEnabled: Boolean;
+ fBombs: Array[0..FieldWidth * FieldHeight - 1] Of TBombInfo; // Das Array ist eigentlich hoch Dynamisch, aber so allokieren wir nicht andauernd neuen Speicher
+ fBombCount: Integer;
+ fBombDetonateFifo: TIntFifo;
+ fPowerUpClearFifo: TPointFifo;
+ fPlaySoundEffect: TPlaySoundEffectCallback;
+ fHurryIndex: integer; // Der Index in der HurryCoords Konstante, wenn Hurry Aktiv ist.
+{$ENDIF}
+ fHasArrows: Boolean; // Wenn True, dann hat die Karte die Lustigen Pfeilchen auf denen die Bomben hin und her geschubst werden..
+ fArrowDirs: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of integer; // Die Richtungen der "Pfeile" -1 = Aus, 0, 90, 180, 270 = Winkel
+ fHasConveyors: Boolean; // Wenn True, dann hat die Karte diese Blauen Fließbänder auf denen Spieler und Bomben automatisch bewegt werden (geschwindigkeit via Settings einstellbar)
+ fConveyorDirs: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of integer; // Die Richtungen der "Pfeile" -1 = Aus, 0, 90, 180, 270 = Winkel
+ fHasHoles: Boolean; // Wenn True, dann hat die Karte die 4 Löcher, welche den Atomic im Gegenuhrzeigersinn hin und her beamen
+ fHastrampolins: Boolean; // Wenn True, dann hat die Karte "trampoline"
+ fHoles: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of boolean; // True, an dieser Stelle wird ein "Loch" gezeichnet
+{$IFDEF Client}
+ fTrampStaticSprite, fHoleTex, fFieldTex, fBrickTex, fSolidTex: integer;
+ fxBricks: Array[0..FieldWidth - 1, 0..FieldHeight - 1] Of TBrickAnimation;
+ fxBrickAniTime: integer;
+ fPreviewLines: Array[0..4] Of String;
+ fTramp, fArrows, fConveyors: TOpenGL_Animation;
+{$ENDIF}
+ fSoundFile: String;
+ fHash: Uint64; // Wird beim laden der Karte berechnet, dient zur Identifizierung auf "Gleichheit"
+ fField: TFieldBricks;
+{$IFDEF Client}
+ Procedure RenderBlock(x, y: integer; Brick: TBrickData);
+ Function OnxBrickOverflow(Sender: TObject): Boolean;
+{$ENDIF}
+{$IFDEF Server}
+ (*
+ * False, wenn der Strahl gestoppt wird und nicht mehr "weiter" Laufen darf
+ *)
+ Function Detonate(x, y: integer; TriggerPlayerindex, ColorIndex: integer; Flame: TFlame): Boolean;
+ Function FielWalkable(x, y: integer; AlsoCheckPowerUps: Boolean): Boolean;
+{$ENDIF}
+ public
+ Name: String;
+ Available: Boolean; // Wenn True, dann kann die Karte verwendet werden und Alle Spieler haben sie.
+{$IFDEF Server}
+ StatisticCallback: TStatisticCallback;
+ Property BombsEnabled: Boolean read fBombsEnabled;
+{$ENDIF}
+ Property Hash: UInt64 read fHash; // Pseudo MD5Hash über alle Dateien der Karte
+ Property Sound: String read fSoundFile;
+ Constructor Create(
+{$IFDEF Server}
+ PlaySoundEffectCallback: TPlaySoundEffectCallback;
+ sStatisticCallback: TStatisticCallback
+{$ENDIF}
+ ); virtual;
+
+ Destructor Destroy(); override;
+ Function loadFromDirectory(Dir: String
+{$IFDEF Client}
+ ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
+{$ENDIF}
+ ): Boolean;
+{$IFDEF Client}
+ Procedure RenderPreview; virtual;
+ Procedure Render(Const Atomics: TAtomics; PowerTexs: TPowerTexArray);
+ Procedure ReadGameingData(Const Stream: TStream);
+ Procedure Reset(); // Wie Initialize nur eben die Client version
+{$ENDIF}
+{$IFDEF Server}
+ Procedure Initialize(Const Players: TPlayers; Const Scheme: TScheme); // Setzt die Spielerpositionen gleich mit
+ Procedure AppendGamingData(Const Stream: TStream);
+ Function HandleMovePlayer(Var Players: TPlayers; PlayerIndex: integer; ConveyorSpeed: TConveyorSpeed): Boolean; // True, wenn der Spieler gestorben ist.
+ Procedure HandleActionPlayer(Var Player: TPlayer; PlayerIndex: integer);
+ Procedure HandleBombs(Var Players: TPlayers; PreHurry: Boolean; ConveyorSpeed: TConveyorSpeed);
+ Procedure HandlePlayerVsMap(Var Players: TPlayers; PlayerGetsPowerUp: TPlayerGetsPowerUpEvent);
+ Procedure HandleFieldAnims;
+ Procedure DisableAllBombs();
+ Function GetAiInfo(Const Players: TPlayers; TeamPlay: Boolean): TaiInfo;
+ Procedure IncHurry();
+ Procedure KillPlayer(Var Players: TPlayers; Index: integer); // Ohne Punktewertung
+ Procedure RepopulatePlayersCollectedPowerUps(Const Players: TPlayers; PlayerIndex: Integer);
+ Procedure TelePortPlayer(Var Player: TPlayer);
+{$ENDIF}
+ End;
+
+ { TAtomicRandomField }
+
+ TAtomicRandomField = Class(TAtomicField)
+ private
+{$IFDEF Client}
+ fPreviewGrid: Array[0..4, 0..4] Of Integer;
+{$ENDIF}
+ public
+{$IFDEF Client}
+ Procedure CreatePreview(Const Fields: Array Of TAtomicField);
+ Procedure RenderPreview; override;
+{$ENDIF}
+ End;
+
+Implementation
+
+Uses
+ Graphics, IniFiles, md5
+{$IFDEF server}
+ , math
+{$ENDIF}
+{$IFDEF Client}
+ , uvectormath
+ , dglOpenGL
+ , uopengl_graphikengine
+ , uopengl_spriteengine
+ , ugraphics
+{$ENDIF}
+ ;
+
+{$IFDEF server}
+Const
+ (*
+ * Beschreibt einen Weg von Links oben schneckenmäßig im Uhrzeigersinn bis nach innen rein, bis nur noch 5 Felder in der Mitte ügrig sind.
+ *)
+ HurryCoords: Array[0..159] Of Tpoint = (
+ (x: 0; y: 0), (x: 1; y: 0), (x: 2; y: 0), (x: 3; y: 0), (x: 4; y: 0), (x: 5; y: 0), (x: 6; y: 0), (x: 7; y: 0), (x: 8; y: 0), (x: 9; y: 0), (x: 10; y: 0), (x: 11; y: 0), (x: 12; y: 0), (x: 13; y: 0), (x: 14; y: 0),
+ (x: 14; y: 1), (x: 14; y: 2), (x: 14; y: 3), (x: 14; y: 4), (x: 14; y: 5), (x: 14; y: 6), (x: 14; y: 7), (x: 14; y: 8), (x: 14; y: 9), (x: 14; y: 10),
+ (x: 13; y: 10), (x: 12; y: 10), (x: 11; y: 10), (x: 10; y: 10), (x: 9; y: 10), (x: 8; y: 10), (x: 7; y: 10), (x: 6; y: 10), (x: 5; y: 10), (x: 4; y: 10), (x: 3; y: 10), (x: 2; y: 10), (x: 1; y: 10), (x: 0; y: 10),
+ (x: 0; y: 9), (x: 0; y: 8), (x: 0; y: 7), (x: 0; y: 6), (x: 0; y: 5), (x: 0; y: 4), (x: 0; y: 3), (x: 0; y: 2), (x: 0; y: 1),
+ (x: 1; y: 1), (x: 2; y: 1), (x: 3; y: 1), (x: 4; y: 1), (x: 5; y: 1), (x: 6; y: 1), (x: 7; y: 1), (x: 8; y: 1), (x: 9; y: 1), (x: 10; y: 1), (x: 11; y: 1), (x: 12; y: 1), (x: 13; y: 1),
+ (x: 13; y: 2), (x: 13; y: 3), (x: 13; y: 4), (x: 13; y: 5), (x: 13; y: 6), (x: 13; y: 7), (x: 13; y: 8), (x: 13; y: 9),
+ (x: 12; y: 9), (x: 11; y: 9), (x: 10; y: 9), (x: 9; y: 9), (x: 8; y: 9), (x: 7; y: 9), (x: 6; y: 9), (x: 5; y: 9), (x: 4; y: 9), (x: 3; y: 9), (x: 2; y: 9), (x: 1; y: 9),
+ (x: 1; y: 8), (x: 1; y: 7), (x: 1; y: 6), (x: 1; y: 5), (x: 1; y: 4), (x: 1; y: 3), (x: 1; y: 2),
+ (x: 2; y: 2), (x: 3; y: 2), (x: 4; y: 2), (x: 5; y: 2), (x: 6; y: 2), (x: 7; y: 2), (x: 8; y: 2), (x: 9; y: 2), (x: 10; y: 2), (x: 11; y: 2), (x: 12; y: 2),
+ (x: 12; y: 3), (x: 12; y: 4), (x: 12; y: 5), (x: 12; y: 6), (x: 12; y: 7), (x: 12; y: 8),
+ (x: 11; y: 8), (x: 10; y: 8), (x: 9; y: 8), (x: 8; y: 8), (x: 7; y: 8), (x: 6; y: 8), (x: 5; y: 8), (x: 4; y: 8), (x: 3; y: 8), (x: 2; y: 8),
+ (x: 2; y: 7), (x: 2; y: 6), (x: 2; y: 5), (x: 2; y: 4), (x: 2; y: 3),
+ (x: 3; y: 3), (x: 4; y: 3), (x: 5; y: 3), (x: 6; y: 3), (x: 7; y: 3), (x: 8; y: 3), (x: 9; y: 3), (x: 10; y: 3), (x: 11; y: 3),
+ (x: 11; y: 4), (x: 11; y: 5), (x: 11; y: 6), (x: 11; y: 7),
+ (x: 10; y: 7), (x: 9; y: 7), (x: 8; y: 7), (x: 7; y: 7), (x: 6; y: 7), (x: 5; y: 7), (x: 4; y: 7), (x: 3; y: 7),
+ (x: 3; y: 6), (x: 3; y: 5), (x: 3; y: 4),
+ (x: 4; y: 4), (x: 5; y: 4), (x: 6; y: 4), (x: 7; y: 4), (x: 8; y: 4), (x: 9; y: 4), (x: 10; y: 4),
+ (x: 10; y: 5), (x: 10; y: 6),
+ (x: 9; y: 6), (x: 8; y: 6), (x: 7; y: 6), (x: 6; y: 6), (x: 5; y: 6), (x: 4; y: 6),
+ (x: 4; y: 5)
+ );
+{$ENDIF}
+
+{$IFDEF Client}
+
+ { TAtomicRandomField }
+
+Procedure TAtomicRandomField.CreatePreview(Const Fields: Array Of TAtomicField);
+Var
+ index, i, j: Integer;
+Begin
+ // Irgend eine Hintergrund Graphik Wählen
+ fFieldTex := Fields[random(Length(Fields))].fFieldTex;
+ // Irgend welche Bricks / Solids nehmen
+ For i := 0 To 4 Do Begin
+ For j := 0 To 4 Do Begin
+ index := random(Length(Fields));
+ If ((i = 1) And (j = 1)) Or
+ ((i = 3) And (j = 1)) Or
+ ((i = 1) And (j = 3)) Or
+ ((i = 3) And (j = 3)) Then Begin
+ fPreviewGrid[i, j] := Fields[index].fSolidTex;
+ End
+ Else Begin
+ fPreviewGrid[i, j] := Fields[index].fBrickTex;
+ End;
+ End;
+ End;
+ // Ein Paar Felder sollen auch "Leer" bleiben
+ fPreviewGrid[0, 0] := 0;
+ fPreviewGrid[1, 0] := 0;
+ fPreviewGrid[0, 1] := 0;
+ fPreviewGrid[0, 3] := 0;
+ fPreviewGrid[1, 4] := 0;
+End;
+
+Procedure TAtomicRandomField.RenderPreview;
+
+Var
+ j, i: Integer;
+Begin
+ (*
+ * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
+ *)
+ glColor3f(1, 1, 1);
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_Map_Layer);
+ RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
+ For j := 0 To 4 Do Begin
+ For i := 0 To 4 Do Begin
+ If fPreviewGrid[i, j] = 0 Then Continue;
+ glPushMatrix;
+ glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, atomic_EPSILON);
+ RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fPreviewGrid[i, j]);
+ glPopMatrix;
+ End;
+ End;
+ glpopmatrix();
+End;
+{$ENDIF}
+
+{ TAtomicField }
+
+// Die IDE Code vervollständigung killt manchmal den Korrekten Header, deswegen hier die "Kopiervorlage"
+//Constructor TAtomicField.Create(
+//{$IFDEF Server}
+// PlaySoundEffectCallback: TPlaySoundEffectCallback;
+// sStatisticCallback: TStatisticCallback
+//{$ENDIF}
+// );
+
+Constructor TAtomicField.Create(
+{$IFDEF Server}
+ PlaySoundEffectCallback: TPlaySoundEffectCallback;
+ sStatisticCallback: TStatisticCallback
+{$ENDIF}
+ );
+Var
+ i, j: integer;
+Begin
+{$IFDEF Client}
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ fxBricks[i, j].ani := Nil;
+ End;
+ End;
+{$ENDIF}
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ fArrowDirs[i, j] := -1;
+ fConveyorDirs[i, j] := -1;
+ fHoles[i, j] := false;
+ End;
+ End;
+ // Die 4 Löcher
+ fHoles[2, 2] := true;
+ fHoles[12, 2] := true;
+ fHoles[12, 8] := true;
+ fHoles[2, 8] := true;
+ // Alle nach Rechts
+ fArrowDirs[2, 0] := 0;
+ fArrowDirs[6, 0] := 0;
+ fArrowDirs[10, 0] := 0;
+ fArrowDirs[0, 2] := 0;
+ fArrowDirs[4, 2] := 0;
+ fArrowDirs[8, 2] := 0;
+ fArrowDirs[12, 2] := 0;
+ fArrowDirs[4, 4] := 0;
+ fArrowDirs[0, 6] := 0;
+ fArrowDirs[8, 6] := 0;
+ fArrowDirs[12, 6] := 0;
+ // Alle nach Oben
+ fArrowDirs[2, 2] := 90;
+ fArrowDirs[6, 2] := 90;
+ fArrowDirs[10, 2] := 90;
+ fArrowDirs[0, 4] := 90;
+ fArrowDirs[2, 6] := 90;
+ fArrowDirs[4, 6] := 90;
+ fArrowDirs[10, 6] := 90;
+ fArrowDirs[0, 8] := 90;
+ fArrowDirs[2, 10] := 90;
+ fArrowDirs[6, 10] := 90;
+ fArrowDirs[10, 10] := 90;
+ // Alle nach Links
+ fArrowDirs[2, 4] := 180;
+ fArrowDirs[10, 4] := 180;
+ fArrowDirs[14, 4] := 180;
+ fArrowDirs[6, 6] := 180;
+ fArrowDirs[2, 8] := 180;
+ fArrowDirs[6, 8] := 180;
+ fArrowDirs[10, 8] := 180;
+ fArrowDirs[14, 8] := 180;
+ fArrowDirs[4, 10] := 180;
+ fArrowDirs[8, 10] := 180;
+ fArrowDirs[12, 10] := 180;
+ // Alle nach unten
+ fArrowDirs[4, 0] := 270;
+ fArrowDirs[8, 0] := 270;
+ fArrowDirs[12, 0] := 270;
+ fArrowDirs[14, 2] := 270;
+ fArrowDirs[6, 4] := 270;
+ fArrowDirs[8, 4] := 270;
+ fArrowDirs[12, 4] := 270;
+ fArrowDirs[14, 6] := 270;
+ fArrowDirs[4, 8] := 270;
+ fArrowDirs[8, 8] := 270;
+ fArrowDirs[12, 8] := 270;
+ // Nach Rechts
+ For i := 2 To 11 Do Begin
+ fConveyorDirs[i, 2] := 0;
+ End;
+ // Nach Unten
+ For j := 2 To 7 Do Begin
+ fConveyorDirs[12, j] := 270;
+ End;
+ // Nach Links
+ For i := 3 To 12 Do Begin
+ fConveyorDirs[i, 8] := 180;
+ End;
+ // Nach oben
+ For j := 3 To 8 Do Begin
+ fConveyorDirs[2, j] := 90;
+ End;
+ Name := '';
+ fHash := 0;
+{$IFDEF Server}
+ StatisticCallback := sStatisticCallback;
+ fPlaySoundEffect := PlaySoundEffectCallback;
+ fBombCount := 0;
+ fBombDetonateFifo := TIntFifo.create(128);
+ fPowerUpClearFifo := TPointFifo.create(128);
+{$ENDIF}
+End;
+
+Destructor TAtomicField.Destroy;
+{$IFDEF Client}
+Var
+ i, j: Integer;
+{$ENDIF}
+Begin
+{$IFDEF Client}
+ For i := 0 To FieldWidth - 1 Do
+ For j := 0 To FieldHeight - 1 Do
+ If assigned(fxBricks[i, j].ani) Then fxBricks[i, j].ani.free;
+{$ENDIF}
+{$IFDEF Server}
+ fBombDetonateFifo.free;
+ fPowerUpClearFifo.free;
+{$ENDIF}
+ Inherited Destroy;
+End;
+
+// Die IDE Code vervollständigung killt manchmal den Korrekten Header, deswegen hier die "Kopiervorlage"
+//Function TAtomicField.loadFromDirectory(Dir: String
+//{$IFDEF Client}
+// ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
+//{$ENDIF}
+// ): Boolean;
+
+Function TAtomicField.loadFromDirectory(Dir: String
+{$IFDEF Client}
+ ; Const aArrows: TOpenGL_Animation; Const aConveyors: TOpenGL_Animation; Const aTramp: TOpenGL_Animation; Const aHohle, aTrampStatic: Integer
+{$ENDIF}
+ ): Boolean;
+Var
+ tmphash: TMD5Digest;
+
+ Procedure AppendHash;
+ Var
+ val: UInt64;
+ i: Integer;
+ Begin
+ val := 0;
+ For i := 0 To 7 Do Begin
+ val := val Shl 8;
+ val := val Or tmphash[i];
+ End;
+ fHash := fHash Xor val;
+
+ val := 0;
+ For i := 8 To 15 Do Begin
+ val := val Shl 8;
+ val := val Or tmphash[i];
+ End;
+ fHash := fHash Xor val;
+ End;
+
+Var
+ ini: TIniFile;
+ sl: TStringList;
+ normalizedContent: String;
+ fs: TFileStream;
+ rawContent: AnsiString;
+ normalizedBytes: TMemoryStream;
+ i: Integer;
+{$IFDEF Client}
+ j: Integer;
+ xBrick: TOpenGL_Animation;
+{$ENDIF}
+Begin
+ result := false;
+{$IFDEF Client}
+ fArrows := aArrows;
+ fConveyors := aConveyors;
+ fTramp := aTramp;
+ fTrampStaticSprite := aTrampStatic;
+{$ENDIF}
+ fHash := 0;
+ dir := IncludeTrailingPathDelimiter(dir);
+
+ If Not FileExists(dir + 'brick.png') Then exit;
+{$IFDEF Client}
+ fBrickTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(dir + 'brick.png', ColorToRGB(clfuchsia), smStretchHard);
+{$ENDIF}
+ tmphash := MD5File(dir + 'brick.png');
+ AppendHash;
+
+ If Not FileExists(dir + 'field.png') Then exit;
+{$IFDEF Client}
+ fFieldTex := OpenGL_GraphikEngine.LoadGraphik(dir + 'field.png', smStretchHard);
+{$ENDIF}
+ tmphash := MD5File(dir + 'field.png');
+ AppendHash;
+
+ If Not FileExists(dir + 'info.txt') Then exit;
+ ini := TIniFile.Create(dir + 'info.txt');
+ name := ini.ReadString('General', 'Name', '');
+ fHasArrows := ini.ReadBool('General', 'HasArrows', false);
+ fHasConveyors := ini.ReadBool('General', 'HasConveyors', false);
+ fHasHoles := ini.ReadBool('General', 'HasHoles', false);
+ fHastrampolins := ini.ReadBool('General', 'Hastrampolins', false);
+
+ // T
+{$IFDEF Client}
+ For i := 0 To 4 Do Begin
+ fPreviewLines[i] := ini.ReadString('Preview', 'Row' + inttostr(i + 1), '.....');
+ End;
+{$ENDIF}
+ ini.free;
+ // Normalize line endings before calculating hash to ensure cross-platform consistency
+ // Windows uses CRLF (\r\n), Mac/Linux use LF (\n)
+ // We normalize to LF for consistent hashing across platforms
+ // Read file as raw bytes to avoid automatic line ending conversion
+ fs := TFileStream.Create(dir + 'info.txt', fmOpenRead);
+ Try
+ SetLength(rawContent, fs.Size);
+ fs.Read(rawContent[1], fs.Size);
+ Finally
+ fs.Free;
+ End;
+ // Normalize line endings: CRLF -> LF, CR -> LF
+ normalizedBytes := TMemoryStream.Create;
+ Try
+ i := 1;
+ While i <= Length(rawContent) Do Begin
+ If (i < Length(rawContent)) And (rawContent[i] = #13) And (rawContent[i + 1] = #10) Then Begin
+ // CRLF -> LF
+ normalizedBytes.WriteByte(10);
+ Inc(i, 2);
+ End
+ Else If rawContent[i] = #13 Then Begin
+ // CR -> LF
+ normalizedBytes.WriteByte(10);
+ Inc(i);
+ End
+ Else Begin
+ // Keep other bytes as-is
+ normalizedBytes.WriteByte(Ord(rawContent[i]));
+ Inc(i);
+ End;
+ End;
+ normalizedBytes.Position := 0;
+ // Calculate MD5 from normalized bytes
+ // Convert normalized bytes to string for MD5String
+ SetLength(normalizedContent, normalizedBytes.Size);
+ normalizedBytes.Read(normalizedContent[1], normalizedBytes.Size);
+ tmphash := MD5String(normalizedContent);
+ Finally
+ normalizedBytes.Free;
+ End;
+ AppendHash;
+ If name = '' Then exit; // Name ='' und Hash = 0 ist reserviert für das Random Field
+
+ If Not FileExists(dir + 'solid.png') Then exit;
+{$IFDEF Client}
+ fSolidTex := OpenGL_GraphikEngine.LoadAlphaColorGraphik(dir + 'solid.png', ColorToRGB(clfuchsia), smStretchHard);
+ fHoleTex := aHohle;
+{$ENDIF}
+ tmphash := MD5File(dir + 'solid.png');
+ AppendHash;
+
+ fSoundFile := Dir + 'sound.wav';
+ If Not FileExists(fSoundFile) Then exit;
+ tmphash := MD5File(fSoundFile);
+ AppendHash;
+
+ If Not FileExists(dir + 'xbrick.ani') Then exit;
+{$IFDEF Client}
+ xBrick := TOpenGL_Animation.Create;
+ xBrick.LoadFromFile(dir + 'xbrick.ani');
+ For i := 0 To FieldWidth - 1 Do
+ For j := 0 To FieldHeight - 1 Do Begin
+ fxBricks[i, j].ani := TOpenGL_Animation.Create;
+ fxBricks[i, j].ani.CloneFrom(xBrick);
+ fxBricks[i, j].ani.Tag := i + j * FieldWidth;
+ // TODO: Das Problem ist wenn der Server zu Langsam ist scheint das nicht zu gehen ...
+ fxBricks[i, j].ani.OnAnimationOverflowEvent := @OnxBrickOverflow;
+ fxBricks[i, j].Active := false;
+ End;
+ fxBrickAniTime := xBrick.Sprite[0].FrameCount * xBrick.Sprite[0].TimePerFrame;
+ xBrick.Free;
+{$ENDIF}
+ tmphash := MD5File(dir + 'xbrick.ani');
+ AppendHash;
+
+ result := true;
+End;
+
+{$IFDEF Server}
+
+Function TAtomicField.Detonate(x, y: integer; TriggerPlayerindex, ColorIndex: integer;
+ Flame: TFlame): Boolean;
+Var
+ i: Integer;
+{$IFDEF Server}
+ f: TextFile;
+ flameStr: String;
+{$ENDIF}
+Begin
+ result := false;
+ If (x < 0) Or (y < 0) Or (x > FieldWidth - 1) Or (y > FieldHeight - 1) Then exit;
+ (*
+ * Durch Analyse von: https://www.youtube.com/watch?v=qOtCVIMFJu0 bei sec 0.37
+ * Flamen "überschreiben" sich gegenseitig
+ * Powerups verbrennen sofort ohne Flamme
+ *)
+ result := true;
+ Case fField[x, y].BrickData Of
+ bdBlank: Begin
+ If fField[x, y].PowerUp = puNone Then Begin
+ fField[x, y].FlameColor := ColorIndex;
+ fField[x, y].FlamePlayer := TriggerPlayerindex;
+ If Not (fCross In fField[x, y].Flame) Then Begin // Sonst sieht es komisch aus ..
+ fField[x, y].Flame := [Flame];
+ End;
+ fField[x, y].Counter := 0;
+ End
+ Else Begin
+ fPowerUpClearFifo.Push(point(x, y));
+ // fField[x, y].PowerUp := puNone; -- Das geht net, da sonst 2 Bombem hintereinander durch das Popup durchschießen können !
+ result := false; // Egal wie der Strahl wird hier gestoppt !
+ End;
+ End;
+ bdBrick: Begin
+ If Not fField[x, y].Exploding Then Begin
+ StatisticCallback(sBricksDestroyed);
+ fField[x, y].Exploding := true;
+ fField[x, y].ExplodingRenderFlag := true;
+ End;
+ // Always set flame direction when brick is hit, even if already exploding
+ // This ensures the correct end flame animation is rendered based on the direction the explosion came from
+ // Only update if no direction is set yet, or if this is the first hit
+ If (fField[x, y].Flame = []) Or (Not (fend In fField[x, y].Flame)) Then Begin
+ fField[x, y].FlameColor := ColorIndex;
+ fField[x, y].FlamePlayer := TriggerPlayerindex;
+ // Set fend flag and direction
+ fField[x, y].Flame := [fend, Flame];
+ // Debug: log to file
+ {$IFDEF Server}
+ Try
+ flameStr := '';
+ If fup In fField[x, y].Flame Then flameStr := flameStr + 'fup ';
+ If fdown In fField[x, y].Flame Then flameStr := flameStr + 'fdown ';
+ If fleft In fField[x, y].Flame Then flameStr := flameStr + 'fleft ';
+ If fright In fField[x, y].Flame Then flameStr := flameStr + 'fright ';
+ If fend In fField[x, y].Flame Then flameStr := flameStr + 'fend ';
+ If fCross In fField[x, y].Flame Then flameStr := flameStr + 'fCross ';
+ AssignFile(f, 'debug.log');
+ If FileExists('debug.log') Then
+ Append(f)
+ Else
+ Rewrite(f);
+ WriteLn(f, Format('[SERVER] Detonate bdBrick: x=%d y=%d Flame param=%d -> fField.Flame=[%s]',
+ [x, y, Ord(Flame), Trim(flameStr)]));
+ CloseFile(f);
+ Except
+ // Ignore file errors
+ End;
+ {$ENDIF}
+ End;
+ // fField[x, y].BrickData := bdBlank; // der darf nicht Gleich weg genommen werden, da sonst 2 Bomben auch 2 Steine auf einmal wegsprengen !
+ fField[x, y].Counter := 0;
+ result := False;
+ End;
+ bdSolid: result := false; // Ein Nicht zerstörbarer Brick, der ist einfach ;)
+ End;
+ // Auslösen von Kettenreaktionen
+ For i := 0 To fBombCount - 1 Do Begin
+ If Not fBombs[i].Detonated Then Begin
+ If (trunc(fBombs[i].Position.x) = x) And (trunc(fBombs[i].Position.y) = y) Then Begin
+ // Derjenige der die Kettenreaktion auslöst, der bekommt den Kill
+ fBombs[i].TriggerPlayerindex := TriggerPlayerindex;
+ fBombDetonateFifo.push(i);
+ End;
+ End;
+ End;
+End;
+
+(*
+ * True, wenn man auf diese Koordinaten laufen kann
+ * es Kann belegt sein von einer Bombe und oder einem Stein
+ *)
+
+Function TAtomicField.FielWalkable(x, y: integer; AlsoCheckPowerUps: Boolean
+ ): Boolean;
+Var
+ i: Integer;
+Begin
+ result := false;
+ If (x < 0) Or (x > FieldWidth - 1) Or (y < 0) Or (y > FieldHeight - 1) Then exit;
+ result := fField[x, y].BrickData = bdBlank;
+ If Not result Then exit;
+ If AlsoCheckPowerUps Then Begin
+ result := fField[x, y].PowerUp = puNone;
+ End;
+ If Not result Then exit;
+ // Prüfung auf Bomben, reicht das so schon ?
+ For i := 0 To fBombCount - 1 Do Begin
+ If (x = trunc(fBombs[i].Position.x)) And
+ (y = trunc(fBombs[i].Position.y)) And
+ (fBombs[i].MoveDir <> bmFly) Then Begin
+ result := false;
+ exit;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.Initialize(Const Players: TPlayers; Const Scheme: TScheme
+ );
+ Function SetBlank(x, y: integer): Boolean;
+ Begin
+ result := false;
+ If (x >= 0) And (x < FieldWidth) And (y >= 0) And (y < FieldHeight) Then Begin
+ fField[x, y].BrickData := bdBlank;
+ result := true;
+ End;
+ End;
+
+ Function IsBlank(x, y: integer): boolean;
+ Begin
+ result := false;
+ If (x >= 0) And (x < FieldWidth) And (y >= 0) And (y < FieldHeight) Then Begin
+ result := fField[x, y].BrickData = bdBlank;
+ End;
+ End;
+
+Var
+ px, py, i, j, maxpow: Integer;
+ b: Boolean;
+Begin
+{$IFDEF Server}
+ fBombCount := 0; // Sollte es je noch Bomben gegeben haben nu sind sie Platt ;)
+ fBombsEnabled := true;
+ fHurryIndex := -1;
+{$ENDIF}
+ // Die Felder mit Elementen "Bevölkern"
+ // 1. Brick / Solid / Blank
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ fField[i, j].Exploding := false;
+ fField[i, j].ExplodingRenderFlag := false;
+ fField[i, j].Counter := 0;
+ fField[i, j].PowerUp := puNone;
+ fField[i, j].Flame := [];
+ fField[i, j].FlameColor := 0;
+ fField[i, j].FlamePlayer := -1;
+ fField[i, j].Tramp := false;
+ fField[i, j].TrampRunning := false;
+ fField[i, j].TrampOffset := random(256);
+ Case Scheme.BrickData[i, j] Of
+ bdSolid: fField[i, j].BrickData := bdSolid;
+ bdBlank: fField[i, j].BrickData := bdBlank;
+ bdBrick: Begin
+ If Scheme.BrickDensity > random(100) Then Begin
+ fField[i, j].BrickData := bdBrick;
+ End
+ Else Begin
+ fField[i, j].BrickData := bdBlank;
+ End;
+ End;
+ End;
+ End;
+ End;
+ // 2. Die Spielerpositionen "Frei" Räumen
+ For i := 0 To high(Players) Do Begin
+ If Players[i].Info.Alive Then Begin
+ SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y));
+ SetBlank(trunc(Players[i].Info.Position.x) - 1, trunc(Players[i].Info.Position.y));
+ SetBlank(trunc(Players[i].Info.Position.x) + 1, trunc(Players[i].Info.Position.y));
+ SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y - 1));
+ SetBlank(trunc(Players[i].Info.Position.x), trunc(Players[i].Info.Position.y + 1));
+ End;
+ End;
+ // 2.5 Wenn die Karte Trampoline hat, dann verteilen wir diese nun
+ If fHastrampolins Then Begin
+ For i := 0 To FieldTrampCount - 1 Do Begin
+ px := -1;
+ While px = -1 Do Begin
+ px := random(FieldWidth);
+ py := random(FieldHeight);
+ // Verhindern, dass Trampoline an Aktiven Spieler Positionen erstellt werden
+ For j := 0 To high(Players) Do Begin
+ If Players[j].Info.Alive Then Begin
+ If (trunc(Players[j].Info.Position.x) = px) And
+ (trunc(Players[j].Info.Position.x) = px) Then Begin
+ px := -1;
+ break;
+ End;
+ End;
+ End;
+ If (px <> -1) And fField[px, py].Tramp Then px := -1; // Sicherstellen, dass es auch wirklich FieldTrampCount werden !
+ End;
+ fField[px, py].Tramp := true;
+ End;
+ End;
+ // 2.5 Wenn die Karte "löcher" hat, dann müssen die immer Frei bleiben, und mindestens 1 adjazentes Feld auch !
+ If fHasHoles Then Begin
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ If fHoles[i, j] Then Begin
+ SetBlank(i, j);
+ If (Not IsBlank(i - 1, j)) And (Not IsBlank(i + 1, j))
+ And (Not IsBlank(i, j - 1)) And (Not IsBlank(i, j + 1)) Then Begin
+ b := false;
+ While Not b Do Begin
+ Case Random(4) Of
+ 0: b := SetBlank(i - 1, j);
+ 1: b := SetBlank(i + 1, j);
+ 2: b := SetBlank(i, j - 1);
+ 3: b := SetBlank(i, j + 1);
+ End;
+ End;
+ End;
+ End;
+ End;
+ End;
+ End;
+ // 3. Die PowerUps die Hinter den "Bricks" liegen
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ If fField[i, j].BrickData = bdBrick Then Begin // Nur Wo Wegsprengbare Steine sind, können Powerups drunder sein..
+ (* Die Random Powerups sind "Abschaltbar" *)
+ If Scheme.PowerUps[purandom].BornWith > 0 Then Begin
+ maxpow := 15;
+ End
+ Else Begin
+ maxpow := 14;
+ End;
+ Case random(maxpow) Of
+ 0: fField[i, j].PowerUp := puNone;
+ 1: fField[i, j].PowerUp := puExtraBomb;
+ 2: fField[i, j].PowerUp := puLongerFlameLength;
+ 3: fField[i, j].PowerUp := puDisease;
+ 4: fField[i, j].PowerUp := puCanCick;
+ 5: fField[i, j].PowerUp := puExtraSpeed;
+ 6: fField[i, j].PowerUp := puCanPunch;
+ 7: fField[i, j].PowerUp := puCanGrab;
+ 8: fField[i, j].PowerUp := puCanSpooger;
+ 9: fField[i, j].PowerUp := puGoldFlame;
+ 10: fField[i, j].PowerUp := puTrigger;
+ 11: fField[i, j].PowerUp := puCanJelly;
+ 12: fField[i, j].PowerUp := puSuperBadDisease;
+ 13: fField[i, j].PowerUp := puSlow;
+ 14: fField[i, j].PowerUp := purandom;
+ End;
+ // TODO: das sollte ggf noch feiner Justiert werden ..
+ If fField[i, j].PowerUp <> puNone Then Begin
+ If Scheme.PowerUps[fField[i, j].PowerUp].Forbidden Then fField[i, j].PowerUp := puNone;
+ End;
+ End;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.AppendGamingData(Const Stream: TStream);
+Var
+ i, j: integer;
+Begin
+ (*
+ * Da auf jedem Feld immer nur 1 Ding Gerendert werden kann ist das hier recht Easy ;)
+ *)
+ stream.Write(fField, SizeOf(fField));
+ // Sicherstellen, dass das ExplodingRenderFlag nur als Flanke raus geht (Also genau 1 mal gesetzt ist !)
+ For i := 0 To high(fField) Do Begin
+ For j := 0 To high(fField[i]) Do Begin
+ fField[i, j].ExplodingRenderFlag := false;
+ End;
+ End;
+{$IFDEF Server}
+ (*
+ * Wir Kopieren nur die Gültigen Bomben raus
+ *)
+ stream.Write(fBombCount, SizeOf(fBombCount));
+ For i := 0 To fBombCount - 1 Do Begin
+ stream.Write(fBombs[i].ColorIndex, SizeOf(fBombs[i].ColorIndex));
+ stream.Write(fBombs[i].Position, SizeOf(fBombs[i].Position));
+ stream.Write(fBombs[i].Animation, SizeOf(fBombs[i].Animation));
+ stream.Write(fBombs[i].AnimationOffset, SizeOf(fBombs[i].AnimationOffset));
+ End;
+{$ENDIF}
+End;
+
+Function TAtomicField.HandleMovePlayer(Var Players: TPlayers; PlayerIndex: integer; ConveyorSpeed: TConveyorSpeed): Boolean;
+
+ Function GetBombIndex(x, y: integer): integer;
+ Var
+ i: Integer;
+ Begin
+ result := -1;
+ For i := 0 To fBombCount - 1 Do Begin
+ If (trunc(fBombs[i].Position.x) = x) And
+ (trunc(fBombs[i].Position.y) = y) And
+ (fBombs[i].MoveDir <> bmFly) Then Begin // Fliegende Bomben haben keine Kollisionen !
+ result := i;
+ exit;
+ End;
+ End;
+ End;
+
+Const
+ Epsilon = 0.25; // Je Größer dieser Wert, desto mehr wird das Umlaufen der Ecken unterstützt (maximal wäre 0.5 möglich)
+Var
+ s, dx, dy, cSpeed, commaparty, commapartx, rSpeed: Single;
+ dxi, dyi, nx, ny, x, y, index: Integer;
+
+Begin
+ result := false;
+
+ If Players[PlayerIndex].Flying Then Begin
+ s := Players[PlayerIndex].Info.Counter / AtomicTrampFlyTime;
+ dx := Players[PlayerIndex].FlyTarget.x - Players[PlayerIndex].FlyStart.x;
+ dy := Players[PlayerIndex].FlyTarget.y - Players[PlayerIndex].FlyStart.y;
+ Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].FlyStart.x + dx * s;
+ Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].FlyStart.y + dy * s - (FieldHeight * 3) * sin(pi * s); // Die Bogenhöhe beim Trampolin
+ // Der Flug ist Beendet, sicherstellen, dass wir auf jeden Fall am Ziel angekommen sind.
+ If Players[PlayerIndex].Info.Counter > AtomicTrampFlyTime Then Begin
+ Players[PlayerIndex].Info.Position := Players[PlayerIndex].FlyTarget;
+ Players[PlayerIndex].Flying := false;
+ End;
+ exit; // Während des Fluges hat der Spieler natürlich keine Kontrolle über sich ;)
+ End;
+
+ // Die Kick Animation -> da bewegen wir uns erst mal nicht ;)
+ If (Players[PlayerIndex].Info.Animation = raKick) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimeKick - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
+ If (Players[PlayerIndex].Info.Animation = raPup) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimePup - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
+ If (Players[PlayerIndex].Info.Animation = raTeleport) And (Players[PlayerIndex].Info.Counter < AtomicAnimationTimeTeleport - 2 * UpdateRate) Then exit; // A Bissle schneller wieder "Frei" geben als geplant
+
+ (*
+ * Kickt der Spieler eine Bombe auf einem Laufband addieren sich die Geschwindigkeiten !
+ *)
+ cSpeed := 0;
+ If fHasConveyors And (Not Players[PlayerIndex].Flying) Then Begin
+ Case ConveyorSpeed Of
+ csSlow: cSpeed := ConveyorSlowSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ csMiddle: cSpeed := ConveyorMiddleSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ csFast: cSpeed := ConveyorFastSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ End;
+ x := trunc(Players[PlayerIndex].info.Position.x);
+ y := trunc(Players[PlayerIndex].info.Position.y);
+ If fConveyorDirs[x, y] <> -1 Then Begin // -- Aber nur wenn wir auch tatsächlich auf einem Laufband stehen..
+ commapartx := (Players[PlayerIndex].info.Position.x - trunc(Players[PlayerIndex].info.Position.x));
+ commaparty := (Players[PlayerIndex].info.Position.y - trunc(Players[PlayerIndex].info.Position.y));
+ // Die Bombe befindet sich "ungefähr" in der Mitte
+ dxi := 0;
+ dyi := 0;
+ Case fConveyorDirs[x, y] Of
+ 0: dxi := 1;
+ 90: dyi := -1;
+ 180: dxi := -1;
+ 270: dyi := 1;
+ End;
+ nx := x + dxi;
+ ny := y + dyi;
+ If Not FielWalkable(nx, ny, false) Then Begin // Das Laufband kann uns theoretisch auf ein Powerup drauf schieben, ob wir das nun wollen oder nicht ;)
+ dxi := 0;
+ dyi := 0;
+ End;
+ Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + dxi * cSpeed;
+ Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + dyi * cSpeed;
+ // Reinziehen der Bomben auf Ordentliche Koordinaten !
+ If (commaparty <> 0.5) Then Begin
+ If (dxi <> 0) Then Begin
+ Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End
+ Else Begin
+ If Not (Players[PlayerIndex].MoveState In [msDown, msUp]) Then
+ Players[PlayerIndex].info.Position.y := Players[PlayerIndex].info.Position.y + (0.5 - commaparty) * cSpeed;
+ End;
+ End;
+ If (commapartx <> 0.5) Then Begin
+ If (dyi <> 0) Then Begin
+ Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End
+ Else Begin
+ If Not (Players[PlayerIndex].MoveState In [msRight, msLeft]) Then
+ Players[PlayerIndex].info.Position.x := Players[PlayerIndex].info.Position.x + (0.5 - commapartx) * cSpeed;
+ End;
+ End;
+ End;
+ End;
+ cSpeed := 0;
+ rSpeed := Players[PlayerIndex].Powers.Speed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+
+ // Das Bewegen des Atomics anhand Seiner Daten
+ Case Players[PlayerIndex].MoveState Of
+ msStill: Players[PlayerIndex].Info.Animation := raStandStill;
+ msRight: Begin
+ Players[PlayerIndex].Info.Animation := raWalk;
+ Players[PlayerIndex].Info.Direction := 0;
+ Players[PlayerIndex].Info.Position.x := min(FieldWidth - 0.5, Players[PlayerIndex].Info.Position.x + rSpeed);
+ commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
+ commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
+ If commaparty <> 0.5 Then Begin
+ Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].Info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End;
+ // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
+ If commapartx > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(Players[PlayerIndex].Info.Position.x) + 1;
+ y := trunc(Players[PlayerIndex].info.Position.y);
+ If commaparty > 0.5 + Epsilon Then Begin
+ y := y + 1;
+ End;
+ If Not FielWalkable(x, y, false) Then Begin
+ index := GetBombIndex(x, y);
+ // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
+ If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
+ If FielWalkable(x + 1, y, true) Then Begin // Kann die Bombe sich bewegen ?
+ If fBombs[index].MoveDir <> bmRight Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombKick);
+ Players[PlayerIndex].Info.Animation := raKick;
+ Players[PlayerIndex].Info.Counter := 0;
+ fBombs[index].MoveDir := bmRight;
+ fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
+ fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
+ End;
+ End
+ Else Begin
+ If fBombs[index].MoveDir <> bmNone Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
+ End;
+ End
+ Else Begin
+ If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
+ End;
+ End;
+ End;
+ End;
+ msLeft: Begin
+ Players[PlayerIndex].Info.Animation := raWalk;
+ Players[PlayerIndex].Info.Direction := 180;
+ Players[PlayerIndex].Info.Position.x := max(0.5, Players[PlayerIndex].Info.Position.x - rSpeed);
+ commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
+ commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
+ If commaparty <> 0.5 Then Begin
+ Players[PlayerIndex].Info.Position.y := Players[PlayerIndex].Info.Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End;
+ // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
+ If commapartx < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(Players[PlayerIndex].Info.Position.x) - 1;
+ y := trunc(Players[PlayerIndex].info.Position.y);
+ If commaparty > 0.5 + Epsilon Then Begin
+ y := y + 1;
+ End;
+ If Not FielWalkable(x, y, false) Then Begin
+ index := GetBombIndex(x, y);
+ // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
+ If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
+ If FielWalkable(x - 1, y, true) Then Begin // Kann die Bombe sich bewegen ?
+ If fBombs[index].MoveDir <> bmLeft Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombKick);
+ Players[PlayerIndex].Info.Animation := raKick;
+ Players[PlayerIndex].Info.Counter := 0;
+ fBombs[index].MoveDir := bmLeft;
+ fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
+ fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
+ End;
+ End
+ Else Begin
+ If fBombs[index].MoveDir <> bmNone Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
+ End;
+ End
+ Else Begin
+ If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.x := trunc(Players[PlayerIndex].Info.Position.x) + 0.5;
+ End;
+ End;
+ End;
+ End;
+ msUp: Begin
+ Players[PlayerIndex].Info.Animation := raWalk;
+ Players[PlayerIndex].Info.Direction := 90;
+ Players[PlayerIndex].Info.Position.y := max(0.5, Players[PlayerIndex].Info.Position.y - rSpeed);
+ commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
+ commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
+ If commapartx <> 0.5 Then Begin
+ Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].Info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End;
+ // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
+ If commaparty < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(Players[PlayerIndex].Info.Position.x);
+ y := trunc(Players[PlayerIndex].info.Position.y) - 1;
+ If commapartx > 0.5 + Epsilon Then Begin
+ x := x + 1;
+ End;
+ If Not FielWalkable(x, y, false) Then Begin
+ index := GetBombIndex(x, y);
+ // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
+ If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
+ If FielWalkable(x, y - 1, true) Then Begin // Kann die Bombe sich bewegen ?
+ If fBombs[index].MoveDir <> bmUp Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombKick);
+ Players[PlayerIndex].Info.Animation := raKick;
+ Players[PlayerIndex].Info.Counter := 0;
+ fBombs[index].MoveDir := bmUp;
+ fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
+ fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
+ End;
+ End
+ Else Begin
+ If fBombs[index].MoveDir <> bmNone Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
+ End;
+ End
+ Else Begin
+ If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
+ End;
+ End;
+ End;
+ End;
+ msDown: Begin
+ Players[PlayerIndex].Info.Animation := raWalk;
+ Players[PlayerIndex].Info.Direction := 270;
+ Players[PlayerIndex].Info.Position.y := min(FieldHeight - 0.5, Players[PlayerIndex].Info.Position.y + rSpeed);
+ commapartx := (Players[PlayerIndex].Info.Position.x - trunc(Players[PlayerIndex].Info.Position.x));
+ commaparty := (Players[PlayerIndex].Info.Position.y - trunc(Players[PlayerIndex].Info.Position.y));
+ If commapartx <> 0.5 Then Begin
+ Players[PlayerIndex].Info.Position.x := Players[PlayerIndex].Info.Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End;
+ // Schauen ob die kachel auf die wir Laufen wollen überhaupt "begehbar" ist
+ If commaparty > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(Players[PlayerIndex].Info.Position.x);
+ y := trunc(Players[PlayerIndex].info.Position.y) + 1;
+ If commapartx > 0.5 + Epsilon Then Begin
+ x := x + 1;
+ End;
+ If Not FielWalkable(x, y, false) Then Begin
+ index := GetBombIndex(x, y);
+ // Kann der Spieler Bomben Kicken ? und liegt da ne Bombe
+ If (Players[PlayerIndex].Powers.CanKickBombs) And (index <> -1) Then Begin
+ If FielWalkable(x, y + 1, true) Then Begin // Kann die Bombe sich bewegen ?
+ If fBombs[index].MoveDir <> bmDown Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombKick);
+ Players[PlayerIndex].Info.Animation := raKick;
+ Players[PlayerIndex].Info.Counter := 0;
+ fBombs[index].MoveDir := bmDown;
+ fBombs[index].Jelly := Players[PlayerIndex].Powers.JellyBombs;
+ fBombs[index].Speed := Players[PlayerIndex].Powers.Speed + cSpeed;
+ End;
+ End
+ Else Begin
+ If fBombs[index].MoveDir <> bmNone Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
+ End;
+ End
+ Else Begin
+ If (index <> -1) And (fBombs[index].MoveDir <> bmNone) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombStop);
+ fBombs[index].MoveDir := bmNone;
+ fBombs[index].Position.x := trunc(fBombs[index].Position.x) + 0.5;
+ fBombs[index].Position.y := trunc(fBombs[index].Position.y) + 0.5;
+ End;
+ Players[PlayerIndex].Info.Position.y := trunc(Players[PlayerIndex].Info.Position.y) + 0.5;
+ End;
+ End;
+ End;
+ End;
+ End;
+ // evtl. ist der Spieler ja "eingesperrt"
+ x := trunc(Players[PlayerIndex].Info.Position.x);
+ y := trunc(Players[PlayerIndex].info.Position.y);
+ If (Not FielWalkable(x - 1, y, false)) And
+ (Not FielWalkable(x + 1, y, false)) And
+ (Not FielWalkable(x, y - 1, false)) And
+ (Not FielWalkable(x, y + 1, false)) And
+ (Players[PlayerIndex].info.Animation <> raLockedIn) Then Begin
+ Players[PlayerIndex].info.Animation := raLockedIn;
+ // Determine corner animation based on blocked diagonal directions
+ // Check diagonal directions: top-left, top-right, bottom-left, bottom-right
+ // corner0-corner7 correspond to different corner configurations
+ // Map diagonal block pattern to corner index (0-7)
+ // Pattern: TL, TR, BL, BR as bits
+ Players[PlayerIndex].info.Value := 0;
+ If Not FielWalkable(x - 1, y - 1, false) Then Players[PlayerIndex].info.Value := Players[PlayerIndex].info.Value Or 1; // bit 0: top-left
+ If Not FielWalkable(x + 1, y - 1, false) Then Players[PlayerIndex].info.Value := Players[PlayerIndex].info.Value Or 2; // bit 1: top-right
+ If Not FielWalkable(x - 1, y + 1, false) Then Players[PlayerIndex].info.Value := Players[PlayerIndex].info.Value Or 4; // bit 2: bottom-left
+ If Not FielWalkable(x + 1, y + 1, false) Then Players[PlayerIndex].info.Value := Players[PlayerIndex].info.Value Or 8; // bit 3: bottom-right
+ // Map 16 possible combinations to 8 corner animations (0-7)
+ Players[PlayerIndex].info.Value := Players[PlayerIndex].info.Value Mod 8;
+ Players[PlayerIndex].info.Counter := 0;
+ End;
+ result := fField[x, y].BrickData = bdSolid;
+End;
+
+Procedure TAtomicField.HandleActionPlayer(Var Player: TPlayer;
+ PlayerIndex: integer);
+
+ Function PlaceBombOn(aX, aY: Single): Boolean;
+ Var
+ i: Integer;
+ Begin
+ result := false;
+ // Darf der Spieler überhaupt noch Bomben legen =
+ If player.Powers.AvailableBombs <= 0 Then exit;
+ // Liegt auf dem Feld schon eine Bombe ?
+ For i := 0 To fBombCount - 1 Do Begin
+ If (trunc(fBombs[i].Position.x) = trunc(ax)) And
+ (trunc(fBombs[i].Position.y) = trunc(ay)) Then exit;
+ End;
+ // Es darf keine Bombe auf ein Loch gelegt werden !
+ If fHasHoles And fHoles[trunc(ax), trunc(ay)] Then exit;
+ fBombs[fBombCount].ColorIndex := player.info.ColorIndex;
+ fBombs[fBombCount].Position.x := trunc(ax) + 0.5;
+ fBombs[fBombCount].Position.y := trunc(ay) + 0.5;
+ If player.Powers.TriggerBomb > 0 Then Begin
+ fBombs[fBombCount].Animation := baTimeTriggered;
+ player.Powers.TriggerBomb := player.Powers.TriggerBomb - 1;
+ End
+ Else Begin
+ If dDudBombs In player.Disease Then Begin
+ fBombs[fBombCount].Animation := baDud;
+ fBombs[fBombCount].DudTime := AtomicBombDudTimeMin + random(AtomicBombDudTimeMax - AtomicBombDudTimeMin);
+ End
+ Else Begin
+ fBombs[fBombCount].Animation := baNormal;
+ End;
+ End;
+ fBombs[fBombCount].AnimationOffset := random(65536);
+ fBombs[fBombCount].PlayerIndex := PlayerIndex;
+ fBombs[fBombCount].TriggerPlayerindex := -1; // Force a exception, should be set during triggering !
+ fBombs[fBombCount].Lifetime := 0;
+ fBombs[fBombCount].FireLen := player.Powers.FlameLen;
+ fBombs[fBombCount].Jelly := false; // Das wird vom "Kickenden" Spieler übernommen
+ fBombs[fBombCount].MoveDir := bmNone;
+ fBombs[fBombCount].Speed := player.Powers.Speed;
+ inc(fBombCount);
+ player.Powers.AvailableBombs := player.Powers.AvailableBombs - 1;
+ result := true;
+ If fBombCount > high(fBombs) Then Begin
+ log('TAtomicField.HandleActionPlayer: bomb overflow', llfatal);
+ exit;
+ End;
+ End;
+
+Var
+ bx, by, x, y, dx, dy, i: Integer;
+ handled: Boolean;
+Begin
+ If Player.Flying Then exit; // Im Flug darf der Spieler natürlich nichts machen ;)
+ Case player.Action Of
+ aaFirstDouble: Begin
+ (* Jeder Doppelt action geht eine Einfach Aktion vorraus ! *)
+ player.Action := aaFirst;
+ HandleActionPlayer(Player, PlayerIndex);
+ // Ab jetzt können die Doppelt Aktionen richtig ausgewertet werden
+ If player.Powers.CanSpooger Then Begin // Die Fähigkeit Viele auf einen Schlag zu legen
+ dx := 0;
+ dy := 0;
+ Case (trunc(player.info.Direction) Div 90) Of
+ 0: dx := 1;
+ 1: dy := -1;
+ 2: dx := -1;
+ 3: dy := 1;
+ End;
+ x := trunc(player.Info.Position.x);
+ y := trunc(player.Info.Position.y);
+ For i := 1 To player.Powers.AvailableBombs Do Begin
+ If Not FielWalkable(x + i * dx, y + i * dy, true) {And (i <> 1)} Then exit;
+ If fHasHoles Then Begin // An Löchern ist auch schluss mit dem "Spoogen"
+ If fHoles[x + i * dx, y + i * dy] Then exit;
+ End;
+ If fHastrampolins Then Begin // Auf Trampoline kann ebenfalls keine Bombe gelegt werden
+ If fField[x + i * dx, y + i * dy].Tramp Then exit;
+ End;
+ If PlaceBombOn(x + i * dx + 0.5, y + i * dy + 0.5) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombDrop);
+ StatisticCallback(sBombsDropped);
+ End;
+ End;
+ End;
+ If Player.Powers.CanGrabBombs Then Begin
+ // Gibt es eine Bombe zum Graben ?
+ x := trunc(player.Info.Position.x);
+ y := trunc(player.Info.Position.y);
+ For i := 0 To high(fBombs) Do Begin
+ If fBombs[i].MoveDir = bmFly Then Continue; // Fliegende Bomben dürfen nicht gegriffen werden.
+ bx := trunc(fBombs[i].Position.x);
+ by := trunc(fBombs[i].Position.y);
+ If (x = bx) And (y = by) Then Begin
+ dx := 0;
+ dy := 0;
+ Case (trunc(player.info.Direction) Div 90) Of
+ 0: dx := 1;
+ 1: dy := -1;
+ 2: dx := -1;
+ 3: dy := 1;
+ End;
+ fBombs[i].FlyStart := v2(bx + 0.5, by + 0.5);
+ fBombs[i].FlyTarget := v2(bx + 0.5 + 3 * dx, by + 0.5 + 3 * dy);
+ fBombs[i].MoveDir := bmFly;
+ fBombs[i].FlyTime := 0;
+ fBombs[i].FlyFinTime := AtomicBombBigFlyTime;
+ fPlaySoundEffect(PlayerIndex, seBombGrab);
+ Player.Info.Animation := raPup;
+ Player.Info.Counter := 0;
+ break;
+ End;
+ End;
+ End;
+ End;
+ aaFirst: Begin
+ If PlaceBombOn(trunc(player.Info.Position.x) + 0.5, trunc(player.Info.Position.y) + 0.5) Then Begin
+ fPlaySoundEffect(PlayerIndex, seBombDrop);
+ StatisticCallback(sBombsDropped);
+ End;
+ End;
+ aaSecond: Begin
+ handled := false; // This flag allows to trigger bombs while walking = more responsive ;)
+ // Punch = Laufen gegen eine Bombe und dann Second Key ;)
+ If Player.Powers.CanPunchBombs And (Player.MoveState <> msStill) Then Begin
+ x := trunc(player.Info.Position.x);
+ y := trunc(player.Info.Position.y);
+ dx := 0;
+ dy := 0;
+ Case (trunc(player.info.Direction) Div 90) Of
+ 0: dx := 1;
+ 1: dy := -1;
+ 2: dx := -1;
+ 3: dy := 1;
+ End;
+ For i := 0 To high(fBombs) Do Begin
+ If fBombs[i].MoveDir = bmFly Then Continue; // Fliegende Bomben dürfen nicht gepuncht werden.
+ bx := trunc(fBombs[i].Position.x);
+ by := trunc(fBombs[i].Position.y);
+ If (x + dx = bx) And (y + dy = by) Then Begin
+ fBombs[i].FlyStart := v2(bx + 0.5, by + 0.5);
+ fBombs[i].FlyTarget := v2(bx + 0.5 + 3 * dx, by + 0.5 + 3 * dy);
+ fBombs[i].MoveDir := bmFly;
+ fBombs[i].FlyTime := 0;
+ fBombs[i].FlyFinTime := AtomicBombBigFlyTime;
+ fBombs[i].Lifetime := 0; // Reset Bomb timer when punch
+ fPlaySoundEffect(PlayerIndex, seBombPunch);
+ Player.Info.Animation := raPunch;
+ Player.Info.Counter := 0;
+ handled := true;
+ break;
+ End;
+ End;
+ End;
+ If Not handled Then Begin
+ (*
+ * Zünden der eigenen Time Triggered Bomben, das geht irgendwie immer ...
+ *)
+ For i := 0 To fBombCount - 1 Do Begin
+ If (fBombs[i].PlayerIndex = PlayerIndex) And (fBombs[i].Animation = baTimeTriggered) And (fBombs[i].MoveDir <> bmFly) Then Begin
+ fBombs[i].Animation := baNormal;
+ fBombs[i].Lifetime := AtomicBombDetonateTime;
+ End;
+ End;
+ End;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.HandleBombs(Var Players: TPlayers; PreHurry: Boolean; ConveyorSpeed: TConveyorSpeed);
+Type
+ TDir = (DirUp, DirDown, DirLeft, DirRight);
+
+ Function BlockedByHole(x, y: integer): Boolean; // Gillt nur für Bomben, wenn diese sich bewegen, deswegen extra
+ Begin
+ If fHasHoles Then Begin
+ result := fHoles[x, y];
+ End
+ Else Begin
+ result := false;
+ End;
+ End;
+
+ Function BlockedByTramp(x, y: integer): Boolean; // Gillt nur für Bomben, wenn diese sich bewegen, deswegen extra
+ Begin
+ If fHastrampolins Then Begin
+ result := fField[x, y].Tramp;
+ End
+ Else Begin
+ result := false;
+ End;
+ End;
+
+ Function BlockedByPlayer(x, y: integer): Boolean;
+ Var
+ i: Integer;
+ Begin
+ result := false;
+ For i := 0 To high(Players) Do Begin
+ If (Players[i].Info.Alive) And (Not Players[i].Info.Dying) Then Begin
+ If (trunc(Players[i].Info.Position.x) = x) And
+ (trunc(Players[i].Info.Position.y) = y) Then Begin
+ result := true;
+ break;
+ End;
+ End;
+ End;
+ End;
+
+ Function DirToMoveDir(aDir: integer): TBombMoveDir;
+ Begin
+ result := bmNone;
+ Case aDir Of
+ 0: result := bmRight;
+ 90: result := bmUp;
+ 180: result := bmLeft;
+ 270: result := bmDown;
+ End;
+ End;
+
+ Procedure AddEndFlame(x, y, TriggerPlayerindex: integer; Direction: TFlame);
+ Begin
+ (*
+ * So überschreibt jeder Spieler ggf. einen Anderen, es sieht so aus als
+ * ob TAtomicField.Detonate das auch so macht, wenn nicht, muss das If mit rein !
+ *)
+ //If fField[x, y].Flame = [] Then Begin
+ fField[x, y].FlamePlayer := TriggerPlayerindex;
+ //End;
+ // Add both fend flag and direction so Render can determine the correct angle
+ fField[x, y].Flame := fField[x, y].Flame + [fend, Direction];
+ End;
+
+Var
+ dxi, dyi, nx, ny, x, y, i: Integer;
+ index, j, dir: Integer;
+ dirs: Set Of TDir;
+ p: TPoint;
+ cSpeed, rSpeed, commapartx, commaparty: Single;
+ BombExplodeSound: Array[0..Length(PlayerColors) - 1] Of Boolean;
+ dx, dy, s: Single;
+ mdir: TBombMoveDir;
+Begin
+ If Not fBombsEnabled Then exit; // Bomben dürfen nicht mehr gezündet werden !
+ fBombDetonateFifo.Clear;
+ fPowerUpClearFifo.Clear;
+ For i := 0 To fBombCount - 1 Do Begin
+ rSpeed := fBombs[i].Speed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ fBombs[i].Lifetime := fBombs[i].Lifetime + FrameRate; // Countdown bis zur Detonation
+ fBombs[i].detonated := false;
+ // Die Bombe bewegt
+ If fHasArrows And (fBombs[i].MoveDir In [bmDown, bmLeft, bmUp, bmRight]) Then Begin
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y);
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ // Die Bombe befindet sich "ungefähr" in der Mitte
+ If (abs(commapartx - 0.5) <= rSpeed) And (abs(commaparty - 0.5) <= rSpeed) Then Begin
+ dir := fArrowDirs[x, y];
+ mdir := DirToMoveDir(dir);
+ If (dir <> -1) And (mdir <> fBombs[i].MoveDir) Then Begin
+ fBombs[i].MoveDir := mdir;
+ fBombs[i].Position.x := x + 0.5;
+ fBombs[i].Position.y := y + 0.5;
+ // TODO: hier prüfen ob die Bombe weiter in dir gewünschte Richtung kann, wenn nicht Stop
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombBounce);
+ End;
+ End;
+ End;
+ If fHasConveyors And (fBombs[i].MoveDir In [bmNone, bmDown, bmLeft, bmUp, bmRight]) Then Begin
+ cSpeed := 0; // -- Fehler
+ Case ConveyorSpeed Of
+ csSlow: cSpeed := ConveyorSlowSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ csMiddle: cSpeed := ConveyorMiddleSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ csFast: cSpeed := ConveyorFastSpeed / FrameRate; // So Umrechnen dass Speed = Kachel Pro Sekunde ist.
+ End;
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y);
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ // Die Bombe befindet sich "ungefähr" in der Mitte
+ dxi := 0;
+ dyi := 0;
+ Case fConveyorDirs[x, y] Of
+ 0: dxi := 1;
+ 90: dyi := -1;
+ 180: dxi := -1;
+ 270: dyi := 1;
+ End;
+ nx := x + dxi;
+ ny := y + dyi;
+ If Not FielWalkable(nx, ny, true) Then Begin
+ dxi := 0;
+ dyi := 0;
+ End;
+ fBombs[i].Position.x := fBombs[i].Position.x + dxi * cSpeed;
+ fBombs[i].Position.y := fBombs[i].Position.y + dyi * cSpeed;
+ // Reinziehen der Bomben auf Ordentliche Koordinaten !
+ If (commaparty <> 0.5) Then Begin
+ If (dxi <> 0) Then Begin
+ fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End
+ Else Begin
+ fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * cSpeed;
+ End;
+ End;
+ If (commapartx <> 0.5) Then Begin
+ If (dyi <> 0) Then Begin
+ fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End
+ Else Begin
+ fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * cSpeed;
+ End;
+ End;
+ End;
+ Case fBombs[i].MoveDir Of
+ bmFly: Begin
+ fBombs[i].Lifetime := fBombs[i].Lifetime - FrameRate; // Countdown bis zur Detonation wieder Rückgängig machen
+ fBombs[i].FlyTime := fBombs[i].FlyTime + FrameRate;
+ s := fBombs[i].FlyTime / fBombs[i].FlyFinTime;
+ dx := fBombs[i].FlyTarget.x - fBombs[i].FlyStart.x;
+ dy := fBombs[i].FlyTarget.y - fBombs[i].FlyStart.y;
+ If dy = 0 Then Begin
+ // Die Bombe "Fliegt" Waagrecht
+ fBombs[i].Position.x := fBombs[i].FlyStart.x + dx * s;
+ fBombs[i].Position.y := fBombs[i].FlyStart.y - 1.5 * sin(pi * s); // Die Bogenhöhe beim Werfen
+ End
+ Else Begin
+ // Die Bombe fliegt Senkrecht
+ fBombs[i].Position.y := fBombs[i].FlyStart.y + dy * s;
+ End;
+ // Hier muss ein Mod der Position rein !
+ If fBombs[i].Position.x < 0 Then fBombs[i].Position.x := fBombs[i].Position.x + FieldWidth - 1;
+ If fBombs[i].Position.x >= FieldWidth Then fBombs[i].Position.x := fBombs[i].Position.x - FieldWidth;
+ If dy <> 0 Then Begin
+ If fBombs[i].Position.y < 0 Then fBombs[i].Position.y := fBombs[i].Position.y + FieldHeight - 1;
+ If fBombs[i].Position.y >= FieldHeight Then fBombs[i].Position.y := fBombs[i].Position.y - FieldHeight;
+ End;
+ If fBombs[i].FlyTime >= fBombs[i].FlyFinTime Then Begin
+ fBombs[i].Position := fBombs[i].FlyTarget;
+ // Hier muss ein Mod der Position rein !
+ If fBombs[i].Position.x < 0 Then fBombs[i].Position.x := fBombs[i].Position.x + FieldWidth - 1;
+ If fBombs[i].Position.x >= FieldWidth Then fBombs[i].Position.x := fBombs[i].Position.x - FieldWidth;
+ If fBombs[i].Position.y < 0 Then fBombs[i].Position.y := fBombs[i].Position.y + FieldHeight - 1;
+ If fBombs[i].Position.y >= FieldHeight Then fBombs[i].Position.y := fBombs[i].Position.y - FieldHeight;
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y);
+ If FielWalkable(x, y, true) And (Not BlockedByHole(x, y)) And (Not BlockedBytramp(x, y)) Then Begin
+ // 1. Das Feld darf belegt werden -> Fertig
+ fBombs[i].MoveDir := bmNone;
+ End
+ Else Begin
+ // 2. Das Feld ist belegt, wir starten ein Bouncing
+ dx := 0;
+ dy := 0;
+ Case random(4) Of
+ 0: dx := 1;
+ 1: dy := -1;
+ 2: dx := -1;
+ 3: dy := 1;
+ End;
+ fBombs[i].FlyStart := v2(x + 0.5, y + 0.5);
+ fBombs[i].FlyTarget := v2(x + 0.5 + dx, y + 0.5 + dy);
+ fBombs[i].FlyTime := 0;
+ fBombs[i].FlyFinTime := AtomicBombSmallFlyTime;
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombBounce);
+ End;
+ End;
+ End;
+ bmNone: Begin // Nix zu tun
+ End;
+ bmRight: Begin
+ fBombs[i].Position.x := fBombs[i].Position.x + rSpeed;
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ If commaparty <> 0.5 Then Begin // Reinziehen der Bomben auf Ordentliche Koordinaten !
+ fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End;
+ If commapartx > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(fBombs[i].Position.x) + 1;
+ y := trunc(fBombs[i].Position.y);
+ If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
+ fBombs[i].Position.x := trunc(fBombs[i].Position.x) + 0.5;
+ If fBombs[i].Jelly Then Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
+ fBombs[i].MoveDir := bmLeft;
+ If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
+ End
+ Else Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
+ fBombs[i].MoveDir := bmNone;
+ If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
+ End;
+ End;
+ End;
+ End;
+ bmLeft: Begin
+ fBombs[i].Position.x := fBombs[i].Position.x - rSpeed;
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ If commaparty <> 0.5 Then Begin // Reinziehen der Bomben auf Ordentliche Koordinaten !
+ fBombs[i].Position.y := fBombs[i].Position.y + (0.5 - commaparty) * abs(commapartx - 0.5);
+ End;
+ If commapartx < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(fBombs[i].Position.x) - 1;
+ y := trunc(fBombs[i].Position.y);
+ If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
+ fBombs[i].Position.x := trunc(fBombs[i].Position.x) + 0.5;
+ If fBombs[i].Jelly Then Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
+ fBombs[i].MoveDir := bmRight;
+ If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
+ End
+ Else Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
+ fBombs[i].MoveDir := bmNone;
+ If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
+ End;
+ End;
+ End;
+ End;
+ bmUp: Begin
+ fBombs[i].Position.y := fBombs[i].Position.y - rSpeed;
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ If commapartx <> 0.5 Then Begin
+ fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End;
+ If commaparty < 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y) - 1;
+ If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
+ fBombs[i].Position.y := trunc(fBombs[i].Position.y) + 0.5;
+ If fBombs[i].Jelly Then Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
+ fBombs[i].MoveDir := bmDown;
+ If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
+ End
+ Else Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
+ fBombs[i].MoveDir := bmNone;
+ If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
+ End;
+ End;
+ End;
+ End;
+ bmDown: Begin
+ fBombs[i].Position.y := fBombs[i].Position.y + rSpeed;
+ commapartx := (fBombs[i].Position.x - trunc(fBombs[i].Position.x));
+ commaparty := (fBombs[i].Position.y - trunc(fBombs[i].Position.y));
+ If commapartx <> 0.5 Then Begin
+ fBombs[i].Position.x := fBombs[i].Position.x + (0.5 - commapartx) * abs(commaparty - 0.5);
+ End;
+ If commaparty > 0.5 Then Begin // Wir wollen Tatsächlich auf die Nächste Kachel Laufen
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y) + 1;
+ If (Not FielWalkable(x, y, true)) Or (BlockedByPlayer(x, y) Or BlockedByHole(x, y) Or BlockedBytramp(x, y)) Then Begin
+ fBombs[i].Position.y := trunc(fBombs[i].Position.y) + 0.5;
+ If fBombs[i].Jelly Then Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombJelly);
+ fBombs[i].MoveDir := bmUp;
+ If fBombs[i].Animation = baNormal Then fBombs[i].Animation := baWobble;
+ End
+ Else Begin
+ fPlaySoundEffect(fBombs[i].PlayerIndex, seBombStop);
+ fBombs[i].MoveDir := bmNone;
+ If fBombs[i].Animation = baWobble Then fBombs[i].Animation := baNormal;
+ End;
+ End;
+ End;
+ End;
+ End;
+ Case fBombs[i].Animation Of
+ baNormal, baWobble: Begin
+ If fBombs[i].Lifetime >= AtomicBombDetonateTime Then Begin
+ fBombs[i].TriggerPlayerindex := fBombs[i].PlayerIndex;
+ fBombDetonateFifo.Push(i);
+ End;
+ End;
+ baTimeTriggered: Begin
+ If fBombs[i].Lifetime >= AtomicTimeTriggeredBombTimeOut Then Begin
+ fBombs[i].Animation := baNormal;
+ fBombs[i].Lifetime := 0;
+ End;
+ End;
+ baDud: Begin
+ If fBombs[i].Lifetime >= fBombs[i].DudTime Then Begin
+ fBombs[i].Animation := baNormal;
+ fBombs[i].Lifetime := 0;
+ End;
+ End;
+ End;
+ // Trifft eine Bombe auf ein bereits Explodierendes Feld geht sie auf jeden Fall auch hoch
+ // (dass kann nur bei sich bewegenden Bomben passieren, da die Liegenden in Detonate schon berücksichtigt werden.)
+ x := trunc(fBombs[i].Position.x);
+ y := trunc(fBombs[i].Position.y);
+ If (y > 0) And (fBombs[i].MoveDir <> bmFly) Then Begin // Eine Fliegende Bombe kann Negative Koordinaten kriegen
+ If (fField[x, y].Flame <> []) Then Begin
+ fBombs[i].Position.x := x + 0.5;
+ fBombs[i].Position.y := y + 0.5;
+ fBombs[i].TriggerPlayerindex := fField[x, y].FlamePlayer;
+ fBombDetonateFifo.Push(i);
+ End;
+ End;
+ (*
+ * Die Bombe muss explodieren bevor sie unter dem Stein begraben wird !
+ *)
+ If PreHurry Then Begin
+ If (fHurryIndex + 1 >= 0) And (fHurryIndex + 1 <= high(HurryCoords)) Then Begin
+ p := HurryCoords[fHurryIndex + 1];
+ If (x = p.x) And (y = p.y) Then Begin
+ fBombs[i].Position.x := x + 0.5;
+ fBombs[i].Position.y := y + 0.5;
+ fBombs[i].TriggerPlayerindex := fBombs[i].PlayerIndex;
+ fBombDetonateFifo.Push(i);
+ End;
+ End;
+ End;
+ End;
+
+ // Alle Bombem die Hochgehen sollen ab arbeiten
+ While Not fBombDetonateFifo.isempty Do Begin
+ index := fBombDetonateFifo.Pop;
+ If fBombs[index].Detonated Then Continue;
+ fBombs[index].Detonated := true;
+ (*
+ * Die Bombe wurde gezündet, der Spieler darf wieder eine Neue Legen
+ *)
+ Players[fBombs[index].PlayerIndex].Powers.AvailableBombs := Players[fBombs[index].PlayerIndex].Powers.AvailableBombs + 1;
+ x := trunc(fBombs[index].Position.x);
+ y := trunc(fBombs[index].Position.y);
+ If fField[x, y].BrickData = bdSolid Then continue; // Die Bombe Explodiert auf einem Festen Brick -> dann richtet sie keinen Schaden an
+ If fField[x, y].BrickData = bdBrick Then Begin // Die Bombe explodiert auf einem Brick, den macht sie kaputt, aber nichts weiter ..
+ Detonate(x, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fCross);
+ Continue;
+ End
+ Else Begin
+ Detonate(x, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fCross);
+ End;
+ dirs := [DirUp, DirDown, DirLeft, DirRight];
+ For i := 1 To fBombs[index].FireLen Do Begin
+ If DirUp In dirs Then Begin
+ If (Not Detonate(x, y - i, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fup)) Then Begin
+ dirs := dirs - [DirUp];
+ AddEndFlame(x, y - i + 1, fBombs[index].TriggerPlayerindex, fup);
+ End;
+ If (i = fBombs[index].FireLen) And (y - i >= 0) Then Begin
+ AddEndFlame(x, y - i, fBombs[index].TriggerPlayerindex, fup);
+ End;
+ End;
+ If Dirdown In dirs Then Begin
+ If (Not Detonate(x, y + i, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fdown)) Then Begin
+ dirs := dirs - [Dirdown];
+ AddEndFlame(x, y + i - 1, fBombs[index].TriggerPlayerindex, fdown);
+ End;
+ If (i = fBombs[index].FireLen) And (y + i < FieldHeight) Then Begin
+ AddEndFlame(x, y + i, fBombs[index].TriggerPlayerindex, fdown);
+ End;
+ End;
+ If DirLeft In dirs Then Begin
+ If (Not Detonate(x - i, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fleft)) Then Begin
+ dirs := dirs - [DirLeft];
+ AddEndFlame(x - i + 1, y, fBombs[index].TriggerPlayerindex, fleft);
+ End;
+ If (i = fBombs[index].FireLen) And (x - i > 0) Then Begin
+ AddEndFlame(x - i, y, fBombs[index].TriggerPlayerindex, fleft);
+ End;
+ End;
+ If DirRight In dirs Then Begin
+ If (Not Detonate(x + i, y, fBombs[index].TriggerPlayerindex, fBombs[index].ColorIndex, fright)) Then Begin
+ dirs := dirs - [DirRight];
+ AddEndFlame(x + i - 1, y, fBombs[index].TriggerPlayerindex, fright);
+ End;
+ If (i = fBombs[index].FireLen) And (x + i < FieldWidth) Then Begin
+ AddEndFlame(x + i, y, fBombs[index].TriggerPlayerindex, fright);
+ End;
+ End;
+ End;
+ End;
+
+ (*
+ * Entfernen aller Gezündeter Bomben
+ *)
+ For i := 0 To high(BombExplodeSound) Do Begin // Merken welchen Spielern wir den Explode Sound senden sollen
+ BombExplodeSound[i] := false;
+ End;
+ For i := fBombCount - 1 Downto 0 Do Begin
+ If fBombs[i].Detonated Then Begin
+ BombExplodeSound[fBombs[i].PlayerIndex] := true;
+ For j := i To fBombCount - 2 Do Begin
+ fBombs[j] := fBombs[j + 1];
+ End;
+ Dec(fBombCount);
+ End;
+ End;
+ // So hört ein Spieler Pro Massen Explusion immer nur einen Sound !
+ For i := 0 To high(BombExplodeSound) Do Begin
+ If BombExplodeSound[i] Then Begin
+ fPlaySoundEffect(i, seBombExplode);
+ End;
+ End;
+
+ (*
+ * Entfernen aller explodierten Powerups
+ *)
+ While Not fPowerUpClearFifo.isempty Do Begin
+ p := fPowerUpClearFifo.Pop;
+ If fField[p.x, p.y].PowerUp <> puNone Then Begin
+ StatisticCallback(sPowerUpDestroyed);
+ End;
+ fField[p.x, p.y].PowerUp := puNone;
+ End;
+End;
+
+Procedure TAtomicField.HandlePlayerVsMap(Var Players: TPlayers;
+ PlayerGetsPowerUp: TPlayerGetsPowerUpEvent);
+
+// Gemäß: https://www.youtube.com/watch?v=fO9HhzhEloE (bei 6:00) sieht es aber so aus,
+// das die Atomics in einem "Range" von +-2 wieder Runter kommen
+Const
+ TrampRange = 2;
+Var
+ nx, ny, x, y, i: integer;
+Begin
+ For i := 0 To high(Players) Do Begin
+ If (Not Players[i].Info.Alive) Or (Players[i].Info.Dying) Or (Players[i].Flying) Then Continue;
+ x := trunc(Players[i].Info.Position.x);
+ y := trunc(Players[i].Info.Position.y);
+ // Die Kollision Spieler gegen PowerUp
+ If fField[x, y].PowerUp <> puNone Then Begin
+ PlayerGetsPowerUp(Players[i], i, fField[x, y].PowerUp);
+ fField[x, y].PowerUp := puNone;
+ End;
+ // Die Kollision gegen ein Loch
+ If fHasHoles And fHoles[x, y] Then Begin
+ If (Not Players[i].IsInHohle) Then Begin // Flanke generieren ;)
+ Players[i].IsInHohle := true;
+ Players[i].Info.Animation := raTeleport;
+ Players[i].Info.Counter := 0;
+ Players[i].Info.Position.x := x + 0.5;
+ Players[i].Info.Position.y := y + 0.5;
+ fPlaySoundEffect(i, seWrapHohle);
+ End;
+ End
+ Else Begin
+ Players[i].IsInHohle := false;
+ End;
+ If fHastrampolins And fField[x, y].Tramp Then Begin
+ fPlaySoundEffect(i, seTrampoline);
+ // Triggern der Animation der Karte
+ fField[x, y].TrampRunning := true;
+ fField[x, y].Counter := 0;
+ // Triggern des "Fliegens" des Spielers
+ // 1. Neue ZielKoordinate bestimmen
+ nx := -1;
+ While nx = -1 Do Begin
+ // So können die Atomics einfach "irgendwo" wieder landen
+ // nx := random(FieldWidth);
+ // ny := Random(FieldHeight);
+ nx := min(FieldWidth - 1, max(0, x + random(TrampRange * 2 + 1) - TrampRange));
+ ny := min(FieldHeight - 1, max(0, y + random(TrampRange * 2 + 1) - TrampRange));
+ // Das Ziel Feld muss Leer sein = Kein Stein oder Tramp
+ If (fField[nx, ny].BrickData <> bdBlank)
+ Or (fField[nx, ny].Tramp) Then Begin
+ nx := -1;
+ End;
+ // Das gibt es eigentlich nicht, aber auf Löchern landen ist auch verboten!
+ If fHasHoles Then Begin
+ If fHoles[nx, ny] Then
+ nx := -1;
+ End;
+ End;
+ Players[i].Flying := true;
+ Players[i].Info.Counter := 0;
+ Players[i].FlyStart := Players[i].Info.Position;
+ Players[i].FlyTarget := v2(nx + 0.5, ny + 0.5);
+ End;
+ // Die Kollision Spieler gegen eine Flamme
+ If fField[x, y].Flame <> [] Then Begin
+ // TODO: Während eines Teleport vorgangs ist der Spieler unsterblich -> Klären ob das wirklich gewollt ist..
+ If (Not Players[i].Info.Dying) And (Players[i].Info.Animation <> raTeleport) Then Begin
+ If i = fField[x, y].FlamePlayer Then Begin
+ // Selfkill
+ Players[fField[x, y].FlamePlayer].Kills := Players[fField[x, y].FlamePlayer].Kills - 1;
+ End
+ Else Begin
+ // Echter Kill ;)
+ Players[fField[x, y].FlamePlayer].Kills := Players[fField[x, y].FlamePlayer].Kills + 1;
+ End;
+ fPlaySoundEffect(i, seAtomicDie);
+ fPlaySoundEffect(i, seOtherPlayerDied);
+ StatisticCallback(sPlayerDeaths);
+ KillPlayer(Players, i);
+ End;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.HandleFieldAnims;
+Var
+ i, j: Integer;
+Begin
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ (*
+ * Der Counter läuft pauschal immer mit, und läuft alle 60s über, alles was den Counter braucht setzt ihn auf 0 zurück
+ *)
+ fField[i, j].Counter := (fField[i, j].Counter + FrameRate) Mod 60000;
+ If fField[i, j].Exploding Then Begin
+ (*
+ * Dauert es zu lange, bis Brickdate auf bdBlank gesetzt wird
+ * dann sieht das Optisch doof aus (nur bei Synchronisationsthemen
+ * Geht es zu schnell (oder eben so schnell wie jetzt, dann kann der Spieler)
+ * viel zu Früh auf die Felder laufen, das macht er aber auf eigenes Risiko, da
+ * hier natürlich ein PowerUp liegt, dass er noch nicht sieht ;)
+ *)
+ If fField[i, j].Counter >= 2 * UpdateRate Then Begin
+ fField[i, j].BrickData := bdBlank;
+ End;
+ If fField[i, j].Counter >= BrickExplodeTime Then Begin
+ // Die Explosionsanimation gibt es in nur 2 Fällen
+ fField[i, j].Exploding := false;
+ End;
+ End;
+ If fField[i, j].Flame <> [] Then Begin
+ If fField[i, j].Counter >= FlameTime Then Begin
+ // Die Explusionsanimation gibt es in nur 2 Fällen
+ fField[i, j].Flame := [];
+ End;
+ End;
+ If fField[i, j].TrampRunning Then Begin
+ If fField[i, j].Counter >= AtomicTrampFlyTime Then Begin
+ fField[i, j].TrampRunning := false;
+ End;
+ End;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.DisableAllBombs;
+Begin
+ fBombsEnabled := false;
+End;
+
+Function TAtomicField.GetAiInfo(Const Players: TPlayers; TeamPlay: Boolean): TaiInfo;
+Var
+ i, j: Integer;
+Begin
+ result.Teamplay := TeamPlay;
+ For i := 0 To high(Players) Do Begin
+ result.PlayerInfos[i].Team := Players[i].Team;
+ result.PlayerInfos[i].Position.x := Players[i].Info.Position.x;
+ result.PlayerInfos[i].Position.y := Players[i].Info.Position.y;
+ result.PlayerInfos[i].Alive := Players[i].Info.Alive And (Not Players[i].Info.Dying);
+ result.PlayerInfos[i].Flying := Players[i].Flying;
+ result.PlayerInfos[i].FlameLength := Players[i].Powers.FlameLen;
+ result.PlayerInfos[i].Speed := Players[i].Powers.Speed;
+ result.PlayerInfos[i].IsIll := Players[i].Disease <> [];
+ result.PlayerInfos[i].Abilities := 0;
+ If Players[i].Powers.CanKickBombs Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanKick;
+ End;
+ If Players[i].Powers.CanSpooger Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanSpoog;
+ End;
+ If Players[i].Powers.CanPunchBombs Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanPunch;
+ End;
+ If Players[i].Powers.CanGrabBombs Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanGrab;
+ End;
+ If Players[i].Powers.TriggerBomb > 0 Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanTrigger;
+ End;
+ If Players[i].Powers.JellyBombs Then Begin
+ result.PlayerInfos[i].Abilities := result.PlayerInfos[i].Abilities Or Ability_CanJelly;
+ End;
+ If dNoBombs In Players[i].Disease Then Begin
+ result.PlayerInfos[i].AvailableBombs := 0;
+ End
+ Else Begin
+ result.PlayerInfos[i].AvailableBombs := Players[i].Powers.AvailableBombs;
+ End;
+ End;
+ // Im Debug Modus die Oberen "Tot" schalten
+ For i := high(Players) + 1 To 9 Do Begin
+ result.PlayerInfos[i].Alive := false;
+ End;
+ // Field
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ Case fField[i, j].BrickData Of
+ bdSolid: result.Field[i, j] := fSolid;
+ bdBrick: result.Field[i, j] := fBrick;
+ bdBlank: Begin
+ If fField[i, j].Flame <> [] Then Begin
+ result.Field[i, j] := fFlame;
+ End
+ Else Begin
+ Case fField[i, j].PowerUp Of
+ puNone: Begin
+ result.Field[i, j] := fBlank;
+ If fHasHoles Then Begin
+ If fHoles[i, j] Then Begin
+ result.Field[i, j] := fHole;
+ End;
+ End;
+ If fHastrampolins Then Begin
+ If fField[i, j].Tramp Then Begin
+ result.Field[i, j] := fTramp;
+ End;
+ End;
+ If fHasConveyors Then Begin
+ Case fConveyorDirs[i, j] Of
+ 0: result.Field[i, j] := fConveyorRight;
+ 90: result.Field[i, j] := fConveyorUp;
+ 180: result.Field[i, j] := fConveyorLeft;
+ 270: result.Field[i, j] := fConveyorDown;
+ End;
+ End;
+ If fHasArrows Then Begin
+ Case fArrowDirs[i, j] Of
+ 0: result.Field[i, j] := fArrowRight;
+ 90: result.Field[i, j] := fArrowUp;
+ 180: result.Field[i, j] := fArrowLeft;
+ 270: result.Field[i, j] := fArrowDown;
+ End;
+ End;
+ End;
+ puExtraBomb: result.Field[i, j] := fExtraBomb;
+ puLongerFlameLength: result.Field[i, j] := fLongerFlame;
+ puCanCick: result.Field[i, j] := fKick;
+ puExtraSpeed: result.Field[i, j] := fExtraSpeed;
+ puCanSpooger: result.Field[i, j] := fSpooger;
+ puCanPunch: result.Field[i, j] := fPunch;
+ puCanGrab: result.Field[i, j] := fGrab;
+ puGoldFlame: result.Field[i, j] := fGoldflame;
+ puTrigger: result.Field[i, j] := fTrigger;
+ puCanJelly: result.Field[i, j] := fJelly;
+ // Ab hier Krankheiten oder "schlechtes"
+ puDisease: result.Field[i, j] := fBadDisease;
+ puSuperBadDisease: result.Field[i, j] := fBadDisease;
+ puSlow: result.Field[i, j] := fSlow;
+ // Zufall, ...
+ purandom: result.Field[i, j] := fRandom;
+ End;
+ End;
+ End;
+ End;
+ End;
+ End;
+ // Bombs
+ result.BombsCount := fBombCount;
+ setlength(result.Bombs, fBombCount);
+ For i := 0 To result.BombsCount - 1 Do Begin
+ result.Bombs[i].Position.x := fBombs[i].Position.x;
+ result.Bombs[i].Position.y := fBombs[i].Position.y;
+ // Das kann nur bei "Fliegenden" Bombem vor kommen, fangen wir aber dennoch mal ab ;)
+ If result.Bombs[i].Position.x < 0 Then result.Bombs[i].Position.x := result.Bombs[i].Position.x + FieldWidth - 1;
+ If result.Bombs[i].Position.x >= FieldWidth Then result.Bombs[i].Position.x := result.Bombs[i].Position.x - FieldWidth;
+ If result.Bombs[i].Position.y < 0 Then result.Bombs[i].Position.y := result.Bombs[i].Position.y + FieldHeight - 1;
+ If result.Bombs[i].Position.y >= FieldWidth Then result.Bombs[i].Position.y := result.Bombs[i].Position.y - FieldHeight;
+ result.Bombs[i].FlameLength := fBombs[i].FireLen;
+ result.Bombs[i].Flying := fBombs[i].MoveDir = bmFly;
+ result.Bombs[i].Owner := fBombs[i].PlayerIndex;
+ result.Bombs[i].ManualTrigger := fBombs[i].Animation = baTimeTriggered;
+ result.Bombs[i].Jelly := fBombs[i].Jelly;
+ result.Bombs[i].DudBomb := fBombs[i].Animation = baDud;
+ result.Bombs[i].Lifetime := fBombs[i].Lifetime;
+ End;
+End;
+
+Procedure TAtomicField.IncHurry;
+Var
+ p: TPoint;
+Begin
+ inc(fHurryIndex);
+ If (fHurryIndex < 0) Or (fHurryIndex > high(HurryCoords)) Then exit; // Komisch ..
+ p := HurryCoords[fHurryIndex];
+ // Set the Solid Brick
+ fField[p.x, p.y].BrickData := bdSolid;
+ // Reset everything else
+ fField[p.x, p.y].Exploding := false;
+ fField[p.x, p.y].ExplodingRenderFlag := false;
+ fField[p.x, p.y].PowerUp := puNone;
+ fField[p.x, p.y].Flame := [];
+ fField[p.x, p.y].Tramp := false;
+ fField[p.x, p.y].TrampRunning := false;
+ fField[p.x, p.y].Counter := 0;
+End;
+
+Procedure TAtomicField.KillPlayer(Var Players: TPlayers; Index: integer);
+Begin
+ Players[Index].MoveState := msStill; // Zum Sterben halten wir an ;)
+ Players[Index].Info.Animation := raDie;
+ Players[Index].Info.Value := Random(65536); // Eine Zufällige Todesanimation wählen
+ Players[Index].Info.Dying := true;
+ Players[Index].Info.Direction := 0;
+ Players[Index].Info.Counter := 0;
+End;
+
+Procedure TAtomicField.RepopulatePlayersCollectedPowerUps(
+ Const Players: TPlayers; PlayerIndex: Integer);
+Var
+ pu: TPowerUps;
+ cnt, i, OverflowProtect, j: Integer;
+ x, y: Int64;
+ b, noHole: Boolean;
+Begin
+ log('TServer.RepopulatePlayersCollectedPowerUps', lltrace);
+ For pu In TPowerUps Do Begin
+ If pu = puNone Then Continue;
+ (*
+ * Bei "Fähigkeiten" begrenzen wir das ganze auf maximal 1
+ *)
+ cnt := Players[PlayerIndex].PowerUpCounter[pu];
+ If pu In [puCanCick, puCanSpooger, puCanPunch, puCanGrab, puGoldFlame, puCanJelly] Then Begin
+ cnt := min(cnt, 1);
+ End;
+ For i := 0 To cnt - 1 Do Begin
+ OverflowProtect := 0;
+ While (OverflowProtect < FieldWidth * FieldHeight) Do Begin
+ x := Random(FieldWidth);
+ y := Random(FieldHeight);
+ // Das Feld ist Prinzipiel mal "Frei"
+ noHole := true;
+ If fHasHoles Then Begin // Auf Löchern dürfen keine PowerUps erzeugt werden
+ If fHoles[x, y] Then noHole := false;
+ End;
+ If (fField[x, y].BrickData = bdBlank) And (fField[x, y].Flame = []) And (fField[x, y].PowerUp = puNone) And noHole Then Begin
+ b := true;
+ // Verhindern dass ein Powerup da generiert wird wo ein Spieler Steht.
+ For j := 0 To high(Players) Do Begin
+ If Not Players[j].Info.Alive Then Continue;
+ If Players[j].Flying Then Continue;
+ If (x = trunc(Players[j].Info.Position.x)) And
+ (y = trunc(Players[j].Info.Position.y)) Then Begin
+ b := false;
+ break;
+ End;
+ End;
+ // Verhindern, das ein Powerup da generiert wird wo eine Bombe liegt
+ If b Then Begin
+ For j := 0 To fBombCount - 1 Do Begin
+ If fBombs[j].MoveDir = bmFly Then Continue;
+ If (x = trunc(fBombs[j].Position.x)) And
+ (x = trunc(fBombs[j].Position.x)) Then Begin
+ b := false;
+ break;
+ End;
+ End;
+ End;
+ // Wie haben eine Feld gefunden, das belegt werden kann ;)
+ If b Then Begin
+ fField[x, y].PowerUp := pu;
+ OverflowProtect := FieldWidth * FieldHeight; // Aus der While Sauber Raus gehen..
+ End;
+ End;
+ inc(OverflowProtect);
+ End;
+ End;
+ End;
+ LogLeave;
+End;
+
+Procedure TAtomicField.TelePortPlayer(Var Player: TPlayer);
+Var
+ x, y: Integer;
+Begin
+ (*
+ * Den Spieler im Gegenuhrzegeigersinn auf der Karte drehen
+ *)
+ x := trunc(Player.Info.Position.x);
+ y := trunc(Player.Info.Position.y);
+ If x = 2 Then Begin
+ If y = 2 Then Begin
+ Player.Info.Position.y := 8.5;
+ End
+ Else Begin
+ Player.Info.Position.x := 12.5;
+ End;
+ End
+ Else Begin
+ If y = 2 Then Begin
+ Player.Info.Position.x := 2.5;
+ End
+ Else Begin
+ Player.Info.Position.y := 2.5;
+ End;
+ End;
+End;
+
+{$ENDIF}
+
+{$IFDEF Client}
+
+Procedure TAtomicField.RenderBlock(x, y: integer; Brick: TBrickData);
+Begin
+ If Brick = bdBlank Then exit;
+ glPushMatrix;
+ glTranslatef(Fieldxoff + x * FieldBlockWidth, FieldyOff + y * FieldBlockHeight, 0);
+ If Brick = bdSolid Then Begin
+ RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fSolidTex);
+ End
+ Else Begin
+ RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fBrickTex);
+ End;
+ glPopMatrix;
+End;
+
+Function TAtomicField.OnxBrickOverflow(Sender: TObject): Boolean;
+Var
+ index, x, y: integer;
+Begin
+ index := TOpenGL_Animation(sender).Tag;
+ x := index Mod FieldWidth;
+ y := index Div FieldWidth;
+ fxBricks[x, y].Active := false;
+ result := false; // Do not loop the animation !
+End;
+
+Procedure TAtomicField.RenderPreview;
+Var
+ j, i: Integer;
+Begin
+ (*
+ * Die Hintergrund Graphik kann auf jeden Fall gerendert werden..
+ *)
+ glColor3f(1, 1, 1);
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_Map_Layer);
+ RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
+ glTranslatef(0, 0, atomic_EPSILON);
+ For j := 0 To 4 Do Begin
+ For i := 0 To 4 Do Begin
+ Case fPreviewLines[j][i + 1] Of
+ '.': RenderBlock(i, j, bdBlank);
+ ':': RenderBlock(i, j, bdBrick);
+ '#': RenderBlock(i, j, bdSolid);
+ End;
+ End;
+ End;
+ glpopmatrix();
+End;
+
+Procedure TAtomicField.Render(Const Atomics: TAtomics; PowerTexs: TPowerTexArray
+ );
+
+ Procedure RenderArrow(x, y: integer);
+ Begin
+ If fArrowDirs[x, y] <> -1 Then Begin
+ glPushMatrix;
+ glTranslatef(Fieldxoff + x * FieldBlockWidth + 10, FieldyOff + y * FieldBlockHeight + 15, atomic_EPSILON);
+ fArrows.Render(fArrowDirs[x, y]);
+ glPopMatrix;
+ End;
+ End;
+
+ Procedure RenderConveyor(x, y: integer);
+ Begin
+ If fConveyorDirs[x, y] <> -1 Then Begin
+ glPushMatrix;
+ glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
+ fConveyors.Render(fConveyorDirs[x, y]);
+ glPopMatrix;
+ End;
+ End;
+
+ Procedure RenderHohle(x, y: integer);
+ Begin
+ If fholes[x, y] Then Begin
+ glPushMatrix;
+ glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
+ RenderAlphaQuad(v2(FieldBlockWidth / 2, FieldBlockHeight / 2), FieldBlockWidth, -FieldBlockHeight, 0, fHoleTex);
+ glPopMatrix;
+ End;
+ End;
+
+ Procedure RenderTramp(x, y: integer);
+ Begin
+ If fField[x, y].Tramp Then Begin
+ glPushMatrix;
+ glTranslatef(Fieldxoff + x * FieldBlockWidth + 00, FieldyOff + y * FieldBlockHeight + 00, atomic_EPSILON);
+ If fField[x, y].TrampRunning Then Begin
+ fTramp.AnimationOffset := fField[x, y].TrampOffset;
+ fTramp.Render(fConveyorDirs[x, y]);
+ End
+ Else Begin
+ OpenGL_SpriteEngine.RenderSprite(fTrampStaticSprite);
+ End;
+ glPopMatrix;
+ End;
+ End;
+
+Var
+ i, j: Integer;
+ FlameAni: TOpenGL_Animation;
+ FlameAngle: integer;
+{$IFDEF Client}
+ f: TextFile;
+ flameStr: String;
+{$ENDIF}
+Begin
+ glColor3f(1, 1, 1);
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_Map_Layer);
+ RenderQuad(v2(0, 0), v2(GameWidth, GameHeight), 0, false, fFieldTex);
+ // Alle Blöcke, Flammen Powerups etc ...
+ glpushmatrix();
+ glTranslatef(0, 0, atomic_EPSILON);
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ // Rendern der Brickdaten
+ If fxBricks[i, j].Active Then Begin // Soll gerade die "Explode" Animation laufen ??
+ glPushMatrix;
+ glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
+ fxBricks[i, j].Ani.Render(0);
+ glPopMatrix;
+ End
+ Else Begin
+ If fField[i, j].BrickData <> bdBlank Then Begin
+ RenderBlock(i, j, fField[i, j].BrickData);
+ End;
+ End;
+ // Rendern der Flamen (render flames even if brick is exploding or still present)
+ // Flames should be rendered on top of exploding bricks to show the correct direction
+ If fField[i, j].Flame <> [] Then Begin
+ // Wählen der Richtigen Animation
+ If fCross In fField[i, j].Flame Then Begin
+ FlameAni := Atomics[fField[i, j].FlameColor].FlameCross;
+ End
+ Else Begin
+ If fend In fField[i, j].Flame Then Begin
+ FlameAni := Atomics[fField[i, j].FlameColor].FlameEnd;
+ End
+ Else Begin
+ FlameAni := Atomics[fField[i, j].FlameColor].FlameMiddle;
+ End;
+ End;
+ FlameAngle := 0;
+ // Check directions in order: up, left, down, right
+ // Note: right (0°) is default, so we check it last
+ // For FlameEnd: check direction AND fend flag
+ // For FlameMiddle: check direction WITHOUT fend flag (FlameMiddle doesn't have fend)
+ If fend In fField[i, j].Flame Then Begin
+ // FlameEnd: must have both direction and fend
+ If fup In fField[i, j].Flame Then FlameAngle := 90
+ Else If fleft In fField[i, j].Flame Then FlameAngle := 180
+ Else If fdown In fField[i, j].Flame Then FlameAngle := 270
+ Else If fright In fField[i, j].Flame Then FlameAngle := 0;
+ End
+ Else Begin
+ // FlameMiddle: check direction without fend
+ If fup In fField[i, j].Flame Then FlameAngle := 90
+ Else If fleft In fField[i, j].Flame Then FlameAngle := 180
+ Else If fdown In fField[i, j].Flame Then FlameAngle := 270
+ Else If fright In fField[i, j].Flame Then FlameAngle := 0;
+ End;
+ // If no direction found, FlameAngle remains 0 (right)
+ // Debug: log to file
+ {$IFDEF Client}
+ Try
+ flameStr := '';
+ If fup In fField[i, j].Flame Then flameStr := flameStr + 'fup ';
+ If fdown In fField[i, j].Flame Then flameStr := flameStr + 'fdown ';
+ If fleft In fField[i, j].Flame Then flameStr := flameStr + 'fleft ';
+ If fright In fField[i, j].Flame Then flameStr := flameStr + 'fright ';
+ If fend In fField[i, j].Flame Then flameStr := flameStr + 'fend ';
+ If fCross In fField[i, j].Flame Then flameStr := flameStr + 'fCross ';
+ AssignFile(f, 'debug.log');
+ If FileExists('debug.log') Then
+ Append(f)
+ Else
+ Rewrite(f);
+ WriteLn(f, Format('[CLIENT] Render FlameEnd: x=%d y=%d Flame=[%s] -> FlameAngle=%d',
+ [i, j, Trim(flameStr), FlameAngle]));
+ CloseFile(f);
+ Except
+ // Ignore file errors
+ End;
+ {$ENDIF}
+ glPushMatrix;
+ glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
+ FlameAni.Render(FlameAngle);
+ glPopMatrix;
+ End
+ Else Begin
+ // Render der Powerups (only if no flame and brick is blank)
+ If fField[i, j].BrickData = bdBlank Then Begin
+ // Render der Powerups
+ If fField[i, j].PowerUp <> puNone Then Begin
+ glPushMatrix;
+ glTranslatef(Fieldxoff + i * FieldBlockWidth, FieldyOff + j * FieldBlockHeight, 0);
+ RenderQuad(v2(20, 18), 40, 36, 0, PowerTexs[fField[i, j].PowerUp]);
+ glPopMatrix;
+ End
+ Else Begin
+ // Es ist einfach nichts auf der Kachel, ggf ist dann ja ein Pfeil oder ein Laufband zu sehen ..
+ If fHasArrows Then Begin
+ RenderArrow(i, j);
+ End;
+ If fHasConveyors Then Begin
+ RenderConveyor(i, j);
+ End;
+ If fHasHoles Then Begin
+ RenderHohle(i, j);
+ End;
+ If fHastrampolins Then Begin
+ RenderTramp(i, j);
+ End;
+ End;
+ End;
+ End;
+ End;
+ End;
+ glpopmatrix();
+ glpopmatrix();
+End;
+
+Procedure TAtomicField.ReadGameingData(Const Stream: TStream);
+
+Var
+ i, j: Integer;
+Begin
+ (*
+ * Da auf jedem Feld immer nur 1 Ding Gerendert werden kann ist das hier recht Easy ;)
+ *)
+ Stream.Read(fField, sizeof(fField));
+ // GGF Starten einer Brick Explosion Animation
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ (*
+ * Das ist ein Bischen Tricky da wir keinen direkten Event bekommen
+ * nur die Information dass die Explosionsanimation laufen soll
+ * und einen Counter wie Lange sie schon läuft..
+ *)
+ If fField[i, j].ExplodingRenderFlag Then Begin
+ fxBricks[i, j].ani.ResetAnimation();
+ fxBricks[i, j].Active := true;
+ End;
+ End;
+ End;
+End;
+
+Procedure TAtomicField.Reset;
+Var
+ i, j: Integer;
+Begin
+ For i := 0 To FieldWidth - 1 Do Begin
+ For j := 0 To FieldHeight - 1 Do Begin
+ fxBricks[i, j].Active := false;
+ End;
+ End;
+End;
+
+{$ENDIF}
+
+End.
+
diff --git a/units/uchunkmanager.pas b/units/uchunkmanager.pas
index cb945b7..25cfb3b 100644
--- a/units/uchunkmanager.pas
+++ b/units/uchunkmanager.pas
@@ -44,6 +44,11 @@
(* 0.16 - Disconnect socket instead of raising AV on error *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit uChunkmanager;
{$MODE objfpc}{$H+}
@@ -62,7 +67,7 @@
Interface
Uses
- Classes, SysUtils, lnet, ufifo
+ Classes, SysUtils, lnet, ufifo, uthreadsafequeue
{$IFDEF UseLogger}
, ulogger
{$ENDIF}
@@ -90,6 +95,19 @@
*)
TOnReceivedChunk = Procedure(Sender: TObject; Const Chunk: TChunk) Of Object;
+ // Forward declaration
+ TChunkManager = Class;
+
+ { TNetworkThread - Dedicated thread for network processing }
+ TNetworkThread = Class(TThread)
+ private
+ fChunkManager: TChunkManager;
+ protected
+ Procedure Execute; override;
+ public
+ Constructor Create(AChunkManager: TChunkManager);
+ End;
+
{ TChunkManager
Typical usage :
@@ -120,6 +138,10 @@
FOnReceivedChunk: TOnReceivedChunk; // Eventhandler für received Chunks
fconnection: TLTcp; // the connection to which we were bind
+
+ // Network thread support
+ fIncomingQueue: specialize TThreadSafeQueue; // Queue for incoming chunks from network thread
+ fNetworkThread: TNetworkThread; // Dedicated thread for network processing
(*
* Captured Events
@@ -211,12 +233,45 @@
* der TLTCPComponent ist der Aufruf nicht notwendig, bzw füht ins Leere, da hier der LCLEventer das ganze abhandelt.
*)
Procedure CallAction();
+
+ (*
+ * Network thread management
+ * StartNetworkThread: Creates and starts a dedicated thread for network processing
+ * StopNetworkThread: Stops and frees the network thread
+ * ProcessIncomingChunks: Processes all pending chunks from the network thread (call from main thread!)
+ *)
+ Procedure StartNetworkThread();
+ Procedure StopNetworkThread();
+ Procedure ProcessIncomingChunks();
End;
Implementation
Uses math;
+{ TNetworkThread }
+
+Constructor TNetworkThread.Create(AChunkManager: TChunkManager);
+Begin
+ Inherited Create(False); // Start immediately
+ FreeOnTerminate := False; // We'll free it manually
+ fChunkManager := AChunkManager;
+End;
+
+Procedure TNetworkThread.Execute;
+Begin
+ While Not Terminated Do Begin
+ // Process all pending network events
+ If Assigned(fChunkManager) Then Begin
+ fChunkManager.CallAction();
+ End;
+
+ // Sleep for 5ms to avoid busy-wait
+ // This gives ~200 network updates per second
+ Sleep(5);
+ End;
+End;
+
Const
{$IFDEF UseMagicHeader}
MagicHeader: Array[0..3] Of byte = (ord('C'), ord('U'), ord('S'), ord('W'));
@@ -291,6 +346,8 @@
Funique_counter := 1; // 0 ist "ungültige" id
fIsServer := false;
fconnection := Nil;
+ fIncomingQueue := specialize TThreadSafeQueue.Create;
+ fNetworkThread := Nil;
{$IFDEF UseLogger}
logleave;
{$ENDIF}
@@ -301,10 +358,12 @@
{$IFDEF UseLogger}
log('TChunkManager.destroy', llTrace);
{$ENDIF}
+ StopNetworkThread();
If Connected Then Begin
Disconnect(true);
End;
RegisterConnection(Nil); // Löschen aller alten Captures..
+ fIncomingQueue.Free;
{$IFDEF UseLogger}
logleave;
{$ENDIF}
@@ -481,11 +540,26 @@
exit;
End;
If assigned(fOnReceivedChunk) Then Begin
- pu^.RecvBuf.Data.Position := 0;
- Chunk.Data := pu^.RecvBuf.Data;
- Chunk.UID := pu^.UID;
- Chunk.UserDefinedID := pu^.RecvBuf.UserDefinedId;
- fOnReceivedChunk(self, Chunk);
+ // If network thread is running, enqueue the chunk for processing in main thread
+ // Otherwise, call the callback directly (legacy behavior)
+ If Assigned(fNetworkThread) Then Begin
+ // Create a copy of the data for the queue
+ Chunk.Data := TMemoryStream.Create;
+ pu^.RecvBuf.Data.Position := 0;
+ Chunk.Data.CopyFrom(pu^.RecvBuf.Data, pu^.RecvBuf.Data.Size);
+ Chunk.Data.Position := 0;
+ Chunk.UID := pu^.UID;
+ Chunk.UserDefinedID := pu^.RecvBuf.UserDefinedId;
+ fIncomingQueue.Enqueue(Chunk);
+ End
+ Else Begin
+ // Legacy mode: direct callback (no network thread)
+ pu^.RecvBuf.Data.Position := 0;
+ Chunk.Data := pu^.RecvBuf.Data;
+ Chunk.UID := pu^.UID;
+ Chunk.UserDefinedID := pu^.RecvBuf.UserDefinedId;
+ fOnReceivedChunk(self, Chunk);
+ End;
End;
// Wenn fOnReceivedChunk Chunkmanager.Disconnect aufruft, dann ist der Pointer nicht mehr gültig, weil schon freigegeben !
If assigned(asocket.UserData) Then Begin
@@ -885,11 +959,14 @@
Procedure TChunkManager.SetNoDelay(Value: Boolean);
Begin
{$IFDEF UseLogger}
- log('TChunkManager.SetNoDelay', llTrace);
+ log('TChunkManager.SetNoDelay : ' + BoolToStr(Value, True), llTrace);
{$ENDIF}
fconnection.IterReset;
- fconnection.Iterator.SetState(ssNoDelay, Value);
- While fconnection.IterNext Do Begin // Skipt Root Socket
+ // Enable TCP_NODELAY on all platforms (including macOS/Darwin)
+ // This disables Nagle's algorithm to reduce latency for real-time games
+ If Assigned(fconnection.Iterator) Then
+ fconnection.Iterator.SetState(ssNoDelay, Value);
+ While fconnection.IterNext Do Begin // Skip Root Socket
fconnection.Iterator.SetState(ssNoDelay, Value);
End;
{$IFDEF UseLogger}
@@ -904,5 +981,54 @@
End;
End;
+Procedure TChunkManager.StartNetworkThread();
+Begin
+{$IFDEF UseLogger}
+ log('TChunkManager.StartNetworkThread', llTrace);
+{$ENDIF}
+ If Not Assigned(fNetworkThread) Then Begin
+ fNetworkThread := TNetworkThread.Create(Self);
+{$IFDEF UseLogger}
+ log('Network thread started', llInfo);
+{$ENDIF}
+ End;
+{$IFDEF UseLogger}
+ logleave;
+{$ENDIF}
+End;
+
+Procedure TChunkManager.StopNetworkThread();
+Begin
+{$IFDEF UseLogger}
+ log('TChunkManager.StopNetworkThread', llTrace);
+{$ENDIF}
+ If Assigned(fNetworkThread) Then Begin
+ fNetworkThread.Terminate;
+ fNetworkThread.WaitFor;
+ fNetworkThread.Free;
+ fNetworkThread := Nil;
+{$IFDEF UseLogger}
+ log('Network thread stopped', llInfo);
+{$ENDIF}
+ End;
+{$IFDEF UseLogger}
+ logleave;
+{$ENDIF}
+End;
+
+Procedure TChunkManager.ProcessIncomingChunks();
+Var
+ Chunk: TChunk;
+Begin
+ // Process all pending chunks from the network thread
+ While fIncomingQueue.Dequeue(Chunk) Do Begin
+ If assigned(fOnReceivedChunk) Then Begin
+ fOnReceivedChunk(self, Chunk);
+ End;
+ // Free the data stream (it was created in OnReceive as a copy)
+ Chunk.Data.Free;
+ End;
+End;
+
End.
diff --git a/units/uip.pas b/units/uip.pas
index 8675da8..77ffe46 100644
--- a/units/uip.pas
+++ b/units/uip.pas
@@ -29,6 +29,11 @@
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit uip;
{$MODE ObjFPC}{$H+}
@@ -36,7 +41,7 @@
Interface
Uses
- Classes, SysUtils;
+ Classes, SysUtils, math;
Type
TIPAddress = Array[0..3] Of Byte;
@@ -104,7 +109,7 @@
sl: TStringList;
responce, tmp: String;
{$IFDEF Windows}
- j,
+ j, k: Integer;
{$ENDIF}
i: Integer;
Begin
@@ -113,6 +118,10 @@
{$IFDEF Linux}
RunCommand('ifconfig', [], responce, [poWaitOnExit]);
{$ENDIF}
+{$IFDEF Darwin}
+ // macOS uses ifconfig similar to Linux
+ RunCommand('ifconfig', [], responce, [poWaitOnExit]);
+{$ENDIF}
{$IFDEF Windows}
RunCommand('ipconfig', [], responce, [poNoConsole, poWaitOnExit]);
{$ENDIF}
@@ -132,26 +141,104 @@
result[high(result)].AdapterName := copy(sl[i - 1], 1, pos(':', sl[i - 1]) - 1);
End;
{$ENDIF}
+{$IFDEF Darwin}
+ // macOS ifconfig format: "inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255"
+ // or: " inet 192.168.0.72 netmask 0xffffff00 broadcast 192.168.0.255"
+ If (pos('inet ', sl[i]) <> 0) And (pos('inet6 ', sl[i]) = 0) Then Begin
+ // Extract IP address (skip "inet " and get the first word)
+ tmp := trim(sl[i]);
+ tmp := copy(tmp, pos('inet ', tmp) + length('inet '), length(tmp));
+ tmp := copy(tmp, 1, pos(' ', tmp) - 1);
+ // Skip loopback interface (127.0.0.1)
+ If (tmp <> '127.0.0.1') And (tmp <> '') Then Begin
+ setlength(result, high(result) + 2);
+ result[high(result)].IpAddress := tmp;
+
+ // Extract netmask (can be in hex format like 0xffffff00 or decimal)
+ tmp := sl[i];
+ If pos('netmask ', tmp) <> 0 Then Begin
+ tmp := copy(tmp, pos('netmask ', tmp) + length('netmask '), length(tmp));
+ tmp := copy(tmp, 1, pos(' ', tmp) - 1);
+ // If netmask is in hex format (0x...), we could convert it, but for now just store as is
+ // Most common: 0xffffff00 = 255.255.255.0
+ result[high(result)].SubnetMask := tmp;
+ End Else Begin
+ result[high(result)].SubnetMask := '255.255.255.0'; // Default fallback
+ End;
+
+ // Get adapter name from previous line (format: "en0: flags=..." or "en0:")
+ If i > 0 Then Begin
+ tmp := trim(sl[i - 1]);
+ If pos(':', tmp) <> 0 Then Begin
+ tmp := copy(tmp, 1, pos(':', tmp) - 1);
+ result[high(result)].AdapterName := trim(tmp);
+ End Else Begin
+ result[high(result)].AdapterName := 'unknown';
+ End;
+ End Else Begin
+ result[high(result)].AdapterName := 'unknown';
+ End;
+ End;
+ End;
+{$ENDIF}
{$IFDEF Windows}
- If pos('IPv4-', sl[i]) <> 0 Then Begin
+ // Windows ipconfig format can be:
+ // " IPv4 Address. . . . . . . . . . . : 192.168.1.100"
+ // or localized versions like " IPv4-Adresse . . . . . . . . . : 192.168.1.100"
+ // Look for "IPv4" followed by "Address" or "Adresse" (German) or similar
+ If (pos('IPv4', sl[i]) <> 0) And ((pos('Address', sl[i]) <> 0) Or (pos('Adresse', sl[i]) <> 0)) Then Begin
setlength(result, high(result) + 2);
- tmp := copy(sl[i], pos(':', sl[i]) + 1, length(sl[i]));
- result[high(result)].IpAddress := trim(tmp);
+ // Extract IP address - it's after the last colon
+ tmp := sl[i];
+ j := length(tmp);
+ // Find last colon
+ While (j > 0) And (tmp[j] <> ':') Do
+ dec(j);
+ If j > 0 Then Begin
+ tmp := copy(tmp, j + 1, length(tmp));
+ result[high(result)].IpAddress := trim(tmp);
+ // Skip loopback interface
+ If result[high(result)].IpAddress = '127.0.0.1' Then Begin
+ setlength(result, high(result));
+ Continue;
+ End;
+ End Else Begin
+ setlength(result, high(result));
+ Continue;
+ End;
- // TODO: Maybe implement a more "Robust" method to get the subnet mask ??
- tmp := copy(sl[i + 1], pos(':', sl[i]) + 1, length(sl[i]));
- result[high(result)].SubnetMask := tmp;
+ // Try to find subnet mask in next few lines
+ result[high(result)].SubnetMask := '255.255.255.0'; // Default fallback
+ For j := i + 1 To min(i + 5, sl.Count - 1) Do Begin
+ If (pos('Subnet Mask', sl[j]) <> 0) Or (pos('Subnetmaske', sl[j]) <> 0) Then Begin
+ tmp := sl[j];
+ k := length(tmp);
+ While (k > 0) And (tmp[k] <> ':') Do
+ dec(k);
+ If k > 0 Then Begin
+ tmp := copy(tmp, k + 1, length(tmp));
+ result[high(result)].SubnetMask := trim(tmp);
+ End;
+ break;
+ End;
+ End;
- result[high(result)].AdapterName := 'Could not resolve adapter name';
- For j := i Downto 1 Do Begin
+ // Find adapter name - look backwards for adapter name (usually before "IPv4" line)
+ result[high(result)].AdapterName := 'unknown';
+ For j := i Downto max(1, i - 10) Do Begin
If trim(sl[j]) = '' Then Begin
- tmp := sl[j - 1];
- tmp := copy(tmp, 1, pos(':', tmp) - 1);
- If tmp <> '' Then Begin
- result[high(result)].AdapterName := tmp;
+ If j > 0 Then Begin
+ tmp := trim(sl[j - 1]);
+ // Adapter name is usually on a line ending with ":"
+ If (pos(':', tmp) <> 0) And (pos('IPv4', tmp) = 0) Then Begin
+ tmp := copy(tmp, 1, pos(':', tmp) - 1);
+ If tmp <> '' Then Begin
+ result[high(result)].AdapterName := trim(tmp);
+ End;
+ break;
+ End;
End;
- break;
End;
End;
End;
diff --git a/units/ulogger.pas b/units/ulogger.pas
index dfefe76..2ce95b5 100644
--- a/units/ulogger.pas
+++ b/units/ulogger.pas
@@ -1,773 +1,794 @@
-(******************************************************************************)
-(* ulogger.pas 06.11.2015 *)
-(* *)
-(* Version : 0.06 *)
-(* *)
-(* Author : Uwe Schchterle (Corpsman) *)
-(* *)
-(* Support : www.Corpsman.de *)
-(* *)
-(* Description : This unit gives you the ability to create application logs *)
-(* to support a better error finding within your application *)
-(* there a several log levels and log outputs supported. *)
-(* *)
-(* License : See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(* Warranty : There is no warranty, neither in correctness of the *)
-(* implementation, nor anything other that could happen *)
-(* or go wrong, use at your own risk. *)
-(* *)
-(* Known Issues: none *)
-(* *)
-(* History : 0.01 - Initial version *)
-(* 0.02 - prototypen fr Stacktracing *)
-(* 0.03 - Halt on Fatal Option *)
-(* MaxStackDepth *)
-(* Optionales StackBoundaryChecking *)
-(* Optionales Anfgen Methodenname beim Logging *)
-(* LogShow *)
-(* 0.04 - Added loglevel llError *)
-(* 0.05 - Logshow fr Konsole *)
-(* 0.06 - laderoutine fr Logfiles *)
-(* *)
-(******************************************************************************)
-
-Unit ulogger;
-
-{$MODE objfpc}{$H+}
-
-Interface
-
-(*
- * if you get an compiler error here create the ulogger.inc and enable the following
- * defines as needed:
- {$.define USELCL} // Use LCL instead of console output
- *)
-{$I ulogger.inc}
-
-Uses classes
-{$IFDEF USELCL}
- , dialogs
-{$ENDIF}
- ;
-
-Type
-
- (*
- * Jeder Logeintrag kann einer bestimmten Log Gruppe zugeordnet werden
- * Es empfiehlt sich dabei folgende Gliederungshierarchie zu verwenden.
- *
- * Fr Produktivcode sollte mindetens LogLevel (3) Aktiv sein.
- *
- * Level :
- *(0) Trace = [llTrace, lldebug, llInfo, llWarning, llError, llCritical, llFatal]
- * Ein Trace Log, dient im Allgemeinen der Nachvollziehbarkeit des
- * Programmflusses, er erzeugt den Grten Datenoutput und ist
- * deswegen, die schwchste Form des Loggings
- * z.B.: bei Betreten und Beenden einer Methode
- *
- *(1) Debugg = [lldebug, llInfo, llWarning, llError, llCritical, llFatal]
- * Ein Debugg Log, ist eine Willkrlich und generell nur Temporr
- * ausgegebene Information
- * z.B.: Bei der Suche nach Fehlern, Ausgabe von Werten
- *
- *(2) Info = [llInfo, llWarning, llError, llCritical, llFatal]
- * Alles was nur der "Interesse" halber geloggt wird, aber eigentlich
- * nicht kritisch ist.
- * z.B.: Aktuelle Uhrzeit, Anzahl eingeloggter Benutzer ..
- *
- *(3) Warning = [llWarning, llError, llCritical, llFatal]
- * Ein Warning Log, ist ein Fehler, welcher die Ausfhrung der
- * Anwendung nicht weiter beeinflusst. Aber dennoch nicht der
- * bliche/ Erwartete Zustand eingenommen wird.
- * z.B.: Vergessen eine Setting zu spezifizieren, die Anwendung nimmt einen Default Wert
- *
- *(4) Error = [llError, llCritical, llFatal]
- * Ein Error Log, ist ein Fehler, welcher die Ausfhrung negativ
- * beeinflusst aber nicht zum Absturz fhrt.
- * z.B.: Fehlen einer kompletten Konfigurationsdatei, das Programm kann eingeschrnkt weiter genutzt werden.
- *
- *(5)Critical = [llCritical, llFatal]
- * Ein Kritischer Log, ist ein Fataler Fehler, welcher aber eine
- * geeignete Fehlerbehandlung hat, das Programm bleibt Konsistent
- * und kann weiter Fehlerfrei (mit Defaultwerten) betrieben werden.
- * z.B.: Zugriff auf ein nicht existierendes Array Element => Rckgabe Default Wert
- * Umwandlung von String in Int, mit Defaultwert
- *
- *(6) Fatal = [llFatal]
- * Ein Fataler Log, fhrt im Prinzip zu einem Programmabsturz,
- * alles oder Programmteile sind hiernach nicht mehr ausfhrbar.
- * Die Anwendung ist in einem Undefinierten Zustand, bei dem sie
- * nicht mehr definiert weiter arbeiten kann und beendet werden
- * sollte.
- * z.B.: Zugriffsverletzung auf einen Speicherbereich,
- * except block im Try
- *)
-
- TLogLevel = (llTrace, lldebug, llInfo, llWarning, llError, llCritical, llFatal);
- TLogLevelSet = Set Of TLogLevel;
-
- (*
- * Die Loggerklasse ist nur Verfgbar, damit "eigene" instanzen erzeugt
- * werden knnen.
- * Zur Nutzung der unit ist kein eigenstndiges Erzeugen notwendig.
- *)
-
- (*
- * Soll der Stack mit geloggt werden muss jede Prozedur wie folgt gestaltet werden
- * Zur Nutzung muss das llTrace nicht Aktiviert werden, es gengt, dass LogTraceStack
- * gesetzt wird, und das an LogStack bergebene Loglevel aktuell ebenfalls geloggt wird.
- *
- * Procedure Dummy;
- * begin
- * Log('Dummy', llTrace);
- * ..
- * { Vor jedem "Halt"/ "Exit", muss auch LogLeave stehen }
- *
- * LogLeave;
- * end;
- *
- * Dann kann zu jeder Zeit Mittels : LogStack( .. ) der Aktuelle Stack geschrieben werden.
- *)
-
- { TLogger }
-
- TLogger = Class
- private
- fAddRoutineNameToLogs: Boolean;
- fAutoLogStackOnFatal: Boolean;
- fCheckMaxStackDepth: integer;
- fFilename: String;
- fHaltOnFatal: Boolean;
- fLogLevel: TLogLevelSet;
- FLogFile: TextFile;
- fFlushLogFileOnLog: Boolean;
- flogfileisopened: Boolean;
- FEnable: Boolean;
- FDateFormat: String; // Todo : Soll mal dem User verfgbar gemacht werden
- fLogToConsole: Boolean;
- flogtoFile: Boolean;
- fLogStackTrace: Boolean;
- fStack: TStringList;
- fMaxStackDepth: integer;
- fCheckStackBoundaries: Boolean;
- Procedure OpenLogFile; // ffnet evtl. das Filehandle
- Procedure DoLog(Const Text: String); // Gibt den Text auf der Console aus, oder Speichert in ihn die LogDatei
- Function CreateLog(Logtext: String; Const Loglevel: TLogLevel): String; // Erzeugt den Passend Eingerckten Logeintrag, welcher Gespeichert oder auf die Konsole Ausgegeben wird
- Procedure CloseLogFile(Force: Boolean); // Schliet evtl. das Filehandle
- Function StackLog: String; // Der Stacklog als Text
- Procedure SetEnable(Const aValue: Boolean);
- Function getLoglevel(): integer;
- public
- (*
- * Stack Bezogene Optionen
- *)
- Property AddRoutineNameToLogs: Boolean read fAddRoutineNameToLogs write fAddRoutineNameToLogs; // Wenn Stacktracing Aktiviert ist, dann kann hier der Aktuelle Methodenname Automatisch mit angefgt werden.
- Property AutoLogStackOnFatal: Boolean read fAutoLogStackOnFatal write fAutoLogStackOnFatal; // Automatisches Stack Trace Schreiben bei Fatalen Logs
- Property CheckMaxStackDepth: integer read fCheckMaxStackDepth write fCheckMaxStackDepth; // Bei Aktivierter Stack berwachung ist dies die Grenze wogegen geprft wird
- Property CheckStackBoundaries: Boolean read fCheckStackBoundaries write fCheckStackBoundaries; // Wenn Gesetzt, dann Loggt der Logger einen Fatalen Log, wenn Stacktiefe > fCheckMaxStackDepth oder < 0 wird.
- Property LogStackTrace: Boolean read fLogStackTrace write fLogStackTrace; // Wenn Aktiviert, dann muss zu jedem llTrace ein LogLeave aufgerufen werden.
- Property MaxStackDepth: integer read fMaxStackDepth; // Gibt die bisher tiefste Stacktiefe zurck
-
- (*
- * Generelle Optionen
- *)
- Property Enable: Boolean read FEnable write SetEnable; //Nur Wenn Enabled wird berhaupt geloggt
- Property HaltOnFatal: Boolean read fHaltOnFatal write fHaltOnFatal; // Wenn gesetzt, dann wird die Anwendung via Halt bei einem Fatalen Eintrag automatisch beendet.
-
- (*
- * Logging Spezifische Optionen
- *)
- Property FlushLogFileOnLog: Boolean read fFlushLogFileOnLog write fFlushLogFileOnLog; // Wenn True, wird jedes Log Ereignis auf die HDD durchgeschrieben und Sichergestellt, dass es auch drin ist, andernfalls wird evtl durch das OS gecached
- Property LogToConsole: Boolean read fLogToConsole write fLogToConsole; // Soll Auch ein Logging auf die Konsole stattfinden
- Property LogToFile: Boolean read flogtoFile write flogtofile; // Soll in eine Datei geschrieben werden ?
- Property LogLevel: Integer read getLoglevel;
-
- Constructor Create();
- Destructor Destroy; override;
-
- Procedure SetCustomLogging(Const LogLevel_: TLogLevelSet); // Frei Konfigurierbares Logging
- Procedure SetLogFilename(Const Filename: String); // Setzt das den Dateinamen fr die Logdatei
- Procedure SetLogLevel(Const Level: integer); // Setzt gem der Obigen Spezifikation das Logging
-
- // Der Eigentliche Log Mechanismus
- Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel_: TLogLevel = llInfo); // Logt nur wenn "Criteria" = true
- Procedure Log(LogText: String; LogLevel_: TLogLevel = llInfo);
- Procedure LogShow(LogText: String; LogLevel_: TLogLevel = llInfo);
- Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel_: TLogLevel = llInfo);
- Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
- Procedure LogInt(Value: Int32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
- Procedure LogUInt(Value: uInt32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
-
- Function LoggerLogs(Const LogLevel_: TLogLevel): Boolean; // True, wenn Loglevel vom Logger geloggt wird
-
- Procedure LogLeave; // Wenn LogTraceStack Aktiviert, "Ende" einer Routine
- Procedure LogStack(LogLevel_: TLogLevel = llinfo); // Wenn LogTraceStack Aktiviert, dann kann so der Stacktrace geloggt werden
- End;
-
- (*
- * Zum Laden einer LogDatei
- *)
-
- TLogEntry = Record
- TimeStamp: TDateTime;
- LogLevel: TLogLevel;
- LogText: String;
- End;
-
- TLogEntryArray = Array Of TLogEntry;
-
-Var
- (*
- * Konfiguration des Loggers, Optional
- *
- * Ohne Konfiguration gelten folgende Einstellungen :
- *
- * Loglevel(2)
- * Enable = True
- * LogToFile = True
- * LogToConsole = False
- * FlushLogFileOnLog = True
- * Logfilename = Exename mit Dateiendung ".log"
- * DateFormat = 'YYYY.MM.DD HH:NN:SS'
- *
- *)
- Logger: TLogger = Nil; // Wird Automatisch initialisiert und Freigegeben, dient nur dem Zugriff auf die Konfiguration
-
- (*
- * Diverse Log Funktionen fr Basistypen, Wrapper fr logger.XY
- *)
-Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel: TLogLevel = llInfo); // Logt nur wenn "Criteria" = true
-Procedure Log(LogText: String; LogLevel: TLogLevel = llInfo); // -- Kann auch mit Mehrzeiligen Strings umgehen
-Procedure LogShow(LogText: String; LogLevel: TLogLevel = llInfo);
-Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Procedure LogInt(Value: Int32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Procedure LogUInt(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-
-Procedure LogLeave; // Wenn LogTraceStack Aktiviert, dann kann so der Stacktrace geloggt werden
-Procedure LogStack(LogLevel: TLogLevel = llinfo); // Wenn LogTraceStack Aktiviert, "Ende" einer Routine
-
-(*
- * Sonstige
- *)
-Function LogLevelToString(LogLevel: TLogLevel): String;
-Function LoadLogFile(Const Filename: String): TLogEntryArray;
-
-Implementation
-
-Uses sysutils, FileUtil, LazFileUtils,
-{$IFDEF USELCL}
- lazutf8,
-{$ENDIF}
- math;
-
-{$IFNDEF USELCL}
-
-Function utf8tosys(value: String): String;
-Begin
- result := value;
-End;
-{$ENDIF}
-
-(*
- * Umkehrfunktion zu FormatDateTime
- * Die Implementierung ist nicht vollstndig, Erkennt aber ob die Konvertierung
- * Fehlgeschlagen ist, wenn dem so ist, dann result := -1
- *)
-// TODO: Diese Funktion hier knnte auch durch die "ScanDateTime" routine aus dateutil ersetzt werden.
-Function StrToDateTimeFormat(Input, Format: String): TDateTime;
-Var
- y, m, d, h, n, s, z: String;
- ip, fp: integer;
- Block: Boolean;
-Begin
- (*
- * Die Idee ist den Input String gem dem Format String zu Parsen und alle
- * Formatstring Tokens in den einzelnen Container zu sammeln.
- * Dann wird Konvertiert und mittels anschlieender Rckkonvertierung
- * geprft ob alles geklappt hat *g*.
- *)
- // Der Formatstring muss mindestens so lang sein wie der Eingabestring.
- If length(Format) < length(Input) Then Begin
- Result := -1;
- exit;
- End;
- y := '';
- m := '';
- d := '';
- h := '';
- n := '';
- s := '';
- z := '';
- Block := FALSE;
- Format := lowercase(Format);
- ip := 1;
- fp := 1;
- While fp <= length(Format) Do Begin
- If Block Then Begin
- If Format[fp] = '''' Then Begin
- Block := FALSE;
- inc(fp);
- End
- Else Begin
- inc(fp);
- inc(ip);
- End;
- End
- Else Begin
- Case Format[fp] Of
- '''': Begin
- Block := true;
- dec(ip);
- End;
- 'y': y := y + Input[ip];
- 'm': m := m + Input[ip];
- 'd': d := d + Input[ip];
- 'h': h := h + Input[ip];
- 'n': n := n + Input[ip];
- 's': s := s + Input[ip];
- 'z': z := z + Input[ip];
- End;
- inc(fp);
- inc(ip);
- End;
- End;
- // Sind die yy Daten nur als zweistellige Zahl vorhanden, dann auf 2000+ verschieben
- If strtointdef(y, 0) < 2000 Then Begin
- y := IntToStr(strtointdef(y, 0) + 2000);
- End;
- Try
- Result := EncodeDate(strtointdef(y, 0), strtointdef(m, 0), strtointdef(d, 0)) + EncodeTime(strtointdef(h, 0), strtointdef(n, 0), strtointdef(s, 0), strtointdef(z, 0));
- Except
- Result := -1;
- exit;
- End;
- // Wenn alles geklappt hat, muss sich die Inverse wieder bilden lassen ;)
- z := FormatDateTime(Format, Result);
- If lowercase(FormatDateTime(Format, Result)) <> lowercase(Input) Then Begin
- Result := -1;
- End;
-End;
-
-Procedure LogLeave;
-Begin
- If assigned(logger) Then
- logger.LogLeave;
-End;
-
-Procedure LogStack(LogLevel: TLogLevel);
-Begin
- If assigned(logger) Then
- logger.LogStack(loglevel);
-End;
-
-Function LogLevelToString(LogLevel: TLogLevel): String;
-Begin
- result := 'unkn.';
- Case LogLevel Of
- llTrace: result := 'Trace';
- lldebug: result := 'Debug';
- llInfo: result := 'Info ';
- llWarning: result := 'Warn ';
- llError: result := 'Error';
- llCritical: result := 'Crit ';
- llFatal: result := 'Fatal';
- End;
-End;
-
-Function StrToLogLevel(LogLevel: String): TLogLevel;
-Begin
- result := llFatal;
- Case LogLevel Of
- 'Trace': result := llTrace;
- 'Debug': result := lldebug;
- 'Info ': result := llInfo;
- 'Warn ': result := llWarning;
- 'Error': result := llError;
- 'Crit ': result := llCritical;
- 'Fatal': result := llFatal;
- End;
-End;
-
-Function LoadLogFile(Const Filename: String): TLogEntryArray;
-Var
- s: String;
- sl: TStringList;
- cnt, i: Integer;
-Begin
- result := Nil;
- If FileExistsutf8(Filename) Then Begin
- // Gepuffertes Laden des Logfiles, so kann das Logfile whrend des neu ladens weiter beschrieben werden.
- s := GetTempFileNameUTF8(GetTempDir(), '');
- sl := TStringList.Create;
- If CopyFile(utf8tosys(filename), utf8tosys(s), false, false) Then Begin
- sl.LoadFromFile(s);
- If Not DeleteFileUTF8(s) Then Begin
-{$IFDEF USELCL}
- showmessage('Error on deleting temporary file : ' + s);
-{$ELSE}
- writeln('Error on deleting temporary file : ' + s);
-{$ENDIF}
- End;
- End;
- End
- Else Begin
- sl.LoadFromFile(Filename);
- End;
- // Laden der Eintrge
- setlength(result, sl.Count);
- cnt := 0;
- i := 0;
- While i < sl.count Do Begin
- s := sl[i];
- If trim(s) <> '' Then Begin
- If s[26] = '|' Then Begin // Der Begin eines Einziligen Logs
- result[cnt].TimeStamp := StrToDateTimeFormat(copy(s, 1, 19), Logger.fDateFormat);
- result[cnt].Loglevel := StrToLogLevel(copy(s, 21, 5));
- result[cnt].LogText := copy(s, 27, length(s));
- inc(cnt);
- End
- Else Begin // Ein Mehrzeiliger Log
- If cnt = 0 Then Begin
-{$IFDEF USELCL}
- showmessage('Error invalid .log file.');
-{$ELSE}
- writeln('Error invalid .log file.');
-{$ENDIF}
- setlength(result, 0);
- sl.free;
- exit;
- End;
-{$IFDEF Linux}
- result[cnt - 1].Logtext := result[cnt - 1].Logtext + LineEnding + copy(s, 27, length(s));
-{$ELSE}
- // Auf Windows kann die Listview kein CRT in den Zellen Darstellen, leider :(
- result[cnt - 1].Logtext := result[cnt - 1].Logtext + ' ' + copy(s, 27, length(s));
-{$ENDIF}
- End;
- End;
- inc(i);
- End;
- setlength(result, cnt);
- sl.free;
-End;
-
-Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel: TLogLevel);
-Begin
- logger.AssertLog(Criteria, LogText, LogLevel);
-End;
-
-Procedure Log(LogText: String; LogLevel: TLogLevel = llInfo);
-Begin
- logger.Log(LogText, LogLevel);
-End;
-
-Procedure LogShow(LogText: String; LogLevel: TLogLevel);
-Begin
- logger.LogShow(LogText, LogLevel);
-End;
-
-Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Begin
- logger.LogBool(value, Description, LogLevel);
-End;
-
-Procedure LogInt(Value: Int32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Begin
- logger.LogInt(value, Description, LogLevel);
-End;
-
-Procedure LoguInt(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Begin
- logger.LoguInt(value, Description, LogLevel);
-End;
-
-Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
-Begin
- logger.LogHex(value, Description, LogLevel);
-End;
-
-{ TLogger }
-
-Constructor TLogger.Create;
-Begin
- Inherited create;
- fAddRoutineNameToLogs := true;
- fCheckMaxStackDepth := 100;
- fCheckStackBoundaries := false;
- fMaxStackDepth := 0;
- fHaltOnFatal := false;
- fAutoLogStackOnFatal := false;
- fStack := TStringList.Create;
- fLogStackTrace := false;
- fFilename := '';
- Enable := True;
- SetLogFilename(ChangeFileExt(ParamStr(0), '.log'));
- SetLogLevel(2);
- flogfileisopened := false;
- fFlushLogFileOnLog := true;
- FDateFormat := 'YYYY.MM.DD HH:NN:SS';
- fLogToConsole := false;
- flogtoFile := true;
-End;
-
-Destructor TLogger.Destroy;
-Begin
- fStack.free;
- CloseLogFile(true);
-End;
-
-Procedure TLogger.CloseLogFile(Force: Boolean);
-Begin
- If (Force Or fFlushLogFileOnLog) And flogfileisopened Then Begin
- CloseFile(FLogFile);
- flogfileisopened := false;
- End;
-End;
-
-Function TLogger.CreateLog(Logtext: String; Const Loglevel: TLogLevel): String;
-Var
- s, t: String;
- i: integer;
-Begin
- If fAddRoutineNameToLogs And fLogStackTrace And (loglevel <> lltrace) Then Begin
- If fStack.Count > 0 Then Begin
- Logtext := fstack[fStack.Count - 1] + ': ' + Logtext;
- End;
- End;
- // Evtl. Vorkommende Steuerzeichen in CRT's umwandeln
- Logtext := StringReplace(Logtext, '\n', LineEnding, [rfReplaceAll, rfIgnoreCase]);
- If pos(LineEnding, Logtext) <> 0 Then Begin
- Logtext := TrimRight(Logtext);
- // 1. Zeile mit Header
- s := FormatDateTime(FDateFormat, now) + '|' + LogLevelToString(Loglevel) + '|';
- result := s;
- For i := 1 To length(s) Do Begin
- s[i] := ' ';
- End;
- Logtext := Logtext + LineEnding;
- While Logtext <> '' Do Begin
- t := copy(Logtext, 1, pos(LineEnding, Logtext) - 1);
- delete(Logtext, 1, length(t) + length(LineEnding));
- result := result + t;
- If Logtext <> '' Then
- result := result + LineEnding + s;
- End;
- End
- Else Begin
- result := FormatDateTime(FDateFormat, now) + '|' + LogLevelToString(Loglevel) + '|' + Logtext;
- End;
-End;
-
-Procedure TLogger.Log(LogText: String; LogLevel_: TLogLevel);
-Begin
- If Not assigned(self) Then exit; // Wenn sich der Logger selbst killt via halt, dann wird er freigegeben bevor er fertig ist.
- If Not FEnable Then exit;
- If loglevel_ In fLogLevel Then Begin
- OpenLogFile;
- DoLog(CreateLog(Logtext, Loglevel_));
- If fAutoLogStackOnFatal And (LogLevel_ = llFatal) Then Begin
- DoLog(CreateLog(StackLog(), Loglevel_));
- End;
- CloseLogFile(false);
- End;
- // Wenn ein Stacktrace geschrieben werden soll, dann
- If fLogStackTrace And (LogLevel_ = llTrace) Then Begin
- fStack.Add(LogText);
- fMaxStackDepth := max(fMaxStackDepth, fstack.Count);
- If fstack.count > fCheckMaxStackDepth Then Begin
- log('Stack overflow.', llfatal);
- End;
- End;
- // Halt on Fatal
- If fHaltOnFatal And (loglevel_ = llFatal) Then Begin
- fstack.Clear; // Wir beenden via Gewalt, also Stack auch Lschen, wenn dann wurde er eh schon geloggt.
- CloseLogFile(true);
- halt(1);
- End;
-End;
-
-Procedure TLogger.LogShow(LogText: String; LogLevel_: TLogLevel);
-Begin
-{$IFDEF USELCL}
- ShowMessage(LogLevelToString(LogLevel_) + ' : ' + LogText);
-{$ELSE}
- writeln(LogLevelToString(LogLevel_) + ' : ' + LogText);
-{$ENDIF}
- If LogLevel_ In fLogLevel Then Begin
- log(LogText, LogLevel_);
- End;
-End;
-
-Procedure TLogger.LogBool(Value: Boolean; Description: String;
- LogLevel_: TLogLevel);
-Begin
- If value Then Begin
- log(Description + ' = True ', LogLevel_);
- End
- Else Begin
- log(Description + ' = False', LogLevel_);
- End;
-End;
-
-Procedure TLogger.LogHex(Value: uInt32; Description: String; LogLevel_: TLogLevel
- );
-Begin
- log(Description + format(' = %0.8X', [value]), LogLevel_);
-End;
-
-Function TLogger.LoggerLogs(Const LogLevel_: TLogLevel): Boolean;
-Begin
- result := LogLevel_ In fLogLevel;
-End;
-
-Procedure TLogger.LogInt(Value: Int32; Description: String; LogLevel_: TLogLevel
- );
-Begin
- log(Description + format(' = %d', [value]), LogLevel_);
-End;
-
-Procedure TLogger.LogLeave;
-Begin
- If fLogStackTrace Then Begin
- If (fstack.Count <> 0) Then Begin
- fstack.Delete(fstack.Count - 1);
- End
- Else Begin
- If fCheckStackBoundaries Then Begin
- log('Stack underflow.', llfatal);
- End;
- End;
- End;
-End;
-
-Function TLogger.StackLog: String;
-Var
- i: integer;
-Begin
- result := 'Stacktrace:' + LineEnding;
- For I := 0 To fStack.Count - 1 Do Begin
- result := result + ' ' + fstack[i] + LineEnding;
- End;
-End;
-
-Procedure TLogger.LogStack(LogLevel_: TLogLevel);
-Begin
- If fLogStackTrace And (LogLevel_ In fLogLevel) Then Begin
- Log(StackLog(), LogLevel_);
- End;
-End;
-
-Procedure TLogger.DoLog(Const Text: String);
-Begin
- If flogfileisopened Then Begin // Wenn Keine datei geffnet ist, kann auch nicht geschrieben werden.
- writeln(FLogFile, Text);
- End;
- If fLogToConsole Then Begin // Wenn auch auf die Konsole ausgegeben werden soll
- writeln(Text);
- End;
-End;
-
-Procedure TLogger.LogUInt(Value: uInt32; Description: String;
- LogLevel_: TLogLevel);
-Begin
- log(Description + format(' = %u', [value]), LogLevel_);
-End;
-
-Procedure TLogger.OpenLogFile;
-Begin
- If Not flogtoFile Then exit;
- If Not flogfileisopened Then Begin
- assignfile(FLogFile, utf8tosys(fFilename));
- If FileExists(fFilename) Then Begin
- append(FLogFile);
- End
- Else Begin
- Rewrite(FLogFile);
- End;
- flogfileisopened := true;
- End;
-End;
-
-Procedure TLogger.SetCustomLogging(Const LogLevel_: TLogLevelSet);
-Begin
- fLogLevel := LogLevel_;
-End;
-
-Procedure TLogger.SetEnable(Const aValue: Boolean);
-Begin
- If FEnable <> avalue Then Begin
- FEnable := avalue;
- If Not FEnable Then CloseLogFile(true);
- End;
-End;
-
-Procedure TLogger.SetLogFilename(Const Filename: String);
-Begin
- If (fFilename <> Filename) Then Begin
- fFilename := Filename;
- // Wird der Dateiname Gendert, obwohl die Logdatei gerade geffnet ist, muss die alte vorher geschlossen werden.
- If flogfileisopened Then Begin
- CloseLogFile(true);
- End;
- End;
-End;
-
-Procedure TLogger.AssertLog(Criteria: Boolean; LogText: String;
- LogLevel_: TLogLevel);
-Begin
- If Not assigned(self) Then exit;
- If Not FEnable Then exit;
- If Criteria Then Begin
- Log(LogText, LogLevel_);
- End
- Else Begin
- If fLogStackTrace And (loglevel_ = lltrace) Then Begin
- fstack.Add(Logtext);
- fMaxStackDepth := max(fMaxStackDepth, fstack.Count);
- End;
- End;
-End;
-
-Function TLogger.getLoglevel: integer;
-Begin
- result := -1;
- If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo, lldebug, llTrace] Then result := 0;
- If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo, lldebug] Then result := 1;
- If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo] Then result := 2;
- If fLogLevel = [llFatal, llCritical, llError, llWarning] Then result := 3;
- If fLogLevel = [llFatal, llCritical, llError] Then result := 4;
- If fLogLevel = [llFatal, llCritical] Then result := 5;
- If fLogLevel = [llFatal] Then result := 6;
-End;
-
-Procedure TLogger.SetLogLevel(Const Level: integer);
-Begin
- Case level Of
- 0: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo, lldebug, llTrace];
- 1: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo, lldebug];
- 2: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo];
- 3: fLogLevel := [llFatal, llCritical, llError, llWarning];
- 4: fLogLevel := [llFatal, llCritical, llError];
- 5: fLogLevel := [llFatal, llCritical];
- 6: fLogLevel := [llFatal]
- Else
- fLogLevel := []; // Undefiniert = Aus
- End;
-End;
-
-Initialization
- logger := TLogger.Create;
-
-Finalization
- logger.Free;
- logger := Nil;
-
-End.
-
+(******************************************************************************)
+(* ulogger.pas 06.11.2015 *)
+(* *)
+(* Version : 0.06 *)
+(* *)
+(* Author : Uwe Sch�chterle (Corpsman) *)
+(* *)
+(* Support : www.Corpsman.de *)
+(* *)
+(* Description : This unit gives you the ability to create application logs *)
+(* to support a better error finding within your application *)
+(* there a several log levels and log outputs supported. *)
+(* *)
+(* License : See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(* Warranty : There is no warranty, neither in correctness of the *)
+(* implementation, nor anything other that could happen *)
+(* or go wrong, use at your own risk. *)
+(* *)
+(* Known Issues: none *)
+(* *)
+(* History : 0.01 - Initial version *)
+(* 0.02 - prototypen f�r Stacktracing *)
+(* 0.03 - Halt on Fatal Option *)
+(* MaxStackDepth *)
+(* Optionales StackBoundaryChecking *)
+(* Optionales Anf�gen Methodenname beim Logging *)
+(* LogShow *)
+(* 0.04 - Added loglevel llError *)
+(* 0.05 - Logshow f�r Konsole *)
+(* 0.06 - laderoutine f�r Logfiles *)
+(* *)
+(******************************************************************************)
+
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit ulogger;
+
+{$MODE objfpc}{$H+}
+
+Interface
+
+(*
+ * if you get an compiler error here create the ulogger.inc and enable the following
+ * defines as needed:
+ {$.define USELCL} // Use LCL instead of console output
+ *)
+{$I ulogger.inc}
+
+Uses classes
+{$IFDEF USELCL}
+ , dialogs
+{$ENDIF}
+ ;
+
+Type
+
+ (*
+ * Jeder Logeintrag kann einer bestimmten Log Gruppe zugeordnet werden
+ * Es empfiehlt sich dabei folgende Gliederungshierarchie zu verwenden.
+ *
+ * F�r Produktivcode sollte mindetens LogLevel (3) Aktiv sein.
+ *
+ * Level :
+ *(0) Trace = [llTrace, lldebug, llInfo, llWarning, llError, llCritical, llFatal]
+ * Ein Trace Log, dient im Allgemeinen der Nachvollziehbarkeit des
+ * Programmflusses, er erzeugt den Gr��ten Datenoutput und ist
+ * deswegen, die schw�chste Form des Loggings
+ * z.B.: bei Betreten und Beenden einer Methode
+ *
+ *(1) Debugg = [lldebug, llInfo, llWarning, llError, llCritical, llFatal]
+ * Ein Debugg Log, ist eine Willk�rlich und generell nur Tempor�r
+ * ausgegebene Information
+ * z.B.: Bei der Suche nach Fehlern, Ausgabe von Werten
+ *
+ *(2) Info = [llInfo, llWarning, llError, llCritical, llFatal]
+ * Alles was nur der "Interesse" halber geloggt wird, aber eigentlich
+ * nicht kritisch ist.
+ * z.B.: Aktuelle Uhrzeit, Anzahl eingeloggter Benutzer ..
+ *
+ *(3) Warning = [llWarning, llError, llCritical, llFatal]
+ * Ein Warning Log, ist ein Fehler, welcher die Ausf�hrung der
+ * Anwendung nicht weiter beeinflusst. Aber dennoch nicht der
+ * �bliche/ Erwartete Zustand eingenommen wird.
+ * z.B.: Vergessen eine Setting zu spezifizieren, die Anwendung nimmt einen Default Wert
+ *
+ *(4) Error = [llError, llCritical, llFatal]
+ * Ein Error Log, ist ein Fehler, welcher die Ausf�hrung negativ
+ * beeinflusst aber nicht zum Absturz f�hrt.
+ * z.B.: Fehlen einer kompletten Konfigurationsdatei, das Programm kann eingeschr�nkt weiter genutzt werden.
+ *
+ *(5)Critical = [llCritical, llFatal]
+ * Ein Kritischer Log, ist ein Fataler Fehler, welcher aber eine
+ * geeignete Fehlerbehandlung hat, das Programm bleibt Konsistent
+ * und kann weiter Fehlerfrei (mit Defaultwerten) betrieben werden.
+ * z.B.: Zugriff auf ein nicht existierendes Array Element => R�ckgabe Default Wert
+ * Umwandlung von String in Int, mit Defaultwert
+ *
+ *(6) Fatal = [llFatal]
+ * Ein Fataler Log, f�hrt im Prinzip zu einem Programmabsturz,
+ * alles oder Programmteile sind hiernach nicht mehr ausf�hrbar.
+ * Die Anwendung ist in einem Undefinierten Zustand, bei dem sie
+ * nicht mehr definiert weiter arbeiten kann und beendet werden
+ * sollte.
+ * z.B.: Zugriffsverletzung auf einen Speicherbereich,
+ * except block im Try
+ *)
+
+ TLogLevel = (llTrace, lldebug, llInfo, llWarning, llError, llCritical, llFatal);
+ TLogLevelSet = Set Of TLogLevel;
+
+ (*
+ * Die Loggerklasse ist nur Verf�gbar, damit "eigene" instanzen erzeugt
+ * werden k�nnen.
+ * Zur Nutzung der unit ist kein eigenst�ndiges Erzeugen notwendig.
+ *)
+
+ (*
+ * Soll der Stack mit geloggt werden muss jede Prozedur wie folgt gestaltet werden
+ * Zur Nutzung muss das llTrace nicht Aktiviert werden, es gen�gt, dass LogTraceStack
+ * gesetzt wird, und das an LogStack �bergebene Loglevel aktuell ebenfalls geloggt wird.
+ *
+ * Procedure Dummy;
+ * begin
+ * Log('Dummy', llTrace);
+ * ..
+ * { Vor jedem "Halt"/ "Exit", muss auch LogLeave stehen }
+ *
+ * LogLeave;
+ * end;
+ *
+ * Dann kann zu jeder Zeit Mittels : LogStack( .. ) der Aktuelle Stack geschrieben werden.
+ *)
+
+ { TLogger }
+
+ TLogger = Class
+ private
+ fAddRoutineNameToLogs: Boolean;
+ fAutoLogStackOnFatal: Boolean;
+ fCheckMaxStackDepth: integer;
+ fFilename: String;
+ fHaltOnFatal: Boolean;
+ fLogLevel: TLogLevelSet;
+ FLogFile: TextFile;
+ fFlushLogFileOnLog: Boolean;
+ flogfileisopened: Boolean;
+ FEnable: Boolean;
+ FDateFormat: String; // Todo : Soll mal dem User verf�gbar gemacht werden
+ fLogToConsole: Boolean;
+ flogtoFile: Boolean;
+ fLogStackTrace: Boolean;
+ fStack: TStringList;
+ fMaxStackDepth: integer;
+ fCheckStackBoundaries: Boolean;
+ Procedure OpenLogFile; // �ffnet evtl. das Filehandle
+ Procedure DoLog(Const Text: String); // Gibt den Text auf der Console aus, oder Speichert in ihn die LogDatei
+ Function CreateLog(Logtext: String; Const Loglevel: TLogLevel): String; // Erzeugt den Passend Einger�ckten Logeintrag, welcher Gespeichert oder auf die Konsole Ausgegeben wird
+ Procedure CloseLogFile(Force: Boolean); // Schlie�t evtl. das Filehandle
+ Function StackLog: String; // Der Stacklog als Text
+ Procedure SetEnable(Const aValue: Boolean);
+ Function getLoglevel(): integer;
+ public
+ (*
+ * Stack Bezogene Optionen
+ *)
+ Property AddRoutineNameToLogs: Boolean read fAddRoutineNameToLogs write fAddRoutineNameToLogs; // Wenn Stacktracing Aktiviert ist, dann kann hier der Aktuelle Methodenname Automatisch mit angef�gt werden.
+ Property AutoLogStackOnFatal: Boolean read fAutoLogStackOnFatal write fAutoLogStackOnFatal; // Automatisches Stack Trace Schreiben bei Fatalen Logs
+ Property CheckMaxStackDepth: integer read fCheckMaxStackDepth write fCheckMaxStackDepth; // Bei Aktivierter Stack �berwachung ist dies die Grenze wogegen gepr�ft wird
+ Property CheckStackBoundaries: Boolean read fCheckStackBoundaries write fCheckStackBoundaries; // Wenn Gesetzt, dann Loggt der Logger einen Fatalen Log, wenn Stacktiefe > fCheckMaxStackDepth oder < 0 wird.
+ Property LogStackTrace: Boolean read fLogStackTrace write fLogStackTrace; // Wenn Aktiviert, dann muss zu jedem llTrace ein LogLeave aufgerufen werden.
+ Property MaxStackDepth: integer read fMaxStackDepth; // Gibt die bisher tiefste Stacktiefe zur�ck
+
+ (*
+ * Generelle Optionen
+ *)
+ Property Enable: Boolean read FEnable write SetEnable; //Nur Wenn Enabled wird �berhaupt geloggt
+ Property HaltOnFatal: Boolean read fHaltOnFatal write fHaltOnFatal; // Wenn gesetzt, dann wird die Anwendung via Halt bei einem Fatalen Eintrag automatisch beendet.
+
+ (*
+ * Logging Spezifische Optionen
+ *)
+ Property FlushLogFileOnLog: Boolean read fFlushLogFileOnLog write fFlushLogFileOnLog; // Wenn True, wird jedes Log Ereignis auf die HDD durchgeschrieben und Sichergestellt, dass es auch drin ist, andernfalls wird evtl durch das OS gecached
+ Property LogToConsole: Boolean read fLogToConsole write fLogToConsole; // Soll Auch ein Logging auf die Konsole stattfinden
+ Property LogToFile: Boolean read flogtoFile write flogtofile; // Soll in eine Datei geschrieben werden ?
+ Property LogLevel: Integer read getLoglevel;
+
+ Constructor Create();
+ Destructor Destroy; override;
+
+ Procedure SetCustomLogging(Const LogLevel_: TLogLevelSet); // Frei Konfigurierbares Logging
+ Procedure SetLogFilename(Const Filename: String); // Setzt das den Dateinamen f�r die Logdatei
+ Procedure SetLogLevel(Const Level: integer); // Setzt gem�� der Obigen Spezifikation das Logging
+
+ // Der Eigentliche Log Mechanismus
+ Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel_: TLogLevel = llInfo); // Logt nur wenn "Criteria" = true
+ Procedure Log(LogText: String; LogLevel_: TLogLevel = llInfo);
+ Procedure LogShow(LogText: String; LogLevel_: TLogLevel = llInfo);
+ Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel_: TLogLevel = llInfo);
+ Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
+ Procedure LogInt(Value: Int32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
+ Procedure LogUInt(Value: uInt32; Description: String = ''; LogLevel_: TLogLevel = llInfo);
+
+ Function LoggerLogs(Const LogLevel_: TLogLevel): Boolean; // True, wenn Loglevel vom Logger geloggt wird
+
+ Procedure LogLeave; // Wenn LogTraceStack Aktiviert, "Ende" einer Routine
+ Procedure LogStack(LogLevel_: TLogLevel = llinfo); // Wenn LogTraceStack Aktiviert, dann kann so der Stacktrace geloggt werden
+ End;
+
+ (*
+ * Zum Laden einer LogDatei
+ *)
+
+ TLogEntry = Record
+ TimeStamp: TDateTime;
+ LogLevel: TLogLevel;
+ LogText: String;
+ End;
+
+ TLogEntryArray = Array Of TLogEntry;
+
+Var
+ (*
+ * Konfiguration des Loggers, Optional
+ *
+ * Ohne Konfiguration gelten folgende Einstellungen :
+ *
+ * Loglevel(2)
+ * Enable = True
+ * LogToFile = True
+ * LogToConsole = False
+ * FlushLogFileOnLog = True
+ * Logfilename = Exename mit Dateiendung ".log"
+ * DateFormat = 'YYYY.MM.DD HH:NN:SS'
+ *
+ *)
+ Logger: TLogger = Nil; // Wird Automatisch initialisiert und Freigegeben, dient nur dem Zugriff auf die Konfiguration
+
+ (*
+ * Diverse Log Funktionen f�r Basistypen, Wrapper f�r logger.XY
+ *)
+Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel: TLogLevel = llInfo); // Logt nur wenn "Criteria" = true
+Procedure Log(LogText: String; LogLevel: TLogLevel = llInfo); // -- Kann auch mit Mehrzeiligen Strings umgehen
+Procedure LogShow(LogText: String; LogLevel: TLogLevel = llInfo);
+Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Procedure LogInt(Value: Int32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Procedure LogUInt(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+
+Procedure LogLeave; // Wenn LogTraceStack Aktiviert, dann kann so der Stacktrace geloggt werden
+Procedure LogStack(LogLevel: TLogLevel = llinfo); // Wenn LogTraceStack Aktiviert, "Ende" einer Routine
+
+(*
+ * Sonstige
+ *)
+Function LogLevelToString(LogLevel: TLogLevel): String;
+Function LoadLogFile(Const Filename: String): TLogEntryArray;
+
+Implementation
+
+Uses sysutils,
+{$IFDEF USELCL}
+ FileUtil, LazFileUtils, lazutf8,
+{$ENDIF}
+ math;
+
+{$IFNDEF USELCL}
+
+Function utf8tosys(value: String): String;
+Begin
+ result := value;
+End;
+{$ENDIF}
+
+(*
+ * Umkehrfunktion zu FormatDateTime
+ * Die Implementierung ist nicht vollst�ndig, Erkennt aber ob die Konvertierung
+ * Fehlgeschlagen ist, wenn dem so ist, dann result := -1
+ *)
+// TODO: Diese Funktion hier k�nnte auch durch die "ScanDateTime" routine aus dateutil ersetzt werden.
+Function StrToDateTimeFormat(Input, Format: String): TDateTime;
+Var
+ y, m, d, h, n, s, z: String;
+ ip, fp: integer;
+ Block: Boolean;
+Begin
+ (*
+ * Die Idee ist den Input String gem�� dem Format String zu Parsen und alle
+ * Formatstring Tokens in den einzelnen Container zu sammeln.
+ * Dann wird Konvertiert und mittels anschlie�ender R�ckkonvertierung
+ * gepr�ft ob alles geklappt hat *g*.
+ *)
+ // Der Formatstring muss mindestens so lang sein wie der Eingabestring.
+ If length(Format) < length(Input) Then Begin
+ Result := -1;
+ exit;
+ End;
+ y := '';
+ m := '';
+ d := '';
+ h := '';
+ n := '';
+ s := '';
+ z := '';
+ Block := FALSE;
+ Format := lowercase(Format);
+ ip := 1;
+ fp := 1;
+ While fp <= length(Format) Do Begin
+ If Block Then Begin
+ If Format[fp] = '''' Then Begin
+ Block := FALSE;
+ inc(fp);
+ End
+ Else Begin
+ inc(fp);
+ inc(ip);
+ End;
+ End
+ Else Begin
+ Case Format[fp] Of
+ '''': Begin
+ Block := true;
+ dec(ip);
+ End;
+ 'y': y := y + Input[ip];
+ 'm': m := m + Input[ip];
+ 'd': d := d + Input[ip];
+ 'h': h := h + Input[ip];
+ 'n': n := n + Input[ip];
+ 's': s := s + Input[ip];
+ 'z': z := z + Input[ip];
+ End;
+ inc(fp);
+ inc(ip);
+ End;
+ End;
+ // Sind die yy Daten nur als zweistellige Zahl vorhanden, dann auf 2000+ verschieben
+ If strtointdef(y, 0) < 2000 Then Begin
+ y := IntToStr(strtointdef(y, 0) + 2000);
+ End;
+ Try
+ Result := EncodeDate(strtointdef(y, 0), strtointdef(m, 0), strtointdef(d, 0)) + EncodeTime(strtointdef(h, 0), strtointdef(n, 0), strtointdef(s, 0), strtointdef(z, 0));
+ Except
+ Result := -1;
+ exit;
+ End;
+ // Wenn alles geklappt hat, muss sich die Inverse wieder bilden lassen ;)
+ z := FormatDateTime(Format, Result);
+ If lowercase(FormatDateTime(Format, Result)) <> lowercase(Input) Then Begin
+ Result := -1;
+ End;
+End;
+
+Procedure LogLeave;
+Begin
+ If assigned(logger) Then
+ logger.LogLeave;
+End;
+
+Procedure LogStack(LogLevel: TLogLevel);
+Begin
+ If assigned(logger) Then
+ logger.LogStack(loglevel);
+End;
+
+Function LogLevelToString(LogLevel: TLogLevel): String;
+Begin
+ result := 'unkn.';
+ Case LogLevel Of
+ llTrace: result := 'Trace';
+ lldebug: result := 'Debug';
+ llInfo: result := 'Info ';
+ llWarning: result := 'Warn ';
+ llError: result := 'Error';
+ llCritical: result := 'Crit ';
+ llFatal: result := 'Fatal';
+ End;
+End;
+
+Function StrToLogLevel(LogLevel: String): TLogLevel;
+Begin
+ result := llFatal;
+ Case LogLevel Of
+ 'Trace': result := llTrace;
+ 'Debug': result := lldebug;
+ 'Info ': result := llInfo;
+ 'Warn ': result := llWarning;
+ 'Error': result := llError;
+ 'Crit ': result := llCritical;
+ 'Fatal': result := llFatal;
+ End;
+End;
+
+Function LoadLogFile(Const Filename: String): TLogEntryArray;
+Var
+ s: String;
+ sl: TStringList;
+ cnt, i: Integer;
+Begin
+ result := Nil;
+ {$IFDEF USELCL}
+ If FileExistsutf8(Filename) Then Begin
+ {$ELSE}
+ If FileExists(Filename) Then Begin
+ {$ENDIF}
+ // Gepuffertes Laden des Logfiles, so kann das Logfile w�hrend des neu ladens weiter beschrieben werden.
+ {$IFDEF USELCL}
+ s := GetTempFileNameUTF8(GetTempDir(), '');
+ {$ELSE}
+ s := GetTempFileName(GetTempDir(), '');
+ {$ENDIF}
+ sl := TStringList.Create;
+ {$IFDEF USELCL}
+ If CopyFile(utf8tosys(filename), utf8tosys(s), false, false) Then Begin
+ sl.LoadFromFile(s);
+ If Not DeleteFileUTF8(s) Then Begin
+ {$ELSE}
+ // For non-LCL builds, directly load the file
+ sl.LoadFromFile(filename);
+ Begin
+ // Dummy block for compatibility
+ If False Then Begin
+ {$ENDIF}
+{$IFDEF USELCL}
+ showmessage('Error on deleting temporary file : ' + s);
+{$ELSE}
+ writeln('Error on deleting temporary file : ' + s);
+{$ENDIF}
+ End;
+ End;
+ End
+ Else Begin
+ sl.LoadFromFile(Filename);
+ End;
+ // Laden der Eintr�ge
+ setlength(result, sl.Count);
+ cnt := 0;
+ i := 0;
+ While i < sl.count Do Begin
+ s := sl[i];
+ If trim(s) <> '' Then Begin
+ If s[26] = '|' Then Begin // Der Begin eines Einziligen Logs
+ result[cnt].TimeStamp := StrToDateTimeFormat(copy(s, 1, 19), Logger.fDateFormat);
+ result[cnt].Loglevel := StrToLogLevel(copy(s, 21, 5));
+ result[cnt].LogText := copy(s, 27, length(s));
+ inc(cnt);
+ End
+ Else Begin // Ein Mehrzeiliger Log
+ If cnt = 0 Then Begin
+{$IFDEF USELCL}
+ showmessage('Error invalid .log file.');
+{$ELSE}
+ writeln('Error invalid .log file.');
+{$ENDIF}
+ setlength(result, 0);
+ sl.free;
+ exit;
+ End;
+{$IFDEF Linux}
+ result[cnt - 1].Logtext := result[cnt - 1].Logtext + LineEnding + copy(s, 27, length(s));
+{$ELSE}
+ // Auf Windows kann die Listview kein CRT in den Zellen Darstellen, leider :(
+ result[cnt - 1].Logtext := result[cnt - 1].Logtext + ' ' + copy(s, 27, length(s));
+{$ENDIF}
+ End;
+ End;
+ inc(i);
+ End;
+ setlength(result, cnt);
+ sl.free;
+End;
+
+Procedure AssertLog(Criteria: Boolean; LogText: String; LogLevel: TLogLevel);
+Begin
+ logger.AssertLog(Criteria, LogText, LogLevel);
+End;
+
+Procedure Log(LogText: String; LogLevel: TLogLevel = llInfo);
+Begin
+ logger.Log(LogText, LogLevel);
+End;
+
+Procedure LogShow(LogText: String; LogLevel: TLogLevel);
+Begin
+ logger.LogShow(LogText, LogLevel);
+End;
+
+Procedure LogBool(Value: Boolean; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Begin
+ logger.LogBool(value, Description, LogLevel);
+End;
+
+Procedure LogInt(Value: Int32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Begin
+ logger.LogInt(value, Description, LogLevel);
+End;
+
+Procedure LoguInt(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Begin
+ logger.LoguInt(value, Description, LogLevel);
+End;
+
+Procedure LogHex(Value: uInt32; Description: String = ''; LogLevel: TLogLevel = llInfo);
+Begin
+ logger.LogHex(value, Description, LogLevel);
+End;
+
+{ TLogger }
+
+Constructor TLogger.Create;
+Begin
+ Inherited create;
+ fAddRoutineNameToLogs := true;
+ fCheckMaxStackDepth := 100;
+ fCheckStackBoundaries := false;
+ fMaxStackDepth := 0;
+ fHaltOnFatal := false;
+ fAutoLogStackOnFatal := false;
+ fStack := TStringList.Create;
+ fLogStackTrace := false;
+ fFilename := '';
+ Enable := True;
+ SetLogFilename(ChangeFileExt(ParamStr(0), '.log'));
+ SetLogLevel(2);
+ flogfileisopened := false;
+ fFlushLogFileOnLog := true;
+ FDateFormat := 'YYYY.MM.DD HH:NN:SS';
+ fLogToConsole := false;
+ flogtoFile := true;
+End;
+
+Destructor TLogger.Destroy;
+Begin
+ fStack.free;
+ CloseLogFile(true);
+End;
+
+Procedure TLogger.CloseLogFile(Force: Boolean);
+Begin
+ If (Force Or fFlushLogFileOnLog) And flogfileisopened Then Begin
+ CloseFile(FLogFile);
+ flogfileisopened := false;
+ End;
+End;
+
+Function TLogger.CreateLog(Logtext: String; Const Loglevel: TLogLevel): String;
+Var
+ s, t: String;
+ i: integer;
+Begin
+ If fAddRoutineNameToLogs And fLogStackTrace And (loglevel <> lltrace) Then Begin
+ If fStack.Count > 0 Then Begin
+ Logtext := fstack[fStack.Count - 1] + ': ' + Logtext;
+ End;
+ End;
+ // Evtl. Vorkommende Steuerzeichen in CRT's umwandeln
+ Logtext := StringReplace(Logtext, '\n', LineEnding, [rfReplaceAll, rfIgnoreCase]);
+ If pos(LineEnding, Logtext) <> 0 Then Begin
+ Logtext := TrimRight(Logtext);
+ // 1. Zeile mit Header
+ s := FormatDateTime(FDateFormat, now) + '|' + LogLevelToString(Loglevel) + '|';
+ result := s;
+ For i := 1 To length(s) Do Begin
+ s[i] := ' ';
+ End;
+ Logtext := Logtext + LineEnding;
+ While Logtext <> '' Do Begin
+ t := copy(Logtext, 1, pos(LineEnding, Logtext) - 1);
+ delete(Logtext, 1, length(t) + length(LineEnding));
+ result := result + t;
+ If Logtext <> '' Then
+ result := result + LineEnding + s;
+ End;
+ End
+ Else Begin
+ result := FormatDateTime(FDateFormat, now) + '|' + LogLevelToString(Loglevel) + '|' + Logtext;
+ End;
+End;
+
+Procedure TLogger.Log(LogText: String; LogLevel_: TLogLevel);
+Begin
+ If Not assigned(self) Then exit; // Wenn sich der Logger selbst killt via halt, dann wird er freigegeben bevor er fertig ist.
+ If Not FEnable Then exit;
+ If loglevel_ In fLogLevel Then Begin
+ OpenLogFile;
+ DoLog(CreateLog(Logtext, Loglevel_));
+ If fAutoLogStackOnFatal And (LogLevel_ = llFatal) Then Begin
+ DoLog(CreateLog(StackLog(), Loglevel_));
+ End;
+ CloseLogFile(false);
+ End;
+ // Wenn ein Stacktrace geschrieben werden soll, dann
+ If fLogStackTrace And (LogLevel_ = llTrace) Then Begin
+ fStack.Add(LogText);
+ fMaxStackDepth := max(fMaxStackDepth, fstack.Count);
+ If fstack.count > fCheckMaxStackDepth Then Begin
+ log('Stack overflow.', llfatal);
+ End;
+ End;
+ // Halt on Fatal
+ If fHaltOnFatal And (loglevel_ = llFatal) Then Begin
+ fstack.Clear; // Wir beenden via Gewalt, also Stack auch L�schen, wenn dann wurde er eh schon geloggt.
+ CloseLogFile(true);
+ halt(1);
+ End;
+End;
+
+Procedure TLogger.LogShow(LogText: String; LogLevel_: TLogLevel);
+Begin
+{$IFDEF USELCL}
+ ShowMessage(LogLevelToString(LogLevel_) + ' : ' + LogText);
+{$ELSE}
+ writeln(LogLevelToString(LogLevel_) + ' : ' + LogText);
+{$ENDIF}
+ If LogLevel_ In fLogLevel Then Begin
+ log(LogText, LogLevel_);
+ End;
+End;
+
+Procedure TLogger.LogBool(Value: Boolean; Description: String;
+ LogLevel_: TLogLevel);
+Begin
+ If value Then Begin
+ log(Description + ' = True ', LogLevel_);
+ End
+ Else Begin
+ log(Description + ' = False', LogLevel_);
+ End;
+End;
+
+Procedure TLogger.LogHex(Value: uInt32; Description: String; LogLevel_: TLogLevel
+ );
+Begin
+ log(Description + format(' = %0.8X', [value]), LogLevel_);
+End;
+
+Function TLogger.LoggerLogs(Const LogLevel_: TLogLevel): Boolean;
+Begin
+ result := LogLevel_ In fLogLevel;
+End;
+
+Procedure TLogger.LogInt(Value: Int32; Description: String; LogLevel_: TLogLevel
+ );
+Begin
+ log(Description + format(' = %d', [value]), LogLevel_);
+End;
+
+Procedure TLogger.LogLeave;
+Begin
+ If fLogStackTrace Then Begin
+ If (fstack.Count <> 0) Then Begin
+ fstack.Delete(fstack.Count - 1);
+ End
+ Else Begin
+ If fCheckStackBoundaries Then Begin
+ log('Stack underflow.', llfatal);
+ End;
+ End;
+ End;
+End;
+
+Function TLogger.StackLog: String;
+Var
+ i: integer;
+Begin
+ result := 'Stacktrace:' + LineEnding;
+ For I := 0 To fStack.Count - 1 Do Begin
+ result := result + ' ' + fstack[i] + LineEnding;
+ End;
+End;
+
+Procedure TLogger.LogStack(LogLevel_: TLogLevel);
+Begin
+ If fLogStackTrace And (LogLevel_ In fLogLevel) Then Begin
+ Log(StackLog(), LogLevel_);
+ End;
+End;
+
+Procedure TLogger.DoLog(Const Text: String);
+Begin
+ If flogfileisopened Then Begin // Wenn Keine datei ge�ffnet ist, kann auch nicht geschrieben werden.
+ writeln(FLogFile, Text);
+ End;
+ If fLogToConsole Then Begin // Wenn auch auf die Konsole ausgegeben werden soll
+ writeln(Text);
+ End;
+End;
+
+Procedure TLogger.LogUInt(Value: uInt32; Description: String;
+ LogLevel_: TLogLevel);
+Begin
+ log(Description + format(' = %u', [value]), LogLevel_);
+End;
+
+Procedure TLogger.OpenLogFile;
+Begin
+ If Not flogtoFile Then exit;
+ If Not flogfileisopened Then Begin
+ assignfile(FLogFile, utf8tosys(fFilename));
+ If FileExists(fFilename) Then Begin
+ append(FLogFile);
+ End
+ Else Begin
+ Rewrite(FLogFile);
+ End;
+ flogfileisopened := true;
+ End;
+End;
+
+Procedure TLogger.SetCustomLogging(Const LogLevel_: TLogLevelSet);
+Begin
+ fLogLevel := LogLevel_;
+End;
+
+Procedure TLogger.SetEnable(Const aValue: Boolean);
+Begin
+ If FEnable <> avalue Then Begin
+ FEnable := avalue;
+ If Not FEnable Then CloseLogFile(true);
+ End;
+End;
+
+Procedure TLogger.SetLogFilename(Const Filename: String);
+Begin
+ If (fFilename <> Filename) Then Begin
+ fFilename := Filename;
+ // Wird der Dateiname Ge�ndert, obwohl die Logdatei gerade ge�ffnet ist, muss die alte vorher geschlossen werden.
+ If flogfileisopened Then Begin
+ CloseLogFile(true);
+ End;
+ End;
+End;
+
+Procedure TLogger.AssertLog(Criteria: Boolean; LogText: String;
+ LogLevel_: TLogLevel);
+Begin
+ If Not assigned(self) Then exit;
+ If Not FEnable Then exit;
+ If Criteria Then Begin
+ Log(LogText, LogLevel_);
+ End
+ Else Begin
+ If fLogStackTrace And (loglevel_ = lltrace) Then Begin
+ fstack.Add(Logtext);
+ fMaxStackDepth := max(fMaxStackDepth, fstack.Count);
+ End;
+ End;
+End;
+
+Function TLogger.getLoglevel: integer;
+Begin
+ result := -1;
+ If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo, lldebug, llTrace] Then result := 0;
+ If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo, lldebug] Then result := 1;
+ If fLogLevel = [llFatal, llCritical, llError, llWarning, llInfo] Then result := 2;
+ If fLogLevel = [llFatal, llCritical, llError, llWarning] Then result := 3;
+ If fLogLevel = [llFatal, llCritical, llError] Then result := 4;
+ If fLogLevel = [llFatal, llCritical] Then result := 5;
+ If fLogLevel = [llFatal] Then result := 6;
+End;
+
+Procedure TLogger.SetLogLevel(Const Level: integer);
+Begin
+ Case level Of
+ 0: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo, lldebug, llTrace];
+ 1: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo, lldebug];
+ 2: fLogLevel := [llFatal, llCritical, llError, llWarning, llInfo];
+ 3: fLogLevel := [llFatal, llCritical, llError, llWarning];
+ 4: fLogLevel := [llFatal, llCritical, llError];
+ 5: fLogLevel := [llFatal, llCritical];
+ 6: fLogLevel := [llFatal]
+ Else
+ fLogLevel := []; // Undefiniert = Aus
+ End;
+End;
+
+Initialization
+ logger := TLogger.Create;
+
+Finalization
+ logger.Free;
+ logger := Nil;
+
+End.
+
diff --git a/units/uopengl_ascii_font.pas b/units/uopengl_ascii_font.pas
index 7d7bcfc..03d72e0 100644
--- a/units/uopengl_ascii_font.pas
+++ b/units/uopengl_ascii_font.pas
@@ -47,6 +47,11 @@
(* !! Gilt seit ver 0.02 nicht mehr !! *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit uOpenGL_ASCII_Font;
{$MODE ObjFPC}{$H+}
@@ -59,7 +64,11 @@
uvectormath, // http://corpsman.de/index.php?doc=opengl/opengl_graphikengine
LConvEncoding,
uopengl_font_common,
- math;
+ math
+{$IFDEF Windows}
+ , uearlylog // For debug logging on Windows
+{$ENDIF}
+ ;
Type
@@ -182,8 +191,18 @@
Begin
If Assigned(OpenGL_ASCII_Font) Then OpenGL_ASCII_Font.free;
Bitmap := TBitmap.Create;
- bitmap.LoadFromLazarusResource('OpenGLFont');
- OpenGL_ASCII_Font := TOpenGL_ASCII_Font.Create(bitmap, 8, 12, 256);
+ Try
+ bitmap.LoadFromLazarusResource('OpenGLFont');
+ OpenGL_ASCII_Font := TOpenGL_ASCII_Font.Create(bitmap, 8, 12, 256);
+ Except
+ On E: Exception Do Begin
+ // Log error but don't crash - font might not be critical
+ WriteLn('ERROR: Failed to load OpenGLFont resource: ', E.Message);
+ WriteLn('Font will not be available');
+ bitmap.Free;
+ exit;
+ End;
+ End;
bitmap.Free;
End;
@@ -285,9 +304,21 @@
light: Boolean;
// f: GLfloat; <-- Alte Variante mittels glPoints
currentColor: TVector4;
+ textureEnabled: Boolean;
Begin
// glGetFloatv(GL_POINT_SIZE, @f); // Bakup der Point Size, diese wird hier Verändert !! <-- Alte Variante mittels glPoints
light := glIsEnabled(GL_LIGHTING);
+ textureEnabled := glIsEnabled(GL_TEXTURE_2D);
+{$IFDEF Windows}
+ // Log OpenGL state on Windows for debugging (only for loading dialog text to avoid spam)
+ If (Pos('Loading', Text) > 0) Or (Pos('%', Text) > 0) Then Begin
+ Try
+ uearlylog.EarlyLog('Textout: Text="' + Text + '" x=' + IntToStr(x) + ' y=' + IntToStr(y) + ' GL_LIGHTING=' + BoolToStr(light, true) + ' GL_TEXTURE_2D=' + BoolToStr(textureEnabled, true));
+ Except
+ // Ignore errors in logging - don't crash the app
+ End;
+ End;
+{$ENDIF}
If light Then Begin
glDisable(GL_LIGHTING); // Deaktivieren der Beleuchtung, die können wir hier nun wirklich nicht gebrauchen..
End;
diff --git a/units/uopengl_graphikengine.pas b/units/uopengl_graphikengine.pas
index 6156e59..7b656d0 100644
--- a/units/uopengl_graphikengine.pas
+++ b/units/uopengl_graphikengine.pas
@@ -42,6 +42,11 @@
(* transparency *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit uopengl_graphikengine;
{$IFDEF FPC}
@@ -1264,12 +1269,14 @@
OpenGLData[c, 0] := CurColor.Red Div 256;
OpenGLData[c, 1] := CurColor.green Div 256;
OpenGLData[c, 2] := CurColor.blue Div 256;
- If (OpenGLData[c, 0] = Color.r) And
- (OpenGLData[c, 1] = Color.g) And
- (OpenGLData[c, 2] = Color.b) Then
- OpenGLData[c, 3] := 255
+ // Chroma key with tolerance to handle edge artifacts (e.g., FE00FE vs FF00FF)
+ // Tolerance: ±2 for each RGB component to handle compression/antialiasing artifacts
+ If (Abs(OpenGLData[c, 0] - Color.r) <= 2) And
+ (Abs(OpenGLData[c, 1] - Color.g) <= 2) And
+ (Abs(OpenGLData[c, 2] - Color.b) <= 2) Then
+ OpenGLData[c, 3] := 255 // Fully transparent
Else
- OpenGLData[c, 3] := 0;
+ OpenGLData[c, 3] := 0; // Fully opaque
inc(c);
End;
End;
@@ -1601,12 +1608,15 @@
OpenGLData[c, 3] := 255 - AlphaMask[i, j];
End
Else Begin
- If (OpenGLData[c, 0] = Fuchsia.r) And
- (OpenGLData[c, 1] = Fuchsia.g) And
- (OpenGLData[c, 2] = Fuchsia.b) Then
- OpenGLData[c, 3] := 255
+ // Chroma key with tolerance to remove magenta/fuchsia border artifacts
+ // Check if pixel is close enough to fuchsia (magenta) to be considered transparent
+ // Tolerance: ±10 for each RGB component to handle antialiasing and compression artifacts
+ If (Abs(OpenGLData[c, 0] - Fuchsia.r) <= 10) And
+ (Abs(OpenGLData[c, 1] - Fuchsia.g) <= 10) And
+ (Abs(OpenGLData[c, 2] - Fuchsia.b) <= 10) Then
+ OpenGLData[c, 3] := 255 // Fully transparent
Else
- OpenGLData[c, 3] := 0;
+ OpenGLData[c, 3] := 0; // Fully opaque
End;
inc(c);
End;
diff --git a/units/usdl_gamecontroller.pas b/units/usdl_gamecontroller.pas
new file mode 100644
index 0000000..b721670
--- /dev/null
+++ b/units/usdl_gamecontroller.pas
@@ -0,0 +1,209 @@
+Unit usdl_gamecontroller;
+
+{$MODE objfpc}{$H+}
+
+Interface
+
+Uses
+ Classes, SysUtils,
+ sdl2;
+
+Type
+
+ { TSDL_GameControllerEx }
+
+ TSDL_GameControllerEx = class
+ private
+ fJoy: PSDL_Joystick;
+ public
+ constructor Create(Index: Integer);
+ destructor Destroy; override;
+ function IsAttached: Boolean;
+ // Axes (normalized GameController axes)
+ function AxisLeftX: Integer; // -32768 .. 32767
+ function AxisLeftY: Integer; // -32768 .. 32767
+ // D-Pad
+ function DpadUp: Boolean;
+ function DpadDown: Boolean;
+ function DpadLeft: Boolean;
+ function DpadRight: Boolean;
+ // Buttons
+ function ButtonX: Boolean; // Primary as requested
+ function ButtonSquare: Boolean; // Secondary as requested (on PlayStation layout)
+ end;
+
+// Helpers
+function DetectGameControllerIndices(MaxCount: Integer; out idx0, idx1: Integer): Boolean;
+
+Implementation
+
+constructor TSDL_GameControllerEx.Create(Index: Integer);
+begin
+ inherited Create;
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) and SDL_INIT_JOYSTICK) = 0 then begin
+ raise Exception.Create('SDL Joystick subsystem not initialized.');
+ end;
+ SDL_JoystickEventState(SDL_ENABLE);
+ fJoy := SDL_JoystickOpen(Index);
+ if not Assigned(fJoy) then begin
+ raise Exception.Create('Could not open SDL Joystick for controller wrapper.');
+ end;
+end;
+
+destructor TSDL_GameControllerEx.Destroy;
+begin
+ if Assigned(fJoy) then begin
+ SDL_JoystickClose(fJoy);
+ fJoy := nil;
+ end;
+ inherited Destroy;
+end;
+
+function TSDL_GameControllerEx.IsAttached: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ Result := SDL_JoystickGetAttached(fJoy) = SDL_TRUE;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.AxisLeftX: Integer;
+begin
+ if not Assigned(fJoy) then exit(0);
+ try
+ // Common mapping: axis 0 = left stick X
+ Result := SDL_JoystickGetAxis(fJoy, 0);
+ except
+ Result := 0;
+ end;
+end;
+
+function TSDL_GameControllerEx.AxisLeftY: Integer;
+begin
+ if not Assigned(fJoy) then exit(0);
+ try
+ // Common mapping: axis 1 = left stick Y
+ Result := SDL_JoystickGetAxis(fJoy, 1);
+ except
+ Result := 0;
+ end;
+end;
+
+function TSDL_GameControllerEx.DpadUp: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ // Prefer hat if present
+ if SDL_JoystickNumHats(fJoy) > 0 then begin
+ Result := (SDL_JoystickGetHat(fJoy, 0) and SDL_HAT_UP) <> 0;
+ end else begin
+ // Fallback: treat stick Y negative as up with threshold
+ Result := AxisLeftY < -12000;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.DpadDown: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ if SDL_JoystickNumHats(fJoy) > 0 then begin
+ Result := (SDL_JoystickGetHat(fJoy, 0) and SDL_HAT_DOWN) <> 0;
+ end else begin
+ Result := AxisLeftY > 12000;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.DpadLeft: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ if SDL_JoystickNumHats(fJoy) > 0 then begin
+ Result := (SDL_JoystickGetHat(fJoy, 0) and SDL_HAT_LEFT) <> 0;
+ end else begin
+ Result := AxisLeftX < -12000;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.DpadRight: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ if SDL_JoystickNumHats(fJoy) > 0 then begin
+ Result := (SDL_JoystickGetHat(fJoy, 0) and SDL_HAT_RIGHT) <> 0;
+ end else begin
+ Result := AxisLeftX > 12000;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.ButtonX: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ // PlayStation layout: Button 0 = X (bottom), Button 1 = Circle, Button 2 = Square, Button 3 = Triangle
+ // Xbox layout: Button 0 = A, Button 1 = B, Button 2 = X, Button 3 = Y
+ // Try both common mappings: PlayStation X is button 0, Xbox A (equivalent) is also button 0
+ if SDL_JoystickNumButtons(fJoy) > 0 then begin
+ Result := SDL_JoystickGetButton(fJoy, 0) = SDL_PRESSED;
+ end else begin
+ Result := false;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function TSDL_GameControllerEx.ButtonSquare: Boolean;
+begin
+ if not Assigned(fJoy) then exit(false);
+ try
+ // PlayStation layout: Square is button 2
+ // Xbox layout: X button is button 2 (equivalent position)
+ if SDL_JoystickNumButtons(fJoy) > 2 then begin
+ Result := SDL_JoystickGetButton(fJoy, 2) = SDL_PRESSED;
+ end else begin
+ Result := false;
+ end;
+ except
+ Result := false;
+ end;
+end;
+
+function DetectGameControllerIndices(MaxCount: Integer; out idx0, idx1: Integer): Boolean;
+var
+ i, found: Integer;
+begin
+ idx0 := -1;
+ idx1 := -1;
+ found := 0;
+ for i := 0 to SDL_NumJoysticks() - 1 do begin
+ // Without SDL_GameController API available, consider any joystick as candidate controller
+ if found = 0 then begin
+ idx0 := i;
+ inc(found);
+ end else if (found = 1) then begin
+ idx1 := i;
+ inc(found);
+ break;
+ end;
+ if (MaxCount > 0) and (found >= MaxCount) then break;
+ end;
+ Result := idx0 <> -1;
+end;
+
+end.
+
+
diff --git a/units/usdl_joystick.pas b/units/usdl_joystick.pas
index b3a1b56..0fd6951 100644
--- a/units/usdl_joystick.pas
+++ b/units/usdl_joystick.pas
@@ -1,129 +1,164 @@
-(******************************************************************************)
-(* SDL Joystick wrapper by Corpsman 2020.04.21 *)
-(* *)
-(* Version : 0.01 *)
-(* *)
-(* Author : Uwe Schächterle (Corpsman) *)
-(* *)
-(* Support : www.Corpsman.de *)
-(* *)
-(* Description : SDL2 Wrapper for joysticks *)
-(* *)
-(* License : See the file license.md, located under: *)
-(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
-(* for details about the license. *)
-(* *)
-(* It is not allowed to change or remove this text from any *)
-(* source file of the project. *)
-(* *)
-(* Warranty : There is no warranty, neither in correctness of the *)
-(* implementation, nor anything other that could happen *)
-(* or go wrong, use at your own risk. *)
-(* *)
-(* Known Issues: none *)
-(* *)
-(* History : 0.01 - Initial version *)
-(* *)
-(******************************************************************************)
-Unit usdl_joystick;
-
-{$MODE objfpc}{$H+}
-
-Interface
-
-(*
- * Wenn es nicht Compiliert, hift ein
- *
- * sudo aptitude install libsdl2-dev
- *)
-
-Uses
- Classes, SysUtils
- , sdl2
- ;
-
-Type
-
- { TSDL_Joystick }
-
- TSDL_Joystick = Class
- private
- fAxisCount: integer;
- fButtonCount: integer;
- fInstance: Pointer;
- Function GetAxisValue(index: integer): integer;
- Function GetButtonValue(index: integer): boolean;
- public
- Property ButtonCount: integer read fButtonCount;
- Property Button[index: integer]: boolean read GetButtonValue;
-
- Property AxisCount: integer read fAxisCount;
- Property Axis[index: integer]: integer read GetAxisValue; // ranging from -32768 to 32767
-
- Constructor Create(Index: integer);
- Destructor Destroy; override;
- End;
-
-Function ResolveJoystickNameToIndex(Const aName: String; aIndex: integer = 0): integer; // -1 wenn nicht gefunden
-
-Implementation
-
-Function ResolveJoystickNameToIndex(Const aName: String; aIndex: integer): integer;
-Var
- index, i: Integer;
- s: String;
-Begin
- result := -1;
- index := 0;
- If aname = '' Then exit;
- For i := 0 To SDL_NumJoysticks() - 1 Do Begin
- s := SDL_JoystickNameForIndex(i);
- If (aName = s) Then Begin
- result := i;
- If aIndex = index Then Begin
- exit;
- End
- Else Begin
- inc(index);
- End;
- End;
- End;
-End;
-
-{ TSDL_Joystick }
-
-Function TSDL_Joystick.GetAxisValue(index: integer): integer;
-Begin
- result := SDL_JoystickGetAxis(fInstance, index);
-End;
-
-Function TSDL_Joystick.GetButtonValue(index: integer): boolean;
-Begin
- result := SDL_JoystickGetButton(fInstance, index) = SDL_PRESSED;
-End;
-
-Constructor TSDL_Joystick.Create(Index: integer);
-Begin
- Inherited create;
- If (SDL_WasInit(SDL_INIT_JOYSTICK) And SDL_INIT_JOYSTICK) = 0 Then Begin
- Raise Exception.create('Error SDL subsystem for joystick is not initialized.');
- End;
- SDL_JoystickEventState(SDL_ENABLE);
- fInstance := SDL_JoystickOpen(Index);
- If Not assigned(fInstance) Then Begin
- Raise Exception.create('Error could not create joystick instance.');
- End;
- fAxisCount := SDL_JoystickNumAxes(fInstance);
- fButtonCount := SDL_JoystickNumButtons(fInstance);
-End;
-
-Destructor TSDL_Joystick.Destroy;
-Begin
- If assigned(fInstance) Then Begin
- SDL_JoystickClose(fInstance);
- fInstance := Nil;
- End;
-End;
-
-End.
-
+(******************************************************************************)
+(* SDL Joystick wrapper by Corpsman 2020.04.21 *)
+(* *)
+(* Version : 0.01 *)
+(* *)
+(* Author : Uwe Schächterle (Corpsman) *)
+(* *)
+(* Support : www.Corpsman.de *)
+(* *)
+(* Description : SDL2 Wrapper for joysticks *)
+(* *)
+(* License : See the file license.md, located under: *)
+(* https://github.com/PascalCorpsman/Software_Licenses/blob/main/license.md *)
+(* for details about the license. *)
+(* *)
+(* It is not allowed to change or remove this text from any *)
+(* source file of the project. *)
+(* *)
+(* Warranty : There is no warranty, neither in correctness of the *)
+(* implementation, nor anything other that could happen *)
+(* or go wrong, use at your own risk. *)
+(* *)
+(* Known Issues: none *)
+(* *)
+(* History : 0.01 - Initial version *)
+(* *)
+(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
+Unit usdl_joystick;
+
+{$MODE objfpc}{$H+}
+
+Interface
+
+(*
+ * Wenn es nicht Compiliert, hift ein
+ *
+ * sudo aptitude install libsdl2-dev
+ *)
+
+Uses
+ Classes, SysUtils
+ , sdl2
+ ;
+
+Type
+
+ { TSDL_Joystick }
+
+ TSDL_Joystick = Class
+ private
+ fAxisCount: integer;
+ fButtonCount: integer;
+ fHatCount: integer;
+ fInstance: Pointer;
+ Function GetAxisValue(index: integer): integer;
+ Function GetButtonValue(index: integer): boolean;
+ Function GetHatValue(index: integer): byte;
+ public
+ Property ButtonCount: integer read fButtonCount;
+ Property Button[index: integer]: boolean read GetButtonValue;
+
+ Property AxisCount: integer read fAxisCount;
+ Property Axis[index: integer]: integer read GetAxisValue; // ranging from -32768 to 32767
+
+ Property HatCount: integer read fHatCount;
+ Property Hat[index: integer]: byte read GetHatValue;
+
+ Constructor Create(Index: integer);
+ Destructor Destroy; override;
+ End;
+
+Function ResolveJoystickNameToIndex(Const aName: String; aIndex: integer = 0): integer; // -1 wenn nicht gefunden
+
+Implementation
+
+Function ResolveJoystickNameToIndex(Const aName: String; aIndex: integer): integer;
+Var
+ index, i: Integer;
+ s: String;
+Begin
+ result := -1;
+ index := 0;
+ If aname = '' Then exit;
+ For i := 0 To SDL_NumJoysticks() - 1 Do Begin
+ s := SDL_JoystickNameForIndex(i);
+ If (aName = s) Then Begin
+ result := i;
+ If aIndex = index Then Begin
+ exit;
+ End
+ Else Begin
+ inc(index);
+ End;
+ End;
+ End;
+End;
+
+{ TSDL_Joystick }
+
+Function TSDL_Joystick.GetAxisValue(index: integer): integer;
+Begin
+ // Defensive: avoid out-of-range or nil access
+ If (Not Assigned(fInstance)) Or (index < 0) Or (index >= fAxisCount) Then Begin
+ result := 0;
+ exit;
+ End;
+ result := SDL_JoystickGetAxis(fInstance, index);
+End;
+
+Function TSDL_Joystick.GetButtonValue(index: integer): boolean;
+Begin
+ If (Not Assigned(fInstance)) Or (index < 0) Or (index >= fButtonCount) Then Begin
+ result := false;
+ exit;
+ End;
+ result := SDL_JoystickGetButton(fInstance, index) = SDL_PRESSED;
+End;
+
+Function TSDL_Joystick.GetHatValue(index: integer): byte;
+Begin
+ // Defensive: avoid out-of-range or nil access
+ If (Not Assigned(fInstance)) Or (index < 0) Or (index >= fHatCount) Then Begin
+ result := SDL_HAT_CENTERED;
+ exit;
+ End;
+ try
+ result := SDL_JoystickGetHat(fInstance, index);
+ except
+ result := SDL_HAT_CENTERED;
+ end;
+End;
+
+Constructor TSDL_Joystick.Create(Index: integer);
+Begin
+ Inherited create;
+ fInstance := SDL_JoystickOpen(Index);
+ If Not assigned(fInstance) Then Begin
+ Raise Exception.Create('Error, could not open Joystick : ' + inttostr(index));
+ End;
+ SDL_JoystickEventState(SDL_ENABLE);
+ fAxisCount := SDL_JoystickNumAxes(fInstance);
+ fButtonCount := SDL_JoystickNumButtons(fInstance);
+ try
+ fHatCount := SDL_JoystickNumHats(fInstance);
+ except
+ fHatCount := 0;
+ end;
+End;
+
+Destructor TSDL_Joystick.Destroy;
+Begin
+ If assigned(fInstance) Then Begin
+ SDL_JoystickClose(fInstance);
+ fInstance := Nil;
+ End;
+End;
+
+End.
+
diff --git a/units/usynapsedownloader.pas b/units/usynapsedownloader.pas
index 510d440..a8de426 100644
--- a/units/usynapsedownloader.pas
+++ b/units/usynapsedownloader.pas
@@ -24,8 +24,14 @@
(* Known Issues: none *)
(* *)
(* History : 0.01 - Initial version *)
+(* 0.02 - Replaced synapse with fphttpclient (2024-12-05) *)
(* *)
(******************************************************************************)
+(* *)
+(* Modified by : Pavel Zverina *)
+(* Note : This file has been modified while preserving the original *)
+(* authorship and license terms. *)
+(* *)
Unit usynapsedownloader;
{$MODE ObjFPC}{$H+}
@@ -33,7 +39,7 @@
Interface
Uses
- Classes, SysUtils, blcksock, httpsend, synautil;
+ Classes, SysUtils, fphttpclient, URIParser;
Type
@@ -43,9 +49,9 @@
TSynapesDownloader = Class
private
- fInstance: THTTPSend;
+ fClient: TFPHTTPClient;
aTotalSize, aFileSize: int64;
- Procedure OnHookSocketStatus(Sender: TObject; Reason: THookSocketReason; Const Value: String);
+ Procedure OnDataReceived(Sender: TObject; Const ContentLength, CurrentPos: Int64);
public
OnFileDownloadUpdateEvent: TOnFileDownloadUpdateEvent;
@@ -58,89 +64,18 @@
Implementation
Uses
- ssl_openssl;
-
-(*
- * Verfolgt 302 und 301 Weiterleitungen
- *)
-
-Procedure Follow_Links(Connection: THTTPSend; BaseURL: String);
- Function ExtractBaseURL(U: String): String;
- Var
- Prot, User, Pass, Host, Port, Path, Para: String;
- Begin
- Prot := '';
- User := '';
- Pass := '';
- Host := '';
- Port := '';
- Path := '';
- Para := '';
- ParseURL(u, Prot, User, Pass, Host, Port, Path, Para);
- result := Prot + '://' + host + '/';
- End;
-Var
- t: String;
- timeout, i: Integer;
-Begin
- If BaseURL = '' Then exit;
- BaseURL := ExtractBaseURL(BaseURL);
- timeout := 20;
- While ((Connection.ResultCode = 303) Or (Connection.ResultCode = 302) Or (Connection.ResultCode = 301)) And (timeout >= 0) Do Begin
- dec(timeout);
- t := '';
- For i := 0 To Connection.Headers.Count - 1 Do Begin
- If pos('location', lowercase(Connection.Headers[i])) <> 0 Then Begin
- t := Connection.Headers[i];
- t := copy(t, pos(':', t) + 1, length(t));
- t := trim(t);
- If pos('http', lowercase(t)) = 0 Then Begin
- If t[1] = '/' Then delete(t, 1, 1);
- t := BaseURL + t;
- End;
- Connection.Headers.Clear;
- Connection.Document.Clear;
- BaseURL := ExtractBaseURL(t);
- Connection.HTTPMethod('GET', t);
- break;
- End;
- End;
- If t = '' Then Begin
- // das Location feld konnte im Header nicht gefunden werden.
- exit;
- End;
- End;
-End;
+ LazFileUtils;
{ TSynapesDownloader }
-Procedure TSynapesDownloader.OnHookSocketStatus(Sender: TObject;
- Reason: THookSocketReason; Const Value: String);
-Var
- i: Integer;
- s: String;
- sa: TStringArray;
+Procedure TSynapesDownloader.OnDataReceived(Sender: TObject; Const ContentLength, CurrentPos: Int64);
Begin
- If Not assigned(fInstance) Then exit;
- If aTotalSize = 0 Then Begin
- // Read Filesize from Header
- For i := 0 To fInstance.Headers.Count - 1 Do Begin
- s := fInstance.Headers[i];
- If pos('Content-Length:', s) <> 0 Then Begin
- sa := s.Split(':');
- If length(sa) = 2 Then Begin
- aTotalSize := StrToInt64Def(trim(sa[1]), 0);
- End;
+ If ContentLength > 0 Then Begin
+ aTotalSize := ContentLength;
End;
- End;
- End
- Else Begin
- If Reason = HR_ReadCount Then Begin
- aFileSize := aFileSize + StrToInt64Def(value, 0);
+ aFileSize := CurrentPos;
If assigned(OnFileDownloadUpdateEvent) Then Begin
OnFileDownloadUpdateEvent(self, aFileSize, aTotalSize);
- End;
- End;
End;
End;
@@ -148,84 +83,78 @@
Begin
Inherited Create;
OnFileDownloadUpdateEvent := Nil;
+ fClient := Nil;
+ aTotalSize := 0;
+ aFileSize := 0;
End;
Destructor TSynapesDownloader.Destroy;
Begin
-
+ If assigned(fClient) Then Begin
+ fClient.Free;
+ fClient := Nil;
+ End;
+ Inherited Destroy;
End;
-Function TSynapesDownloader.DownloadFile(URL: String; Filename: String
- ): Boolean;
+Function TSynapesDownloader.DownloadFile(URL: String; Filename: String): Boolean;
Var
f: TFileStream;
- s, dir: String;
+ dir: String;
+ RedirectCount: Integer;
+ FinalURL: String;
Begin
result := false;
- If assigned(fInstance) Then fInstance.free;
- fInstance := Nil;
+ aTotalSize := 0;
+ aFileSize := 0;
+
If FileExists(Filename) Then Begin
If Not DeleteFile(Filename) Then Begin
Raise exception.create('Error, unable to delete old file: ' + Filename);
exit;
End;
End;
- aTotalSize := 0;
- aFileSize := 0;
- fInstance := THTTPSend.Create;
-
- // TODO: Proxy support ?
- //fInstance.ProxyHost := ProxyHost;
- //fInstance.ProxyPass := ProxyPass;
- //fInstance.ProxyPort := ProxyPort;
- //fInstance.ProxyUser := ProxyUser;
-
- fInstance.Sock.OnStatus := @OnHookSocketStatus;
- If Not fInstance.HTTPMethod('GET', url) Then Begin
- s :=
- '\-fInstance.ResultCode: ' + inttostr(fInstance.ResultCode) + ' ; ' + fInstance.ResultString + LineEnding +
- '\-fInstance.Sock.LastError: ' + inttostr(fInstance.Sock.LastError) + ' ; ' + fInstance.Sock.LastErrorDesc + LineEnding +
- '\-fInstance.Sock.SSL.LastError: ' + inttostr(fInstance.Sock.SSL.LastError) + ' ; ' + fInstance.Sock.SSL.LastErrorDesc;
- fInstance.free;
- fInstance := Nil;
- Raise Exception.Create(s);
- exit;
- End;
- Follow_Links(fInstance, url);
- If fInstance.Document.Size <> 0 Then Begin
- // Fertig melden, hat ja wohl geklappt ;)
- If assigned(OnFileDownloadUpdateEvent) Then Begin
- OnFileDownloadUpdateEvent(self, aTotalSize, aTotalSize);
- End;
dir := ExtractFileDir(Filename);
If dir <> '' Then Begin
If Not ForceDirectories(dir) Then Begin
- s := 'Error, could not create: ' + ExtractFileDir(Filename);
- fInstance.free;
- fInstance := Nil;
- Raise Exception.Create(s);
+ Raise Exception.Create('Error, could not create: ' + dir);
exit;
End;
End;
+
+ fClient := TFPHTTPClient.Create(Nil);
+ Try
+ fClient.OnDataReceived := @OnDataReceived;
+ fClient.AllowRedirect := true;
+ fClient.MaxRedirects := 20; // Follow up to 20 redirects
+
+ // Handle redirects manually if needed
+ FinalURL := URL;
+ RedirectCount := 0;
+
Try
- f := TFileStream.Create(Filename, fmOpenWrite Or fmCreate);
- f.CopyFrom(fInstance.Document, fInstance.Document.Size);
- f.Free;
+ f := TFileStream.Create(Filename, fmCreate);
+ Try
+ fClient.Get(FinalURL, f);
result := true;
- Except
- On av: Exception Do Begin
- fInstance.free;
- fInstance := Nil;
+ // Final progress update
+ If assigned(OnFileDownloadUpdateEvent) Then Begin
+ OnFileDownloadUpdateEvent(self, aFileSize, aTotalSize);
+ End;
+ Finally
f.Free;
- Raise;
- exit;
+ End;
+ Except
+ On E: Exception Do Begin
+ If assigned(f) Then f.Free;
+ Raise Exception.Create('Error downloading file: ' + E.Message);
End;
End;
+ Finally
+ fClient.Free;
+ fClient := Nil;
End;
- fInstance.free;
- fInstance := Nil;
End;
End.
-
diff --git a/units/uthreadsafequeue.pas b/units/uthreadsafequeue.pas
new file mode 100644
index 0000000..f3756db
--- /dev/null
+++ b/units/uthreadsafequeue.pas
@@ -0,0 +1,110 @@
+(******************************************************************************)
+(* *)
+(* Author : AI Assistant + Corpsman Base Code *)
+(* *)
+(* This file is part of FPC_Atomic *)
+(* *)
+(* Description : Thread-safe generic queue for inter-thread communication *)
+(* *)
+(******************************************************************************)
+Unit uthreadsafequeue;
+
+{$MODE ObjFPC}{$H+}
+
+Interface
+
+Uses
+ Classes, SysUtils, SyncObjs;
+
+Type
+ { TThreadSafeQueue - Generic thread-safe queue }
+ Generic TThreadSafeQueue = Class
+ private
+ fQueue: Array Of T;
+ fLock: TCriticalSection;
+ fCount: Integer;
+ public
+ Constructor Create;
+ Destructor Destroy; override;
+
+ Procedure Enqueue(Const Item: T);
+ Function Dequeue(Out Item: T): Boolean;
+ Function Count: Integer;
+ Procedure Clear;
+ End;
+
+Implementation
+
+{ TThreadSafeQueue }
+
+Constructor TThreadSafeQueue.Create;
+Begin
+ Inherited Create;
+ fLock := TCriticalSection.Create;
+ fQueue := Nil;
+ fCount := 0;
+End;
+
+Destructor TThreadSafeQueue.Destroy;
+Begin
+ Clear;
+ fLock.Free;
+ Inherited Destroy;
+End;
+
+Procedure TThreadSafeQueue.Enqueue(Const Item: T);
+Begin
+ fLock.Enter;
+ Try
+ SetLength(fQueue, fCount + 1);
+ fQueue[fCount] := Item;
+ Inc(fCount);
+ Finally
+ fLock.Leave;
+ End;
+End;
+
+Function TThreadSafeQueue.Dequeue(Out Item: T): Boolean;
+Var
+ i: Integer;
+Begin
+ Result := False;
+ fLock.Enter;
+ Try
+ If fCount > 0 Then Begin
+ Item := fQueue[0];
+ // Shift array
+ For i := 1 To fCount - 1 Do
+ fQueue[i - 1] := fQueue[i];
+ Dec(fCount);
+ SetLength(fQueue, fCount);
+ Result := True;
+ End;
+ Finally
+ fLock.Leave;
+ End;
+End;
+
+Function TThreadSafeQueue.Count: Integer;
+Begin
+ fLock.Enter;
+ Try
+ Result := fCount;
+ Finally
+ fLock.Leave;
+ End;
+End;
+
+Procedure TThreadSafeQueue.Clear;
+Begin
+ fLock.Enter;
+ Try
+ SetLength(fQueue, 0);
+ fCount := 0;
+ Finally
+ fLock.Leave;
+ End;
+End;
+
+End.
+