diff --git a/.azure/pipelines/linux-template.yml b/.azure/pipelines/linux-template.yml deleted file mode 100644 index 0e8f256d..00000000 --- a/.azure/pipelines/linux-template.yml +++ /dev/null @@ -1,46 +0,0 @@ -jobs: - - ${{ each vmImage in parameters.vmImages }}: - - ${{ each pythonVersion in parameters.pythonVersions }}: - - job: - displayName: ${{ format('OS:{0} PY:{1}', vmImage, pythonVersion) }} - pool: - vmImage: ${{ vmImage }} - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '${{ pythonVersion }}' - - - script: | - sudo apt update && sudo apt install -y --no-install-recommends graphviz - displayName: 'Install dependencies' - - - script: | - pip install --pre "textworld[full]" - condition: eq(variables.installFromSource, false) - displayName: 'Install a prerelease of TextWorld from PyPi' - - - script: | - setup.sh - pip install -r requirements-full.txt - pip install -e . - condition: eq(variables.installFromSource, true) - displayName: 'Install TextWorld from source' - - - script: | - pip install pytest pytest-azurepipelines pytest-cov - pytest --durations=10 --junitxml=junit/test-results.xml --cov=textworld --cov-report=xml --cov-report=html tests/ textworld/ - displayName: 'Run tests' - - - script: | - pip install codecov - for i in {1..5}; do codecov --required && break || sleep 30; done - env: - CODECOV_TOKEN: $(TEXTWORLD_CODECOV_TOKEN) - displayName: 'Publish coverage on Codecov' - - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: Cobertura - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - reportDirectory: '$(System.DefaultWorkingDirectory)/**/htmlcov' diff --git a/.azure/pipelines/macos-template.yml b/.azure/pipelines/macos-template.yml deleted file mode 100644 index 0a3903ca..00000000 --- a/.azure/pipelines/macos-template.yml +++ /dev/null @@ -1,39 +0,0 @@ -jobs: - - ${{ each vmImage in parameters.vmImages }}: - - ${{ each pythonVersion in parameters.pythonVersions }}: - - job: - displayName: ${{ format('OS:{0} PY:{1}', vmImage, pythonVersion) }} - pool: - vmImage: ${{ vmImage }} - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '${{ pythonVersion }}' - - - script: | - brew install graphviz - displayName: 'Install dependencies' - - - script: | - pip install --pre --use-pep517 textworld[full] - condition: eq(variables.installFromSource, false) - displayName: 'Install a prerelease of TextWorld from PyPi' - - - script: | - setup.sh - pip install -r requirements-full.txt - pip install -e . - condition: eq(variables.installFromSource, true) - displayName: 'Install TextWorld from source' - - - script: | - pip install pytest pytest-azurepipelines pytest-cov - pytest --junitxml=junit/test-results.xml --cov=textworld --cov-report=xml --cov-report=html tests/ textworld/ - displayName: 'Run tests' - - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: Cobertura - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - reportDirectory: '$(System.DefaultWorkingDirectory)/**/htmlcov' diff --git a/.azure/pipelines/prerelease.yml b/.azure/pipelines/prerelease.yml deleted file mode 100644 index d37c67a5..00000000 --- a/.azure/pipelines/prerelease.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Release code in the main branch to PyPi as a release candidate - -stages: -- stage: Prerelease_on_PyPi - jobs: - - job: - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: UsePythonVersion@0 - displayName: 'Use Python' - - - script: | - pip install twine - - # Build the python distribution from source - - script: | - pip install -r requirements.txt - TEXTWORLD_PRERELEASE=true ./tools/package.sh - - - task: TwineAuthenticate@1 - displayName: 'Twine Authenticate' - inputs: - pythonUploadServiceConnection: pypi - - # Use command line script to 'twine upload', use -r to pass the repository name and --config-file to pass the environment variable set by the authenticate task. - - script: | - python -m twine upload -r pypi --config-file $(PYPIRC_PATH) dist/textworld-* - -- stage: Test_library - variables: - - name: installFromSource - value: false - readonly: true - jobs: - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-20.04' ] - pythonVersions: [ '3.9' ] - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-latest' ] - pythonVersions: [ '3.12' ] - - template: macos-template.yml - parameters: - vmImages: [ 'macOS-11' ] - pythonVersions: [ '3.9' ] - - template: macos-template.yml - parameters: - vmImages: [ 'macOS-latest' ] - pythonVersions: [ '3.12' ] \ No newline at end of file diff --git a/.azure/pipelines/release.yml b/.azure/pipelines/release.yml deleted file mode 100644 index 67d56b8a..00000000 --- a/.azure/pipelines/release.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Release code in the main branch to PyPi - -jobs: -- job: - displayName: Release_on_PyPi - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: UsePythonVersion@0 - displayName: 'Use Python' - - - script: | - pip install twine - - # Build the python distribution from source - - script: | - pip install -r requirements.txt - ./tools/package.sh - - - task: TwineAuthenticate@1 - displayName: 'Twine Authenticate' - inputs: - pythonUploadServiceConnection: pypi - - # Use command line script to 'twine upload', use -r to pass the repository name and --config-file to pass the environment variable set by the authenticate task. - - script: | - python -m twine upload -r pypi --config-file $(PYPIRC_PATH) dist/textworld-* diff --git a/.azure/pipelines/security.yml b/.azure/pipelines/security.yml deleted file mode 100644 index 6f9bf848..00000000 --- a/.azure/pipelines/security.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Run the Component Governance Detection task - -trigger: -- main - -pool: - vmImage: 'ubuntu-latest' - -steps: -- task: ComponentGovernanceComponentDetection@0 - inputs: - scanType: 'Register' - verbosity: 'Verbose' - alertWarningLevel: 'High' - failOnAlert: true \ No newline at end of file diff --git a/.azure/pipelines/tests.yml b/.azure/pipelines/tests.yml deleted file mode 100644 index 27bfce45..00000000 --- a/.azure/pipelines/tests.yml +++ /dev/null @@ -1,34 +0,0 @@ -trigger: -- main - -stages: -- stage: Test - variables: - - name: installFromSource - value: true - readonly: true - jobs: - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-latest' ] - pythonVersions: [ '3.9' ] - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-latest' ] - pythonVersions: [ '3.10' ] - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-latest' ] - pythonVersions: [ '3.11' ] - - template: linux-template.yml - parameters: - vmImages: [ 'ubuntu-latest' ] - pythonVersions: [ '3.12' ] - - template: macos-template.yml - parameters: - vmImages: [ 'macOS-latest' ] - pythonVersions: [ '3.9' ] - - template: macos-template.yml - parameters: - vmImages: [ 'macOS-latest' ] - pythonVersions: [ '3.12' ] diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index feead3c8..00000000 --- a/.codecov.yml +++ /dev/null @@ -1,29 +0,0 @@ -comment: - layout: "reach, diff, files" - behavior: default - require_changes: false # if true: only post the comment if coverage changes - require_base: no # [yes :: must have a base report to post] - require_head: yes # [yes :: must have a head report to post] - branches: null - -ignore: - - "*/docs/*" - - "*/notebooks/*" - - "*/thirdparty/*" - - "setup.py" - - "*/setup.py" - - "*/tests/*" - -coverage: - status: - project: - default: - # Drops on the order 0.01% are typical even when no change occurs - # Having this threshold set a little higher (0.1%) than that makes it - # a little more tolerant to fluctuations - target: auto - threshold: 0.1% - patch: - default: - target: auto - threshold: 0.1% \ No newline at end of file diff --git a/.github/workflows/pep8.yml b/.github/workflows/pep8.yml index f6fd2989..f2dac956 100644 --- a/.github/workflows/pep8.yml +++ b/.github/workflows/pep8.yml @@ -4,11 +4,11 @@ jobs: run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: Setup Python 3.7 - uses: actions/setup-python@master + - uses: actions/checkout@v5 + - name: Setup Python + uses: actions/setup-python@v5 with: - version: 3.7 + python-version: '3.12' - name: flake8 run: | pip install flake8 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5635c88f..7dd7338a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,10 +2,6 @@ name: Build and upload to PyPI on: workflow_dispatch: - pull_request: - push: - branches: - - main release: types: - published @@ -20,11 +16,6 @@ jobs: matrix: include: # Linux 64 bit manylinux2014 - - os: ubuntu-latest - python: '3.9' - cp: '39' - platform_id: manylinux_x86_64 - manylinux_image: manylinux2014 - os: ubuntu-latest python: '3.10' cp: '310' @@ -40,46 +31,64 @@ jobs: cp: '312' platform_id: manylinux_x86_64 manylinux_image: manylinux2014 + - os: ubuntu-latest + python: '3.13' + cp: '313' + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 + - os: ubuntu-latest + python: '3.14' + cp: '314' + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 # MacOS x86_64 - - os: macos-13 - python: '3.9' - cp: '39' - platform_id: macosx_x86_64 - - os: macos-13 + - os: macos-latest-large python: '3.10' cp: '310' platform_id: macosx_x86_64 - - os: macos-13 + - os: macos-latest-large python: '3.11' cp: '311' platform_id: macosx_x86_64 - - os: macos-13 + - os: macos-latest-large python: '3.12' cp: '312' platform_id: macosx_x86_64 + - os: macos-latest-large + python: '3.13' + cp: '313' + platform_id: macosx_x86_64 + - os: macos-latest-large + python: '3.14' + cp: '314' + platform_id: macosx_x86_64 # MacOS arm64 - - os: macos-14 - python: '3.9' - cp: '39' - platform_id: macosx_arm64 - - os: macos-14 + - os: macos-latest python: '3.10' cp: '310' platform_id: macosx_arm64 - - os: macos-14 + - os: macos-latest python: '3.11' cp: '311' platform_id: macosx_arm64 - - os: macos-14 + - os: macos-latest python: '3.12' cp: '312' platform_id: macosx_arm64 + - os: macos-latest + python: '3.13' + cp: '313' + platform_id: macosx_arm64 + - os: macos-latest + python: '3.14' + cp: '314' + platform_id: macosx_arm64 steps: - name: Checkout TextWorld - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Build Wheel uses: pypa/cibuildwheel@v2.22.0 @@ -127,7 +136,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Python uses: actions/setup-python@v5 with: diff --git a/.github/workflows/test_pypi.yml b/.github/workflows/test_pypi.yml index 517b6161..afdc0877 100644 --- a/.github/workflows/test_pypi.yml +++ b/.github/workflows/test_pypi.yml @@ -12,10 +12,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-13, macos-14] - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + os: [ubuntu-latest, macos-latest, macos-large] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Use Python ${{ matrix.python }} uses: actions/setup-python@v5 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..a7236d35 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,38 @@ +name: "Run tests and coverage" + +on: + pull_request: + push: + branches: + - main + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, macos-latest-large] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] + steps: + - uses: actions/checkout@v5 + - name: Use Python ${{ matrix.python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install dependencies (Linux) + run: sudo apt update && sudo apt install -y --no-install-recommends graphviz + if: startsWith(matrix.os, 'ubuntu') + + - name: Install dependencies (MacOS) + run: brew install graphviz + if: startsWith(matrix.os, 'macos') + + - name: Install TextWorld from source + run: | + python -m pip install --upgrade pip + pip install -e .[dev] + - name: Run tests + run: | + pytest -n 16 --cov=textworld --cov-report=term-missing --cov-fail-under=85 tests/ textworld/ diff --git a/.gitignore b/.gitignore index c2aaddf5..91558630 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ build/* gen_games*/ experiments*/ /textworld/thirdparty/inform7-6M62 +/textworld/thirdparty/frotz gameinfo.dbg textworld_data/ Inform/ @@ -26,3 +27,5 @@ tmp/* /wheelhouse docs/build docs/src +*.code-workspace +.coverage \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..4abfe4d0 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: +- repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + exclude: ^textworld/thirdparty/ diff --git a/MANIFEST.in b/MANIFEST.in index c6b9ab2b..2aae89e9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,9 +7,6 @@ include CONTRIBUTING.md include License.md include setup.sh -include glk_build.py -recursive-include src * - include textworld/logic/*.ebnf include textworld/textgen/*.ebnf include textworld/generator/data/logic/*.twl @@ -22,8 +19,6 @@ include textworld/envs/pddl/textgen/*.ebnf recursive-include textworld/render/tmpl * -recursive-include textworld/thirdparty/glulx * - recursive-include textworld/thirdparty/inform7 * include textworld/thirdparty/inform7-6M62/share/inform7/Compilers/inform6 include textworld/thirdparty/inform7-6M62/share/inform7/Compilers/ni diff --git a/README.md b/README.md index a851f14e..e33f8be1 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ To play a game, one can use the `tw-play` script. For instance, the command to p tw-play tw_games/custom_game.z8 -> **Note:** Only Z-machine's games (*.z1 through *.z8) and Glulx's games (*.ulx) are supported. +> **Note:** Only Z-machine's games (*.z1 through *.z8) are supported. To visualize the game state while playing, use the `--viewer [port]` option. @@ -175,4 +175,3 @@ contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additio - [Jericho](https://github.com/microsoft/jericho) - GNU General Public License (GPL) v2.0 - [Fast Downward](https://github.com/MarcCote/downward) - GNU General Public License (GPL) v3.0 - [Git](https://github.com/DavidKinder/Git) - MIT License -- [cheakglk](https://github.com/erkyrath/cheapglk) - MIT License diff --git a/docker/run-tests.sh b/docker/run-tests.sh deleted file mode 100755 index 9c9ae71e..00000000 --- a/docker/run-tests.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -ex - -export PATH=$PWD/glulx/Git-Glulx:$PATH - -pip3 install -v . -pip3 install nose coverage -nosetests -sv --with-xunit --with-coverage --cover-xml --cover-html --cover-package textworld \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index a4cac70e..a6b589e0 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,9 +16,7 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -import os import sphinx_rtd_theme -import subprocess # -- Project information ----------------------------------------------------- diff --git a/docs/source/textworld.envs.glulx.rst b/docs/source/textworld.envs.glulx.rst deleted file mode 100644 index c3654602..00000000 --- a/docs/source/textworld.envs.glulx.rst +++ /dev/null @@ -1,13 +0,0 @@ -Glulx -===== - -.. automodule:: textworld.envs.glulx - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: textworld.envs.glulx.git_glulx - :members: - :undoc-members: - :show-inheritance: - diff --git a/docs/source/textworld.envs.rst b/docs/source/textworld.envs.rst index e29bb6bb..bc403515 100644 --- a/docs/source/textworld.envs.rst +++ b/docs/source/textworld.envs.rst @@ -9,7 +9,5 @@ textworld.envs .. toctree:: textworld.envs.tw - textworld.envs.glulx textworld.envs.wrappers textworld.envs.zmachine - diff --git a/glk_build.py b/glk_build.py deleted file mode 100644 index f6fe8b3c..00000000 --- a/glk_build.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. - - -from cffi import FFI - - -ffibuilder = FFI() - -with open('src/glk_comm.c') as f: - ffibuilder.set_source("glk", f.read()) - - ffibuilder.cdef(r""" - struct sock_names { - char* sock_name; - ...; - }; - """) - - ffibuilder.cdef(r""" - int init_glulx(struct sock_names* names); - const char* communicate(struct sock_names* names, const char* msg); - const char* get_output_nosend(struct sock_names* names); - void cleanup_glulx(struct sock_names* names); - void free(void* ptr); - """) - -if __name__ == "__main__": - ffibuilder.compile(verbose=True) diff --git a/notebooks/Handcrafting a game.ipynb b/notebooks/Handcrafting a game.ipynb index 5485dbaa..f538adc2 100644 --- a/notebooks/Handcrafting a game.ipynb +++ b/notebooks/Handcrafting a game.ipynb @@ -85,7 +85,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAAJYCAIAAACFB2zoAAAakUlEQVR4nO3de5xVdbn48WfPDCgjKCBCxkVAbtZLLUWlFEFQ8dbFPL8Us0TBWx1S0pM3vJRd7KiZWnkg/RmezsnETBRFixFRE/WAJirCIIMBgiBiilxyhtnnj5E5dLELD7iZ4f3+xz2z114+a/T1fX1m7TVrF2oWLQ3YEnp03b3UIwBAaZSVegAAgCZPUQEAZCkqAIAsRQUAkFXYb8ChpZ6BZmLWjOmlHgEASqNQs2jp0KFDSz0GTV5VVZW/9QNgu+VdPwCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMiq+Mc3nfXUE+3atf23iy755d33bLV52E4tXLys1CNsST267l7qEYBmqK6ubvGy1xseFyMKpZ0mrXVlq912bVvqKbaYJnOO6vjPfLqmes5ee/Ur9SAAAH+uyRTVscccvXkvLC8v37KTAAD8mc0sqi9+YXhN9Zz/+NGNBx7Q//5Jd7/43KxfTbzjI3vtFRHnjzm3pnrO3RN/3rjxCZ/7bE31nBmPPVIoFMrKyr589pnTpj4498XnHps29YxRpzduNvOp39ZUz9l3n72vvHzs72Y++fQTj379gq+VlZVVVlbWVM8ZctigiLh/0t2T7p7YsP3xn/n0vb+666Xnn33+2Zl3/NftAw85uHFXs556oqZ6zicGHPSL//7PF2c/c/MPb6ypnnP1d65q3OD7136vpnrONVd/JyLOGHlaTfWcxt1ScsWmKYrvzV9WaOpn4oFtVOFPl5dSL3ubqXH+iuZ1ymMzi2r9+j9GRI8e3a/93nfnvDR31ao39913nx/ddH15efn9Ux6MiH323rt9u3YNGw897LCIuH/Kg8Vi8fJLL77ga+e1aNFi/E9uXb169cVfv2Dkaadu3Of6iLh87CX9+vZ5YsZTHTp0OPvMUcd/9tO1tbW3Tbi94b/BpPsm33vf5Ig4c9TI6665ul/fPg8/Mn3mrFkHHtD/p7eOP3zokIZd/fHdP0bEv51/XteuXebNq77jzokRceThhzecryovLx986KERcfc9kzb358ZWVGiaGq9oKCgqYOv4s+Wl1MveZmqcv6JCUUXUF+sjonevXmMu+Pq/XXTJiFFnRsQe3br17NFj7tx5NTULy8rKBg0aGBEtW7Q4dODBEXHf5Pt3bd/+5OEnRsS5Yy74/g9u/NLpZ9TW1n757LMaQqdYX4yINWvWnPSFL3159Ln3PzAlIg4bPKi2tvaqb19dX18fEeNv+f+33jahTZs2547+ckRcdsU3vjL6vNNGnXX7z/67UChc8LXzGsbbULchIsrKygcPOfIzn/t/jz72+KtLl7Ztu8snPzEgIg7ov3/btrssXbZsxpNPRcSDv/7NqLPOuerb3838HAGA7VnqOqplr70265lnI2LBgpp31qyJiE6ddouIBx58KCIOGzQoIj7xiQGVlZWLFi9+bvbz++67d0VFRX19/WuvLf9Qp04V5eVLlrzarl3bfn37NO5z8v1TGh787rnZEdGpY8e//Pd+/GP7tmrVKiLunfxAw3cemPJgRPTp3WuXXXZp3Ozueya9W1sbEcVi8a5f/ioijjn6qIg44vAhEfGre+5t2Gzx4iUPT5s+c9YzmR8FALA9SxXVH978Q+Pj9evWRURZWXlETL7/gYg4dODBZWVlhw89LCLum/xAROzcZueIKCsre+yRqU88Nu2Jx6b16NE9Ijp37ty4nzf/8N4+161bHxHl5X9lwnZt20bE+vXr161b1/CdVavebHiwy847N262YsWKxscT77q7vr7+iMOHlJWVDR40KLzlBwBsOf/E/aj+cdXzX57/8su9e/Xaf7+PDzlscGxsrLfefisi6urqzv7K6E23f+HFOf/U/v/w1lsRseOOO+64444NV1+1b//eNVuNQRYRGzbUNz5eumzZo489PnjQoZ8+7tge3fd47rnZCxe+8s8fGQDAX7G17p7wwJSHIuL0Eafu/qEPVc9/eV71/IiYPfuFurq6ioqK115b8fC06dMffXznNjsXovD226v/7g4brkzfqbIyIp559ncNIXXcxlsqfOZTx0XE8y+8uHr1++7qFxPviojzx5wbEb/81f+doOratcuQwwb133+/zT9aAGD7trWKavIDUyJi2JGHx8YTVBHxxqpVDX92d9st475xxWU//9mE71/7vbPPOqMhj/625ctXRMQ3r7z80osvXL169U0/ujkivvXNK66/7t9vv+2W4Sd9vq6u7up/v/Zv7GFq1bSVK1d27vzhd2tr79s4UkQcdeQRt4y7+bJLL978owUAtm9bq6gWLKhpOC8VGy+ianDlN799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gCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIOt/AZX5OlGtAmIVAAAAAElFTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAAJYCAIAAACFB2zoAAAakUlEQVR4nO3de5xVdbn48WfPDCgjKCBCxkVAbtZLLUWlFEFQ8dbFPL8Us0TBWx1S0pM3vJRd7KiZWnkg/RmezsnETBRFixFRE/WAJirCIIMBgiBiilxyhtnnj5E5dLELD7iZ4f3+xz2z114+a/T1fX1m7TVrF2oWLQ3YEnp03b3UIwBAaZSVegAAgCZPUQEAZCkqAIAsRQUAkFXYb8ChpZ6BZmLWjOmlHgEASqNQs2jp0KFDSz0GTV5VVZW/9QNgu+VdPwCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMiq+Mc3nfXUE+3atf23iy755d33bLV52E4tXLys1CNsST267l7qEYBmqK6ubvGy1xseFyMKpZ0mrXVlq912bVvqKbaYJnOO6vjPfLqmes5ee/Ur9SAAAH+uyRTVscccvXkvLC8v37KTAAD8mc0sqi9+YXhN9Zz/+NGNBx7Q//5Jd7/43KxfTbzjI3vtFRHnjzm3pnrO3RN/3rjxCZ/7bE31nBmPPVIoFMrKyr589pnTpj4498XnHps29YxRpzduNvOp39ZUz9l3n72vvHzs72Y++fQTj379gq+VlZVVVlbWVM8ZctigiLh/0t2T7p7YsP3xn/n0vb+666Xnn33+2Zl3/NftAw85uHFXs556oqZ6zicGHPSL//7PF2c/c/MPb6ypnnP1d65q3OD7136vpnrONVd/JyLOGHlaTfWcxt1ScsWmKYrvzV9WaOpn4oFtVOFPl5dSL3ubqXH+iuZ1ymMzi2r9+j9GRI8e3a/93nfnvDR31ao39913nx/ddH15efn9Ux6MiH323rt9u3YNGw897LCIuH/Kg8Vi8fJLL77ga+e1aNFi/E9uXb169cVfv2Dkaadu3Of6iLh87CX9+vZ5YsZTHTp0OPvMUcd/9tO1tbW3Tbi94b/BpPsm33vf5Ig4c9TI6665ul/fPg8/Mn3mrFkHHtD/p7eOP3zokIZd/fHdP0bEv51/XteuXebNq77jzokRceThhzecryovLx986KERcfc9kzb358ZWVGiaGq9oKCgqYOv4s+Wl1MveZmqcv6JCUUXUF+sjonevXmMu+Pq/XXTJiFFnRsQe3br17NFj7tx5NTULy8rKBg0aGBEtW7Q4dODBEXHf5Pt3bd/+5OEnRsS5Yy74/g9u/NLpZ9TW1n757LMaQqdYX4yINWvWnPSFL3159Ln3PzAlIg4bPKi2tvaqb19dX18fEeNv+f+33jahTZs2547+ckRcdsU3vjL6vNNGnXX7z/67UChc8LXzGsbbULchIsrKygcPOfIzn/t/jz72+KtLl7Ztu8snPzEgIg7ov3/btrssXbZsxpNPRcSDv/7NqLPOuerb3838HAGA7VnqOqplr70265lnI2LBgpp31qyJiE6ddouIBx58KCIOGzQoIj7xiQGVlZWLFi9+bvbz++67d0VFRX19/WuvLf9Qp04V5eVLlrzarl3bfn37NO5z8v1TGh787rnZEdGpY8e//Pd+/GP7tmrVKiLunfxAw3cemPJgRPTp3WuXXXZp3Ozueya9W1sbEcVi8a5f/ioijjn6qIg44vAhEfGre+5t2Gzx4iUPT5s+c9YzmR8FALA9SxXVH978Q+Pj9evWRURZWXlETL7/gYg4dODBZWVlhw89LCLum/xAROzcZueIKCsre+yRqU88Nu2Jx6b16NE9Ijp37ty4nzf/8N4+161bHxHl5X9lwnZt20bE+vXr161b1/CdVavebHiwy847N262YsWKxscT77q7vr7+iMOHlJWVDR40KLzlBwBsOf/E/aj+cdXzX57/8su9e/Xaf7+PDzlscGxsrLfefisi6urqzv7K6E23f+HFOf/U/v/w1lsRseOOO+64444NV1+1b//eNVuNQRYRGzbUNz5eumzZo489PnjQoZ8+7tge3fd47rnZCxe+8s8fGQDAX7G17p7wwJSHIuL0Eafu/qEPVc9/eV71/IiYPfuFurq6ioqK115b8fC06dMffXznNjsXovD226v/7g4brkzfqbIyIp559ncNIXXcxlsqfOZTx0XE8y+8uHr1++7qFxPviojzx5wbEb/81f+doOratcuQwwb133+/zT9aAGD7trWKavIDUyJi2JGHx8YTVBHxxqpVDX92d9st475xxWU//9mE71/7vbPPOqMhj/625ctXRMQ3r7z80osvXL169U0/ujkivvXNK66/7t9vv+2W4Sd9vq6u7up/v/Zv7GFq1bSVK1d27vzhd2tr79s4UkQcdeQRt4y7+bJLL978owUAtm9bq6gWLKhpOC8VGy+ianDlN799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gCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIOt/AZX5OlGtAmIVAAAAAElFTkSuQmCC", "text/plain": [ "" ] @@ -116,7 +116,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAAJYCAIAAACFB2zoAAAetElEQVR4nO3de5yVdb3o8e9aMww3uQyaXFXgoCKm5LUsFRUz3Tu7Z2C7DLzUsdNW0Uy8t7MybbePmV1Utu12XjgqeUE0E9EQlQxNUVSI0VQEBUGuA8zMWuePETRLt/EFl7Pm/X7xevHMWs88813zB3xez/Nbzyo0PPdiwOYwaLu+lR4BACqjWOkBAADaPEUFAJClqAAAshQVAEBWYc8PHVjpGagSsx64t9IjAEBlFBqee3HkyJGVHoM2b+rUqd7rB0C75aofAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZNW+811nzby/vr7nN88488ZJN22xeWinCmdv2CpHFCo5yRa04aV9ZY+46rOVHgaAzarNnKP69Cc/0TB3zi67DK30IAAAb9Zmiuqf/+mITfvGmpqazTsJAMCbbGJRfemLoxvmzvn5ZT/ed5+9b7t50hOPzvrN9dcN22WXiDj1lJMa5s6ZdP21G3f+7Gc+1TB3zgPT7ykUCsVi8cSvnTDtrjueeuLR6dPuOv64sRt3++PMGQ1z5wzffbfzzz37T3988A/3//7008YVi8UuXbo0zJ1zyMEjIuK2myfdPOn61v0//clP3PKbG56c/cjsR/543dW/OmD/j2w81KyZ9zfMnbPfhz448Zr/fuKxh3/2kx83zJ1z4fe+s3GHH/3wBw1z51x84fci4vhjxzTMnbPxsLCl7dCz0hMAsLltYlGtXbsuIgYNGvjDH3x/zpNPLV26bPjw3S+79D9qampuu/2OiNh9t9161de37jzy4IMj4rbb7yiXy+eeNf60cSd36NDh8ismrFy5cvzppx075pgNx1wbEeeefebQnXe6/4GZ22yzzddOOO7Tn/pEU1PTVf/1q3K5HBE33zr5llsnR8QJxx377xdfOHTnne6+594/zpq17z57/3LC5YeOPKT1UOvWr4uIb5568nbbDXj66bnX/b/rI+KwQw9tPV9VU1Nz0IEHRsSkm27e1N8bbLrte1Z6AgA2t00sqlK5FBE7Dhlyymmnf/OMM79y3AkRscP22w8eNOipp55uaHimWCyOGHFARNR16HDgAR+JiFsn37Z1r15Hj/5CRJx0ymk/+r8//vLY45uamk782ldbQ6dcKkfE6tWrR33xyyd+46TbptweEQcfNKKpqek7372wVCpFxOVX/ueEq/6rW7duJ33jxIg457xvf/0bJ4857qu/+vU1hULhtHEnt47X0twSEcVizUGHHPbJz3z+99PvW/Diiz179vjwfh+KiH323qtnzx4vLlz4wIMzI+KOO3933Ff/93e++/3M7xEAaM9S66gWLlo06+FHImL+/IZVq1dHRO/e74uIKXf8NiIOHjEiIvbb70NdunR57vnnH31s9vDhu9XW1pZKpUWLXurTu3dtTc0LLyyor+85dOedNh5z8m23t2786dHHIqL3ttv+7c/d4wPDO3fuHBG3TJ7S+siU2++IiJ12HNKjR4+Nu0266eb1TU0RUS6Xb7jxNxHxT0ccHhEfPfSQiPjNTbe07vb88y/cPe3eP856OPOrAADas1RRvbrs1Y3baxsbI6JYrImIybdNiYgDD/hIsVg8dOTBEXHr5CkR0b1b94goFovT77nr/unT7p8+bdCggRHRv3//jcdZ9uprx2xsXBsRNTV/Z8L6nj0jYu3atY2Nja2PLF26rHWjR/fuG3d7+eWXN25ff8OkUqn00UMPKRaLB40YES75AQCbzz9wP6p3bu68P8/78593HDJkrz33OOTgg2JDYy1fsTwimpubv/b1b7xx/8efmPMPHf/V5csjolOnTp06dWpdfdWr12trtjYGWUS0tJQ2br+4cOHvp9930IgDP/Hxfx40cIdHH33smWee/cdfGQDA37Gl7p4w5fbfRsTYrxzTt0+fufP+/PTceRHx2GOPNzc319bWLlr08t3T7r339/d179a9EIUVK1b+jwdsXZnetUuXiHj4kT+1htTHN9xS4ZNHfjwiZj/+xMqVb3moidffEBGnnnJSRNz4m9dPUG233YBDDh6x9157bvqrBQDaty1VVJOn3B4RHzvs0NhwgioiXlm6tPVtd1dd+Ytvn3fOtb/+rx/98Adf++rxrXn09l566eWI+Lfzzz1r/LdWrlx56WU/i4gL/u28//j3i3511ZWjRx3V3Nx84UU/fJsj3DV12pIlS/r377e+qenWDSNFxOGHffTKX/zsnLPGb/qrBQDaty1VVPPnN7Sel4oNi6hanf9v3/2PSy5du3btqKM+N2BA//+++toxx57wTg544cX/vmTJkkEDd2hdxv6zX1xx+hln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GeN7b9t74YsL16xp7Ne3X32vXhHRpUvn7QYMmDtv3osLFjzz7DMRMXTo0NZv2XHHnSLiL395buNBBg8cHBHv22abiNh+hx1qa2sjotfW9atWrWxcs6auR3v8+HpX/QCgyl32059OnTr1iiuvLBaLf/nLc527domIcpQjolB4/f3VrY9EsRjl1qf+6iDFNyRDTYeajQ/V1L52dqYYxYhot3cQUFQA0C4MHjTo8CMOX7Vq5X9OmBARffr06dKl86KXFi1dtiwiVq1e/fzzL3ToUDegX79BgwZHxFNPPd36jU8+OSciWh/krSgqAGgvxn5lTOfOnadMmfL003OLxeLo0Ue3tLScc/bZ119//Vnjx69du3bUqC/Udew4dOjQvffeu6Gh4YILvjNx4nUXX3RxRPzLv/xLpcd/T1NUANBe1PfqNWrUqHK5/JOfXFoul0eNGjV27Nhly5ZdccUVi5csOeaYY770pS+17nn2WWcdfvjhDz/88FVX/bJb927nnnPOnnvuWdnh3+PcM533BPdMB3iH/qF7pr/HVdM9052jAgDIUlQAAFnuRwXvtruuOv+nX51c6SmAtuqkU8btf+DBlZ6CN1NUvLd8eMD6CUe8Uukptoj3T+jb0rpq8f1Hn7LfjhWeBmiz9tx7n0qPwN+hqHhveX/v6Na5SlYpvknXulixLiJim/47ffHInSo9DtBWVdPK9GqiqHhvGVBf17/3NpWeYovo2em1ovpAv0qPArQbx59wQsP8+a3bhUKhZ339sF12GTt27MCBAys6VxVSVABQ5fY/YP+ePXqWSi3z5s2bMWPG008/fe211xaL3p22OSkqAKhyo0cfPXTnnSOiubn585//3JIlS15+6eU+fftUeq6qok8BoF0olUpz585tbFxb36tXr222rvQ41cY5KgCocl8/8cSN2/369jv3vHPrOlTne4AqSFEBQJUbMeKgnj17RMQrr7wyc+bM884/76KLLhrQf0Cl56oqigoAqtxRXziqdR1VREyaNOmyyy6bOHHiqeNOrexUVcY6KgBoR8pRjoj169ZXepBq4xwVAFS5a6+9pmePnhHx6vJXZz44MyL23/+ACs9UdRQVAFS5+6bf17rRtUuXwYMHf/ZznzvggP0rO1L1UVQAULWuuPzySo/QXlhHBQCQpagAALIUFQBAlnVUVJuWpnVNq1e0rG8slcuF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qAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALL+P/980dpTQLoUAAAAAElFTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAAJYCAIAAACFB2zoAAAetElEQVR4nO3de5yVdb3o8e9aMww3uQyaXFXgoCKm5LUsFRUz3Tu7Z2C7DLzUsdNW0Uy8t7MybbePmV1Utu12XjgqeUE0E9EQlQxNUVSI0VQEBUGuA8zMWuePETRLt/EFl7Pm/X7xevHMWs88813zB3xez/Nbzyo0PPdiwOYwaLu+lR4BACqjWOkBAADaPEUFAJClqAAAshQVAEBWYc8PHVjpGagSsx64t9IjAEBlFBqee3HkyJGVHoM2b+rUqd7rB0C75aofAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZNW+811nzby/vr7nN88488ZJN22xeWinCmdv2CpHFCo5yRa04aV9ZY+46rOVHgaAzarNnKP69Cc/0TB3zi67DK30IAAAb9Zmiuqf/+mITfvGmpqazTsJAMCbbGJRfemLoxvmzvn5ZT/ed5+9b7t50hOPzvrN9dcN22WXiDj1lJMa5s6ZdP21G3f+7Gc+1TB3zgPT7ykUCsVi8cSvnTDtrjueeuLR6dPuOv64sRt3++PMGQ1z5wzffbfzzz37T3988A/3//7008YVi8UuXbo0zJ1zyMEjIuK2myfdPOn61v0//clP3PKbG56c/cjsR/543dW/OmD/j2w81KyZ9zfMnbPfhz448Zr/fuKxh3/2kx83zJ1z4fe+s3GHH/3wBw1z51x84fci4vhjxzTMnbPxsLCl7dCz0hMAsLltYlGtXbsuIgYNGvjDH3x/zpNPLV26bPjw3S+79D9qampuu/2OiNh9t9161de37jzy4IMj4rbb7yiXy+eeNf60cSd36NDh8ismrFy5cvzppx075pgNx1wbEeeefebQnXe6/4GZ22yzzddOOO7Tn/pEU1PTVf/1q3K5HBE33zr5llsnR8QJxx377xdfOHTnne6+594/zpq17z57/3LC5YeOPKT1UOvWr4uIb5568nbbDXj66bnX/b/rI+KwQw9tPV9VU1Nz0IEHRsSkm27e1N8bbLrte1Z6AgA2t00sqlK5FBE7Dhlyymmnf/OMM79y3AkRscP22w8eNOipp55uaHimWCyOGHFARNR16HDgAR+JiFsn37Z1r15Hj/5CRJx0ymk/+r8//vLY45uamk782ldbQ6dcKkfE6tWrR33xyyd+46TbptweEQcfNKKpqek7372wVCpFxOVX/ueEq/6rW7duJ33jxIg457xvf/0bJ4857qu/+vU1hULhtHEnt47X0twSEcVizUGHHPbJz3z+99PvW/Diiz179vjwfh+KiH323qtnzx4vLlz4wIMzI+KOO3933Ff/93e++/3M7xEAaM9S66gWLlo06+FHImL+/IZVq1dHRO/e74uIKXf8NiIOHjEiIvbb70NdunR57vnnH31s9vDhu9XW1pZKpUWLXurTu3dtTc0LLyyor+85dOedNh5z8m23t2786dHHIqL3ttv+7c/d4wPDO3fuHBG3TJ7S+siU2++IiJ12HNKjR4+Nu0266eb1TU0RUS6Xb7jxNxHxT0ccHhEfPfSQiPjNTbe07vb88y/cPe3eP856OPOrAADas1RRvbrs1Y3baxsbI6JYrImIybdNiYgDD/hIsVg8dOTBEXHr5CkR0b1b94goFovT77nr/unT7p8+bdCggRHRv3//jcdZ9uprx2xsXBsRNTV/Z8L6nj0jYu3atY2Nja2PLF26rHWjR/fuG3d7+eWXN25ff8OkUqn00UMPKRaLB40YES75AQCbzz9wP6p3bu68P8/78593HDJkrz33OOTgg2JDYy1fsTwimpubv/b1b7xx/8efmPMPHf/V5csjolOnTp06dWpdfdWr12trtjYGWUS0tJQ2br+4cOHvp9930IgDP/Hxfx40cIdHH33smWee/cdfGQDA37Gl7p4w5fbfRsTYrxzTt0+fufP+/PTceRHx2GOPNzc319bWLlr08t3T7r339/d179a9EIUVK1b+jwdsXZnetUuXiHj4kT+1htTHN9xS4ZNHfjwiZj/+xMqVb3moidffEBGnnnJSRNz4m9dPUG233YBDDh6x9157bvqrBQDaty1VVJOn3B4RHzvs0NhwgioiXlm6tPVtd1dd+Ytvn3fOtb/+rx/98Adf++rxrXn09l566eWI+Lfzzz1r/LdWrlx56WU/i4gL/u28//j3i3511ZWjRx3V3Nx84UU/fJsj3DV12pIlS/r377e+qenWDSNFxOGHffTKX/zsnLPGb/qrBQDaty1VVPPnN7Sel4oNi6hanf9v3/2PSy5du3btqKM+N2BA//+++toxx57wTg544cX/vmTJkkEDd2hdxv6zX1xx+hln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GeN7b9t74YsL16xp7Ne3X32vXhHRpUvn7QYMmDtv3osLFjzz7DMRMXTo0NZv2XHHnSLiL395buNBBg8cHBHv22abiNh+hx1qa2sjotfW9atWrWxcs6auR3v8+HpX/QCgyl32059OnTr1iiuvLBaLf/nLc527domIcpQjolB4/f3VrY9EsRjl1qf+6iDFNyRDTYeajQ/V1L52dqYYxYhot3cQUFQA0C4MHjTo8CMOX7Vq5X9OmBARffr06dKl86KXFi1dtiwiVq1e/fzzL3ToUDegX79BgwZHxFNPPd36jU8+OSciWh/krSgqAGgvxn5lTOfOnadMmfL003OLxeLo0Ue3tLScc/bZ119//Vnjx69du3bUqC/Udew4dOjQvffeu6Gh4YILvjNx4nUXX3RxRPzLv/xLpcd/T1NUANBe1PfqNWrUqHK5/JOfXFoul0eNGjV27Nhly5ZdccUVi5csOeaYY770pS+17nn2WWcdfvjhDz/88FVX/bJb927nnnPOnnvuWdnh3+PcM533BPdMB3iH/qF7pr/HVdM9052jAgDIUlQAAFnuRwXvtruuOv+nX51c6SmAtuqkU8btf+DBlZ6CN1NUvLd8eMD6CUe8Uukptoj3T+jb0rpq8f1Hn7LfjhWeBmiz9tx7n0qPwN+hqHhveX/v6Na5SlYpvknXulixLiJim/47ffHInSo9DtBWVdPK9GqiqHhvGVBf17/3NpWeYovo2em1ovpAv0qPArQbx59wQsP8+a3bhUKhZ339sF12GTt27MCBAys6VxVSVABQ5fY/YP+ePXqWSi3z5s2bMWPG008/fe211xaL3p22OSkqAKhyo0cfPXTnnSOiubn585//3JIlS15+6eU+fftUeq6qok8BoF0olUpz585tbFxb36tXr222rvQ41cY5KgCocl8/8cSN2/369jv3vHPrOlTne4AqSFEBQJUbMeKgnj17RMQrr7wyc+bM884/76KLLhrQf0Cl56oqigoAqtxRXziqdR1VREyaNOmyyy6bOHHiqeNOrexUVcY6KgBoR8pRjoj169ZXepBq4xwVAFS5a6+9pmePnhHx6vJXZz44MyL23/+ACs9UdRQVAFS5+6bf17rRtUuXwYMHf/ZznzvggP0rO1L1UVQAULWuuPzySo/QXlhHBQCQpagAALIUFQBAlnVUVJuWpnVNq1e0rG8slcuF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qAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALIUFQBAlqICAMhSVAAAWYoKACBLUQEAZCkqAIAsRQUAkKWoAACyFBUAQJaiAgDIUlQAAFmKCgAgS1EBAGQpKgCALEUFAJClqAAAshQVAECWogIAyFJUAABZigoAIEtRAQBkKSoAgCxFBQCQpagAALL+P/980dpTQLoUAAAAAElFTkSuQmCC", "text/plain": [ "" ] @@ -140,12 +140,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [ { "data": { - "image/png": "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tQ888MCUKVNK8uxKRVGxfplfl69vyJV6irZjfl15RFmppwDWL+dfcH7n6s5PP/308OHD99xzzz322CMi5syeExErPjG1V69eETFnzpzZc95xe88ePTOZzNy5c1ZsrUfPHhFRVVUVET2XL1dHRHOueR0+p9JTVKwfist/LYvmZY1NJR2lTckWi1FUVMA77DFoj9oetbvvPuipp5667bbbDj744C222KL3hhtExOzZs1vWmTVrVkT02bBPS0utuH3O7DnFYrF3nz4lmn39pahYP2SW/9qturK2e2VJR2lTunf+z+8twMo6dqw884wzvnvZZT//+c9/85vfDNptUN+N+j744IPbb79d167drr/++oqKiqFHDe1cXX3QQQfdf//9v//973fdddebb745Ij760eNKPf56R1EBQDs1eP/9d77zzhdeeOGO228/9rjjrrjiiquvvvoPf/hjc3PzwIEDL7zwwv79+0fEOeecU9ujx0MPP3Tbbbf17dv3vPPPO/yww0s9+3onUywW//dasJZlvrl84brj46SdSzlJG3PDi3HiP5YvF79X0lGAtSNfKEydvvyUXLHVHpXu3bOmqlPrPkHh3RMAAFI56wftxVlnnZXLeR0ltDUDN9/8hBM/W+opUFTQbowfP75QKJR6CuBD1tzcvt6kYL2lqKC9GDlyZKlHAD58K19HRQm5jgoAIJVjVADQXpz8uZPfnPZmy3JZWVmP2to99txz2LBhnTt3Lu1gbYCiAoD25cwzz6yuqm7ONY8aNWr48OFNTU1f//rXSz1Uq6eoAKB9GXLgkNoetRGx26DdTv7syRMmTCj1RG2BogKA9mXBooUR0ZRrHnn/yIjYZZddSjxQm6CoAKB9OX3YsBXLO+6446c//ekSDtNmKCoAaF8u/sY3unTuXCgUZ82aee21fxk2bNjVV11VU1tb6rlaN0UFAO3LLjvt3HIdVUSMH//6vfeOGPPimP33P6C0U7V2igoA2peRD4ysrqouFotz5s556KEHKyoqNh+4eamHavUUFW1NrlBoaMwVi8VOHcsryspKPQ7Aeueqq65qWejcuctWW231mc98pt/GG5d2pDZAUdFGNOUKsxc3PjXprXGzliyub8o1N1VG43Ybddt724371HbuWOFHHSCu/cu1pR6hzfLPDK1eoRhjZyweNX7u+NlL6hvz+WKxWIyIzKJi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FQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKT6fx4ANkmir1VSAAAAAElFTkSuQmCC\n", + "image/png": "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tQ888MCUKVNK8uxKRVGxfplfl69vyJV6irZjfl15RFmppwDWL+dfcH7n6s5PP/308OHD99xzzz322CMi5syeExErPjG1V69eETFnzpzZc95xe88ePTOZzNy5c1ZsrUfPHhFRVVUVET2XL1dHRHOueR0+p9JTVKwfist/LYvmZY1NJR2lTckWi1FUVMA77DFoj9oetbvvPuipp5667bbbDj744C222KL3hhtExOzZs1vWmTVrVkT02bBPS0utuH3O7DnFYrF3nz4lmn39pahYP2SW/9qturK2e2VJR2lTunf+z+8twMo6dqw884wzvnvZZT//+c9/85vfDNptUN+N+j744IPbb79d167drr/++oqKiqFHDe1cXX3QQQfdf//9v//973fdddebb745Ij760eNKPf56R1EBQDs1eP/9d77zzhdeeOGO228/9rjjrrjiiquvvvoPf/hjc3PzwIEDL7zwwv79+0fEOeecU9ujx0MPP3Tbbbf17dv3vPPPO/yww0s9+3onUywW//dasJZlvrl84brj46SdSzlJG3PDi3HiP5YvF79X0lGAtSNfKEydvvyUXLHVHpXu3bOmqlPrPkHh3RMAAFI56wftxVlnnZXLeR0ltDUDN9/8hBM/W+opUFTQbowfP75QKJR6CuBD1tzcvt6kYL2lqKC9GDlyZKlHAD58K19HRQm5jgoAIJVjVADQXpz8uZPfnPZmy3JZWVmP2to99txz2LBhnTt3Lu1gbYCiAoD25cwzz6yuqm7ONY8aNWr48OFNTU1f//rXSz1Uq6eoAKB9GXLgkNoetRGx26DdTv7syRMmTCj1RG2BogKA9mXBooUR0ZRrHnn/yIjYZZddSjxQm6CoAKB9OX3YsBXLO+6446c//ekSDtNmKCoAaF8u/sY3unTuXCgUZ82aee21fxk2bNjVV11VU1tb6rlaN0UFAO3LLjvt3HIdVUSMH//6vfeOGPPimP33P6C0U7V2igoA2peRD4ysrqouFotz5s556KEHKyoqNh+4eamHavUUFW1NrlBoaMwVi8VOHcsryspKPQ7Aeueqq65qWejcuctWW231mc98pt/GG5d2pDZAUdFGNOUKsxc3PjXprXGzliyub8o1N1VG43Ybddt724371HbuWOFHHSCu/cu1pR6hzfLPDK1eoRhjZyweNX7u+NlL6hvz+WKxWIyIzKJi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FQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKRSVAAAqRQVAEAqRQUAkEpRAQCkUlQAAKkUFQBAKkUFAJBKUQEApFJUAACpFBUAQCpFBQCQSlEBAKT6fx4ANkmir1VSAAAAAElFTkSuQmCC", "text/plain": [ "" ] @@ -157,7 +157,7 @@ ], "source": [ "note = M.new(type='o', name=\"note\") # Provide the type and the name of the object.\n", - "note.infos.desc = \"Bravo! You can read.\" # Text to display when issuing command \"examine note\". \n", + "note.infos.desc = \"Bravo! You can read.\" # Text to display when issuing command \"examine note\".\n", "\n", "supporter = M.new(type='s') # When not provided, names are automatically generated.\n", "\n", @@ -200,7 +200,7 @@ "outputs": [ { "data": { - "image/png": "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K64YNmzYV7/61QEDBtx/3/1XX311vlA49stfLi4qCiHce889p5566k033fTSyy9Nmjz51FNPeeaZZ4YNG/bgQw9961vfaun3uu4oKoC2L5HPTliYmdJYSCWWfSqdL8xqymYLoXtJon8ut4KNTJky5bnnnmtsbKysrKyoqFi4cOHIkSMXLly4xx57lJSUrMXRs6adccYZS5Z79+59xhlnVFVVvfDCC1OmTjnooIMOP+zwEMKiRQsvueSSJ554vFevnsOGDevRo8epp54aQtiw74YvHffSY488euyXv9y8hUMPOXTAgAFTpkx59913d9ppp9133722pmbYsGETJ05skXfXUhQV65c5i3L1DdmWHkXbMWdRUQiplh4F64VsIWxYFnqUhMSno6oxF6YWhenpkFnxy7PZN954o76+fuDAgf369SsqKlqwYMFbb701YcKETp067bTTTk7/tSLnnndux4qOr7322pAhQ3bbbbddd901hDBj+owQwpI7pnbt2jWEMGPGjOkzPvV4l9ouiURi5swZS7ZW26U2hFBeXh5C6LJ4uSKEkMmu+HuqrVFUrB8+PheRCpnGpnSLDqVNSRYKoaCoWCwVQnEisUxRZROhKJFIJQqZFd5EZ9y4cXV1dVtuueVmm23WfESqurp6p512mjNnzgcffNC/f/9O7WnGTGu364Bda2prdtllwKuvvnr//ffvv//+m222WfcNuoUQpk+f3rzORx99FELosUGP5pZa8viM6TMKhUL3Hj1aaOzrL0XF+uHj/+KrKspqOpuTscZ07vjJ3y2stlwuN3HixKKion79+i19gq+qqqpXr17vvPNOXV2domp1SkvLTjv11F/9+tdXXnnlVVddNWDnAb169nr66ae32WbrTp2qbrvttuLi4sMOP6xjRcV+++331FNP3XDDDTvttNPdd98dQjjmmKNbevjrHUUFsLZ8MHHivvsfXFxcnAghmUpt2Kf3QQcecMpJJ5a3to+pp9PpxsbGioqKjh07LvNUbW1tPp+fN29eiwyMSIP23nuHhx9+6623HnrwwaOOPvqyyy677rrr/v73GzOZTL9+/c4///y+ffuGEM4666ya2tpnnn3m/vvv79Wr1znnnnPwQQe39NjXO4oKYO0a+sSjvXv3WrBw4TvvjPr9H6948qmhd91xe8eKitXbWi6XS6XW9ZncXC6XyWTK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AACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBArP8H4uOR27iGp8MAAAAASUVORK5CYII=\n", + "image/png": "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K64YNmzYV7/61QEDBtx/3/1XX311vlA49stfLi4qCiHce889p5566k033fTSyy9Nmjz51FNPeeaZZ4YNG/bgQw9961vfaun3uu4oKoC2L5HPTliYmdJYSCWWfSqdL8xqymYLoXtJon8ut4KNTJky5bnnnmtsbKysrKyoqFi4cOHIkSMXLly4xx57lJSUrMXRs6adccYZS5Z79+59xhlnVFVVvfDCC1OmTjnooIMOP+zwEMKiRQsvueSSJ554vFevnsOGDevRo8epp54aQtiw74YvHffSY488euyXv9y8hUMPOXTAgAFTpkx59913d9ppp9133722pmbYsGETJ05skXfXUhQV65c5i3L1DdmWHkXbMWdRUQiplh4F64VsIWxYFnqUhMSno6oxF6YWhenpkFnxy7PZN954o76+fuDAgf369SsqKlqwYMFbb701YcKETp067bTTTk7/tSLnnndux4qOr7322pAhQ3bbbbddd901hDBj+owQwpI7pnbt2jWEMGPGjOkzPvV4l9ouiURi5swZS7ZW26U2hFBeXh5C6LJ4uSKEkMmu+HuqrVFUrB8+PheRCpnGpnSLDqVNSRYKoaCoWCwVQnEisUxRZROhKJFIJQqZFd5EZ9y4cXV1dVtuueVmm23WfESqurp6p512mjNnzgcffNC/f/9O7WnGTGu364Bda2prdtllwKuvvnr//ffvv//+m222WfcNuoUQpk+f3rzORx99FELosUGP5pZa8viM6TMKhUL3Hj1aaOzrL0XF+uHj/+KrKspqOpuTscZ07vjJ3y2stlwuN3HixKKion79+i19gq+qqqpXr17vvPNOXV2domp1SkvLTjv11F/9+tdXXnnlVVddNWDnAb169nr66ae32WbrTp2qbrvttuLi4sMOP6xjRcV+++331FNP3XDDDTvttNPdd98dQjjmmKNbevjrHUUFsLZ8MHHivvsfXFxcnAghmUpt2Kf3QQcecMpJJ5a3to+pp9PpxsbGioqKjh07LvNUbW1tPp+fN29eiwyMSIP23nuHhx9+6623HnrwwaOOPvqyyy677rrr/v73GzOZTL9+/c4///y+ffuGEM4666ya2tpnnn3m/vvv79Wr1znnnnPwQQe39NjXO4oKYO0a+sSjvXv3WrBw4TvvjPr9H6948qmhd91xe8eKitXbWi6XS6XW9ZncXC6XyWTKysqKipb9qdH8Qb/GxsZ1PCRWzy0337LMI5dffvmS5e4bdL/45xd/9lUdOnQ49ZRTTj3llGUeP+MHZ5zxg8WT3Pfff//999+/eXnDvhsOHTp0jQ26lVBUAOtCZceOA3fb9babbzzokCNuuvnWH55xejqdvuJPf/33U0+FEDp16nT+eefstusuIYS3Roz47SV/mD17TiKZ2HOP3c8/9+yysrILL/p5Kpl6e9SoivLy22/5xzobdjabnThx4vz58xsbG3O53Pvvv79Mz82dO7dQKEybNu3VV1+tqKjYfPPNP1td0B74vof24vTTT89mfY5yrfjxOefV1lStzJodKyoOOnD/54Y//8MzTr/+7/8Y/sILD9x7V2Vl5RNPPnXKaWc8M/TJoqLUiSef9tPzf/LlY45qaGj41vEnXn3NdWf/6MzS0tKHHh5yx+239t9s09UeZ7oQGvKFZWbWNeYLjfnPnZZeV1f3wgsvpNPpfD4fQnjppZc+u06hUPjwww/ffPPN8vLympqaHsubs3zllVeOHTtmtUfOCvTbdNPjvvGdlh4FigrajTFjxjT/UGSNW6VzXj179nxu+AshhMeeePK4Y79cWVkZQjjwgP0u/uWvXnrlleKiokQicczRR4YQOnTocOwxR9986+1n/+jMREhsu802MTlVlgizMmHRZy441ZQPMxpDthBqSsMnH7v9WCaTSafTuY+vU1VY3jVCmx/P5/NNTU1NTU3LXWHSpIljx45d7cGzAplM+7pIwXpLUUF70Q6nNawzM2bVrfzKU6dO3WCDbiGEmTNn1X58J5AQQk119axZs4uKUjU1NUuucFBdXT1r9qzm5aVXXg0blIaa4s8mU2jMh5JCKKrMd98lk62Lbe7PS64rr/xTSYmfOGtFLp+fNGV6S4+C4IJsAOvOgoULH37k0f0GDw4hdOvaddas2Uuemj17Tvdu3bp17Tp79uwlXTJr9qzu3bo1Ly97IalVlAihEBKFxGe+mp8sJEJIrOS1NubOnTt58mSz0WFpfmMAWBey2ezb77zzy99c0rtXr68f95UQwiEHH3jXvfcdc8xRlR07PvDQw9lc9ksDd02mUslE8oEHHz76qCMWLFz4r7vuOeTgg9bIAKY0hfpcoTS5bDU15cKcTKFxTmL+MyV9+n7xr9npdPrNN9+cNGnSwIED+/fvH9l5rGPHf/f4Dyd/2LycSqVqa2p23W23k08++bPXxWBVKSqAtWvwgYckQgiJRM8ePQ479ODvn3ZKcXFxCOGk752wYMGCo475SqEQamtr/nHDtc0Xybzx+mt+c8nvr/rbNSGE/ffb75STTlwjw8gUQpfi0LV42QRqyIWSkJiRKWQyzUeqvkAymWy+jIJ7+bVep512WkV5RSabGT58+JAhQ9Lp9E9+8pOWHlSrp6gA1paN+vYdP2bU5z1bUlz8k3PP/sm5Zy/z+Pbbb3f3nf9c5sGLf3bBmh/faikqKurevfucOXOWnu9F6zJ438E1tTUhhJ0H7Hz8d473oYE1QlEBsGpKSkoqKirW/YVGWVPq5s0NIaSzmaFPDQ0h7Ljjji08oDZBUQGwanr27NmjR49k0mebWqtTTj55yfJ22233zW9+swUH02YoKoD2IlsITfnCMmfq0vlCOl/Ifs4VPpdLS7V2F/70p5UdO+bzhY8+mnbLLTeffPLJ1117bXVN1OU5UFQA7UJpIoxvCJ+dL5POh1lNIRHChmXLedVKzpRaspqZVa3CjtvvUPPx5c3GjHn/iSceHzFyxN5779Oyo2rtFBVA21dIFvWpKOpdvpwjUY35wtSGRCGEZCKR+Mwt+crLyzt16lRfX7+ijRcKIYTS0tJOnTpVVa3U3XhoWUOHDa0orygUCjNmznjmmaeLi4s37bf6l+OnmaKircnm8w1N2UKh0KG0qNjMWQghhFB56V3hc65mHkL45D58nznCVFVVdeyxx37h9pujKpFIOCHYKlx77bXNCx07Vm6++ebf+ta3evfp07JDagMUFW1EOpufPr/p1fGzR3+0YH59OptJl4WmrXtW7b5Vnx41HUuLfavTvqVW9E9gxSfqRFJbcsvNt7T0ENosP2Zo9fKFMGrq/OFjZo6ZvqC+KZcrLP5teV6hZPr7854ZNXXz7hWDd+y3/cYbJJNmeACwVvjNg9ZtQWP24bem3vz8B298UDe/IZvNL3Wf1kQyFJVmS6v+8+Giqx565e7hb8+vb1rV7X8wceIm/bc688fnLP3gt44/8Z933LmCVz3x5FPTPvpoVfcFQOulqGjFmrL5f7066fG3P6qrTy9/hkgikUwVlVVWNxZV3vfCqBsfe72+Kb2qeyktLX35lVeHDnt65V/yl6v/9tFHbgUP0I4oKlqrdDZ/5yuT/jNxXjqbX/GaiWSypLxjKO340uhJNz/5Zn1TZpV2VCgUfnnxRT+9+BcLFixYdgzp9KV/uHzwAQcPPuDgo4897pVXXwsh/PCss0ePfvess8/9x823hhAeffyJQw4/avCBhxx65DGPPfHkKu0agNZCUdFajZo6/4Wxs5uyuZVZOZlMdehUk02khr057pXRk1ZpR7lc7qAD999pxx1+d+kflnnq+r//Y/gLLzxw711Dn3zstFNOPuW0M+rq5v71T5eXFBf/6fLLTvzud/779jtnn3v+Hy793dAnHr3ist+f+5MLx44bt0p7p1Xo1qU6Zfr256uuqiwpMW2XNs5/AbRKDZncy+Pn5POrcJnnZKqotLxTNp97ZuSERY2rcO6veWbWLy++6PEnn3rhxZeWfuqxJ5487tgvV1ZWhhAOPGC/sg5lL73yytIrDHn0sb0H7bnN1luFEDbvv9lee+7+0MOPrPyuAWgt/NJAq9SUyU+cXb8qt80IiUQiVVxaKCQ+nDW/MZ2tKCtZpT127drlwvPPveBnFz8+5MElD86cOau29pP7NtRUV8+aNXvpV82cMfP5F17cc+/9mv/Y2NhYU+0+DwBtkKKilSqs0gGqxRIhhJAvFAqff6nDFfjKl495eMgjf7ziz0UfX1e6W9euSyfU7NlzunfrtvRLunfvts/eg/5y5eWrsTsAWhFn/WiVipLJ2o6rdpCpUCjkc9kQCp0ryoqLVvNa6r/79a/uvvfeiRMXz8Q65OAD77r3vgULF4YQHnjo4Wwu+6WBu4YQikuK586dF0I47NBDnn12+Jj3x4YQFixYcM5PLhg1evTq7RqA9ZljVLRKZSWprXtVjZm+cOWPNhXy+UzDwkQisdWG3cpLi1dvv7179/rxWf/7699e2vzHk753woIFC4465iuFQqitrfnHDdd26tQphHDk4Yf/8KwfH/eVYy/66fmX/O7XZ519bv2i+kIoHHHYoZv37796uwZgfZZYvdMfsGYlfrZ44dZjw7d3WKmXzFzQdM3T4z+cU59bie/hfC7XtHBueuGcjbt1/t+j/6dP1/ZyM9c7RoZv3LV4ufCbFh0KsHbk8vlJUxZfAK/wRfcUWm9171Jd3qGspUcRxVk/WquulaU/HNxvuz5V5SWpZDKRWPoOr0s1VqGQz2WaMovmloeGPbbue+E39m4/OQXAOuOsH61YdUXJiXtsNGlO/dgZiybMXDRzYVNDOpfJ5fO5XCjkUyFfksxXlSZ7VHXs27XHxhtU96ytdMtkoI359LmmVnbiKfHxMbVsNtuyI4nnpwutW3lp0RY9Om3Ro1MIIZcvpHP5xnQ2k82lEqFDaXFpSVEq0UoPgQOslPynIqq1/peXy3/B3S/Wf4qKtiOVTHRIpjoUr+bn+ABgtSkqAGjFipLJ4qLFn18uKy1OtKqjVOl0OpcPIYSSklW7IM56SFEBQCuWTCZ79+jS0qPAZ/0AAKIpKgCAWIoKACCWogIAiKWoAABiKSoAgFiKCgAglqICAIilqAAAYikqAIBYigoAIJaiAgCI5U7JrF/mLMrVN2RbehRtx5xFRSGkWnoUAG2fomL9kipkGpvSLT2KtiNZKCgqgHVAUbF+qepYVtO5rKVH0XZ07tjSIwBoH8yjAgCIpagAAGIpKgCAWIoKACCWogIAiKWoAABiKSoAgFiKCgAglqICAIilqAAAYikqAIBYigoAIJaiAgCIpagAAGIpKgCAWIoKACCWogIAiFXU0gMAlq+uru65556bPHlynz59dt999y5durT0iAD4XI5R0Vrl87lcLruyX9lPfa38Xj6YOHGT/lttvvX2W2y9/RZbbz9wj0HnX3jR3LnzQggPD3l08IGHrOC174wa/drrb6z2G5w2bVp9fX2/fv2amppmzpy52tsBYB1wjIpWqWnR/Fcfvq2Qz6/UyplsYzq35I+pVHLQsSdWdOq88rsb+sSjvXv3CiFMmTL1R+ecd+FFF//tr3/+wlfdd/+DXbrU7jJg55Xf0dIqKysLhcLkyZMrKioqKipWbyMArBuKilYpn8+n6xfmc9kZE8fUz69b8cr1jZn5DU3JZKpLrw1rN+iTSCRCYaVS7LN69ep5+qmnnPG/Z+U/HXO33v5/t9x6WzaXK0qlzvzfHxxx2KE33HjTv+6+p7xDh/feG/OnKy4bPfrdX/32khkzZqRSRYcectAPvn9aKpX6vL3kcrkZM2bMmzevpKRk/vz51dXVc+fOLS4u7tat2wpeBUALUlS0Sh0qO+97wnn5bObJG35bP2/OilcuFPKFQiEkwpa77LnnUceHEBKJxGrvOp/PpVLJZPKTM+bvjBr9699e8uSjD2+88UZDhz19+g/OHLTnHid/74TnX3hx4G67nn7qyfX19SecfOoZp5/27W9+ff78+V/75ne6du3yja8d93m7yGQy06ZNmzJlysKFC/P5/MKFCydOnJhOp2traxUVwPpJUdFaJRKJkEhkmhoSiWRYYSClUqlkMpXP5esXzI9pqRDCpMmTr77m+oMOPGDpB7feasv/vPpiZWVlCGHQXntms9nJH06pqqpassIrr76eTqe//c2vhxA6der0ta9+5cGHhqygqIqLi/v27du1a9epU6cWFRVtsskmvXv3rqioKCryDxZgPeU/aFqxQiHfVL+o/8D9qjfoE5Kf+zGLXC7X0JR567nHmuoX5vO5ZHKVD/MMPvCQ5hCrra3db/A+557z46WfbWhouOpv17762ushhJBIhBCWOSc4Y+bMhQsX7bn3fs1/zGQznZfqrWWGWigUioqKamtra2pqcrnc9OnTu3fv3rt37+ajYtlstlAoFBcXr+pbAGCtUlS0ZvlCpqmh/8DB3fpunkiu6OBTLpud+eEHjfUL8rnVKaolM9OX62/XXv/iSy/fetON1dWd0+n0FtvssMwKG3Tv1rlz5+HPPLXivWQymcmTJ9fX12+66aZlZWXLXWHcuHGLFi3aeuutl7sCAC3F1RNoxXLZTKJQqKiqSaZSiURyBV/JVKqq6wbphvp8PvfF211Fs2bP7rvhhtXVnbPZ7JV//mtxcfGiRYtCCCXFxXPnzQsh7LrLgGQycd/9D4YQcrncn/5y1f0PPvTZ7TQ0NLz55ptvvPHGnDlz8sv7GOP8+fNffvnl559/ft68eWv8XQAQQ1HRijUunF/coTxVVPKFayZCorprj6bG+pW84MIqOemE706YOHHf/Q8++tjj/udLAw879OCzzj539Oh3Dzn4oNv/ecfRxx7XoUOHm2647p777t978IF7Dz5wwgcfDNprz89uJ5VKlZSUNDU1NTQ0LHdHixYtqqurKy8vd9YPYH3jrB+t2IK6meWdqpMrM187kejUpXumsSGfW7VjVBv17Tt+zKjlPnX4YYccftghIYR+/TZ55MH7ljy+5x67Ny9sueUWRx91xJLl/7vt5hXvq0OHDttss82iRYvmzZuXTqdLSj5Vik1NTdOnTy8pKdlll12qPmcaFgAtRVHRii2aO7O8sjpV9MUHbBKJRGXn2mwuuzbO+q0pyWSyR48evXr1GjNmTHl5+YYbbth87i+Xy9XX10+YMOG1117r1atX//79XUMBYH2jqGjFFtXNKq+uTaVW6tu4pKystKwil8ms7VHFKCsr22GHHRobG1988cXJkycnk8m6urqJEyeOHz/+3Xff3WCDDQYNGlReXt7SwwRgWYqKVqym98alZRWJlSuqsg4VO+57WFFJ6doeVaTKyso99thj3LhxkyZNWrRoUXFxcV1dXUVFxeDBg/v16yenANZPiopWbKNtB678ysWlZQP2PXztDWYNap5Qtc0227T0QABYWT7rBwAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMQqaukBwKe8OTV0LmvpQbQh/5na0iMAaB8ShUKhpccAIfGzlh5BO1D4TUuPAKDtctYPACCWogIAiJVo6QHQdjiDDEC75RgVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBALEUFABBLUQEAxFJUAACxFBUAQCxFBQAQS1EBAMRSVAAAsRQVAEAsRQUAEEtRAQDEUlQAALEUFQBArP8H4uOR27iGp8MAAAAASUVORK5CYII=", "text/plain": [ "" ] @@ -240,12 +240,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [ { "data": { - "image/png": "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hMu6GCo2NubZiS/MnfOt0XjpFFu5cnXirl0UFVDEmXba9smLrkLb+U8VuvQ0m0tERDT/uo1i7xh/ke1kZWUdPXrUarVWrVo1JibGwH0RriSb1Xbq5CkRycnNWbVqlYjUqV0nLz//8ccf13X9348+mpGZOXXq1IyMjFdffTUpKWnChAlNmzadMGHihg3rZ86caTKbR40caTabRWT578sffPChyZNfnjZ1WseOHR955OHJkydPnz596tSpHv6QVwxFBa+Ua3N+vubwodS8i5+DrhkMPgEh+fbCeeuS/H0sQzo1Lv1b9OzebfeevZ998eUdt99WfHleXv5LL09ev2GTiDRr1mTSxAk7ExNfee0Nl8t16nTy9Knvbti46b+TX83Nywvw93/mqf+0a9umTB8R8HK2Avvm5fuzCqyuc58pdOmnCxyaJlUsWozdeqEN2O32TZs27d692+FwGAyGbdu2RUdHd+zYMTIy8spOfg3bsGHD6DGj3Y8DAgPvuefupk2bLl26NC0tbezYsd26d3evs379+vSMjIULF+q6ft999zds2KB161aLFy/+7bdfR40c6X750FuGNmnS5KefmmzdunXMP8ZUj63+zTffHDt61FMf7Sog9uF9nC79913Ju07mlOaSPoPR6BcSYXXKT2sT86yFl/EuTtcLz0989/1pyckpxZe/8/7U08kpvyz4acmvC3Rdn/LGm506dhgx/JabBg+cPvXdjIzMu+994Inxjy35ZcGk5ybc9+DDuXl5l/sBgUpAE9F1PceuR5v16pazfmItehWLLrqed15sFdF1/c8//9y5c2dMTMzAgQOHDRvWsmXLzMzMFStW5OfnX8XPcW1p3LjxpEmTnnnmGbPZEhUROXToLSKSnJwsItHRUe51IiIjRCQ1JdW9PCo6SkRMJlNoaFhqyt//t4wIjxARPz8/EQkPixARf3//Qrv9Kn+iq4migvfJLrBvOpyhl/oWCQajyWTxy8gpWPHHodK/iy56g/r1hg29+cWXXym+fPHiJaNGDDebzZqmjRg+bPnylcWfXbV6TVz16p06dhCRFs0TateqtWrVmtK/KVDJGDUJNmpBprN/jFqAUbNc9M+fjIyMpKSkqlWrdurUqWrVqkFBQS1atGjZsmV6evr+/fuv1vjXnIjIiM6dO/fs2XPIzUMOHT70808/i0h0dLSIFP3dMvl0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ogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoOr/AYDK5rTQL5q4AAAAAElFTkSuQmCC\n", + "image/png": "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hMu6GCo2NubZiS/MnfOt0XjpFFu5cnXirl0UFVDEmXba9smLrkLb+U8VuvQ0m0tERDT/uo1i7xh/ke1kZWUdPXrUarVWrVo1JibGwH0RriSb1Xbq5CkRycnNWbVqlYjUqV0nLz//8ccf13X9348+mpGZOXXq1IyMjFdffTUpKWnChAlNmzadMGHihg3rZ86caTKbR40caTabRWT578sffPChyZNfnjZ1WseOHR955OHJkydPnz596tSpHv6QVwxFBa+Ua3N+vubwodS8i5+DrhkMPgEh+fbCeeuS/H0sQzo1Lv1b9OzebfeevZ998eUdt99WfHleXv5LL09ev2GTiDRr1mTSxAk7ExNfee0Nl8t16nTy9Knvbti46b+TX83Nywvw93/mqf+0a9umTB8R8HK2Avvm5fuzCqyuc58pdOmnCxyaJlUsWozdeqEN2O32TZs27d692+FwGAyGbdu2RUdHd+zYMTIy8spOfg3bsGHD6DGj3Y8DAgPvuefupk2bLl26NC0tbezYsd26d3evs379+vSMjIULF+q6ft999zds2KB161aLFy/+7bdfR40c6X750FuGNmnS5KefmmzdunXMP8ZUj63+zTffHDt61FMf7Sog9uF9nC79913Ju07mlOaSPoPR6BcSYXXKT2sT86yFl/EuTtcLz0989/1pyckpxZe/8/7U08kpvyz4acmvC3Rdn/LGm506dhgx/JabBg+cPvXdjIzMu+994Inxjy35ZcGk5ybc9+DDuXl5l/sBgUpAE9F1PceuR5v16pazfmItehWLLrqed15sFdF1/c8//9y5c2dMTMzAgQOHDRvWsmXLzMzMFStW5OfnX8XPcW1p3LjxpEmTnnnmGbPZEhUROXToLSKSnJwsItHRUe51IiIjRCQ1JdW9PCo6SkRMJlNoaFhqyt//t4wIjxARPz8/EQkPixARf3//Qrv9Kn+iq4migvfJLrBvOpyhl/oWCQajyWTxy8gpWPHHodK/iy56g/r1hg29+cWXXym+fPHiJaNGDDebzZqmjRg+bPnylcWfXbV6TVz16p06dhCRFs0TateqtWrVmtK/KVDJGDUJNmpBprN/jFqAUbNc9M+fjIyMpKSkqlWrdurUqWrVqkFBQS1atGjZsmV6evr+/fuv1vjXnIjIiM6dO/fs2XPIzUMOHT70808/i0h0dLSIFP3dMvl0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ogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoOr/AYDK5rTQL5q4AAAAAElFTkSuQmCC", "text/plain": [ "" ] @@ -256,7 +256,7 @@ } ], "source": [ - "key = M.new(type=\"k\", name=\"old key\") # Create a 'k' (i.e. key) object. \n", + "key = M.new(type=\"k\", name=\"old key\") # Create a 'k' (i.e. key) object.\n", "M.add_fact(\"match\", key, door) # Tell the game 'old key' is matching the 'door''s lock\n", "\n", "supporter.add(key) # Add the 'old key' on the supporter.\n", @@ -278,7 +278,7 @@ "outputs": [ { "data": { - "image/png": "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N/jUDwAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACg6v8BST7r5ceR8qAAAAAASUVORK5CYII=\n", + "image/png": "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N/jUDwAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACgiqICAABQRVEBAACooqgAAABUUVQAAACqKCoAAABVFBUAAIAqigoAAEAVRQUAAKCKogIAAFBFUQEAAKiiqAAAAFRRVAAAAKooKgAAAFUUFQAAgCqKCgAAQBVFBQAAoIqiAgAAUEVRAQAAqKKoAAAAVFFUAAAAqigqAAAAVRQVAACAKooKAABAFUUFAACg6v8BST7r5ceR8qAAAAAASUVORK5CYII=", "text/plain": [ "" ] @@ -437,7 +437,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -525,7 +525,7 @@ ], "source": [ "# Test the game by issuing commands from the generated walkthrough.\n", - "# You can set `walkthrough=False` if you want to play the game yourself. \n", + "# You can set `walkthrough=False` if you want to play the game yourself.\n", "M.test(walkthrough=True)" ] }, @@ -543,7 +543,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "" ] @@ -707,27 +707,11 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "collapsed": true }, - "outputs": [ - { - "ename": "MissingPlayerError", - "evalue": "Player position has not been specified. Use 'M.set_player(room)'.", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mMissingPlayerError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;31m# print(\"\\n\" + quest.desc)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0mM\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Try your game.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/data/src/TextWorld/textworld/generator/maker.py\u001b[0m in \u001b[0;36mtest\u001b[0;34m(self, walkthrough)\u001b[0m\n\u001b[1;32m 607\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 608\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mmake_temp_directory\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtmpdir\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 609\u001b[0;31m \u001b[0mgame_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtmpdir\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"test_game.ulx\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 610\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 611\u001b[0m \u001b[0magent\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtextworld\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0magents\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mHumanAgent\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mautocompletion\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/data/src/TextWorld/textworld/generator/maker.py\u001b[0m in \u001b[0;36mcompile\u001b[0;34m(self, path)\u001b[0m\n\u001b[1;32m 823\u001b[0m \u001b[0mPath\u001b[0m \u001b[0mto\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mgame\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 824\u001b[0m \"\"\"\n\u001b[0;32m--> 825\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_working_game\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 826\u001b[0m \u001b[0moptions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtextworld\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGameOptions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 827\u001b[0m \u001b[0moptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpath\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/data/src/TextWorld/textworld/generator/maker.py\u001b[0m in \u001b[0;36mbuild\u001b[0;34m(self, validate)\u001b[0m\n\u001b[1;32m 782\u001b[0m \"\"\"\n\u001b[1;32m 783\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mvalidate\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 784\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Validate the state of the world.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 785\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 786\u001b[0m \u001b[0mworld\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mWorld\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_facts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfacts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkb\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_kb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/data/src/TextWorld/textworld/generator/maker.py\u001b[0m in \u001b[0;36mvalidate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 761\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplayer\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 762\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"Player position has not been specified. Use 'M.set_player(room)'.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 763\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mMissingPlayerError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 764\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 765\u001b[0m \u001b[0mfailed_constraints\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_failing_constraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_kb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mMissingPlayerError\u001b[0m: Player position has not been specified. Use 'M.set_player(room)'." - ] - } - ], + "outputs": [], "source": [ "import textworld\n", "from textworld import GameMaker\n", diff --git a/notebooks/Playing TextWorld generated games with OpenAI Gym.ipynb b/notebooks/Playing TextWorld generated games with OpenAI Gym.ipynb index 7b099c8f..1101f15f 100644 --- a/notebooks/Playing TextWorld generated games with OpenAI Gym.ipynb +++ b/notebooks/Playing TextWorld generated games with OpenAI Gym.ipynb @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "!tw-make custom --world-size 2 --quest-length 3 --nb-objects 10 --output tw_games/game.ulx -f -v --seed 123" + "!tw-make custom --world-size 2 --quest-length 3 --nb-objects 10 --output tw_games/game.z8 -f -v --seed 123" ] }, { @@ -60,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -73,7 +73,7 @@ ], "source": [ "import textworld.gym\n", - "env_id = textworld.gym.register_game('tw_games/game.ulx')\n", + "env_id = textworld.gym.register_game('tw_games/game.z8')\n", "print(env_id)" ] }, @@ -296,7 +296,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -336,7 +336,7 @@ ")\n", "\n", "# Requesting additional information should be done when registering the game.\n", - "env_id = textworld.gym.register_game('tw_games/game.ulx', request_infos)\n", + "env_id = textworld.gym.register_game('tw_games/game.z8', request_infos)\n", "env = textworld.gym.make(env_id)\n", "\n", "obs, infos = env.reset()\n", @@ -353,7 +353,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -392,7 +392,7 @@ ")\n", "\n", "# Requesting additional information should be done when registering the game.\n", - "env_id = textworld.gym.register_game('tw_games/game.ulx', request_infos)\n", + "env_id = textworld.gym.register_game('tw_games/game.z8', request_infos)\n", "env = textworld.gym.make(env_id)\n", "\n", "obs, infos = env.reset()\n", diff --git a/pyproject.toml b/pyproject.toml index 544d2079..ae40ef26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [build-system] requires = [ "setuptools >= 61.0", - "cffi >= 1.0.0", ] build-backend = "setuptools.build_meta" @@ -35,4 +34,9 @@ license = {file = "LICENSE.txt"} [project.urls] Homepage = "https://github.com/microsoft/TextWorld" -Issues = "https://github.com/microsoft/TextWorld/issues" \ No newline at end of file +Issues = "https://github.com/microsoft/TextWorld/issues" + +[tool.pytest.ini_options] +filterwarnings = [ + "ignore::jericho.UnsupportedGameWarning", +] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..6eae28b9 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,35 @@ +# Main dependencies +numpy>=1.14.5 +tqdm>=4.17.1 +networkx>=2 +more_itertools +tatsu==5.8.3 +hashids>=1.2.0 +jericho>=2.2.0 +mementos>=1.3.1 +termcolor + +# For advanced prompt +prompt_toolkit + +# For visualization +pybars3>=0.9.3 +flask>=1.0.2 +selenium>=3.12.0,<4.3 +greenlet>=0.4.13 +gevent>=1.3.5 +pillow>=5.1.0 +plotly>=4.0.0,<6.0.0 +pydot>=1.2.4 +psutil +matplotlib + +# For using PddlEnv (needed for ALFWorld) +fast-downward-textworld + +# For testing +pytest +pytest-asyncio +pytest-cov +pytest-xdist +pytest-timeout diff --git a/requirements-full.txt b/requirements-full.txt index 74f65627..dda5d833 100644 --- a/requirements-full.txt +++ b/requirements-full.txt @@ -1,7 +1,6 @@ # Main dependencies numpy>=1.14.5 tqdm>=4.17.1 -cffi>=1.0.0 networkx>=2 more_itertools tatsu==5.8.3 diff --git a/requirements.txt b/requirements.txt index 7648060d..8a1184c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ # Main dependencies numpy>=1.14.5 tqdm>=4.17.1 -cffi>=1.0.0 networkx>=2 more_itertools tatsu==5.8.3 diff --git a/scripts/benchmark_framework.py b/scripts/benchmark_framework.py index d23bca59..80d3ff81 100644 --- a/scripts/benchmark_framework.py +++ b/scripts/benchmark_framework.py @@ -34,7 +34,7 @@ def generate_never_ending_game(args): game.quests = [] game_name = "neverending" - path = pjoin(args.output, game_name + ".ulx") + path = pjoin(args.output, game_name + ".z8") options = textworld.GameOptions() options.path = path options.force_recompile = True diff --git a/scripts/sample_quests.py b/scripts/sample_quests.py index 7901dd2d..fac33e92 100644 --- a/scripts/sample_quests.py +++ b/scripts/sample_quests.py @@ -62,7 +62,7 @@ def main(): args = parse_args() # Load game for which to sample quests for. - game = Game.load(args.game.replace(".ulx", ".json")) + game = Game.load(args.game.replace(".z8", ".json")) options = ChainingOptions() options.backward = False diff --git a/scripts/tw-extract b/scripts/tw-extract index b9b8b4df..f04ca216 100644 --- a/scripts/tw-extract +++ b/scripts/tw-extract @@ -35,7 +35,7 @@ def build_parser(): vocab_parser = subparsers.add_parser("vocab", parents=[general_parser], help='Extract vocabulary.') vocab_parser.add_argument("games", metavar="game", nargs="*", - help="List of TextWorld games (.ulx|.z8|.json).") + help="List of TextWorld games (.z8|.json).") vocab_parser.add_argument("--output", default="vocab.txt", help="Output file containing all words (.txt). Default: %(default)s") vocab_parser.add_argument("--theme", @@ -44,21 +44,21 @@ def build_parser(): entities_parser = subparsers.add_parser("entities", parents=[general_parser], help='Extract entity names.') entities_parser.add_argument("games", metavar="game", nargs="+", - help="List of TextWorld games (.ulx|.z8|.json).") + help="List of TextWorld games (.z8|.json).") entities_parser.add_argument("--output", default="entities.txt", help="Output file containing all entity names (.txt). Default: %(default)s") walkthrough_parser = subparsers.add_parser("walkthroughs", parents=[general_parser], help='Extract walkthroughs.') walkthrough_parser.add_argument("games", metavar="game", nargs="+", - help="List of TextWorld games (.ulx|.json).") + help="List of TextWorld games (.z8|.json).") walkthrough_parser.add_argument("--output", default="walkthroughs.txt", help="Output file containing all walkthroughs (.txt). Default: %(default)s") commands_parser = subparsers.add_parser("commands", parents=[general_parser], help='Extract all possible commands.') commands_parser.add_argument("games", metavar="game", nargs="+", - help="List of TextWorld games (.ulx|.json).") + help="List of TextWorld games (.z8|.json).") commands_parser.add_argument("--output", default="commands.txt", help="Output file containing all commands (.txt). Default: %(default)s") diff --git a/scripts/tw-make b/scripts/tw-make index e64f7ab0..d0b5a449 100755 --- a/scripts/tw-make +++ b/scripts/tw-make @@ -44,7 +44,7 @@ def _maybe_load_third_party_module(): def build_parser(default_parser_only=True): - description = "Make a TextWorld game (.z8 or .ulx)." + description = "Make a TextWorld game (.z8 or .json)." general_parser = argparse.ArgumentParser(add_help=False, description=description) general_parser.add_argument("--third-party", metavar="PATH", help="Load an external python file. Useful to register custom challenges on-the-fly.") @@ -118,7 +118,7 @@ def build_parser(default_parser_only=True): help="Path where to save the generated game. If it points to a folder," " the game's UUID will be used as the filename.") general_group.add_argument('--seed', type=int) - general_group.add_argument('--format', choices=["ulx", "z8"], default="z8", + general_group.add_argument('--format', choices=["z8"], default="z8", help="Which format to use when compiling the game. Default: %(default)s") general_group.add_argument("--overview", action="store_true", help="Display an overview of the generated game.") diff --git a/scripts/tw-play b/scripts/tw-play index 4846f843..fa40749f 100755 --- a/scripts/tw-play +++ b/scripts/tw-play @@ -12,7 +12,7 @@ import textworld.agents def build_parser(): - description = "Play a TextWorld game (.z8 or .ulx)." + description = "Play a TextWorld game (.z8 or .json)." parser = argparse.ArgumentParser(description=description) parser.add_argument("game") parser.add_argument("--mode", default="human", metavar="MODE", diff --git a/scripts/tw-stats b/scripts/tw-stats index dbef4559..fa562ef3 100755 --- a/scripts/tw-stats +++ b/scripts/tw-stats @@ -29,7 +29,7 @@ if __name__ == "__main__": game_logger = GameLogger() for game_filename in args.games: try: - game = Game.load(game_filename.replace(".ulx", ".json")) + game = Game.load(game_filename.replace(".z8", ".json")) except Exception as e: print("Cannot load {}.".format(game)) if args.verbose: diff --git a/setup.py b/setup.py index cc66352e..37f39b97 100644 --- a/setup.py +++ b/setup.py @@ -59,8 +59,6 @@ def run(self): zip_safe=False, long_description=open("README.md").read(), long_description_content_type="text/markdown", - cffi_modules=["glk_build.py:ffibuilder"], - setup_requires=['cffi>=1.0.0'], install_requires=open('requirements.txt').readlines(), test_suite='pytest', tests_require=[ @@ -70,5 +68,6 @@ def run(self): 'vis': open('requirements-vis.txt').readlines(), 'pddl': open('requirements-pddl.txt').readlines(), 'full': open('requirements-full.txt').readlines(), + 'dev': open('requirements-dev.txt').readlines(), } ) diff --git a/setup.sh b/setup.sh index a94a5071..aecc0f78 100755 --- a/setup.sh +++ b/setup.sh @@ -62,16 +62,3 @@ if [ "${machine}" == 'Mac' ] && [ -e inform7-6M62 ]; then echo "Unmounting Inform for Mac" hdiutil detach /Volumes/Inform/ fi - - -# Install modified fork of Glulx and build it - we have this one locally -( - echo "Installing cheapglk" - cd glulx/cheapglk - make -B -) -( - echo "Installing git-glulx-ml" - cd glulx/Git-Glulx - make -B -) diff --git a/src/glk_comm.c b/src/glk_comm.c deleted file mode 100644 index 02be5d02..00000000 --- a/src/glk_comm.c +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - - -// -// Created by james on 8/10/17. -// - -#include -#include -#include -#include -#include -#include -/* posix */ -#include -#include -#include -#include -#include -#include -#include -/* socket */ -#include -#include -#include -/* ulimit */ -#include -#include - -struct sock_names { - char* sock_name; - int serv_sock_fd; - int sock_fd; -}; - -void cleanup_glulx(struct sock_names* names) { - if (names->sock_fd != -1) { - int close_res = close(names->sock_fd); - if (close_res == -1) { - perror("glk_comm.c: Cannot close socket"); - } - - names->sock_fd = -1; /* protection against double-kill */ - } - - if (names->serv_sock_fd != -1) { - int close_res = close(names->serv_sock_fd); - if (close_res == -1) { - perror("glk_comm.c: Cannot close server socket"); - } - names->serv_sock_fd = -1; - } - - if (names->sock_name != NULL) { - int status = unlink(names->sock_name); - if (status == -1 && errno != ENOENT) { - perror("glk_comm.c: Cannot unlink socket"); - } - - const char *dir = dirname(names->sock_name); - status = rmdir(dir); - if (status == -1 && errno != ENOENT) { - perror("glk_comm.c: Cannot unlink socket directory"); - } - - free(names->sock_name); - names->sock_name = NULL; - } -} - -static int init_mq(struct sock_names* names) { - names->sock_name = NULL; - names->sock_fd = -1; - names->serv_sock_fd = -1; - - char temp[25] = "/tmp/mlglk_XXXXXX"; - if (mkdtemp(temp) == NULL) { - perror("glk_comm.c: mkdtemp()"); - return -1; - } - strcat(temp, "/socket"); - - names->sock_name = strdup(temp); - if (!names->sock_name) { - perror("glk_comm.c: strdup()"); - return -1; - } - - /* sockets */ - struct sockaddr_un sock_addr; - sock_addr.sun_family = AF_UNIX; - memset(sock_addr.sun_path, 0, sizeof(sock_addr.sun_path)); - strncpy(sock_addr.sun_path, names->sock_name, sizeof(sock_addr.sun_path) - 1); - - names->serv_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (names->serv_sock_fd == -1) { - perror("glk_comm.c: Error opening socket"); - return -1; - } - - int status = bind(names->serv_sock_fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); - if (status == -1) { - perror("glk_comm.c: Error binding socket"); - return -1; - } - - status = listen(names->serv_sock_fd, 1); - if (status == -1) { - perror("glk_comm.c: Error listening socket"); - return -1; - } - - return 0; -} - -/** - * accept() wrapper that handles EINTR. - */ -static int robust_accept(int socket, struct sockaddr* address, socklen_t* address_len) { - while (true) { - int ret = accept(socket, address, address_len); - if (ret >= 0 || errno != EINTR) { - return ret; - } - } -} - -/** - * recv() wrapper that handles EINTR. - */ -static ssize_t robust_recv(int socket, void* buffer, size_t length, int flags) { - while (true) { - ssize_t ret = recv(socket, buffer, length, flags); - if (ret >= 0 || errno != EINTR) { - return ret; - } - } -} - -static int glk_connect(struct sock_names* names) { /* arg mutable for connection */ - if (names->sock_fd != -1) { - return 0; - } - - names->sock_fd = robust_accept(names->serv_sock_fd, NULL, NULL); - if (names->sock_fd == -1) { - perror("glk_comm.c: Could not accept socket"); - return -1; - } - - return 0; -} - -const char* get_output_nosend(struct sock_names* names) { - if (glk_connect(names) != 0) { - return NULL; - } - - uint32_t net_buf_size = 0; - ssize_t amt = robust_recv(names->sock_fd, &net_buf_size, sizeof(net_buf_size), MSG_WAITALL); - if (amt <= 0) { - perror("glk_comm.c: Could not read msg size"); - return NULL; - } - - uint32_t buf_size = ntohl(net_buf_size); - char* msg_buf = calloc(buf_size + 1, 1); - if (!msg_buf) { - return NULL; - } - amt = robust_recv(names->sock_fd, msg_buf, buf_size, MSG_WAITALL); - if (amt < 0) { - perror("glk_comm.c: Could not read msg"); - free(msg_buf); - return NULL; - } - if (amt == 0 && buf_size != 0) { - fprintf(stderr, "glk_comm.c: Expected %d but only got %zd!\n", buf_size, amt); - } - - return msg_buf; -} - -const char* communicate(struct sock_names* names, const char* message) { - if (glk_connect(names) != 0) { - return NULL; - } - - int msg_len = strlen(message); - uint32_t net_msg_len = htonl(msg_len); - - int result = send(names->sock_fd, &net_msg_len, sizeof(net_msg_len), 0); - if (result == -1) { - perror("glk_comm.c: Could not send msg size"); - return NULL; - } - - result = send(names->sock_fd, message, msg_len, 0); - if (result == -1) { - perror("glk_comm.c: Could not send msg"); - return NULL; - } - - return get_output_nosend(names); -} - -/* ensure we're allowed as many open files as we want */ -static void check_rlimit(void) { - struct rlimit limits; - - int status = getrlimit(RLIMIT_NOFILE, &limits); - if (status == -1) { - perror("glk_comm.c: Cannot get rlimit"); - return; /* fail */ - } - - // It's not likely we can really open infinity files. macOS apparently - // recommends using the minimum of rlim_max and OPEN_MAX. - rlim_t max = limits.rlim_max; - if (max == RLIM_INFINITY) { -#ifdef OPEN_MAX - max = OPEN_MAX; -#else - max = _POSIX_OPEN_MAX; -#endif - } - - if (limits.rlim_cur != RLIM_INFINITY && limits.rlim_cur < max) { - limits.rlim_cur = max; - status = setrlimit(RLIMIT_NOFILE, &limits); - if (status == -1) { - perror("glk_comm.c: Cannot set rlimit"); - return; - } - } -} - -int init_glulx(struct sock_names* names) { - // check_rlimit(); - return init_mq(names); -} diff --git a/tests/test_sample_quests.py b/tests/test_sample_quests.py index a99c9e7b..41ec782b 100644 --- a/tests/test_sample_quests.py +++ b/tests/test_sample_quests.py @@ -12,7 +12,7 @@ def test_sample_quests(): with make_temp_directory(prefix="test_sample_quests") as tmpdir: - game_file = pjoin(tmpdir, "game.ulx") + game_file = pjoin(tmpdir, "game.z8") command = ["tw-make", "custom", "--seed", "20181004", "--output", game_file] check_output(command).decode() diff --git a/tests/test_textworld.py b/tests/test_textworld.py index 1e7d81b1..e45a0645 100644 --- a/tests/test_textworld.py +++ b/tests/test_textworld.py @@ -2,7 +2,6 @@ # Licensed under the MIT license. -import glob import shutil import tempfile import unittest @@ -34,17 +33,6 @@ def setUpClass(cls): def tearDownClass(cls): shutil.rmtree(cls.tmpdir) - def setUp(self): - self.before_tw = glob.glob(pjoin(tempfile.gettempdir(), "tw_*")) - self.before_mlglk = glob.glob(pjoin(tempfile.gettempdir(), "mlglk_*")) - - def tearDown(self): - # Check for file leaks. - after_tw = glob.glob(pjoin(tempfile.gettempdir(), "tw_*")) - after_mlglk = glob.glob(pjoin(tempfile.gettempdir(), "mlglk_*")) - assert set(after_tw) == set(self.before_tw) - assert set(after_mlglk) == set(self.before_mlglk) - def test_100_sequential_runs(self): for gamefile in [self.game_file, self.game_file_z8]: for _ in range(100): diff --git a/tests/test_tw-make.py b/tests/test_tw-make.py index 1acabb0a..93728ccf 100644 --- a/tests/test_tw-make.py +++ b/tests/test_tw-make.py @@ -16,7 +16,7 @@ def test_making_a_custom_game(): with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games") - game_file = pjoin(output_folder, "game_1234.ulx") + game_file = pjoin(output_folder, "game_1234.z8") command = ["tw-make", "custom", "--seed", "1234", "--output", game_file, "--silent"] assert check_call(command) == 0 @@ -76,7 +76,7 @@ def test_making_challenge_game(): for challenge in textworld.challenges.CHALLENGES: for i, params in enumerate(settings[challenge]): output_folder = pjoin(tmpdir, "gen_games") - game_file = pjoin(output_folder, challenge + "_{}".format(i) + ".ulx") + game_file = pjoin(output_folder, challenge + "_{}".format(i) + ".z8") command = ["tw-make", challenge, "--seed", "1234", "--output", game_file, "--silent"] + params assert check_call(command) == 0 @@ -92,7 +92,7 @@ def test_making_a_game_using_basic_theme(): for i in range(10): # Try a few different games. with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games") - game_file = pjoin(output_folder, "game_1234.ulx") + game_file = pjoin(output_folder, "game_1234.z8") command = ["tw-make", "custom", "--theme", "basic", "--seed", str(i), "--output", game_file, "--silent"] assert check_call(command) == 0 @@ -142,7 +142,7 @@ def make_game(settings: Mapping[str, str], options: Optional[GameOptions] = None NB_LOCATIONS = 3 output_folder = pjoin(tmpdir, "gen_games") - game_file = pjoin(output_folder, "game_1234.ulx") + game_file = pjoin(output_folder, "game_1234.z8") command = ["tw-make", "--third-party", challenge_py, "my-challenge", "--seed", "1234", "--output", game_file, "--silent"] try: @@ -155,5 +155,5 @@ def make_game(settings: Mapping[str, str], options: Optional[GameOptions] = None command += ["--nb-locations", str(NB_LOCATIONS)] assert check_call(command) == 0 - game = textworld.Game.load(game_file.replace(".ulx", ".json")) + game = textworld.Game.load(game_file.replace(".z8", ".json")) assert len(game.world.rooms) == NB_LOCATIONS diff --git a/tests/test_tw-play.py b/tests/test_tw-play.py index 12089b6a..96084ea0 100644 --- a/tests/test_tw-play.py +++ b/tests/test_tw-play.py @@ -8,7 +8,7 @@ def test_playing_a_game(): - for ext in [".ulx", ".z8"]: + for ext in [".z8"]: with make_temp_directory(prefix="test_tw-play") as tmpdir: options = textworld.GameOptions() options.file_ext = ext diff --git a/textworld/challenges/tests/test_coin_collector.py b/textworld/challenges/tests/test_coin_collector.py index 95c0774b..dfcb59f8 100644 --- a/textworld/challenges/tests/test_coin_collector.py +++ b/textworld/challenges/tests/test_coin_collector.py @@ -15,7 +15,7 @@ def test_making_coin_collector(): 101: {"quest_length": 1, "nb_rooms": 2}, 200: {"quest_length": 100, "nb_rooms": 200}, 201: {"quest_length": 1, "nb_rooms": 3}, - 300: {"quest_length": 100, "nb_rooms": 300}, + # 300: {"quest_length": 100, "nb_rooms": 300}, # Too large for .z8 game file. } for level in [1, 100, 101, 200, 201, 300]: options = textworld.GameOptions() diff --git a/textworld/challenges/tests/test_cooking.py b/textworld/challenges/tests/test_cooking.py index 25ec0f10..e69e7a16 100644 --- a/textworld/challenges/tests/test_cooking.py +++ b/textworld/challenges/tests/test_cooking.py @@ -23,7 +23,6 @@ def test_making_cooking_games(): "recipe": nb_ingredients, "take": 3, "open": True, - "open": True, "cook": True, "cut": False, "drop": False, diff --git a/textworld/challenges/tw_cooking/cooking.py b/textworld/challenges/tw_cooking/cooking.py index 25ade009..81002cee 100644 --- a/textworld/challenges/tw_cooking/cooking.py +++ b/textworld/challenges/tw_cooking/cooking.py @@ -1013,7 +1013,7 @@ def _place_one_distractor(candidates, ingredient): _place_one_distractor(same_suffix_list, ingredient) # Add distractors foods. The amount is drawn from N(nb_ingredients, 3). - nb_distractors = abs(int(rng_objects.randn(1) * 3 + nb_ingredients)) + nb_distractors = abs(int(rng_objects.randn(1).item() * 3 + nb_ingredients)) distractors = place_random_foods(M, nb_distractors, rng_objects, allowed_foods) # If recipe_seed is positive, a new recipe is sampled. diff --git a/textworld/envs/__init__.py b/textworld/envs/__init__.py index cb39b91c..2988e239 100644 --- a/textworld/envs/__init__.py +++ b/textworld/envs/__init__.py @@ -2,7 +2,6 @@ # Licensed under the MIT license. import re -from textworld.envs.glulx.git_glulx import GitGlulxEnv from textworld.envs.zmachine.jericho import JerichoEnv from textworld.envs.tw import TextWorldEnv from textworld.envs.wrappers.tw_inform7 import TWInform7 @@ -12,7 +11,8 @@ def _guess_backend(path): # Guess the backend from the extension. if path.endswith(".ulx"): - return GitGlulxEnv + msg = "Glulx games are not supported anymore. Use TextWorld version < 1.7.0 to play Glulx games." + raise NotImplementedError(msg) elif re.search(r"\.z[1-8]", path): return JerichoEnv elif path.endswith(".json"): diff --git a/textworld/envs/batch/tests/test_batch_env.py b/textworld/envs/batch/tests/test_batch_env.py index 23ac82ff..804266d8 100644 --- a/textworld/envs/batch/tests/test_batch_env.py +++ b/textworld/envs/batch/tests/test_batch_env.py @@ -15,7 +15,7 @@ def test_batch_env(): options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 - options.file_ext = ".ulx" + options.file_ext = ".z8" game_file1, game1 = textworld.make(options) options.seeds = 4321 options.file_ext = ".z8" diff --git a/textworld/envs/glulx/__init__.py b/textworld/envs/glulx/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/textworld/envs/glulx/git_glulx.py b/textworld/envs/glulx/git_glulx.py deleted file mode 100644 index 5b6ecf25..00000000 --- a/textworld/envs/glulx/git_glulx.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. - - -# -*- coding: utf-8 -*- -import sys -import textwrap -import subprocess - -import importlib.resources -from typing import Union -from os.path import join as pjoin - - -from glk import ffi, lib -from io import StringIO - -import textworld -from textworld.core import GameState -from textworld.core import GameNotRunningError - -GLULX_PATH = pjoin(importlib.resources.files("textworld"), "thirdparty", "glulx", "Git-Glulx") - - -def _strip_input_prompt_symbol(text: str) -> str: - if text.endswith("\n>"): - return text[:-2] - - return text - - -class GitGlulxEnv(textworld.Environment): - """ Environment to support playing Glulx games. - - This environment supports playing text-based games that were compiled for - the `Glulx virtual machine `_. The main - advantage of using Glulx over Z-Machine is it uses 32-bit data and - addresses, so it can handle game files up to four gigabytes long. This - comes handy when we want to generate large world with a lot of objects - in it. - - We use a customized version of `git-glulx `_ - as the glulx interpreter. That way we don't rely on stdin/stdout to - communicate with the interpreter but instead use UNIX sockets. - - """ - - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - self._process = None - - def close(self) -> None: - if self.game_running: - self._process.kill() - self._process.wait() - self._process = None - - try: - lib.cleanup_glulx(self._names_struct) - except AttributeError: - pass # Attempted to kill before reset - - def __del__(self): - self.close() - - def load(self, ulx_file: str) -> None: - # TODO check file format. - self.close() # Terminate existing process if needed. - self._gamefile = ulx_file - - @property - def game_running(self) -> bool: - """ Determines if the game is still running. """ - return self._process is not None and self._process.poll() is None - - def step(self, command: str) -> str: - if not self.game_running: - raise GameNotRunningError() - - self.state = GameState() - self.state.last_command = command.strip() - self.state.raw = self._send(self.state.last_command) - if self.state.raw is None: - raise GameNotRunningError() - - self.state.feedback = _strip_input_prompt_symbol(self.state.raw) - self.state.score = 0 # Default value. - self.state.done = False # Default value. - return self.state, self.state.score, self.state.done - - def _send(self, command: str) -> Union[str, None]: - """ Send a command directly to the interpreter. - - This method will not affect the internal state variable. - """ - if not self.game_running: - return None - - if len(command) == 0: - command = " " - - c_command = ffi.new('char[]', command.encode('utf-8')) - result = lib.communicate(self._names_struct, c_command) - if result == ffi.NULL: - self.close() - return None - - result = ffi.gc(result, lib.free) - return ffi.string(result).decode('utf-8') - - def reset(self) -> str: - self.close() # Terminate existing process if needed. - - self._names_struct = ffi.new('struct sock_names*') - - lib.init_glulx(self._names_struct) - sock_name = ffi.string(self._names_struct.sock_name).decode('utf-8') - self._process = subprocess.Popen(["%s/git-glulx-ml" % (GLULX_PATH,), self._gamefile, '-g', sock_name, '-q']) - c_feedback = lib.get_output_nosend(self._names_struct) - if c_feedback == ffi.NULL: - self.close() - raise ValueError("Game failed to start properly: {}.".format(self._gamefile)) - c_feedback = ffi.gc(c_feedback, lib.free) - - feedback = ffi.string(c_feedback).decode('utf-8') - feedback = _strip_input_prompt_symbol(feedback) - self.state = GameState(feedback=feedback, raw=feedback) - return self.state - - def render(self, mode: str = "human") -> None: - outfile = StringIO() if mode in ['ansi', "text"] else sys.stdout - - msg = self.state.feedback.rstrip() + "\n" - if self.display_command_during_render and self.state.last_command is not None: - msg = '> ' + self.state.last_command + "\n" + msg - - # Wrap each paragraph. - if mode == "human": - paragraphs = msg.split("\n") - paragraphs = ["\n".join(textwrap.wrap(paragraph, width=80)) for paragraph in paragraphs] - msg = "\n".join(paragraphs) - - outfile.write(msg + "\n") - - if mode == "text": - outfile.seek(0) - return outfile.read() - - if mode == 'ansi': - return outfile diff --git a/textworld/envs/glulx/tests/test_git_glulx.py b/textworld/envs/glulx/tests/test_git_glulx.py deleted file mode 100644 index dde70b10..00000000 --- a/textworld/envs/glulx/tests/test_git_glulx.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. - - -import shutil -import tempfile -import unittest - -import numpy.testing as npt - -import textworld -from textworld import g_rng -from textworld import testing - -from textworld.core import GameNotRunningError - -from textworld.envs.glulx.git_glulx import GitGlulxEnv - - -class TestGitGlulxEnv(unittest.TestCase): - - @classmethod - def setUpClass(cls): - g_rng.set_seed(201809) - cls.tmpdir = tempfile.mkdtemp() - cls.options = textworld.GameOptions() - cls.options.path = cls.tmpdir - cls.options.file_ext = ".ulx" - cls.game, cls.game_file = testing.build_and_compile_game(cls.options) - - @classmethod - def tearDownClass(cls): - shutil.rmtree(cls.tmpdir) - - def setUp(self): - self.env = GitGlulxEnv() - self.env.load(self.game_file) - self.env.reset() - - def tearDown(self): - self.env.close() - - def test_render(self): - # Only validates that render does not raise exception. - with testing.capture_stdout() as stdout: - self.env.render() - stdout.seek(0) - assert len(stdout.read()) > 0 - - assert self.env.render(mode="text").strip() == self.env.state.feedback.strip() - - # Try rendering to a file. - f = self.env.render(mode="ansi") - f.seek(0) - assert f.read().strip() == self.env.state.feedback.strip() - - # Display command that was just entered. - self.env.step("look") - text1 = self.env.render(mode="text") - self.env.display_command_during_render = True - text2 = self.env.render(mode="text") - assert "> look" not in text1 - assert "> look" in text2 - - def test_step(self): - env = GitGlulxEnv() - npt.assert_raises(GameNotRunningError, env.step, "look") - env.load(self.game_file) - npt.assert_raises(GameNotRunningError, env.step, "look") - - # Test sending command when the game is done. - self.env.reset() - self.env.step("quit") - self.env.step("yes") - npt.assert_raises(GameNotRunningError, self.env.step, "look") - - # Test sending empty command. - self.env.reset() - self.env.step("") - - def test_quit_no(self): - self.env.step("quit") - self.env.step("no") - self.env.step("look") diff --git a/textworld/envs/tw.py b/textworld/envs/tw.py index c2dbd68a..8532f573 100644 --- a/textworld/envs/tw.py +++ b/textworld/envs/tw.py @@ -12,7 +12,7 @@ DEFAULT_OBSERVATION = """ -[To get text observation use the '.z8' or '.ulx' files instead of the '.json' one.] +[To get text observation use the '.z8' file instead of the '.json' one.] """ diff --git a/textworld/envs/wrappers/tests/test_tw_inform7.py b/textworld/envs/wrappers/tests/test_tw_inform7.py index 15d5bf9f..537cdad5 100644 --- a/textworld/envs/wrappers/tests/test_tw_inform7.py +++ b/textworld/envs/wrappers/tests/test_tw_inform7.py @@ -14,7 +14,7 @@ from textworld import testing from textworld import EnvInfos -from textworld.envs import JerichoEnv, GitGlulxEnv +from textworld.envs import JerichoEnv from textworld.envs.wrappers.tw_inform7 import TWInform7 from textworld.envs.wrappers.tw_inform7 import GameData, Inform7Data from textworld.envs.wrappers.tw_inform7 import StateTracking @@ -30,10 +30,8 @@ def setUpClass(cls): g_rng.set_seed(201809) cls.tmpdir = tempfile.mkdtemp() cls.options = textworld.GameOptions() - cls.options.path = pjoin(cls.tmpdir, "tw-game.ulx") - cls.game, cls.gamefile_ulx = testing.build_and_compile_game(cls.options) cls.options.path = pjoin(cls.tmpdir, "tw-game.z8") - cls.gamefile_z8 = textworld.generator.compile_game(cls.game, cls.options) + cls.game, cls.gamefile_z8 = testing.build_and_compile_game(cls.options) cls.request_infos = EnvInfos( inventory=True, description=True, @@ -51,15 +49,11 @@ def setUp(self): self.env_z8 = Inform7Data(JerichoEnv(self.request_infos)) self.env_z8.load(self.gamefile_z8) - self.env_ulx = Inform7Data(GitGlulxEnv(self.request_infos)) - self.env_ulx.load(self.gamefile_ulx) - def tearDown(self): self.env_z8.close() - self.env_ulx.close() def test_description(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() game_state, _, _ = env.step("look") @@ -78,7 +72,7 @@ def test_description(self): assert game_state.description != "" def test_inventory(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert "carrot" in initial_state.inventory @@ -100,7 +94,7 @@ def test_inventory(self): assert game_state.inventory != "" # Game has ended def test_score(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert initial_state.score == 0 @@ -115,7 +109,7 @@ def test_score(self): assert game_state.score == 3 def test_moves(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert initial_state.moves == 0 @@ -130,7 +124,7 @@ def test_moves(self): assert game_state.moves == 3 def test_won(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert not initial_state.won @@ -144,7 +138,7 @@ def test_won(self): assert done def test_lost(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert not initial_state.lost @@ -155,8 +149,6 @@ def test_lost(self): assert game_state.lost def test_copy(self): - npt.assert_raises(NotImplementedError, self.env_ulx.copy) - # Copy before env.reset. env = self.env_z8.copy() assert env.state == self.env_z8.state @@ -192,10 +184,8 @@ def setUpClass(cls): g_rng.set_seed(201809) cls.tmpdir = tempfile.mkdtemp() cls.options = textworld.GameOptions() - cls.options.path = pjoin(cls.tmpdir, "tw-game.ulx") - cls.game, cls.gamefile_ulx = testing.build_and_compile_game(cls.options) cls.options.path = pjoin(cls.tmpdir, "tw-game.z8") - cls.gamefile_z8 = textworld.generator.compile_game(cls.game, cls.options) + cls.game, cls.gamefile_z8 = testing.build_and_compile_game(cls.options) cls.request_infos = EnvInfos( inventory=True, description=True, @@ -213,27 +203,19 @@ def setUp(self): self.env_z8 = TWInform7(JerichoEnv(self.request_infos)) self.env_z8.load(self.gamefile_z8) - self.env_ulx = TWInform7(GitGlulxEnv(self.request_infos)) - self.env_ulx.load(self.gamefile_ulx) - def tearDown(self): self.env_z8.close() - self.env_ulx.close() def test_compatible(self): - assert TWInform7.compatible(self.gamefile_ulx) assert TWInform7.compatible(self.gamefile_z8) - # To be compatible, a game needs the .json alongside its z8/ulx file. + # To be compatible, a game needs the .json alongside its .z8 file. gamefile_json = self.gamefile_z8.replace(".z8", ".json") shutil.move(gamefile_json, gamefile_json + ".bkp") - assert not TWInform7.compatible(self.gamefile_ulx) assert not TWInform7.compatible(self.gamefile_z8) shutil.move(gamefile_json + ".bkp", gamefile_json) def test_copy(self): - npt.assert_raises(NotImplementedError, self.env_ulx.copy) - # Copy before env.reset. env = self.env_z8.copy() assert env.state == self.env_z8.state @@ -264,7 +246,7 @@ def test_copy(self): def test_no_quest_game(self): game_name = "tw-no_quest_game" with make_temp_directory(prefix=game_name) as tmpdir: - for ext, env_class in [(".ulx", GitGlulxEnv), (".z8", JerichoEnv)]: + for ext, env_class in [(".z8", JerichoEnv)]: options = textworld.GameOptions() options.path = pjoin(tmpdir, game_name + ext) @@ -287,10 +269,8 @@ def setUpClass(cls): g_rng.set_seed(201809) cls.tmpdir = tempfile.mkdtemp() cls.options = textworld.GameOptions() - cls.options.path = pjoin(cls.tmpdir, "tw-game.ulx") - cls.game, cls.gamefile_ulx = testing.build_and_compile_game(cls.options) cls.options.path = pjoin(cls.tmpdir, "tw-game.z8") - cls.gamefile_z8 = textworld.generator.compile_game(cls.game, cls.options) + cls.game, cls.gamefile_z8 = testing.build_and_compile_game(cls.options) cls.request_infos = EnvInfos( max_score=True, objective=True, @@ -306,27 +286,23 @@ def setUp(self): self.env_z8 = GameData(JerichoEnv(self.request_infos)) self.env_z8.load(self.gamefile_z8) - self.env_ulx = GameData(GitGlulxEnv(self.request_infos)) - self.env_ulx.load(self.gamefile_ulx) - def tearDown(self): self.env_z8.close() - self.env_ulx.close() def test_max_score(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert initial_state.max_score == 3 def test_objective(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert initial_state.objective.strip() in initial_state.feedback game_state, _, _ = env.step("goal") assert game_state.feedback.strip() == initial_state.objective def test_win_facts(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert len(initial_state.win_facts) == len(self.game.quests) for i, quest in enumerate(self.game.quests): @@ -338,7 +314,7 @@ def test_win_facts(self): assert game_state.win_facts == initial_state.win_facts def test_fail_facts(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert len(initial_state.fail_facts) == len(self.game.quests) for i, quest in enumerate(self.game.quests): @@ -351,7 +327,7 @@ def test_fail_facts(self): def test_missing_game_infos_file(self): with make_temp_directory() as tmpdir: - for ext, env_class in [(".ulx", GitGlulxEnv), (".z8", JerichoEnv)]: + for ext, env_class in [(".z8", JerichoEnv)]: gamefile = pjoin(tmpdir, "tmp" + ext) with open(gamefile, "w"): pass # Empty file @@ -360,8 +336,6 @@ def test_missing_game_infos_file(self): npt.assert_raises(MissingGameInfosError, env.load, gamefile) def test_copy(self): - npt.assert_raises(NotImplementedError, self.env_ulx.copy) - # Copy before env.reset. env = self.env_z8.copy() assert env._gamefile == self.env_z8._gamefile @@ -381,10 +355,8 @@ def setUpClass(cls): g_rng.set_seed(201809) cls.tmpdir = tempfile.mkdtemp() cls.options = textworld.GameOptions() - cls.options.path = pjoin(cls.tmpdir, "tw-game.ulx") - cls.game, cls.gamefile_ulx = testing.build_and_compile_game(cls.options) cls.options.path = pjoin(cls.tmpdir, "tw-game.z8") - cls.gamefile_z8 = textworld.generator.compile_game(cls.game, cls.options) + cls.game, cls.gamefile_z8 = testing.build_and_compile_game(cls.options) cls.request_infos = EnvInfos( facts=True, policy_commands=True, @@ -400,15 +372,11 @@ def setUp(self): self.env_z8 = StateTracking(JerichoEnv(self.request_infos)) self.env_z8.load(self.gamefile_z8) - self.env_ulx = StateTracking(GitGlulxEnv(self.request_infos)) - self.env_ulx.load(self.gamefile_ulx) - def tearDown(self): self.env_z8.close() - self.env_ulx.close() def test_intermediate_reward(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() assert initial_state.intermediate_reward == 0 @@ -431,7 +399,7 @@ def test_intermediate_reward(self): assert game_state.intermediate_reward == 1 def test_policy_commands(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: initial_state = env.reset() walkthrough = tuple(self.game.metadata["walkthrough"]) @@ -474,7 +442,7 @@ def test_policy_commands(self): assert len(game_state.policy_commands) == 0 def test_admissible_commands(self): - for env in [self.env_ulx, self.env_z8]: + for env in [self.env_z8]: game_state = env.reset() # Make sure examine, look and inventory are in the admissible commands. assert "examine carrot" in game_state.admissible_commands @@ -493,7 +461,7 @@ def test_admissible_commands(self): def test_missing_game_infos_file(self): with make_temp_directory() as tmpdir: - for ext, env_class in [(".ulx", GitGlulxEnv), (".z8", JerichoEnv)]: + for ext, env_class in [(".z8", JerichoEnv)]: gamefile = pjoin(tmpdir, "tmp" + ext) with open(gamefile, "w"): pass # Empty file @@ -502,8 +470,6 @@ def test_missing_game_infos_file(self): npt.assert_raises(MissingGameInfosError, env.load, gamefile) def test_copy(self): - npt.assert_raises(NotImplementedError, self.env_ulx.copy) - # Copy before env.reset. env = self.env_z8.copy() assert env._gamefile == self.env_z8._gamefile diff --git a/textworld/envs/wrappers/tw_inform7.py b/textworld/envs/wrappers/tw_inform7.py index 9f473ccf..8afa5ea5 100644 --- a/textworld/envs/wrappers/tw_inform7.py +++ b/textworld/envs/wrappers/tw_inform7.py @@ -19,14 +19,14 @@ class MissingGameInfosError(NameError): """ - Thrown if an action requiring GameInfos is used on a game without GameInfos, such as a Frotz game or a - Glulx game not generated by TextWorld. + Thrown if an action requiring GameInfos is used on a game without GameInfos, + such as a Frotz game not generated by TextWorld. """ def __init__(self, env): msg = ("Can only use '{}' with games generated by " " TextWorld. Make sure the generated .json file is in the same " - " folder as the .ulx or .z8 game file.") + " folder as the .z8 game file.") super().__init__(msg.format(env.__class__.__name__)) @@ -105,7 +105,7 @@ def _wrap(self, env): def compatible(cls, path: str) -> bool: """ Check if path point to a TW Inform7 compatible game. """ basepath, ext = os.path.splitext(path) - if ext not in [".z8", ".ulx"]: + if ext not in [".z8"]: return False return os.path.isfile(basepath + ".json") diff --git a/textworld/generator/game.py b/textworld/generator/game.py index 1096f137..281be003 100644 --- a/textworld/generator/game.py +++ b/textworld/generator/game.py @@ -1109,12 +1109,12 @@ class GameOptions: quest_depth (int): Number of actions that need to be performed to solve a subquest. path (str): - Path of the compiled game (.ulx or .z8). Also, the source (.ni) + Path of the compiled game (.z8). Also, the source (.ni) and metadata (.json) files will be saved along with it. force_recompile (bool): If `True`, recompile game even if it already exists. file_ext (str): - Type of the generated game file. Either .z8 (Z-Machine) or .ulx (Glulx). + Type of the generated game file. Either .z8 (Z-Machine). If `path` already has an extension, this is ignored. chaining (ChainingOptions): For customizing the quest generation (see @@ -1136,7 +1136,7 @@ def __init__(self): self.nb_rooms = 1 self.nb_objects = 1 self.force_recompile = False - self.file_ext = ".ulx" + self.file_ext = ".z8" self.path = "./tw_games/" @property diff --git a/textworld/generator/inform7/world2inform7.py b/textworld/generator/inform7/world2inform7.py index 24b54996..1a75e616 100644 --- a/textworld/generator/inform7/world2inform7.py +++ b/textworld/generator/inform7/world2inform7.py @@ -1012,6 +1012,7 @@ def generate_inform7_source(game: Game, seed: int = 1234, use_i7_description: bo def compile_inform7_game(source: str, output: str, verbose: bool = False) -> None: with make_temp_directory(prefix="tmp_inform") as project_folder: filename, ext = os.path.splitext(output) + assert ext in [".z8"], f"Output file `{output}` must have a .z8 extension." story_filename = filename + ".ni" # Save story file. @@ -1049,7 +1050,7 @@ def compile_inform7_game(source: str, output: str, verbose: bool = False) -> Non msg += "\n-== ni =-\nFAIL: {}\n{}========\n".format(exc.returncode, exc.output.decode()) msg += "*** Usually this means a compilation error.\n" if ext == ".z8": - msg += "*** Maybe the game is too big for a .z8 file. Try using .ulx instead.\n" + msg += "*** Maybe the game is too big for a .z8 file.\n" msg += "*** See {} for more information.\n".format(story_filename) raise CouldNotCompileGameError(msg) else: @@ -1065,7 +1066,7 @@ def compile_inform7_game(source: str, output: str, verbose: bool = False) -> Non i6_options += "D" # Debug mode, enables Inform7 testing commands. i6_options += "E2wS" - i6_options += "G" if ext == ".ulx" else "v8" + i6_options += "v8" i6_options += "F0" # Use extra memory rather than temporary files. cmd = [i6, i6_options, i6_input_filename, output] @@ -1079,7 +1080,7 @@ def compile_inform7_game(source: str, output: str, verbose: bool = False) -> Non msg += "\n-= i6 =-\nFAIL: {}\n{}========\n".format(exc.returncode, exc.output.decode()) msg += "*** Usually this means a compilation error.\n" if ext == ".z8": - msg += "*** Maybe the game is too big for a .z8 file. Try using .ulx instead.\n" + msg += "*** Maybe the game is too big for a .z8 file.\n" msg += "*** See {} for more information.\n".format(story_filename) raise CouldNotCompileGameError(msg) else: diff --git a/textworld/generator/maker.py b/textworld/generator/maker.py index 844dee46..6a28401a 100644 --- a/textworld/generator/maker.py +++ b/textworld/generator/maker.py @@ -604,7 +604,7 @@ def test(self, walkthrough: bool = False) -> None: """ with make_temp_directory() as tmpdir: - game_file = self.compile(pjoin(tmpdir, "test_game.ulx")) + game_file = self.compile(pjoin(tmpdir, "test_game.z8")) agent = textworld.agents.HumanAgent(autocompletion=True) if walkthrough: @@ -621,7 +621,7 @@ def record_quest(self) -> Quest: The resulting quest. """ with make_temp_directory() as tmpdir: - game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) + game_file = self.compile(pjoin(tmpdir, "record_quest.z8")) recorder = Recorder() agent = textworld.agents.HumanAgent(autocompletion=True) textworld.play(game_file, agent=agent, wrappers=[recorder]) @@ -649,7 +649,7 @@ def set_quest_from_commands(self, commands: List[str]) -> Quest: """ with make_temp_directory() as tmpdir: try: - game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) + game_file = self.compile(pjoin(tmpdir, "record_quest.z8")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrappers=[recorder], silent=True) @@ -693,7 +693,7 @@ def new_event_using_commands(self, commands: List[str]) -> Event: """ with make_temp_directory() as tmpdir: try: - game_file = self.compile(pjoin(tmpdir, "record_event.ulx")) + game_file = self.compile(pjoin(tmpdir, "record_event.z8")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrappers=[recorder], silent=True) @@ -721,7 +721,7 @@ def new_quest_using_commands(self, commands: List[str]) -> Quest: def set_walkthrough(self, commands: List[str]): with make_temp_directory() as tmpdir: - game_file = self.compile(pjoin(tmpdir, "set_walkthrough.ulx")) + game_file = self.compile(pjoin(tmpdir, "set_walkthrough.z8")) env = textworld.start(game_file, request_infos=EnvInfos(last_action=True, intermediate_reward=True)) state = env.reset() diff --git a/textworld/gym/envs/textworld.py b/textworld/gym/envs/textworld.py index 8e1dc03f..e2f5de49 100644 --- a/textworld/gym/envs/textworld.py +++ b/textworld/gym/envs/textworld.py @@ -19,7 +19,7 @@ def __init__(self, Arguments: gamefiles: - Paths of every game composing the pool (`*.ulx|*.z[1-8]`). + Paths of every game composing the pool (`*.z[1-8]`). request_infos: For customizing the information returned by this environment (see :py:class:`textworld.EnvInfos ` diff --git a/textworld/gym/envs/textworld_batch.py b/textworld/gym/envs/textworld_batch.py index 30bdbb49..75ae563e 100644 --- a/textworld/gym/envs/textworld_batch.py +++ b/textworld/gym/envs/textworld_batch.py @@ -45,7 +45,7 @@ def __init__(self, Arguments: gamefiles: - Paths of every game composing the pool (`*.ulx|*.z[1-8]|*.json`). + Paths of every game composing the pool (`*.z[1-8]|*.json`). request_infos: For customizing the information returned by this environment (see :py:class:`textworld.EnvInfos ` diff --git a/textworld/gym/tests/test_textworld_gym.py b/textworld/gym/tests/test_textworld_gym.py index 2f639aca..3f6debdc 100644 --- a/textworld/gym/tests/test_textworld_gym.py +++ b/textworld/gym/tests/test_textworld_gym.py @@ -1,5 +1,4 @@ import os -import glob import shutil import tempfile import unittest @@ -34,17 +33,6 @@ def setUpClass(cls): def tearDownClass(cls): shutil.rmtree(cls.tmpdir) - def setUp(self): - self.before_tw = glob.glob(pjoin(tempfile.gettempdir(), "tw_*")) - self.before_mlglk = glob.glob(pjoin(tempfile.gettempdir(), "mlglk_*")) - - def tearDown(self): - # Check for file leaks. - after_tw = glob.glob(pjoin(tempfile.gettempdir(), "tw_*")) - after_mlglk = glob.glob(pjoin(tempfile.gettempdir(), "mlglk_*")) - assert set(after_tw) == set(self.before_tw) - assert set(after_mlglk) == set(self.before_mlglk) - def test_register_game(self): env_options = EnvInfos(inventory=True, description=True, admissible_commands=True, diff --git a/textworld/gym/utils.py b/textworld/gym/utils.py index a65104a6..a31da347 100644 --- a/textworld/gym/utils.py +++ b/textworld/gym/utils.py @@ -43,7 +43,7 @@ def register_games(gamefiles: List[str], Arguments: gamefiles: - Paths for the TextWorld games (`*.ulx|*.z[1-8]`). + Paths for the TextWorld games (`*.z[1-8]`). request_infos: For customizing the information returned by this environment (see @@ -133,7 +133,7 @@ def register_game(gamefile: str, Arguments: gamefile: - Path for the TextWorld game (`*.ulx|*.z[1-8]`). + Path for the TextWorld game (`*.z[1-8]`). request_infos: For customizing the information returned by this environment (see :py:class:`textworld.EnvInfos ` diff --git a/textworld/render/serve.py b/textworld/render/serve.py index 076edd87..4c5c6343 100644 --- a/textworld/render/serve.py +++ b/textworld/render/serve.py @@ -202,7 +202,7 @@ def update_state(self, game_state: GameState, command: str): """ Propogate state update to server. We use a multiprocessing.Pipe to pass state into flask process. - :param game_state: Glulx game state. + :param game_state: game state. :param command: previous command """ state_dict = textworld.render.load_state_from_game_state(game_state) diff --git a/textworld/thirdparty/glulx/Git-Glulx/.gitignore b/textworld/thirdparty/glulx/Git-Glulx/.gitignore deleted file mode 100644 index 100062eb..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.o -*.pyc diff --git a/textworld/thirdparty/glulx/Git-Glulx/Makefile b/textworld/thirdparty/glulx/Git-Glulx/Makefile deleted file mode 100644 index 391bde04..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -# Unix makefile for Git (shamelessly ripped off from Glulxe's makefile) - -# ----------------------------------------------------------------- -# Step 1: pick a Glk library. - -# Note: when using xglk, do NOT define USE_MMAP in step 2, below. - -GLK = cheapglk -#GLK = glkterm -#GLK = xglk - -GLKINCLUDEDIR = ../$(GLK) -GLKLIBDIR = ../$(GLK) -GLKMAKEFILE = Make.$(GLK) - -# ----------------------------------------------------------------- -# Step 2: pick a C compiler. - -# Generic C compiler -CC = cc -O2 -OPTIONS = - -# Best settings for GCC 2.95. This generates faster code than -# GCC 3, so you should use this setup if possible. -#CC = gcc -Wall -O3 -#OPTIONS = -DUSE_DIRECT_THREADING -DUSE_MMAP -DUSE_INLINE - -# Best settings for GCC 3. The optimiser in this version of GCC -# is somewhat broken, so we can't use USE_DIRECT_THREADING. -#CC = gcc -Wall -O3 -#OPTIONS = -DUSE_MMAP -DUSE_INLINE - -# Mac OS X (PowerPC) settings. -#CC = gcc2 -Wall -O3 -no-cpp-precomp -#OPTIONS = -DUSE_DIRECT_THREADING -DUSE_BIG_ENDIAN_UNALIGNED -DUSE_MMAP -DUSE_INLINE - -# ----------------------------------------------------------------- -# Step 3: decide where you want to install the compiled executable. - -INSTALLDIR = /usr/local/bin - -# ----------------------------------------------------------------- -# You shouldn't have to change anything from here on down. - -MAJOR = 1 -MINOR = 3 -PATCH = 5 - --include $(GLKINCLUDEDIR)/$(GLKMAKEFILE) - -EXENAME := git-glulx-ml - -CFLAGS = $(OPTIONS) -I$(GLKINCLUDEDIR) - -LIBS = -L$(GLKLIBDIR) $(GLKLIB) $(LINKLIBS) -lm - -HEADERS = version.h git.h config.h compiler.h \ - memory.h opcodes.h labels.inc - -SOURCE = compiler.c gestalt.c git.c git_mac.c git_unix.c \ - git_windows.c glkop.c heap.c memory.c opcodes.c \ - operands.c peephole.c savefile.c saveundo.c \ - search.c terp.c accel.c - -OBJS = git.o memory.o compiler.o opcodes.o operands.o \ - peephole.o terp.o glkop.o search.o git_unix.o \ - savefile.o saveundo.o gestalt.o heap.o accel.o - -TESTS = test/test.sh \ - test/Alabaster.gblorb test/Alabaster.walk test/Alabaster.golden - -all: $(EXENAME) - -$(EXENAME): $(OBJS) - $(CC) $(OPTIONS) -o $@ $(OBJS) $(LIBS) - -install: git - cp $(EXENAME) $(INSTALLDIR)/$(EXENAME) - -clean: - rm -f *~ *.o $(EXENAME) test/*.tmp - -$(OBJS): $(HEADERS) - -version.h: Makefile - echo "// Automatically generated file -- do not edit!" > version.h - echo "#define GIT_MAJOR" $(MAJOR) >> version.h - echo "#define GIT_MINOR" $(MINOR) >> version.h - echo "#define GIT_PATCH" $(PATCH) >> version.h - -DISTZIP = git-$(MAJOR)$(MINOR)$(PATCH).zip - -DISTDIR = git-$(MAJOR).$(MINOR).$(PATCH) - -DISTFILES = README.txt Makefile Makefile.win win $(HEADERS) $(SOURCE) - -dist: $(DISTFILES) - rm -rf $(DISTDIR) - mkdir $(DISTDIR) - cp -r $(DISTFILES) $(DISTDIR) - mkdir $(DISTDIR)/test - cp $(TESTS) $(DISTDIR)/test - find $(DISTDIR) -name "CVS" | xargs rm -rf - rm -f $(DISTZIP) - zip -r $(DISTZIP) $(DISTDIR) - -test: git - sh test/test.sh diff --git a/textworld/thirdparty/glulx/Git-Glulx/Makefile.win b/textworld/thirdparty/glulx/Git-Glulx/Makefile.win deleted file mode 100644 index 5b3946a4..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/Makefile.win +++ /dev/null @@ -1,35 +0,0 @@ -# Makefile for Windows Git, compiled with MinGW GCC 2.95 - -CC = gcc-2 -Wall -O3 -mwindows -OPTIONS = -DUSE_INLINE -DUSE_DIRECT_THREADING -DUSE_OWN_POWF -LIBS = -L. -lglk - -OUTPUT = ../Executables/Release/Git - -CFLAGS = $(OPTIONS) -I../Include - -OBJS = git.o memory.o compiler.o opcodes.o operands.o peephole.o terp.o \ - glkop.o search.o git_windows.o savefile.o saveundo.o gestalt.o \ - accel.o heap.o glk.o res.o - -all: git chm - -git: $(OBJS) libglk.a - $(CC) -s -o $(OUTPUT) $(OBJS) $(LIBS) - -glk.o: ../glk.c - $(CC) $(CFLAGS) -c -o $@ $^ - -res.o: win/git.rc - windres --preprocessor "gcc-2 -E -xc-header -DRC_INVOKED" $^ $@ - -libglk.a: - dlltool --dllname=Glk.dll --def=../GlkDll/Glk.def --output-lib=libglk.a - -chm: - -C:\\Program\ Files\ \(x86\)\\HTML\ Help\ Workshop\\hhc help\\Git.hhp - copy help\\Git.chm ..\\Executables\\Release - -clean: - del *.o *.a - diff --git a/textworld/thirdparty/glulx/Git-Glulx/README.txt b/textworld/thirdparty/glulx/Git-Glulx/README.txt deleted file mode 100644 index 28627ad3..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/README.txt +++ /dev/null @@ -1,299 +0,0 @@ -Git is an interpreter for the Glulx virtual machine. Its homepage is here: - -http://ifarchive.org/indexes/if-archiveXprogrammingXglulxXinterpretersXgit.html - -Git's main goal in life is to be fast. It's about five times faster than Glulxe, -and about twice as fast as Frotz (using the same Inform source compiled for the -Z-machine). It also tries to be reasonably careful with memory: it's possible to -trade speed off against memory by changing the sizes of Git's internal buffers. - -I wrote Git because I want people to be able to write huge games or try out -complicated algorithms without worrying about how fast their games are going to -run. I want to play City of Secrets on a Palm without having to wait ten seconds -between each prompt. - -Have fun, and let me know what you think! - - Iain Merrick (Original author) - iain@diden.net - - David Kinder (Current maintainer) - davidk@davidkinder.co.uk - --------------------------------------------------------------------------------- - -* Building and installing Git - -This is just source code, not a usable application. You'll have to do a bit of -work before you can start playing games with it. If you're not confident about -compiling stuff yourself, you probably want to wait until somebody uploads a -compiled version of Git for your own platform. - -Git needs to be linked with a Glk library in order to run. This can be easy or -hard, depending on what kind of computer you're using and whether you want Git -to be able to display graphics and play sounds. To find a suitable Glk library, -look here: - -http://eblong.com/zarf/glk/ -http://ifarchive.org/indexes/if-archiveXprogrammingXglkXimplementations.html - -Exactly how you build and link everything depends on what platform you're on and -which Glk library you're using. The supplied Makefile should work on any Unix -machine (including Macs with OS X), but you'll probably want to tweak it to -account for your particular setup. If you're not using Unix, I'm afraid you'll -have to play it by ear. If the Glk library you chose comes with instructions, -that's probably a good place to start. - -On Unix, git_unix.c contains the startup code required by the Glk library. -git_mac.c and git_windows.c contain startup code for MacGlk and WinGlk -respectively, but I can't guarantee that they're fully up-to-date. - -It should be possible to build Git with any C compiler, but it works best with -GCC, because that has a non-standard extension that Git can use for a big speed -boost. GCC 2.95 actually generates faster code than later versions, so if you -have a choice, use the former. (On OS X, this means compiling with 'gcc2'.) - --------------------------------------------------------------------------------- - -* Configuring Git - -There are several configuration options you can use when compiling Git. Have a -look at config.h and see which ones look applicable to your platform. The -Makefile includes settings to configure Git for maximum speed on Mac OS X; the -best settings for other Unix platforms should be similar. - -The most important setting is USE_DIRECT_THREADING, which makes the interpreter -engine use GCC's labels-as-values extension, but this only works with GCC 2.95. - --------------------------------------------------------------------------------- - -* Porting to a new platform - -To do a new port, you first need to find a suitable Glk library, or write a new -one. Then you need to write the startup code. Start with a copy of git_unix.c, -git_mac.c or git_windows.c and modify it appropriately. - -The startup code needs to implement the following functions: - - void glk_main() // Standard Glk entrypoint - void fatalError(const char* s) // Display error message and quit - -In glk_main(), you need to locate the game file somehow. Then you have two -options. You can open the game as a Glk stream and pass it to this function: - - extern void gitWithStream (strid_t stream, - git_uint32 cacheSize, - git_uint32 undoSize); - -Or you can load the game yourself, and just pass Git a pointer to your buffer: - - extern void git (const git_uint8 * game, - git_uint32 gameSize, - git_uint32 cacheSize, - git_uint32 undoSize); - -If the operating system provides some way of memory-mapping files (such as -Unix's mmap() system call), you should do that and call git(), because it will -allow the game to start up much more quickly. If you can't do memory-mapping, -you should just open the game as a file stream and call gitWithStream(). Note -that some Glk libraries, such as xglk, aren't compatible with memory-mapped -files. - -"cacheSize" and "undoSize" tell Git what size to use for its two main internal -buffers. Both sizes are in bytes. You may want to make these values -user-configurable, or you may just want to pick values that make sense for your -platform and use those. (My Unix version currently uses fixed values, but I'm -going to add some optional command-line parameters to override these defaults.) - -"cacheSize" is the size of the buffer used to store Glulx code that Git has -recompiled into its internal format. Git will run faster with a larger buffer, -but using a huge buffer is just a waste of memory; 256KB is plenty. - -"undoSize" is the maximum amount of memory used to remember previous moves. The -larger you make it, the more levels of undo will be available. The amount of -memory required to remember one undo position varies from a few KB up to tens of -KB. 256KB is usually enough to store dozens of moves. - --------------------------------------------------------------------------------- - -* Known problems - -GCC 3 has bigger problems than I thought. On PowerPC, the direct threading -option results in much slower code; and on x86, terp.c crashes GCC itself if -direct threading is used. GCC 4 seems to work, given some very limited testing, -but still results in slow code. Therefore, I recommend that you use GCC 2.95 if -possible. If you only have GCC 3, don't define USE_DIRECT_THREADING. - -Some Glk libraries, such as xglk, can't deal with memory-mapped files. You can -tell that this is happening if Git can open .ulx files, but complains that .blb -files are invalid. The solution is to use gitWithStream() rather than git() in -your startup file, and make sure you're giving it a file stream rather than a -memory stream. If you're using the git_unix.c startup file, just make sure -USE_MMAP isn't defined. - -1-byte and 2-byte local variables are not implemented. This means git can't -play games created with old versions of the Superglus system. As these small -local variables now deprecated, it is unlikely that this will be fixed. - -In the search opcodes, direct keys don't work unless they're exactly 4 bytes -long. - --------------------------------------------------------------------------------- - -* Copyright information - -Note: previous versions of Git used an informal freeware license, but I've -decided it's worth formalising. As of version 1.2.3, I've switched to the -MIT license. - -Copyright (c) 2003 Iain Merrick - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------------------------------------------------------------------------- - -* Credits - -Andrew Plotkin invented Glulx, so obviously Git wouldn't exist without him. I -also reused some code from his Glulxe interpreter (glkop.c and search.c), which -saved me a lot of time and let me concentrate on the more interesting stuff. - -Many thanks are due to John Cater, who not only persuaded me to use source -control, but let me use his own CVS server. John also provided lots of useful -advice and encouragement, as did Sean Barrett. - -Thanks also to Joe Mason, Adam Thornton, Simon Baldwin and Joonas Pihlaja who -were among the first to try it out and complain that it wasn't working. Joonas -also gets special brownie points for trying out more bizarre boundary cases than -I realised existed in the first place. - -Tor Andersson was apparently the first person to use setmemsize, since he also -explained why it didn't work and contributed a fix. Thanks, Tor! - -David Kinder has done a stellar job of maintaining the code recently. Thanks -also to Eliuk Blau for tracking down bugs in the memory management opcodes. - --------------------------------------------------------------------------------- - -* Version History - -1.3.5 2016-11-19 Fixed a bug when the streamnum opcode is called with the - smallest possible negative number. - -1.3.4 2015-06-13 Performance improvements from Peter De Wachter, which give - approximately a 15% speed increase. - -1.3.3 2014-03-15 Added acceleration functions 8 through 13, which work - correctly when the Inform 6 compiler setting NUM_ATTR_BYTES - is changed, contributed by Andrew Plotkin. - -1.3.2 2013-03-26 A further fix to glkop.c, following the similar fix added to - Glulxe 0.5.1. - Increased the default undo buffer size in all ports to 2Mb. - -1.3.1 2012-11-09 Further fixes to glkop.c, following similar fixes added to - Glulxe 0.5.0. - -1.3.0 2011-12-16 Fixed a bug in glkop.c dispatching, to do with arrays - of opaque objects, following a similar fix in Glulxe. - Fixed a problem with the memory heap not being sorted - correctly on restore, contributed by Brady Garvin. - -1.2.9 2011-08-28 Fixed a bug in glkop.c dispatching, to do with optional - array arguments, following a similar fix in Glulxe. - Glk array and string operations are now checked for memory - overflows (though not for ROM writing), following a similar - fix in Glulxe. - -1.2.8 2010-08-25 Fixed a problem with 'undo' when compiled as 64 bit, - contributed by Ben Cressey. - Fixed a sign problem for the @fceil opcode, following a - similar fix in Glulxe. - -1.2.7 2010-08-20 Floating point opcode support (VM spec 3.1.2). - Restart does not now discard undo information, so that a - restart can be undone. - -1.2.6 2010-02-09 Imported fix for retained Glk array handling from Glulxe. - -1.2.5 2009-11-21 Fixes for problems shown by Andrew Plotkin's glulxercise test - cases, from David Kinder. - -1.2.4 2009-04-02 More David Kinder! Accelerated opcode support (VM spec 3.1.1). - -1.2.3 2009-02-22 David Kinder and Eliuk Blau fixed some memory management bugs. - Added a regression test (thanks to Emily Short for assistance) - Switched to MIT-style license (see above). - -1.2.2 2009-01-21 malloc & mfree contributed by the most excellent David Kinder. - -1.2.1 2008-09-14 Support for 64-bit machines, contributed by Alexander Beels. - Fix for crashing bug in RESTORE, contributed by David Kinder. - Non-Unicode display bug fix, contributed by Jeremy Bernstein. - -1.2 2008-01-06 Minor version increment for VM spec 3.1. - Implemented mzero and mcopy, but not malloc and mfree (yet). - -1.1.3 2006-10-04 Fixed a bug in the cache logic that broke the game Floatpoint. - Added some other caching tweaks and put in a few more asserts. - -1.1.2 2006-08-22 streamnum in filter I/O mode no longer prints a garbage char. - Merged in David Kinder's updated Windows startup code. - -1.1.1 2006-08-17 Wow, over a year since the last update. - Rolled in Tor Andersson's fix for setmemsize. - -1.1 2004-12-22 Minor version increment because we now implement VM spec 3.0. - Implemented new Unicode opcodes and string types. - -1.0.6 2004-12-10 Random number generator now handles random(0) correctly. - Code cache now tracks the number of function calls properly. - Fixed a bug that could hang the terp when the cache filled up. - -1.0.5 2004-05-31 Random number generator is now initialised properly. - Some source files had Mac line-endings, now fixed. - Version number is now set in the Makefile, not in git.h. - Merged David Kinder's Windows Git code into main distribution. - -1.0.4 2004-03-13 Fixed a silly bug in direct threading mode that broke stkroll. - Memory access bounds checking has been tightened up slightly. - aload and astore now work correctly with negative offsets. - Rewrote the shift opcodes a bit more defensively. - Implemented the "verify" opcode. - Code in RAM is no longer cached by default. - Adding some special opcodes to control the code cache. - Bad instructions are now caught in the terp, not the compiler. - Now passes all of Joonas' indirect string decoding tests. - -1.0.3 2004-01-22 No longer hangs when using streamnum in the "filter" I/O mode. - setstringtbl opcode now works correctly. - -1.0.2 2003-10-25 Stupid bug in 1.0.1 -- gitWithStream() was broken and wasn't - able to load Blorb files. Now it's *really* fixed. - -1.0.1 2003-10-23 Fixed a bug where strings were printed as "[string]" - Fixed a bug in tailcall - Implemented setmemsize - Implemented protect - Moved git_init_dispatch() call out of startup code, into git.c - Added divide-by-zero check - Compiler now stops when it finds a 'quit' or 'restart' - Added gitWithStream() as a workaround for xglk - -1.0 2003-10-18 First public release - diff --git a/textworld/thirdparty/glulx/Git-Glulx/accel.c b/textworld/thirdparty/glulx/Git-Glulx/accel.c deleted file mode 100644 index 8bd7e697..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/accel.c +++ /dev/null @@ -1,642 +0,0 @@ -/* accel.c: Glulxe code for accelerated functions - Designed by Andrew Plotkin - http://eblong.com/zarf/glulx/index.html -*/ - -#include "glk.h" -#include "git.h" - -#define ARGS_REVERSED -#define glulx_malloc malloc - -/* Git passes along function arguments in reverse order. To make our lives - more interesting. */ -#ifdef ARGS_REVERSED -#define ARG(argv, argc, ix) (argv[(argc-1)-ix]) -#else -#define ARG(argv, argc, ix) (argv[ix]) -#endif - -/* Any function can be called with any number of arguments. This macro - lets us snarf a given argument, or zero if it wasn't supplied. */ -#define ARG_IF_GIVEN(argv, argc, ix) ((argc > ix) ? (ARG(argv, argc, ix)) : 0) - -static void accel_error(char *msg); -static glui32 func_1_z__region(glui32 argc, glui32 *argv); -static glui32 func_2_cp__tab(glui32 argc, glui32 *argv); -static glui32 func_3_ra__pr(glui32 argc, glui32 *argv); -static glui32 func_4_rl__pr(glui32 argc, glui32 *argv); -static glui32 func_5_oc__cl(glui32 argc, glui32 *argv); -static glui32 func_6_rv__pr(glui32 argc, glui32 *argv); -static glui32 func_7_op__pr(glui32 argc, glui32 *argv); -static glui32 func_8_cp__tab(glui32 argc, glui32 *argv); -static glui32 func_9_ra__pr(glui32 argc, glui32 *argv); -static glui32 func_10_rl__pr(glui32 argc, glui32 *argv); -static glui32 func_11_oc__cl(glui32 argc, glui32 *argv); -static glui32 func_12_rv__pr(glui32 argc, glui32 *argv); -static glui32 func_13_op__pr(glui32 argc, glui32 *argv); - -static int obj_in_class(glui32 obj); -static glui32 get_prop(glui32 obj, glui32 id); -static glui32 get_prop_new(glui32 obj, glui32 id); - -/* Parameters, set by @accelparam. */ -static glui32 classes_table = 0; /* class object array */ -static glui32 indiv_prop_start = 0; /* first individual prop ID */ -static glui32 class_metaclass = 0; /* "Class" class object */ -static glui32 object_metaclass = 0; /* "Object" class object */ -static glui32 routine_metaclass = 0; /* "Routine" class object */ -static glui32 string_metaclass = 0; /* "String" class object */ -static glui32 self = 0; /* address of global "self" */ -static glui32 num_attr_bytes = 0; /* number of attributes / 8 */ -static glui32 cpv__start = 0; /* array of common prop defaults */ - -typedef struct accelentry_struct { - glui32 addr; - acceleration_func func; - struct accelentry_struct *next; -} accelentry_t; - -#define ACCEL_HASH_SIZE (511) - -static accelentry_t **accelentries = NULL; - -void init_accel() -{ - accelentries = NULL; -} - -acceleration_func accel_find_func(glui32 index) -{ - switch (index) { - case 0: return NULL; /* 0 always means no acceleration */ - case 1: return func_1_z__region; - case 2: return func_2_cp__tab; - case 3: return func_3_ra__pr; - case 4: return func_4_rl__pr; - case 5: return func_5_oc__cl; - case 6: return func_6_rv__pr; - case 7: return func_7_op__pr; - case 8: return func_8_cp__tab; - case 9: return func_9_ra__pr; - case 10: return func_10_rl__pr; - case 11: return func_11_oc__cl; - case 12: return func_12_rv__pr; - case 13: return func_13_op__pr; - } - return NULL; -} - -acceleration_func accel_get_func(glui32 addr) -{ - int bucknum; - accelentry_t *ptr; - - if (!accelentries) - return NULL; - - bucknum = (addr % ACCEL_HASH_SIZE); - for (ptr = accelentries[bucknum]; ptr; ptr = ptr->next) { - if (ptr->addr == addr) - return ptr->func; - } - return NULL; -} - -void accel_set_func(glui32 index, glui32 addr) -{ - int bucknum; - accelentry_t *ptr; - int functype; - acceleration_func new_func = NULL; - - /* Check the Glulx type identifier byte. */ - functype = memRead8(addr); - if (functype != 0xC0 && functype != 0xC1) { - fatalError("Attempt to accelerate non-function."); - } - - if (!accelentries) { - accelentries = (accelentry_t **)glulx_malloc(ACCEL_HASH_SIZE - * sizeof(accelentry_t *)); - if (!accelentries) - fatalError("Cannot malloc acceleration table."); - for (bucknum=0; bucknumnext) { - if (ptr->addr == addr) - break; - } - if (!ptr) { - if (!new_func) { - return; /* no need for a new entry */ - } - ptr = (accelentry_t *)glulx_malloc(sizeof(accelentry_t)); - if (!ptr) - fatalError("Cannot malloc acceleration entry."); - ptr->addr = addr; - ptr->func = NULL; - ptr->next = accelentries[bucknum]; - accelentries[bucknum] = ptr; - } - - ptr->func = new_func; -} - -void accel_set_param(glui32 index, glui32 val) -{ - switch (index) { - case 0: classes_table = val; break; - case 1: indiv_prop_start = val; break; - case 2: class_metaclass = val; break; - case 3: object_metaclass = val; break; - case 4: routine_metaclass = val; break; - case 5: string_metaclass = val; break; - case 6: self = val; break; - case 7: num_attr_bytes = val; break; - case 8: cpv__start = val; break; - } -} - -static void accel_error(char *msg) -{ - glk_put_char('\n'); - glk_put_string(msg); - glk_put_char('\n'); -} - -static int obj_in_class(glui32 obj) -{ - /* This checks whether obj is contained in Class, not whether - it is a member of Class. */ - return (memRead32(obj + 13 + num_attr_bytes) == class_metaclass); -} - -/* Look up a property entry. */ -static glui32 get_prop(glui32 obj, glui32 id) -{ - glui32 cla = 0; - glui32 prop; - glui32 call_argv[2]; - - if (id & 0xFFFF0000) { - cla = memRead32(classes_table+((id & 0xFFFF) * 4)); - ARG(call_argv, 2, 0) = obj; - ARG(call_argv, 2, 1) = cla; - if (func_5_oc__cl(2, call_argv) == 0) - return 0; - - id >>= 16; - obj = cla; - } - - ARG(call_argv, 2, 0) = obj; - ARG(call_argv, 2, 1) = id; - prop = func_2_cp__tab(2, call_argv); - if (prop == 0) - return 0; - - if (obj_in_class(obj) && (cla == 0)) { - if ((id < indiv_prop_start) || (id >= indiv_prop_start+8)) - return 0; - } - - if (memRead32(self) != obj) { - if (memRead8(prop + 9) & 1) - return 0; - } - return prop; -} - -/* Look up a property entry. This is part of the newer set of accel - functions (8 through 13), which support increasing NUM_ATTR_BYTES. - It is identical to get_prop() except that it calls the new versions - of func_5 and func_2. */ -static glui32 get_prop_new(glui32 obj, glui32 id) -{ - glui32 cla = 0; - glui32 prop; - glui32 call_argv[2]; - - if (id & 0xFFFF0000) { - cla = memRead32(classes_table+((id & 0xFFFF) * 4)); - ARG(call_argv, 2, 0) = obj; - ARG(call_argv, 2, 1) = cla; - if (func_11_oc__cl(2, call_argv) == 0) - return 0; - - id >>= 16; - obj = cla; - } - - ARG(call_argv, 2, 0) = obj; - ARG(call_argv, 2, 1) = id; - prop = func_8_cp__tab(2, call_argv); - if (prop == 0) - return 0; - - if (obj_in_class(obj) && (cla == 0)) { - if ((id < indiv_prop_start) || (id >= indiv_prop_start+8)) - return 0; - } - - if (memRead32(self) != obj) { - if (memRead8(prop + 9) & 1) - return 0; - } - return prop; -} - -static glui32 func_1_z__region(glui32 argc, glui32 *argv) -{ - glui32 addr; - glui32 tb; - - if (argc < 1) - return 0; - - addr = ARG(argv, argc, 0); - if (addr < 36) - return 0; - if (addr >= gEndMem) - return 0; - - tb = memRead8(addr); - if (tb >= 0xE0) { - return 3; - } - if (tb >= 0xC0) { - return 2; - } - if (tb >= 0x70 && tb <= 0x7F && addr >= gRamStart) { - return 1; - } - return 0; -} - -/* The old set of accel functions (2 through 7) are deprecated; they - behave badly if the Inform 6 NUM_ATTR_BYTES option (parameter 7) is - changed from its default value (7). They will not be removed, but - new games should use functions 8 through 13 instead. */ - -static glui32 func_2_cp__tab(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 otab, max; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - if (func_1_z__region(1, &obj) != 1) { - accel_error("[** Programming error: tried to find the \".\" of (something) **]"); - return 0; - } - - otab = memRead32(obj + 16); - if (!otab) - return 0; - - max = memRead32(otab); - otab += 4; - /* @binarysearch id 2 otab 10 max 0 0 res; */ - return git_binary_search(id, 2, otab, 10, max, 0, 0); -} - -static glui32 func_3_ra__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 prop; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - prop = get_prop(obj, id); - if (prop == 0) - return 0; - - return memRead32(prop + 4); -} - -static glui32 func_4_rl__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 prop; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - prop = get_prop(obj, id); - if (prop == 0) - return 0; - - return 4 * memRead16(prop + 2); -} - -static glui32 func_5_oc__cl(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 cla; - glui32 zr, prop, inlist, inlistlen, jx; - - obj = ARG_IF_GIVEN(argv, argc, 0); - cla = ARG_IF_GIVEN(argv, argc, 1); - - zr = func_1_z__region(1, &obj); - if (zr == 3) - return (cla == string_metaclass) ? 1 : 0; - if (zr == 2) - return (cla == routine_metaclass) ? 1 : 0; - if (zr != 1) - return 0; - - if (cla == class_metaclass) { - if (obj_in_class(obj)) - return 1; - if (obj == class_metaclass) - return 1; - if (obj == string_metaclass) - return 1; - if (obj == routine_metaclass) - return 1; - if (obj == object_metaclass) - return 1; - return 0; - } - if (cla == object_metaclass) { - if (obj_in_class(obj)) - return 0; - if (obj == class_metaclass) - return 0; - if (obj == string_metaclass) - return 0; - if (obj == routine_metaclass) - return 0; - if (obj == object_metaclass) - return 0; - return 1; - } - if ((cla == string_metaclass) || (cla == routine_metaclass)) - return 0; - - if (!obj_in_class(cla)) { - accel_error("[** Programming error: tried to apply 'ofclass' with non-class **]"); - return 0; - } - - prop = get_prop(obj, 2); - if (prop == 0) - return 0; - - inlist = memRead32(prop + 4); - if (inlist == 0) - return 0; - - inlistlen = memRead16(prop + 2); - for (jx = 0; jx < inlistlen; jx++) { - if (memRead32(inlist + (4 * jx)) == cla) - return 1; - } - return 0; -} - -static glui32 func_6_rv__pr(glui32 argc, glui32 *argv) -{ - glui32 id; - glui32 addr; - - id = ARG_IF_GIVEN(argv, argc, 1); - - addr = func_3_ra__pr(argc, argv); - - if (addr == 0) { - if ((id > 0) && (id < indiv_prop_start)) - return memRead32(cpv__start + (4 * id)); - - accel_error("[** Programming error: tried to read (something) **]"); - return 0; - } - - return memRead32(addr); -} - -static glui32 func_7_op__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 zr; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - zr = func_1_z__region(1, &obj); - if (zr == 3) { - /* print is INDIV_PROP_START+6 */ - if (id == indiv_prop_start+6) - return 1; - /* print_to_array is INDIV_PROP_START+7 */ - if (id == indiv_prop_start+7) - return 1; - return 0; - } - if (zr == 2) { - /* call is INDIV_PROP_START+5 */ - return ((id == indiv_prop_start+5) ? 1 : 0); - } - if (zr != 1) - return 0; - - if ((id >= indiv_prop_start) && (id < indiv_prop_start+8)) { - if (obj_in_class(obj)) - return 1; - } - - return ((func_3_ra__pr(argc, argv)) ? 1 : 0); -} - -/* Here are the newer functions, which support changing NUM_ATTR_BYTES. - These call get_prop_new() instead of get_prop(). */ - -static glui32 func_8_cp__tab(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 otab, max; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - if (func_1_z__region(1, &obj) != 1) { - accel_error("[** Programming error: tried to find the \".\" of (something) **]"); - return 0; - } - - otab = memRead32(obj + 4*(3+(int)(num_attr_bytes/4))); - if (!otab) - return 0; - - max = memRead32(otab); - otab += 4; - /* @binarysearch id 2 otab 10 max 0 0 res; */ - return git_binary_search(id, 2, otab, 10, max, 0, 0); -} - -static glui32 func_9_ra__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 prop; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - prop = get_prop_new(obj, id); - if (prop == 0) - return 0; - - return memRead32(prop + 4); -} - -static glui32 func_10_rl__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 prop; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - prop = get_prop_new(obj, id); - if (prop == 0) - return 0; - - return 4 * memRead16(prop + 2); -} - -static glui32 func_11_oc__cl(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 cla; - glui32 zr, prop, inlist, inlistlen, jx; - - obj = ARG_IF_GIVEN(argv, argc, 0); - cla = ARG_IF_GIVEN(argv, argc, 1); - - zr = func_1_z__region(1, &obj); - if (zr == 3) - return (cla == string_metaclass) ? 1 : 0; - if (zr == 2) - return (cla == routine_metaclass) ? 1 : 0; - if (zr != 1) - return 0; - - if (cla == class_metaclass) { - if (obj_in_class(obj)) - return 1; - if (obj == class_metaclass) - return 1; - if (obj == string_metaclass) - return 1; - if (obj == routine_metaclass) - return 1; - if (obj == object_metaclass) - return 1; - return 0; - } - if (cla == object_metaclass) { - if (obj_in_class(obj)) - return 0; - if (obj == class_metaclass) - return 0; - if (obj == string_metaclass) - return 0; - if (obj == routine_metaclass) - return 0; - if (obj == object_metaclass) - return 0; - return 1; - } - if ((cla == string_metaclass) || (cla == routine_metaclass)) - return 0; - - if (!obj_in_class(cla)) { - accel_error("[** Programming error: tried to apply 'ofclass' with non-class **]"); - return 0; - } - - prop = get_prop_new(obj, 2); - if (prop == 0) - return 0; - - inlist = memRead32(prop + 4); - if (inlist == 0) - return 0; - - inlistlen = memRead16(prop + 2); - for (jx = 0; jx < inlistlen; jx++) { - if (memRead32(inlist + (4 * jx)) == cla) - return 1; - } - return 0; -} - -static glui32 func_12_rv__pr(glui32 argc, glui32 *argv) -{ - glui32 id; - glui32 addr; - - id = ARG_IF_GIVEN(argv, argc, 1); - - addr = func_9_ra__pr(argc, argv); - - if (addr == 0) { - if ((id > 0) && (id < indiv_prop_start)) - return memRead32(cpv__start + (4 * id)); - - accel_error("[** Programming error: tried to read (something) **]"); - return 0; - } - - return memRead32(addr); -} - -static glui32 func_13_op__pr(glui32 argc, glui32 *argv) -{ - glui32 obj; - glui32 id; - glui32 zr; - - obj = ARG_IF_GIVEN(argv, argc, 0); - id = ARG_IF_GIVEN(argv, argc, 1); - - zr = func_1_z__region(1, &obj); - if (zr == 3) { - /* print is INDIV_PROP_START+6 */ - if (id == indiv_prop_start+6) - return 1; - /* print_to_array is INDIV_PROP_START+7 */ - if (id == indiv_prop_start+7) - return 1; - return 0; - } - if (zr == 2) { - /* call is INDIV_PROP_START+5 */ - return ((id == indiv_prop_start+5) ? 1 : 0); - } - if (zr != 1) - return 0; - - if ((id >= indiv_prop_start) && (id < indiv_prop_start+8)) { - if (obj_in_class(obj)) - return 1; - } - - return ((func_9_ra__pr(argc, argv)) ? 1 : 0); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/compiler.c b/textworld/thirdparty/glulx/Git-Glulx/compiler.c deleted file mode 100644 index 6faa94c5..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/compiler.c +++ /dev/null @@ -1,579 +0,0 @@ -// $Id: compiler.c,v 1.27 2004/12/10 00:37:00 iain Exp $ - -#include "git.h" -#include -#include -#include -#include - -// ------------------------------------------------------------- -// Constants - -enum -{ - LONGJMP_NO_ERROR = 0, - LONGJMP_CACHE_FULL = 1, - LONGJMP_BAD_OPCODE = 2 -}; - -// ------------------------------------------------------------- -// Globals - -int gPeephole = 1; -int gDebug = 0; -int gCacheRAM = 0; - -BlockHeader * gBlockHeader; - -const char * gLabelNames [] = { -#define LABEL(label) #label, -#include "labels.inc" - NULL -}; - -HashNode ** gHashTable; // Hash table of glulx address -> code. -git_uint32 gHashSize; // Number of slots in the hash table. - -// ------------------------------------------------------------- -// Types. - -typedef struct PatchNode -{ - git_uint32 address; // The glulx address of this instruction. - git_sint16 codeOffset; // Offset from the block header to the compiled code for this instruction. - git_sint16 branchOffset; // If non-zero, offset to a branch opcode followed by a glulx address. - union { - int isReferenced; // Set to TRUE if this can be the destination of a jump. - HashNode* pad; // This pad assures that PatchNode and HashNode are the same size. - } u; -} -PatchNode; - -// ------------------------------------------------------------- -// Static variables. - -static git_uint32 * sBuffer; // The buffer where everything is stored. -static git_uint32 sBufferSize; // Size of the buffer, in 4-byte words. - -static Block sCodeStart; // Start of code cache. -static Block sCodeTop; // Next free space in code cache. -static PatchNode* sTempStart; // Start of temporary storage. -static PatchNode* sTempEnd; // End of temporary storage. - -static jmp_buf sJumpBuf; // setjmp buffer, used to abort compilation when the buffer is full. - -// This is the patch node for the opcode currently being compiled. -// The 'address' and 'code' fields will be filled in. The other -// fields can be updated during compilation as necessary. -static PatchNode * sPatch; - -static int sNextInstructionIsReferenced; -static git_uint32 sLastAddr; - -// ------------------------------------------------------------- -// Functions - -void initCompiler (size_t size) -{ - static BlockHeader dummyHeader; - gBlockHeader = &dummyHeader; - - // Make sure various assumptions we're making are correct. - - assert (sizeof(HashNode) <= sizeof(PatchNode)); - - // Allocate the buffer. As far as possible, we're going to - // use this buffer for everything compiler-related, and - // avoid further dynamic allocation. - - sBuffer = malloc (size); - if (sBuffer == NULL) - fatalError ("Couldn't allocate code cache"); - - memset (sBuffer, 0, size); - sBufferSize = size / 4; - - // Pick a reasonable size for the hash table. This should be - // a power of two, and take up about a tenth of the buffer. - // (If the buffer is itself a power of two in size, the hash - // table will take up a sixteenth of it, which is fine.) - - gHashSize = 1; - while (gHashSize < (sBufferSize / 20)) - gHashSize *= 2; - - // The hash table is stored at the beginning of the buffer, - // and the rest is used for code and temporary storage. - - gHashTable = (HashNode**) sBuffer; - - sCodeStart = sCodeTop = (Block) (gHashTable + gHashSize); - sTempStart = sTempEnd = (PatchNode*) (sBuffer + sBufferSize); -} - -void shutdownCompiler () -{ - free (sBuffer); - - sBuffer = NULL; - sCodeStart = sCodeTop = NULL; - sTempStart = sTempEnd = NULL; - - gHashTable = NULL; - gBlockHeader = NULL; -} - -static void abortIfBufferFull () -{ - // Make sure we have at least two words free, - // because we'll need them to store a jumpabs - // instruction at the very end of the buffer. - - if ((void*) (sCodeTop + 2) >= (void*) sTempStart) - longjmp (sJumpBuf, LONGJMP_CACHE_FULL); -} - -void abortCompilation () -{ - longjmp (sJumpBuf, LONGJMP_BAD_OPCODE); -} - -void nextInstructionIsReferenced () -{ - sNextInstructionIsReferenced = 1; -} - -Block compile (git_uint32 pc) -{ - git_uint32 endOfBlock; - int i, numNodes; - - // Make sure we have enough room for, at a minimum: - // - the block header - // - one patch node - // - one jumpabs instruction (two words). - - int spaceNeeded = (sizeof(BlockHeader) + sizeof(PatchNode) + 8) / 4; - if ((void*) (sCodeTop + spaceNeeded) >= (void*) sTempStart) - { - compressCodeCache(); - } - - // Emit the header for this block. - - gBlockHeader = (BlockHeader*) sCodeTop; - sCodeTop = (git_uint32*) (gBlockHeader + 1); - - sLastAddr = 0; - sNextInstructionIsReferenced = 1; - resetPeepholeOptimiser(); - - sPatch = NULL; - - i = setjmp (sJumpBuf); - if (i == LONGJMP_NO_ERROR) - { - git_uint32 patchSize = 0; - git_uint32 codeSize = 0; - - int done = 0; - - while (!done) - { - // If we don't have room for more code, abort. - if ((void*) (sCodeTop + 2) >= (void*) (sTempStart - 1)) - { - longjmp (sJumpBuf, LONGJMP_CACHE_FULL); - } - - // Create a temporary patch node for this instruction. - --sTempStart; - sPatch = sTempStart; - sPatch->address = pc; - sPatch->codeOffset = sCodeTop - (git_uint32*)gBlockHeader; - sPatch->branchOffset = 0; - sPatch->u.isReferenced = sNextInstructionIsReferenced; - - sNextInstructionIsReferenced = 0; - - // Make sure we haven't generated over 32K of code. - - patchSize += sizeof(PatchNode) / 4; - codeSize = sCodeTop - (git_uint32*)gBlockHeader; - - if (codeSize + patchSize > 32000) - { - // We've generated almost 32K words of code, which will - // start to cause problems for the 16-bit offsets we use - // in the hash nodes, so let's just stop here. - longjmp (sJumpBuf, LONGJMP_CACHE_FULL); - } - - // Parse the next instruction. - - parseInstruction (&pc, &done); - - if (pc < sLastAddr) - done = 0; - } - } - else - { - // Compilation was aborted, but we should have a - // patch node and at least two words of space free. - - assert (sPatch != NULL); - sPatch->branchOffset = 0; // Make sure the patch isn't treated as a branch. - - sCodeTop = ((git_uint32*)gBlockHeader) + sPatch->codeOffset; - - if (i == LONGJMP_CACHE_FULL) - { - // The buffer is full. We'll replace the partially-compiled - // instruction with a jumpabs, forcing another cache lookup - // when the terp hits this point in the code. - - *sCodeTop++ = (git_uint32) labelToOpcode (label_recompile); - *sCodeTop++ = sPatch->address; - - // Make sure this node doesn't get put into the hash table. - sPatch->u.isReferenced = 0; - } - else if (i == LONGJMP_BAD_OPCODE) - { - // We found a badly-formed instruction. We'll replace the - // partially-compiled instruction with a label that raises - // an error if the terp hits this code location. - - *sCodeTop++ = (git_uint32) labelToOpcode (label_error_bad_opcode); - *sCodeTop++ = sPatch->address; - } - else - { - fatalError ("unknown error in compile (BUG)"); - } - } - - assert ((void*) sCodeTop <= (void*) sTempStart); - - // We now know where the block ends. - - endOfBlock = pc; - - // Fix up the constant branches. - - numNodes = sTempEnd - sTempStart; - for (i = 0 ; i < numNodes ; ++i) - { - git_uint32* constBranch; - - git_uint32 dest; - git_uint32 lower = 0; - git_uint32 upper = numNodes; - - PatchNode * p = sTempStart + i; - if (p->branchOffset == 0) - continue; - - constBranch = ((git_uint32*)gBlockHeader) + p->branchOffset; - dest = constBranch [1]; - while (upper > lower) - { - git_uint32 guess = (lower + upper) / 2; - PatchNode * p2 = sTempStart + guess; - if (p2->address == dest) - { - git_uint32 * op = constBranch; - git_uint32 * by = constBranch + 1; - - // Change the 'const' branch to a 'by' branch. - *op = *op - label_jump_const + label_jump_by; - - // Turn the address into a relative offset. - *by = ((git_uint32*)gBlockHeader + p2->codeOffset) - (constBranch + 2); - - // And we're done. - break; - } - else if (p2->address > dest) - lower = guess + 1; - else - upper = guess; - } - - // Whether we found the branch destination or not, - // turn the label into a real opcode. - *constBranch = (git_uint32) labelToOpcode (*constBranch); - } - - // Convert all the referenced addresses into hash table nodes, - // as long as they're not in RAM. - - numNodes = 0; - for ( ; sTempStart < sTempEnd ; ++sTempStart) - { - // 'pc' holds the address of *end* of the instruction, - // so we'll use that to determine whether it overlaps - // the start of RAM. - - int isInRAM = (pc > gRamStart); - - // Set the PC to the start of the instruction, since - // that's equal to the end of the previous instruction. - - pc = sTempStart->address; - - if (isInRAM && !gCacheRAM) - continue; - - // If we're not skipping this instruction, and it's - // referenced somewhere, attach it to the hash table. - - if (sTempStart->u.isReferenced) - { - HashNode * node = (HashNode*) sCodeTop; - sCodeTop = (git_uint32*) (node + 1); - - node->address = sTempStart->address; - node->headerOffset = (git_uint32*)gBlockHeader - (git_uint32*)node; - node->codeOffset = node->headerOffset + sTempStart->codeOffset; - - node->u.next = gHashTable [node->address & (gHashSize-1)]; - gHashTable [node->address & (gHashSize-1)] = node; - - ++numNodes; - } - } - - // Write the block header. - - assert (sCodeTop - (git_uint32*) gBlockHeader < 32767); - - gBlockHeader->numHashNodes = numNodes; - gBlockHeader->compiledSize = sCodeTop - (git_uint32*) gBlockHeader; - gBlockHeader->glulxSize = endOfBlock - pc; - gBlockHeader->runCounter = 0; - - assert(gBlockHeader->compiledSize > 0); - - // And we're done. - return (git_uint32*) (gBlockHeader + 1); -} - -#define END_OF_BLOCK(header) ((void*) (((git_uint32*)header) + header->compiledSize)) - -static git_uint32 findCutoffPoint () -{ - BlockHeader * start = (BlockHeader*) sCodeStart; - BlockHeader * top = (BlockHeader*) sCodeTop; - BlockHeader * h; - - git_uint32 blockCount = 0; - git_uint32 runCount = 0; - - for (h = start ; h < top ; h = END_OF_BLOCK(h)) - { - if (h->glulxSize > 0) - { - ++blockCount; - } - } - - for (h = start ; h < top ; h = END_OF_BLOCK(h)) - { - if (h->glulxSize > 0) - { - runCount += (h->runCounter + blockCount + 1) / blockCount; - } - } - - return runCount / 2; -} - -static void compressWithCutoff (git_uint32 cutoff) -{ - BlockHeader * start = (BlockHeader*) sCodeStart; - BlockHeader * top = (BlockHeader*) sCodeTop; - BlockHeader * h = start; - - git_uint32 saveCount = 0; - git_uint32 deleteCount = 0; - - sCodeTop = sCodeStart; - - while (h < top) - { - BlockHeader * next = END_OF_BLOCK(h); - if (h->runCounter >= cutoff && h->glulxSize > 0) - { - git_uint32 size = h->compiledSize; - - // Lower the run count of the saved blocks so that they'll - // stick around in the short term, but eventually fall out - // of the cache if they're not used much in the future. - h->runCounter /= 2; - - memmove (sCodeTop, h, size * sizeof(git_uint32)); - sCodeTop += size; - ++saveCount; - } - else - { - ++deleteCount; - } - h = next; - } -} - -static void rebuildHashTable () -{ - BlockHeader * start = (BlockHeader*) sCodeStart; - BlockHeader * top = (BlockHeader*) sCodeTop; - BlockHeader * h; - - memset (gHashTable, 0, gHashSize * sizeof(HashNode*)); - - for (h = start ; h < top ; h = END_OF_BLOCK(h)) - { - if (h->glulxSize > 0) - { - HashNode * node = END_OF_BLOCK(h); - git_uint32 i; - for (i = 0 ; i < h->numHashNodes ; ++i) - { - --node; - node->u.next = gHashTable [node->address & (gHashSize-1)]; - gHashTable [node->address & (gHashSize-1)] = node; - } - } - } -} - -static void removeHashNode (HashNode* deadNode) -{ - HashNode* n = gHashTable [deadNode->address & (gHashSize-1)]; - assert (deadNode != NULL); - - if (n == NULL) - { - // This hash bucket is empty! We have nothing to do. - } - else if (n == deadNode) - { - // The node to be removed is the first one in its bucket. - gHashTable [deadNode->address & (gHashSize-1)] = NULL; - } - else - { - // The node to be removed is somewhere in the middle - // of the bucket. Step along the linked list until - // we find it. - - while (n->u.next != deadNode) - n = n->u.next; - - // Unlink it from the linked list. - n->u.next = deadNode->u.next; - } -} - -void pruneCodeCache (git_uint32 address, git_uint32 size) -{ - BlockHeader * start = (BlockHeader*) sCodeStart; - BlockHeader * top = (BlockHeader*) sCodeTop; - BlockHeader * h; - - // Step through the cache, looking for blocks that overlap the - // specified range. If we find any, remove their nodes from the - // hash table, and set glulxSize to 0 so that they're dropped - // the next time we clean up the cache. - - for (h = start ; h < top ; h = END_OF_BLOCK(h)) - { - // The start address of the block is in its final hash node. - - HashNode * node = END_OF_BLOCK(h); - git_uint32 glulxAddr = node[-1].address; - - if (glulxAddr < (address + size) && (glulxAddr + h->glulxSize) > address) - { - // This block overlaps the range of code that has to be pruned. - - git_uint32 i; - for (i = 0 ; i < h->numHashNodes ; ++i) - { - --node; - removeHashNode (node); - } - - h->glulxSize = 0; - } - } -} - -void compressCodeCache () -{ - git_uint32 n; - git_uint32 spaceUsed, spaceFree; - - n = findCutoffPoint(); - compressWithCutoff (n); - rebuildHashTable (); - - spaceUsed = sCodeTop - sCodeStart; - spaceFree = sBufferSize - spaceUsed - gHashSize; - -// { -// char buffer [100]; -// sprintf (buffer, "[Cache cleanup: %d bytes used, %d free]\n", -// spaceUsed * 4, spaceFree * 4); -// glk_put_string (buffer); -// } - - // If that didn't free up at least a quarter of the cache, - // clear it out entirely. - - if (spaceFree * 3 < spaceUsed) - resetCodeCache(); -} - -void resetCodeCache () -{ -// glk_put_string ("[resetting cache]\n"); - - memset (sBuffer, 0, sBufferSize * 4); - sCodeStart = sCodeTop = (Block) (gHashTable + gHashSize); - sTempStart = sTempEnd = (PatchNode*) (sBuffer + sBufferSize); -} - -Block peekAtEmittedStuff (int numOpcodes) -{ - return sCodeTop - numOpcodes; -} - -void emitConstBranch (Label op, git_uint32 address) -{ - sPatch->branchOffset = sCodeTop - (git_uint32*)gBlockHeader; - emitData (op); - emitData (address); - - if (sLastAddr < address) - sLastAddr = address; -} - -void emitData (git_uint32 val) -{ - abortIfBufferFull (); - *sCodeTop++ = val; -} - -extern void emitFinalCode (Label op) -{ - abortIfBufferFull (); - *sCodeTop++ = (git_uint32) labelToOpcode (op); -} - -extern git_uint32 undoEmit () -{ - return *--sCodeTop; -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/compiler.h b/textworld/thirdparty/glulx/Git-Glulx/compiler.h deleted file mode 100644 index f68df5a1..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/compiler.h +++ /dev/null @@ -1,109 +0,0 @@ -// Header for compiler.c -// $Id: compiler.h,v 1.11 2004/02/02 00:13:46 iain Exp $ - -#ifndef GIT_COMPILER_H -#define GIT_COMPILER_H - -// ------------------------------------------------------------- -// Types - -typedef enum -{ -#define LABEL(foo) label_ ## foo, -#include "labels.inc" - MAX_LABEL -} -Label; - -#ifdef USE_DIRECT_THREADING -typedef void* Opcode; // Generated opcode: pointer to a label in exec(). -#else -typedef Label Opcode; -#endif - -typedef git_uint32* Block; // Generated code block: array of labels. - -// ------------------------------------------------------------- -// Settings - -extern int gPeephole; // Peephole optimisation of generated code? -extern int gDebug; // Insert debug statements into generated code? -extern int gCacheRAM; // Keep RAM-based code in the JIT cache? - -// ------------------------------------------------------------- -// Compiling code - -extern const char* gLabelNames[]; - -extern void initCompiler (size_t cacheSize); -extern void shutdownCompiler (); - -extern void emitData (git_uint32); -extern void emitFinalCode (Label); -extern void emitConstBranch (Label op, git_uint32 address); - -extern void abortCompilation (); - -extern git_uint32 undoEmit(); -extern void nextInstructionIsReferenced (); - -extern Block peekAtEmittedStuff (int numOpcodes); - -// ------------------------------------------------------------- -// Accessing compiled code - -extern void pruneCodeCache (git_uint32 start, git_uint32 size); -extern void resetCodeCache (); -extern void compressCodeCache (); - -extern Block compile (git_uint32 pc); - -typedef struct HashNode HashNode; - -struct HashNode -{ - git_uint32 address; // Glulx address for this entry. - git_sint16 codeOffset; // Offset in 4-byte words from this hash node to the compiled code. - git_sint16 headerOffset; // Offset in 4-byte words from this hash node to the block header. - union { - int pad; // This pad assures that PatchNode and HashNode are the same size. - HashNode * next; // Next node in the same hash table slot. - } u; -}; - -typedef struct BlockHeader -{ - git_uint16 numHashNodes; // Number of lookup-able addresses in this block. - git_uint16 compiledSize; // Total size of this block, in 4-byte words. - git_uint32 glulxSize; // Size of the glulx code this block represents, in bytes. - git_uint32 runCounter; // Total number of times this block was retrieved from the cache -} // (used to determine which blocks stay in the cache) -BlockHeader; - -// This is the header for the block currently being executed -- -// that is, the one containing the return value of the last call -// to getCode(). -extern BlockHeader * gBlockHeader; - -// Hash table for code lookup -- inlined for speed - -extern HashNode ** gHashTable; // Hash table of glulx address -> code. -extern git_uint32 gHashSize; // Number of slots in the hash table. - -GIT_INLINE Block getCode (git_uint32 pc) -{ - HashNode * n = gHashTable [pc & (gHashSize-1)]; - while (n) - { - if (n->address == pc) - { - gBlockHeader = (BlockHeader*) ((git_uint32*)n + n->headerOffset); - gBlockHeader->runCounter++; - return (git_uint32*)n + n->codeOffset; - } - n = n->u.next; - } - return compile (pc); -} - -#endif // GIT_COMPILER_H diff --git a/textworld/thirdparty/glulx/Git-Glulx/config.h b/textworld/thirdparty/glulx/Git-Glulx/config.h deleted file mode 100644 index e61b13e8..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/config.h +++ /dev/null @@ -1,100 +0,0 @@ -// $Id: config.h,v 1.4 2003/10/18 23:19:52 iain Exp $ -// Platform-dependent configuration for Git - -#ifndef GIT_CONFIG_H -#define GIT_CONFIG_H - -// Various compile-time options. You can define them in the -// makefile or uncomment them here, whichever's easiest. - -// Define if we're big-endian and can read and write unaligned data. -// #define USE_BIG_ENDIAN_UNALIGNED - -// Define this to use GCC's labels-as-values extension for a big speedup. -// #define USE_DIRECT_THREADING - -// Define this if we can use the "inline" keyword. -// #define USE_INLINE - -// Define this to memory-map the game file to speed up loading. (Unix-specific) -// #define USE_MMAP - -// Define this to use an OS-specific git_powf() power math function. This -// is useful if your compiler's powf() doesn't implement every special case -// of the C99 standard. -// #define USE_OWN_POWF - -// ------------------------------------------------------------------- - -// Make sure we're compiling for a sane platform. For now, this means -// 8-bit bytes and 32-bit pointers. We'll support 64-bit machines at -// some point in the future, but we will probably never support machines -// that can't read memory 8 bits at a time; it's just too much hassle. - -#include - -#if CHAR_BIT != 8 -#error "Git needs 8-bit bytes" -#endif - -// This check doesn't work on all compilers, unfortunately. -// It's checked by an assert() at runtime in initCompiler(). -#if 0 -// #if sizeof(void*) != 4 -#error "Git needs 32-bit pointers" -#endif - -// Now we determine what types to use for 8-bit, 16-bit and 32-bit ints. - -#if UCHAR_MAX==0xff -typedef signed char git_sint8; -typedef unsigned char git_uint8; -#else -#error "Can't find an 8-bit integer type" -#endif - -#if SHRT_MAX==0x7fff -typedef signed short git_sint16; -typedef unsigned short git_uint16; -#elif INT_MAX==0x7fff -typedef signed int git_sint16; -typedef unsigned int git_uint16; -#else -#error "Can't find a 16-bit integer type" -#endif - -#if INT_MAX==0x7fffffff -typedef signed int git_sint32; -typedef unsigned int git_uint32; -#elif LONG_MAX==0x7fffffff -typedef signed long git_sint32; -typedef unsigned long git_uint32; -#else -#error "Can't find a 32-bit integer type" -#endif - -// USE_INLINE is pretty simple to deal with. - -#ifdef USE_INLINE -#define GIT_INLINE static inline -#else -#define GIT_INLINE static -#endif - -typedef float git_float; - - -#if defined(__GNUC__) -// GCC and compatible compilers such as clang -# define maybe_unused __attribute__((__unused__)) -# define git_noreturn __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -// Microsoft Visual Studio -# define maybe_unused -# define git_noreturn __declspec(noreturn) -#else -# define maybe_unused -# define git_noreturn -#endif - -#endif // GIT_CONFIG_H diff --git a/textworld/thirdparty/glulx/Git-Glulx/gestalt.c b/textworld/thirdparty/glulx/Git-Glulx/gestalt.c deleted file mode 100644 index 2fabcdab..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/gestalt.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "git.h" - -git_uint32 gestalt (enum GestaltSelector sel, git_uint32 param) -{ - switch (sel) - { - case GESTALT_SPEC_VERSION: - return 0x00030102; - - case GESTALT_TERP_VERSION: - return GIT_VERSION_NUM; - - case GESTALT_RESIZEMEM: - return 1; - - case GESTALT_UNDO: - return 1; - - case GESTALT_IO_SYSTEM: - if (param == IO_NULL || param == IO_FILTER || param == IO_GLK) - return 1; - else - return 0; - - case GESTALT_UNICODE: - return 1; - - case GESTALT_MEM_COPY: - return 1; - - case GESTALT_MALLOC: - return 1; - - case GESTALT_MALLOC_HEAP: - return heap_get_start(); - - case GESTALT_ACCELERATION: - return 1; - - case GESTALT_ACCELFUNC: - if (accel_find_func(param)) - return 1; - return 0; - - case GESTALT_FLOAT: - return 1; - - case GESTALT_GIT_CACHE_CONTROL: - return 1; - - default: // Unknown selector. - return 0; - } -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/git.c b/textworld/thirdparty/glulx/Git-Glulx/git.c deleted file mode 100644 index 65c35776..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/git.c +++ /dev/null @@ -1,176 +0,0 @@ -// $Id: git.c,v 1.21 2004/12/22 12:40:07 iain Exp $ - -#include "git.h" -#include -#include -#include - -// The four-char code 'FORM' as a big-endian value. -// This is the magic number at the start of Blorb files. -#define FORM 0x464f524d - -static void gitMain (const git_uint8 * game, git_uint32 gameSize, git_uint32 cacheSize, git_uint32 undoSize) -{ - git_uint32 version; - enum IOMode ioMode = IO_NULL; - - init_accel (); - - // Initialise the Glk dispatch layer. - git_init_dispatch(); - - // Set various globals. - gPeephole = 1; - gDebug = 0; - - // Load the gamefile into memory - // and initialise undo records. - initMemory (game, gameSize); - initUndo (undoSize); - - // Check that we're compatible with the - // glulx spec version that the game uses. - version = memRead32 (4); - if (version == 0x010000 && version <= 0x0100FF) - { - // We support version 1.0.0 even though it's - // officially obsolete. The only significant - // difference is the lack of I/O modes. In 1.0, - // all output goes directly to the Glk library. - ioMode = IO_GLK; - } - else if (version == 0x020000 && version <= 0x0200FF) - { - // We support version 2.0, which most people currently use. - } - else if (version >= 0x030000 && version <= 0x0300FF) - { - // We support version 3.0, which adds Unicode functionality. - } - else if (version >= 0x030100 && version <= 0x0301FF) - { - // We support version 3.1, which adds some memory-management opcodes. - } - else - { - fatalError ("Can't run this game, because it uses a newer version " - "of the gamefile format than Git understands. You should check " - "whether a newer version of Git is available."); - } - - // Call the top-level function. - startProgram (cacheSize, ioMode); - - // Shut everything down cleanly. - shutdownUndo(); - shutdownMemory(); -} - -static giblorb_result_t handleBlorb (strid_t stream) -{ - giblorb_err_t err; - giblorb_result_t blorbres; - giblorb_map_t *map; - - err = giblorb_set_resource_map (stream); - switch (err) - { - case giblorb_err_None: - break; - - case giblorb_err_CompileTime: - fatalError ("Can't read the Blorb file because something is compiled wrong in the Blorb library."); - case giblorb_err_Alloc: - fatalError ("Can't read the Blorb file because there isn't enough memory available."); - case giblorb_err_Read: - fatalError ("Can't read data from the Blorb file."); - case giblorb_err_Format: - fatalError ("Can't read the Blorb file because it seems to be corrupted."); - default: - fatalError ("Can't read the Blorb file because an unknown error occurred."); - } - - map = giblorb_get_resource_map(); - if (map == NULL) - fatalError ("Can't find the Blorb file's resource map."); - - err = giblorb_load_resource(map, giblorb_method_FilePos, &blorbres, giblorb_ID_Exec, 0); - if (err) - fatalError ("This Blorb file does not contain an executable Glulx chunk."); - - if (blorbres.chunktype != giblorb_make_id('G', 'L', 'U', 'L')) - fatalError ("This Blorb file contains an executable chunk, but it is not a Glulx file."); - - return blorbres; -} - -void gitWithStream (strid_t str, git_uint32 cacheSize, git_uint32 undoSize) -{ - char * game; - git_uint32 gamePos; - git_uint32 gameSize; - - git_uint32 remaining; - char * ptr; - - char buffer [4]; - - glk_stream_set_position (str, 0, seekmode_Start); - if (4 != glk_get_buffer_stream (str, buffer, 4)) - fatalError ("can't read from game file stream"); - - if (readtag (buffer) == FORM) - { - giblorb_result_t result = handleBlorb (str); - gamePos = result.data.startpos; - gameSize = result.length; - } - else - { - gamePos = 0; - glk_stream_set_position (str, 0, seekmode_End); - gameSize = glk_stream_get_position (str); - } - - game = malloc (gameSize); - if (game == NULL) - fatalError ("failed to allocate memory to store game file"); - - glk_stream_set_position (str, gamePos, seekmode_Start); - - remaining = gameSize; - ptr = game; - while (remaining > 0) - { - git_uint32 n = glk_get_buffer_stream (str, ptr, remaining); - if (n == 0) - fatalError ("failed to read entire game file"); - remaining -= n; - ptr += n; - } - - gitMain ((git_uint8 *) game, gameSize, cacheSize, undoSize); - free (game); -} - -void git (const git_uint8 * game, git_uint32 gameSize, git_uint32 cacheSize, git_uint32 undoSize) -{ - // If this is a blorb file, register it - // with glk and find the gamefile chunk. - - if (read32 (game) == FORM) - { - strid_t stream; - giblorb_result_t result; - - stream = glk_stream_open_memory ((char *) game, gameSize, filemode_Read, 0); - if (stream == NULL) - fatalError ("Can't open the Blorb file as a Glk memory stream."); - - result = handleBlorb (stream); - game += result.data.startpos; - gameSize = result.length; - } - - gitMain (game, gameSize, cacheSize, undoSize); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/git.h b/textworld/thirdparty/glulx/Git-Glulx/git.h deleted file mode 100644 index ce4d00fb..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/git.h +++ /dev/null @@ -1,172 +0,0 @@ -// Main header for git -// $Id: git.h,v 1.32 2004/12/22 12:40:07 iain Exp $ - -#ifndef GIT_H -#define GIT_H - -#include -#include -#include -#include - -#include "version.h" -#include "config.h" - -// Version number formatting - -#define GIT_VERSION_NUM (GIT_MAJOR << 16) \ - | (GIT_MINOR << 8) \ - | (GIT_PATCH) - -#define _str2(s) #s -#define _str(s) _str2(s) - -#define GIT_VERSION_STR \ -_str(GIT_MAJOR) "." _str(GIT_MINOR) "." _str(GIT_PATCH) - -// git.c - -extern void gitWithStream (strid_t stream, - git_uint32 cacheSize, - git_uint32 undoSize); - -extern void git (const git_uint8 * game, - git_uint32 gameSize, - git_uint32 cacheSize, - git_uint32 undoSize); - -extern git_noreturn void fatalError (const char *); - -// memory.c - -#include "memory.h" - -// gestalt.c - -enum IOMode -{ - IO_NULL = 0, - IO_FILTER = 1, - IO_GLK = 2, - IO_MAX -}; - -enum GestaltSelector -{ - GESTALT_SPEC_VERSION = 0, - GESTALT_TERP_VERSION = 1, - GESTALT_RESIZEMEM = 2, - GESTALT_UNDO = 3, - GESTALT_IO_SYSTEM = 4, - GESTALT_UNICODE = 5, - GESTALT_MEM_COPY = 6, - GESTALT_MALLOC = 7, - GESTALT_MALLOC_HEAP = 8, - GESTALT_ACCELERATION = 9, - GESTALT_ACCELFUNC = 10, - GESTALT_FLOAT = 11, - - // This special selector returns 1 if the cache control - // opcodes 'git_setcacheram' and 'git_prunecache' are available. - - GESTALT_GIT_CACHE_CONTROL = 0x7940 -}; - -extern git_uint32 gestalt (enum GestaltSelector sel, git_uint32 param); - -// opcodes.c - -extern void parseInstruction (git_uint32 * pc, int * done); - -// operand.c - -typedef enum { reg_L1, reg_L2, reg_L3, reg_L4, reg_L5, reg_L6, reg_L7 } LoadReg; -typedef enum { reg_S1, reg_S2 } StoreReg; -typedef enum { size32, size16, size8 } TransferSize; - -extern git_uint32 parseLoad (git_uint32 * pc, LoadReg reg, int mode, TransferSize, git_sint32 * constVal); -extern void parseStore (git_uint32 * pc, StoreReg reg, int mode, TransferSize); - -extern void parseCallStub (git_uint32 * pc, int mode); -extern void parseSaveStub (git_uint32 * pc, int mode); -extern void parseUndoStub (git_uint32 * pc, int mode); -extern void parseCatchStub (git_uint32 * pc, int * modes); - -// compiler.c - -#include "compiler.h" - -// peephole.c - -extern void resetPeepholeOptimiser(); -extern void emitCode (Label); - -// terp.c - -#ifdef USE_DIRECT_THREADING - extern Opcode* gOpcodeTable; -# define labelToOpcode(label) (gOpcodeTable[label]) -#else -# define labelToOpcode(label) label -#endif - -extern git_sint32* gStackPointer; - -extern void startProgram (size_t cacheSize, enum IOMode ioMode); - -// glkop.c - -extern int git_init_dispatch(); -extern glui32 git_perform_glk(glui32 funcnum, glui32 numargs, glui32 *arglist); -extern strid_t git_find_stream_by_id(glui32 id); -extern glui32 git_find_id_for_stream(strid_t str); - -// git_search.c - -extern glui32 git_binary_search(glui32 key, glui32 keysize, - glui32 start, glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options); - -extern glui32 git_linked_search(glui32 key, glui32 keysize, - glui32 start, glui32 keyoffset, glui32 nextoffset, glui32 options); - -extern glui32 git_linear_search(glui32 key, glui32 keysize, - glui32 start, glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options); - -// savefile.c - -extern git_sint32 saveToFile (git_sint32* base, git_sint32 * sp, git_sint32 file); -extern git_sint32 restoreFromFile (git_sint32* base, git_sint32 file, - git_uint32 protectPos, git_uint32 protectSize); - -// saveundo.c - -extern void initUndo (git_uint32 size); -extern void resetUndo (); -extern void shutdownUndo (); - -extern int saveUndo (git_sint32* base, git_sint32* sp); -extern int restoreUndo (git_sint32* base, - git_uint32 protectPos, git_uint32 protectSize); - -// heap.c - -extern glui32 heap_get_start (); -extern glui32 heap_alloc (glui32 len); -extern void heap_free (glui32 addr); -extern int heap_is_active (); -extern void heap_clear (); -extern int heap_get_summary (glui32 *valcount, glui32 **summary); -extern int heap_apply_summary (glui32 valcount, glui32 *summary); - -// accel.c - -typedef glui32 (*acceleration_func)(glui32 argc, glui32 *argv); -extern void init_accel (); -extern acceleration_func accel_find_func (glui32 index); -extern acceleration_func accel_get_func (glui32 addr); -extern void accel_set_func (glui32 index, glui32 addr); -extern void accel_set_param (glui32 index, glui32 val); - -#endif // GIT_H diff --git a/textworld/thirdparty/glulx/Git-Glulx/git_mac.c b/textworld/thirdparty/glulx/Git-Glulx/git_mac.c deleted file mode 100644 index 6e4a0a4a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/git_mac.c +++ /dev/null @@ -1,79 +0,0 @@ -/* macglk_startup.c: Sample Mac-specific startup code. - Designed by Andrew Plotkin - http://www.eblong.com/zarf/glk/index.html - - This is an extremely simple piece of startup code; it doesn't - do anything. -*/ - -#include "glk.h" -#include "macglk_startup.h" -#include "git.h" -#include -#include -#include - -static strid_t mac_gamefile; - -Boolean macglk_startup_code(macglk_startup_t *data) -{ - OSType mac_gamefile_types[] = { 'UlxG', 'IFRS' }; - - data->startup_model = macglk_model_ChooseOrBuiltIn; - data->app_creator = 'MGit' /* 'niTf' */; - data->gamefile_types = mac_gamefile_types; - data->num_gamefile_types = sizeof(mac_gamefile_types) / sizeof(*mac_gamefile_types); - data->savefile_type = 'IFZS' /* 'IFZS' */; - data->datafile_type = 'UlxD' /* 'ZipD' */; - data->gamefile = &mac_gamefile; -/* data->when_selected = mac_whenselected; - data->when_builtin = mac_whenbuiltin;*/ - return TRUE; -} - -#define CACHE_SIZE (256 * 1024L) -#define UNDO_SIZE (2 * 1024 * 1024L) - -void glk_main () -{ - strid_t file = mac_gamefile; - size_t size, remaining; - git_uint8 * data; - git_uint8 * ptr; - - glk_stream_set_position (file, 0, seekmode_End); - size = glk_stream_get_position (file); - glk_stream_set_position (file, 0, seekmode_Start); - - data = malloc (size); - - ptr = data; - remaining = size; - while (remaining > 0) - { - size_t n = glk_get_buffer_stream (file, (char *) ptr, remaining); - if (n == 0) - { - printf ("Can't read file."); - exit(1); - } - remaining -= n; - ptr += n; - } - glk_stream_close (file, NULL); - - git (data, size, CACHE_SIZE, UNDO_SIZE); -} - -void __msl_assertion_failed (const char * cond, const char * file, const char * func, int line) -{ - fprintf (stderr, "*** fatal error: assertion failed in function \"%s\" (%s:%d) ***\n", func, file, line); - fprintf (stderr, "*** assert(%s) ***\n", cond); - exit (1); -} - -void fatalError (const char * s) -{ - fprintf (stderr, "*** fatal error: %s ***\n", s); - exit (1); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/git_unix.c b/textworld/thirdparty/glulx/Git-Glulx/git_unix.c deleted file mode 100644 index f8e57825..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/git_unix.c +++ /dev/null @@ -1,106 +0,0 @@ -// $Id: git_unix.c,v 1.5 2004/01/25 18:44:51 iain Exp $ - -// unixstrt.c: Unix-specific code for Glulxe. -// Designed by Andrew Plotkin -// http://www.eblong.com/zarf/glulx/index.html - -#include "git.h" -#include -#include // This comes with the Glk library. - -#ifdef USE_MMAP -#include -#include -#include -#include -#endif - -// The only command-line argument is the filename. -glkunix_argumentlist_t glkunix_arguments[] = -{ - { "", glkunix_arg_ValueFollows, "filename: The game file to load." }, - { NULL, glkunix_arg_End, NULL } -}; - -#define CACHE_SIZE (256 * 1024L) -#define UNDO_SIZE (2 * 1024 * 1024L) - -void fatalError (const char * s) -{ - fprintf (stderr, "*** fatal error: %s ***\n", s); - exit (1); -} - -#ifdef USE_MMAP -// Fast loader that uses some fancy Unix features. - -const char * gFilename = 0; - -int glkunix_startup_code(glkunix_startup_t *data) -{ - if (data->argc <= 1) - { - printf ("usage: git gamefile.ulx\n"); - return 0; - } - gFilename = data->argv[1]; - return 1; -} - -void glk_main () -{ - int file; - struct stat info; - const char * ptr; - - file = open (gFilename, O_RDONLY); - if (file < 0) - goto error; - - if (fstat (file, &info) != 0) - goto error; - - if (info.st_size < 256) - { - fprintf (stderr, "This is too small to be a glulx file.\n"); - exit (1); - } - - ptr = mmap (NULL, info.st_size, PROT_READ, MAP_PRIVATE, file, 0); - if (ptr == MAP_FAILED) - goto error; - - git (ptr, info.st_size, CACHE_SIZE, UNDO_SIZE); - munmap ((void*) ptr, info.st_size); - return; - -error: - perror ("git"); - exit (errno); -} - -#else -// Generic loader that should work anywhere. - -strid_t gStream = 0; - -int glkunix_startup_code(glkunix_startup_t *data) -{ - if (data->argc <= 1) - { - printf ("usage: git gamefile.ulx\n"); - return 0; - } - gStream = glkunix_stream_open_pathname ((char*) data->argv[1], 0, 0); - return 1; -} - -void glk_main () -{ - if (gStream == NULL) - fatalError ("could not open game file"); - - gitWithStream (gStream, CACHE_SIZE, UNDO_SIZE); -} - -#endif // USE_MMAP diff --git a/textworld/thirdparty/glulx/Git-Glulx/git_windows.c b/textworld/thirdparty/glulx/Git-Glulx/git_windows.c deleted file mode 100644 index beb63b9e..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/git_windows.c +++ /dev/null @@ -1,115 +0,0 @@ -// Startup code for Windows Git - -#include "glk.h" -#include "WinGlk.h" -#include "git.h" - -#include - -const char* gFilename = NULL; -char gExePath[_MAX_PATH]; - -int winglk_startup_code(const char* cmdline) -{ - char* sep; - int i; - - winglk_set_gui(100); - winglk_app_set_name("Git"); - winglk_set_menu_name("&Git"); - winglk_window_set_title("Windows Git"); - winglk_set_about_text("Windows Git "GIT_VERSION_STR); - winglk_show_game_dialog(); - - if (GetModuleFileName(0,gExePath,_MAX_PATH) == 0) - return 0; - sep = strrchr(gExePath,'.'); - if (sep != 0) - { - strcpy(sep,".chm"); - winglk_set_help_file(gExePath); - } - - if (GetModuleFileName(0,gExePath,_MAX_PATH) == 0) - return 0; - sep = strrchr(gExePath,'.'); - if (sep != 0) - { - static char* exts[5] = { ".blb",".blorb",".glb",".gblorb",".ulx" }; - for (i = 0; i < 5; i++) - { - strcpy(sep,exts[i]); - if (GetFileAttributes(gExePath) != INVALID_FILE_ATTRIBUTES) - { - gFilename = gExePath; - break; - } - } - } - - if (gFilename == NULL) - { - gFilename = (char*)winglk_get_initial_filename(cmdline, - "Select a Glulx game to run", - "Glulx Files (.ulx;.blb;.blorb;.glb;.gblorb)|*.ulx;*.blb;*.blorb;*.glb;*.gblorb|" - "All Files (*.*)|*.*||"); - } - - if (gFilename == NULL) - return 0; - winglk_load_config_file(gFilename); - return 1; -} - -#define CACHE_SIZE (256 * 1024) -#define UNDO_SIZE (2 * 1024 * 1024) - -void fatalError (const char * s) -{ - MessageBox(0,s,"Git Fatal Error",MB_OK|MB_ICONERROR); - exit (1); -} - -void glk_main() -{ - void* file = INVALID_HANDLE_VALUE; - void* mapping = NULL; - void* ptr = NULL; - size_t size = 0; - - // Memory-map the gamefile - file = CreateFile(gFilename,GENERIC_READ,FILE_SHARE_READ,0, - OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); - if (file != INVALID_HANDLE_VALUE) - { - size = GetFileSize(file,0); - mapping = CreateFileMapping(file,0,PAGE_READONLY,0,0,0); - } - if (mapping) - ptr = MapViewOfFile(mapping,FILE_MAP_READ,0,0,0); - - // Pass the gamefile to git - if (ptr) - git(ptr,size,CACHE_SIZE,UNDO_SIZE); - else - fatalError("Can't open gamefile"); - - // Close the gamefile - if (ptr) - UnmapViewOfFile(ptr); - if (mapping) - CloseHandle(mapping); - if (file != INVALID_HANDLE_VALUE) - CloseHandle(file); -} - -float git_powf(float x, float y) -{ - if (x == 1.0f) - return 1.0f; - else if ((y == 0.0f) || (y == -0.0f)) - return 1.0f; - else if ((x == -1.0f) && isinf(y)) - return 1.0f; - return powf(x,y); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/glkop.c b/textworld/thirdparty/glulx/Git-Glulx/glkop.c deleted file mode 100644 index 5579b769..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/glkop.c +++ /dev/null @@ -1,1504 +0,0 @@ -// $Id: glkop.c,v 1.4 2004/12/22 14:33:40 iain Exp $ - -// glkop.c: Glulxe code for Glk API dispatching. -// Designed by Andrew Plotkin -// http://www.eblong.com/zarf/glulx/index.html - -/* This code is actually very general; it could work for almost any - 32-bit VM which remotely resembles Glulxe or the Z-machine in design. - - To be precise, we make the following assumptions: - - - An argument list is an array of 32-bit values, which can represent - either integers or addresses. - - We can read or write to a 32-bit integer in VM memory using the macros - ReadMemory(addr) and WriteMemory(addr), where addr is an address - taken from the argument list. - - A character array is a sequence of bytes somewhere in VM memory. - The array can be turned into a C char array by the macro - CaptureCArray(addr, len), and released by ReleaseCArray(). - The passin, passout hints may be used to avoid unnecessary copying. - - An integer array is a sequence of integers somewhere in VM memory. - The array can be turned into a C integer array by the macro - CaptureIArray(addr, len), and released by ReleaseIArray(). - These macros are responsible for fixing byte-order and alignment - (if the C ABI does not match the VM's). The passin, passout hints - may be used to avoid unnecessary copying. - - A Glk object array is a sequence of integers in VM memory. It is - turned into a C pointer array (remember that C pointers may be more - than 4 bytes!) The pointer array is allocated by - CapturePtrArray(addr, len, objclass) and released by ReleasePtrArray(). - Again, the macros handle the conversion. - - A Glk structure (such as event_t) is a set of integers somewhere - in VM memory, which can be read and written with the macros - ReadStructField(addr, fieldnum) and WriteStructField(addr, fieldnum). - The fieldnum is an integer (from 0 to 3, for event_t.) - - A VM string can be turned into a C-style string with the macro - ptr = DecodeVMString(addr). After the string is used, this code - calls ReleaseVMString(ptr), which should free any memory that - DecodeVMString allocates. - - A VM Unicode string can be turned into a zero-terminated array - of 32-bit integers, in the same way, with DecodeVMUstring - and ReleaseVMUstring. - - To work this code over for a new VM, just diddle the macros. -*/ - -#define Stk1(sp) \ - (*((unsigned char *)(sp))) -#define Stk2(sp) \ - (*((glui16 *)(sp))) -#define Stk4(sp) \ - (*((glui32 *)(sp))) - -#define StkW1(sp, vl) \ - (*((unsigned char *)(sp)) = (unsigned char)(vl)) -#define StkW2(sp, vl) \ - (*((glui16 *)(sp)) = (glui16)(vl)) -#define StkW4(sp, vl) \ - (*((glui32 *)(sp)) = (glui32)(vl)) - - -#define ReadMemory(addr) \ - (((addr) == 0xffffffff) \ - ? (gStackPointer -= 1, Stk4(gStackPointer)) \ - : (memRead32(addr))) -#define WriteMemory(addr, val) \ - do { \ - if ((addr) == 0xffffffff) { \ - StkW4(gStackPointer, (val)); \ - gStackPointer += 1; \ - } else { \ - memWrite32((addr), (val)); \ - } \ - } while (0) -#define CaptureCArray(addr, len, passin) \ - (grab_temp_c_array(addr, len, passin)) -#define ReleaseCArray(ptr, addr, len, passout) \ - (release_temp_c_array(ptr, addr, len, passout)) -#define CaptureIArray(addr, len, passin) \ - (grab_temp_i_array(addr, len, passin)) -#define ReleaseIArray(ptr, addr, len, passout) \ - (release_temp_i_array(ptr, addr, len, passout)) -#define CapturePtrArray(addr, len, objclass, passin) \ - (grab_temp_ptr_array(addr, len, objclass, passin)) -#define ReleasePtrArray(ptr, addr, len, objclass, passout) \ - (release_temp_ptr_array(ptr, addr, len, objclass, passout)) -#define ReadStructField(addr, fieldnum) \ - (((addr) == 0xffffffff) \ - ? (gStackPointer -= 1, Stk4(gStackPointer)) \ - : (memRead32((addr)+(fieldnum)*4))) -#define WriteStructField(addr, fieldnum, val) \ - do { \ - if ((addr) == 0xffffffff) { \ - StkW4(gStackPointer, (val)); \ - gStackPointer += 1; \ - } else { \ - memWrite32((addr)+(fieldnum)*4, (val)); \ - } \ - } while (0) - -#define glulx_malloc malloc -#define glulx_free free -#define glulx_random rand - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#include "glk.h" -#include "git.h" -#include "gi_dispa.h" - -static char * DecodeVMString (git_uint32 addr) -{ - glui32 end; - char * data; - char * c; - - // The string must be a C string. - if (memRead8(addr) != 0xE0) - { - fatalError ("Illegal string type passed to Glk function"); - } - addr += 1; - - end = addr; - while (memRead8(end) != 0) - ++end; - - data = glulx_malloc (end - addr + 1); - if (data == NULL) - fatalError ("Couldn't allocate string"); - - c = data; - while (addr < end) - *c++ = memRead8(addr++); - *c = 0; - - return data; -} - -static glui32 * DecodeVMUstring (git_uint32 addr) -{ - glui32 end; - glui32 * data; - glui32 * c; - - // The string must be a Unicode string. - if (memRead8(addr) != 0xE2) - { - fatalError ("Illegal string type passed to Glk function"); - } - addr += 4; - - end = addr; - while (memRead32(end) != 0) - end += 4; - - data = glulx_malloc (end - addr + 4); - if (data == NULL) - fatalError ("Couldn't allocate string"); - - c = data; - while (addr < end) - { - *c++ = memRead32(addr); - addr += 4; - } - *c = 0; - - return data; -} - -static void ReleaseVMString (char * ptr) -{ - glulx_free (ptr); -} - -static void ReleaseVMUstring (glui32 * ptr) -{ - glulx_free (ptr); -} - -typedef struct dispatch_splot_struct { - int numwanted; - int maxargs; - gluniversal_t *garglist; - glui32 *varglist; - int numvargs; - glui32 *retval; -} dispatch_splot_t; - -/* We maintain a linked list of arrays being used for Glk calls. It is - only used for integer (glui32) arrays -- char arrays are handled in - place. It's not worth bothering with a hash table, since most - arrays appear here only momentarily. */ - -typedef struct arrayref_struct arrayref_t; -struct arrayref_struct { - void *array; - glui32 addr; - glui32 elemsize; - glui32 len; /* elements */ - int retained; - arrayref_t *next; -}; - -static arrayref_t *arrays = NULL; - -/* We maintain a hash table for each opaque Glk class. classref_t are the - nodes of the table, and classtable_t are the tables themselves. */ - -typedef struct classref_struct classref_t; -struct classref_struct { - void *obj; - glui32 id; - int bucknum; - classref_t *next; -}; - -#define CLASSHASH_SIZE (31) -typedef struct classtable_struct { - glui32 lastid; - classref_t *bucket[CLASSHASH_SIZE]; -} classtable_t; - -/* The list of hash tables, for the git_classes. */ -static int num_classes = 0; -classtable_t **git_classes = NULL; - -static classtable_t *new_classtable(glui32 firstid); -static void *classes_get(int classid, glui32 objid); -static classref_t *classes_put(int classid, void *obj, glui32 origid); -static void classes_remove(int classid, void *obj); - -static gidispatch_rock_t glulxe_classtable_register(void *obj, - glui32 objclass); -static void glulxe_classtable_unregister(void *obj, glui32 objclass, - gidispatch_rock_t objrock); -static gidispatch_rock_t glulxe_retained_register(void *array, - glui32 len, char *typecode); -static void glulxe_retained_unregister(void *array, glui32 len, - char *typecode, gidispatch_rock_t objrock); - -/* The library_select_hook is called every time the VM blocks for input. - The app might take this opportunity to autosave, for example. */ -static void (*library_select_hook)(glui32) = NULL; - -static char *grab_temp_c_array(glui32 addr, glui32 len, int passin); -static void release_temp_c_array(char *arr, glui32 addr, glui32 len, int passout); -static glui32 *grab_temp_i_array(glui32 addr, glui32 len, int passin); -static void release_temp_i_array(glui32 *arr, glui32 addr, glui32 len, int passout); -static void **grab_temp_ptr_array(glui32 addr, glui32 len, int objclass, int passin); -static void release_temp_ptr_array(void **arr, glui32 addr, glui32 len, int objclass, int passout); - -static void prepare_glk_args(char *proto, dispatch_splot_t *splot); -static void parse_glk_args(dispatch_splot_t *splot, char **proto, int depth, - int *argnumptr, glui32 subaddress, int subpassin); -static void unparse_glk_args(dispatch_splot_t *splot, char **proto, int depth, - int *argnumptr, glui32 subaddress, int subpassout); - -static maybe_unused char *get_game_id(void); - -/* git_init_dispatch(): - Set up the class hash tables and other startup-time stuff. -*/ -int git_init_dispatch() -{ - int ix; - - /* What with one thing and another, this *could* be called more than - once. We only need to allocate the tables once. */ - if (git_classes) - return TRUE; - - /* Set up the game-ID hook. (This is ifdeffed because not all Glk - libraries have this call.) */ -#ifdef GI_DISPA_GAME_ID_AVAILABLE - gidispatch_set_game_id_hook(&get_game_id); -#endif /* GI_DISPA_GAME_ID_AVAILABLE */ - - /* Allocate the class hash tables. */ - num_classes = gidispatch_count_classes(); - git_classes = (classtable_t **)glulx_malloc(num_classes - * sizeof(classtable_t *)); - if (!git_classes) - return FALSE; - - for (ix=0; ix&+:#!" chars. -*/ -static char *read_prefix(char *cx, int *isref, int *isarray, - int *passin, int *passout, int *nullok, int *isretained, - int *isreturn) -{ - *isref = FALSE; - *passin = FALSE; - *passout = FALSE; - *nullok = TRUE; - *isarray = FALSE; - *isretained = FALSE; - *isreturn = FALSE; - while (1) { - if (*cx == '<') { - *isref = TRUE; - *passout = TRUE; - } - else if (*cx == '>') { - *isref = TRUE; - *passin = TRUE; - } - else if (*cx == '&') { - *isref = TRUE; - *passout = TRUE; - *passin = TRUE; - } - else if (*cx == '+') { - *nullok = FALSE; - } - else if (*cx == ':') { - *isref = TRUE; - *passout = TRUE; - *nullok = FALSE; - *isreturn = TRUE; - } - else if (*cx == '#') { - *isarray = TRUE; - } - else if (*cx == '!') { - *isretained = TRUE; - } - else { - break; - } - cx++; - } - return cx; -} - -/* prepare_glk_args(): - This reads through the prototype string, and pulls Floo objects off the - stack. It also works out the maximal number of gluniversal_t objects - which could be used by the Glk call in question. It then allocates - space for them. -*/ -static void prepare_glk_args(char *proto, dispatch_splot_t *splot) -{ - static gluniversal_t *garglist = NULL; - static int garglist_size = 0; - - int ix; - int numwanted, numvargswanted, maxargs; - char *cx; - - cx = proto; - numwanted = 0; - while (*cx >= '0' && *cx <= '9') { - numwanted = 10 * numwanted + (*cx - '0'); - cx++; - } - splot->numwanted = numwanted; - - maxargs = 0; - numvargswanted = 0; - for (ix = 0; ix < numwanted; ix++) { - int isref, passin, passout, nullok, isarray, isretained, isreturn; - cx = read_prefix(cx, &isref, &isarray, &passin, &passout, &nullok, - &isretained, &isreturn); - if (isref) { - maxargs += 2; - } - else { - maxargs += 1; - } - if (!isreturn) { - if (isarray) { - numvargswanted += 2; - } - else { - numvargswanted += 1; - } - } - - if (*cx == 'I' || *cx == 'C') { - cx += 2; - } - else if (*cx == 'Q') { - cx += 2; - } - else if (*cx == 'S' || *cx == 'U') { - cx += 1; - } - else if (*cx == '[') { - int refdepth, nwx; - cx++; - nwx = 0; - while (*cx >= '0' && *cx <= '9') { - nwx = 10 * nwx + (*cx - '0'); - cx++; - } - maxargs += nwx; /* This is *only* correct because all structs contain - plain values. */ - refdepth = 1; - while (refdepth > 0) { - if (*cx == '[') - refdepth++; - else if (*cx == ']') - refdepth--; - cx++; - } - } - else { - fatalError("Illegal format string."); - } - } - - if (*cx != ':' && *cx != '\0') - fatalError("Illegal format string."); - - splot->maxargs = maxargs; - - if (splot->numvargs != numvargswanted) - fatalError("Wrong number of arguments to Glk function."); - - if (garglist && garglist_size < maxargs) { - glulx_free(garglist); - garglist = NULL; - garglist_size = 0; - } - if (!garglist) { - garglist_size = maxargs + 16; - garglist = (gluniversal_t *)glulx_malloc(garglist_size - * sizeof(gluniversal_t)); - } - if (!garglist) - fatalError("Unable to allocate storage for Glk arguments."); - - splot->garglist = garglist; -} - -/* parse_glk_args(): - This long and unpleasant function translates a set of Floo objects into - a gluniversal_t array. It's recursive, too, to deal with structures. -*/ -static void parse_glk_args(dispatch_splot_t *splot, char **proto, int depth, - int *argnumptr, glui32 subaddress, int subpassin) -{ - char *cx; - int ix, argx; - int gargnum, numwanted; - void *opref; - gluniversal_t *garglist; - glui32 *varglist; - - garglist = splot->garglist; - varglist = splot->varglist; - gargnum = *argnumptr; - cx = *proto; - - numwanted = 0; - while (*cx >= '0' && *cx <= '9') { - numwanted = 10 * numwanted + (*cx - '0'); - cx++; - } - - for (argx = 0, ix = 0; argx < numwanted; argx++, ix++) { - char typeclass; - int skipval; - int isref, passin, passout, nullok, isarray, isretained, isreturn; - cx = read_prefix(cx, &isref, &isarray, &passin, &passout, &nullok, - &isretained, &isreturn); - - typeclass = *cx; - cx++; - - skipval = FALSE; - if (isref) { - if (!isreturn && varglist[ix] == 0) { - if (!nullok) - fatalError("Zero passed invalidly to Glk function."); - garglist[gargnum].ptrflag = FALSE; - gargnum++; - skipval = TRUE; - } - else { - garglist[gargnum].ptrflag = TRUE; - gargnum++; - } - } - if (!skipval) { - glui32 thisval; - - if (typeclass == '[') { - - parse_glk_args(splot, &cx, depth+1, &gargnum, varglist[ix], passin); - - } - else if (isarray) { - /* definitely isref */ - - switch (typeclass) { - case 'C': - /* This test checks for a giant array length, and cuts it down to - something reasonable. Future releases of this interpreter may - treat this case as a fatal error. */ - if (varglist[ix+1] > gEndMem || varglist[ix]+varglist[ix+1] > gEndMem) - varglist[ix+1] = gEndMem - varglist[ix]; - - garglist[gargnum].array = (void*) CaptureCArray(varglist[ix], varglist[ix+1], passin); - gargnum++; - ix++; - garglist[gargnum].uint = varglist[ix]; - gargnum++; - cx++; - break; - case 'I': - /* See comment above. */ - if (varglist[ix+1] > gEndMem/4 || varglist[ix+1] > (gEndMem-varglist[ix])/4) - varglist[ix+1] = (gEndMem - varglist[ix]) / 4; - - garglist[gargnum].array = CaptureIArray(varglist[ix], varglist[ix+1], passin); - gargnum++; - ix++; - garglist[gargnum].uint = varglist[ix]; - gargnum++; - cx++; - break; - case 'Q': - garglist[gargnum].array = CapturePtrArray(varglist[ix], varglist[ix+1], (*cx-'a'), passin); - gargnum++; - ix++; - garglist[gargnum].uint = varglist[ix]; - gargnum++; - cx++; - break; - default: - fatalError("Illegal format string."); - break; - } - } - else { - /* a plain value or a reference to one. */ - - if (isreturn) { - thisval = 0; - } - else if (depth > 0) { - /* Definitely not isref or isarray. */ - if (subpassin) - thisval = ReadStructField(subaddress, ix); - else - thisval = 0; - } - else if (isref) { - if (passin) - thisval = ReadMemory(varglist[ix]); - else - thisval = 0; - } - else { - thisval = varglist[ix]; - } - - switch (typeclass) { - case 'I': - if (*cx == 'u') - garglist[gargnum].uint = (glui32)(thisval); - else if (*cx == 's') - garglist[gargnum].sint = (glsi32)(thisval); - else - fatalError("Illegal format string."); - gargnum++; - cx++; - break; - case 'Q': - if (thisval) { - opref = classes_get(*cx-'a', thisval); - if (!opref) { - fatalError("Reference to nonexistent Glk object."); - } - } - else { - opref = NULL; - } - garglist[gargnum].opaqueref = opref; - gargnum++; - cx++; - break; - case 'C': - if (*cx == 'u') - garglist[gargnum].uch = (unsigned char)(thisval); - else if (*cx == 's') - garglist[gargnum].sch = (signed char)(thisval); - else if (*cx == 'n') - garglist[gargnum].ch = (char)(thisval); - else - fatalError("Illegal format string."); - gargnum++; - cx++; - break; - case 'S': - garglist[gargnum].charstr = DecodeVMString(thisval); - gargnum++; - break; -#ifdef GLK_MODULE_UNICODE - case 'U': - garglist[gargnum].unicharstr = DecodeVMUstring(thisval); - gargnum++; - break; -#endif /* GLK_MODULE_UNICODE */ - default: - fatalError("Illegal format string."); - break; - } - } - } - else { - /* We got a null reference, so we have to skip the format element. */ - if (typeclass == '[') { - int numsubwanted, refdepth; - numsubwanted = 0; - while (*cx >= '0' && *cx <= '9') { - numsubwanted = 10 * numsubwanted + (*cx - '0'); - cx++; - } - refdepth = 1; - while (refdepth > 0) { - if (*cx == '[') - refdepth++; - else if (*cx == ']') - refdepth--; - cx++; - } - } - else if (typeclass == 'S' || typeclass == 'U') { - /* leave it */ - } - else { - cx++; - if (isarray) - ix++; - } - } - } - - if (depth > 0) { - if (*cx != ']') - fatalError("Illegal format string."); - cx++; - } - else { - if (*cx != ':' && *cx != '\0') - fatalError("Illegal format string."); - } - - *proto = cx; - *argnumptr = gargnum; -} - -/* unparse_glk_args(): - This is about the reverse of parse_glk_args(). -*/ -static void unparse_glk_args(dispatch_splot_t *splot, char **proto, int depth, - int *argnumptr, glui32 subaddress, int subpassout) -{ - char *cx; - int ix, argx; - int gargnum, numwanted; - void *opref; - gluniversal_t *garglist; - glui32 *varglist; - - garglist = splot->garglist; - varglist = splot->varglist; - gargnum = *argnumptr; - cx = *proto; - - numwanted = 0; - while (*cx >= '0' && *cx <= '9') { - numwanted = 10 * numwanted + (*cx - '0'); - cx++; - } - - for (argx = 0, ix = 0; argx < numwanted; argx++, ix++) { - char typeclass; - int skipval; - int isref, passin, passout, nullok, isarray, isretained, isreturn; - cx = read_prefix(cx, &isref, &isarray, &passin, &passout, &nullok, - &isretained, &isreturn); - - typeclass = *cx; - cx++; - - skipval = FALSE; - if (isref) { - if (!isreturn && varglist[ix] == 0) { - if (!nullok) - fatalError("Zero passed invalidly to Glk function."); - garglist[gargnum].ptrflag = FALSE; - gargnum++; - skipval = TRUE; - } - else { - garglist[gargnum].ptrflag = TRUE; - gargnum++; - } - } - if (!skipval) { - glui32 thisval = 0; - - if (typeclass == '[') { - - unparse_glk_args(splot, &cx, depth+1, &gargnum, varglist[ix], passout); - - } - else if (isarray) { - /* definitely isref */ - - switch (typeclass) { - case 'C': - ReleaseCArray(garglist[gargnum].array, varglist[ix], varglist[ix+1], passout); - gargnum++; - ix++; - gargnum++; - cx++; - break; - case 'I': - ReleaseIArray(garglist[gargnum].array, varglist[ix], varglist[ix+1], passout); - gargnum++; - ix++; - gargnum++; - cx++; - break; - case 'Q': - ReleasePtrArray(garglist[gargnum].array, varglist[ix], varglist[ix+1], (*cx-'a'), passout); - gargnum++; - ix++; - gargnum++; - cx++; - break; - default: - fatalError("Illegal format string."); - break; - } - } - else { - /* a plain value or a reference to one. */ - - if (isreturn || (depth > 0 && subpassout) || (isref && passout)) { - skipval = FALSE; - } - else { - skipval = TRUE; - } - - switch (typeclass) { - case 'I': - if (!skipval) { - if (*cx == 'u') - thisval = (glui32)garglist[gargnum].uint; - else if (*cx == 's') - thisval = (glui32)garglist[gargnum].sint; - else - fatalError("Illegal format string."); - } - gargnum++; - cx++; - break; - case 'Q': - if (!skipval) { - opref = garglist[gargnum].opaqueref; - if (opref) { - gidispatch_rock_t objrock = - gidispatch_get_objrock(opref, *cx-'a'); - thisval = ((classref_t *)objrock.ptr)->id; - } - else { - thisval = 0; - } - } - gargnum++; - cx++; - break; - case 'C': - if (!skipval) { - if (*cx == 'u') - thisval = (glui32)garglist[gargnum].uch; - else if (*cx == 's') - thisval = (glui32)garglist[gargnum].sch; - else if (*cx == 'n') - thisval = (glui32)garglist[gargnum].ch; - else - fatalError("Illegal format string."); - } - gargnum++; - cx++; - break; - case 'S': - if (garglist[gargnum].charstr) - ReleaseVMString(garglist[gargnum].charstr); - gargnum++; - break; -#ifdef GLK_MODULE_UNICODE - case 'U': - if (garglist[gargnum].unicharstr) - ReleaseVMUstring(garglist[gargnum].unicharstr); - gargnum++; - break; -#endif /* GLK_MODULE_UNICODE */ - default: - fatalError("Illegal format string."); - break; - } - - if (isreturn) { - *(splot->retval) = thisval; - } - else if (depth > 0) { - /* Definitely not isref or isarray. */ - if (subpassout) - WriteStructField(subaddress, ix, thisval); - } - else if (isref) { - if (passout) - WriteMemory(varglist[ix], thisval); - } - } - } - else { - /* We got a null reference, so we have to skip the format element. */ - if (typeclass == '[') { - int numsubwanted, refdepth; - numsubwanted = 0; - while (*cx >= '0' && *cx <= '9') { - numsubwanted = 10 * numsubwanted + (*cx - '0'); - cx++; - } - refdepth = 1; - while (refdepth > 0) { - if (*cx == '[') - refdepth++; - else if (*cx == ']') - refdepth--; - cx++; - } - } - else if (typeclass == 'S' || typeclass == 'U') { - /* leave it */ - } - else { - cx++; - if (isarray) - ix++; - } - } - } - - if (depth > 0) { - if (*cx != ']') - fatalError("Illegal format string."); - cx++; - } - else { - if (*cx != ':' && *cx != '\0') - fatalError("Illegal format string."); - } - - *proto = cx; - *argnumptr = gargnum; -} - -/* git_find_stream_by_id(): - This is used by some interpreter code which has to, well, find a Glk - stream given its ID. -*/ -strid_t git_find_stream_by_id(glui32 objid) -{ - if (!objid) - return NULL; - - /* Recall that class 1 ("b") is streams. */ - return classes_get(gidisp_Class_Stream, objid); -} - -/* git_find_id_for_window(): - Return the ID of a given Glk window. -*/ -glui32 git_find_id_for_window(winid_t win) -{ - gidispatch_rock_t objrock; - - if (!win) - return 0; - - objrock = gidispatch_get_objrock(win, gidisp_Class_Window); - return ((classref_t *)objrock.ptr)->id; -} - -/* git_find_id_for_stream(): - Return the ID of a given Glk stream. -*/ -glui32 git_find_id_for_stream(strid_t str) -{ - gidispatch_rock_t objrock; - - if (!str) - return 0; - - objrock = gidispatch_get_objrock(str, gidisp_Class_Stream); - return ((classref_t *)objrock.ptr)->id; -} - -/* git_find_id_for_fileref(): - Return the ID of a given Glk fileref. -*/ -glui32 git_find_id_for_fileref(frefid_t fref) -{ - gidispatch_rock_t objrock; - - if (!fref) - return 0; - - objrock = gidispatch_get_objrock(fref, gidisp_Class_Fileref); - return ((classref_t *)objrock.ptr)->id; -} - -/* git_find_id_for_schannel(): - Return the ID of a given Glk schannel. -*/ -glui32 git_find_id_for_schannel(schanid_t schan) -{ - gidispatch_rock_t objrock; - - if (!schan) - return 0; - - objrock = gidispatch_get_objrock(schan, gidisp_Class_Schannel); - return ((classref_t *)objrock.ptr)->id; -} - -/* Build a hash table to hold a set of Glk objects. */ -static classtable_t *new_classtable(glui32 firstid) -{ - int ix; - classtable_t *ctab = (classtable_t *)glulx_malloc(sizeof(classtable_t)); - if (!ctab) - return NULL; - - for (ix=0; ixbucket[ix] = NULL; - - ctab->lastid = firstid; - - return ctab; -} - -/* Find a Glk object in the appropriate hash table. */ -static void *classes_get(int classid, glui32 objid) -{ - classtable_t *ctab; - classref_t *cref; - if (classid < 0 || classid >= num_classes) - return NULL; - ctab = git_classes[classid]; - cref = ctab->bucket[objid % CLASSHASH_SIZE]; - for (; cref; cref = cref->next) { - if (cref->id == objid) - return cref->obj; - } - return NULL; -} - -/* Put a Glk object in the appropriate hash table. If origid is zero, - invent a new unique ID for it. */ -static classref_t *classes_put(int classid, void *obj, glui32 origid) -{ - int bucknum; - classtable_t *ctab; - classref_t *cref; - if (classid < 0 || classid >= num_classes) - return NULL; - ctab = git_classes[classid]; - cref = (classref_t *)glulx_malloc(sizeof(classref_t)); - if (!cref) - return NULL; - cref->obj = obj; - if (!origid) { - cref->id = ctab->lastid; - ctab->lastid++; - } - else { - cref->id = origid; - if (ctab->lastid <= origid) - ctab->lastid = origid+1; - } - bucknum = cref->id % CLASSHASH_SIZE; - cref->bucknum = bucknum; - cref->next = ctab->bucket[bucknum]; - ctab->bucket[bucknum] = cref; - return cref; -} - -/* Delete a Glk object from the appropriate hash table. */ -static void classes_remove(int classid, void *obj) -{ - classtable_t *ctab; - classref_t *cref; - classref_t **crefp; - gidispatch_rock_t objrock; - if (classid < 0 || classid >= num_classes) - return; - ctab = git_classes[classid]; - objrock = gidispatch_get_objrock(obj, classid); - cref = objrock.ptr; - if (!cref) - return; - crefp = &(ctab->bucket[cref->bucknum]); - for (; *crefp; crefp = &((*crefp)->next)) { - if ((*crefp) == cref) { - *crefp = cref->next; - cref->obj = NULL; - cref->id = 0; - cref->next = NULL; - glulx_free(cref); - return; - } - } - return; -} - -/* The object registration/unregistration callbacks that the library calls - to keep the hash tables up to date. */ - -static gidispatch_rock_t glulxe_classtable_register(void *obj, - glui32 objclass) -{ - classref_t *cref; - gidispatch_rock_t objrock; - cref = classes_put(objclass, obj, 0); - objrock.ptr = cref; - return objrock; -} - -static void glulxe_classtable_unregister(void *obj, glui32 objclass, - gidispatch_rock_t objrock) -{ - classes_remove(objclass, obj); -} - -static char *grab_temp_c_array(glui32 addr, glui32 len, int passin) -{ - arrayref_t *arref = NULL; - char *arr = NULL; - glui32 ix, addr2; - - if (len) { - arr = (char *)glulx_malloc(len * sizeof(char)); - arref = (arrayref_t *)glulx_malloc(sizeof(arrayref_t)); - if (!arr || !arref) - fatalError("Unable to allocate space for array argument to Glk call."); - - arref->array = arr; - arref->addr = addr; - arref->elemsize = 1; - arref->retained = FALSE; - arref->len = len; - arref->next = arrays; - arrays = arref; - - if (passin) { - for (ix=0, addr2=addr; ixnext))) { - if ((*aptr)->array == arr) - break; - } - arref = *aptr; - if (!arref) - fatalError("Unable to re-find array argument in Glk call."); - if (arref->addr != addr || arref->len != len) - fatalError("Mismatched array argument in Glk call."); - - if (arref->retained) { - return; - } - - *aptr = arref->next; - arref->next = NULL; - - if (passout) { - for (ix=0, addr2=addr; ixarray = arr; - arref->addr = addr; - arref->elemsize = 4; - arref->retained = FALSE; - arref->len = len; - arref->next = arrays; - arrays = arref; - - if (passin) { - for (ix=0, addr2=addr; ixnext))) { - if ((*aptr)->array == arr) - break; - } - arref = *aptr; - if (!arref) - fatalError("Unable to re-find array argument in Glk call."); - if (arref->addr != addr || arref->len != len) - fatalError("Mismatched array argument in Glk call."); - - if (arref->retained) { - return; - } - - *aptr = arref->next; - arref->next = NULL; - - if (passout) { - for (ix=0, addr2=addr; ixarray = arr; - arref->addr = addr; - arref->elemsize = sizeof(void *); - arref->retained = FALSE; - arref->len = len; - arref->next = arrays; - arrays = arref; - - if (passin) { - for (ix=0, addr2=addr; ixnext))) { - if ((*aptr)->array == arr) - break; - } - arref = *aptr; - if (!arref) - fatalError("Unable to re-find array argument in Glk call."); - if (arref->addr != addr || arref->len != len) - fatalError("Mismatched array argument in Glk call."); - - if (arref->retained) { - return; - } - - *aptr = arref->next; - arref->next = NULL; - - if (passout) { - for (ix=0, addr2=addr; ixid; - } - else { - val = 0; - } - memWrite32(addr2, val); - } - } - glulx_free(arr); - glulx_free(arref); - } -} - -static gidispatch_rock_t glulxe_retained_register(void *array, - glui32 len, char *typecode) -{ - gidispatch_rock_t rock; - arrayref_t *arref = NULL; - arrayref_t **aptr; - int elemsize = 0; - - if (typecode[4] == 'C') - elemsize = 1; - else if (typecode[4] == 'I') - elemsize = 4; - - if (!elemsize || array == NULL) { - rock.ptr = NULL; - return rock; - } - - for (aptr=(&arrays); (*aptr); aptr=(&((*aptr)->next))) { - if ((*aptr)->array == array) - break; - } - arref = *aptr; - if (!arref) - fatalError("Unable to re-find array argument in Glk call."); - if (arref->elemsize != elemsize || arref->len != len) - fatalError("Mismatched array argument in Glk call."); - - arref->retained = TRUE; - - rock.ptr = arref; - return rock; -} - -static void glulxe_retained_unregister(void *array, glui32 len, - char *typecode, gidispatch_rock_t objrock) -{ - arrayref_t *arref = NULL; - arrayref_t **aptr; - glui32 ix, addr2, val; - int elemsize = 0; - - if (typecode[4] == 'C') - elemsize = 1; - else if (typecode[4] == 'I') - elemsize = 4; - - if (!elemsize || array == NULL) { - return; - } - - for (aptr=(&arrays); (*aptr); aptr=(&((*aptr)->next))) { - if ((*aptr)->array == array) - break; - } - arref = *aptr; - if (!arref) { - if (objrock.num == 0) - return; - fatalError("Unable to re-find array argument in Glk call."); - } - if (arref != objrock.ptr) - fatalError("Mismatched array reference in Glk call."); - if (!arref->retained) - fatalError("Unretained array reference in Glk call."); - if (arref->elemsize != elemsize || arref->len != len) - fatalError("Mismatched array argument in Glk call."); - - *aptr = arref->next; - arref->next = NULL; - - if (elemsize == 1) { - for (ix=0, addr2=arref->addr; ixlen; ix++, addr2+=1) { - val = ((char *)array)[ix]; - memWrite8(addr2, val); - } - } - else if (elemsize == 4) { - for (ix=0, addr2=arref->addr; ixlen; ix++, addr2+=4) { - val = ((glui32 *)array)[ix]; - memWrite32(addr2, val); - } - } - - glulx_free(array); - glulx_free(arref); -} - -void set_library_select_hook(void (*func)(glui32)) -{ - library_select_hook = func; -} - -/* Create a string identifying this game. We use the first 64 bytes of the - memory map, encoded as hex, -*/ -static char *get_game_id() -{ - /* This buffer gets rewritten on every call, but that's okay -- the caller - is supposed to copy out the result. */ - static char buf[2*64+2]; - int ix, jx; - - if (!gInitMem) - return NULL; - - for (ix=0, jx=0; ix<64; ix++) { - char ch = gInitMem[ix]; - int val = ((ch >> 4) & 0x0F); - buf[jx++] = ((val < 10) ? (val + '0') : (val + 'A' - 10)); - val = (ch & 0x0F); - buf[jx++] = ((val < 10) ? (val + '0') : (val + 'A' - 10)); - } - buf[jx++] = '\0'; - - return buf; -} - diff --git a/textworld/thirdparty/glulx/Git-Glulx/heap.c b/textworld/thirdparty/glulx/Git-Glulx/heap.c deleted file mode 100644 index 09eaab36..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/heap.c +++ /dev/null @@ -1,380 +0,0 @@ -/* heap.c: Glulxe code related to the dynamic allocation heap. - Designed by Andrew Plotkin - http://eblong.com/zarf/glulx/index.html -*/ - -#define glulx_malloc malloc -#define glulx_free free - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#include "glk.h" -#include "git.h" - -typedef struct heapblock_struct { - glui32 addr; - glui32 len; - int isfree; - struct heapblock_struct *next; - struct heapblock_struct *prev; -} heapblock_t; - -static glui32 heap_start = 0; /* zero for inactive heap */ -static int alloc_count = 0; - -/* The heap_head/heap_tail is a doubly-linked list of blocks, both - free and allocated. It is kept in address order. It should be - complete -- that is, the first block starts at heap_start, and each - block ends at the beginning of the next block, until the last one, - which ends at gEndMem. - - (Heap_start is never the same as end_mem; if there is no heap space, - then the heap is inactive and heap_start is zero.) - - Adjacent free blocks may be merged at heap_alloc() time. - - ### To make alloc more efficient, we could keep a separate - free-list. To make free more efficient, we could keep a hash - table of allocations. - */ -static heapblock_t *heap_head = NULL; -static heapblock_t *heap_tail = NULL; - -/* heap_clear(): - Set the heap state to inactive, and free the block lists. This is - called when the game starts or restarts. -*/ -void heap_clear() -{ - while (heap_head) { - heapblock_t *blo = heap_head; - heap_head = blo->next; - blo->next = NULL; - blo->prev = NULL; - glulx_free(blo); - } - heap_tail = NULL; - - if (heap_start) { - glui32 res = resizeMemory(heap_start, 1); - if (res) - fatalError("Unable to revert memory size when deactivating heap."); - } - - heap_start = 0; - alloc_count = 0; - /* heap_sanity_check(); */ -} - -/* heap_is_active(): - Returns whether the heap is active. -*/ -int heap_is_active() { - return (heap_start != 0); -} - -/* heap_get_start(): - Returns the start address of the heap, or 0 if the heap is not active. - */ -glui32 heap_get_start() { - return heap_start; -} - -/* heap_alloc(): - Allocate a block. If necessary, activate the heap and/or extend memory. - Returns the memory address of the block, or 0 if the operation failed. -*/ -glui32 heap_alloc(glui32 len) -{ - heapblock_t *blo, *newblo; - - if (len <= 0) - fatalError("Heap allocation length must be positive."); - - blo = heap_head; - while (blo) { - if (blo->isfree && blo->len >= len) - break; - - if (!blo->isfree) { - blo = blo->next; - continue; - } - - if (!blo->next || !blo->next->isfree) { - blo = blo->next; - continue; - } - - /* This is a free block, but the next block in the list is also - free, so we "advance" by merging rather than by going to - blo->next. */ - newblo = blo->next; - blo->len += newblo->len; - if (newblo->next) { - blo->next = newblo->next; - newblo->next->prev = blo; - } - else { - blo->next = NULL; - heap_tail = blo; - } - newblo->next = NULL; - newblo->prev = NULL; - glulx_free(newblo); - newblo = NULL; - continue; - } - - if (!blo) { - /* No free area is visible on the list. Try extending memory. How - much? Double the heap size, or by 256 bytes, or by the memory - length requested -- whichever is greatest. */ - glui32 res; - glui32 extension; - glui32 oldendmem = gEndMem; - - extension = 0; - if (heap_start) - extension = gEndMem - heap_start; - if (extension < len) - extension = len; - if (extension < 256) - extension = 256; - /* And it must be rounded up to a multiple of 256. */ - extension = (extension + 0xFF) & (~(glui32)0xFF); - - res = resizeMemory(gEndMem+extension, 1); - if (res) - return 0; - - /* If we just started the heap, note that. */ - if (heap_start == 0) - heap_start = oldendmem; - - if (heap_tail && heap_tail->isfree) { - /* Append the new space to the last block. */ - blo = heap_tail; - blo->len += extension; - } - else { - /* Append the new space to the block list, as a new block. */ - newblo = glulx_malloc(sizeof(heapblock_t)); - if (!newblo) - fatalError("Unable to allocate record for heap block."); - newblo->addr = oldendmem; - newblo->len = extension; - newblo->isfree = TRUE; - newblo->next = NULL; - newblo->prev = NULL; - - if (!heap_tail) { - heap_head = newblo; - heap_tail = newblo; - } - else { - blo = heap_tail; - heap_tail = newblo; - blo->next = newblo; - newblo->prev = blo; - } - - blo = newblo; - newblo = NULL; - } - - /* and continue forwards, using this new block (blo). */ - } - - /* Something strange happened. */ - if (!blo || !blo->isfree || blo->len < len) - return 0; - - /* We now have a free block of size len or longer. */ - - if (blo->len == len) { - blo->isfree = FALSE; - } - else { - newblo = glulx_malloc(sizeof(heapblock_t)); - if (!newblo) - fatalError("Unable to allocate record for heap block."); - newblo->isfree = TRUE; - newblo->addr = blo->addr + len; - newblo->len = blo->len - len; - blo->len = len; - blo->isfree = FALSE; - newblo->next = blo->next; - if (newblo->next) - newblo->next->prev = newblo; - newblo->prev = blo; - blo->next = newblo; - if (heap_tail == blo) - heap_tail = newblo; - } - - alloc_count++; - /* heap_sanity_check(); */ - return blo->addr; -} - -/* heap_free(): - Free a heap block. If necessary, deactivate the heap. -*/ -void heap_free(glui32 addr) -{ - heapblock_t *blo; - - for (blo = heap_head; blo; blo = blo->next) { - if (blo->addr == addr) - break; - }; - if (!blo || blo->isfree) - fatalError("Attempt to free unallocated address from heap."); - - blo->isfree = TRUE; - alloc_count--; - if (alloc_count <= 0) { - heap_clear(); - } - - /* heap_sanity_check(); */ -} - -/* heap_get_summary(): - Create an array of words, in the VM serialization format: - - heap_start - alloc_count - addr of first block - len of first block - ... - - (Note that these are glui32 values -- native byte ordering. Also, - the blocks will be in address order, which is a stricter guarantee - than the VM specifies; that'll help in heap_apply_summary().) - - If the heap is inactive, store NULL. Return 0 for success; - otherwise, the operation failed. - - The array returned in summary must be freed with glulx_free() after - the caller uses it. -*/ -int heap_get_summary(glui32 *valcount, glui32 **summary) -{ - glui32 *arr, len, pos; - heapblock_t *blo; - - *valcount = 0; - *summary = NULL; - - if (heap_start == 0) - return 0; - - len = 2 + 2*alloc_count; - arr = glulx_malloc(len * sizeof(glui32)); - if (!arr) - return 1; - - pos = 0; - arr[pos++] = heap_start; - arr[pos++] = alloc_count; - - for (blo = heap_head; blo; blo = blo->next) { - if (blo->isfree) - continue; - arr[pos++] = blo->addr; - arr[pos++] = blo->len; - } - - if (pos != len) - fatalError("Wrong number of active blocks in heap"); - - *valcount = len; - *summary = arr; - return 0; -} - -/* heap_apply_summary(): - Given an array of words in the above format, set up the heap to - contain it. As noted above, the caller must ensure that the blocks - are in address order. When this is called, the heap must be - inactive. - - Return 0 for success. Otherwise the operation failed (and, most - likely, caused a fatal error). -*/ -int heap_apply_summary(glui32 valcount, glui32 *summary) -{ - glui32 lx, jx, lastend; - - if (heap_start) - fatalError("Heap active when heap_apply_summary called"); - - if (valcount == 0 || summary == NULL) - return 0; - if (valcount == 2 && summary[0] == 0 && summary[1] == 0) - return 0; - - lx = 0; - heap_start = summary[lx++]; - alloc_count = summary[lx++]; - - for (jx=lx; jx+2= summary[jx+2]) - fatalError("Heap block summary is out of order."); - } - - lastend = heap_start; - - while (lx < valcount || lastend < gEndMem) { - heapblock_t *blo; - - blo = glulx_malloc(sizeof(heapblock_t)); - if (!blo) - fatalError("Unable to allocate record for heap block."); - - if (lx >= valcount) { - blo->addr = lastend; - blo->len = gEndMem - lastend; - blo->isfree = TRUE; - } - else { - if (lastend < summary[lx]) { - blo->addr = lastend; - blo->len = summary[lx] - lastend; - blo->isfree = TRUE; - } - else { - blo->addr = summary[lx++]; - blo->len = summary[lx++]; - blo->isfree = FALSE; - } - } - - blo->prev = NULL; - blo->next = NULL; - - if (!heap_head) { - heap_head = blo; - heap_tail = blo; - } - else { - heap_tail->next = blo; - blo->prev = heap_tail; - heap_tail = blo; - } - - lastend = blo->addr + blo->len; - } - - /* heap_sanity_check(); */ - - return 0; -} - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/Git.css b/textworld/thirdparty/glulx/Git-Glulx/help/Git.css deleted file mode 100644 index 14e46455..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/Git.css +++ /dev/null @@ -1,6 +0,0 @@ -body { font-family:verdana;font-size:8pt } -td { font-family:verdana;font-size:8pt } -h1 { font-size:12pt } -h2 { font-size:10pt } -ul { margin-left:16pt;margin-top:2pt } - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhc b/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhc deleted file mode 100644 index 6095d725..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhc +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - -
    -
  • - - - -
  • - - -
      -
    • - - - -
    • - - - -
    • - - - -
    • - - - -
    -
  • - - -
      -
    • - - - -
    • - - - -
    • - - - -
    -
  • - - -
      -
    • - - - -
    • - - - -
    • - - - -
    -
  • - - - -
  • - - - -
  • - - - -
- diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhp b/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhp deleted file mode 100644 index 84b335b8..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/Git.hhp +++ /dev/null @@ -1,20 +0,0 @@ -[OPTIONS] -Compatibility=1.1 or later -Compiled file=Git.chm -Contents file=Git.hhc -Default Window=help -Default topic=overview.htm -Display compile progress=No -Full-text search=Yes -Language=0x809 English (United Kingdom) -Title=Windows Git - -[WINDOWS] -help=,"Git.hhc",,"overview.htm",,,,,,0x42520,,0x3006,[600,32,1200,632],,,,,,,0 - - -[FILES] -overview.htm - -[INFOTYPES] - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/about.png b/textworld/thirdparty/glulx/Git-Glulx/help/about.png deleted file mode 100644 index 966b0f39..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/about.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/archive.htm b/textworld/thirdparty/glulx/Git-Glulx/help/archive.htm deleted file mode 100644 index c418507a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/archive.htm +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - -

The IF Archive

-The IF Archive is the central site on the Internet for text adventures and related interpreters, -compilers and other tools. The Archive has an unrivalled collection of material relating -to text adventures, including something in the region of two thousand games. -

-Formerly at the FTP site ftp.gmd.de, it is now at the web site -http://www.ifarchive.org/. -The Archive is also still accessible through FTP, at -ftp://ftp.ifarchive.org/if-archive/. -You might also like to consider using one of the Archive's mirror sites, which are listed -on the Archive's home page: depending on where you are, you might well find a mirror that -responds faster than the main Archive site. -

-The Archive's main collection of Glulx games is in the -games/glulx -directory. Another source of Glulx games is the annual -IF Competition. -Two other sites well worth a look are -Baf's Guide to the Archive and -Mike Robert's Interactive Fiction Database, -both of which provide information and reviews of games in the IF Archive. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/autorun.htm b/textworld/thirdparty/glulx/Git-Glulx/help/autorun.htm deleted file mode 100644 index e9bf3140..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/autorun.htm +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - -

Automatic Running

-When it comes time to distribute your game, you can package up the interpreter with your game -into an archive or installer. But if you want the user to be able to start your game just by -clicking on an icon, you can rename Git.exe to the same as the name as your game's -Glulx file (apart from the .exe file extension). When the interpreter starts up it -first looks for a Blorb file with the same name as the executable, and if one is found, loads -and runs it straight away. So, if your game file is Foo.blb and the renamed interpreter -executable is Foo.exe, all the user needs to do to run your game is double click on -Foo.exe. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/blorb.htm b/textworld/thirdparty/glulx/Git-Glulx/help/blorb.htm deleted file mode 100644 index 92dbe90b..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/blorb.htm +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -

Blorb

-The Blorb specification -was written by Andrew Plotkin as a way of providing graphics and sound resources for Z-code and Glulx games. -

-A Blorb file contains all the graphics and sound files needed for a game. It can also contain the Glulx code -for the game as well, but does not need to: The game could also be distributed as separate Glulx and Blorb -files. If you try to load a Blorb file into Windows Git that does not contain a Glulx game, it will ask -you to load the appropriate Glulx file into the interpreter instead. -

-Blorb files can contain JPEG and PNG graphics files, AIFF sound samples, and MOD and Ogg Vorbis music files. -Windows Git supports all of these formats, including transparency, opacity and gamma correction for -PNG graphics. -

-From version 2.0, the Blorb specification also includes iFiction metadata and cover art chunks; Inform 7 -can produce Blorb files containing these. If present, Windows Git uses them to determine the title of the -game and to populate the About This Game dialog. -

-More information on Blorb is available from the Blorb web page: -http://www.eblong.com/zarf/blorb/ - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/config.htm b/textworld/thirdparty/glulx/Git-Glulx/help/config.htm deleted file mode 100644 index 422c5ce3..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/config.htm +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - -

Configuration Files

-Windows Git can load a configuration file with the game that sets various attributes of -the interpreter window. The configuration file should have the same name as the game except -for an extension of .cfg. -

-The configuration file is a text file where each line contains a key name, followed by an -equals sign, then a value, e.g. WindowBorders=no. Possible keys are:
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WindowBorders=[yes/no]Turns on or off borders between windows.
WindowFrame=[yes/no]Turns on or off the interpreter window's frame, that is, the title bar and the - border around the whole window.
WindowMask=[number]Uses the given Blorb resource number to set the mask for the window from the - graphic. If a particular pixel in the graphic is white then the window is - transparent at that point, else it is opaque. This key only takes effect if - "WindowFrame=no".
WindowWidth=[width]Sets the width of the interpreter's window so that a single, full-size Glk window - will have a width of the given value.
WindowHeight=[height]Sets the height of the interpreter's window so that a single, full-size Glk window - will have a height of the given value.
FullScreen=[yes/no]If set to "yes", the interpreter's window opens filling the entire screen.
FontName=[font]Sets the font used for proportional text to the given font name, - e.g. Times New Roman.
FontSize=[size]Sets the size of the font used for proportional text to the given value, - measured in points.
FixedFontName=[font]Sets the font used for fixed width text to the given font name.
FixedFontSize=[size]Sets the size of the font used for fixed width text to the given value.
FontFile=[filename]The name of a font file (usually ending in ".ttf") to load fonts from.
- - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/credits.htm b/textworld/thirdparty/glulx/Git-Glulx/help/credits.htm deleted file mode 100644 index 1dc8e955..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/credits.htm +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - -

Credits and Licenses

-Windows Git package by David Kinder.
-Windows Glk is copyright 1998-2016 by David Kinder.
-Git is copyright 2003 by Iain Merrick.
-

-License -

-Both Git and Windows Glk are released under the terms of the MIT license: -

-Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: -

-The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -

-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -

-Git Credits -

-Iain's text file with the Git source code includes the following credits: -

-Andrew Plotkin invented Glulx, so obviously Git wouldn't exist without him. I -also reused some code from his Glulxe interpreter (glkop.c and search.c), which -saved me a lot of time and let me concentrate on the more interesting stuff. -

-Many thanks are due to John Cater, who not only persuaded me to use source -control, but let me use his own CVS server. John also provided lots of useful -advice and encouragement, as did Sean Barrett. -

-Thanks also to Joe Mason, Adam Thornton, Simon Baldwin and Joonas Pihlaja who -were among the first to try it out and complain that it wasn't working. Joonas -also gets special brownie points for trying out more bizarre boundary cases than -I realised existed in the first place. -

-Tor Andersson was apparently the first person to use setmemsize, since he also -explained why it didn't work and contributed a fix. Thanks, Tor! -

-David Kinder has done a stellar job of maintaining the code recently. Thanks -also to Eliuk Blau for tracking down bugs in the memory management opcodes. -

-Windows Glk Credits -

-The user interface for Windows Glk has been translated into Spanish by Javier San José, -and into Italian by Tommaso Caldarola. -

-Windows Glk contains bitmap scaling code written by Eran Yariv. -The code that handles Ogg Vorbis music resources is based on code submitted by David Moreno. -

-Windows Glk uses the following libraries: -

    -
  • jpeglib by the Independent JPEG Group. -
  • libpng by Guy Eric Schalnat, Andreas Dilger, Glenn Randers-Pehrson, and others. -
  • zlib by Jean-loup Gailly and Mark Adler. -
  • libogg and libvorbis by the Xiph.org Foundation. (Click here for the license.) -
  • MODPlug by Olivier Lapicque. -
- - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/editing_keys.htm b/textworld/thirdparty/glulx/Git-Glulx/help/editing_keys.htm deleted file mode 100644 index bae6e529..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/editing_keys.htm +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - -

Editing Keys

-When Windows Git is waiting for input from the user, the following keys have special meanings: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DeleteDelete the character under the cursor.
BackspaceDelete the character to the left of the cursor.
HomeMove the cursor to the start of the input line.
EndMove the cursor to the end of the input line.
Cursor LeftMove the cursor to the left.
Cursor RightMove the cursor to the right.
Cursor UpShow the previous input in the input history.
Cursor DownShow the next input in the input history.
Ctrl+Cursor LeftMove the cursor to the start of the current word, or the previous word -if already at the start of a word.
Ctrl+Cursor RightMove the cursor to the end of the current word, or the next word -if already at the end of a word.
TabMove the input focus to the next window which is waiting for input.
Shift+TabMove the input focus to the previous window which is waiting for input.
Ctrl+PauseHalts any speech currently being spoken.
Ctrl+VPaste the contents of the clipboard into the input line.
Alt+EnterToggle full screen mode.
-

-The hotkeys assigned to menu items are given here. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/fixed.png b/textworld/thirdparty/glulx/Git-Glulx/help/fixed.png deleted file mode 100644 index 1d22f5b4..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/fixed.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/getting_started.htm b/textworld/thirdparty/glulx/Git-Glulx/help/getting_started.htm deleted file mode 100644 index 00dbb991..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/getting_started.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - -

Getting Started

-In order to use Windows Git, you will need a Glulx game file to play on it. -This format was invented by Andrew Plotkin to address the limitations of the widely used Z-code format -(also referred to as the Z-Machine), which was originally invented by Infocom, Inc. for the games they -released during the 1980s. -

-Members of the current interactive fiction community have written many games using Graham Nelson's -compiler Inform. Inform can produce as output either Z-code or Glulx game files. Glulx games can be -downloaded from the IF Archive at
-http://www.ifarchive.org/indexes/if-archiveXgamesXglulx.html -

-When Windows Git is first started, a file dialog opens, prompting you for a game file to load. -This file can be either a Glulx file or a Blorb file. A Glulx -file has a name ending with .ulx. A Blorb file contains multimedia resources for games, and can also -contain the Glulx game as well. Blorb files have a name ending with .blb, .blorb, -.glb or .gblorb. -

-Once a game file is selected, Windows Git will open its main window and start running the game. If the game -is packaged with an iFiction record, then the cover art and description is shown first. -

-Further information: -

- - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/gfx_sound.htm b/textworld/thirdparty/glulx/Git-Glulx/help/gfx_sound.htm deleted file mode 100644 index 528f05b0..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/gfx_sound.htm +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - -

Graphics and Sound

-Windows Git can load graphics and sound resources either from within -Blorb files or as separate files. -

-If a Blorb file is loaded into the interpreter, or a Blorb file exists with the same name -as the Glulx game file, then graphics and sound resources will be looked for first in that -Blorb file. -

-If Windows Git cannot find a requested resource in the Blorb file (or there is no Blorb -file), it will look for a suitably named file in the same directory as the game file. The -resource formats currently supported are shown below, along with the filename for which -the interpreter will look if the resource is not in the Blorb file (as an example, the -filename is for resource number 1): -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FormatTypeExample Filename
PNGimagepic1.png
JPEGimagepic1.jpg
AIFFsoundsnd1.aif or snd1.aiff
MODmusicmus1.mod
OGGVmusicmus1.ogg
-
- - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/glk.htm b/textworld/thirdparty/glulx/Git-Glulx/help/glk.htm deleted file mode 100644 index 406d593a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/glk.htm +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - -

Glk

-The Glk specification -was written by Andrew Plotkin as an attempt to define a standard input and output interface for general -use in IF related projects. Windows Git uses my (David Kinder) implementation of Glk, called Windows -Glk. Windows Glk is a complete implementation of all the features described in version 0.7.4 of the Glk -specification. -

-The complete Windows Glk package, including developer information, can be downloaded from the IF Archive's -Glk implementations -page. -

-More information on Glk is available from the Glk web page: -http://www.eblong.com/zarf/glk/ - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/glulx.htm b/textworld/thirdparty/glulx/Git-Glulx/help/glulx.htm deleted file mode 100644 index f5eac1e3..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/glulx.htm +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - -

Glulx

-The Glulx specification -was written by Andrew Plotkin as an attempt to define a format for interactive fiction games that -the Inform compiler could compile to, without the limitations of its original output format, Infocom's -Z-Machine. -

-Windows Git is based on Iain Merrick's Git 1.3.5, which is a complete implementation of version 3.1.2 -of the Glulx specification. -

-More information on Glulx is available from the Glulx web page: -http://www.eblong.com/zarf/glulx/ - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/help.png b/textworld/thirdparty/glulx/Git-Glulx/help/help.png deleted file mode 100644 index fbcc8314..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/help.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/license_ogg.htm b/textworld/thirdparty/glulx/Git-Glulx/help/license_ogg.htm deleted file mode 100644 index 5b25ce80..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/license_ogg.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - -

Ogg Vorbis License

-Copyright (c) 2002, Xiph.org Foundation -

-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 the Xiph.org Foundation 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 FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/menus_toolbar.htm b/textworld/thirdparty/glulx/Git-Glulx/help/menus_toolbar.htm deleted file mode 100644 index c2a9c2c2..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/menus_toolbar.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - -

Menus and the Toolbar

-Windows Git provides the following menu items, the most commonly used of which also appear on the toolbar: -

-Scrollback Ctrl+L
-Opens the scrollback dialog, which shows all the text printed since the current game was started. -

-Fonts/Proportional Font...
-Opens the font dialog for selecting the proportional font used for text in the game. -

-Fonts/Fixed Width Font...
-Opens the font dialog for selecting the fixed-width font used for text in the game that needs a -particular layout, such as the status bar, or any maps or symbols the game might display. -

-View/Options...
-Opens the options dialog. -

-Help
-Opens this help window. -

-About This Game
-Opens a dialog showing the cover art and description of the game, if available. -

-About Git
-Opens the About dialog, which shows the version number and credits for this version of Windows Git. -

-Exit Alt+F4
-Exits the interpreter. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/options.htm b/textworld/thirdparty/glulx/Git-Glulx/help/options.htm deleted file mode 100644 index 23715308..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/options.htm +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - -

Changing Options

-From the Options dialog, you can change the various display options of Windows Git. -

-

General Options

-

-Borders between windows
-If selected, windows that the game opens in the main interpreter window are surrounded by a standard -window border. -

-Enable menus, toolbars and the status bar
-If selected, the interpreter window has a menu bar, a toolbar and a status bar. If not selected, these -items are not present. In either case, the options dialog is still always accessible from the system -menu (that is, the menu obtained by clicking on the icon in the left corner of the interpreter's title bar). -

-Style hints override user settings
-If selected, style hints set by the game override any style options selected by the user. The style -options are described below. -

-Use a custom hyperlink colour
-If selected, hyperlinks are displayed using the colour set by the colour chooser button to the right of -this option. -

-Underline hyperlinks
-If selected, hyperlinks are displayed underlined, as in most web browsers. -

-If the game has an iFiction record ...
-When Windows Git loads a game that contains an iFiction record, it may show the About This Game -dialog. This option determines whether the dialog is never shown, only shown the first time, or shown -every time. -

-

Style Options

-Note that changing the values discussed below will only affect new windows opened by the game, not any -existing ones. Furthermore, if the game overrides any of these settings with style hints, then that -particular style will not be editable. -

-Window
-Determines the type of window for which the style is being edited. Text buffer windows are the normal -windows in which output appears in the proportional font and the user enters input. Text grid windows -always show text in a fixed width font and are used for tasks such as a status bar. Only some of the -style options are relevant for text grid windows; the remainder are greyed out. -

-Style
-Determines the particular style being edited. -

-Indentation
-How much a paragraph in this style is indented, in arbitrary units. -

-Paragraph Indentation
-How much the first line of a paragraph in this style is indented, in arbitrary units. -

-Justification
-Whether paragraphs are drawn flush with the left margin, the right margin, both margins, or -centered. -

-Text Size
-The size of the text, measured in arbitrary units, relative to the default size determined -by the user using the font dialogs from the menu or toolbar. -

-Text Weight
-Whether the text is drawn normally, emphasized, or lightly. -

-Italic
-If selected, text is drawn italicised. -

-Proportional
-If selected, text is drawn using the proportional font. If not selected, the fixed-width -font is used instead. -

-Reverse
-If selected, text is drawn reversed, i.e. the background colour is used to draw the text, -with the background set to the text colour. -

-Text Colour
-The colour in which the text is drawn in. -

-Background
-The colour in which the background behind the text is drawn. -

-

Speech Options

-Windows Git can use Microsoft's Speech Engine 5 to speak text, which is present by default -in Windows XP and later. If it is present, there is a Speech tab in in the options -dialog, containing controls that allow speaking of the game's text to be turned on, and the -voice and speed at which it is spoken in to be set. - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/options.png b/textworld/thirdparty/glulx/Git-Glulx/help/options.png deleted file mode 100644 index cef8fbb0..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/options.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/overview.htm b/textworld/thirdparty/glulx/Git-Glulx/help/overview.htm deleted file mode 100644 index 9e5de6ce..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/overview.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - -

Windows Git 1.3.5
(Windows Glk 1.47)

-Windows Git is an interpreter for Glulx games. Windows Git -consists of a core interpreter called Git, and an input/output library, called Windows -Glk. Together these two components form the Windows Git package, which has been created -by David Kinder.
-Web: http://www.davidkinder.co.uk/
-Email: davidk@davidkinder.co.uk
-

-Git's main goal in life is to be fast. It's about five times faster than Glulxe, -and about twice as fast as Frotz (using the same Inform source compiled for the -Z-machine). It also tries to be reasonably careful with memory: it's possible to -trade speed off against memory by changing the sizes of Git's internal buffers. -Git was written so that people would be able to write huge games or try out -complicated algorithms without worrying about how fast their games are going to -run. -

-The latest release of Windows Git is available from the -Git -page at the IF Archive, which also contains many games that can be -played with Windows Git. -For help on how to get started with Windows Git, click here. -

-Windows Git supports all the features of the Glk and -Blorb specifications, including graphics (with alpha blending and -gamma correction) and sound (as either samples or music). -Windows Git is based on Windows Glk by David Kinder and Git by Iain Merrick. -Windows Glk and Git are released under these licenses. -

- - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/prop.png b/textworld/thirdparty/glulx/Git-Glulx/help/prop.png deleted file mode 100644 index e0c27d24..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/prop.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/revision.htm b/textworld/thirdparty/glulx/Git-Glulx/help/revision.htm deleted file mode 100644 index 777215ad..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/help/revision.htm +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - -

Revision History

- -Git 1.3.5 (Windows Glk 1.47) -
    -
  • Updated to support Glk 0.7.5, which adds character input to graphics windows, clarifies -the behaviour of zero-size windows, and specifies the encoding of Unicode text files as UTF-8. -
- -Git 1.3.5 (Windows Glk 1.46) -
    -
  • Fixed a bug when the streamnum opcode is called with the smallest possible negative number. -
  • A new configuration file option, "FontFile", allows the game's font to be loaded from -a font file in the same directory as the game. -
  • Some of the Unicode characters above $FFFF (that is, those in the Supplementary Multilingual -Plane) can now be output, provided that an appropriate font is available. -
  • Unicode text files are now encoded as UTF-8, as specified in the latest draft of the Glk -0.7.5 specification. -
- -Git 1.3.4 (Windows Glk 1.45) -
    -
  • Performance improvements from Peter De Wachter, which give approximately a 15% speed -increase. -
- -Git 1.3.3 (Windows Glk 1.45) -
    -
  • The way in which colours are specified in the options dialog has been simplified: the -"General" tab now contains three buttons that allow the overall text, background and hyperlink -colours to be specified. Text and background colours are no longer specified in the "Styles" -tab on a per-style basis. -
  • The function glk_window_get_arrangement() no longer causes a crash if any of its output -arguments are 0. -
  • Added acceleration functions 8 through 13, which work correctly when the Inform 6 compiler -setting NUM_ATTR_BYTES is changed, contributed by Andrew Plotkin. -
- -Git 1.3.2 (Windows Glk 1.44) -
    -
  • A further fix related to Glk call dispatching, following the similar fix added to -Glulxe 0.5.1. -
  • Increased the undo buffer size to 2Mb. -
- -Git 1.3.1 (Windows Glk 1.44) -
    -
  • Further fixes related to Glk call dispatching, following similar fixes added to -Glulxe 0.5.0. -
- -Git 1.3.0 (Windows Glk 1.44) -
    -
  • Updated to Git 1.3.0, which fixes a bug related to Glk call dispatching, -and a bug in the file restore logic. -
  • Updated to support Glk 0.7.4, which introduces resource streams (i.e. access to -read-only data held in the Blorb game file). -
- -Git 1.2.9 (Windows Glk 1.43) -
    -
  • Updated to support Glk 0.7.3, which includes more control when playing sounds. -This revision of the Glk specification also now specifies the meaning of the volume argument to -sound related Glk calls: as a result the handling of the volume has been changed to match the -specification. -
  • [More] prompts now function even if the game has exited, allowing any -long amount of final text to be read. -
  • Fixed a bug with file streams when reading and writing to the same file. -
  • Updated to Git 1.2.9, which fixes bugs related to Glk call dispatching, -following similar fixes in Glulxe. -
- -Git 1.2.8 (Windows Glk 1.42) -
    -
  • The accuracy of the time returned by glk_current_time() has been improved. Providing that the -computer supports a sufficiently high resolution timer, the returned time is now correct to the -nearest microsecond. -
- -Git 1.2.8 (Windows Glk 1.41) -
    -
  • Updated to support Glk 0.7.2, which includes functions for accessing the system's date and time. -
  • Updated to support Glk 0.7.1, which includes functions for Unicode string decomposition and -normalization, and control over line input echoing and terminator characters. -
  • Unicode characters now appear correctly in the scrollback dialog, provided that the dialog -font supports them. -
- -Git 1.2.8 (Windows Glk 1.40) -
    -
  • Updated to Git 1.2.8, which fixes a few obscure bugs. -
  • Corrected problems with formatting and line input when margin images are present. -
  • Corrected a mistake in the handling of alpha-blended images. -
- -Git 1.2.7 (Windows Glk 1.39) -
    -
  • Updated to Git 1.2.7, which implements the Glulx 3.1.2 specification (for floating point opcodes). -
  • The window can be made to fill the entire screen; press Alt+Enter to toggle -this full screen mode on and off. -
  • A new configuration file option, "FullScreen", also makes the window fill the entire screen. -
  • During line input, Ctrl+Left moves the cursor to the start of the current word, and Ctrl+Right -moves to the end. -
  • The logic when scaling alpha-blended images has been improved, so there should no longer be -artifacts round the edges of such images. -
  • Data being written to files is now flushed whenever input is requested from the user. -This allows, for example, transcript files to update as a game is being played, and not only -when the interpreter closes the file. -
  • Corrected a problem which could result in the options dialog using the wrong font. -
- -Git 1.2.6 (Windows Glk 1.38) -
    -
  • Fixed a file creation bug in glk_stream_open_file(). -
- -Git 1.2.6 (Windows Glk 1.37) -
    -
  • Updated to Git 1.2.6, which fixes a bug in retained Glk array handling. -
- -Git 1.2.5 (Windows Glk 1.37) -
    -
  • Updated to Git 1.2.5, which fixes several problems shown by Andrew Plotkin's -glulxercise test cases. -
- -Git 1.2.4 (Windows Glk 1.37) -
    -
  • Clicking on a Glk window now only shifts the keyboard input focus to that window if the -window is capable of text input: this means that after clicking on a graphics window, text can -still be input in a text buffer window without having to click back to the text buffer window. -
  • The implementation of the algorithm for scaling images has been sped up again. -
- - diff --git a/textworld/thirdparty/glulx/Git-Glulx/help/scroll.png b/textworld/thirdparty/glulx/Git-Glulx/help/scroll.png deleted file mode 100644 index d899105b..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/help/scroll.png and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/labels.inc b/textworld/thirdparty/glulx/Git-Glulx/labels.inc deleted file mode 100644 index d0dfbbd0..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/labels.inc +++ /dev/null @@ -1,235 +0,0 @@ -// Pseudo-operations. - -LABEL (jump_abs_L7) -LABEL (enter_function_L1) - -LABEL (debug_step) - -LABEL (args_stack_call_stub_discard) -LABEL (args_stack_call_stub_addr) -LABEL (args_stack_call_stub_local) -LABEL (args_stack_call_stub_stack) - -LABEL (args_stack) -LABEL (args_0) -LABEL (args_1) -LABEL (args_2) -LABEL (args_3) - -LABEL (call_stub_discard) -LABEL (call_stub_addr) -LABEL (call_stub_local) -LABEL (call_stub_stack) - -LABEL (catch_stub_discard) -LABEL (catch_stub_addr) -LABEL (catch_stub_local) -LABEL (catch_stub_stack) - -LABEL (save_stub_discard) -LABEL (save_stub_addr) -LABEL (save_stub_local) -LABEL (save_stub_stack) - -LABEL (undo_stub_discard) -LABEL (undo_stub_addr) -LABEL (undo_stub_local) -LABEL (undo_stub_stack) - -LABEL (tailcall) -LABEL (throw) - -// Loading and storing registers. - -#define LOAD_LABELS(tag) \ - LABEL (L1_ ## tag) \ - LABEL (L2_ ## tag) \ - LABEL (L3_ ## tag) \ - LABEL (L4_ ## tag) \ - LABEL (L5_ ## tag) \ - LABEL (L6_ ## tag) \ - LABEL (L7_ ## tag) \ - LABEL (L1_const_L2_ ## tag) \ - LABEL (L1_stack_L2_ ## tag) \ - LABEL (L1_local_L2_ ## tag) \ - LABEL (L1_addr_L2_ ## tag) - -#define STORE_LABELS(tag) \ - LABEL (S1_ ## tag) \ - LABEL (S2_ ## tag) - -LOAD_LABELS(const) -LOAD_LABELS(stack) -LOAD_LABELS(local) -LOAD_LABELS(addr) - -STORE_LABELS(stack) -STORE_LABELS(local) -STORE_LABELS(addr) - -LABEL(L1_addr16) -LABEL(L1_addr8) - -LABEL(S1_addr16) -LABEL(S1_addr8) - -#undef LOAD_LABELS -#undef STORE_LABELS - -// Labels corresponding to glulx opcodes. - -LABEL (nop) - -#define PEEPHOLE_STORE_LABELS(tag) \ - LABEL (add ## tag) \ - LABEL (sub ## tag) \ - LABEL (mul ## tag) \ - LABEL (div ## tag) \ - LABEL (mod ## tag) \ - LABEL (neg ## tag) \ - LABEL (bitand ## tag) \ - LABEL (bitor ## tag) \ - LABEL (bitxor ## tag) \ - LABEL (bitnot ## tag) \ - LABEL (shiftl ## tag) \ - LABEL (sshiftr ## tag) \ - LABEL (ushiftr ## tag) \ - LABEL (copys ## tag) \ - LABEL (copyb ## tag) \ - LABEL (sexs ## tag) \ - LABEL (sexb ## tag) \ - LABEL (aload ## tag) \ - LABEL (aloads ## tag) \ - LABEL (aloadb ## tag) \ - LABEL (aloadbit ## tag) \ - LABEL (fadd ## tag) \ - LABEL (fsub ## tag) \ - LABEL (fmul ## tag) \ - LABEL (fdiv ## tag) - -PEEPHOLE_STORE_LABELS(_discard) -PEEPHOLE_STORE_LABELS(_S1_stack) -PEEPHOLE_STORE_LABELS(_S1_local) -PEEPHOLE_STORE_LABELS(_S1_addr) - -#define PEEPHOLE_LOAD_LABELS(tag) \ - LABEL (return_L1_ ## tag) \ - LABEL (astore_L3_ ## tag) \ - LABEL (astores_L3_ ## tag) \ - LABEL (astoreb_L3_ ## tag) \ - LABEL (astorebit_L3_ ## tag) - -PEEPHOLE_LOAD_LABELS(const) -PEEPHOLE_LOAD_LABELS(stack) -PEEPHOLE_LOAD_LABELS(addr) -PEEPHOLE_LOAD_LABELS(local) - -LABEL (return) -LABEL (astore) -LABEL (astores) -LABEL (astoreb) -LABEL (astorebit) - -#undef PEEPHOLE_STORE_LABELS - -#define BRANCH_LABELS(tag) \ - LABEL (jump ## tag) \ - LABEL (jz ## tag) \ - LABEL (jnz ## tag) \ - LABEL (jeq ## tag) \ - LABEL (jne ## tag) \ - LABEL (jlt ## tag) \ - LABEL (jge ## tag) \ - LABEL (jgt ## tag) \ - LABEL (jle ## tag) \ - LABEL (jltu ## tag) \ - LABEL (jgeu ## tag) \ - LABEL (jgtu ## tag) \ - LABEL (jleu ## tag) \ - LABEL (jflt ## tag) \ - LABEL (jfge ## tag) \ - LABEL (jfgt ## tag) \ - LABEL (jfle ## tag) \ - LABEL (jisnan ## tag) \ - LABEL (jisinf ## tag) \ - LABEL (jfeq ## tag) \ - LABEL (jfne ## tag) - -BRANCH_LABELS(_var) -BRANCH_LABELS(_const) -BRANCH_LABELS(_by) -BRANCH_LABELS(_return0) -BRANCH_LABELS(_return1) - -LABEL (stkcount) -LABEL (stkpeek) -LABEL (stkswap) -LABEL (stkroll) -LABEL (stkcopy) - -LABEL (streamchar) -LABEL (streamnum) -LABEL (streamstr) -LABEL (streamunichar) - -LABEL (gestalt) -LABEL (debugtrap) -LABEL (getmemsize) -LABEL (setmemsize) -LABEL (jumpabs) - -LABEL (random) -LABEL (setrandom) - -LABEL (quit) -LABEL (verify) -LABEL (restart) -LABEL (restore) -LABEL (restoreundo) -LABEL (protect) - -LABEL (glk) - -LABEL (getstringtbl) -LABEL (setstringtbl) -LABEL (getiosys) -LABEL (setiosys) - -LABEL (linearsearch) -LABEL (binarysearch) -LABEL (linkedsearch) - -LABEL (mzero) -LABEL (mcopy) -LABEL (malloc) -LABEL (mfree) - -LABEL (accelfunc) -LABEL (accelparam) - -LABEL (numtof) -LABEL (ftonumz) -LABEL (ftonumn) -LABEL (ceil) -LABEL (floor) -LABEL (fmod) -LABEL (sqrt) -LABEL (exp) -LABEL (log) -LABEL (pow) -LABEL (sin) -LABEL (cos) -LABEL (tan) -LABEL (asin) -LABEL (acos) -LABEL (atan) -LABEL (atan2) - -LABEL (git_setcacheram) -LABEL (git_prunecache) - -LABEL (error_bad_opcode) -LABEL (recompile) - -// No more labels to define. -#undef LABEL diff --git a/textworld/thirdparty/glulx/Git-Glulx/memory.c b/textworld/thirdparty/glulx/Git-Glulx/memory.c deleted file mode 100644 index 9b92bc50..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/memory.c +++ /dev/null @@ -1,161 +0,0 @@ -// $Id: memory.c,v 1.11 2004/01/25 21:04:19 iain Exp $ - -#include "git.h" -#include -#include - -const git_uint8 * gInitMem; -git_uint8 * gMem; - -git_uint32 gRamStart; -git_uint32 gExtStart; -git_uint32 gEndMem; -git_uint32 gOriginalEndMem; - -void initMemory (const git_uint8 * gamefile, git_uint32 size) -{ - // Make sure we have at least enough - // data for the standard glulx header. - - if (size < 36) - fatalError("This file is too small to be a valid glulx gamefile"); - - gInitMem = gamefile; - - // Check the magic number. From the spec: - // * Magic number: 47 6C 75 6C, which is to say ASCII 'Glul'. - - if (read32 (gInitMem + 0) != 0x476c756c) - fatalError("This is not a glulx game file"); - - // Load the correct values for ramstart, extstart and endmem. - - gRamStart = read32 (gInitMem + 8); - gExtStart = read32 (gInitMem + 12); - gOriginalEndMem = gEndMem = read32 (gInitMem + 16); - - // Make sure the values are sane. - - if (gRamStart < 36) - fatalError ("Bad header (RamStart is too low)"); - - if (gRamStart > size) - fatalError ("Bad header (RamStart is bigger than the entire gamefile)"); - - if (gExtStart > size) - fatalError ("Bad header (ExtStart is bigger than the entire gamefile)"); - - if (gExtStart < gRamStart) - fatalError ("Bad header (ExtStart is lower than RamStart)"); - - if (gEndMem < gExtStart) - fatalError ("Bad header (EndMem is lower than ExtStart)"); - - if (gRamStart & 255) - fatalError ("Bad header (RamStart is not a multiple of 256)"); - - if (gExtStart & 255) - fatalError ("Bad header (ExtStart is not a multiple of 256)"); - - if (gEndMem & 255) - fatalError ("Bad header (EndMem is not a multiple of 256)"); - - // Allocate the RAM. We'll duplicate the last few bytes of ROM - // here so that reads which cross the ROM/RAM boundary don't fail. - - gMem = malloc (gEndMem); - if (gMem == NULL) - fatalError ("Failed to allocate game RAM"); - - // Copy the initial memory contents. - memcpy (gMem, gInitMem, gExtStart); - - // Zero out the extended RAM. - memset (gMem + gExtStart, 0, gEndMem - gExtStart); -} - -int verifyMemory () -{ - git_uint32 checksum = 0; - - git_uint32 n; - for (n = 0 ; n < gExtStart ; n += 4) - checksum += read32 (gInitMem + n); - - checksum -= read32 (gInitMem + 32); - return (checksum == read32 (gInitMem + 32)) ? 0 : 1; -} - -int resizeMemory (git_uint32 newSize, int isInternal) -{ - git_uint8* newMem; - - if (newSize == gEndMem) - return 0; // Size is not changed. - if (!isInternal && heap_is_active()) - fatalError ("Cannot resize Glulx memory space while heap is active."); - if (newSize < gOriginalEndMem) - fatalError ("Cannot resize Glulx memory space smaller than it started."); - if (newSize & 0xFF) - fatalError ("Can only resize Glulx memory space to a 256-byte boundary."); - - newMem = realloc(gMem, newSize); - if (!newMem) - { - return 1; // Failed to extend memory. - } - if (newSize > gEndMem) - memset (newMem + gEndMem, 0, newSize - gEndMem); - - gMem = newMem; - gEndMem = newSize; - return 0; -} - -void resetMemory (git_uint32 protectPos, git_uint32 protectSize) -{ - git_uint32 protectEnd = protectPos + protectSize; - git_uint32 i; - - // Deactivate the heap (if it was active). - heap_clear(); - - gEndMem = gOriginalEndMem; - - // Copy the initial contents of RAM. - for (i = gRamStart; i < gExtStart; ++i) - { - if (i >= protectEnd || i < protectPos) - gMem [i] = gInitMem [i]; - } - - // Zero out the extended RAM. - for (i = gExtStart; i < gEndMem; ++i) - { - if (i >= protectEnd || i < protectPos) - gMem [i] = 0; - } -} - -void shutdownMemory () -{ - // We didn't allocate the ROM, so we - // only need to dispose of the RAM. - - free (gMem); - - // Zero out all our globals. - - gRamStart = gExtStart = gEndMem = gOriginalEndMem = 0; - gInitMem = gMem = NULL; -} - -void memReadError (git_uint32 address) -{ - fatalError ("Out-of-bounds memory access"); -} - -void memWriteError (git_uint32 address) -{ - fatalError ("Out-of-bounds memory access"); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/memory.h b/textworld/thirdparty/glulx/Git-Glulx/memory.h deleted file mode 100644 index c95d27a8..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/memory.h +++ /dev/null @@ -1,158 +0,0 @@ -// $Id: memory.h,v 1.7 2004/01/25 21:04:19 iain Exp $ -// Functions and macros for accessing game memory. - -#ifndef GIT_MEMORY_H -#define GIT_MEMORY_H - -#include "config.h" - -// -------------------------------------------------------------- -// Macros for reading and writing big-endian data. - -#ifdef USE_BIG_ENDIAN_UNALIGNED -// We're on a big-endian platform which can handle unaligned -// accesses, such as the PowerPC. This means we can read and -// write multi-byte values in glulx memory directly, without -// having to pack and unpack each byte. - -#define read32(ptr) (*((git_uint32*)(ptr))) -#define read16(ptr) (*((git_uint16*)(ptr))) -#define write32(ptr,v) (read32(ptr)=(git_uint32)(v)) -#define write16(ptr,v) (read16(ptr)=(git_uint16)(v)) - -#else -// We're on a little-endian platform, such as the x86, or a -// big-endian platform that doesn't like unaligned accesses, -// such as the 68K. This means we have to read and write the -// slow and tedious way. - -#define read32(ptr) \ - ( (git_uint32)(((git_uint8 *)(ptr))[0] << 24) \ - | (git_uint32)(((git_uint8 *)(ptr))[1] << 16) \ - | (git_uint32)(((git_uint8 *)(ptr))[2] << 8) \ - | (git_uint32)(((git_uint8 *)(ptr))[3])) -#define read16(ptr) \ - ( (git_uint16)(((git_uint8 *)(ptr))[0] << 8) \ - | (git_uint16)(((git_uint8 *)(ptr))[1])) - -#define write32(ptr, v) \ - (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 24)), \ - ((ptr)[1] = (git_uint8)(((git_uint32)(v)) >> 16)), \ - ((ptr)[2] = (git_uint8)(((git_uint32)(v)) >> 8)), \ - ((ptr)[3] = (git_uint8)(((git_uint32)(v))))) -#define write16(ptr, v) \ - (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 8)), \ - ((ptr)[1] = (git_uint8)(((git_uint32)(v))))) - -#endif // USE_BIG_ENDIAN_UNALIGNED - -GIT_INLINE git_uint32 readtag (const char *ptr) { - return read32((const git_uint8 *)ptr); -} - -// Accessing single bytes is easy on any platform. - -#define read8(ptr) (*((git_uint8*)(ptr))) -#define write8(ptr, v) (read8(ptr)=(git_uint8)(v)) - -// -------------------------------------------------------------- -// Globals - -extern git_uint32 gRamStart; // The start of RAM. -extern git_uint32 gExtStart; // The start of extended memory (initialised to zero). -extern git_uint32 gEndMem; // The current end of memory. -extern git_uint32 gOriginalEndMem; // The value of EndMem when the game was first loaded. - -// This is the entire gamefile, as read-only memory. It contains -// both the ROM, which is constant for the entire run of the program, -// and the original RAM, which is useful for checking what's changed -// when saving to disk or remembering a position for UNDO. -extern const git_uint8 * gInitMem; - -// This is the current contents of memory. This buffer includes -// both the ROM and the current contents of RAM. -extern git_uint8 * gMem; - - -// -------------------------------------------------------------- -// Functions - -// Initialise game memory. This sets up all the global variables -// declared above. Note that it does *not* copy the given memory -// image: it must be valid for the lifetime of the program. - -extern void initMemory (const git_uint8 * game, git_uint32 gameSize); - -// Verifies the gamefile based on its checksum. 0 on success, 1 on failure. - -extern int verifyMemory (); - -// Resizes the game's memory. Returns 0 on success, 1 on failure. - -extern int resizeMemory (git_uint32 newSize, int isInternal); - -// Resets memory to its initial state. Call this when the game restarts. - -extern void resetMemory (git_uint32 protectPos, git_uint32 protectSize); - -// Disposes of all the data structures allocated in initMemory(). - -extern void shutdownMemory (); - -// Utility functions -- these just pass an appropriate -// string to fatalError(). - -extern git_noreturn void memReadError (git_uint32 address); -extern git_noreturn void memWriteError (git_uint32 address); - -// Functions for reading and writing game memory. - -GIT_INLINE git_uint32 memRead32 (git_uint32 address) -{ - if (address <= gEndMem - 4) - return read32 (gMem + address); - else - return memReadError (address), 0; -} - -GIT_INLINE git_uint32 memRead16 (git_uint32 address) -{ - if (address <= gEndMem - 2) - return read16 (gMem + address); - else - return memReadError (address), 0; -} - -GIT_INLINE git_uint32 memRead8 (git_uint32 address) -{ - if (address < gEndMem) - return read8 (gMem + address); - else - return memReadError (address), 0; -} - -GIT_INLINE void memWrite32 (git_uint32 address, git_uint32 val) -{ - if (address >= gRamStart && address <= (gEndMem - 4)) - write32 (gMem + address, val); - else - memWriteError (address); -} - -GIT_INLINE void memWrite16 (git_uint32 address, git_uint32 val) -{ - if (address >= gRamStart && address <= (gEndMem - 2)) - write16 (gMem + address, val); - else - memWriteError (address); -} - -GIT_INLINE void memWrite8 (git_uint32 address, git_uint32 val) -{ - if (address >= gRamStart && address < gEndMem) - write8 (gMem + address, val); - else - memWriteError (address); -} - -#endif // GIT_MEMORY_H diff --git a/textworld/thirdparty/glulx/Git-Glulx/opcodes.c b/textworld/thirdparty/glulx/Git-Glulx/opcodes.c deleted file mode 100644 index d809df00..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/opcodes.c +++ /dev/null @@ -1,508 +0,0 @@ -// $Id: opcodes.c,v 1.20 2004/12/22 12:40:07 iain Exp $ - -#include "git.h" -#include "opcodes.h" - -static void parseModeNibbles (git_uint32* pc, int numModes, int * modeBuffer) -{ - int * mode = modeBuffer; - - while (numModes > 0) - { - // Load byte. - git_uint32 byte = memRead8((*pc)++); - - // Load low nibble. - *mode++ = byte & 0x0f; - --numModes; - - // Check whether we need to load any more. - if (numModes == 0) - break; - - // Load high nibble. - *mode++ = (byte >> 4) & 0x0f; - --numModes; - } -} - -static void parseLS (git_uint32* pc, Label op) -{ - int modes [2]; - parseModeNibbles (pc, 2, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - emitCode (op); - parseStore (pc, reg_S1, modes [1], size32); -} -static void parseLLS (git_uint32* pc, Label op) -{ - int modes [3]; - parseModeNibbles (pc, 3, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (op); - parseStore (pc, reg_S1, modes [2], size32); -} -static void parseLLSS (git_uint32* pc, Label op) -{ - int modes [4]; - parseModeNibbles (pc, 4, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (op); - parseStore (pc, reg_S1, modes [2], size32); - parseStore (pc, reg_S2, modes [3], size32); -} -static void parseL (git_uint32* pc, Label op) -{ - int modes [1]; - parseModeNibbles (pc, 1, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - emitCode (op); -} -static void parseLL (git_uint32* pc, Label op) -{ - int modes [2]; - parseModeNibbles (pc, 2, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (op); -} -static void parse_finish_branch (git_uint32* pc, Label op, LoadReg reg, int mode) -{ - git_sint32 val; - if (parseLoad (pc, reg, mode, size32, &val)) - { - // The branch offset is a constant, so we can - // check for the special values 0 and 1 right here. - - if (val == 0) - { - emitCode (op - label_jeq_var + label_jeq_return0); - } - else if (val == 1) - { - emitCode (op - label_jeq_var + label_jeq_return1); - } - else - { - // Calculate the destination address and - // emit a constant branch opcode. - emitConstBranch (op - label_jeq_var + label_jeq_const, *pc + val - 2); - } - } - else - { - // The branch offset isn't a constant, so just - // emit the normal opcode plus the current PC. - - emitCode (op); - emitData(*pc); - } -} -static void parseLLLL_branch (git_uint32* pc, Label op) -{ - int modes [4]; - parseModeNibbles (pc, 4, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - parse_finish_branch (pc, op, reg_L4, modes [3]); -} -static void parseLLL_branch (git_uint32* pc, Label op) -{ - int modes [3]; - parseModeNibbles (pc, 3, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parse_finish_branch (pc, op, reg_L3, modes [2]); -} -static void parseLL_branch (git_uint32* pc, Label op) -{ - int modes [2]; - parseModeNibbles (pc, 2, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parse_finish_branch (pc, op, reg_L2, modes [1]); -} -static void parseL_branch (git_uint32* pc, Label op) -{ - int modes [1]; - parseModeNibbles (pc, 1, modes); - - parse_finish_branch (pc, op, reg_L1, modes [0]); -} -static void parseLLL (git_uint32* pc, Label op) -{ - int modes [3]; - parseModeNibbles (pc, 3, modes); - - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - emitCode (op); -} -static void parseS (git_uint32* pc, Label op) -{ - int modes [1]; - parseModeNibbles (pc, 1, modes); - - emitCode (op); - parseStore (pc, reg_S1, modes [0], size32); -} -static void parseSS (git_uint32* pc, Label op) -{ - int modes [2]; - parseModeNibbles (pc, 2, modes); - - emitCode (op); - parseStore (pc, reg_S1, modes [0], size32); - parseStore (pc, reg_S2, modes [1], size32); -} -static void parseCatch (git_uint32 * pc) -{ - int modes [2]; - parseModeNibbles (pc, 2, modes); - - parseCatchStub (pc, modes); -} -void parseInstruction (git_uint32* pc, int * done) -{ - git_uint32 pcStart = *pc; - int modes [8]; - git_uint32 opcode; - - static int ops = 0; - ++ops; - - // Fetch the opcode. - opcode = memRead8((*pc)++); - - // Check for multi-byte opcode. - if (opcode & 0x80) - { - if (opcode & 0x40) - { - // Four-byte opcode. - opcode &= 0x3F; - opcode = (opcode << 8) | memRead8((*pc)++); - opcode = (opcode << 8) | memRead8((*pc)++); - opcode = (opcode << 8) | memRead8((*pc)++); - } - else - { - // Two-byte opcode. - opcode &= 0x7F; - opcode = (opcode << 8) | memRead8((*pc)++); - } - } - - if (gDebug) - { - emitCode (label_debug_step); - emitData (pcStart); - emitData (opcode); - } - - // printf (" opcode=0x%x", opcode); - - // Now we have an opcode number, - // parse the operands and emit code. - - switch (opcode) - { - case op_nop: emitCode (label_nop); break; - - // Arithmetic and logic - - case op_add: parseLLS (pc, label_add_discard); break; - case op_sub: parseLLS (pc, label_sub_discard); break; - case op_mul: parseLLS (pc, label_mul_discard); break; - case op_div: parseLLS (pc, label_div_discard); break; - case op_mod: parseLLS (pc, label_mod_discard); break; - - case op_bitand: parseLLS (pc, label_bitand_discard); break; - case op_bitor: parseLLS (pc, label_bitor_discard); break; - case op_bitxor: parseLLS (pc, label_bitxor_discard); break; - - case op_neg: parseLS (pc, label_neg_discard); break; - case op_bitnot: parseLS (pc, label_bitnot_discard); break; - - case op_shiftl: parseLLS (pc, label_shiftl_discard); break; - case op_ushiftr: parseLLS (pc, label_ushiftr_discard); break; - case op_sshiftr: parseLLS (pc, label_sshiftr_discard); break; - - // Branches - - case op_jump: parseL_branch (pc, label_jump_var); *done = 1; break; - case op_jz: parseLL_branch (pc, label_jz_var); break; - case op_jnz: parseLL_branch (pc, label_jnz_var); break; - case op_jeq: parseLLL_branch (pc, label_jeq_var); break; - case op_jne: parseLLL_branch (pc, label_jne_var); break; - case op_jlt: parseLLL_branch (pc, label_jlt_var); break; - case op_jgt: parseLLL_branch (pc, label_jgt_var); break; - case op_jle: parseLLL_branch (pc, label_jle_var); break; - case op_jge: parseLLL_branch (pc, label_jge_var); break; - case op_jltu: parseLLL_branch (pc, label_jltu_var); break; - case op_jgtu: parseLLL_branch (pc, label_jgtu_var); break; - case op_jleu: parseLLL_branch (pc, label_jleu_var); break; - case op_jgeu: parseLLL_branch (pc, label_jgeu_var); break; - - case op_jumpabs: parseL (pc, label_jumpabs); *done = 1; break; - - // Moving data - - case op_copy: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseStore (pc, reg_S1, modes [1], size32); - break; - - case op_copys: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size16, NULL); - emitCode (label_copys_discard); - parseStore (pc, reg_S1, modes [1], size16); - break; - - case op_copyb: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size8, NULL); - emitCode (label_copyb_discard); - parseStore (pc, reg_S1, modes [1], size8); - break; - - case op_sexs: parseLS (pc, label_sexs_discard); break; - case op_sexb: parseLS (pc, label_sexb_discard); break; - - // Array data - - case op_aload: parseLLS (pc, label_aload_discard); break; - case op_aloads: parseLLS (pc, label_aloads_discard); break; - case op_aloadb: parseLLS (pc, label_aloadb_discard); break; - case op_aloadbit: parseLLS (pc, label_aloadbit_discard); break; - - case op_astore: parseLLL (pc, label_astore); break; - case op_astores: parseLLL (pc, label_astores); break; - case op_astoreb: parseLLL (pc, label_astoreb); break; - case op_astorebit: parseLLL (pc, label_astorebit); break; - - // The stack - - case op_stkcount: parseS (pc, label_stkcount); break; - case op_stkpeek: parseLS (pc, label_stkpeek); break; - case op_stkswap: emitCode (label_stkswap); break; - case op_stkcopy: parseL (pc, label_stkcopy); break; - case op_stkroll: parseLL (pc, label_stkroll); break; - - // Functions - - case op_call: - parseModeNibbles (pc, 3, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (label_args_stack); - parseCallStub (pc, modes [2]); - break; - - case op_callf: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - emitCode (label_args_0); - parseCallStub (pc, modes [1]); - break; - - case op_callfi: - parseModeNibbles (pc, 3, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (label_args_1); - parseCallStub (pc, modes [2]); - break; - - case op_callfii: - parseModeNibbles (pc, 4, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - emitCode (label_args_2); - parseCallStub (pc, modes [3]); - break; - - case op_callfiii: - parseModeNibbles (pc, 5, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - parseLoad (pc, reg_L4, modes [3], size32, NULL); - emitCode (label_args_3); - parseCallStub (pc, modes [4]); - break; - - case op_return: - parseL (pc, label_return); - *done = 1; - break; - - case op_tailcall: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - emitCode (label_args_stack); - emitCode (label_tailcall); - *done = 1; - break; - - // Continuations - - case op_catch: parseCatch (pc); break; - case op_throw: - parseLL (pc, label_throw); - *done = 1; - break; - - case op_random: parseLS (pc, label_random); break; - case op_setrandom: parseL (pc, label_setrandom); break; - - case op_getmemsize: parseS (pc, label_getmemsize); break; - case op_setmemsize: parseLS (pc, label_setmemsize); break; - - case op_quit: - emitCode (label_quit); - *done = 1; - break; - - case op_restart: - emitCode (label_restart); - *done = 1; - break; - - case op_restore: parseLS (pc, label_restore); break; - case op_restoreundo: parseS (pc, label_restoreundo); break; - case op_protect: parseLL (pc, label_protect); break; - case op_verify: parseS (pc, label_verify); break; - - case op_save: - parseModeNibbles (pc, 2, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseSaveStub (pc, modes [1]); - break; - - case op_saveundo: - parseModeNibbles (pc, 1, modes); - parseUndoStub (pc, modes [0]); - break; - - case op_getiosys: parseSS (pc, label_getiosys); break; - case op_setiosys: parseLL (pc, label_setiosys); break; - - case op_getstringtbl: parseS (pc, label_getstringtbl); break; - case op_setstringtbl: parseL (pc, label_setstringtbl); break; - - case op_streamchar: parseL (pc, label_streamchar); emitData(*pc); break; - case op_streamnum: parseL (pc, label_streamnum); emitData(*pc); break; - case op_streamstr: parseL (pc, label_streamstr); emitData(*pc); break; - case op_streamunichar: parseL (pc, label_streamunichar); emitData(*pc); break; - - case op_glk: parseLLS (pc, label_glk); break; - case op_gestalt: parseLLS (pc, label_gestalt); break; - - case op_binarysearch: - case op_linearsearch: - parseModeNibbles (pc, 8, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - parseLoad (pc, reg_L4, modes [3], size32, NULL); - parseLoad (pc, reg_L5, modes [4], size32, NULL); - parseLoad (pc, reg_L6, modes [5], size32, NULL); - parseLoad (pc, reg_L7, modes [6], size32, NULL); - emitCode (opcode == op_linearsearch ? label_linearsearch : label_binarysearch); - parseStore (pc, reg_S1, modes [7], size32); - break; - - case op_linkedsearch: - parseModeNibbles (pc, 7, modes); - parseLoad (pc, reg_L1, modes [0], size32, NULL); - parseLoad (pc, reg_L2, modes [1], size32, NULL); - parseLoad (pc, reg_L3, modes [2], size32, NULL); - parseLoad (pc, reg_L4, modes [3], size32, NULL); - parseLoad (pc, reg_L5, modes [4], size32, NULL); - parseLoad (pc, reg_L6, modes [5], size32, NULL); - emitCode (label_linkedsearch); - parseStore (pc, reg_S1, modes [6], size32); - break; - - case op_debugtrap: - parseL (pc, label_debugtrap); - break; - - // Memory management - - case op_mzero: parseLL (pc, label_mzero); break; - case op_mcopy: parseLLL (pc, label_mcopy); break; - - case op_malloc: parseLS (pc, label_malloc); break; - case op_mfree: parseL (pc, label_mfree); break; - - // Function acceleration - - case op_accelfunc: parseLL (pc, label_accelfunc); break; - case op_accelparam: parseLL (pc, label_accelparam); break; - - // Floating point - - case op_numtof: parseLS (pc, label_numtof); break; - case op_ftonumz: parseLS (pc, label_ftonumz); break; - case op_ftonumn: parseLS (pc, label_ftonumn); break; - case op_ceil: parseLS (pc, label_ceil); break; - case op_floor: parseLS (pc, label_floor); break; - case op_sqrt: parseLS (pc, label_sqrt); break; - case op_exp: parseLS (pc, label_exp); break; - case op_log: parseLS (pc, label_log); break; - - case op_fadd: parseLLS (pc, label_fadd_discard); break; - case op_fsub: parseLLS (pc, label_fsub_discard); break; - case op_fmul: parseLLS (pc, label_fmul_discard); break; - case op_fdiv: parseLLS (pc, label_fdiv_discard); break; - case op_pow: parseLLS (pc, label_pow); break; - case op_atan2: parseLLS (pc, label_atan2); break; - - case op_fmod: parseLLSS (pc, label_fmod); break; - - case op_sin: parseLS (pc, label_sin); break; - case op_cos: parseLS (pc, label_cos); break; - case op_tan: parseLS (pc, label_tan); break; - case op_asin: parseLS (pc, label_asin); break; - case op_acos: parseLS (pc, label_acos); break; - case op_atan: parseLS (pc, label_atan); break; - - case op_jfeq: parseLLLL_branch (pc, label_jfeq_var); break; - case op_jfne: parseLLLL_branch (pc, label_jfne_var); break; - - case op_jflt: parseLLL_branch (pc, label_jflt_var); break; - case op_jfle: parseLLL_branch (pc, label_jfle_var); break; - case op_jfgt: parseLLL_branch (pc, label_jfgt_var); break; - case op_jfge: parseLLL_branch (pc, label_jfge_var); break; - - case op_jisnan: parseLL_branch (pc, label_jisnan_var); break; - case op_jisinf: parseLL_branch (pc, label_jisinf_var); break; - - // Special Git opcodes - - case op_git_setcacheram: parseL (pc, label_git_setcacheram); break; - case op_git_prunecache: parseLL (pc, label_git_prunecache); break; - - default: - // Unknown opcode. - abortCompilation(); - break; - } -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/opcodes.h b/textworld/thirdparty/glulx/Git-Glulx/opcodes.h deleted file mode 100644 index 8f6fc55a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/opcodes.h +++ /dev/null @@ -1,146 +0,0 @@ -// $Id: opcodes.h,v 1.7 2004/12/22 12:40:07 iain Exp $ - -#ifndef OPCODES_H -#define OPCODES_H - -// Glulx opcodes. - -#define op_nop (0x00) - -#define op_add (0x10) -#define op_sub (0x11) -#define op_mul (0x12) -#define op_div (0x13) -#define op_mod (0x14) -#define op_neg (0x15) -#define op_bitand (0x18) -#define op_bitor (0x19) -#define op_bitxor (0x1A) -#define op_bitnot (0x1B) -#define op_shiftl (0x1C) -#define op_sshiftr (0x1D) -#define op_ushiftr (0x1E) - -#define op_jump (0x20) -#define op_jz (0x22) -#define op_jnz (0x23) -#define op_jeq (0x24) -#define op_jne (0x25) -#define op_jlt (0x26) -#define op_jge (0x27) -#define op_jgt (0x28) -#define op_jle (0x29) -#define op_jltu (0x2A) -#define op_jgeu (0x2B) -#define op_jgtu (0x2C) -#define op_jleu (0x2D) - -#define op_call (0x30) -#define op_return (0x31) -#define op_catch (0x32) -#define op_throw (0x33) -#define op_tailcall (0x34) - -#define op_copy (0x40) -#define op_copys (0x41) -#define op_copyb (0x42) -#define op_sexs (0x44) -#define op_sexb (0x45) -#define op_aload (0x48) -#define op_aloads (0x49) -#define op_aloadb (0x4A) -#define op_aloadbit (0x4B) -#define op_astore (0x4C) -#define op_astores (0x4D) -#define op_astoreb (0x4E) -#define op_astorebit (0x4F) - -#define op_stkcount (0x50) -#define op_stkpeek (0x51) -#define op_stkswap (0x52) -#define op_stkroll (0x53) -#define op_stkcopy (0x54) - -#define op_streamchar (0x70) -#define op_streamnum (0x71) -#define op_streamstr (0x72) -#define op_streamunichar (0x73) - -#define op_gestalt (0x100) -#define op_debugtrap (0x101) -#define op_getmemsize (0x102) -#define op_setmemsize (0x103) -#define op_jumpabs (0x104) - -#define op_random (0x110) -#define op_setrandom (0x111) - -#define op_quit (0x120) -#define op_verify (0x121) -#define op_restart (0x122) -#define op_save (0x123) -#define op_restore (0x124) -#define op_saveundo (0x125) -#define op_restoreundo (0x126) -#define op_protect (0x127) - -#define op_glk (0x130) - -#define op_getstringtbl (0x140) -#define op_setstringtbl (0x141) -#define op_getiosys (0x148) -#define op_setiosys (0x149) - -#define op_linearsearch (0x150) -#define op_binarysearch (0x151) -#define op_linkedsearch (0x152) - -#define op_callf (0x160) -#define op_callfi (0x161) -#define op_callfii (0x162) -#define op_callfiii (0x163) - -#define op_mzero (0x170) -#define op_mcopy (0x171) -#define op_malloc (0x178) -#define op_mfree (0x179) - -#define op_accelfunc (0x180) -#define op_accelparam (0x181) - -#define op_numtof (0x190) -#define op_ftonumz (0x191) -#define op_ftonumn (0x192) -#define op_ceil (0x198) -#define op_floor (0x199) -#define op_fadd (0x1A0) -#define op_fsub (0x1A1) -#define op_fmul (0x1A2) -#define op_fdiv (0x1A3) -#define op_fmod (0x1A4) -#define op_sqrt (0x1A8) -#define op_exp (0x1A9) -#define op_log (0x1AA) -#define op_pow (0x1AB) -#define op_sin (0x1B0) -#define op_cos (0x1B1) -#define op_tan (0x1B2) -#define op_asin (0x1B3) -#define op_acos (0x1B4) -#define op_atan (0x1B5) -#define op_atan2 (0x1B6) -#define op_jfeq (0x1C0) -#define op_jfne (0x1C1) -#define op_jflt (0x1C2) -#define op_jfle (0x1C3) -#define op_jfgt (0x1C4) -#define op_jfge (0x1C5) -#define op_jisnan (0x1C8) -#define op_jisinf (0x1C9) - -// Special cache control opcodes. - -#define op_git_setcacheram (0x7940) -#define op_git_prunecache (0x7941) - -#endif // OPCODES_H diff --git a/textworld/thirdparty/glulx/Git-Glulx/operands.c b/textworld/thirdparty/glulx/Git-Glulx/operands.c deleted file mode 100644 index 99c24af7..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/operands.c +++ /dev/null @@ -1,399 +0,0 @@ -// $Id: operands.c,v 1.11 2004/02/02 00:13:46 iain Exp $ - -#include "git.h" -#include - -git_uint32 parseLoad (git_uint32 * pc, LoadReg reg, int mode, TransferSize size, git_sint32 * constVal) -{ - git_uint32 value; - - switch (mode) - { - case 0x0: // Constant zero. (Zero bytes) - value = 0; - goto load_const; - - case 0x1: // Constant, -80 to 7F. (One byte) - value = (git_sint32) ((git_sint8) memRead8(*pc)); - *pc += 1; - goto load_const; - - case 0x2: // Constant, -8000 to 7FFF. (Two bytes) - value = (git_sint32) ((git_sint16) memRead16(*pc)); - *pc += 2; - goto load_const; - - case 0x3: // Constant, any value. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto load_const; - - case 0x5: // Contents of address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto load_addr; - - case 0x6: // Contents of address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto load_addr; - - case 0x7: // Contents of any address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto load_addr; - - case 0x8: // Value popped off stack. (Zero bytes) - goto load_stack; - - case 0x9: // Call frame local at address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto load_local; - - case 0xA: // Call frame local at address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto load_local; - - case 0xB: // Call frame local at any address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto load_local; - - case 0xD: // Contents of RAM address 00 to FF. (One byte) - value = memRead8(*pc) + gRamStart; - *pc += 1; - goto load_addr; - - case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes) - value = memRead16(*pc) + gRamStart; - *pc += 2; - goto load_addr; - - case 0xF: // Contents of RAM, any address. (Four bytes) - value = memRead32(*pc) + gRamStart; - *pc += 4; - goto load_addr; - - default: // Illegal addressing mode - abortCompilation(); - break; - - // ------------------------------------------------------ - - load_const: - if (constVal) - { - *constVal = value; - return 1; - } - else - { - emitCode (label_L1_const + reg); - emitData (value); - } - break; - - load_stack: - emitCode (label_L1_stack + reg); - break; - - load_addr: - if (value < gRamStart) - { - if (size == size32) - value = memRead32(value); - else if (size == size16) - value = memRead16(value); - else - value = memRead8(value); - goto load_const; - } - switch (size) - { - case size8: - assert (reg == reg_L1); - emitCode (label_L1_addr8); - break; - - case size16: - assert (reg == reg_L1); - emitCode (label_L1_addr16); - break; - - case size32: - emitCode (label_L1_addr + reg); - break; - } - emitData (value); - break; - - load_local: - emitCode (label_L1_local + reg); - emitData (value / 4); // Convert byte offset to word offset. - break; - } - - return 0; -} - -void parseStore (git_uint32 * pc, StoreReg reg, int mode, TransferSize size) -{ - git_uint32 value; - - switch (mode) - { - case 0x0: // Discard - break; - - case 0x5: // Contents of address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto store_addr; - - case 0x6: // Contents of address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto store_addr; - - case 0x7: // Contents of any address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto store_addr; - - case 0x8: // Value popped off stack. (Zero bytes) - goto store_stack; - - case 0x9: // Call frame local at store_address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto store_local; - - case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto store_local; - - case 0xB: // Call frame local at any store_address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto store_local; - - case 0xD: // Contents of RAM address 00 to FF. (One byte) - value = memRead8(*pc) + gRamStart; - *pc += 1; - goto store_addr; - - case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes) - value = memRead16(*pc) + gRamStart; - *pc += 2; - goto store_addr; - - case 0xF: // Contents of RAM, any address. (Four bytes) - value = memRead32(*pc) + gRamStart; - *pc += 4; - goto store_addr; - - // ------------------------------------------------------ - - store_stack: - emitCode (reg == reg_S1 ? label_S1_stack : label_S2_stack); - break; - - store_addr: - if (size == size32) - { - emitCode (reg == reg_S1 ? label_S1_addr : label_S2_addr); - } - else - { - assert (reg == reg_S1); - emitCode (size == size16 ? label_S1_addr16 : label_S1_addr8); - } - emitData (value); - break; - - store_local: - emitCode (reg == reg_S1 ? label_S1_local : label_S2_local); - emitData (value / 4); // Convert byte offset to word offset. - break; - } -} - -static void parseStub (git_uint32 * pc, int mode, Label discardOp) -{ - git_uint32 value; - switch (mode) - { - case 0x0: // Discard - goto store_discard; - case 0x5: // Contents of address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto store_addr; - case 0x6: // Contents of address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto store_addr; - case 0x7: // Contents of any address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto store_addr; - case 0x8: // Value popped off stack. (Zero bytes) - goto store_stack; - case 0x9: // Call frame local at store_address 00 to FF. (One byte) - value = memRead8(*pc); - *pc += 1; - goto store_local; - case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes) - value = memRead16(*pc); - *pc += 2; - goto store_local; - case 0xB: // Call frame local at any store_address. (Four bytes) - value = memRead32(*pc); - *pc += 4; - goto store_local; - case 0xD: // Contents of RAM address 00 to FF. (One byte) - value = memRead8(*pc) + gRamStart; - *pc += 1; - goto store_addr; - case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes) - value = memRead16(*pc) + gRamStart; - *pc += 2; - goto store_addr; - case 0xF: // Contents of RAM, any address. (Four bytes) - value = memRead32(*pc) + gRamStart; - *pc += 4; - goto store_addr; - // ------------------------------------------------------ - store_discard: - emitCode (discardOp); - break; - store_stack: - emitCode (discardOp + (label_call_stub_stack - label_call_stub_discard)); - break; - store_addr: - emitCode (discardOp + (label_call_stub_addr - label_call_stub_discard)); - emitData (value); - break; - store_local: - emitCode (discardOp + (label_call_stub_local - label_call_stub_discard)); - emitData (value); - break; - } - - // Every call stub ends with the glulx return address. - emitData (*pc); - - // ...which means that every call stub references the next instruction. - nextInstructionIsReferenced (); -} -void parseCallStub (git_uint32 * pc, int mode) -{ - parseStub (pc, mode, label_call_stub_discard); -} -void parseSaveStub (git_uint32 * pc, int mode) -{ - parseStub (pc, mode, label_save_stub_discard); -} -void parseUndoStub (git_uint32 * pc, int mode) -{ - parseStub (pc, mode, label_undo_stub_discard); -} - -void parseCatchStub (git_uint32 * pc, int * modes) -{ - git_uint32 tokenVal; - git_sint32 branchVal; - git_uint32 branchConst = 0; - Block stubCode; - - switch (modes[0]) - { - case 0x0: // Discard - goto store_discard; - case 0x5: // Contents of address 00 to FF. (One byte) - tokenVal = memRead8(*pc); - *pc += 1; - goto store_addr; - case 0x6: // Contents of address 0000 to FFFF. (Two bytes) - tokenVal = memRead16(*pc); - *pc += 2; - goto store_addr; - case 0x7: // Contents of any address. (Four bytes) - tokenVal = memRead32(*pc); - *pc += 4; - goto store_addr; - case 0x8: // Value popped off stack. (Zero bytes) - goto store_stack; - case 0x9: // Call frame local at store_address 00 to FF. (One byte) - tokenVal = memRead8(*pc); - *pc += 1; - goto store_local; - case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes) - tokenVal = memRead16(*pc); - *pc += 2; - goto store_local; - case 0xB: // Call frame local at any store_address. (Four bytes) - tokenVal = memRead32(*pc); - *pc += 4; - goto store_local; - case 0xD: // Contents of RAM address 00 to FF. (One byte) - tokenVal = memRead8(*pc) + gRamStart; - *pc += 1; - goto store_addr; - case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes) - tokenVal = memRead16(*pc) + gRamStart; - *pc += 2; - goto store_addr; - case 0xF: // Contents of RAM, any address. (Four bytes) - tokenVal = memRead32(*pc) + gRamStart; - *pc += 4; - goto store_addr; - // ------------------------------------------------------ - store_discard: - branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal); - emitCode (label_catch_stub_discard); - break; - store_stack: - branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal); - emitCode (label_catch_stub_stack); - break; - store_addr: - branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal); - emitCode (label_catch_stub_addr); - emitData (tokenVal); - break; - store_local: - branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal); - emitCode (label_catch_stub_local); - emitData (tokenVal); - break; - } - - // The catch stub ends with the address to go to on throw, - // which is after the branch, so we don't know what it is yet. - emitData (0); - stubCode = peekAtEmittedStuff (1); - - // Emit the branch taken after storing the catch token. - if (branchConst) - { - if (branchVal == 0) - emitCode (label_jump_return0); - else if (branchVal == 1) - emitCode (label_jump_return1); - else - emitConstBranch (label_jump_const, *pc + branchVal - 2); - } - else - { - emitCode (label_jump_var); - emitData (*pc); - } - - // Fix up the throw return address - *stubCode = *pc; - nextInstructionIsReferenced (); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/peephole.c b/textworld/thirdparty/glulx/Git-Glulx/peephole.c deleted file mode 100644 index 08b96065..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/peephole.c +++ /dev/null @@ -1,135 +0,0 @@ -// $Id: peephole.c,v 1.6 2003/10/13 22:53:04 iain Exp $ -// Peephole optimiser for git - -#include "git.h" - -static Label sLastOp; - -extern void resetPeepholeOptimiser () -{ - sLastOp = label_nop; -} - -#define REPLACE_SINGLE(lastOp,thisOp,newOp) \ - case label_ ## thisOp: \ - if (sLastOp == label_ ## lastOp) \ - { \ - op = label_ ## newOp; \ - goto replaceNoOperands; \ - } \ - break - -#define CASE_NO_OPERANDS(lastOp,newOp) \ - case label_ ## lastOp: op = label_ ## newOp; goto replaceNoOperands - -#define CASE_ONE_OPERAND(lastOp,newOp) \ - case label_ ## lastOp: op = label_ ## newOp; goto replaceOneOperand - -#define REPLACE_STORE(storeOp) \ - case label_ ## storeOp: \ - switch(sLastOp) \ - { \ - CASE_NO_OPERANDS (add_discard, add_ ## storeOp); \ - CASE_NO_OPERANDS (sub_discard, sub_ ## storeOp); \ - CASE_NO_OPERANDS (mul_discard, mul_ ## storeOp); \ - CASE_NO_OPERANDS (div_discard, div_ ## storeOp); \ - CASE_NO_OPERANDS (mod_discard, mod_ ## storeOp); \ - CASE_NO_OPERANDS (neg_discard, neg_ ## storeOp); \ - CASE_NO_OPERANDS (bitand_discard, bitand_ ## storeOp); \ - CASE_NO_OPERANDS (bitor_discard, bitor_ ## storeOp); \ - CASE_NO_OPERANDS (bitxor_discard, bitxor_ ## storeOp); \ - CASE_NO_OPERANDS (bitnot_discard, bitnot_ ## storeOp); \ - CASE_NO_OPERANDS (shiftl_discard, shiftl_ ## storeOp); \ - CASE_NO_OPERANDS (sshiftr_discard, sshiftr_ ## storeOp); \ - CASE_NO_OPERANDS (ushiftr_discard, ushiftr_ ## storeOp); \ - CASE_NO_OPERANDS (copys_discard, copys_ ## storeOp); \ - CASE_NO_OPERANDS (copyb_discard, copyb_ ## storeOp); \ - CASE_NO_OPERANDS (sexs_discard, sexs_ ## storeOp); \ - CASE_NO_OPERANDS (sexb_discard, sexb_ ## storeOp); \ - CASE_NO_OPERANDS (aload_discard, aload_ ## storeOp); \ - CASE_NO_OPERANDS (aloads_discard, aloads_ ## storeOp); \ - CASE_NO_OPERANDS (aloadb_discard, aloadb_ ## storeOp); \ - CASE_NO_OPERANDS (aloadbit_discard, aloadbit_ ## storeOp); \ - CASE_NO_OPERANDS (fadd_discard, fadd_ ## storeOp); \ - CASE_NO_OPERANDS (fsub_discard, fsub_ ## storeOp); \ - CASE_NO_OPERANDS (fmul_discard, fmul_ ## storeOp); \ - CASE_NO_OPERANDS (fdiv_discard, fdiv_ ## storeOp); \ - default: break; \ - } \ - break - -#define REPLACE_L1_L2(mode2) \ - case label_L2_ ## mode2: \ - switch(sLastOp) \ - { \ - CASE_ONE_OPERAND (L1_const, L1_const_L2_ ## mode2); \ - CASE_NO_OPERANDS (L1_stack, L1_stack_L2_ ## mode2); \ - CASE_ONE_OPERAND (L1_local, L1_local_L2_ ## mode2); \ - CASE_ONE_OPERAND (L1_addr, L1_addr_L2_ ## mode2); \ - default: break; \ - } \ - break - -#define REPLACE_LOAD_OP(loadOp,reg) \ - case label_ ## loadOp: \ - switch(sLastOp) \ - { \ - CASE_ONE_OPERAND (reg ## _const, loadOp ## _ ## reg ## _const); \ - CASE_NO_OPERANDS (reg ## _stack, loadOp ## _ ## reg ## _stack); \ - CASE_ONE_OPERAND (reg ## _local, loadOp ## _ ## reg ## _local); \ - CASE_ONE_OPERAND (reg ## _addr, loadOp ## _ ## reg ## _addr); \ - default: break; \ - } \ - break - -extern void emitCode (Label op) -{ - git_uint32 temp; - - if (gPeephole) - { - switch (op) - { - REPLACE_SINGLE (args_stack, call_stub_discard, args_stack_call_stub_discard); - REPLACE_SINGLE (args_stack, call_stub_addr, args_stack_call_stub_addr); - REPLACE_SINGLE (args_stack, call_stub_local, args_stack_call_stub_local); - REPLACE_SINGLE (args_stack, call_stub_stack, args_stack_call_stub_stack); - - REPLACE_STORE (S1_stack); - REPLACE_STORE (S1_local); - REPLACE_STORE (S1_addr); - - REPLACE_L1_L2 (const); - REPLACE_L1_L2 (stack); - REPLACE_L1_L2 (local); - REPLACE_L1_L2 (addr); - - REPLACE_LOAD_OP (return, L1); - REPLACE_LOAD_OP (astore, L3); - REPLACE_LOAD_OP (astores, L3); - REPLACE_LOAD_OP (astoreb, L3); - REPLACE_LOAD_OP (astorebit, L3); - - default: break; - } - } - goto noPeephole; - -replaceOneOperand: - // The previous opcode has one operand, so - // we have to go back two steps to update it. - temp = undoEmit(); // Save the operand. - undoEmit(); // Remove the old opcode. - emitFinalCode (op); // Emit the new opcode. - emitData (temp); // Emit the operand again. - goto done; - -replaceNoOperands: - undoEmit(); - // ... fall through -noPeephole: - emitFinalCode (op); - // ... fall through -done: - sLastOp = op; -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/savefile.c b/textworld/thirdparty/glulx/Git-Glulx/savefile.c deleted file mode 100644 index 63a8153a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/savefile.c +++ /dev/null @@ -1,317 +0,0 @@ -// $Id: savefile.c,v 1.6 2003/10/20 16:05:06 iain Exp $ - -#include "git.h" - -static void writeWord (git_sint32 word) -{ - git_uint8 buffer [4]; - write32 (buffer, word); - glk_put_buffer ((char *) buffer, 4); -} - -static git_uint32 readWord (strid_t file) -{ - git_uint8 buffer [4]; - glk_get_buffer_stream (file, (char *) buffer, 4); - return (git_uint32) read32 (buffer); -} - -static int sort_heap_summary(const void *p1, const void *p2) -{ - glui32 v1 = *((const glui32 *)p1); - glui32 v2 = *((const glui32 *)p2); - - if (v1 < v2) - return -1; - if (v1 > v2) - return 1; - return 0; -} - -git_sint32 restoreFromFile (git_sint32 * base, git_sint32 id, - git_uint32 protectPos, git_uint32 protectSize) -{ - git_uint32 protectEnd = protectPos + protectSize; - git_uint32 i; - strid_t file; - glui32 fileSize, fileStart; - - int gotIdent = 0; - int gotMemory = 0; - int gotStack = 0; - int gotHeap = 0; - - // Find out what stream they want to use, and make sure it's valid. - file = git_find_stream_by_id (id); - if (file == 0) - return 1; - - // Read IFF header. - if (readWord (file) != readtag("FORM")) - return 1; // Not an IFF file. - - fileSize = readWord (file); - fileStart = glk_stream_get_position (file); - - if (readWord (file) != readtag("IFZS")) - return 1; // Not a Quetzal file. - - // Discard the current heap. - heap_clear(); - - // Read all the chunks. - - while (glk_stream_get_position(file) < fileStart + fileSize) - { - git_uint32 chunkType, chunkSize; - chunkType = readWord (file); - chunkSize = readWord (file); - - if (chunkType == readtag("IFhd")) - { - if (gotIdent) - return 1; - - gotIdent = 1; - - if (chunkSize != 128) - return 1; - - for (i = 0 ; i < 128 ; ++i) - { - glui32 c = glk_get_char_stream (file); - if (gInitMem [i] != c) - return 1; - } - } - else if (chunkType == readtag("Stks")) - { - if (gotStack) - return 1; - - gotStack = 1; - - if (chunkSize & 3) - return 1; - - gStackPointer = base; - for ( ; chunkSize > 0 ; chunkSize -= 4) - *gStackPointer++ = readWord(file); - } - else if (chunkType == readtag("CMem")) - { - git_uint32 bytesRead = 0; - if (gotMemory) - return 1; - - gotMemory = 1; - - if (resizeMemory (readWord(file), 1)) - fatalError ("Can't resize memory map"); - - bytesRead = 4; - i = gRamStart; - while (i < gExtStart && bytesRead < chunkSize) - { - int mult = 0; - char c = (char) glk_get_char_stream(file); - ++bytesRead; - - if (c == 0) - { - mult = (unsigned char) glk_get_char_stream(file); - ++bytesRead; - } - - for (++mult ; mult > 0 ; --mult, ++i) - if (i >= protectEnd || i < protectPos) - gMem [i] = gInitMem [i] ^ c; - } - - while (i < gEndMem && bytesRead < chunkSize) - { - int mult = 0; - char c = (char) glk_get_char_stream(file); - ++bytesRead; - - if (c == 0) - { - mult = (unsigned char) glk_get_char_stream(file); - ++bytesRead; - } - - for (++mult ; mult > 0 ; --mult, ++i) - if (i >= protectEnd || i < protectPos) - gMem [i] = c; - } - - while (i < gExtStart) - if (i >= protectEnd || i < protectPos) - gMem [i] = gInitMem [i], ++i; - - while (i < gEndMem) - if (i >= protectEnd || i < protectPos) - gMem [i] = 0, ++i; - - if (bytesRead != chunkSize) - return 1; // Too much data! - - if (chunkSize & 1) - glk_get_char_stream (file); - } - else if (chunkType == readtag("MAll")) - { - glui32 heapSize = 0; - glui32 * heap = 0; - - if (gotHeap) - return 1; - - gotHeap = 1; - - if (chunkSize & 3) - return 1; - - if (chunkSize > 0) - { - heap = malloc (chunkSize); - heapSize = chunkSize / 4; - for (i = 0 ; i < heapSize ; ++i) - heap[i] = readWord(file); - - /* The summary might have come from any interpreter, so it could - be out of order. We'll sort it. */ - qsort(heap+2, (heapSize-2)/2, 8, &sort_heap_summary); - - if (heap_apply_summary (heapSize, heap)) - fatalError ("Couldn't apply heap summary"); - free (heap); - } - } - else - { - // Unknown chunk type -- just skip it. - glk_stream_set_position (file, (chunkSize + 1) & ~1, seekmode_Current); - } - } - - // Make sure we have all the chunks we need. - - if (!gotIdent) - fatalError ("No ident chunk in save file"); - - if (!gotStack) - fatalError ("No stack chunk in save file"); - - if (!gotMemory) - fatalError ("No memory chunk in save file"); - - // If we reach this point, we restored successfully. - - return 0; -} - -git_sint32 saveToFile (git_sint32 * base, git_sint32 * sp, git_sint32 id) -{ - git_uint32 n, zeroCount; - glui32 fileSize, fileSizePos; - glui32 memSize, memSizePos; - glui32 heapSize; - glui32* heap; - - strid_t file, oldFile; - - // Find out what stream they want to use, and make sure it's valid. - file = git_find_stream_by_id (id); - if (file == 0) - return 1; - - // Get the state of the heap. - if (heap_get_summary (&heapSize, &heap)) - fatalError ("Couldn't get heap summary"); - - // Make the given stream the default. - oldFile = glk_stream_get_current (); - glk_stream_set_current (file); - - // Write Quetzal header. - glk_put_string ("FORM"); - - fileSizePos = glk_stream_get_position (file); - writeWord (0); - - glk_put_string ("IFZS"); - - // Header chunk. - glk_put_string ("IFhd"); - writeWord (128); - glk_put_buffer ((char *) gInitMem, 128); - - // Stack chunk. - glk_put_string ("Stks"); - writeWord ((sp - base) * 4); - for (n = 0 ; n < (git_uint32) (sp - base) ; ++n) - writeWord (base [n]); - - // Heap chunk. - if (heap != 0) - { - glk_put_string ("MAll"); - writeWord (heapSize * 4); - for (n = 0 ; n < heapSize ; ++n) - writeWord (heap [n]); - free(heap); - } - - // Memory chunk. - glk_put_string ("CMem"); - memSizePos = glk_stream_get_position (file); - writeWord (0); - - writeWord (gEndMem); - for (zeroCount = 0, n = gRamStart ; n < gEndMem ; ++n) - { - unsigned char romC = (n < gExtStart) ? gInitMem[n] : 0; - unsigned char c = ((git_uint32) romC) ^ ((git_uint32) gMem[n]); - if (c == 0) - ++zeroCount; - else - { - for ( ; zeroCount > 256 ; zeroCount -= 256) - { - glk_put_char (0); - glk_put_char (0xff); - } - - if (zeroCount > 0) - { - glk_put_char (0); - glk_put_char ((char) (zeroCount - 1)); - zeroCount = 0; - } - - glk_put_char (c); - } - } - // Note: we don't bother writing out any remaining zeroes, - // because the memory is padded out with zeroes on restore. - - memSize = glk_stream_get_position (file) - memSizePos - 4; - if (memSize & 1) - glk_put_char (0); - - // Back up and fill in the lengths. - fileSize = glk_stream_get_position (file) - fileSizePos - 4; - - glk_stream_set_position (file, fileSizePos, seekmode_Start); - writeWord (fileSize); - - glk_stream_set_position (file, memSizePos, seekmode_Start); - writeWord (memSize); - - // Restore the previous default stream. - glk_stream_set_current (oldFile); - - // And we're done. - return 0; -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/saveundo.c b/textworld/thirdparty/glulx/Git-Glulx/saveundo.c deleted file mode 100644 index 7ed73930..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/saveundo.c +++ /dev/null @@ -1,350 +0,0 @@ -// $Id: saveundo.c,v 1.15 2003/10/20 16:05:06 iain Exp $ - -#include "git.h" -#include -#include -#include - -typedef const git_uint8 * MemoryPage; -typedef MemoryPage * MemoryMap; - -typedef struct UndoRecord UndoRecord; - -struct UndoRecord -{ - git_uint32 endMem; - MemoryMap memoryMap; - git_sint32 stackSize; - git_sint32 * stack; - glui32 heapSize; - glui32 * heap; - UndoRecord * prev; - UndoRecord * next; -}; - -static UndoRecord * gUndo = NULL; -static git_uint32 gUndoSize = 0; -static git_uint32 gMaxUndoSize = 256 * 1024; - -static void reserveSpace (git_uint32); -static void deleteRecord (UndoRecord * u); - -void initUndo (git_uint32 size) -{ - gMaxUndoSize = size; - gUndoSize = 0; - gUndo = NULL; -} - -int saveUndo (git_sint32 * base, git_sint32 * sp) -{ - git_uint32 undoSize = sizeof(UndoRecord); - git_uint32 mapSize = sizeof(MemoryPage*) * (gEndMem - gRamStart) / 256; - git_uint32 stackSize = sizeof(git_sint32) * (sp - base); - git_uint32 totalSize = undoSize + mapSize + stackSize; - - git_uint32 addr = gRamStart; // Address in glulx memory. - git_uint32 slot = 0; // Slot in our memory map. - - UndoRecord * undo = malloc (undoSize); - if (undo == NULL) - fatalError ("Couldn't allocate undo record"); - - undo->endMem = gEndMem; - undo->memoryMap = malloc (mapSize); - undo->stackSize = stackSize; - undo->stack = malloc (stackSize); - undo->prev = NULL; - undo->next = NULL; - - if (undo->memoryMap == NULL || undo->stack == NULL) - fatalError ("Couldn't allocate memory for undo"); - - // Save the stack. - memcpy (undo->stack, base, undo->stackSize); - - // Are we diffing against the previous undo record, - // or against the initial gamefile state? - if (gUndo == NULL) - { - // We're diffing against the gamefile. - for ( ; addr < gExtStart ; addr += 256, ++slot) - { - if (memcmp (gInitMem + addr, gMem + addr, 256) != 0) - { - // We need to save this page. - git_uint8 * page = malloc(256); - if (page == NULL) - fatalError ("Couldn't allocate memory for undo"); - - memcpy (page, gMem + addr, 256); - undo->memoryMap[slot] = page; - totalSize += 256; - } - else - { - // We don't need to save this page. - // Just make it point into ROM. - undo->memoryMap[slot] = gInitMem + addr; - } - } - - // If the memory map has been extended, save the exended area - for (addr = gExtStart ; addr < gEndMem ; addr += 256, ++slot) - { - git_uint8 * page = malloc(256); - if (page == NULL) - fatalError ("Couldn't allocate memory for undo"); - - memcpy (page, gMem + addr, 256); - undo->memoryMap[slot] = page; - totalSize += 256; - } - } - else - { - // We're diffing against the most recent undo record. - git_uint32 endMem = (gUndo->endMem < gEndMem) ? gUndo->endMem : gEndMem; - for ( ; addr < endMem ; addr += 256, ++slot) - { - if (memcmp (gUndo->memoryMap [slot], gMem + addr, 256) != 0) - { - // We need to save this page. - git_uint8 * page = malloc(256); - memcpy (page, gMem + addr, 256); - undo->memoryMap[slot] = page; - totalSize += 256; - } - else - { - // We don't need to save this page. Just copy - // the pointer from the previous undo record. - undo->memoryMap[slot] = gUndo->memoryMap[slot]; - } - } - - // If the memory map has been extended, save the exended area - for (addr = endMem ; addr < gEndMem ; addr += 256, ++slot) - { - git_uint8 * page = malloc(256); - if (page == NULL) - fatalError ("Couldn't allocate memory for undo"); - - memcpy (page, gMem + addr, 256); - undo->memoryMap[slot] = page; - totalSize += 256; - } - } - - // Save the heap. - if (heap_get_summary (&(undo->heapSize), &(undo->heap))) - fatalError ("Couldn't get heap summary"); - totalSize += undo->heapSize * 4; - - // Link this record into the undo list. - - undo->prev = gUndo; - if (gUndo) - gUndo->next = undo; - - gUndo = undo; - gUndoSize += totalSize; - - // Delete old records until we have enough free space. - reserveSpace (0); - - // And we're done. - return 0; -} - -int restoreUndo (git_sint32* base, git_uint32 protectPos, git_uint32 protectSize) -{ - if (gUndo == NULL) - { - // Nothing to undo! - return 1; - } - else - { - UndoRecord * undo = gUndo; - - git_uint32 addr = gRamStart; // Address in glulx memory. - MemoryMap map = undo->memoryMap; // Glulx memory map. - - // Restore the size of the memory map - heap_clear (); - resizeMemory (undo->endMem, 1); - - // Restore the stack. - memcpy (base, undo->stack, undo->stackSize); - gStackPointer = base + (undo->stackSize / sizeof(git_sint32)); - - // Restore the contents of RAM. - - if (protectSize > 0 && protectPos < gEndMem) - { - for ( ; addr < (protectPos & ~0xff) ; addr += 256, ++map) - memcpy (gMem + addr, *map, 256); - - memcpy (gMem + addr, *map, protectPos & 0xff); - protectSize += protectPos & 0xff; - - while (protectSize > 256) - addr += 256, ++map, protectSize -= 256; - - if (addr < gEndMem) - { - memcpy (gMem + addr + protectSize, - *map + protectSize, - 256 - protectSize); - } - addr += 256, ++map; - } - - for ( ; addr < gEndMem ; addr += 256, ++map) - memcpy (gMem + addr, *map, 256); - - // Restore the heap. - if (heap_apply_summary (undo->heapSize, undo->heap)) - fatalError ("Couldn't apply heap summary"); - - // Delete the undo record. - - gUndo = undo->prev; - deleteRecord (undo); - - if (gUndo) - gUndo->next = NULL; - else - assert (gUndoSize == 0); - - // And we're done. - return 0; - } -} - -void resetUndo () -{ - reserveSpace (gMaxUndoSize); - assert (gUndo == NULL); - assert (gUndoSize == 0); -} - -void shutdownUndo () -{ - resetUndo(); -} - -static void reserveSpace (git_uint32 n) -{ - UndoRecord * u = gUndo; - if (u == NULL) - return; - - // Find the oldest undo record. - - while (u->prev) - u = u->prev; - - // Delete records until we've freed up the required amount of space. - - while (gUndoSize + n > gMaxUndoSize) - { - if (u->next) - { - assert (u->next->prev == u); - u = u->next; - - deleteRecord (u->prev); - u->prev = NULL; - } - else - { - assert (u == gUndo); - if (n > 0) - { - gUndo = NULL; - - deleteRecord (u); - assert (gUndoSize == 0); - } - break; - } - } -} - -static void deleteRecord (UndoRecord * u) -{ - git_uint32 addr = gRamStart; // Address in glulx memory. - git_uint32 slot = 0; // Slot in our memory map. - - // Zero out all the slots which are duplicates - // of pages held in older undo records. - - if (u->prev) - { - // We're diffing against the previous undo record. - while (addr < u->endMem && addr < u->prev->endMem) - { - if (u->memoryMap [slot] == u->prev->memoryMap [slot]) - u->memoryMap [slot] = NULL; - addr += 256, ++slot; - } - } - else - { - // We're diffing against the gamefile. - while (addr < u->endMem && addr < gExtStart) - { - if (u->memoryMap [slot] == (gInitMem + addr)) - u->memoryMap [slot] = NULL; - addr += 256, ++slot; - } - } - - // Zero out all the slots which are duplicates - // of newer undo records. - - if (u->next) - { - addr = gRamStart; - slot = 0; - - while (addr < u->endMem && addr < u->next->endMem) - { - if (u->memoryMap [slot] == u->next->memoryMap [slot]) - u->memoryMap [slot] = NULL; - addr += 256, ++slot; - } - } - - // Free all the slots which are owned by this record only. - - addr = gRamStart; - slot = 0; - while (addr < u->endMem) - { - if (u->memoryMap [slot]) - { - free ((void*) u->memoryMap [slot]); - gUndoSize -= 256; - } - addr += 256, ++slot; - } - - // Free the memory map itself. - free ((void*) u->memoryMap); - gUndoSize -= sizeof(MemoryPage*) * (u->endMem - gRamStart) / 256; - - // Free the stack. - free (u->stack); - gUndoSize -= u->stackSize; - - // Free the heap. - free (u->heap); - gUndoSize -= u->heapSize * 4; - - // Finally, free the record. - free (u); - gUndoSize -= sizeof(UndoRecord); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/search.c b/textworld/thirdparty/glulx/Git-Glulx/search.c deleted file mode 100644 index b50ac68a..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/search.c +++ /dev/null @@ -1,366 +0,0 @@ -// $Id: search.c,v 1.1 2003/10/18 20:06:41 iain Exp $ - -// search.c: Glulxe code for built-in search opcodes -// Designed by Andrew Plotkin -// http://www.eblong.com/zarf/glulx/index.html - -#include "glk.h" -#include "git.h" -#include "opcodes.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define serop_KeyIndirect (0x01) -#define serop_ZeroKeyTerminates (0x02) -#define serop_ReturnIndex (0x04) -/* ### KeyZeroBounded? variants? */ -/* ### LowerBoundKey? */ - -/* In general, these search functions look through a bunch of structures - in memory, searching for one whose key (a fixed-size sequence of bytes - within the structure) matches a given key. The result can indicate a - particular structure within the bunch, or it can be NULL ("not found".) - - Any or all of these options can be applied: - - KeyIndirect: If this is true, the key argument is taken to be the - start of an array of bytes in memory (whose length is keysize). - If it is false, the key argument contains the key itself. In - this case, keysize *must* be 1, 2, or 4. The key is stored in the - lower bytes of the key argument, big-endian. (The upper bytes are - ignored.) - - ZeroKeyTerminates: If this is true, when the search reaches a struct - whose key is all zeroes, the search terminates (and returns NULL). - If the searched-for key happens to also be zeroes, the key-match - (returning the struct) takes precedence over the zero-match (returning - NULL.) - - ReturnIndex: If this is false, the return value is the memory address - of the matching struct, or 0 to indicate NULL. If true, the return value - is the array index of the matching struct, or -1 to indicate NULL. -*/ - -static void fetchkey(unsigned char *keybuf, glui32 key, glui32 keysize, - glui32 options); - -/* linear_search(): - An array of data structures is stored in memory, beginning at start, - each structure being structsize bytes. Within each struct, there is - a key value keysize bytes long, starting at position keyoffset (from - the start of the structure.) Search through these in order. If one - is found whose key matches, return it. If numstructs are searched - with no result, return NULL. - - numstructs may be -1 (0xFFFFFFFF) to indicate no upper limit to the - number of structures to search. The search will continue until a match - is found, or (if ZeroKeyTerminates is set) a zero key. - - The KeyIndirect, ZeroKeyTerminates, and ReturnIndex options may be - used. -*/ -glui32 git_linear_search(glui32 key, glui32 keysize, - glui32 start, glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options) -{ - unsigned char keybuf[4]; - glui32 count; - int ix; - int retindex = ((options & serop_ReturnIndex) != 0); - int zeroterm = ((options & serop_ZeroKeyTerminates) != 0); - - fetchkey(keybuf, key, keysize, options); - - for (count=0; count byte2) - cmp = 1; - } - } - else { - for (ix=0; (!cmp) && ix byte2) - cmp = 1; - } - } - - if (!cmp) { - if (retindex) - return val; - else - return addr; - } - - if (cmp < 0) { - bot = val+1; - } - else { - top = val; - } - } - - if (retindex) - return -1; - else - return 0; -} - -static glui32 binary_search_16bit(git_uint16 key, glui32 start, - glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options) -{ - glui32 addr, top, bot, val; - git_uint16 m; - int retindex = ((options & serop_ReturnIndex) != 0); - - bot = 0; - top = numstructs; - while (bot < top) { - val = (top+bot) / 2; - addr = start + val * structsize; - - m = memRead16(addr + keyoffset); - if (m == key) { - if (retindex) - return val; - else - return addr; - } else if (m < key) { - bot = val + 1; - } else { - top = val; - } - } - - if (retindex) - return -1; - else - return 0; -} - -static glui32 binary_search_32bit(git_uint32 key, glui32 start, - glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options) -{ - glui32 addr, top, bot, val, m; - int retindex = ((options & serop_ReturnIndex) != 0); - - bot = 0; - top = numstructs; - while (bot < top) { - val = (top+bot) / 2; - addr = start + val * structsize; - - m = memRead32(addr + keyoffset); - if (m == key) { - if (retindex) - return val; - else - return addr; - } else if (m < key) { - bot = val + 1; - } else { - top = val; - } - } - - if (retindex) - return -1; - else - return 0; -} - -glui32 git_binary_search(glui32 key, glui32 keysize, - glui32 start, glui32 structsize, glui32 numstructs, - glui32 keyoffset, glui32 options) -{ - if (keysize == 2) { - git_uint16 key16; - if ((options & serop_KeyIndirect) != 0) { - key16 = memRead16(key); - } else { - key16 = key; - } - return binary_search_16bit(key16, start, structsize, numstructs, keyoffset, options); - } - if (keysize == 4) { - git_uint32 key32; - if ((options & serop_KeyIndirect) != 0) { - key32 = memRead32(key); - } else { - key32 = key; - } - return binary_search_32bit(key32, start, structsize, numstructs, keyoffset, options); - } - return binary_search_generic(key, keysize, start, structsize, numstructs, keyoffset, options); -} - -/* linked_search(): - The structures may be anywhere in memory, in any order. They are - linked by a four-byte address field, which is found in each struct - at position nextoffset. If this field contains zero, it indicates - the end of the linked list. - - The KeyIndirect and ZeroKeyTerminates options may be used. -*/ -glui32 git_linked_search(glui32 key, glui32 keysize, - glui32 start, glui32 keyoffset, glui32 nextoffset, glui32 options) -{ - unsigned char keybuf[4]; - int ix; - glui32 val; - int zeroterm = ((options & serop_ZeroKeyTerminates) != 0); - - fetchkey(keybuf, key, keysize, options); - - while (start != 0) { - int match = TRUE; - if (keysize <= 4) { - for (ix=0; match && ix -#include -#include -#include -#include -#include - -// ------------------------------------------------------------- -// Global variables - -git_sint32* gStackPointer; - -#ifdef USE_DIRECT_THREADING -Opcode* gOpcodeTable; -#endif - -// ------------------------------------------------------------- -// Useful macros for manipulating the stack - -#define LOCAL(n) (locals[(n)]) - -#define PUSH(n) *sp++ = (n) -#define POP (*--sp) -#define READ_PC ((git_uint32)(*pc++)) - -#define CHECK_FREE(n) if ((top - sp) < (n)) goto stack_overflow -#define CHECK_USED(n) if ((sp - values) < (n)) goto stack_underflow - -// ------------------------------------------------------------- -// Floating point support - -GIT_INLINE git_uint32 ENCODE_FLOAT(git_float f) -{ - git_uint32 n; - memcpy(&n, &f, 4); - return n; -} - -GIT_INLINE git_float DECODE_FLOAT(git_uint32 n) { - git_float f; - memcpy(&f, &n, 4); - return f; -} - -int floatCompare(git_sint32 L1, git_sint32 L2, git_sint32 L3) -{ - git_float F1, F2; - - if (((L3 & 0x7F800000) == 0x7F800000) && ((L3 & 0x007FFFFF) != 0)) - return 0; - if ((L1 == 0x7F800000 || L1 == 0xFF800000) && (L2 == 0x7F800000 || L2 == 0xFF800000)) - return (L1 == L2); - - F1 = DECODE_FLOAT(L2) - DECODE_FLOAT(L1); - F2 = fabs(DECODE_FLOAT(L3)); - return ((F1 <= F2) && (F1 >= -F2)); -} - -#ifdef USE_OWN_POWF -float git_powf(float x, float y); -#endif - -// ------------------------------------------------------------- -// Functions - -void startProgram (size_t cacheSize, enum IOMode ioMode) -{ - Block pc; // Program counter (pointer into dynamically generated code) - - git_sint32 L1=0, L2=0, L3=0, L4=0, L5=0, L6=0, L7=0; -#define S1 L1 -#define S2 L2 - git_float F1=0.0f, F2=0.0f, F3=0.0f, F4=0.0f; - - git_sint32* base; // Bottom of the stack. - git_sint32* frame; // Bottom of the current stack frame. - git_sint32* locals; // Start of the locals section of the current frame. - git_sint32* values; // Start of the values section of the current frame. - git_sint32* sp; // Next free stack slot. - git_sint32* top; // The top of the stack -- that is, the first unusable slot. - - git_sint32 args [64]; // Array of arguments. Count is stored in L2. - - git_uint32 ioRock = 0; - - git_uint32 stringTable = memRead32(28); - git_uint32 startPos = memRead32(24); - git_uint32 stackSize = memRead32(20); - - git_uint32 protectPos = 0; - git_uint32 protectSize = 0; - - git_uint32 maybe_unused glulxPC = 0; - git_uint32 maybe_unused glulxOpcode = 0; - - acceleration_func accelfunc; - - // Initialise the code cache. - -#ifdef USE_DIRECT_THREADING - static Opcode opcodeTable [] = { -#define LABEL(label) &&do_ ## label, -#include "labels.inc" - NULL}; - gOpcodeTable = opcodeTable; -#endif - - initCompiler (cacheSize); - - // Initialise the random number generator. - srand (time(NULL)); - - // Set up the stack. - - base = malloc (stackSize); - if (base == NULL) - fatalError ("Couldn't allocate stack"); - - top = base + (stackSize / 4); - frame = locals = values = sp = base; - - // Call the first function. - - L1 = startPos; // Initial PC. - L2 = 0; // No arguments. - goto do_enter_function_L1; - -#ifdef USE_DIRECT_THREADING -#define NEXT do { goto **(pc++); } while(0) -#else -#define NEXT goto next -//#define NEXT do { CHECK_USED(0); CHECK_FREE(0); goto next; } while (0) -next: - switch (*pc++) - { -#define LABEL(foo) case label_ ## foo: goto do_ ## foo; -#include "labels.inc" - default: fatalError("exec: bad opcode"); - } -#endif - -do_debug_step: - // This opcode lets us keep track of how the compiled - // code relates to the original glulx code. - glulxPC = READ_PC; // Glulx program counter. - glulxOpcode = READ_PC; // Glulx opcode number. -// fprintf (stdout, "\nPC: 0x%08x\nOpcode: 0x%04x\n", glulxPC, glulxOpcode); -// fprintf (stdout, "Stack:"); -// for (L7 = 0 ; L7 < (sp - base) ; ++L7) -// fprintf (stdout," 0x%x", base[L7]); -// fprintf (stdout, "\n"); - NEXT; - -#define LOAD_INSTRUCTIONS(reg) \ - do_ ## reg ## _const: reg = READ_PC; NEXT; \ - do_ ## reg ## _stack: CHECK_USED(1); reg = POP; NEXT; \ - do_ ## reg ## _addr: reg = memRead32 (READ_PC); NEXT; \ - do_ ## reg ## _local: reg = LOCAL (READ_PC); NEXT - - LOAD_INSTRUCTIONS(L1); - LOAD_INSTRUCTIONS(L2); - LOAD_INSTRUCTIONS(L3); - LOAD_INSTRUCTIONS(L4); - LOAD_INSTRUCTIONS(L5); - LOAD_INSTRUCTIONS(L6); - LOAD_INSTRUCTIONS(L7); - -#define STORE_INSTRUCTIONS(reg) \ - do_ ## reg ## _stack: CHECK_FREE(1); PUSH(reg); NEXT; \ - do_ ## reg ## _addr: memWrite32 (READ_PC, reg); NEXT; \ - do_ ## reg ## _local: LOCAL (READ_PC) = reg; NEXT - - STORE_INSTRUCTIONS(S1); - STORE_INSTRUCTIONS(S2); - -#define DOUBLE_LOAD(mode2) \ - do_L1_const_L2_ ## mode2: L1 = READ_PC; goto do_L2_ ## mode2; \ - do_L1_stack_L2_ ## mode2: CHECK_USED(1); L1 = POP; goto do_L2_ ## mode2; \ - do_L1_local_L2_ ## mode2: L1 = LOCAL (READ_PC); goto do_L2_ ## mode2; \ - do_L1_addr_L2_ ## mode2: L1 = memRead32 (READ_PC); goto do_L2_ ## mode2 - - DOUBLE_LOAD(const); - DOUBLE_LOAD(stack); - DOUBLE_LOAD(local); - DOUBLE_LOAD(addr); - -#undef LOAD_INSTRUCTIONS -#undef STORE_INSTRUCTIONS -#undef DOUBLE_LOAD - -do_L1_addr16: L1 = memRead16 (READ_PC); NEXT; -do_L1_addr8: L1 = memRead8 (READ_PC); NEXT; -do_S1_addr16: memWrite16 (READ_PC, S1); NEXT; -do_S1_addr8: memWrite8 (READ_PC, S1); NEXT; - -#define UL7 ((git_uint32)L7) - -do_recompile: - pc = compile (READ_PC); - NEXT; - -do_jump_abs_L7: - pc = getCode (UL7); - NEXT; - -do_enter_function_L1: // Arg count is in L2. - - // Check for an accelerated function - accelfunc = accel_get_func(L1); - if (accelfunc) { - S1 = accelfunc(L2, (glui32 *) args); - goto do_pop_call_stub; - } - - frame = sp; - // Read the function type. - L7 = memRead8(L1++); - // Parse the local variables descriptor. - L6 = L5 = L4 = 0; - do - { - L6 = memRead8(L1++); // LocalType - L5 = memRead8(L1++); // LocalCount - if (L6 != 4 && L6 != 0) // We only support 4-byte locals. - { - if (L6 == 1 || L6 == 2) - fatalError("Short local variables are not supported, use Glulxe"); - else - fatalError("Local variable wasn't 4 bytes wide"); - } - L4 += L5; // Cumulative local count. - } - while (L5 != 0); - - // Write out the stack frame. - // Recall that the number of locals is stored in L4. - - CHECK_FREE(3 + L4); - - PUSH (L4*4 + 12); // FrameLen - PUSH (12); // LocalsPos - if (L4 == 0) - L6 = 0; - else - L6 = (4 << 24) | (L4 << 16); - PUSH (L6); // format of locals - - // This is where the local variables start, so: - locals = sp; - - // Read the arguments, based on the function type. - switch (L7) - { - case 0xC0: // arguments should be placed on the stack. - // argc is in L2; we'll randomly use L5 as scratch. - CHECK_FREE(L5 + 1); - // Initialise the local variables. - for ( ; L4 > 0 ; --L4) - PUSH (0); - // This is where the temporary values start, so: - values = sp; - // Push the args onto the stack. - for (L5 = 0 ; L5 < L2 ; ++L5) - PUSH (args [L5]); - // Push the arg count. - PUSH (L2); - break; - - case 0xC1: // arguments should be written into locals. - // argc is in L2, num locals is in L4. - // Stuff as many locals as possible with arguments. - for (L5 = 1 ; L5 <= L2 && L4 > 0 ; ++L5, --L4) - PUSH (args [L2 - L5]); - // Initialise any remaining locals. - for ( ; L4 > 0 ; --L4) - PUSH (0); - // This is where the temporary values start, so: - values = sp; - break; - - default: - // This isn't a function! - fatalError("Not a function"); - break; - } - - // Start executing the function. - L7 = L1; - goto do_jump_abs_L7; - - do_nop: NEXT; - -#define PEEPHOLE_STORE(tag, code) \ - do_ ## tag ## _discard: code; NEXT; \ - do_ ## tag ## _S1_stack: code; goto do_S1_stack; \ - do_ ## tag ## _S1_local: code; goto do_S1_local; \ - do_ ## tag ## _S1_addr: code; goto do_S1_addr - - PEEPHOLE_STORE(add, S1 = L1 + L2); - PEEPHOLE_STORE(sub, S1 = L1 - L2); - PEEPHOLE_STORE(mul, S1 = L1 * L2); - PEEPHOLE_STORE(div, if (L2 == 0) fatalError ("Divide by zero"); S1 = L1 / L2); - PEEPHOLE_STORE(mod, if (L2 == 0) fatalError ("Divide by zero"); S1 = L1 % L2); - - PEEPHOLE_STORE(neg, S1 = -L1); - PEEPHOLE_STORE(bitnot, S1 = ~L1); - - PEEPHOLE_STORE(bitand, S1 = L1 & L2); - PEEPHOLE_STORE(bitor, S1 = L1 | L2); - PEEPHOLE_STORE(bitxor, S1 = L1 ^ L2); - - PEEPHOLE_STORE(shiftl, if (L2 > 31 || L2 < 0) S1 = 0; else S1 = L1 << ((git_uint32) L2)); - PEEPHOLE_STORE(sshiftr, if (L2 > 31 || L2 < 0) L2 = 31; S1 = ((git_sint32) L1) >> ((git_uint32) L2)); - PEEPHOLE_STORE(ushiftr, if (L2 > 31 || L2 < 0) S1 = 0; else S1 = ((git_uint32) L1) >> ((git_uint32) L2)); - - PEEPHOLE_STORE(aload, S1 = memRead32 (L1 + (L2<<2))); - PEEPHOLE_STORE(aloads, S1 = memRead16 (L1 + (L2<<1))); - PEEPHOLE_STORE(aloadb, S1 = memRead8 (L1 + L2)); - PEEPHOLE_STORE(aloadbit,S1 = (memRead8 (L1 + (L2>>3)) >> (L2 & 7)) & 1); - - PEEPHOLE_STORE(copys, S1 = L1 & 0xFFFF); - PEEPHOLE_STORE(copyb, S1 = L1 & 0x00FF); - PEEPHOLE_STORE(sexs, S1 = (git_sint32)((signed short)(L1 & 0xFFFF))); - PEEPHOLE_STORE(sexb, S1 = (git_sint32)((signed char)(L1 & 0x00FF))); - - PEEPHOLE_STORE(fadd, F1 = DECODE_FLOAT(L1) + DECODE_FLOAT(L2); S1 = ENCODE_FLOAT(F1)); - PEEPHOLE_STORE(fsub, F1 = DECODE_FLOAT(L1) - DECODE_FLOAT(L2); S1 = ENCODE_FLOAT(F1)); - PEEPHOLE_STORE(fmul, F1 = DECODE_FLOAT(L1) * DECODE_FLOAT(L2); S1 = ENCODE_FLOAT(F1)); - PEEPHOLE_STORE(fdiv, F1 = DECODE_FLOAT(L1) / DECODE_FLOAT(L2); S1 = ENCODE_FLOAT(F1)); - -#define PEEPHOLE_LOAD(tag,reg) \ - do_ ## tag ## _ ## reg ## _const: reg = READ_PC; goto do_ ## tag; \ - do_ ## tag ## _ ## reg ## _stack: CHECK_USED(1); reg = POP; goto do_ ## tag; \ - do_ ## tag ## _ ## reg ## _local: reg = LOCAL(READ_PC); goto do_ ## tag; \ - do_ ## tag ## _ ## reg ## _addr: reg = memRead32(READ_PC); goto do_ ## tag - - PEEPHOLE_LOAD (return, L1); - PEEPHOLE_LOAD (astore, L3); - PEEPHOLE_LOAD (astores, L3); - PEEPHOLE_LOAD (astoreb, L3); - PEEPHOLE_LOAD (astorebit, L3); - -#undef PEEPHOLE_STORE - - do_astore: memWrite32 (L1 + (L2<<2), L3); NEXT; - do_astores: memWrite16 (L1 + (L2<<1), L3); NEXT; - do_astoreb: memWrite8 (L1 + L2, L3); NEXT; - do_astorebit: - L4 = memRead8(L1 + (L2>>3)); - if (L3 == 0) - L4 &= ~(1 << (L2 & 7)); - else - L4 |= (1 << (L2 & 7)); - memWrite8(L1 + (L2>>3), L4); - NEXT; - -#define DO_JUMP(tag, reg, cond) \ - do_ ## tag ## _var: L7 = READ_PC; if (cond) goto do_goto_ ## reg ## _from_L7; NEXT; \ - do_ ## tag ## _const: L7 = READ_PC; if (cond) goto do_jump_abs_L7; NEXT; \ - do_ ## tag ## _by: L7 = READ_PC; if (cond) pc += L7; NEXT; \ - do_ ## tag ## _return0: if (cond) { L1 = 0; goto do_return; } NEXT; \ - do_ ## tag ## _return1: if (cond) { L1 = 1; goto do_return; } NEXT - - DO_JUMP(jump, L1, 1 == 1); - DO_JUMP(jz, L2, L1 == 0); - DO_JUMP(jnz, L2, L1 != 0); - DO_JUMP(jeq, L3, L1 == L2); - DO_JUMP(jne, L3, L1 != L2); - DO_JUMP(jlt, L3, L1 < L2); - DO_JUMP(jge, L3, L1 >= L2); - DO_JUMP(jgt, L3, L1 > L2); - DO_JUMP(jle, L3, L1 <= L2); - DO_JUMP(jltu, L3, ((git_uint32)L1 < (git_uint32)L2)); - DO_JUMP(jgeu, L3, ((git_uint32)L1 >= (git_uint32)L2)); - DO_JUMP(jgtu, L3, ((git_uint32)L1 > (git_uint32)L2)); - DO_JUMP(jleu, L3, ((git_uint32)L1 <= (git_uint32)L2)); - DO_JUMP(jisnan, L2, (((L1 & 0x7F800000) == 0x7F800000) && ((L1 & 0x007FFFFF) != 0))); - DO_JUMP(jisinf, L2, ((L1 == 0x7F800000) || (L1 == 0xFF800000))); - DO_JUMP(jflt, L3, DECODE_FLOAT(L1) < DECODE_FLOAT(L2)); - DO_JUMP(jfge, L3, DECODE_FLOAT(L1) >= DECODE_FLOAT(L2)); - DO_JUMP(jfgt, L3, DECODE_FLOAT(L1) > DECODE_FLOAT(L2)); - DO_JUMP(jfle, L3, DECODE_FLOAT(L1) <= DECODE_FLOAT(L2)); - DO_JUMP(jfeq, L4, floatCompare(L1, L2, L3) != 0); - DO_JUMP(jfne, L4, floatCompare(L1, L2, L3) == 0); - -#undef DO_JUMP - - do_jumpabs: L7 = L1; goto do_jump_abs_L7; NEXT; - - do_goto_L4_from_L7: L1 = L4; goto do_goto_L1_from_L7; - do_goto_L3_from_L7: L1 = L3; goto do_goto_L1_from_L7; - do_goto_L2_from_L7: L1 = L2; goto do_goto_L1_from_L7; - do_goto_L1_from_L7: - if (L1 == 0 || L1 == 1) goto do_return; - L7 = L7 + L1 - 2; goto do_jump_abs_L7; - - do_args_stack: - // The first argument is topmost in the stack; the count is in L2. - CHECK_USED(L2); - // We want to store the arguments in 'args' in the same order. - for (L3 = L2 - 1 ; L3 >= 0 ; --L3) - args [L3] = POP; - NEXT; - - // Specialised versions of above: - do_args_stack_call_stub_discard: - CHECK_USED(L2); - for (L3 = L2 - 1 ; L3 >= 0 ; --L3) - args [L3] = POP; - goto do_call_stub_discard; - - do_args_stack_call_stub_addr: - CHECK_USED(L2); - for (L3 = L2 - 1 ; L3 >= 0 ; --L3) - args [L3] = POP; - goto do_call_stub_addr; - - do_args_stack_call_stub_local: - CHECK_USED(L2); - for (L3 = L2 - 1 ; L3 >= 0 ; --L3) - args [L3] = POP; - goto do_call_stub_local; - - do_args_stack_call_stub_stack: - CHECK_USED(L2); - for (L3 = L2 - 1 ; L3 >= 0 ; --L3) - args [L3] = POP; - goto do_call_stub_stack; - - do_args_3: - args [0] = L4; - args [1] = L3; - args [2] = L2; - L2 = 3; - NEXT; - - do_args_2: - args [0] = L3; - args [1] = L2; - L2 = 2; - NEXT; - - do_args_1: - args [0] = L2; - L2 = 1; - NEXT; - - do_args_0: - L2 = 0; - NEXT; - - do_undo_stub_discard: - CHECK_FREE(4); - PUSH (0); // DestType - PUSH (0); // DestAddr - goto finish_undo_stub; - - do_undo_stub_addr: - CHECK_FREE(4); - PUSH (1); // DestType - PUSH (READ_PC); // DestAddr - goto finish_undo_stub; - - do_undo_stub_local: - CHECK_FREE(4); - PUSH (2); // DestType - PUSH (READ_PC); // DestAddr - goto finish_undo_stub; - - do_undo_stub_stack: - CHECK_FREE(4); - PUSH (3); // DestType - PUSH (0); // DestAddr - goto finish_undo_stub; - -finish_undo_stub: - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - saveUndo (base, sp); - S1 = 0; - goto do_pop_call_stub; - - do_restoreundo: - if (restoreUndo (base, protectPos, protectSize) == 0) - { - sp = gStackPointer; - S1 = -1; - goto do_pop_call_stub; - } - S1 = 1; - NEXT; - - do_save_stub_discard: - CHECK_FREE(4); - PUSH (0); // DestType - PUSH (0); // DestAddr - goto finish_save_stub; - - do_save_stub_addr: - CHECK_FREE(4); - PUSH (1); // DestType - PUSH (READ_PC); // DestAddr - goto finish_save_stub; - - do_save_stub_local: - CHECK_FREE(4); - PUSH (2); // DestType - PUSH (READ_PC); // DestAddr - goto finish_save_stub; - - do_save_stub_stack: - CHECK_FREE(4); - PUSH (3); // DestType - PUSH (0); // DestAddr - goto finish_save_stub; - -finish_save_stub: - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - if (ioMode == IO_GLK) - S1 = saveToFile (base, sp, L1); - else - S1 = 1; - goto do_pop_call_stub; - - do_restore: - if (ioMode == IO_GLK - && restoreFromFile (base, L1, protectPos, protectSize) == 0) - { - sp = gStackPointer; - S1 = -1; - goto do_pop_call_stub; - } - S1 = 1; - NEXT; - - do_catch_stub_discard: - CHECK_FREE(4); - L7 = 0; - PUSH (0); // DestType - goto finish_catch_stub_addr_L7; - - do_catch_stub_addr: - CHECK_FREE(4); - L7 = READ_PC; - memWrite32(L7, (sp-base+4)*4); - PUSH (1); // DestType - goto finish_catch_stub_addr_L7; - - do_catch_stub_local: - CHECK_FREE(4); - L7 = READ_PC; - LOCAL(L7 / 4) = (sp-base+4)*4; - PUSH (2); // DestType - goto finish_catch_stub_addr_L7; - - do_catch_stub_stack: - CHECK_FREE(5); - PUSH (3); // DestType - PUSH (0); // DestAddr - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - L7 = (sp - base)*4; // Catch token. - PUSH (L7); - NEXT; - -finish_catch_stub_addr_L7: - PUSH (L7); // DestAddr - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - NEXT; - - do_throw: - if (L2 < 16 || L2 > ((sp-base)*4)) - fatalError ("Invalid catch token in throw"); - sp = base + L2 / 4; - goto do_pop_call_stub; - -do_call_stub_discard: - CHECK_FREE(4); - PUSH (0); // DestType - PUSH (0); // DestAddr - goto finish_call_stub; - - do_call_stub_addr: - CHECK_FREE(4); - PUSH (1); // DestType - PUSH (READ_PC); // DestAddr - goto finish_call_stub; - - do_call_stub_local: - CHECK_FREE(4); - PUSH (2); // DestType - PUSH (READ_PC); // DestAddr - goto finish_call_stub; - - do_call_stub_stack: - CHECK_FREE(4); - PUSH (3); // DestType - PUSH (0); // DestAddr - goto finish_call_stub; - -finish_call_stub: - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - goto do_enter_function_L1; - -do_tailcall: - // Zap the current stack frame, down to its call stub. - sp = frame; - // Call the function! - goto do_enter_function_L1; - - do_return: - sp = frame; - // ... - // fall through - // ... - do_pop_call_stub:// L1 holds the return value. - if (sp - base < 4) - { - if (sp == base) - // We just exited the top-level function. - goto finished; - else - // Something nasty happened. - goto stack_underflow; - } - L2 = POP; // FramePtr - L7 = POP; // PC - L6 = POP; // DestAddr - switch (POP) // DestType - { - case 0: // Do not store. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - break; - - case 1: // Store in main memory. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - memWrite32 (L6, L1); - break; - - case 2: // Store in local variable. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - LOCAL(L6/4) = L1; - break; - - case 3: // Push on stack. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - PUSH (L1); - break; - - case 10: // Resume printing a compressed (E1) string. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - goto resume_compressed_string_L7_bit_L6; - - case 11: // Resume executing function code after a string completes. - // Don't restore the frame pointer. - break; - - case 12: // Resume printing a signed decimal integer. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - goto resume_number_L7_digit_L6; - - case 13: // Resume printing a C-style (E0) string. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - goto resume_c_string_L7; - - case 14: // Resume printing a Unicode (E2) string. - frame = base + L2 / 4; - locals = frame + frame[1]/4; - values = frame + frame[0]/4; - goto resume_uni_string_L7; - - default: - fatalError("Bad call stub"); - } - // Restore the PC. - goto do_jump_abs_L7; - - do_stkcount: - S1 = sp - values; NEXT; - - do_stkpeek: - if (L1 < 0 || L1 > (sp - values)) - fatalError("Out of bounds in stkpeek"); - S1 = sp[-1 - L1]; NEXT; - - do_stkswap: - CHECK_USED(2); - L1 = POP; L2 = POP; PUSH(L1); PUSH(L2); NEXT; - - do_stkcopy: - CHECK_USED(L1); - for (L2 = L1 ; L2 > 0 ; --L2) - { - L3 = sp[-L1]; - PUSH (L3); - } - NEXT; - - resume_number_L7_digit_L6: - { - char buffer [16]; - git_uint32 absn; - - // If the IO mode is 'null', do nothing. - if (ioMode == IO_NULL) - goto do_pop_call_stub; - - // Write the number into the buffer. - absn = (L7 < 0) ? -L7 : L7; // Absolute value of number. - L2 = 0; // Current buffer position. - do - { - buffer [L2++] = '0' + (absn % 10); - absn /= 10; - } - while (absn > 0); - - if (L7 < 0) - buffer [L2++] = '-'; - - if (L6 >= L2) - goto do_pop_call_stub; // We printed the whole number already. - - // If we're in filter mode, push a call stub - // and filter the next character. - if (ioMode == IO_FILTER) - { - // Store the next character in the args array. - args[0] = buffer [L2 - L6 - 1]; - ++L6; - - // Push a call stub to print the next character. - CHECK_FREE(4); - PUSH(12); // DestType - PUSH(L6); // DestAddr (next digit) - PUSH(L7); // PC (number to print) - PUSH ((frame - base) * 4); // FramePtr - - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - else - { - // We're in Glk mode. Just print all the characters. - for ( ; L6 < L2 ; ++L6) - glk_put_char (buffer [L2 - L6 - 1]); - } - } - goto do_pop_call_stub; - - resume_c_string_L7: - // If the IO mode is 'null', or if we've reached the - // end of the string, do nothing. - L2 = memRead8(L7++); - if (L2 == 0 || ioMode == IO_NULL) - goto do_pop_call_stub; - // Otherwise we're going to have to print something, - // If the IO mode is 'filter', filter the next char. - if (ioMode == IO_FILTER) - { - // Store this character in the args array. - args [0] = L2; - // Push a call stub. - CHECK_FREE(4); - PUSH(13); // DestType (resume C string) - PUSH(L6); // DestAddr (ignored) - PUSH(L7); // PC (next char to print) - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - // We're in Glk mode. Just print all the characters. - while (L2 != 0) - { - glk_put_char ((unsigned char) L2); - L2 = memRead8(L7++); - } - goto do_pop_call_stub; - - resume_uni_string_L7: - // If the IO mode is 'null', or if we've reached the - // end of the string, do nothing. - L2 = memRead32(L7); - L7 += 4; - if (L2 == 0 || ioMode == IO_NULL) - goto do_pop_call_stub; - // Otherwise we're going to have to print something, - // If the IO mode is 'filter', filter the next char. - if (ioMode == IO_FILTER) - { - // Store this character in the args array. - args [0] = L2; - // Push a call stub. - CHECK_FREE(4); - PUSH(14); // DestType (resume Unicode string) - PUSH(L6); // DestAddr (ignored) - PUSH(L7); // PC (next char to print) - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - // We're in Glk mode. Just print all the characters. - while (L2 != 0) - { -#ifdef GLK_MODULE_UNICODE - glk_put_char_uni ((glui32) L2); -#else - unsigned char c = (L2 > 0 && L2 < 256) ? L2 : '?'; - glk_put_char (c); -#endif // GLK_MODULE_UNICODE - L2 = memRead32(L7); - L7 += 4; - } - goto do_pop_call_stub; - - resume_compressed_string_L7_bit_L6: - // Load the first string table node into L1. - // Its address is stored at stringTable + 8. - L1 = memRead32 (stringTable + 8); - // Load the node's type byte. - L2 = memRead8 (L1++); - // Is the root node a branch? - if (L2 == 0) - { - // We'll keep a reservoir of input bits in L5. - L5 = memRead8(L7); - // Keep following branch nodes until we hit a leaf node. - while (L2 == 0) - { - // Read the next bit. - L4 = (L5 >> L6) & 1; - // If we're finished reading this byte, - // move on to the next one. - if (++L6 > 7) - { - L6 -= 8; - L5 = memRead8(++L7); - } - // Follow the branch. - L1 = memRead32(L1 + 4 * L4); - L2 = memRead8 (L1++); - } - } - else if (L2 == 2 || L2 == 3) - { - // The root node prints a single character or a string. - // This will produce infinite output in the Null or Glk - // I/O modes, so we'll catch that here. - - if (ioMode != IO_FILTER) - fatalError ("String table prints infinite strings!"); - - // In Filter mode, the output will be sent to the current - // filter function, which can change the string table - // before returning, so we'll continue and see what happens. - } - // We're at a leaf node. - switch (L2) - { - case 1: // Terminator. - goto do_pop_call_stub; - - case 2: // Single char. - if (ioMode == IO_NULL) - { /* Do nothing */ } - else if (ioMode == IO_GLK) - glk_put_char ((unsigned char) memRead8(L1)); - else - { - // Store this character in the args array. - args [0] = memRead8(L1); - // Push a call stub. - CHECK_FREE(4); - PUSH(10); // DestType - PUSH(L6); // DestAddr (bit number in string) - PUSH(L7); // PC (byte address in string) - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - break; - - case 3: // C string. - // Push a 'resume compressed string' call stub. - CHECK_FREE(4); - PUSH (10); // DestType - PUSH (L6); // DestAddr (bit number in string) - PUSH (L7); // PC (byte address in string) - PUSH ((frame - base) * 4); // FramePtr - // Print the C string. - L7 = L1; - goto resume_c_string_L7; - - case 4: // Unicode char - if (ioMode == IO_NULL) - { /* Do nothing */ } - else if (ioMode == IO_GLK) - { -#ifdef GLK_MODULE_UNICODE - glk_put_char_uni (memRead32(L1)); -#else - git_uint32 c = memRead32(L1); - if (c > 255) c = '?'; - glk_put_char ((unsigned char) c); -#endif // GLK_MODULE_UNICODE - } - else - { - // Store this character in the args array. - args [0] = memRead32(L1); - // Push a call stub. - CHECK_FREE(4); - PUSH(10); // DestType - PUSH(L6); // DestAddr (bit number in string) - PUSH(L7); // PC (byte address in string) - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - break; - - case 5: // Unicode string. - // Push a 'resume compressed string' call stub. - CHECK_FREE(4); - PUSH (10); // DestType - PUSH (L6); // DestAddr (bit number in string) - PUSH (L7); // PC (byte address in string) - PUSH ((frame - base) * 4); // FramePtr - // Print the Unicode string. - L7 = L1; - goto resume_uni_string_L7; - - case 8: // Indirect reference. - L3 = memRead32(L1); - L2 = 0; goto indirect_L3_args_L2; - - case 9: // Double-indirect reference. - L3 = memRead32(L1); L3 = memRead32(L3); - L2 = 0; goto indirect_L3_args_L2; - - case 10: // Indirect reference with args. - L3 = memRead32(L1); - L2 = memRead32(L1 + 4); goto indirect_L3_args_L2; - - case 11: // Double-indirect reference with args. - L3 = memRead32(L1); L3 = memRead32(L3); - L2 = memRead32(L1 + 4); goto indirect_L3_args_L2; - - indirect_L3_args_L2: - // Push a 'resume compressed string' call stub. - CHECK_FREE(4); - PUSH (10); // DestType - PUSH (L6); // DestAddr (bit number in string) - PUSH (L7); // PC (byte address in string) - PUSH ((frame - base) * 4); // FramePtr - // Check the type of the embedded object. - switch (memRead8(L3)) - { - case 0xE0: // C string. - L7 = L3 + 1; - goto resume_c_string_L7; - - case 0xE1: // Compressed string. - L7 = L3 + 1; - L6 = 0; - goto resume_compressed_string_L7_bit_L6; - - case 0xE2: // Unicode string. - L7 = L3 + 4; // Skip extra three padding bytes. - goto resume_uni_string_L7; - - case 0xC0: case 0xC1: // Function. - // Retrieve arguments. - for (L1 += 8, L4 = L2; L4 > 0 ; --L4, L1+=4) - args[L4-1] = memRead32(L1); - // Enter function. - L1 = L3; - goto do_enter_function_L1; - - default: fatalError ("Embedded object in string has unknown type"); - } - break; - - default: fatalError ("Unknown string table node type"); - } - // Start back at the root node again. - goto resume_compressed_string_L7_bit_L6; - - do_streamstr: - // Push a 'resume function' call stub. - CHECK_FREE(4); - PUSH (11); // DestType - PUSH (0); // Addr - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - - // Load the string's type byte. - L2 = memRead8(L1++); - if (L2 == 0xE0) - { - // Uncompressed string. - L7 = L1; - goto resume_c_string_L7; - } - else if (L2 == 0xE1) - { - // Compressed string. - L7 = L1; - L6 = 0; - goto resume_compressed_string_L7_bit_L6; - } - else if (L2 == 0xE2) - { - // Uncompressed Unicode string. - L7 = L1 + 3; // Skip three padding bytes. - goto resume_uni_string_L7; - } - else - { - fatalError ("Value used in streamstr was not a string"); - goto finished; - } - - do_streamchar: - L7 = READ_PC; - if (ioMode == IO_NULL) - { /* Do nothing */ } - else if (ioMode == IO_GLK) - { - unsigned char c = (L1 & 0xff); - glk_put_char (c); - } - else - { - // Store this character in the args array. - args [0] = (L1 & 0xff); - // Push a 'resume function' call stub. - CHECK_FREE(4); - PUSH (0); // DestType - PUSH (0); // Addr - PUSH (L7); // PC - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - NEXT; - - do_streamunichar: - L7 = READ_PC; - if (ioMode == IO_NULL) - { /* Do nothing */ } - else if (ioMode == IO_GLK) - { -#ifdef GLK_MODULE_UNICODE - glk_put_char_uni ((glui32) L1); -#else - unsigned char c = (L1 > 0 && L1 < 256) ? L1 : '?'; - glk_put_char (c); -#endif // GLK_MODULE_UNICODE - } - else - { - // Store this character in the args array. - args [0] = L1; - // Push a 'resume function' call stub. - CHECK_FREE(4); - PUSH (0); // DestType - PUSH (0); // Addr - PUSH (L7); // PC - PUSH ((frame - base) * 4); // FramePtr - // Call the filter function. - L1 = ioRock; - L2 = 1; - goto do_enter_function_L1; - } - NEXT; - - do_streamnum: - // Push a 'resume function' call stub. - CHECK_FREE(4); - PUSH (11); // DestType - PUSH (0); // Addr - PUSH (READ_PC); // PC - PUSH ((frame - base) * 4); // FramePtr - - // Print the number. - L7 = L1; - L6 = 0; - goto resume_number_L7_digit_L6; - - // Stub opcodes: - - do_getmemsize: - S1 = gEndMem; - NEXT; - - do_getiosys: - S1 = ioMode; - S2 = ioRock; - NEXT; - - do_setiosys: - switch (L1) - { - case IO_NULL: - case IO_FILTER: - case IO_GLK: - ioMode = (enum IOMode) L1; - ioRock = L2; - break; - - default: - fatalError ("Illegal I/O mode"); - break; - } - NEXT; - - do_quit: - goto finished; - - do_restart: - // Reset game memory to its initial state. - resetMemory(protectPos, protectSize); - - // Reset all the stack pointers. - frame = locals = values = sp = base; - - // Call the first function. - L1 = startPos; // Initial PC. - L2 = 0; // No arguments. - goto do_enter_function_L1; - - do_verify: - S1 = verifyMemory(); - NEXT; - - do_random: - if (L1 > 0) - S1 = rand() % L1; - else if (L1 < 0) - S1 = -(rand() % -L1); - else - { - // The parameter is zero, so we should generate a - // random number in "the full 32-bit range". The rand() - // function might not cover the entire range, so we'll - // generate the number with several calls. -#if (RAND_MAX < 0xffff) - S1 = rand() ^ (rand() << 12) ^ (rand() << 24); -#else - S1 = (rand() & 0xffff) | (rand() << 16); -#endif - } - NEXT; - - do_setrandom: - srand (L1 ? L1 : time(NULL)); - NEXT; - - do_glk: - // The first argument is topmost in the stack; count is in L2. - CHECK_USED(L2); - // We want to store the arguments in 'args' in the same order. - for (L3 = 0 ; L3 < L2 ; ++L3) - args [L3] = POP; - gStackPointer = sp; - S1 = git_perform_glk (L1, L2, (glui32*) args); - sp = gStackPointer; - NEXT; - - do_binarysearch: - S1 = git_binary_search (L1, L2, L3, L4, L5, L6, L7); - NEXT; - - do_linearsearch: - S1 = git_linear_search (L1, L2, L3, L4, L5, L6, L7); - NEXT; - - do_linkedsearch: - S1 = git_linked_search (L1, L2, L3, L4, L5, L6); - NEXT; - - do_gestalt: - S1 = gestalt (L1, L2); - NEXT; - - do_getstringtbl: S1 = stringTable; NEXT; - do_setstringtbl: stringTable = L1; NEXT; - - do_debugtrap: - // TODO: do something useful here. - NEXT; - - do_stkroll: - // We need to rotate the top L1 elements by L2 places. - if (L1 < 0) - fatalError ("Negative number of elements to rotate in stkroll"); - if (L1 > (sp - values)) - fatalError ("Tried to rotate too many elements in stkroll"); - if (L1 == 0) - NEXT; - // Now, let's normalise L2 into the range [0..L1). - if (L2 >= 0) - L2 = L2 % L1; - else - L2 = L1 - (-L2 % L1); - // Avoid trivial cases. - if (L2 == 0 || L2 == L1) - NEXT; - L2 = L1 - L2; - // The problem is reduced to swapping elements [0..L2) with - // elements [L2..L1). Let's call these two sequences A and B, - // so we need to transform AB into BA. We do this sneakily - // with reversals, as follows: AB -> A'B -> A'B' -> (A'B')', - // where X' is the reverse of the sequence X. -#define SWAP(x,y) \ - do { L4 = sp[(x)-L1];sp[(x)-L1]=sp[(y)-L1];sp[(y)-L1]=L4; } while (0) - - // Reverse [0..L2). - for (L3 = 0 ; L3 < L2/2 ; ++L3) - SWAP (L3, L2-1-L3); - // Reverse [L2..L1). - for (L3 = L2 ; L3 < (L2 + (L1-L2)/2) ; ++L3) - SWAP (L3, L1-1-(L3-L2)); - // Reverse [0..L1). - for (L3 = 0 ; L3 < L1/2 ; ++L3) - SWAP (L3, L1-1-L3); - -#undef SWAP - // And we're done! - NEXT; - - do_setmemsize: - S1 = resizeMemory (L1, 0); - NEXT; - - do_protect: - protectPos = L1; - protectSize = L2; - NEXT; - - // Memory management (new with glulx spec 3.1) - - do_mzero: - if (L1 > 0) { - if (L2 < gRamStart || (L2 + L1) > gEndMem) - memWriteError(L2); - memset(gMem + L2, 0, L1); - } - NEXT; - - do_mcopy: - if (L1 > 0) { - if (L2 < 0 || (L2 + L1) > gEndMem) - memReadError(L2); - if (L3 < gRamStart || (L3 + L1) > gEndMem) - memWriteError(L3); - memmove(gMem + L3, gMem + L2, L1); - } - NEXT; - - do_malloc: - S1 = heap_alloc(L1); - NEXT; - - do_mfree: - heap_free(L1); - NEXT; - - // Function acceleration (new with glulx spec 3.1.1) - - do_accelfunc: - accel_set_func(L1, L2); - NEXT; - - do_accelparam: - accel_set_param(L1, L2); - NEXT; - - // Floating point (new with glulx spec 3.1.2) - - do_numtof: - F1 = (git_float) L1; - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_ftonumz: - F1 = DECODE_FLOAT(L1); - if (!signbit(F1)) { - if (isnan(F1) || isinf(F1) || (F1 > 2147483647.0)) - S1 = 0x7FFFFFFF; - else - S1 = (git_sint32) truncf(F1); - } else { - if (isnan(F1) || isinf(F1) || (F1 < -2147483647.0)) - S1 = 0x80000000; - else - S1 = (git_sint32) truncf(F1); - } - NEXT; - - do_ftonumn: - F1 = DECODE_FLOAT(L1); - if (!signbit(F1)) { - if (isnan(F1) || isinf(F1) || (F1 > 2147483647.0)) - S1 = 0x7FFFFFFF; - else - S1 = (git_sint32) roundf(F1); - } else { - if (isnan(F1) || isinf(F1) || (F1 < -2147483647.0)) - S1 = 0x80000000; - else - S1 = (git_sint32) roundf(F1); - } - NEXT; - - do_ceil: - F1 = ceilf(DECODE_FLOAT(L1)); - L2 = ENCODE_FLOAT(F1); - if ((L2 == 0x0) || (L2 == 0x80000000)) - L2 = L1 & 0x80000000; - S1 = L2; - NEXT; - - do_floor: - F1 = floorf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_sqrt: - F1 = sqrtf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_exp: - F1 = expf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_log: - F1 = logf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_pow: -#ifdef USE_OWN_POWF - F1 = git_powf(DECODE_FLOAT(L1), DECODE_FLOAT(L2)); -#else - F1 = powf(DECODE_FLOAT(L1), DECODE_FLOAT(L2)); -#endif - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_atan2: - F1 = atan2f(DECODE_FLOAT(L1), DECODE_FLOAT(L2)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_fmod: - F1 = DECODE_FLOAT(L1); - F2 = DECODE_FLOAT(L2); - F3 = fmodf(F1, F2); - F4 = (F1 - F3) / F2; - L4 = ENCODE_FLOAT(F4); - if ((L4 == 0) || (L4 == 0x80000000)) - L4 = (L1 ^ L2) & 0x80000000; - S1 = ENCODE_FLOAT(F3); - S2 = L4; - NEXT; - - do_sin: - F1 = sinf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_cos: - F1 = cosf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_tan: - F1 = tanf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_asin: - F1 = asinf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_acos: - F1 = acosf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - do_atan: - F1 = atanf(DECODE_FLOAT(L1)); - S1 = ENCODE_FLOAT(F1); - NEXT; - - // Special Git opcodes - - do_git_setcacheram: - gCacheRAM = (L1 == 0) ? 0 : 1; - NEXT; - - do_git_prunecache: - pruneCodeCache (L1, L2); - NEXT; - - // Error conditions: - - do_error_bad_opcode: - fatalError ("Illegal instruction"); - goto finished; - - stack_overflow: - fatalError ("Stack overflow"); - goto finished; - - stack_underflow: - fatalError ("Stack underflow"); - goto finished; - -// --------------------------------- - -finished: - - free (base); - shutdownCompiler(); -} diff --git a/textworld/thirdparty/glulx/Git-Glulx/test.sh b/textworld/thirdparty/glulx/Git-Glulx/test.sh deleted file mode 100755 index 49fcf6ef..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -cd ../cheapglk && make -j16 && cd ../Git-Glulx && make -j16 && PYTHONPATH=. ./git-glulx ../Sherbrooke/textworld/games/test.ulx diff --git a/textworld/thirdparty/glulx/Git-Glulx/user_agent.py b/textworld/thirdparty/glulx/Git-Glulx/user_agent.py deleted file mode 100644 index ac587687..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/user_agent.py +++ /dev/null @@ -1,2 +0,0 @@ -def evaluate(words): - return ('n', False) diff --git a/textworld/thirdparty/glulx/Git-Glulx/version.h b/textworld/thirdparty/glulx/Git-Glulx/version.h deleted file mode 100644 index 8eb6cc8e..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/version.h +++ /dev/null @@ -1,4 +0,0 @@ -// Automatically generated file -- do not edit! -#define GIT_MAJOR 1 -#define GIT_MINOR 3 -#define GIT_PATCH 5 diff --git a/textworld/thirdparty/glulx/Git-Glulx/win/git.rc b/textworld/thirdparty/glulx/Git-Glulx/win/git.rc deleted file mode 100644 index 1108ada0..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/win/git.rc +++ /dev/null @@ -1,6 +0,0 @@ -100 ICON DISCARDABLE "win/res/Glulx.ico" -101 ICON DISCARDABLE "win/res/Blorb.ico" -102 ICON DISCARDABLE "win/res/Ulx.ico" - -1 24 "win/res/Git.manifest" - diff --git a/textworld/thirdparty/glulx/Git-Glulx/win/res/Blorb.ico b/textworld/thirdparty/glulx/Git-Glulx/win/res/Blorb.ico deleted file mode 100644 index d87aee42..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/win/res/Blorb.ico and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/win/res/Git.manifest b/textworld/thirdparty/glulx/Git-Glulx/win/res/Git.manifest deleted file mode 100644 index 8d7383ea..00000000 --- a/textworld/thirdparty/glulx/Git-Glulx/win/res/Git.manifest +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - Windows Git Glulx Interpreter - - - - true - - - - - - - - - - - diff --git a/textworld/thirdparty/glulx/Git-Glulx/win/res/Glulx.ico b/textworld/thirdparty/glulx/Git-Glulx/win/res/Glulx.ico deleted file mode 100644 index 86aad48c..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/win/res/Glulx.ico and /dev/null differ diff --git a/textworld/thirdparty/glulx/Git-Glulx/win/res/Ulx.ico b/textworld/thirdparty/glulx/Git-Glulx/win/res/Ulx.ico deleted file mode 100644 index 728174ce..00000000 Binary files a/textworld/thirdparty/glulx/Git-Glulx/win/res/Ulx.ico and /dev/null differ diff --git a/textworld/thirdparty/glulx/cheapglk/.gitignore b/textworld/thirdparty/glulx/cheapglk/.gitignore deleted file mode 100644 index 75e3e60d..00000000 --- a/textworld/thirdparty/glulx/cheapglk/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.o -*.a -Make.* -.idea/* -cmake-build-debug/* \ No newline at end of file diff --git a/textworld/thirdparty/glulx/cheapglk/LICENSE b/textworld/thirdparty/glulx/cheapglk/LICENSE deleted file mode 100644 index df966390..00000000 --- a/textworld/thirdparty/glulx/cheapglk/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 1998-2016, Andrew Plotkin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/textworld/thirdparty/glulx/cheapglk/Makefile b/textworld/thirdparty/glulx/cheapglk/Makefile deleted file mode 100644 index 1c6556a8..00000000 --- a/textworld/thirdparty/glulx/cheapglk/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# Unix Makefile for CheapGlk library - -# This generates two files. One, of course, is libcheapglk.a -- the library -# itself. The other is Make.cheapglk; this is a snippet of Makefile code -# which locates the cheapglk library. -# -# When you install cheapglk, you must put libcheapglk.a in the lib directory, -# and glk.h, glkstart.h, and Make.cheapglk in the include directory. -# -# The file cgunigen.c was generated by the casemap.py script, but -# that step isn't in the Makefile -- you don't have to re-generate it. -# It's based on Unicode character data, which is not platform-dependent. - -# Pick a C compiler. -CC = cc -#CC = gcc -ansi - -OPTIONS = -g -Wall -Werror -std=gnu99 - -CFLAGS = $(OPTIONS) $(INCLUDEDIRS) - -GLKLIB = libcheapglk.a - -CHEAPGLK_OBJS = \ - cgfref.o cggestal.o cgmisc.o cgstream.o cgstyle.o cgwindow.o cgschan.o \ - cgdate.o cgunicod.o main.o gi_dispa.o gi_blorb.o gi_debug.o cgblorb.o \ - agent.o - -CHEAPGLK_HEADERS = cheapglk.h gi_dispa.h gi_debug.h agent.h - -all: $(GLKLIB) Make.cheapglk - -cgunicod.o: cgunigen.c - -$(GLKLIB): $(CHEAPGLK_OBJS) - ar r $(GLKLIB) $(CHEAPGLK_OBJS) - ranlib $(GLKLIB) - -Make.cheapglk: - echo LINKLIBS = $(LIBDIRS) $(LIBS) > Make.cheapglk - echo GLKLIB = -lcheapglk >> Make.cheapglk - -$(CHEAPGLK_OBJS): glk.h $(CHEAPGLK_HEADERS) - -clean: - rm -f *~ *.o $(GLKLIB) Make.cheapglk diff --git a/textworld/thirdparty/glulx/cheapglk/README.txt b/textworld/thirdparty/glulx/cheapglk/README.txt deleted file mode 100644 index 0a3ae347..00000000 --- a/textworld/thirdparty/glulx/cheapglk/README.txt +++ /dev/null @@ -1,282 +0,0 @@ -CheapGlk: Cheapass Implementation of the Glk API. - -CheapGlk Library: version 1.0.6. -Glk API which this implements: version 0.7.5. -Designed by Andrew Plotkin -http://eblong.com/zarf/glk/index.html - -This is a fork of the CheapGlk project, in order to replace the stdio streams -with a machine learning backend. All restrictions below are accurate with regard -to window handling. Ultimate disposition of text will instead proceed to a -call to a machine learning agent in lieu of being output to terminal. - -This is source code for the simplest possible implementation of the Glk -API. It uses stdio.h calls (fopen, putc, getc), but not any of the -curses.h calls (which handle cursor movement and unbuffered keyboard -input.) So there's no way it can support multiple windows, or a status -bar. In fact, this library only allows you to create *one* window at a -time, and that must be a TextBuffer. Fortunately -- well, deliberately --- TextBuffer windows are very simple; all the library has to be able to -do is printf() straight to stdout. - -* Command-line arguments: - -CheapGlk can accept command-line arguments both for itself and on behalf -of the underlying program. These are the arguments the library accepts -itself: - - -w NUM, -h NUM: These set the screen width and height manually. This -is only used when trying to "clear" the screen (by printing a bunch of -newlines.) - - -ui: Assume that stdin contains UTF-8 encoded text. - -uo: Generate UTF-8 encoded text on stdout. - -u: Both of the above. - - -q: Don't display the "Welcome to CheapGlk" banner before the game. - - -D: Consider "/" to be a debug command prefix; all /commands are - passed to the game debugger (if it has one). - -* Notes on building this mess: - -See the top of the Makefile for comments on installation. - -When you compile a Glk program and link it with GlkTerm, you must supply -one more file: you must define a function called glkunix_startup_code(), -and an array glkunix_arguments[]. These set up various Unix-specific -options used by the Glk library. There is a sample "glkstart.c" file -included in this package; you should modify it to your needs. - -The glkunix_arguments[] array is a list of command-line arguments that -your program can accept. The library will sort these out of the command -line and pass them on to your code. The array structure looks like this: - -typedef struct glkunix_argumentlist_struct { - char *name; - int argtype; - char *desc; -} glkunix_argumentlist_t; - -extern glkunix_argumentlist_t glkunix_arguments[]; - -In each entry, name is the option as it would appear on the command line -(including the leading dash, if any.) The desc is a description of the -argument; this is used when the library is printing a list of options. -And argtype is one of the following constants: - - glkunix_arg_NoValue: The argument appears by itself. - glkunix_arg_ValueFollows: The argument must be followed by another -argument (the value). - glkunix_arg_ValueCanFollow: The argument may be followed by a value, -optionally. (If the next argument starts with a dash, it is taken to be -a new argument, not the value of this one.) - glkunix_arg_NumberValue: The argument must be followed by a number, -which may be the next argument or part of this one. (That is, either -"-width 20" or "-width20" will be accepted.) - glkunix_arg_End: The glkunix_arguments[] array must be terminated -with an entry containing this value. - -To accept arbitrary arguments which lack dashes, specify a name of "" -and an argtype of glkunix_arg_ValueFollows. - -If you don't care about command-line arguments, you must still define an -empty arguments list, as follows: - -glkunix_argumentlist_t glkunix_arguments[] = { - { NULL, glkunix_arg_End, NULL } -}; - -Here is a more complete sample list: - -glkunix_argumentlist_t glkunix_arguments[] = { - { "", glkunix_arg_ValueFollows, "filename: The game file to load." -}, - { "-hum", glkunix_arg_ValueFollows, "-hum NUM: Hum some NUM." }, - { "-bom", glkunix_arg_ValueCanFollow, "-bom [ NUM ]: Do a bom (on -the NUM, if given)." }, - { "-goo", glkunix_arg_NoValue, "-goo: Find goo." }, - { "-wob", glkunix_arg_NumberValue, "-wob NUM: Wob NUM times." }, - { NULL, glkunix_arg_End, NULL } -}; - -This would match the arguments "thingfile -goo -wob8 -bom -hum song". - -After the library parses the command line, it does various occult -rituals of initialization, and then calls glkunix_startup_code(). - -int glkunix_startup_code(glkunix_startup_t *data); - -This should return TRUE if everything initializes properly. If it -returns FALSE, the library will shut down without ever calling your -glk_main() function. - -The data structure looks like this: - -typedef struct glkunix_startup_struct { - int argc; - char **argv; -} glkunix_startup_t; - -The fields are a standard Unix (argc, argv) list, which contain the -arguments you requested from the command line. In deference to custom, -argv[0] is always the program name. - -You can put other startup code in glkunix_startup_code(). This should -generally be limited to finding and opening data files. There are a few -Unix Glk library functions which are convenient for this purpose: - -strid_t glkunix_stream_open_pathname(char *pathname, glui32 textmode, - glui32 rock); - -This opens an arbitrary file, in read-only mode. Note that this function -is *only* available during glkunix_startup_code(). It is inherent -non-portable; it should not and cannot be called from inside glk_main(). - -void glkunix_set_base_file(char *filename); - -This sets the library's idea of the "current directory" for the executing -program. The argument should be the name of a file (not a directory). -When this is set, fileref_create_by_name() will create files in the same -directory as that file, and create_by_prompt() will base default filenames -off of the file. If this is not called, the library works in the Unix -current working directory, and picks reasonable default defaults. - -* Notes on the source code: - -Functions which begin with glk_ are, of course, Glk API functions. These -are declared in glk.h. - -Functions which begin with gli_ are internal to the CheapGlk library -implementation. They don't exist in every Glk library, because different -libraries implement things in different ways. (In fact, they may be -declared differently, or have different meanings, in different Glk -libraries.) These gli_ functions (and other internal constants and -structures) are declared in cheapglk.h. - -The files gi_dispa.c and gi_dispa.h are the Glk dispatch layer. -gi_blorb.c,h are the Blorb utility functions, and gi_debug.c,h are -the debug console interface. - -As you can see from the code, I've kept a policy of catching every error -that I can possibly catch, and printing visible warnings. - -This code should be portable to any C environment which has an ANSI -stdio library. The likely trouble spots are glk_fileref_delete_file() -and glk_fileref_does_file_exist() -- I've implemented them with the -Unix calls unlink() and stat() respectively. - -The character-encoding problem is pretty much ignored here (like most -of the more complicated Glk issues.) By default, this reads and writes -the Latin-1 charset. If you use the -u switch, it reads and writes -UTF-8 instead. Most modern terminal windows can do UTF-8. (If you're -using the Terminal app on a Mac, be sure to *uncheck* the "Use option -key as meta key" preference.) - -* Version History - -1.0.6: - Declared support for Glk spec 0.7.5. - Added support for a "debug console". If the -D option is given, lines - beginning with "/" are considered debug commands. (This is not - interesting unless the interpreter is compiled with debug support.) - -1.0.5: - Text-mode Unicode file streams are now read and written in UTF-8 - (Glk 0.7.5, although that won't be formalized until 1.0.6). - Fixed a struct initialization bug in gli_date_to_tm(). (I think this - caused no problems in practice.) - Added an optional timegm() function that you can compile in if your - platform lacks it. (#define NO_TIMEGM_AVAIL) - Removed old, deprecated tmpnam() call. - -1.0.4: - Updated the Blorb-resource functions to understand FORM chunks - (Glk 0.7.4 amendment). - Added stub for autosave/autorestore hooks. (This library does not - support autosave, however.) - -1.0.3: - Added the Blorb-resource functions (Glk 0.7.4). - External filenames now follow the new spec recommendations: standard - filename suffixes, and removing more questionable characters in - fileref_create_by_name(). - -1.0.2: - Added Windows patches for the date-time code. - Fixed a bug with reading and writing to the same file without a - reposition operation in between. - In gi_dispa.c, fixed a notation that was preventing stream_open_memory - and stream_open_memory_uni from accepting a null array argument. - Fixed get_line_stream() to include the terminal null when reading - from a Unicode stream. - Added stubs for the improved sound functions (Glk 0.7.3). - -1.0.1: - Added the date-time functions (Glk 0.7.2). - Fixed bugs in Unicode normalization and case-changing (thanks David - Fletcher and David Kinder). - -1.0.0: - Support for all the Glk 0.7.1 features that can be supported. - (Meaning, the Unicode normalization calls.) - Added -q option to silence banner. - The library now exits cleanly if stdin closes. - Added glkunix_stream_open_pathname_gen(), a more general form of - the pathname opening function in the startup code. (This is needed - for profiling improvements.) - -0.9.1: - Fixed file-creation bug in glk_stream_open_file(). - Fixed readcount bug in gli_get_line(). - Fixed argument parsing bug ("-w 120" was handled wrong). - Fixed potential buffer overflow in glk_fileref_create_by_name(). - -0.9.0: - Upgraded to Glk API version 0.7.0; added the Unicode functions. - Added the -u option. - -0.8.7: - Upgraded to Glk API version 0.6.1; i.e., a couple of new gestalt - selectors. - Fixed dispatch bug for glk_get_char_stream. - -0.8.6: - Upgraded to Glk API version 0.6.0; i.e., stubs for hyperlinks. - -0.8.5: - Added a fflush(stdout) before input. This shouldn't be necessary in - ANSI C, according to Stevens, but it seems to be on the Acorn. - Added glkunix_set_base_file(). - -0.8.4: - Added the ability to open a Blorb file, although the library never - makes use of it. (This allows an interpreter to read a game file - from Blorb.) - -0.8.3: - Upgraded to Glk API version 0.5.2; i.e., stubs for sound code. - Made the license a bit friendlier. - -0.8.2: - Fixed a leak (stream objects were never unregistered). - Added more consistency-checking to the disprock values. - -0.8.1: - Upgraded to Glk API version 0.5.1; i.e., stubs for graphics code. - -0.8: - Upgraded to Glk API version 0.5; added dispatch layer code. - -0.7: - The one true Unix Glk Makefile system. - Startup code and command-line argument system. - -0.5: Alpha release. - -* Permissions - -The CheapGlk, GiDispa, and GiBlorb libraries, as well as the glk.h header -file, are copyright 1998-2016 by Andrew Plotkin. The GiDebug library is -copyright 2014-2017 by Andrew Plotkin. All are distributed under the MIT -license; see the "LICENSE" file. diff --git a/textworld/thirdparty/glulx/cheapglk/agent.c b/textworld/thirdparty/glulx/cheapglk/agent.c deleted file mode 100644 index 16d35a74..00000000 --- a/textworld/thirdparty/glulx/cheapglk/agent.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include - -/* posix */ -#include -#include -#include - -/* sockets */ -#include -#include -#include - -#include "glk.h" -#include "cheapglk.h" -#include "agent.h" - -const glui32 INIT_BUF_SIZE = 8192; - -char* cur_buf = 0; -glui32 str_len = 0; -glui32 cur_buf_len = 0; -int sock_fh = -1; - -void agent_init(char* sock_name) -{ - if(sock_name == NULL) { - gli_strict_warning("agent_init: Cannot initialize process without socket name"); - glk_exit(); - } - - /* Memory buffer */ - if(cur_buf) { - free(cur_buf); - cur_buf = 0; - } - cur_buf = malloc(INIT_BUF_SIZE); - cur_buf_len = INIT_BUF_SIZE; - memset(cur_buf, 0, cur_buf_len); - - /* socket */ - sock_fh = socket(AF_LOCAL, SOCK_STREAM, 0); - if(sock_fh == -1) { - gli_strict_warning("agent_init: Could not open socket"); - glk_exit(); - } - - struct sockaddr_un sock_addr; - sock_addr.sun_family = AF_UNIX; - snprintf(sock_addr.sun_path, sizeof(sock_addr.sun_path), "%s", sock_name); - - int conn_status = connect(sock_fh, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); - if(conn_status < 0) { - gli_strict_warning("agent_init: Could not connect socket"); - glk_exit(); - } -} - -void agent_put_string(char* buf, glui32 len) -{ - glui32 new_str_len, new_buf_len; - char* new_buf; - - /* check for capacity */ - new_str_len = str_len + len; - if(new_str_len >= cur_buf_len) { - /* resize buffer */ - new_buf_len = new_str_len << 1; - if(new_buf_len < cur_buf_len) { /* overflow check */ - gli_strict_warning("agent_put_string: CANNOT write to output, buffer too large"); - } - new_buf = realloc(cur_buf, new_buf_len); - if(new_buf == 0) { /* malloc fail check */ - gli_strict_warning("agent_put_string: CANNOT write to output, buffer too long"); - return; - } - - cur_buf = new_buf; - cur_buf_len = new_buf_len; - } - - /* do the copy */ - memmove(cur_buf+str_len, buf, len); - str_len = new_str_len; -} - -glui32 agent_get_output(char* buf, glui32 len) -{ - char* dest_buf = NULL; /* forward declare for goto; see para 6.8.6.1 */ - glui32 dest_buf_len = 0; - /* - * write to out as one large packet - */ - ssize_t sent = -1; - - glui32 net_len = htonl(str_len); - sent = send(sock_fh, &net_len, 4, 0); - if(sent < 0) { - int err = errno; - gli_strict_warning("agent.c: send size"); - gli_strict_warning(strerror(err)); - goto cleanup; - } - - sent = send(sock_fh, cur_buf, str_len, 0); - - if(sent < 0) { - int err = errno; - gli_strict_warning("agent.c: send message"); - gli_strict_warning(strerror(err)); - goto cleanup; - } - - /* - * receive size, then message - */ - bool restart = false; - glui32 net_dest_buf_len; - - do { //handle EINTR - restart = 0; - ssize_t in_len = recv(sock_fh, &net_dest_buf_len, sizeof(glui32), MSG_WAITALL); - if(in_len == -1) { - int err = errno; - if(err == EINTR) { - restart = true; - continue; - } - gli_strict_warning("agent.c: receive size"); - gli_strict_warning(strerror(err)); - goto cleanup; - } - } while(restart); - - dest_buf_len = ntohl(net_dest_buf_len); - dest_buf = calloc(dest_buf_len+1, 1); - - do { //handle EINTR - restart = false; - ssize_t in_len = recv(sock_fh, dest_buf, dest_buf_len, MSG_WAITALL); - if(in_len == -1) { - int err = errno; - if(err == EINTR) { - restart = true; - continue; - } - gli_strict_warning("agent.c: receive message"); - gli_strict_warning(strerror(err)); - goto cleanup; - } - } while(restart); - - if(dest_buf_len > len) { - dest_buf_len = strlen(dest_buf)+1; - } - if(dest_buf_len > len) { - char errmsg[100]; - snprintf(errmsg, 100, "agent_get_output: string too large for buffer (%d versus %d)", dest_buf_len, len); - gli_strict_warning(errmsg); - goto cleanup; - } - - memmove(buf, dest_buf, dest_buf_len); - - /* "deallocate" buffer */ - cleanup: - if(dest_buf != NULL) { - free(dest_buf); - dest_buf = NULL; - } - memset(cur_buf, 0, str_len); - str_len = 0; - - return dest_buf_len; -} - -void agent_exit() { - if(cur_buf != NULL) { - free(cur_buf); - cur_buf = NULL; - } - - if(sock_fh == -1) { - return; /* never connected */ - } - - char out_buf[11]; - - out_buf[0] = 127; //continuation - out_buf[1] = 0x10; //DLE - strncpy(out_buf+2, "+++EXIT", 8); - out_buf[9] = 0x10; //DLE - out_buf[10] = 0; - - int sent = send(sock_fh, out_buf, 11, 0); - - if(sent < 0) { - int err = errno; - gli_strict_warning("agent.c: agent_exit"); - gli_strict_warning(strerror(err)); - } -} - diff --git a/textworld/thirdparty/glulx/cheapglk/agent.h b/textworld/thirdparty/glulx/cheapglk/agent.h deleted file mode 100644 index 3ea20ebf..00000000 --- a/textworld/thirdparty/glulx/cheapglk/agent.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef AGENT_H -#define AGENT_H -#pragma once - -/** - * Initializes the agent. - * @param sock_name The name of the unix socket file to connect to - */ -void agent_init(char* sock_name); - -/** - * Adds an output-encoded string (UTF-8 or latin1) as input to the agent - * @param buf The buf containing the output - * @param len The length of the output - */ -void agent_put_string(char* buf, glui32 len); - -/** - * Returns agent output for the input buffer for a continuous process. - * @param output_buf Output buffer to write into - * @param max_len Size of output buffer - * @return The length of output actually written - */ -glui32 agent_get_output(char* output_buf, glui32 max_len); - -/** - * Should be called on glk_exit() to avoid client programs hanging. - */ -void agent_exit(void); - -#endif //AGENT_H \ No newline at end of file diff --git a/textworld/thirdparty/glulx/cheapglk/casemap.py b/textworld/thirdparty/glulx/cheapglk/casemap.py deleted file mode 100644 index 474a6881..00000000 --- a/textworld/thirdparty/glulx/cheapglk/casemap.py +++ /dev/null @@ -1,762 +0,0 @@ -#!/usr/bin/env python - -# Moderately dumb script to generate the Glk library tables for Unicode -# case-mapping and normalization. -# -# python casemap.py /path/to/unicode/directory > cgunigen.c -# or -# python casemap.py --js /path/to/unicode/directory > unicodemap.js -# -# The argument should be a directory which contains UnicodeData.txt -# and SpecialCasing.txt. These files can be found at -# , which is version 4.0.1 -# of the Unicode spec. This script has only been tested with that version -# (and the included files are from that version). It is not current. - -from __future__ import print_function - -import os -import re -import sys - -output = 'c' -args = sys.argv[ 1 : ] - -if ('--js' in args): - output = 'js' - args.remove('--js') - -if ('--c' in args): - output = 'c' - args.remove('--c') - -if ('--none' in args): - output = None - args.remove('--none') - -if (len(args) != 1): - print('Usage: casemap.py [ --js | --c | --none ] /path/to/unicode/directory') - sys.exit(1) - -unicode_dir = args[0] -unicode_version = '???' - -try: - ucdfl = open(os.path.join(unicode_dir, 'UnicodeData.txt')) - specfl = open(os.path.join(unicode_dir, 'SpecialCasing.txt')) -except IOError: - print(unicode_dir, 'must contain the files UnicodeData.txt and SpecialCasing.txt.') - sys.exit(1) - -# parse UnicodeData.txt - -combintable = {} -decomptable = {} -recdecomptable = {} -compotable = {} - -casetable = {} -upcasetable = {} -downcasetable = {} -titlecasetable = {} -totalchars = 0 -titleablechars = 0 -totalspecialcases = 0 - -specialtable = {} - -while 1: - ln = ucdfl.readline() - if (not ln): - break - ln = ln.strip() - pos = ln.find('#') - if (pos >= 0): - ln = ln[ : pos] - - ls = ln.split(';') - if ((not ls) or (not ls[0])): - continue - - val = int(ls[0], 16) - totalchars = totalchars+1 - - if (len(ls) > 3 and ls[3]): - combin = int(ls[3]) - if (combin): - combintable[val] = combin - - if (len(ls) > 5 and ls[5]): - decomp = ls[5] - if not decomp.startswith('<'): - ent = [ int(el, 16) for el in decomp.split(' ') ] - recdecomptable[val] = ent - - upcase = val - downcase = val - titlecase = val - - if (len(ls) > 12 and ls[12]): - upcase = int(ls[12], 16) - if (val != upcase): - upcasetable[val] = [upcase] - if (len(ls) > 13 and ls[13]): - downcase = int(ls[13], 16) - if (val != downcase): - downcasetable[val] = [downcase] - if (len(ls) > 14 and ls[14]): - titlecase = int(ls[14], 16) - if (val != titlecase): - titlecasetable[val] = [titlecase] - - if (val == upcase and val == downcase and val == titlecase): - continue - - if (upcase != titlecase): - titleablechars = titleablechars+1 - specialtable[val] = ([upcase], [downcase], [titlecase]) - - casetable[val] = (upcase, downcase, titlecase) - -while 1: - ln = specfl.readline() - if (not ln): - break - if ln.startswith('# SpecialCasing'): - match = re.search('SpecialCasing-([0-9.]+).txt', ln) - if (match): - unicode_version = match.group(1) - continue - - ln = ln.strip() - pos = ln.find('#') - if (pos >= 0): - ln = ln[ : pos] - - ls = ln.split(';') - ls = [st.strip() for st in ls] - if ((not ls) or (not ls[0])): - continue - - val = int(ls[0], 16) - - if (len(ls) > 4 and ls[4]): - # conditional case, ignore - continue - - totalspecialcases = totalspecialcases+1 - - upcase = [ int(st, 16) for st in ls[3].split(' ') ] - downcase = [ int(st, 16) for st in ls[1].split(' ') ] - titlecase = [ int(st, 16) for st in ls[2].split(' ') ] - - if (upcase != [val]): - upcasetable[val] = upcase - if (downcase != [val]): - downcasetable[val] = downcase - if (titlecase != [val]): - titlecasetable[val] = titlecase - - speccase = ( upcase, downcase, titlecase ) - - casetable[val] = (val, val, val) # placeholder - specialtable[val] = speccase - -# The decomposition data we have extracted is recursive; a character can -# decompose to more decomposable characters. We now expand that into -# flat lists. (It only takes a little more space, because most characters -# aren't recursive that way.) - -def try_decompose(val): - if val in decomptable: - return decomptable[val] - res = recdecomptable.get(val) - if not res: - ls = [ val ] - decomptable[val] = ls - return ls - - ls = [] - for subval in res: - ls.extend(try_decompose(subval)) - decomptable[val] = ls - return ls - -for val in recdecomptable.keys(): - try_decompose(val) -for val in list(decomptable.keys()): - if decomptable[val] == [ val ]: - decomptable.pop(val) - -if (len(recdecomptable) != len(decomptable)): - raise Exception('Decomposition table changed length in expansion!') - -# Generate the composition mapping, which is roughly the inverse of the -# (recursive) decomposition data. It only includes decompositions into -# *two* characters, though. (Decompositions of one character to one -# character are actually canonicalizations, and we don't want to reverse -# those.) - -for (val, ls) in recdecomptable.items(): - if len(ls) not in [1, 2]: - raise Exception('Character %x has decomposition %s' % (val, ls)) - head = ls[0] - if len(ls) == 2: - map = compotable.get(head) - if (map is None): - map = {} - compotable[head] = map - map[ls[1]] = val - -max_decompose_length = max([ len(ls) for ls in decomptable.values() ]) - -sys.stderr.write(str(totalchars) + ' characters in the Unicode database\n') -sys.stderr.write(str(len(combintable)) + ' characters with combining classes\n') -sys.stderr.write(str(len(decomptable)) + ' characters with decompositions (max length ' + str(max_decompose_length) + ')\n') -sys.stderr.write(str(len(compotable)) + ' character compositions\n') -sys.stderr.write(str(len(casetable)) + ' characters which can change case\n') -sys.stderr.write(str(titleablechars) + ' characters with a distinct title-case\n') -sys.stderr.write(str(totalspecialcases) + ' characters with length changes\n') -sys.stderr.write(str(len(specialtable)) + ' special-case characters\n') - -# This semi-clever function takes a (sorted) list of integers, and -# divides it into a list of arithmetic runs, and a list of leftovers: -# -# ([ (start, end, jump), (start, end, jump), ...], [ ... ]) -# -# In the worst case, you get back ([], ls) -- no runs, and the entire -# original list as leftovers. The minlength argument tunes the results; -# you get no runs shorter than minlength. -# -def find_runs(ls, minlength=3, jumpone=False): - runs = [] - extras = [] - minlength = max(minlength, 2) - - lslen = len(ls) - pos = 0 - - while True: - if (lslen - pos < minlength): - break - start = ls[pos] - jump = ls[pos+1] - start - if (jump == 0): - raise Exception("Repeated value") - - newpos = pos - val = start - while True: - if (newpos == lslen or ls[newpos] != val): - break - newpos += 1 - val += jump - - if (newpos - pos >= minlength and not (jump != 1 and jumpone)): - runs.append( (start, val-jump, jump) ) - pos = newpos - continue - extras.append(start) - pos += 1 - - extras.extend(ls[pos:]) - - return (runs, extras) - -# Produce the output, in whichever form was requested. - -if (output == 'c'): - # C code output - - blocktable = {} - - for val in casetable.keys(): - (upcase, downcase, titlecase) = casetable[val] - - blocknum = val >> 8 - if (blocknum not in blocktable): - block = [ None ] * 256 - blocktable[blocknum] = block - else: - block = blocktable[blocknum] - block[val & 0xFF] = (upcase, downcase) - - print('/* This file was generated by casemap.py. */') - print('/* Derived from Unicode data files, Unicode version %s. */' % (unicode_version,)) - print('/* This does not get compiled into a cgunigen.o file; it\'s') - print(' * #included in cgunicod.c. */') - print() - - # The case-folding tables. - - blockkeys = list(blocktable.keys()) - blockkeys.sort() - - for blocknum in blockkeys: - print('static gli_case_block_t unigen_case_block_' + hex(blocknum) + '[256] = {') - block = blocktable[blocknum] - for ix in range(256): - ch = blocknum * 0x100 + ix - res = block[ix] - if (res == None): - upcase = ch - downcase = ch - else: - (upcase, downcase) = res - if (ch in specialtable): - print(' { 0xFFFFFFFF, 0xFFFFFFFF },') - else: - if (upcase != downcase): - if (upcase == ch): - comment = ' /* upper */' - elif (downcase == ch): - comment = ' /* lower */' - else: - comment = ' /* different */' - else: - comment = '' - print(' { ' + hex(upcase) + ', ' + hex(downcase) + ' },' + comment) - print('};') - print() - - print('#define GET_CASE_BLOCK(ch, blockptr) \\') - print('switch ((glui32)(ch) >> 8) { \\') - for blocknum in blockkeys: - print(' case ' + hex(blocknum) + ': \\') - print(' *blockptr = unigen_case_block_' + hex(blocknum) + '; \\') - print(' break; \\') - print(' default: \\') - print(' *blockptr = NULL; \\') - print('}') - - specialkeys = list(specialtable.keys()) - specialkeys.sort() - - pos = 0 - specialstructs = [] - - print('static glui32 unigen_special_array[] = {') - - for val in specialkeys: - speccase = specialtable[val] - (upcasel, downcasel, titlecasel) = speccase - - comment = ' /* ' + hex(val) + ' upcase */' - strarr = ', '.join([hex(st) for st in upcasel]) - print(' ' + str(len(upcasel)) + ', ' + strarr + ',' + comment) - pos0 = pos - pos = pos + len(upcasel) + 1 - - comment = ' /* ' + hex(val) + ' downcase */' - strarr = ', '.join([hex(st) for st in downcasel]) - print(' ' + str(len(downcasel)) + ', ' + strarr + ',' + comment) - pos1 = pos - pos = pos + len(downcasel) + 1 - - comment = ' /* ' + hex(val) + ' titlecase */' - strarr = ', '.join([hex(st) for st in titlecasel]) - print(' ' + str(len(titlecasel)) + ', ' + strarr + ',' + comment) - pos2 = pos - pos = pos + len(titlecasel) + 1 - - specialstructs.append( (val, pos0, pos1, pos2) ) - - print('};') - print() - - for (val, pos0, pos1, pos2) in specialstructs: - print('static gli_case_special_t unigen_special_' + hex(val) + ' = { ' + str(pos0) + ', ' + str(pos1) + ', ' + str(pos2) + ' };') - - print() - - print('#define GET_CASE_SPECIAL(ch, specptr) \\') - print('switch (ch) { \\') - for (val, pos0, pos1, pos2) in specialstructs: - print(' case ' + hex(val) + ': \\') - print(' *specptr = unigen_special_' + hex(val) + '; \\') - print(' break; \\') - print(' default: \\') - print(' *specptr = NULL; \\') - print('}') - - print() - - # The combining-class table. - - usetable = {} - - for (val, ent) in combintable.items(): - blocknum = val >> 8 - if blocknum not in usetable: - usetable[blocknum] = {} - if ent not in usetable[blocknum]: - usetable[blocknum][ent] = [] - usetable[blocknum][ent].append(val) - - usels = list(usetable.keys()) - usels.sort() - - print('#define RETURN_COMBINING_CLASS(ch) \\') - print('switch ((glui32)(ch) >> 8) { \\') - for blocknum in usels: - print(' case %d: \\' % (blocknum,)) - print(' switch (ch) { \\') - entls = list(usetable[blocknum].keys()) - entls.sort() - for ent in entls: - valls = usetable[blocknum][ent] - valls.sort() - for val in valls: - print(' case %d: \\' % (val,)) - print(' return %d; \\' % (ent,)) - print(' } \\') - print(' return 0; \\') - print('} \\') - print('return 0;') - - print() - - # The composition tables. - - usetable = {} - - for (val, map) in compotable.items(): - blocknum = val >> 8 - if blocknum not in usetable: - usetable[blocknum] = {} - usetable[blocknum][val] = map - - usels = list(usetable.keys()) - usels.sort() - - print('#define RETURN_COMPOSITION(ch1, ch2) \\') - print('switch ((glui32)(ch1) >> 8) { \\') - for blocknum in usels: - print(' case %d: \\' % (blocknum,)) - print(' switch (ch1) { \\') - map = usetable[blocknum] - ls = list(map.keys()) - ls.sort() - for val in ls: - print(' case %d: \\' % (val,)) - print(' switch (ch2) { \\') - subls = list(map[val].items()) - subls.sort() - for (val2, ent) in subls: - print(' case %d: return %d; \\' % (val2, ent)) - print(' } \\') - print(' return 0; \\') - print(' } \\') - print(' return 0; \\') - print('} \\') - print('return 0;') - print() - - # The decomposition tables. - - usetable = {} - - for val in decomptable.keys(): - blocknum = val >> 8 - usetable[blocknum] = 1 + usetable.get(blocknum, 0) - - for (blocknum, count) in usetable.items(): - if (count < 30): - usetable[blocknum] = None - - blocktable = {} - extratable = {} - - ls = list(decomptable.keys()) - ls.sort() - offsets = [] - - for val in ls: - pos = len(offsets) - ent = decomptable[val] - if (type(ent) == list): - offsets.extend(ent) - count = len(ent) - else: - offsets.append(ent) - count = 1 - - blocknum = val >> 8 - if not usetable[blocknum]: - extratable[val] = (count, pos) - else: - if (blocknum not in blocktable): - block = [ None ] * 256 - blocktable[blocknum] = block - else: - block = blocktable[blocknum] - block[val & 0xFF] = (count, pos) - - print('static glui32 unigen_decomp_data[%d] = {' % (len(offsets),)) - rowcount = 0 - for val in offsets: - if (rowcount >= 8): - print() - rowcount = 0 - print('%s,' % (hex(val)), end=' ') - rowcount += 1 - print('};') - print() - - blockkeys = list(blocktable.keys()) - blockkeys.sort() - - for blocknum in blockkeys: - print('static gli_decomp_block_t unigen_decomp_block_%s[256] = {' % (hex(blocknum),)) - block = blocktable[blocknum] - for ix in range(256): - ch = blocknum * 0x100 + ix - res = block[ix] - if (res == None): - count = 0 - pos = 0 - else: - (count, pos) = res - print(' { %s, %s },' % (str(count), str(pos))) - print('};') - print() - - print('#define GET_DECOMP_BLOCK(ch, blockptr) \\') - print('switch ((glui32)(ch) >> 8) { \\') - for blocknum in blockkeys: - print(' case ' + hex(blocknum) + ': \\') - print(' *blockptr = unigen_decomp_block_' + hex(blocknum) + '; \\') - print(' break; \\') - print(' default: \\') - print(' *blockptr = NULL; \\') - print('}') - - print() - - extrakeys = list(extratable.keys()) - extrakeys.sort() - - print('#define GET_DECOMP_SPECIAL(ch, countptr, posptr) \\') - print('switch (ch) { \\') - for val in extrakeys: - (count, pos) = extratable[val] - print(' case ' + hex(val) + ': \\') - print(' *countptr = ' + str(count) + '; *posptr = ' + str(pos) + '; \\') - print(' break; \\') - print(' default: \\') - print(' *countptr = 0; \\') - print('}') - - print() - - -# Some helper functions for generating the Javascript data tables. We -# have separate functions for the case tables and the decomp tables, -# because their particular structures are amenable to different -# optimizations. (The case tables have long runs of "N => N+K", -# whereas the decomp tables have long runs of arbitrary values.) - -def generate_js_table_case(label, pairs, offsets): - special_offsets = dict([ (key, offsets[key]) for key in offsets.keys() - if offsets[key] >= 16 ]) - offmaps = {} - for offset in special_offsets.keys(): - offmaps[offset] = [] - - print('/* list all the special cases in unicode_%s_table */' % (label,)) - print('var unicode_%s_table = {' % (label,)) - outls = [] - for (key, val) in pairs: - if (type(val) == list): - ls = val - ls = [ str(val) for val in ls ] - outls.append('%s: [ %s ]' % (str(key), ','.join(ls))) - continue - offset = key-val - if (offset in offmaps): - offmaps[offset].append(key) - continue - outls.append('%s: %s' % (str(key), str(val))) - rowcount = 0 - for ix in range(len(outls)): - val = outls[ix] - islast = (ix == len(outls)-1) - if (rowcount >= 5): - print() - rowcount = 0 - print(val+('' if islast else ','), end=' ') - rowcount += 1 - print() - print('};') - - if (not offmaps): - print() - return - - print('/* add all the regular cases to unicode_%s_table */' % (label,)) - print('(function() {') - print(' var ls, ix, val;') - print(' var map = unicode_%s_table;' % (label,)) - ls = list(offmaps.keys()) - ls.sort() - for offset in ls: - if (offset < 0): - op = '+' + str(-offset) - else: - op = '-' + str(offset) - # Divide the list of values into a list of runs (which we can - # do with a simple for loop) and a list of leftovers (which - # we have to do one by one). - # The minlength value of 16 is about optimal (by experiment) - (runs, extras) = find_runs(offmaps[offset], 16) - for (start, end, jump) in runs: - print(' for (val=%s; val<=%s; val+=%s) {' % (str(start), str(end), str(jump))) - print(' map[val] = val%s;' % (op,)) - print(' }') - if (extras and len(extras) < 3): - # It's more efficient to dump a few extras as single lines. - for val in extras: - print(' map[%d] = %d;' % (val, val-offset)) - elif (extras): - # But if we have a lot of extras, we should loop over an array. - print(' ls = [') - rowcount = 0 - for val in extras: - if (rowcount >= 8): - print() - rowcount = 0 - print('%s,' % (str(val)), end=' ') - rowcount += 1 - print() - print(' ];') - print(' for (ix=0; ix<%d; ix++) {' % (len(extras),)) - print(' val = ls[ix];') - print(' map[val] = val%s;' % (op,)) - print(' }') - print('})();') - - print() - -def generate_js_table_decomp(label, table, runmin=16): - keys = list(table.keys()) - keys.sort() - (runs, extras) = find_runs(keys, runmin, True) - - print('/* list all the special cases in unicode_%s_table */' % (label,)) - print('var unicode_%s_table = {' % (label,)) - outls = [] - for key in extras: - val = table[key] - if (type(val) == list): - ls = val - ls = [ str(val) for val in ls ] - outls.append('%s: [ %s ]' % (str(key), ','.join(ls))) - continue - outls.append('%s: %s' % (str(key), str(val))) - rowcount = 0 - for ix in range(len(outls)): - val = outls[ix] - islast = (ix == len(outls)-1) - if (rowcount >= 5): - print() - rowcount = 0 - print(val+('' if islast else ','), end=' ') - rowcount += 1 - print() - print('};') - - if (not runs): - print() - return - - print('/* add all the regular cases to unicode_%s_table */' % (label,)) - print('(function() {') - print(' var ls, ix, val;') - print(' var map = unicode_%s_table;' % (label,)) - for (start, end, jump) in runs: - print(' ls = [') - rowcount = 0 - for ix in range(start, end+1): - val = table[ix] - if (rowcount >= 8): - print() - rowcount = 0 - if (type(val) == list): - val = [ str(ent) for ent in val ] - ent = '[' + ','.join(val) + ']' - else: - ent = str(val) - print('%s,' % (ent), end=' ') - rowcount += 1 - print() - print(' ];') - print(' for (ix=0; ix<%d; ix++) {' % (end-start+1,)) - print(' val = ls[ix];') - print(' map[ix+%d] = val;' % (start,)) - print(' }') - - print('})();') - - print() - -if (output == 'js'): - # javascript code output - print('/* These tables were generated by casemap.py. */') - print('/* Derived from Unicode data files, Unicode version %s. */' % (unicode_version,)) - print() - - tablelist = [ (upcasetable, 'upper'), - (downcasetable, 'lower') ] - for (map, label) in tablelist: - keys = list(map.keys()) - keys.sort() - - pairs = [] - offsets = {} - for key in keys: - if (key not in map): - continue - ls = map[key] - if (len(ls) != 1): - pairs.append( (key, ls) ) - continue - val = ls[0] - offset = key-val - offsets[offset] = offsets.get(offset, 0) + 1 - pairs.append( (key, val) ) - - generate_js_table_case(label, pairs, offsets) - - map = {} - for key in upcasetable.keys(): - if (key not in titlecasetable): - map[key] = key - for key in titlecasetable.keys(): - if (titlecasetable[key] != upcasetable.get(key)): - val = titlecasetable[key] - if (len(val) == 1): - val = val[0] - map[key] = val - generate_js_table_decomp('title', map) - - map = {} - for (key, val) in decomptable.items(): - if (len(val) == 1): - val = val[0] - map[key] = val - generate_js_table_decomp('decomp', map, 16) - generate_js_table_decomp('combin', combintable, 100) - - print('/* list all of unicode_compo_table */') - print('var unicode_compo_table = {') - ls = list(compotable.keys()) - ls.sort() - for key in ls: - islast = (key == ls[-1]) - subls = list(compotable[key].items()) - subls.sort() - val = ', '.join([ '%d:%d' % (subkey, subval) for (subkey, subval) in subls ]) - print(' %d: { %s }%s' % (key, val, ('' if islast else ','))) - print('};') - - print('/* End of tables generated by casemap.py. */') diff --git a/textworld/thirdparty/glulx/cheapglk/cgblorb.c b/textworld/thirdparty/glulx/cheapglk/cgblorb.c deleted file mode 100644 index 7e8f972f..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgblorb.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "glk.h" -#include "gi_blorb.h" - -/* We'd like to be able to deal with game files in Blorb files, even - if we never load a sound or image. We'd also like to be able to - deal with Data chunks. So we're willing to set a map here. */ - -static giblorb_map_t *blorbmap = 0; /* NULL */ - -giblorb_err_t giblorb_set_resource_map(strid_t file) -{ - giblorb_err_t err; - - err = giblorb_create_map(file, &blorbmap); - if (err) { - blorbmap = 0; /* NULL */ - return err; - } - - return giblorb_err_None; -} - -giblorb_map_t *giblorb_get_resource_map() -{ - return blorbmap; -} diff --git a/textworld/thirdparty/glulx/cheapglk/cgdate.c b/textworld/thirdparty/glulx/cheapglk/cgdate.c deleted file mode 100644 index 69f8fb07..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgdate.c +++ /dev/null @@ -1,404 +0,0 @@ -#include -#include -#include -#include -#include -#include "glk.h" -#include "cheapglk.h" - -#ifdef GLK_MODULE_DATETIME - -#ifdef NO_TIMEGM_AVAIL -extern time_t timegm(struct tm *tm); -#endif /* NO_TIMEGM_AVAIL */ - -#ifdef WIN32 -/* Some alterations to make this code work on Windows, in case that's helpful - to you. */ -#define mktime gli_mktime -extern time_t timegm(struct tm *tm); -extern time_t gli_mktime(struct tm *timeptr); -static struct tm *gmtime_r(const time_t *timer, struct tm *result); -static struct tm *localtime_r(const time_t *timer, struct tm *result); -#endif /* WIN32 */ - - -/* Copy a POSIX tm structure to a glkdate. */ -static void gli_date_from_tm(glkdate_t *date, struct tm *tm) -{ - date->year = 1900 + tm->tm_year; - date->month = 1 + tm->tm_mon; - date->day = tm->tm_mday; - date->weekday = tm->tm_wday; - date->hour = tm->tm_hour; - date->minute = tm->tm_min; - date->second = tm->tm_sec; -} - -/* Copy a glkdate to a POSIX tm structure. - This is used in the "glk_date_to_..." functions, which are supposed - to normalize the glkdate. We're going to rely on the mktime() / - timegm() functions to do that -- except they don't handle microseconds. - So we'll have to do that normalization here, adjust the tm_sec value, - and return the normalized number of microseconds. -*/ -static glsi32 gli_date_to_tm(glkdate_t *date, struct tm *tm) -{ - glsi32 microsec; - - bzero(tm, sizeof(*tm)); - tm->tm_year = date->year - 1900; - tm->tm_mon = date->month - 1; - tm->tm_mday = date->day; - tm->tm_wday = date->weekday; - tm->tm_hour = date->hour; - tm->tm_min = date->minute; - tm->tm_sec = date->second; - microsec = date->microsec; - - if (microsec >= 1000000) { - tm->tm_sec += (microsec / 1000000); - microsec = microsec % 1000000; - } - else if (microsec < 0) { - microsec = -1 - microsec; - tm->tm_sec -= (1 + microsec / 1000000); - microsec = 999999 - (microsec % 1000000); - } - - return microsec; -} - -/* Convert a Unix timestamp, along with a microseconds value, to - a glktimeval. -*/ -static void gli_timestamp_to_time(time_t timestamp, glsi32 microsec, - glktimeval_t *time) -{ - if (sizeof(timestamp) <= 4) { - /* This platform has 32-bit time, but we can't do anything - about that. Hope it's not 2038 yet. */ - if (timestamp >= 0) - time->high_sec = 0; - else - time->high_sec = -1; - time->low_sec = timestamp; - } - else { - /* The cast to int64_t shouldn't be necessary, but it - suppresses a pointless warning in the 32-bit case. - (Remember that we won't be executing this line in the - 32-bit case.) */ - time->high_sec = (((int64_t)timestamp) >> 32) & 0xFFFFFFFF; - time->low_sec = timestamp & 0xFFFFFFFF; - } - - time->microsec = microsec; -} - -/* Divide a Unix timestamp by a (positive) value. */ -static glsi32 gli_simplify_time(time_t timestamp, glui32 factor) -{ - /* We want to round towards negative infinity, which takes a little - bit of fussing. */ - if (timestamp >= 0) { - return timestamp / (time_t)factor; - } - else { - return -1 - (((time_t)-1 - timestamp) / (time_t)factor); - } -} - -void glk_current_time(glktimeval_t *time) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL)) { - gli_timestamp_to_time(0, 0, time); - gli_strict_warning("current_time: gettimeofday() failed."); - return; - } - - gli_timestamp_to_time(tv.tv_sec, tv.tv_usec, time); -} - -glsi32 glk_current_simple_time(glui32 factor) -{ - struct timeval tv; - - if (factor == 0) { - gli_strict_warning("current_simple_time: factor cannot be zero."); - return 0; - } - - if (gettimeofday(&tv, NULL)) { - gli_strict_warning("current_simple_time: gettimeofday() failed."); - return 0; - } - - return gli_simplify_time(tv.tv_sec, factor); -} - -void glk_time_to_date_utc(glktimeval_t *time, glkdate_t *date) -{ - time_t timestamp; - struct tm tm; - - timestamp = time->low_sec; - if (sizeof(timestamp) > 4) { - timestamp += ((int64_t)time->high_sec << 32); - } - - gmtime_r(×tamp, &tm); - - gli_date_from_tm(date, &tm); - date->microsec = time->microsec; -} - -void glk_time_to_date_local(glktimeval_t *time, glkdate_t *date) -{ - time_t timestamp; - struct tm tm; - - timestamp = time->low_sec; - if (sizeof(timestamp) > 4) { - timestamp += ((int64_t)time->high_sec << 32); - } - - localtime_r(×tamp, &tm); - - gli_date_from_tm(date, &tm); - date->microsec = time->microsec; -} - -void glk_simple_time_to_date_utc(glsi32 time, glui32 factor, - glkdate_t *date) -{ - time_t timestamp = (time_t)time * factor; - struct tm tm; - - gmtime_r(×tamp, &tm); - - gli_date_from_tm(date, &tm); - date->microsec = 0; -} - -void glk_simple_time_to_date_local(glsi32 time, glui32 factor, - glkdate_t *date) -{ - time_t timestamp = (time_t)time * factor; - struct tm tm; - - localtime_r(×tamp, &tm); - - gli_date_from_tm(date, &tm); - date->microsec = 0; -} - -void glk_date_to_time_utc(glkdate_t *date, glktimeval_t *time) -{ - time_t timestamp; - struct tm tm; - glsi32 microsec; - - microsec = gli_date_to_tm(date, &tm); - /* The timegm function is not standard POSIX. If it's not available - on your platform, try setting the env var "TZ" to "", calling - mktime(), and then resetting "TZ". */ - tm.tm_isdst = 0; - timestamp = timegm(&tm); - - gli_timestamp_to_time(timestamp, microsec, time); -} - -void glk_date_to_time_local(glkdate_t *date, glktimeval_t *time) -{ - time_t timestamp; - struct tm tm; - glsi32 microsec; - - microsec = gli_date_to_tm(date, &tm); - tm.tm_isdst = -1; - timestamp = mktime(&tm); - - gli_timestamp_to_time(timestamp, microsec, time); -} - -glsi32 glk_date_to_simple_time_utc(glkdate_t *date, glui32 factor) -{ - time_t timestamp; - struct tm tm; - - if (factor == 0) { - gli_strict_warning("date_to_simple_time_utc: factor cannot be zero."); - return 0; - } - - gli_date_to_tm(date, &tm); - /* The timegm function is not standard POSIX. If it's not available - on your platform, try setting the env var "TZ" to "", calling - mktime(), and then resetting "TZ". */ - tm.tm_isdst = 0; - timestamp = timegm(&tm); - - return gli_simplify_time(timestamp, factor); -} - -glsi32 glk_date_to_simple_time_local(glkdate_t *date, glui32 factor) -{ - time_t timestamp; - struct tm tm; - - if (factor == 0) { - gli_strict_warning("date_to_simple_time_local: factor cannot be zero."); - return 0; - } - - gli_date_to_tm(date, &tm); - tm.tm_isdst = -1; - timestamp = mktime(&tm); - - return gli_simplify_time(timestamp, factor); -} - -#ifdef NO_TIMEGM_AVAIL -/* If you have no timegm() function, you can #define NO_TIMEGM_AVAIL to - get this definition. */ - -time_t timegm(struct tm *tm) -{ - time_t res; - char *origtz; - - origtz = getenv("TZ"); - setenv("TZ", "", 1); - tzset(); - res = mktime(tm); - if (origtz) - setenv("TZ", origtz, 1); - else - unsetenv("TZ"); - tzset(); - - return res; -} - -#endif /* NO_TIMEGM_AVAIL */ - - -#ifdef WIN32 -/* Windows needs wrappers for time functions to handle pre-epoch dates */ - -/* 31,557,600 seconds per year */ -#define OFFSET84 ((glui32) 0x9E009580) /* 1902-1951 => 1986-2035, +84 years */ -#define OFFSET28 ((glui32) 0x34AADC80) /* 1952-1969 => 1980-1997, +28 years */ - -time_t gli_mktime (struct tm * timeptr) -{ - glui32 offset = 0; - glui32 adjust = 0; - - if (timeptr->tm_year < 70 && timeptr->tm_year > 1) - { - if (timeptr->tm_year < 52) - { - offset = OFFSET84; - adjust = 84; - } - else - { - offset = OFFSET28; - adjust = 28; - } - } - timeptr->tm_year += adjust; - time_t ret = mktime(timeptr) - offset; - timeptr->tm_year -= adjust; - - return ret; -} - -time_t timegm(struct tm *tm) -{ - time_t answer; - putenv("TZ=UTC"); - tzset(); - answer=mktime(tm); - putenv("TZ="); - tzset(); - return answer; -} - -#define UTC_1901 (-2145916801) /* Dec 31, 1901 at 23:59:59 UTC */ -#define UTC_1951 (-568080001) /* Dec 31, 1951 at 23:59:59 UTC */ - -static struct tm * gmtime_r(const time_t *timer, struct tm *result) -{ - time_t eval = *timer; - glui32 adjust = 0; - - if (eval < 0 && eval > UTC_1901) - { - if (eval > UTC_1951) - { - eval += OFFSET28; - adjust = 28; - } - else - { - eval += OFFSET84; - adjust = 84; - } - } - - struct tm *gm = gmtime(&eval); - - if (!gm) - { - time_t zero = 0; - gm = gmtime(&zero); - adjust = 0; - } - - *result = *gm; - result->tm_year -= adjust; - - return result; -} - -static struct tm * localtime_r(const time_t *timer, struct tm *result) -{ - time_t eval = *timer; - glui32 adjust = 0; - - if (eval < 0 && eval > UTC_1901) - { - if (eval > UTC_1951) - { - eval += OFFSET28; - adjust = 28; - } - else - { - eval += OFFSET84; - adjust = 84; - } - } - - struct tm *loc = localtime(&eval); - - if (!loc) - { - time_t zero = 0; - loc = localtime(&zero); - adjust = 0; - } - - *result = *loc; - result->tm_year -= adjust; - - return result; -} -#endif /* WIN32 */ - -#endif /* GLK_MODULE_DATETIME */ diff --git a/textworld/thirdparty/glulx/cheapglk/cgfref.c b/textworld/thirdparty/glulx/cheapglk/cgfref.c deleted file mode 100644 index 0094bd42..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgfref.c +++ /dev/null @@ -1,364 +0,0 @@ -#include -#include -#include -#include /* for unlink() */ -#include /* for stat() */ -#include "glk.h" -#include "cheapglk.h" - -/* This file implements filerefs as they work in a stdio system: a - fileref contains a pathname, a text/binary flag, and a file - type. -*/ - -/* Linked list of all filerefs */ -static fileref_t *gli_filereflist = NULL; - -#define BUFLEN (256) -static char workingdir[BUFLEN] = "."; - -fileref_t *gli_new_fileref(char *filename, glui32 usage, glui32 rock) -{ - fileref_t *fref = (fileref_t *)malloc(sizeof(fileref_t)); - if (!fref) - return NULL; - - fref->magicnum = MAGIC_FILEREF_NUM; - fref->rock = rock; - - fref->filename = malloc(1 + strlen(filename)); - strcpy(fref->filename, filename); - - fref->textmode = ((usage & fileusage_TextMode) != 0); - fref->filetype = (usage & fileusage_TypeMask); - - fref->prev = NULL; - fref->next = gli_filereflist; - gli_filereflist = fref; - if (fref->next) { - fref->next->prev = fref; - } - - if (gli_register_obj) - fref->disprock = (*gli_register_obj)(fref, gidisp_Class_Fileref); - else - fref->disprock.ptr = NULL; - - return fref; -} - -void gli_delete_fileref(fileref_t *fref) -{ - fileref_t *prev, *next; - - if (gli_unregister_obj) { - (*gli_unregister_obj)(fref, gidisp_Class_Fileref, fref->disprock); - fref->disprock.ptr = NULL; - } - - fref->magicnum = 0; - - if (fref->filename) { - free(fref->filename); - fref->filename = NULL; - } - - prev = fref->prev; - next = fref->next; - fref->prev = NULL; - fref->next = NULL; - - if (prev) - prev->next = next; - else - gli_filereflist = next; - if (next) - next->prev = prev; - - free(fref); -} - -void glk_fileref_destroy(fileref_t *fref) -{ - if (!fref) { - gli_strict_warning("fileref_destroy: invalid ref"); - return; - } - gli_delete_fileref(fref); -} - -static char *gli_suffix_for_usage(glui32 usage) -{ - switch (usage & fileusage_TypeMask) { - case fileusage_Data: - return ".glkdata"; - case fileusage_SavedGame: - return ".glksave"; - case fileusage_Transcript: - case fileusage_InputRecord: - return ".txt"; - default: - return ""; - } -} - -frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock) -{ - char filename[BUFLEN]; - fileref_t *fref; - - sprintf(filename, "/tmp/glktempfref-XXXXXX"); - mkstemp(filename); - - fref = gli_new_fileref(filename, usage, rock); - if (!fref) { - gli_strict_warning("fileref_create_temp: unable to create fileref."); - return NULL; - } - - return fref; -} - -frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t oldfref, - glui32 rock) -{ - fileref_t *fref; - - if (!oldfref) { - gli_strict_warning("fileref_create_from_fileref: invalid ref"); - return NULL; - } - - fref = gli_new_fileref(oldfref->filename, usage, rock); - if (!fref) { - gli_strict_warning("fileref_create_from_fileref: unable to create fileref."); - return NULL; - } - - return fref; -} - -frefid_t glk_fileref_create_by_name(glui32 usage, char *name, - glui32 rock) -{ - fileref_t *fref; - char buf[BUFLEN]; - char buf2[2*BUFLEN+10]; - int len; - char *cx; - char *suffix; - - /* The new spec recommendations: delete all characters in the - string "/\<>:|?*" (including quotes). Truncate at the first - period. Change to "null" if there's nothing left. Then append - an appropriate suffix: ".glkdata", ".glksave", ".txt". - */ - - for (cx=name, len=0; (*cx && *cx!='.' && len': - case '<': - case ':': - case '|': - case '?': - case '*': - break; - default: - buf[len++] = *cx; - } - } - buf[len] = '\0'; - - if (len == 0) { - strcpy(buf, "null"); - len = strlen(buf); - } - - suffix = gli_suffix_for_usage(usage); - sprintf(buf2, "%s/%s%s", workingdir, buf, suffix); - - fref = gli_new_fileref(buf2, usage, rock); - if (!fref) { - gli_strict_warning("fileref_create_by_name: unable to create fileref."); - return NULL; - } - - return fref; -} - -frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, - glui32 rock) -{ - fileref_t *fref; - char buf[BUFLEN]; - char newbuf[2*BUFLEN+10]; - char *res; - char *cx; - int val, gotdot; - char *prompt, *prompt2; - - switch (usage & fileusage_TypeMask) { - case fileusage_SavedGame: - prompt = "Enter saved game"; - break; - case fileusage_Transcript: - prompt = "Enter transcript file"; - break; - case fileusage_InputRecord: - prompt = "Enter command record file"; - break; - case fileusage_Data: - default: - prompt = "Enter data file"; - break; - } - - if (fmode == filemode_Read) - prompt2 = "to load"; - else - prompt2 = "to store"; - - printf("%s %s: ", prompt, prompt2); - - res = fgets(buf, BUFLEN-1, stdin); - if (!res) { - printf("\n\n"); - glk_exit(); - } - - /* Trim whitespace from end and beginning. */ - - val = strlen(buf); - while (val - && (buf[val-1] == '\n' - || buf[val-1] == '\r' - || buf[val-1] == ' ')) - val--; - buf[val] = '\0'; - - for (cx = buf; *cx == ' '; cx++) { } - - val = strlen(cx); - if (!val) { - /* The player just hit return. It would be nice to provide a - default value, but this implementation is too cheap. */ - return NULL; - } - - if (cx[0] == '/') - strcpy(newbuf, cx); - else - sprintf(newbuf, "%s/%s", workingdir, cx); - - /* If there is no dot-suffix, add a standard one. */ - val = strlen(newbuf); - gotdot = FALSE; - while (val && (buf[val-1] != '/')) { - if (buf[val-1] == '.') { - gotdot = TRUE; - break; - } - val--; - } - if (!gotdot) { - char *suffix = gli_suffix_for_usage(usage); - strcat(newbuf, suffix); - } - - fref = gli_new_fileref(newbuf, usage, rock); - if (!fref) { - gli_strict_warning("fileref_create_by_prompt: unable to create fileref."); - return NULL; - } - - return fref; -} - -frefid_t glk_fileref_iterate(fileref_t *fref, glui32 *rock) -{ - if (!fref) { - fref = gli_filereflist; - } - else { - fref = fref->next; - } - - if (fref) { - if (rock) - *rock = fref->rock; - return fref; - } - - if (rock) - *rock = 0; - return NULL; -} - -glui32 glk_fileref_get_rock(fileref_t *fref) -{ - if (!fref) { - gli_strict_warning("fileref_get_rock: invalid ref."); - return 0; - } - - return fref->rock; -} - -glui32 glk_fileref_does_file_exist(fileref_t *fref) -{ - struct stat buf; - - if (!fref) { - gli_strict_warning("fileref_does_file_exist: invalid ref"); - return FALSE; - } - - /* This is sort of Unix-specific, but probably any stdio library - will implement at least this much of stat(). */ - - if (stat(fref->filename, &buf)) - return 0; - - if (S_ISREG(buf.st_mode)) - return 1; - else - return 0; -} - -void glk_fileref_delete_file(fileref_t *fref) -{ - if (!fref) { - gli_strict_warning("fileref_delete_file: invalid ref"); - return; - } - - /* If you don't have the unlink() function, obviously, change it - to whatever file-deletion function you do have. */ - - unlink(fref->filename); -} - -/* This should only be called from startup code. */ -void glkunix_set_base_file(char *filename) -{ - int ix; - - for (ix=strlen(filename)-1; ix >= 0; ix--) - if (filename[ix] == '/') - break; - - if (ix >= 0) { - /* There is a slash. */ - strncpy(workingdir, filename, ix); - workingdir[ix] = '\0'; - ix++; - } - else { - /* No slash, just a filename. */ - ix = 0; - } -} - diff --git a/textworld/thirdparty/glulx/cheapglk/cggestal.c b/textworld/thirdparty/glulx/cheapglk/cggestal.c deleted file mode 100644 index 61bfcbfb..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cggestal.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include "glk.h" -#include "cheapglk.h" - -glui32 glk_gestalt(glui32 id, glui32 val) -{ - return glk_gestalt_ext(id, val, NULL, 0); -} - -glui32 glk_gestalt_ext(glui32 id, glui32 val, glui32 *arr, - glui32 arrlen) -{ - switch (id) { - - case gestalt_Version: - /* This implements Glk spec version 0.7.5. */ - return 0x00000705; - - case gestalt_LineInput: - if (val >= 32 && val < 127) - return TRUE; - else - return FALSE; - - case gestalt_CharInput: - if (val >= 32 && val < 127) - return TRUE; - else if (val == keycode_Return) - return TRUE; - else { - /* If we're doing UTF-8 input, we can input any Unicode - character. Except control characters. */ - if (gli_utf8input) { - if (val >= 160 && val < 0x200000) - return TRUE; - } - /* If not, we can't accept anything non-ASCII */ - return FALSE; - } - - case gestalt_CharOutput: - if (val >= 32 && val < 127) { - if (arr && arrlen >= 1) - arr[0] = 1; - return gestalt_CharOutput_ExactPrint; - } - else { - /* cheaply, we don't do any translation of printed - characters, so the output is always one character - even if it's wrong. */ - if (arr && arrlen >= 1) - arr[0] = 1; - /* If we're doing UTF-8 output, we can print any Unicode - character. Except control characters. */ - if (gli_utf8output) { - if (val >= 160 && val < 0x200000) - return gestalt_CharOutput_ExactPrint; - } - return gestalt_CharOutput_CannotPrint; - } - - case gestalt_MouseInput: - return FALSE; - - case gestalt_Timer: - return FALSE; - - case gestalt_Graphics: - case gestalt_GraphicsTransparency: - case gestalt_GraphicsCharInput: - return FALSE; - - case gestalt_DrawImage: - return FALSE; - - case gestalt_Unicode: -#ifdef GLK_MODULE_UNICODE - return TRUE; -#else - return FALSE; -#endif /* GLK_MODULE_UNICODE */ - - case gestalt_UnicodeNorm: -#ifdef GLK_MODULE_UNICODE_NORM - return TRUE; -#else - return FALSE; -#endif /* GLK_MODULE_UNICODE_NORM */ - - case gestalt_Sound: - case gestalt_SoundVolume: - case gestalt_SoundNotify: - case gestalt_SoundMusic: - return FALSE; - case gestalt_Sound2: - /* Sound2 implies all the above sound options. But for - cheapglk, they're all false. */ - return FALSE; - - case gestalt_LineInputEcho: - return FALSE; - - case gestalt_LineTerminators: - case gestalt_LineTerminatorKey: - return FALSE; - - case gestalt_DateTime: - return TRUE; - - case gestalt_ResourceStream: - return TRUE; - - default: - return 0; - - } -} - diff --git a/textworld/thirdparty/glulx/cheapglk/cgmisc.c b/textworld/thirdparty/glulx/cheapglk/cgmisc.c deleted file mode 100644 index bd031dd9..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgmisc.c +++ /dev/null @@ -1,394 +0,0 @@ -#include -#include -#include -#include "glk.h" -#include "cheapglk.h" -#include "agent.h" - -static unsigned char char_tolower_table[256]; -static unsigned char char_toupper_table[256]; - -gidispatch_rock_t (*gli_register_obj)(void *obj, glui32 objclass) = NULL; -void (*gli_unregister_obj)(void *obj, glui32 objclass, - gidispatch_rock_t objrock) = NULL; -gidispatch_rock_t (*gli_register_arr)(void *array, glui32 len, - char *typecode) = NULL; -void (*gli_unregister_arr)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock) = NULL; - -/* This is needed to redisplay prompts properly after debug output. - Not interesting. */ -static int debug_output_counter = 0; - -static int perform_debug_command(char *cmd); - -void gli_initialize_misc() -{ - int ix; - int res; - - /* Initialize the to-uppercase and to-lowercase tables. These should - *not* be localized to a platform-native character set! They are - intended to work on Latin-1 data, and the code below correctly - sets up the tables for that character set. */ - - for (ix=0; ix<256; ix++) { - char_toupper_table[ix] = ix; - char_tolower_table[ix] = ix; - } - for (ix=0; ix<256; ix++) { - if (ix >= 'A' && ix <= 'Z') { - res = ix + ('a' - 'A'); - } - else if (ix >= 0xC0 && ix <= 0xDE && ix != 0xD7) { - res = ix + 0x20; - } - else { - res = 0; - } - if (res) { - char_tolower_table[ix] = res; - char_toupper_table[res] = ix; - } - } - -} - -void glk_exit() -{ - if (gli_debugger) - gidebug_announce_cycle(gidebug_cycle_End); - agent_exit(); - exit(0); -} - -void glk_set_interrupt_handler(void (*func)(void)) -{ - /* This cheap library doesn't understand interrupts. */ -} - -unsigned char glk_char_to_lower(unsigned char ch) -{ - return char_tolower_table[ch]; -} - -unsigned char glk_char_to_upper(unsigned char ch) -{ - return char_toupper_table[ch]; -} - -void glk_select(event_t *event) -{ - window_t *win = gli_window_get(); - - gli_event_clearevent(event); - - if (gli_debugger) { - gidebug_announce_cycle(gidebug_cycle_InputWait); - if (debug_output_counter) { - debug_output_counter = 0; - printf(">"); - } - } - fflush(stdout); - - if (!win || !(win->char_request || win->line_request)) { - /* No input requests. This is legal, but a pity, because the - correct behavior is to wait forever. Bye bye. */ - while (1) { - getchar(); - } - } - - if (win->char_request) { - char buf[256]; - glui32 kval; - int len; - - agent_get_output(buf, 256); - - if (!gli_utf8input) { - kval = buf[0]; - } - else { - int val; - val = strlen(buf); - if (val && (buf[val-1] == '\n' || buf[val-1] == '\r')) - val--; - len = gli_parse_utf8((unsigned char *)buf, val, &kval, 1); - if (!len) - kval = '\n'; - } - - if (kval == '\r' || kval == '\n') { - kval = keycode_Return; - } - else { - if (!win->char_request_uni && kval >= 0x100) - kval = '?'; - } - - win->char_request = FALSE; - event->type = evtype_CharInput; - event->win = win; - event->val1 = kval; - - } - else { - /* line_request */ - char buf[256]; - glui32 ix; - - glui32 val = agent_get_output(buf, 256); - - if (val && (buf[val-1] == '\n' || buf[val-1] == '\r')) - val--; - - if (!gli_utf8input) { - if (val > win->linebuflen) - val = win->linebuflen; - if (!win->line_request_uni) { - memcpy(win->linebuf, buf, val); - } - else { - glui32 *destbuf = (glui32 *)win->linebuf; - for (ix=0; ix win->linebuflen) - val = win->linebuflen; - if (!win->line_request_uni) { - unsigned char *destbuf = (unsigned char *)win->linebuf; - for (ix=0; ix= 0x100) - kval = '?'; - destbuf[ix] = kval; - } - } - else { - /* We ought to perform Unicode Normalization Form C here. */ - glui32 *destbuf = (glui32 *)win->linebuf; - for (ix=0; ixline_request_uni) { - if (win->echostr) { - gli_stream_echo_line(win->echostr, win->linebuf, val); - } - } - else { - if (win->echostr) { - gli_stream_echo_line_uni(win->echostr, win->linebuf, val); - } - } - - if (gli_unregister_arr) { - if (!win->line_request_uni) - (*gli_unregister_arr)(win->linebuf, win->linebuflen, - "&+#!Cn", win->inarrayrock); - else - (*gli_unregister_arr)(win->linebuf, win->linebuflen, - "&+#!Iu", win->inarrayrock); - } - - win->line_request = FALSE; - win->line_request_uni = FALSE; - win->linebuf = NULL; - event->type = evtype_LineInput; - event->win = win; - event->val1 = val; - } - - if (gli_debugger) - gidebug_announce_cycle(gidebug_cycle_InputAccept); -} - -void glk_select_poll(event_t *event) -{ - gli_event_clearevent(event); - - /* This only checks for timer events at the moment, and we don't - support any, so I guess this is a pretty simple function. */ -} - -void glk_tick() -{ - /* Do nothing. */ -} - -void glk_request_timer_events(glui32 millisecs) -{ - /* Don't make me laugh. */ -} - -void gidispatch_set_object_registry( - gidispatch_rock_t (*regi)(void *obj, glui32 objclass), - void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock)) -{ - window_t *win; - stream_t *str; - fileref_t *fref; - - gli_register_obj = regi; - gli_unregister_obj = unregi; - - if (gli_register_obj) { - /* It's now necessary to go through all existing objects, and register - them. */ - for (win = glk_window_iterate(NULL, NULL); - win; - win = glk_window_iterate(win, NULL)) { - win->disprock = (*gli_register_obj)(win, gidisp_Class_Window); - } - for (str = glk_stream_iterate(NULL, NULL); - str; - str = glk_stream_iterate(str, NULL)) { - str->disprock = (*gli_register_obj)(str, gidisp_Class_Stream); - } - for (fref = glk_fileref_iterate(NULL, NULL); - fref; - fref = glk_fileref_iterate(fref, NULL)) { - fref->disprock = (*gli_register_obj)(fref, gidisp_Class_Fileref); - } - } -} - -void gidispatch_set_retained_registry( - gidispatch_rock_t (*regi)(void *array, glui32 len, char *typecode), - void (*unregi)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock)) -{ - gli_register_arr = regi; - gli_unregister_arr = unregi; -} - -gidispatch_rock_t gidispatch_get_objrock(void *obj, glui32 objclass) -{ - switch (objclass) { - case gidisp_Class_Window: - return ((window_t *)obj)->disprock; - case gidisp_Class_Stream: - return ((stream_t *)obj)->disprock; - case gidisp_Class_Fileref: - return ((fileref_t *)obj)->disprock; - default: { - gidispatch_rock_t dummy; - dummy.num = 0; - return dummy; - } - } -} - -void gidispatch_set_autorestore_registry( - long (*locatearr)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock, int *elemsizeref), - gidispatch_rock_t (*restorearr)(long bufkey, glui32 len, - char *typecode, void **arrayref)) -{ - /* CheapGlk is not able to serialize its UI state. Therefore, it - does not have the capability of autosaving and autorestoring. - Therefore, it will never call these hooks. Therefore, we ignore - them and do nothing here. */ -} - -static int perform_debug_command(char *cmd) -{ - char *allocbuf = NULL; - int res = 1; - - if (!gli_utf8input) { - /* The string is Latin-1. We should convert to UTF-8. We do - this in a very lazy way: alloc the largest possible buffer. */ - int len = 4*strlen(cmd)+4; - allocbuf = malloc(len); - char *ptr = allocbuf; - int count = 0; - while (*cmd) { - count += gli_encode_utf8(*cmd, ptr+count, len-count); - cmd++; - } - *(ptr+count) = '\0'; - cmd = allocbuf; - } - - int val = strlen(cmd); - if (val && (cmd[val-1] == '\n' || cmd[val-1] == '\r')) { - cmd[val-1] = '\0'; - } - - res = gidebug_perform_command(cmd); - - if (allocbuf) - free(allocbuf); - - return res; -} - -#if GIDEBUG_LIBRARY_SUPPORT - -void gidebug_output(char *text) -{ - /* Send a line of text to the "debug console", if the user has - requested debugging mode. */ - /* (The text is UTF-8 whether or not the library output has requested - that encoding. The user will just have to cope.) */ - if (gli_debugger) { - printf("Debug: %s\n", text); - debug_output_counter++; - } -} - -/* Block and wait for debug commands. The library will accept debug commands - until gidebug_perform_command() returns nonzero. - - This behaves a lot like glk_select(), except that it only handles debug - input, not any of the standard event types. -*/ -void gidebug_pause() -{ - if (!gli_debugger) { - return; - } - - gidebug_announce_cycle(gidebug_cycle_DebugPause); - debug_output_counter = 0; - printf(">>"); - fflush(stdout); - - while (1) { - char buf[256]; - char *res; - int unpause; - - res = fgets(buf, 255, stdin); - if (!res) { - printf("\n\n"); - break; - } - - /* The slash is optional at the beginning of a line grabbed this - way. */ - if (res[0] == '/') - res++; - - unpause = perform_debug_command(res); - if (unpause) { - debug_output_counter = 0; - break; - } - - debug_output_counter = 0; - printf(">>"); - } - - gidebug_announce_cycle(gidebug_cycle_DebugUnpause); -} - -#endif /* GIDEBUG_LIBRARY_SUPPORT */ diff --git a/textworld/thirdparty/glulx/cheapglk/cgschan.c b/textworld/thirdparty/glulx/cheapglk/cgschan.c deleted file mode 100644 index a8cb69f3..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgschan.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include "glk.h" -#include "cheapglk.h" - -/* The whole sound-channel situation is very simple for us; - we don't support it. */ - -#ifdef GLK_MODULE_SOUND - -schanid_t glk_schannel_create(glui32 rock) -{ - return NULL; -} - -void glk_schannel_destroy(schanid_t chan) -{ -} - -schanid_t glk_schannel_iterate(schanid_t chan, glui32 *rockptr) -{ - if (rockptr) - *rockptr = 0; - return NULL; -} - -glui32 glk_schannel_get_rock(schanid_t chan) -{ - gli_strict_warning("schannel_get_rock: invalid id."); - return 0; -} - -glui32 glk_schannel_play(schanid_t chan, glui32 snd) -{ - gli_strict_warning("schannel_play: invalid id."); - return 0; -} - -glui32 glk_schannel_play_ext(schanid_t chan, glui32 snd, glui32 repeats, - glui32 notify) -{ - gli_strict_warning("schannel_play_ext: invalid id."); - return 0; -} - -void glk_schannel_stop(schanid_t chan) -{ - gli_strict_warning("schannel_stop: invalid id."); -} - -void glk_schannel_set_volume(schanid_t chan, glui32 vol) -{ - gli_strict_warning("schannel_set_volume: invalid id."); -} - -void glk_sound_load_hint(glui32 snd, glui32 flag) -{ - gli_strict_warning("schannel_sound_load_hint: invalid id."); -} - -#ifdef GLK_MODULE_SOUND2 - -schanid_t glk_schannel_create_ext(glui32 rock, glui32 volume) -{ - return NULL; -} - -glui32 glk_schannel_play_multi(schanid_t *chanarray, glui32 chancount, - glui32 *sndarray, glui32 soundcount, glui32 notify) -{ - if (chancount != soundcount) - gli_strict_warning("schannel_play_multi: channel count does not match sound count."); - return 0; -} - -void glk_schannel_pause(schanid_t chan) -{ - gli_strict_warning("schannel_pause: invalid id."); -} - -void glk_schannel_unpause(schanid_t chan) -{ - gli_strict_warning("schannel_unpause: invalid id."); -} - -void glk_schannel_set_volume_ext(schanid_t chan, glui32 vol, - glui32 duration, glui32 notify) -{ - gli_strict_warning("schannel_set_volume_ext: invalid id."); -} - -#endif /* GLK_MODULE_SOUND2 */ - -#endif /* GLK_MODULE_SOUND */ diff --git a/textworld/thirdparty/glulx/cheapglk/cgstream.c b/textworld/thirdparty/glulx/cheapglk/cgstream.c deleted file mode 100644 index 76869475..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgstream.c +++ /dev/null @@ -1,1676 +0,0 @@ -#include -#include -#include -#include "glk.h" -#include "cheapglk.h" -#include "gi_blorb.h" -#include "agent.h" - -/* This implements pretty much what any Glk implementation needs for - stream stuff. Memory streams, file streams (using stdio functions), - and window streams (which just print to stdout.) A fancier - implementation would need to change the window stream stuff, but - memory and file streams would stay the same. (Unless you're on a - wacky platform like the Mac and want to change stdio to native file - functions.) -*/ - -static stream_t *gli_streamlist = NULL; /* linked list of all streams */ -static stream_t *gli_currentstr = NULL; /* the current output stream */ - -/* Grouping of window functions, to ease overrides when necessary -*/ -void gli_put_char_window(stream_t *str, unsigned char ch) -{ - /* If you're going to convert Latin-1 to a different - character set, this is (a) place to do it. Only on the - putc(); not on the gli_put_char to echostr. */ - char buf[5]; - memset(buf, 0, 5); - glui32 len = 0; - - if (!gli_utf8output) { - buf[0] = ch; - len = 1; - } else { - len = gli_encode_utf8(ch, buf, 5); - } - agent_put_string(buf, len); -} - -void gli_put_char_uni_window(stream_t* str, glui32 ch) -{ - /* If you're going to convert Latin-1 to a different - character set, this is (a) place to do it. Only on the - putc(); not on the gli_put_char to echostr. */ - char buf[5]; - memset(buf, 0, 5); - glui32 len = 0; - - if (!gli_utf8output) { - buf[0] = (ch & 0xFF); - len = 1; - } else { - len = gli_encode_utf8(ch, buf, 5); - } - agent_put_string(buf, len); -} - -void gli_put_buffer_window(stream_t* str, char* buf, glui32 len) -{ - /* If you're going to convert Latin-1 to a different - character set, this is (a) place to do it. Only on the - fwrite(); not on the gli_put_buffer to echostr. */ - if (!gli_utf8output) { - agent_put_string(buf, len); - } - else { - for (glui32 lx=0; lxmagicnum = MAGIC_STREAM_NUM; - str->type = type; - str->rock = rock; - - str->unicode = FALSE; - str->isbinary = FALSE; - - str->win = NULL; - str->file = NULL; - str->lastop = 0; - str->buf = NULL; - str->bufptr = NULL; - str->bufend = NULL; - str->bufeof = NULL; - str->ubuf = NULL; - str->ubufptr = NULL; - str->ubufend = NULL; - str->ubufeof = NULL; - str->buflen = 0; - - str->readcount = 0; - str->writecount = 0; - str->readable = readable; - str->writable = writable; - - str->prev = NULL; - str->next = gli_streamlist; - gli_streamlist = str; - if (str->next) { - str->next->prev = str; - } - - if (gli_register_obj) - str->disprock = (*gli_register_obj)(str, gidisp_Class_Stream); - else - str->disprock.ptr = NULL; - - return str; -} - -void gli_delete_stream(stream_t *str) -{ - window_t *win; - stream_t *prev, *next; - - if (str == gli_currentstr) { - gli_currentstr = NULL; - } - - win = gli_window_get(); - if (win && win->echostr == str) { - win->echostr = NULL; - } - - str->magicnum = 0; - - switch (str->type) { - case strtype_Window: - /* nothing necessary; the window is already being closed */ - break; - case strtype_Memory: - if (gli_unregister_arr) { - /* This could be a char array or a glui32 array. */ - char *typedesc = (str->unicode ? "&+#!Iu" : "&+#!Cn"); - void *buf = (str->unicode ? (void*)str->ubuf : (void*)str->buf); - (*gli_unregister_arr)(buf, str->buflen, typedesc, - str->arrayrock); - } - break; - case strtype_Resource: - /* nothing necessary; the array belongs to gi_blorb.c. */ - break; - case strtype_File: - /* close the FILE */ - fclose(str->file); - str->file = NULL; - str->lastop = 0; - break; - } - - if (gli_unregister_obj) { - (*gli_unregister_obj)(str, gidisp_Class_Stream, str->disprock); - str->disprock.ptr = NULL; - } - - prev = str->prev; - next = str->next; - str->prev = NULL; - str->next = NULL; - - if (prev) - prev->next = next; - else - gli_streamlist = next; - if (next) - next->prev = prev; - - free(str); -} - -void gli_stream_fill_result(stream_t *str, stream_result_t *result) -{ - if (!result) - return; - - result->readcount = str->readcount; - result->writecount = str->writecount; -} - -void glk_stream_close(stream_t *str, stream_result_t *result) -{ - if (!str) { - gli_strict_warning("stream_close: invalid ref."); - return; - } - - if (str->type == strtype_Window) { - gli_strict_warning("stream_close: cannot close window stream"); - return; - } - - gli_stream_fill_result(str, result); - gli_delete_stream(str); -} - -strid_t glk_stream_open_memory(char *buf, glui32 buflen, glui32 fmode, - glui32 rock) -{ - stream_t *str; - - if (fmode != filemode_Read - && fmode != filemode_Write - && fmode != filemode_ReadWrite) { - gli_strict_warning("stream_open_memory: illegal filemode"); - return NULL; - } - - str = gli_new_stream(strtype_Memory, - (fmode != filemode_Write), - (fmode != filemode_Read), - rock); - if (!str) { - gli_strict_warning("stream_open_memory: unable to create stream."); - return NULL; - } - - if (buf && buflen) { - str->buf = (unsigned char *)buf; - str->bufptr = (unsigned char *)buf; - str->buflen = buflen; - str->bufend = str->buf + str->buflen; - if (fmode == filemode_Write) - str->bufeof = str->buf; - else - str->bufeof = str->bufend; - if (gli_register_arr) { - str->arrayrock = (*gli_register_arr)(buf, buflen, "&+#!Cn"); - } - } - - return str; -} - -strid_t glk_stream_open_file(fileref_t *fref, glui32 fmode, - glui32 rock) -{ - stream_t *str; - char modestr[16]; - FILE *fl; - - if (!fref) { - gli_strict_warning("stream_open_file: invalid fileref id."); - return NULL; - } - - /* The spec says that Write, ReadWrite, and WriteAppend create the - file if necessary. However, fopen(filename, "r+") doesn't create - a file. So we have to pre-create it in the ReadWrite and - WriteAppend cases. (We use "a" so as not to truncate, and "b" - because we're going to close it immediately, so it doesn't matter.) */ - - /* Another Unix quirk: in r+ mode, you're not supposed to flip from - reading to writing or vice versa without doing an fseek. We will - track the most recent operation (as lastop) -- Write, Read, or - 0 if either is legal next. */ - - if (fmode == filemode_ReadWrite || fmode == filemode_WriteAppend) { - fl = fopen(fref->filename, "ab"); - if (!fl) { - gli_strict_warning("stream_open_file: unable to open file."); - return NULL; - } - - fclose(fl); - } - - switch (fmode) { - case filemode_Write: - strcpy(modestr, "w"); - break; - case filemode_Read: - strcpy(modestr, "r"); - break; - case filemode_ReadWrite: - strcpy(modestr, "r+"); - break; - case filemode_WriteAppend: - /* Can't use "a" here, because then fseek wouldn't work. - Instead we use "r+" and then fseek to the end. */ - strcpy(modestr, "r+"); - break; - } - - if (!fref->textmode) - strcat(modestr, "b"); - - fl = fopen(fref->filename, modestr); - if (!fl) { - gli_strict_warning("stream_open_file: unable to open file."); - return NULL; - } - - if (fmode == filemode_WriteAppend) { - fseek(fl, 0, 2); /* ...to the end. */ - } - - str = gli_new_stream(strtype_File, - (fmode == filemode_Read || fmode == filemode_ReadWrite), - !(fmode == filemode_Read), - rock); - if (!str) { - gli_strict_warning("stream_open_file: unable to create stream."); - fclose(fl); - return NULL; - } - - str->isbinary = !fref->textmode; - str->file = fl; - str->lastop = 0; - - return str; -} - -#ifdef GLK_MODULE_UNICODE - -strid_t glk_stream_open_memory_uni(glui32 *ubuf, glui32 buflen, glui32 fmode, - glui32 rock) -{ - stream_t *str; - - if (fmode != filemode_Read - && fmode != filemode_Write - && fmode != filemode_ReadWrite) { - gli_strict_warning("stream_open_memory_uni: illegal filemode"); - return NULL; - } - - str = gli_new_stream(strtype_Memory, - (fmode != filemode_Write), - (fmode != filemode_Read), - rock); - if (!str) { - gli_strict_warning("stream_open_memory_uni: unable to create stream."); - return NULL; - } - - str->unicode = TRUE; - - if (ubuf && buflen) { - str->ubuf = ubuf; - str->ubufptr = ubuf; - str->buflen = buflen; - str->ubufend = str->ubuf + str->buflen; - if (fmode == filemode_Write) - str->ubufeof = ubuf; - else - str->ubufeof = str->ubufend; - if (gli_register_arr) { - str->arrayrock = (*gli_register_arr)(ubuf, buflen, "&+#!Iu"); - } - } - - return str; -} - -strid_t glk_stream_open_file_uni(fileref_t *fref, glui32 fmode, - glui32 rock) -{ - strid_t str = glk_stream_open_file(fref, fmode, rock); - /* Unlovely, but it works in this library */ - str->unicode = TRUE; - return str; -} - -#endif /* GLK_MODULE_UNICODE */ - -#ifdef GLK_MODULE_RESOURCE_STREAM - -strid_t glk_stream_open_resource(glui32 filenum, glui32 rock) -{ - strid_t str; - int isbinary; - giblorb_err_t err; - giblorb_result_t res; - giblorb_map_t *map = giblorb_get_resource_map(); - if (!map) - return 0; /* Not running from a blorb file */ - - err = giblorb_load_resource(map, giblorb_method_Memory, &res, giblorb_ID_Data, filenum); - if (err) - return 0; /* Not found, or some other error */ - - /* We'll use the in-memory copy of the chunk data as the basis for - our new stream. It's important to not call chunk_unload() until - the stream is closed (and we won't). - - This will be memory-hoggish for giant data chunks, but I don't - expect giant data chunks at this point. A more efficient model - would be to use the file on disk, but this requires some hacking - into the file stream code (we'd need to open a new FILE*) and - I don't feel like doing that. - - Note that binary chunks are normally type BINA, but FORM - chunks also count as binary. (This allows us to embed AIFF - files as readable resources, for example.) */ - - if (res.chunktype == giblorb_ID_TEXT) - isbinary = FALSE; - else if (res.chunktype == giblorb_ID_BINA - || res.chunktype == giblorb_make_id('F', 'O', 'R', 'M')) - isbinary = TRUE; - else - return 0; /* Unknown chunk type */ - - str = gli_new_stream(strtype_Resource, - TRUE, FALSE, rock); - if (!str) { - gli_strict_warning("stream_open_resource: unable to create stream."); - return NULL; - } - - str->isbinary = isbinary; - - if (res.data.ptr && res.length) { - str->buf = (unsigned char *)res.data.ptr; - str->bufptr = (unsigned char *)res.data.ptr; - str->buflen = res.length; - str->bufend = str->buf + str->buflen; - str->bufeof = str->bufend; - } - - return str; -} - -strid_t glk_stream_open_resource_uni(glui32 filenum, glui32 rock) -{ - strid_t str; - int isbinary; - giblorb_err_t err; - giblorb_result_t res; - giblorb_map_t *map = giblorb_get_resource_map(); - if (!map) - return 0; /* Not running from a blorb file */ - - err = giblorb_load_resource(map, giblorb_method_Memory, &res, giblorb_ID_Data, filenum); - if (err) - return 0; /* Not found, or some other error */ - - if (res.chunktype == giblorb_ID_TEXT) - isbinary = FALSE; - else if (res.chunktype == giblorb_ID_BINA - || res.chunktype == giblorb_make_id('F', 'O', 'R', 'M')) - isbinary = TRUE; - else - return 0; /* Unknown chunk type */ - - str = gli_new_stream(strtype_Resource, - TRUE, FALSE, rock); - if (!str) { - gli_strict_warning("stream_open_resource_uni: unable to create stream."); - return NULL; - } - - str->unicode = TRUE; - str->isbinary = isbinary; - - /* We have been handed an array of bytes. (They're big-endian - four-byte chunks, or perhaps a UTF-8 byte sequence, rather than - native-endian four-byte integers). So we drop it into buf, - rather than ubuf -- we'll have to do the translation in the - get() functions. */ - - if (res.data.ptr && res.length) { - str->buf = (unsigned char *)res.data.ptr; - str->bufptr = (unsigned char *)res.data.ptr; - str->buflen = res.length; - str->bufend = str->buf + str->buflen; - str->bufeof = str->bufend; - } - - return str; -} - -#endif /* GLK_MODULE_RESOURCE_STREAM */ - -strid_t gli_stream_open_pathname(char *pathname, int writemode, - int textmode, glui32 rock) -{ - char modestr[16]; - stream_t *str; - FILE *fl; - - if (!writemode) - strcpy(modestr, "r"); - else - strcpy(modestr, "w"); - if (!textmode) - strcat(modestr, "b"); - - fl = fopen(pathname, modestr); - if (!fl) { - return NULL; - } - - str = gli_new_stream(strtype_File, - !writemode, writemode, rock); - if (!str) { - fclose(fl); - return NULL; - } - - str->isbinary = !textmode; - str->file = fl; - str->lastop = 0; - - return str; -} - -strid_t glk_stream_iterate(strid_t str, glui32 *rock) -{ - if (!str) { - str = gli_streamlist; - } - else { - str = str->next; - } - - if (str) { - if (rock) - *rock = str->rock; - return str; - } - - if (rock) - *rock = 0; - return NULL; -} - -glui32 glk_stream_get_rock(stream_t *str) -{ - if (!str) { - gli_strict_warning("stream_get_rock: invalid ref."); - return 0; - } - - return str->rock; -} - -void gli_stream_set_current(stream_t *str) -{ - gli_currentstr = str; -} - -void glk_stream_set_current(stream_t *str) -{ - gli_stream_set_current(str); -} - -strid_t glk_stream_get_current() -{ - if (gli_currentstr) - return gli_currentstr; - else - return NULL; -} - -void glk_stream_set_position(stream_t *str, glsi32 pos, glui32 seekmode) -{ - if (!str) { - gli_strict_warning("stream_set_position: invalid ref"); - return; - } - - switch (str->type) { - case strtype_Memory: - case strtype_Resource: - if (!str->unicode || str->type == strtype_Resource) { - if (seekmode == seekmode_Current) { - pos = (str->bufptr - str->buf) + pos; - } - else if (seekmode == seekmode_End) { - pos = (str->bufeof - str->buf) + pos; - } - else { - /* pos = pos */ - } - if (pos < 0) - pos = 0; - if (pos > (str->bufeof - str->buf)) - pos = (str->bufeof - str->buf); - str->bufptr = str->buf + pos; - } - else { - if (seekmode == seekmode_Current) { - pos = (str->ubufptr - str->ubuf) + pos; - } - else if (seekmode == seekmode_End) { - pos = (str->ubufeof - str->ubuf) + pos; - } - else { - /* pos = pos */ - } - if (pos < 0) - pos = 0; - if (pos > (str->ubufeof - str->ubuf)) - pos = (str->ubufeof - str->ubuf); - str->ubufptr = str->ubuf + pos; - } - break; - case strtype_Window: - /* do nothing; don't pass to echo stream */ - break; - case strtype_File: - /* Either reading or writing is legal after an fseek. */ - str->lastop = 0; - if (str->unicode) { - /* Use 4 here, rather than sizeof(glui32). */ - pos *= 4; - } - fseek(str->file, pos, - ((seekmode == seekmode_Current) ? 1 : - ((seekmode == seekmode_End) ? 2 : 0))); - break; - } -} - -glui32 glk_stream_get_position(stream_t *str) -{ - if (!str) { - gli_strict_warning("stream_get_position: invalid ref"); - return 0; - } - - switch (str->type) { - case strtype_Memory: - case strtype_Resource: - if (!str->unicode || str->type == strtype_Resource) { - return (str->bufptr - str->buf); - } - else { - return (str->ubufptr - str->ubuf); - } - case strtype_File: - if (!str->unicode) { - return ftell(str->file); - } - else { - /* Use 4 here, rather than sizeof(glui32). */ - return ftell(str->file) / 4; - } - case strtype_Window: - default: - return 0; - } -} - -static void gli_stream_ensure_op(stream_t *str, glui32 op) -{ - /* We have to do an fseek() between reading and writing. This will - only come up for ReadWrite or WriteAppend files. */ - if (str->lastop != 0 && str->lastop != op) { - long pos = ftell(str->file); - fseek(str->file, pos, SEEK_SET); - } - str->lastop = op; -} - -static void gli_put_char(stream_t *str, unsigned char ch) -{ - if (!str || !str->writable) - return; - - str->writecount++; - - switch (str->type) { - case strtype_Memory: - if (!str->unicode) { - if (str->bufptr < str->bufend) { - *(str->bufptr) = ch; - str->bufptr++; - if (str->bufptr > str->bufeof) - str->bufeof = str->bufptr; - } - } - else { - if (str->ubufptr < str->ubufend) { - *(str->ubufptr) = (glui32)ch; - str->ubufptr++; - if (str->ubufptr > str->ubufeof) - str->ubufeof = str->ubufptr; - } - } - break; - case strtype_Window: - if (str->win->line_request) { - gli_strict_warning("put_char: window has pending line request"); - break; - } - gli_put_char_window(str, ch); - break; - case strtype_File: - gli_stream_ensure_op(str, filemode_Write); - if (!str->unicode) { - putc(ch, str->file); - } - else { - if (!str->isbinary) { - /* cheap UTF-8 stream */ - gli_putchar_utf8(ch, str->file); - } - else { - /* cheap big-endian stream */ - putc(0, str->file); - putc(0, str->file); - putc(0, str->file); - putc(ch, str->file); - } - } - break; - case strtype_Resource: - /* resource streams are never writable */ - break; - } -} - -#ifdef GLK_MODULE_UNICODE - -static void gli_put_char_uni(stream_t *str, glui32 ch) -{ - if (!str || !str->writable) - return; - - str->writecount++; - - switch (str->type) { - case strtype_Memory: - if (!str->unicode) { - if (ch >= 0x100) - ch = '?'; - if (str->bufptr < str->bufend) { - *(str->bufptr) = ch; - str->bufptr++; - if (str->bufptr > str->bufeof) - str->bufeof = str->bufptr; - } - } - else { - if (str->ubufptr < str->ubufend) { - *(str->ubufptr) = ch; - str->ubufptr++; - if (str->ubufptr > str->ubufeof) - str->ubufeof = str->ubufptr; - } - } - break; - case strtype_Window: - if (str->win->line_request) { - gli_strict_warning("put_char_uni: window has pending line request"); - break; - } - gli_put_char_uni_window(str, ch); - break; - case strtype_File: - gli_stream_ensure_op(str, filemode_Write); - if (!str->unicode) { - if (ch >= 0x100) - ch = '?'; - putc(ch, str->file); - } - else { - if (!str->isbinary) { - /* cheap UTF-8 stream */ - gli_putchar_utf8(ch, str->file); - } - else { - /* cheap big-endian stream */ - putc(((ch >> 24) & 0xFF), str->file); - putc(((ch >> 16) & 0xFF), str->file); - putc(((ch >> 8) & 0xFF), str->file); - putc( (ch & 0xFF), str->file); - } - } - break; - case strtype_Resource: - /* resource streams are never writable */ - break; - } -} - -#endif /* GLK_MODULE_UNICODE */ - -static void gli_put_buffer(stream_t *str, char *buf, glui32 len) -{ - glui32 lx; - - if (!str || !str->writable) - return; - - str->writecount += len; - - switch (str->type) { - case strtype_Memory: - if (!str->unicode) { - if (str->bufptr >= str->bufend) { - len = 0; - } - else { - if (str->bufptr + len > str->bufend) { - lx = (str->bufptr + len) - str->bufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - if (len) { - memcpy(str->bufptr, buf, len); - str->bufptr += len; - if (str->bufptr > str->bufeof) - str->bufeof = str->bufptr; - } - } - else { - if (str->ubufptr >= str->ubufend) { - len = 0; - } - else { - if (str->ubufptr + len > str->ubufend) { - lx = (str->ubufptr + len) - str->ubufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - if (len) { - for (lx=0; lxubufptr = (unsigned char)(buf[lx]); - str->ubufptr++; - } - if (str->ubufptr > str->ubufeof) - str->ubufeof = str->ubufptr; - } - } - break; - case strtype_Window: - if (str->win->line_request) { - gli_strict_warning("put_buffer: window has pending line request"); - break; - } - gli_put_buffer_window(str, buf, len); - case strtype_File: - gli_stream_ensure_op(str, filemode_Write); - if (!str->unicode) { - fwrite(buf, 1, len, str->file); - } - else { - if (!str->isbinary) { - /* cheap UTF-8 stream */ - for (lx=0; lxfile); - } - else { - /* cheap big-endian stream */ - for (lx=0; lx> 24) & 0xFF), str->file); - putc(((ch >> 16) & 0xFF), str->file); - putc(((ch >> 8) & 0xFF), str->file); - putc( (ch & 0xFF), str->file); - } - } - } - break; - case strtype_Resource: - /* resource streams are never writable */ - break; - } -} - -void gli_stream_echo_line(stream_t *str, char *buf, glui32 len) -{ - /* This is only used to echo line input to an echo stream. See - glk_select(). */ - gli_put_buffer(str, buf, len); - gli_put_char(str, '\n'); -} - -#ifdef GLK_MODULE_UNICODE - -void gli_stream_echo_line_uni(stream_t *str, glui32 *buf, glui32 len) -{ - glui32 ix; - /* This is only used to echo line input to an echo stream. See - glk_select(). */ - for (ix=0; ixreadable) - return -1; - - switch (str->type) { - case strtype_Resource: - if (str->unicode) { - glui32 ch; - if (str->isbinary) { - /* cheap big-endian stream */ - if (str->bufptr >= str->bufend) - return -1; - ch = *(str->bufptr); - str->bufptr++; - if (str->bufptr >= str->bufend) - return -1; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - return -1; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - return -1; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - } - else { - /* slightly less cheap UTF8 stream */ - glui32 val0, val1, val2, val3; - int flag = UTF8_DECODE_INLINE(&ch, (str->bufptr >= str->bufend), (*(str->bufptr++)), val0, val1, val2, val3); - if (!flag) - return -1; - } - str->readcount++; - if (!want_unicode && ch >= 0x100) - return '?'; - return (glsi32)ch; - } - /* for text streams, fall through to memory case */ - case strtype_Memory: - if (!str->unicode) { - if (str->bufptr < str->bufend) { - unsigned char ch; - ch = *(str->bufptr); - str->bufptr++; - str->readcount++; - return ch; - } - else { - return -1; - } - } - else { - if (str->ubufptr < str->ubufend) { - glui32 ch; - ch = *(str->ubufptr); - str->ubufptr++; - str->readcount++; - if (!want_unicode && ch >= 0x100) - return '?'; - return ch; - } - else { - return -1; - } - } - case strtype_File: - gli_stream_ensure_op(str, filemode_Read); - if (!str->unicode) { - int res; - res = getc(str->file); - if (res != -1) { - str->readcount++; - return (glsi32)res; - } - else { - return -1; - } - } - else if (str->isbinary) { - /* cheap big-endian stream */ - int res; - glui32 ch; - res = getc(str->file); - if (res == -1) - return -1; - ch = (res & 0xFF); - res = getc(str->file); - if (res == -1) - return -1; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - return -1; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - return -1; - ch = (ch << 8) | (res & 0xFF); - str->readcount++; - if (!want_unicode && ch >= 0x100) - return '?'; - return (glsi32)ch; - } - else { - /* slightly less cheap UTF-8 stream */ - glui32 val0, val1, val2, val3; - int res; - glui32 ch; - int flag = UTF8_DECODE_INLINE(&ch, (res=getc(str->file), res == -1), (res & 0xFF), val0, val1, val2, val3); - if (!flag) - return -1; - str->readcount++; - if (!want_unicode && ch >= 0x100) - return '?'; - return (glsi32)ch; - } - case strtype_Window: - default: - return -1; - } -} - -static glui32 gli_get_buffer(stream_t *str, char *cbuf, glui32 *ubuf, - glui32 len) -{ - if (!str || !str->readable) - return 0; - - switch (str->type) { - case strtype_Resource: - if (str->unicode) { - glui32 count = 0; - while (count < len) { - glui32 ch; - if (str->isbinary) { - /* cheap big-endian stream */ - if (str->bufptr >= str->bufend) - break; - ch = *(str->bufptr); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - } - else { - /* slightly less cheap UTF8 stream */ - glui32 val0, val1, val2, val3; - int flag = UTF8_DECODE_INLINE(&ch, (str->bufptr >= str->bufend), (*(str->bufptr++)), val0, val1, val2, val3); - if (!flag) - break; - } - if (cbuf) { - if (ch >= 0x100) - cbuf[count] = '?'; - else - cbuf[count] = ch; - } - else { - ubuf[count] = ch; - } - count++; - } - str->readcount += count; - return count; - } - /* for text streams, fall through to memory case */ - case strtype_Memory: - if (!str->unicode) { - if (str->bufptr >= str->bufend) { - len = 0; - } - else { - if (str->bufptr + len > str->bufend) { - glui32 lx; - lx = (str->bufptr + len) - str->bufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - if (len) { - if (cbuf) { - memcpy(cbuf, str->bufptr, len); - } - else { - glui32 lx; - for (lx=0; lxbufptr[lx]; - } - } - str->bufptr += len; - if (str->bufptr > str->bufeof) - str->bufeof = str->bufptr; - } - } - else { - if (str->ubufptr >= str->ubufend) { - len = 0; - } - else { - if (str->ubufptr + len > str->ubufend) { - glui32 lx; - lx = (str->ubufptr + len) - str->ubufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - if (len) { - glui32 lx, ch; - if (cbuf) { - for (lx=0; lxubufptr[lx]; - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - } - } - else { - for (lx=0; lxubufptr[lx]; - } - } - str->ubufptr += len; - if (str->ubufptr > str->ubufeof) - str->ubufeof = str->ubufptr; - } - } - str->readcount += len; - return len; - case strtype_File: - gli_stream_ensure_op(str, filemode_Read); - if (!str->unicode) { - if (cbuf) { - glui32 res; - res = fread(cbuf, 1, len, str->file); - str->readcount += res; - return res; - } - else { - glui32 lx; - for (lx=0; lxfile); - if (res == -1) - break; - ch = (res & 0xFF); - str->readcount++; - ubuf[lx] = ch; - } - return lx; - } - } - else if (str->isbinary) { - /* cheap big-endian stream */ - glui32 lx; - for (lx=0; lxfile); - if (res == -1) - break; - ch = (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - str->readcount++; - if (cbuf) { - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - } - else { - ubuf[lx] = ch; - } - } - return lx; - } - else { - /* slightly less cheap UTF-8 stream */ - glui32 lx; - for (lx=0; lxfile), res == -1), (res & 0xFF), val0, val1, val2, val3); - if (!flag) - break; - str->readcount++; - if (cbuf) { - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - } - else { - ubuf[lx] = ch; - } - } - return lx; - } - case strtype_Window: - default: - return 0; - } -} - -static glui32 gli_get_line(stream_t *str, char *cbuf, glui32 *ubuf, - glui32 len) -{ - glui32 lx; - int gotnewline; - - if (!str || !str->readable) - return 0; - - switch (str->type) { - case strtype_Resource: - if (len == 0) - return 0; - len -= 1; /* for the terminal null */ - if (str->unicode) { - glui32 count = 0; - while (count < len) { - glui32 ch; - if (str->isbinary) { - /* cheap big-endian stream */ - if (str->bufptr >= str->bufend) - break; - ch = *(str->bufptr); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - if (str->bufptr >= str->bufend) - break; - ch = (ch << 8) | (*(str->bufptr) & 0xFF); - str->bufptr++; - } - else { - /* slightly less cheap UTF8 stream */ - glui32 val0, val1, val2, val3; - int flag = UTF8_DECODE_INLINE(&ch, (str->bufptr >= str->bufend), (*(str->bufptr++)), val0, val1, val2, val3); - if (!flag) - break; - } - if (cbuf) { - if (ch >= 0x100) - cbuf[count] = '?'; - else - cbuf[count] = ch; - } - else { - ubuf[count] = ch; - } - count++; - if (ch == '\n') - break; - } - if (cbuf) - cbuf[count] = '\0'; - else - ubuf[count] = '\0'; - str->readcount += count; - return count; - } - /* for text streams, fall through to memory case */ - case strtype_Memory: - if (len == 0) - return 0; - len -= 1; /* for the terminal null */ - if (!str->unicode) { - if (str->bufptr >= str->bufend) { - len = 0; - } - else { - if (str->bufptr + len > str->bufend) { - lx = (str->bufptr + len) - str->bufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - gotnewline = FALSE; - if (cbuf) { - for (lx=0; lxbufptr[lx]; - gotnewline = (cbuf[lx] == '\n'); - } - cbuf[lx] = '\0'; - } - else { - for (lx=0; lxbufptr[lx]; - gotnewline = (ubuf[lx] == '\n'); - } - ubuf[lx] = '\0'; - } - str->bufptr += lx; - } - else { - if (str->ubufptr >= str->ubufend) { - len = 0; - } - else { - if (str->ubufptr + len > str->ubufend) { - lx = (str->ubufptr + len) - str->ubufend; - if (lx < len) - len -= lx; - else - len = 0; - } - } - gotnewline = FALSE; - if (cbuf) { - for (lx=0; lxubufptr[lx]; - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - gotnewline = (ch == '\n'); - } - cbuf[lx] = '\0'; - } - else { - for (lx=0; lxubufptr[lx]; - ubuf[lx] = ch; - gotnewline = (ch == '\n'); - } - ubuf[lx] = '\0'; - } - str->ubufptr += lx; - } - str->readcount += lx; - return lx; - case strtype_File: - gli_stream_ensure_op(str, filemode_Read); - if (!str->unicode) { - if (cbuf) { - char *res; - res = fgets(cbuf, len, str->file); - if (!res) { - return 0; - } - else { - glui32 lx = strlen(cbuf); - str->readcount += lx; - return lx; - } - } - else { - glui32 lx; - if (len == 0) - return 0; - len -= 1; /* for the terminal null */ - gotnewline = FALSE; - for (lx=0; lxfile); - if (res == -1) - break; - ch = (res & 0xFF); - str->readcount++; - ubuf[lx] = ch; - gotnewline = (ch == '\n'); - } - ubuf[lx] = '\0'; - return lx; - } - } - else if (str->isbinary) { - /* cheap big-endian stream */ - glui32 lx; - if (len == 0) - return 0; - len -= 1; /* for the terminal null */ - gotnewline = FALSE; - for (lx=0; lxfile); - if (res == -1) - break; - ch = (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - res = getc(str->file); - if (res == -1) - break; - ch = (ch << 8) | (res & 0xFF); - str->readcount++; - if (cbuf) { - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - } - else { - ubuf[lx] = ch; - } - gotnewline = (ch == '\n'); - } - if (cbuf) - cbuf[lx] = '\0'; - else - ubuf[lx] = '\0'; - return lx; - } - else { - /* slightly less cheap UTF-8 stream */ - glui32 lx; - if (len == 0) - return 0; - len -= 1; /* for the terminal null */ - gotnewline = FALSE; - for (lx=0; lxfile), res == -1), (res & 0xFF), val0, val1, val2, val3); - if (!flag) - break; - str->readcount++; - if (cbuf) { - if (ch >= 0x100) - ch = '?'; - cbuf[lx] = ch; - } - else { - ubuf[lx] = ch; - } - gotnewline = (ch == '\n'); - } - if (cbuf) - cbuf[lx] = '\0'; - else - ubuf[lx] = '\0'; - return lx; - } - case strtype_Window: - default: - return 0; - } -} - -void glk_put_char(unsigned char ch) -{ - gli_put_char(gli_currentstr, ch); -} - -void glk_put_char_stream(stream_t *str, unsigned char ch) -{ - if (!str) { - gli_strict_warning("put_char_stream: invalid ref"); - return; - } - gli_put_char(str, ch); -} - -void glk_put_string(char *s) -{ - gli_put_buffer(gli_currentstr, s, strlen(s)); -} - -void glk_put_string_stream(stream_t *str, char *s) -{ - if (!str) { - gli_strict_warning("put_string_stream: invalid ref"); - return; - } - gli_put_buffer(str, s, strlen(s)); -} - -void glk_put_buffer(char *buf, glui32 len) -{ - gli_put_buffer(gli_currentstr, buf, len); -} - -void glk_put_buffer_stream(stream_t *str, char *buf, glui32 len) -{ - if (!str) { - gli_strict_warning("put_string_stream: invalid ref"); - return; - } - gli_put_buffer(str, buf, len); -} - -#ifdef GLK_MODULE_UNICODE - -void glk_put_char_uni(glui32 ch) -{ - gli_put_char_uni(gli_currentstr, ch); -} - -void glk_put_char_stream_uni(stream_t *str, glui32 ch) -{ - if (!str) { - gli_strict_warning("put_char_stream: invalid ref"); - return; - } - gli_put_char_uni(str, ch); -} - -void glk_put_string_uni(glui32 *us) -{ - int len = 0; - glui32 val; - - while (1) { - val = us[len]; - if (!val) - break; - gli_put_char_uni(gli_currentstr, val); - len++; - } -} - -void glk_put_string_stream_uni(stream_t *str, glui32 *us) -{ - int len = 0; - glui32 val; - - if (!str) { - gli_strict_warning("put_string_stream: invalid ref"); - return; - } - - while (1) { - val = us[len]; - if (!val) - break; - gli_put_char_uni(str, val); - len++; - } -} - -void glk_put_buffer_uni(glui32 *buf, glui32 len) -{ - glui32 ix; - for (ix=0; ix -#include "glk.h" -#include "cheapglk.h" - -/* None of these functions do much in CheapGlk. */ - -void glk_stylehint_set(glui32 wintype, glui32 styl, glui32 hint, - glsi32 val) -{ - /* We don't do styles */ -} - -void glk_stylehint_clear(glui32 wintype, glui32 styl, glui32 hint) -{ - /* We don't do styles */ -} - -glui32 glk_style_distinguish(winid_t win, glui32 styl1, glui32 styl2) -{ - /* Styles are never distinguishable. */ - return FALSE; -} - -glui32 glk_style_measure(winid_t win, glui32 styl, glui32 hint, - glui32 *result) -{ - /* We can't measure any style attributes. */ - return FALSE; -} - - diff --git a/textworld/thirdparty/glulx/cheapglk/cgunicod.c b/textworld/thirdparty/glulx/cheapglk/cgunicod.c deleted file mode 100644 index 9248eaf1..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgunicod.c +++ /dev/null @@ -1,563 +0,0 @@ -#include -#include -#include -#include "glk.h" -#include "cheapglk.h" - -void gli_putchar_utf8(glui32 val, FILE *fl) -{ - if (val < 0x80) { - putc(val, fl); - } - else if (val < 0x800) { - putc((0xC0 | ((val & 0x7C0) >> 6)), fl); - putc((0x80 | (val & 0x03F) ), fl); - } - else if (val < 0x10000) { - putc((0xE0 | ((val & 0xF000) >> 12)), fl); - putc((0x80 | ((val & 0x0FC0) >> 6)), fl); - putc((0x80 | (val & 0x003F) ), fl); - } - else if (val < 0x200000) { - putc((0xF0 | ((val & 0x1C0000) >> 18)), fl); - putc((0x80 | ((val & 0x03F000) >> 12)), fl); - putc((0x80 | ((val & 0x000FC0) >> 6)), fl); - putc((0x80 | (val & 0x00003F) ), fl); - } - else { - putc('?', fl); - } -} - -int gli_encode_utf8(glui32 val, char *buf, int len) -{ - /* return the number of bytes (actually) generated */ - char *ptr = buf; - char *end = buf+len; - - if (val < 0x80) { - if (ptr < end) - *ptr++ = val; - } - else if (val < 0x800) { - if (ptr < end) - *ptr++ = (0xC0 | ((val & 0x7C0) >> 6)); - if (ptr < end) - *ptr++ = (0x80 | (val & 0x03F) ); - } - else if (val < 0x10000) { - if (ptr < end) - *ptr++ = (0xE0 | ((val & 0xF000) >> 12)); - if (ptr < end) - *ptr++ = (0x80 | ((val & 0x0FC0) >> 6)); - if (ptr < end) - *ptr++ = (0x80 | (val & 0x003F) ); - } - else if (val < 0x200000) { - if (ptr < end) - *ptr++ = (0xF0 | ((val & 0x1C0000) >> 18)); - if (ptr < end) - *ptr++ = (0x80 | ((val & 0x03F000) >> 12)); - if (ptr < end) - *ptr++ = (0x80 | ((val & 0x000FC0) >> 6)); - if (ptr < end) - *ptr++ = (0x80 | (val & 0x00003F) ); - } - else { - if (ptr < end) - *ptr++ = '?'; - } - - return (ptr - buf); -} - -glui32 gli_parse_utf8(unsigned char *buf, glui32 buflen, - glui32 *out, glui32 outlen) -{ - glui32 pos = 0; - glui32 outpos = 0; - glui32 res; - glui32 val0, val1, val2, val3; - - while (outpos < outlen) { - if (pos >= buflen) - break; - - val0 = buf[pos++]; - - if (val0 < 0x80) { - res = val0; - out[outpos++] = res; - continue; - } - - if ((val0 & 0xe0) == 0xc0) { - if (pos+1 > buflen) { - gli_strict_warning("incomplete two-byte character"); - break; - } - val1 = buf[pos++]; - if ((val1 & 0xc0) != 0x80) { - gli_strict_warning("malformed two-byte character"); - break; - } - res = (val0 & 0x1f) << 6; - res |= (val1 & 0x3f); - out[outpos++] = res; - continue; - } - - if ((val0 & 0xf0) == 0xe0) { - if (pos+2 > buflen) { - gli_strict_warning("incomplete three-byte character"); - break; - } - val1 = buf[pos++]; - val2 = buf[pos++]; - if ((val1 & 0xc0) != 0x80) { - gli_strict_warning("malformed three-byte character"); - break; - } - if ((val2 & 0xc0) != 0x80) { - gli_strict_warning("malformed three-byte character"); - break; - } - res = (((val0 & 0xf)<<12) & 0x0000f000); - res |= (((val1 & 0x3f)<<6) & 0x00000fc0); - res |= (((val2 & 0x3f)) & 0x0000003f); - out[outpos++] = res; - continue; - } - - if ((val0 & 0xf0) == 0xf0) { - if ((val0 & 0xf8) != 0xf0) { - gli_strict_warning("malformed four-byte character"); - break; - } - if (pos+3 > buflen) { - gli_strict_warning("incomplete four-byte character"); - break; - } - val1 = buf[pos++]; - val2 = buf[pos++]; - val3 = buf[pos++]; - if ((val1 & 0xc0) != 0x80) { - gli_strict_warning("malformed four-byte character"); - break; - } - if ((val2 & 0xc0) != 0x80) { - gli_strict_warning("malformed four-byte character"); - break; - } - if ((val3 & 0xc0) != 0x80) { - gli_strict_warning("malformed four-byte character"); - break; - } - res = (((val0 & 0x7)<<18) & 0x1c0000); - res |= (((val1 & 0x3f)<<12) & 0x03f000); - res |= (((val2 & 0x3f)<<6) & 0x000fc0); - res |= (((val3 & 0x3f)) & 0x00003f); - out[outpos++] = res; - continue; - } - - gli_strict_warning("malformed character"); - } - - return outpos; -} - -#ifdef GLK_MODULE_UNICODE - -/* The cgunigen.c file is generated from Unicode data tables, and it's - sort of enormous. Feel free to implement all these case-changing and - normalization functions using your OS's native facilities. */ - -#include "cgunigen.c" - -#define CASE_UPPER (0) -#define CASE_LOWER (1) -#define CASE_TITLE (2) -#define CASE_IDENT (3) - -#define COND_ALL (0) -#define COND_LINESTART (1) - -/* Apply a case change to the buffer. The len is the length of the buffer - array; numchars is the number of characters originally in it. (This - may be less than len.) The result will be clipped to fit len, but - the return value will be the full number of characters that the - converted string should have contained. -*/ -static glui32 gli_buffer_change_case(glui32 *buf, glui32 len, - glui32 numchars, int destcase, int cond, int changerest) -{ - glui32 ix, jx; - glui32 *outbuf; - glui32 *newoutbuf; - glui32 outcount; - int dest_block_rest, dest_block_first; - int dest_spec_rest, dest_spec_first; - - switch (cond) { - case COND_ALL: - dest_spec_rest = destcase; - dest_spec_first = destcase; - break; - case COND_LINESTART: - if (changerest) - dest_spec_rest = CASE_LOWER; - else - dest_spec_rest = CASE_IDENT; - dest_spec_first = destcase; - break; - } - - dest_block_rest = dest_spec_rest; - if (dest_block_rest == CASE_TITLE) - dest_block_rest = CASE_UPPER; - dest_block_first = dest_spec_first; - if (dest_block_first == CASE_TITLE) - dest_block_first = CASE_UPPER; - - newoutbuf = NULL; - outcount = 0; - outbuf = buf; - - for (ix=0; ix len) - finallen = len; - if (finallen) - memcpy(buf, newoutbuf, finallen * sizeof(glui32)); - free(newoutbuf); - } - - return outcount; -} - -glui32 glk_buffer_to_lower_case_uni(glui32 *buf, glui32 len, - glui32 numchars) -{ - return gli_buffer_change_case(buf, len, numchars, - CASE_LOWER, COND_ALL, TRUE); -} - -glui32 glk_buffer_to_upper_case_uni(glui32 *buf, glui32 len, - glui32 numchars) -{ - return gli_buffer_change_case(buf, len, numchars, - CASE_UPPER, COND_ALL, TRUE); -} - -glui32 glk_buffer_to_title_case_uni(glui32 *buf, glui32 len, - glui32 numchars, glui32 lowerrest) -{ - return gli_buffer_change_case(buf, len, numchars, - CASE_TITLE, COND_LINESTART, lowerrest); -} - -#endif /* GLK_MODULE_UNICODE */ - -#ifdef GLK_MODULE_UNICODE_NORM - -/* We're relying on the fact that cgunigen.c has already been included. - So don't try to use GLK_MODULE_UNICODE_NORM without GLK_MODULE_UNICODE. -*/ - -static glui32 combining_class(glui32 ch) -{ - RETURN_COMBINING_CLASS(ch); -} - -/* This returns a new buffer (possibly longer), containing the decomposed - form of the original buffer. The caller must free the returned buffer. - On exit, *numcharsref contains the size of the returned buffer. - The original buffer is unchanged. -*/ -static glui32 *gli_buffer_canon_decompose_uni(glui32 *buf, - glui32 *numcharsref) -{ - /* The algorithm for the canonical decomposition of a string: For - each character, look up the decomposition in the decomp table. - Append the decomposition to the buffer. Finally, sort every - substring of the buffer which is made up of combining - characters (characters with a nonzero combining class). */ - - glui32 numchars = *numcharsref; - glui32 destsize = numchars * 2 + 16; - glui32 *dest = (glui32 *)malloc(destsize * sizeof(glui32)); - glui32 destlen = 0; - glui32 ix, jx; - int anycombining = FALSE; - - if (!dest) - return NULL; - - for (ix=0; ix= destsize) { - destsize = destsize * 2; - dest = (glui32 *)realloc(dest, destsize * sizeof(glui32)); - if (!dest) - return NULL; - } - dest[destlen] = ch; - destlen++; - continue; - } - - /* Assume that a character with a decomposition has a - combining class somewhere in there. Not always true, but - it's simpler to assume it. */ - anycombining = TRUE; - - /* We now append count characters to the buffer, reading from - unigen_decomp_data[pos] onwards. None of these characters - are decomposable; that was already recursively expanded when - unigen_decomp_data was generated. */ - - if (destlen+count >= destsize) { - /* Okay, that wasn't enough. Expand more. */ - destsize = destsize * 2 + count; - dest = (glui32 *)realloc(dest, destsize * sizeof(glui32)); - if (!dest) - return NULL; - } - for (jx=0; jx= destlen) - break; - grpstart = ix; - while (ix < destlen && combining_class(dest[ix])) - ix++; - grpend = ix; - if (grpend - grpstart >= 2) { - /* Sort this group. */ - for (jx = grpend-1; jx > grpstart; jx--) { - for (kx = grpstart; kx < jx; kx++) { - if (combining_class(dest[kx]) > combining_class(dest[kx+1])) { - glui32 tmp = dest[kx]; - dest[kx] = dest[kx+1]; - dest[kx+1] = tmp; - } - } - } - } - } - } - - *numcharsref = destlen; - return dest; -} - -static glui32 check_composition(glui32 ch1, glui32 ch2) -{ - RETURN_COMPOSITION(ch1, ch2); -} - -/* This composes characters in the given buffer, in place. It returns the - number of characters in the result, which will be less than or equal - to len. -*/ -static glui32 gli_buffer_canon_compose_uni(glui32 *buf, glui32 len) -{ - /* This algorithm is lifted from the Java sample code at - . - I apologize for the ugly. - - Roughly, pos is the position of the last base character; - curch is that character in progress; ix is the next character - to write (which may fly ahead of pos, as we encounter a string of - combining chars); and jx is the position that we're scanning. - In the simplest case, jx and ix stay together, with pos one behind. */ - - glui32 curch, newch, curclass, newclass, res; - glui32 ix, jx, pos; - - if (len == 0) - return 0; - - pos = 0; - curch = buf[0]; - curclass = combining_class(curch); - if (curclass) - curclass = 999; /* just in case the first character is a combiner */ - ix = 1; - jx = ix; - while (1) { - if (jx >= len) { - buf[pos] = curch; - pos = ix; - break; - } - newch = buf[jx]; - newclass = combining_class(newch); - res = check_composition(curch, newch); - if (res && (!curclass || curclass < newclass)) { - curch = res; - buf[pos] = curch; - } - else { - if (!newclass) { - pos = ix; - curch = newch; - } - curclass = newclass; - buf[ix] = newch; - ix++; - } - jx++; - } - - return pos; -} - -glui32 glk_buffer_canon_decompose_uni(glui32 *buf, glui32 len, - glui32 numchars) -{ - glui32 *dest = gli_buffer_canon_decompose_uni(buf, &numchars); - glui32 newlen; - - if (!dest) - return 0; - - /* Copy the data back. */ - newlen = numchars; - if (newlen > len) - newlen = len; - if (newlen) - memcpy(buf, dest, newlen * sizeof(glui32)); - free(dest); - - return numchars; -} - -glui32 glk_buffer_canon_normalize_uni(glui32 *buf, glui32 len, - glui32 numchars) -{ - glui32 newlen; - glui32 *dest = gli_buffer_canon_decompose_uni(buf, &numchars); - - if (!dest) - return 0; - - numchars = gli_buffer_canon_compose_uni(dest, numchars); - - /* Copy the data back. */ - newlen = numchars; - if (newlen > len) - newlen = len; - if (newlen) - memcpy(buf, dest, newlen * sizeof(glui32)); - free(dest); - - return numchars; -} - -#endif /* GLK_MODULE_UNICODE_NORM */ - diff --git a/textworld/thirdparty/glulx/cheapglk/cgunigen.c b/textworld/thirdparty/glulx/cheapglk/cgunigen.c deleted file mode 100644 index 1fbd9264..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgunigen.c +++ /dev/null @@ -1,12193 +0,0 @@ -/* This file was generated by casemap.py. */ -/* Derived from Unicode data files, Unicode version 4.0.1. */ -/* This does not get compiled into a cgunigen.o file; it's - * #included in cgunicod.c. */ - -static gli_case_block_t unigen_case_block_0x0[256] = { - { 0x0, 0x0 }, - { 0x1, 0x1 }, - { 0x2, 0x2 }, - { 0x3, 0x3 }, - { 0x4, 0x4 }, - { 0x5, 0x5 }, - { 0x6, 0x6 }, - { 0x7, 0x7 }, - { 0x8, 0x8 }, - { 0x9, 0x9 }, - { 0xa, 0xa }, - { 0xb, 0xb }, - { 0xc, 0xc }, - { 0xd, 0xd }, - { 0xe, 0xe }, - { 0xf, 0xf }, - { 0x10, 0x10 }, - { 0x11, 0x11 }, - { 0x12, 0x12 }, - { 0x13, 0x13 }, - { 0x14, 0x14 }, - { 0x15, 0x15 }, - { 0x16, 0x16 }, - { 0x17, 0x17 }, - { 0x18, 0x18 }, - { 0x19, 0x19 }, - { 0x1a, 0x1a }, - { 0x1b, 0x1b }, - { 0x1c, 0x1c }, - { 0x1d, 0x1d }, - { 0x1e, 0x1e }, - { 0x1f, 0x1f }, - { 0x20, 0x20 }, - { 0x21, 0x21 }, - { 0x22, 0x22 }, - { 0x23, 0x23 }, - { 0x24, 0x24 }, - { 0x25, 0x25 }, - { 0x26, 0x26 }, - { 0x27, 0x27 }, - { 0x28, 0x28 }, - { 0x29, 0x29 }, - { 0x2a, 0x2a }, - { 0x2b, 0x2b }, - { 0x2c, 0x2c }, - { 0x2d, 0x2d }, - { 0x2e, 0x2e }, - { 0x2f, 0x2f }, - { 0x30, 0x30 }, - { 0x31, 0x31 }, - { 0x32, 0x32 }, - { 0x33, 0x33 }, - { 0x34, 0x34 }, - { 0x35, 0x35 }, - { 0x36, 0x36 }, - { 0x37, 0x37 }, - { 0x38, 0x38 }, - { 0x39, 0x39 }, - { 0x3a, 0x3a }, - { 0x3b, 0x3b }, - { 0x3c, 0x3c }, - { 0x3d, 0x3d }, - { 0x3e, 0x3e }, - { 0x3f, 0x3f }, - { 0x40, 0x40 }, - { 0x41, 0x61 }, /* upper */ - { 0x42, 0x62 }, /* upper */ - { 0x43, 0x63 }, /* upper */ - { 0x44, 0x64 }, /* upper */ - { 0x45, 0x65 }, /* upper */ - { 0x46, 0x66 }, /* upper */ - { 0x47, 0x67 }, /* upper */ - { 0x48, 0x68 }, /* upper */ - { 0x49, 0x69 }, /* upper */ - { 0x4a, 0x6a }, /* upper */ - { 0x4b, 0x6b }, /* upper */ - { 0x4c, 0x6c }, /* upper */ - { 0x4d, 0x6d }, /* upper */ - { 0x4e, 0x6e }, /* upper */ - { 0x4f, 0x6f }, /* upper */ - { 0x50, 0x70 }, /* upper */ - { 0x51, 0x71 }, /* upper */ - { 0x52, 0x72 }, /* upper */ - { 0x53, 0x73 }, /* upper */ - { 0x54, 0x74 }, /* upper */ - { 0x55, 0x75 }, /* upper */ - { 0x56, 0x76 }, /* upper */ - { 0x57, 0x77 }, /* upper */ - { 0x58, 0x78 }, /* upper */ - { 0x59, 0x79 }, /* upper */ - { 0x5a, 0x7a }, /* upper */ - { 0x5b, 0x5b }, - { 0x5c, 0x5c }, - { 0x5d, 0x5d }, - { 0x5e, 0x5e }, - { 0x5f, 0x5f }, - { 0x60, 0x60 }, - { 0x41, 0x61 }, /* lower */ - { 0x42, 0x62 }, /* lower */ - { 0x43, 0x63 }, /* lower */ - { 0x44, 0x64 }, /* lower */ - { 0x45, 0x65 }, /* lower */ - { 0x46, 0x66 }, /* lower */ - { 0x47, 0x67 }, /* lower */ - { 0x48, 0x68 }, /* lower */ - { 0x49, 0x69 }, /* lower */ - { 0x4a, 0x6a }, /* lower */ - { 0x4b, 0x6b }, /* lower */ - { 0x4c, 0x6c }, /* lower */ - { 0x4d, 0x6d }, /* lower */ - { 0x4e, 0x6e }, /* lower */ - { 0x4f, 0x6f }, /* lower */ - { 0x50, 0x70 }, /* lower */ - { 0x51, 0x71 }, /* lower */ - { 0x52, 0x72 }, /* lower */ - { 0x53, 0x73 }, /* lower */ - { 0x54, 0x74 }, /* lower */ - { 0x55, 0x75 }, /* lower */ - { 0x56, 0x76 }, /* lower */ - { 0x57, 0x77 }, /* lower */ - { 0x58, 0x78 }, /* lower */ - { 0x59, 0x79 }, /* lower */ - { 0x5a, 0x7a }, /* lower */ - { 0x7b, 0x7b }, - { 0x7c, 0x7c }, - { 0x7d, 0x7d }, - { 0x7e, 0x7e }, - { 0x7f, 0x7f }, - { 0x80, 0x80 }, - { 0x81, 0x81 }, - { 0x82, 0x82 }, - { 0x83, 0x83 }, - { 0x84, 0x84 }, - { 0x85, 0x85 }, - { 0x86, 0x86 }, - { 0x87, 0x87 }, - { 0x88, 0x88 }, - { 0x89, 0x89 }, - { 0x8a, 0x8a }, - { 0x8b, 0x8b }, - { 0x8c, 0x8c }, - { 0x8d, 0x8d }, - { 0x8e, 0x8e }, - { 0x8f, 0x8f }, - { 0x90, 0x90 }, - { 0x91, 0x91 }, - { 0x92, 0x92 }, - { 0x93, 0x93 }, - { 0x94, 0x94 }, - { 0x95, 0x95 }, - { 0x96, 0x96 }, - { 0x97, 0x97 }, - { 0x98, 0x98 }, - { 0x99, 0x99 }, - { 0x9a, 0x9a }, - { 0x9b, 0x9b }, - { 0x9c, 0x9c }, - { 0x9d, 0x9d }, - { 0x9e, 0x9e }, - { 0x9f, 0x9f }, - { 0xa0, 0xa0 }, - { 0xa1, 0xa1 }, - { 0xa2, 0xa2 }, - { 0xa3, 0xa3 }, - { 0xa4, 0xa4 }, - { 0xa5, 0xa5 }, - { 0xa6, 0xa6 }, - { 0xa7, 0xa7 }, - { 0xa8, 0xa8 }, - { 0xa9, 0xa9 }, - { 0xaa, 0xaa }, - { 0xab, 0xab }, - { 0xac, 0xac }, - { 0xad, 0xad }, - { 0xae, 0xae }, - { 0xaf, 0xaf }, - { 0xb0, 0xb0 }, - { 0xb1, 0xb1 }, - { 0xb2, 0xb2 }, - { 0xb3, 0xb3 }, - { 0xb4, 0xb4 }, - { 0x39c, 0xb5 }, /* lower */ - { 0xb6, 0xb6 }, - { 0xb7, 0xb7 }, - { 0xb8, 0xb8 }, - { 0xb9, 0xb9 }, - { 0xba, 0xba }, - { 0xbb, 0xbb }, - { 0xbc, 0xbc }, - { 0xbd, 0xbd }, - { 0xbe, 0xbe }, - { 0xbf, 0xbf }, - { 0xc0, 0xe0 }, /* upper */ - { 0xc1, 0xe1 }, /* upper */ - { 0xc2, 0xe2 }, /* upper */ - { 0xc3, 0xe3 }, /* upper */ - { 0xc4, 0xe4 }, /* upper */ - { 0xc5, 0xe5 }, /* upper */ - { 0xc6, 0xe6 }, /* upper */ - { 0xc7, 0xe7 }, /* upper */ - { 0xc8, 0xe8 }, /* upper */ - { 0xc9, 0xe9 }, /* upper */ - { 0xca, 0xea }, /* upper */ - { 0xcb, 0xeb }, /* upper */ - { 0xcc, 0xec }, /* upper */ - { 0xcd, 0xed }, /* upper */ - { 0xce, 0xee }, /* upper */ - { 0xcf, 0xef }, /* upper */ - { 0xd0, 0xf0 }, /* upper */ - { 0xd1, 0xf1 }, /* upper */ - { 0xd2, 0xf2 }, /* upper */ - { 0xd3, 0xf3 }, /* upper */ - { 0xd4, 0xf4 }, /* upper */ - { 0xd5, 0xf5 }, /* upper */ - { 0xd6, 0xf6 }, /* upper */ - { 0xd7, 0xd7 }, - { 0xd8, 0xf8 }, /* upper */ - { 0xd9, 0xf9 }, /* upper */ - { 0xda, 0xfa }, /* upper */ - { 0xdb, 0xfb }, /* upper */ - { 0xdc, 0xfc }, /* upper */ - { 0xdd, 0xfd }, /* upper */ - { 0xde, 0xfe }, /* upper */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xc0, 0xe0 }, /* lower */ - { 0xc1, 0xe1 }, /* lower */ - { 0xc2, 0xe2 }, /* lower */ - { 0xc3, 0xe3 }, /* lower */ - { 0xc4, 0xe4 }, /* lower */ - { 0xc5, 0xe5 }, /* lower */ - { 0xc6, 0xe6 }, /* lower */ - { 0xc7, 0xe7 }, /* lower */ - { 0xc8, 0xe8 }, /* lower */ - { 0xc9, 0xe9 }, /* lower */ - { 0xca, 0xea }, /* lower */ - { 0xcb, 0xeb }, /* lower */ - { 0xcc, 0xec }, /* lower */ - { 0xcd, 0xed }, /* lower */ - { 0xce, 0xee }, /* lower */ - { 0xcf, 0xef }, /* lower */ - { 0xd0, 0xf0 }, /* lower */ - { 0xd1, 0xf1 }, /* lower */ - { 0xd2, 0xf2 }, /* lower */ - { 0xd3, 0xf3 }, /* lower */ - { 0xd4, 0xf4 }, /* lower */ - { 0xd5, 0xf5 }, /* lower */ - { 0xd6, 0xf6 }, /* lower */ - { 0xf7, 0xf7 }, - { 0xd8, 0xf8 }, /* lower */ - { 0xd9, 0xf9 }, /* lower */ - { 0xda, 0xfa }, /* lower */ - { 0xdb, 0xfb }, /* lower */ - { 0xdc, 0xfc }, /* lower */ - { 0xdd, 0xfd }, /* lower */ - { 0xde, 0xfe }, /* lower */ - { 0x178, 0xff }, /* lower */ -}; - -static gli_case_block_t unigen_case_block_0x1[256] = { - { 0x100, 0x101 }, /* upper */ - { 0x100, 0x101 }, /* lower */ - { 0x102, 0x103 }, /* upper */ - { 0x102, 0x103 }, /* lower */ - { 0x104, 0x105 }, /* upper */ - { 0x104, 0x105 }, /* lower */ - { 0x106, 0x107 }, /* upper */ - { 0x106, 0x107 }, /* lower */ - { 0x108, 0x109 }, /* upper */ - { 0x108, 0x109 }, /* lower */ - { 0x10a, 0x10b }, /* upper */ - { 0x10a, 0x10b }, /* lower */ - { 0x10c, 0x10d }, /* upper */ - { 0x10c, 0x10d }, /* lower */ - { 0x10e, 0x10f }, /* upper */ - { 0x10e, 0x10f }, /* lower */ - { 0x110, 0x111 }, /* upper */ - { 0x110, 0x111 }, /* lower */ - { 0x112, 0x113 }, /* upper */ - { 0x112, 0x113 }, /* lower */ - { 0x114, 0x115 }, /* upper */ - { 0x114, 0x115 }, /* lower */ - { 0x116, 0x117 }, /* upper */ - { 0x116, 0x117 }, /* lower */ - { 0x118, 0x119 }, /* upper */ - { 0x118, 0x119 }, /* lower */ - { 0x11a, 0x11b }, /* upper */ - { 0x11a, 0x11b }, /* lower */ - { 0x11c, 0x11d }, /* upper */ - { 0x11c, 0x11d }, /* lower */ - { 0x11e, 0x11f }, /* upper */ - { 0x11e, 0x11f }, /* lower */ - { 0x120, 0x121 }, /* upper */ - { 0x120, 0x121 }, /* lower */ - { 0x122, 0x123 }, /* upper */ - { 0x122, 0x123 }, /* lower */ - { 0x124, 0x125 }, /* upper */ - { 0x124, 0x125 }, /* lower */ - { 0x126, 0x127 }, /* upper */ - { 0x126, 0x127 }, /* lower */ - { 0x128, 0x129 }, /* upper */ - { 0x128, 0x129 }, /* lower */ - { 0x12a, 0x12b }, /* upper */ - { 0x12a, 0x12b }, /* lower */ - { 0x12c, 0x12d }, /* upper */ - { 0x12c, 0x12d }, /* lower */ - { 0x12e, 0x12f }, /* upper */ - { 0x12e, 0x12f }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x49, 0x131 }, /* lower */ - { 0x132, 0x133 }, /* upper */ - { 0x132, 0x133 }, /* lower */ - { 0x134, 0x135 }, /* upper */ - { 0x134, 0x135 }, /* lower */ - { 0x136, 0x137 }, /* upper */ - { 0x136, 0x137 }, /* lower */ - { 0x138, 0x138 }, - { 0x139, 0x13a }, /* upper */ - { 0x139, 0x13a }, /* lower */ - { 0x13b, 0x13c }, /* upper */ - { 0x13b, 0x13c }, /* lower */ - { 0x13d, 0x13e }, /* upper */ - { 0x13d, 0x13e }, /* lower */ - { 0x13f, 0x140 }, /* upper */ - { 0x13f, 0x140 }, /* lower */ - { 0x141, 0x142 }, /* upper */ - { 0x141, 0x142 }, /* lower */ - { 0x143, 0x144 }, /* upper */ - { 0x143, 0x144 }, /* lower */ - { 0x145, 0x146 }, /* upper */ - { 0x145, 0x146 }, /* lower */ - { 0x147, 0x148 }, /* upper */ - { 0x147, 0x148 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x14a, 0x14b }, /* upper */ - { 0x14a, 0x14b }, /* lower */ - { 0x14c, 0x14d }, /* upper */ - { 0x14c, 0x14d }, /* lower */ - { 0x14e, 0x14f }, /* upper */ - { 0x14e, 0x14f }, /* lower */ - { 0x150, 0x151 }, /* upper */ - { 0x150, 0x151 }, /* lower */ - { 0x152, 0x153 }, /* upper */ - { 0x152, 0x153 }, /* lower */ - { 0x154, 0x155 }, /* upper */ - { 0x154, 0x155 }, /* lower */ - { 0x156, 0x157 }, /* upper */ - { 0x156, 0x157 }, /* lower */ - { 0x158, 0x159 }, /* upper */ - { 0x158, 0x159 }, /* lower */ - { 0x15a, 0x15b }, /* upper */ - { 0x15a, 0x15b }, /* lower */ - { 0x15c, 0x15d }, /* upper */ - { 0x15c, 0x15d }, /* lower */ - { 0x15e, 0x15f }, /* upper */ - { 0x15e, 0x15f }, /* lower */ - { 0x160, 0x161 }, /* upper */ - { 0x160, 0x161 }, /* lower */ - { 0x162, 0x163 }, /* upper */ - { 0x162, 0x163 }, /* lower */ - { 0x164, 0x165 }, /* upper */ - { 0x164, 0x165 }, /* lower */ - { 0x166, 0x167 }, /* upper */ - { 0x166, 0x167 }, /* lower */ - { 0x168, 0x169 }, /* upper */ - { 0x168, 0x169 }, /* lower */ - { 0x16a, 0x16b }, /* upper */ - { 0x16a, 0x16b }, /* lower */ - { 0x16c, 0x16d }, /* upper */ - { 0x16c, 0x16d }, /* lower */ - { 0x16e, 0x16f }, /* upper */ - { 0x16e, 0x16f }, /* lower */ - { 0x170, 0x171 }, /* upper */ - { 0x170, 0x171 }, /* lower */ - { 0x172, 0x173 }, /* upper */ - { 0x172, 0x173 }, /* lower */ - { 0x174, 0x175 }, /* upper */ - { 0x174, 0x175 }, /* lower */ - { 0x176, 0x177 }, /* upper */ - { 0x176, 0x177 }, /* lower */ - { 0x178, 0xff }, /* upper */ - { 0x179, 0x17a }, /* upper */ - { 0x179, 0x17a }, /* lower */ - { 0x17b, 0x17c }, /* upper */ - { 0x17b, 0x17c }, /* lower */ - { 0x17d, 0x17e }, /* upper */ - { 0x17d, 0x17e }, /* lower */ - { 0x53, 0x17f }, /* lower */ - { 0x180, 0x180 }, - { 0x181, 0x253 }, /* upper */ - { 0x182, 0x183 }, /* upper */ - { 0x182, 0x183 }, /* lower */ - { 0x184, 0x185 }, /* upper */ - { 0x184, 0x185 }, /* lower */ - { 0x186, 0x254 }, /* upper */ - { 0x187, 0x188 }, /* upper */ - { 0x187, 0x188 }, /* lower */ - { 0x189, 0x256 }, /* upper */ - { 0x18a, 0x257 }, /* upper */ - { 0x18b, 0x18c }, /* upper */ - { 0x18b, 0x18c }, /* lower */ - { 0x18d, 0x18d }, - { 0x18e, 0x1dd }, /* upper */ - { 0x18f, 0x259 }, /* upper */ - { 0x190, 0x25b }, /* upper */ - { 0x191, 0x192 }, /* upper */ - { 0x191, 0x192 }, /* lower */ - { 0x193, 0x260 }, /* upper */ - { 0x194, 0x263 }, /* upper */ - { 0x1f6, 0x195 }, /* lower */ - { 0x196, 0x269 }, /* upper */ - { 0x197, 0x268 }, /* upper */ - { 0x198, 0x199 }, /* upper */ - { 0x198, 0x199 }, /* lower */ - { 0x19a, 0x19a }, - { 0x19b, 0x19b }, - { 0x19c, 0x26f }, /* upper */ - { 0x19d, 0x272 }, /* upper */ - { 0x220, 0x19e }, /* lower */ - { 0x19f, 0x275 }, /* upper */ - { 0x1a0, 0x1a1 }, /* upper */ - { 0x1a0, 0x1a1 }, /* lower */ - { 0x1a2, 0x1a3 }, /* upper */ - { 0x1a2, 0x1a3 }, /* lower */ - { 0x1a4, 0x1a5 }, /* upper */ - { 0x1a4, 0x1a5 }, /* lower */ - { 0x1a6, 0x280 }, /* upper */ - { 0x1a7, 0x1a8 }, /* upper */ - { 0x1a7, 0x1a8 }, /* lower */ - { 0x1a9, 0x283 }, /* upper */ - { 0x1aa, 0x1aa }, - { 0x1ab, 0x1ab }, - { 0x1ac, 0x1ad }, /* upper */ - { 0x1ac, 0x1ad }, /* lower */ - { 0x1ae, 0x288 }, /* upper */ - { 0x1af, 0x1b0 }, /* upper */ - { 0x1af, 0x1b0 }, /* lower */ - { 0x1b1, 0x28a }, /* upper */ - { 0x1b2, 0x28b }, /* upper */ - { 0x1b3, 0x1b4 }, /* upper */ - { 0x1b3, 0x1b4 }, /* lower */ - { 0x1b5, 0x1b6 }, /* upper */ - { 0x1b5, 0x1b6 }, /* lower */ - { 0x1b7, 0x292 }, /* upper */ - { 0x1b8, 0x1b9 }, /* upper */ - { 0x1b8, 0x1b9 }, /* lower */ - { 0x1ba, 0x1ba }, - { 0x1bb, 0x1bb }, - { 0x1bc, 0x1bd }, /* upper */ - { 0x1bc, 0x1bd }, /* lower */ - { 0x1be, 0x1be }, - { 0x1f7, 0x1bf }, /* lower */ - { 0x1c0, 0x1c0 }, - { 0x1c1, 0x1c1 }, - { 0x1c2, 0x1c2 }, - { 0x1c3, 0x1c3 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1cd, 0x1ce }, /* upper */ - { 0x1cd, 0x1ce }, /* lower */ - { 0x1cf, 0x1d0 }, /* upper */ - { 0x1cf, 0x1d0 }, /* lower */ - { 0x1d1, 0x1d2 }, /* upper */ - { 0x1d1, 0x1d2 }, /* lower */ - { 0x1d3, 0x1d4 }, /* upper */ - { 0x1d3, 0x1d4 }, /* lower */ - { 0x1d5, 0x1d6 }, /* upper */ - { 0x1d5, 0x1d6 }, /* lower */ - { 0x1d7, 0x1d8 }, /* upper */ - { 0x1d7, 0x1d8 }, /* lower */ - { 0x1d9, 0x1da }, /* upper */ - { 0x1d9, 0x1da }, /* lower */ - { 0x1db, 0x1dc }, /* upper */ - { 0x1db, 0x1dc }, /* lower */ - { 0x18e, 0x1dd }, /* lower */ - { 0x1de, 0x1df }, /* upper */ - { 0x1de, 0x1df }, /* lower */ - { 0x1e0, 0x1e1 }, /* upper */ - { 0x1e0, 0x1e1 }, /* lower */ - { 0x1e2, 0x1e3 }, /* upper */ - { 0x1e2, 0x1e3 }, /* lower */ - { 0x1e4, 0x1e5 }, /* upper */ - { 0x1e4, 0x1e5 }, /* lower */ - { 0x1e6, 0x1e7 }, /* upper */ - { 0x1e6, 0x1e7 }, /* lower */ - { 0x1e8, 0x1e9 }, /* upper */ - { 0x1e8, 0x1e9 }, /* lower */ - { 0x1ea, 0x1eb }, /* upper */ - { 0x1ea, 0x1eb }, /* lower */ - { 0x1ec, 0x1ed }, /* upper */ - { 0x1ec, 0x1ed }, /* lower */ - { 0x1ee, 0x1ef }, /* upper */ - { 0x1ee, 0x1ef }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1f4, 0x1f5 }, /* upper */ - { 0x1f4, 0x1f5 }, /* lower */ - { 0x1f6, 0x195 }, /* upper */ - { 0x1f7, 0x1bf }, /* upper */ - { 0x1f8, 0x1f9 }, /* upper */ - { 0x1f8, 0x1f9 }, /* lower */ - { 0x1fa, 0x1fb }, /* upper */ - { 0x1fa, 0x1fb }, /* lower */ - { 0x1fc, 0x1fd }, /* upper */ - { 0x1fc, 0x1fd }, /* lower */ - { 0x1fe, 0x1ff }, /* upper */ - { 0x1fe, 0x1ff }, /* lower */ -}; - -static gli_case_block_t unigen_case_block_0x2[256] = { - { 0x200, 0x201 }, /* upper */ - { 0x200, 0x201 }, /* lower */ - { 0x202, 0x203 }, /* upper */ - { 0x202, 0x203 }, /* lower */ - { 0x204, 0x205 }, /* upper */ - { 0x204, 0x205 }, /* lower */ - { 0x206, 0x207 }, /* upper */ - { 0x206, 0x207 }, /* lower */ - { 0x208, 0x209 }, /* upper */ - { 0x208, 0x209 }, /* lower */ - { 0x20a, 0x20b }, /* upper */ - { 0x20a, 0x20b }, /* lower */ - { 0x20c, 0x20d }, /* upper */ - { 0x20c, 0x20d }, /* lower */ - { 0x20e, 0x20f }, /* upper */ - { 0x20e, 0x20f }, /* lower */ - { 0x210, 0x211 }, /* upper */ - { 0x210, 0x211 }, /* lower */ - { 0x212, 0x213 }, /* upper */ - { 0x212, 0x213 }, /* lower */ - { 0x214, 0x215 }, /* upper */ - { 0x214, 0x215 }, /* lower */ - { 0x216, 0x217 }, /* upper */ - { 0x216, 0x217 }, /* lower */ - { 0x218, 0x219 }, /* upper */ - { 0x218, 0x219 }, /* lower */ - { 0x21a, 0x21b }, /* upper */ - { 0x21a, 0x21b }, /* lower */ - { 0x21c, 0x21d }, /* upper */ - { 0x21c, 0x21d }, /* lower */ - { 0x21e, 0x21f }, /* upper */ - { 0x21e, 0x21f }, /* lower */ - { 0x220, 0x19e }, /* upper */ - { 0x221, 0x221 }, - { 0x222, 0x223 }, /* upper */ - { 0x222, 0x223 }, /* lower */ - { 0x224, 0x225 }, /* upper */ - { 0x224, 0x225 }, /* lower */ - { 0x226, 0x227 }, /* upper */ - { 0x226, 0x227 }, /* lower */ - { 0x228, 0x229 }, /* upper */ - { 0x228, 0x229 }, /* lower */ - { 0x22a, 0x22b }, /* upper */ - { 0x22a, 0x22b }, /* lower */ - { 0x22c, 0x22d }, /* upper */ - { 0x22c, 0x22d }, /* lower */ - { 0x22e, 0x22f }, /* upper */ - { 0x22e, 0x22f }, /* lower */ - { 0x230, 0x231 }, /* upper */ - { 0x230, 0x231 }, /* lower */ - { 0x232, 0x233 }, /* upper */ - { 0x232, 0x233 }, /* lower */ - { 0x234, 0x234 }, - { 0x235, 0x235 }, - { 0x236, 0x236 }, - { 0x237, 0x237 }, - { 0x238, 0x238 }, - { 0x239, 0x239 }, - { 0x23a, 0x23a }, - { 0x23b, 0x23b }, - { 0x23c, 0x23c }, - { 0x23d, 0x23d }, - { 0x23e, 0x23e }, - { 0x23f, 0x23f }, - { 0x240, 0x240 }, - { 0x241, 0x241 }, - { 0x242, 0x242 }, - { 0x243, 0x243 }, - { 0x244, 0x244 }, - { 0x245, 0x245 }, - { 0x246, 0x246 }, - { 0x247, 0x247 }, - { 0x248, 0x248 }, - { 0x249, 0x249 }, - { 0x24a, 0x24a }, - { 0x24b, 0x24b }, - { 0x24c, 0x24c }, - { 0x24d, 0x24d }, - { 0x24e, 0x24e }, - { 0x24f, 0x24f }, - { 0x250, 0x250 }, - { 0x251, 0x251 }, - { 0x252, 0x252 }, - { 0x181, 0x253 }, /* lower */ - { 0x186, 0x254 }, /* lower */ - { 0x255, 0x255 }, - { 0x189, 0x256 }, /* lower */ - { 0x18a, 0x257 }, /* lower */ - { 0x258, 0x258 }, - { 0x18f, 0x259 }, /* lower */ - { 0x25a, 0x25a }, - { 0x190, 0x25b }, /* lower */ - { 0x25c, 0x25c }, - { 0x25d, 0x25d }, - { 0x25e, 0x25e }, - { 0x25f, 0x25f }, - { 0x193, 0x260 }, /* lower */ - { 0x261, 0x261 }, - { 0x262, 0x262 }, - { 0x194, 0x263 }, /* lower */ - { 0x264, 0x264 }, - { 0x265, 0x265 }, - { 0x266, 0x266 }, - { 0x267, 0x267 }, - { 0x197, 0x268 }, /* lower */ - { 0x196, 0x269 }, /* lower */ - { 0x26a, 0x26a }, - { 0x26b, 0x26b }, - { 0x26c, 0x26c }, - { 0x26d, 0x26d }, - { 0x26e, 0x26e }, - { 0x19c, 0x26f }, /* lower */ - { 0x270, 0x270 }, - { 0x271, 0x271 }, - { 0x19d, 0x272 }, /* lower */ - { 0x273, 0x273 }, - { 0x274, 0x274 }, - { 0x19f, 0x275 }, /* lower */ - { 0x276, 0x276 }, - { 0x277, 0x277 }, - { 0x278, 0x278 }, - { 0x279, 0x279 }, - { 0x27a, 0x27a }, - { 0x27b, 0x27b }, - { 0x27c, 0x27c }, - { 0x27d, 0x27d }, - { 0x27e, 0x27e }, - { 0x27f, 0x27f }, - { 0x1a6, 0x280 }, /* lower */ - { 0x281, 0x281 }, - { 0x282, 0x282 }, - { 0x1a9, 0x283 }, /* lower */ - { 0x284, 0x284 }, - { 0x285, 0x285 }, - { 0x286, 0x286 }, - { 0x287, 0x287 }, - { 0x1ae, 0x288 }, /* lower */ - { 0x289, 0x289 }, - { 0x1b1, 0x28a }, /* lower */ - { 0x1b2, 0x28b }, /* lower */ - { 0x28c, 0x28c }, - { 0x28d, 0x28d }, - { 0x28e, 0x28e }, - { 0x28f, 0x28f }, - { 0x290, 0x290 }, - { 0x291, 0x291 }, - { 0x1b7, 0x292 }, /* lower */ - { 0x293, 0x293 }, - { 0x294, 0x294 }, - { 0x295, 0x295 }, - { 0x296, 0x296 }, - { 0x297, 0x297 }, - { 0x298, 0x298 }, - { 0x299, 0x299 }, - { 0x29a, 0x29a }, - { 0x29b, 0x29b }, - { 0x29c, 0x29c }, - { 0x29d, 0x29d }, - { 0x29e, 0x29e }, - { 0x29f, 0x29f }, - { 0x2a0, 0x2a0 }, - { 0x2a1, 0x2a1 }, - { 0x2a2, 0x2a2 }, - { 0x2a3, 0x2a3 }, - { 0x2a4, 0x2a4 }, - { 0x2a5, 0x2a5 }, - { 0x2a6, 0x2a6 }, - { 0x2a7, 0x2a7 }, - { 0x2a8, 0x2a8 }, - { 0x2a9, 0x2a9 }, - { 0x2aa, 0x2aa }, - { 0x2ab, 0x2ab }, - { 0x2ac, 0x2ac }, - { 0x2ad, 0x2ad }, - { 0x2ae, 0x2ae }, - { 0x2af, 0x2af }, - { 0x2b0, 0x2b0 }, - { 0x2b1, 0x2b1 }, - { 0x2b2, 0x2b2 }, - { 0x2b3, 0x2b3 }, - { 0x2b4, 0x2b4 }, - { 0x2b5, 0x2b5 }, - { 0x2b6, 0x2b6 }, - { 0x2b7, 0x2b7 }, - { 0x2b8, 0x2b8 }, - { 0x2b9, 0x2b9 }, - { 0x2ba, 0x2ba }, - { 0x2bb, 0x2bb }, - { 0x2bc, 0x2bc }, - { 0x2bd, 0x2bd }, - { 0x2be, 0x2be }, - { 0x2bf, 0x2bf }, - { 0x2c0, 0x2c0 }, - { 0x2c1, 0x2c1 }, - { 0x2c2, 0x2c2 }, - { 0x2c3, 0x2c3 }, - { 0x2c4, 0x2c4 }, - { 0x2c5, 0x2c5 }, - { 0x2c6, 0x2c6 }, - { 0x2c7, 0x2c7 }, - { 0x2c8, 0x2c8 }, - { 0x2c9, 0x2c9 }, - { 0x2ca, 0x2ca }, - { 0x2cb, 0x2cb }, - { 0x2cc, 0x2cc }, - { 0x2cd, 0x2cd }, - { 0x2ce, 0x2ce }, - { 0x2cf, 0x2cf }, - { 0x2d0, 0x2d0 }, - { 0x2d1, 0x2d1 }, - { 0x2d2, 0x2d2 }, - { 0x2d3, 0x2d3 }, - { 0x2d4, 0x2d4 }, - { 0x2d5, 0x2d5 }, - { 0x2d6, 0x2d6 }, - { 0x2d7, 0x2d7 }, - { 0x2d8, 0x2d8 }, - { 0x2d9, 0x2d9 }, - { 0x2da, 0x2da }, - { 0x2db, 0x2db }, - { 0x2dc, 0x2dc }, - { 0x2dd, 0x2dd }, - { 0x2de, 0x2de }, - { 0x2df, 0x2df }, - { 0x2e0, 0x2e0 }, - { 0x2e1, 0x2e1 }, - { 0x2e2, 0x2e2 }, - { 0x2e3, 0x2e3 }, - { 0x2e4, 0x2e4 }, - { 0x2e5, 0x2e5 }, - { 0x2e6, 0x2e6 }, - { 0x2e7, 0x2e7 }, - { 0x2e8, 0x2e8 }, - { 0x2e9, 0x2e9 }, - { 0x2ea, 0x2ea }, - { 0x2eb, 0x2eb }, - { 0x2ec, 0x2ec }, - { 0x2ed, 0x2ed }, - { 0x2ee, 0x2ee }, - { 0x2ef, 0x2ef }, - { 0x2f0, 0x2f0 }, - { 0x2f1, 0x2f1 }, - { 0x2f2, 0x2f2 }, - { 0x2f3, 0x2f3 }, - { 0x2f4, 0x2f4 }, - { 0x2f5, 0x2f5 }, - { 0x2f6, 0x2f6 }, - { 0x2f7, 0x2f7 }, - { 0x2f8, 0x2f8 }, - { 0x2f9, 0x2f9 }, - { 0x2fa, 0x2fa }, - { 0x2fb, 0x2fb }, - { 0x2fc, 0x2fc }, - { 0x2fd, 0x2fd }, - { 0x2fe, 0x2fe }, - { 0x2ff, 0x2ff }, -}; - -static gli_case_block_t unigen_case_block_0x3[256] = { - { 0x300, 0x300 }, - { 0x301, 0x301 }, - { 0x302, 0x302 }, - { 0x303, 0x303 }, - { 0x304, 0x304 }, - { 0x305, 0x305 }, - { 0x306, 0x306 }, - { 0x307, 0x307 }, - { 0x308, 0x308 }, - { 0x309, 0x309 }, - { 0x30a, 0x30a }, - { 0x30b, 0x30b }, - { 0x30c, 0x30c }, - { 0x30d, 0x30d }, - { 0x30e, 0x30e }, - { 0x30f, 0x30f }, - { 0x310, 0x310 }, - { 0x311, 0x311 }, - { 0x312, 0x312 }, - { 0x313, 0x313 }, - { 0x314, 0x314 }, - { 0x315, 0x315 }, - { 0x316, 0x316 }, - { 0x317, 0x317 }, - { 0x318, 0x318 }, - { 0x319, 0x319 }, - { 0x31a, 0x31a }, - { 0x31b, 0x31b }, - { 0x31c, 0x31c }, - { 0x31d, 0x31d }, - { 0x31e, 0x31e }, - { 0x31f, 0x31f }, - { 0x320, 0x320 }, - { 0x321, 0x321 }, - { 0x322, 0x322 }, - { 0x323, 0x323 }, - { 0x324, 0x324 }, - { 0x325, 0x325 }, - { 0x326, 0x326 }, - { 0x327, 0x327 }, - { 0x328, 0x328 }, - { 0x329, 0x329 }, - { 0x32a, 0x32a }, - { 0x32b, 0x32b }, - { 0x32c, 0x32c }, - { 0x32d, 0x32d }, - { 0x32e, 0x32e }, - { 0x32f, 0x32f }, - { 0x330, 0x330 }, - { 0x331, 0x331 }, - { 0x332, 0x332 }, - { 0x333, 0x333 }, - { 0x334, 0x334 }, - { 0x335, 0x335 }, - { 0x336, 0x336 }, - { 0x337, 0x337 }, - { 0x338, 0x338 }, - { 0x339, 0x339 }, - { 0x33a, 0x33a }, - { 0x33b, 0x33b }, - { 0x33c, 0x33c }, - { 0x33d, 0x33d }, - { 0x33e, 0x33e }, - { 0x33f, 0x33f }, - { 0x340, 0x340 }, - { 0x341, 0x341 }, - { 0x342, 0x342 }, - { 0x343, 0x343 }, - { 0x344, 0x344 }, - { 0x399, 0x345 }, /* lower */ - { 0x346, 0x346 }, - { 0x347, 0x347 }, - { 0x348, 0x348 }, - { 0x349, 0x349 }, - { 0x34a, 0x34a }, - { 0x34b, 0x34b }, - { 0x34c, 0x34c }, - { 0x34d, 0x34d }, - { 0x34e, 0x34e }, - { 0x34f, 0x34f }, - { 0x350, 0x350 }, - { 0x351, 0x351 }, - { 0x352, 0x352 }, - { 0x353, 0x353 }, - { 0x354, 0x354 }, - { 0x355, 0x355 }, - { 0x356, 0x356 }, - { 0x357, 0x357 }, - { 0x358, 0x358 }, - { 0x359, 0x359 }, - { 0x35a, 0x35a }, - { 0x35b, 0x35b }, - { 0x35c, 0x35c }, - { 0x35d, 0x35d }, - { 0x35e, 0x35e }, - { 0x35f, 0x35f }, - { 0x360, 0x360 }, - { 0x361, 0x361 }, - { 0x362, 0x362 }, - { 0x363, 0x363 }, - { 0x364, 0x364 }, - { 0x365, 0x365 }, - { 0x366, 0x366 }, - { 0x367, 0x367 }, - { 0x368, 0x368 }, - { 0x369, 0x369 }, - { 0x36a, 0x36a }, - { 0x36b, 0x36b }, - { 0x36c, 0x36c }, - { 0x36d, 0x36d }, - { 0x36e, 0x36e }, - { 0x36f, 0x36f }, - { 0x370, 0x370 }, - { 0x371, 0x371 }, - { 0x372, 0x372 }, - { 0x373, 0x373 }, - { 0x374, 0x374 }, - { 0x375, 0x375 }, - { 0x376, 0x376 }, - { 0x377, 0x377 }, - { 0x378, 0x378 }, - { 0x379, 0x379 }, - { 0x37a, 0x37a }, - { 0x37b, 0x37b }, - { 0x37c, 0x37c }, - { 0x37d, 0x37d }, - { 0x37e, 0x37e }, - { 0x37f, 0x37f }, - { 0x380, 0x380 }, - { 0x381, 0x381 }, - { 0x382, 0x382 }, - { 0x383, 0x383 }, - { 0x384, 0x384 }, - { 0x385, 0x385 }, - { 0x386, 0x3ac }, /* upper */ - { 0x387, 0x387 }, - { 0x388, 0x3ad }, /* upper */ - { 0x389, 0x3ae }, /* upper */ - { 0x38a, 0x3af }, /* upper */ - { 0x38b, 0x38b }, - { 0x38c, 0x3cc }, /* upper */ - { 0x38d, 0x38d }, - { 0x38e, 0x3cd }, /* upper */ - { 0x38f, 0x3ce }, /* upper */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x391, 0x3b1 }, /* upper */ - { 0x392, 0x3b2 }, /* upper */ - { 0x393, 0x3b3 }, /* upper */ - { 0x394, 0x3b4 }, /* upper */ - { 0x395, 0x3b5 }, /* upper */ - { 0x396, 0x3b6 }, /* upper */ - { 0x397, 0x3b7 }, /* upper */ - { 0x398, 0x3b8 }, /* upper */ - { 0x399, 0x3b9 }, /* upper */ - { 0x39a, 0x3ba }, /* upper */ - { 0x39b, 0x3bb }, /* upper */ - { 0x39c, 0x3bc }, /* upper */ - { 0x39d, 0x3bd }, /* upper */ - { 0x39e, 0x3be }, /* upper */ - { 0x39f, 0x3bf }, /* upper */ - { 0x3a0, 0x3c0 }, /* upper */ - { 0x3a1, 0x3c1 }, /* upper */ - { 0x3a2, 0x3a2 }, - { 0x3a3, 0x3c3 }, /* upper */ - { 0x3a4, 0x3c4 }, /* upper */ - { 0x3a5, 0x3c5 }, /* upper */ - { 0x3a6, 0x3c6 }, /* upper */ - { 0x3a7, 0x3c7 }, /* upper */ - { 0x3a8, 0x3c8 }, /* upper */ - { 0x3a9, 0x3c9 }, /* upper */ - { 0x3aa, 0x3ca }, /* upper */ - { 0x3ab, 0x3cb }, /* upper */ - { 0x386, 0x3ac }, /* lower */ - { 0x388, 0x3ad }, /* lower */ - { 0x389, 0x3ae }, /* lower */ - { 0x38a, 0x3af }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x391, 0x3b1 }, /* lower */ - { 0x392, 0x3b2 }, /* lower */ - { 0x393, 0x3b3 }, /* lower */ - { 0x394, 0x3b4 }, /* lower */ - { 0x395, 0x3b5 }, /* lower */ - { 0x396, 0x3b6 }, /* lower */ - { 0x397, 0x3b7 }, /* lower */ - { 0x398, 0x3b8 }, /* lower */ - { 0x399, 0x3b9 }, /* lower */ - { 0x39a, 0x3ba }, /* lower */ - { 0x39b, 0x3bb }, /* lower */ - { 0x39c, 0x3bc }, /* lower */ - { 0x39d, 0x3bd }, /* lower */ - { 0x39e, 0x3be }, /* lower */ - { 0x39f, 0x3bf }, /* lower */ - { 0x3a0, 0x3c0 }, /* lower */ - { 0x3a1, 0x3c1 }, /* lower */ - { 0x3a3, 0x3c2 }, /* lower */ - { 0x3a3, 0x3c3 }, /* lower */ - { 0x3a4, 0x3c4 }, /* lower */ - { 0x3a5, 0x3c5 }, /* lower */ - { 0x3a6, 0x3c6 }, /* lower */ - { 0x3a7, 0x3c7 }, /* lower */ - { 0x3a8, 0x3c8 }, /* lower */ - { 0x3a9, 0x3c9 }, /* lower */ - { 0x3aa, 0x3ca }, /* lower */ - { 0x3ab, 0x3cb }, /* lower */ - { 0x38c, 0x3cc }, /* lower */ - { 0x38e, 0x3cd }, /* lower */ - { 0x38f, 0x3ce }, /* lower */ - { 0x3cf, 0x3cf }, - { 0x392, 0x3d0 }, /* lower */ - { 0x398, 0x3d1 }, /* lower */ - { 0x3d2, 0x3d2 }, - { 0x3d3, 0x3d3 }, - { 0x3d4, 0x3d4 }, - { 0x3a6, 0x3d5 }, /* lower */ - { 0x3a0, 0x3d6 }, /* lower */ - { 0x3d7, 0x3d7 }, - { 0x3d8, 0x3d9 }, /* upper */ - { 0x3d8, 0x3d9 }, /* lower */ - { 0x3da, 0x3db }, /* upper */ - { 0x3da, 0x3db }, /* lower */ - { 0x3dc, 0x3dd }, /* upper */ - { 0x3dc, 0x3dd }, /* lower */ - { 0x3de, 0x3df }, /* upper */ - { 0x3de, 0x3df }, /* lower */ - { 0x3e0, 0x3e1 }, /* upper */ - { 0x3e0, 0x3e1 }, /* lower */ - { 0x3e2, 0x3e3 }, /* upper */ - { 0x3e2, 0x3e3 }, /* lower */ - { 0x3e4, 0x3e5 }, /* upper */ - { 0x3e4, 0x3e5 }, /* lower */ - { 0x3e6, 0x3e7 }, /* upper */ - { 0x3e6, 0x3e7 }, /* lower */ - { 0x3e8, 0x3e9 }, /* upper */ - { 0x3e8, 0x3e9 }, /* lower */ - { 0x3ea, 0x3eb }, /* upper */ - { 0x3ea, 0x3eb }, /* lower */ - { 0x3ec, 0x3ed }, /* upper */ - { 0x3ec, 0x3ed }, /* lower */ - { 0x3ee, 0x3ef }, /* upper */ - { 0x3ee, 0x3ef }, /* lower */ - { 0x39a, 0x3f0 }, /* lower */ - { 0x3a1, 0x3f1 }, /* lower */ - { 0x3f9, 0x3f2 }, /* lower */ - { 0x3f3, 0x3f3 }, - { 0x3f4, 0x3b8 }, /* upper */ - { 0x395, 0x3f5 }, /* lower */ - { 0x3f6, 0x3f6 }, - { 0x3f7, 0x3f8 }, /* upper */ - { 0x3f7, 0x3f8 }, /* lower */ - { 0x3f9, 0x3f2 }, /* upper */ - { 0x3fa, 0x3fb }, /* upper */ - { 0x3fa, 0x3fb }, /* lower */ - { 0x3fc, 0x3fc }, - { 0x3fd, 0x3fd }, - { 0x3fe, 0x3fe }, - { 0x3ff, 0x3ff }, -}; - -static gli_case_block_t unigen_case_block_0x4[256] = { - { 0x400, 0x450 }, /* upper */ - { 0x401, 0x451 }, /* upper */ - { 0x402, 0x452 }, /* upper */ - { 0x403, 0x453 }, /* upper */ - { 0x404, 0x454 }, /* upper */ - { 0x405, 0x455 }, /* upper */ - { 0x406, 0x456 }, /* upper */ - { 0x407, 0x457 }, /* upper */ - { 0x408, 0x458 }, /* upper */ - { 0x409, 0x459 }, /* upper */ - { 0x40a, 0x45a }, /* upper */ - { 0x40b, 0x45b }, /* upper */ - { 0x40c, 0x45c }, /* upper */ - { 0x40d, 0x45d }, /* upper */ - { 0x40e, 0x45e }, /* upper */ - { 0x40f, 0x45f }, /* upper */ - { 0x410, 0x430 }, /* upper */ - { 0x411, 0x431 }, /* upper */ - { 0x412, 0x432 }, /* upper */ - { 0x413, 0x433 }, /* upper */ - { 0x414, 0x434 }, /* upper */ - { 0x415, 0x435 }, /* upper */ - { 0x416, 0x436 }, /* upper */ - { 0x417, 0x437 }, /* upper */ - { 0x418, 0x438 }, /* upper */ - { 0x419, 0x439 }, /* upper */ - { 0x41a, 0x43a }, /* upper */ - { 0x41b, 0x43b }, /* upper */ - { 0x41c, 0x43c }, /* upper */ - { 0x41d, 0x43d }, /* upper */ - { 0x41e, 0x43e }, /* upper */ - { 0x41f, 0x43f }, /* upper */ - { 0x420, 0x440 }, /* upper */ - { 0x421, 0x441 }, /* upper */ - { 0x422, 0x442 }, /* upper */ - { 0x423, 0x443 }, /* upper */ - { 0x424, 0x444 }, /* upper */ - { 0x425, 0x445 }, /* upper */ - { 0x426, 0x446 }, /* upper */ - { 0x427, 0x447 }, /* upper */ - { 0x428, 0x448 }, /* upper */ - { 0x429, 0x449 }, /* upper */ - { 0x42a, 0x44a }, /* upper */ - { 0x42b, 0x44b }, /* upper */ - { 0x42c, 0x44c }, /* upper */ - { 0x42d, 0x44d }, /* upper */ - { 0x42e, 0x44e }, /* upper */ - { 0x42f, 0x44f }, /* upper */ - { 0x410, 0x430 }, /* lower */ - { 0x411, 0x431 }, /* lower */ - { 0x412, 0x432 }, /* lower */ - { 0x413, 0x433 }, /* lower */ - { 0x414, 0x434 }, /* lower */ - { 0x415, 0x435 }, /* lower */ - { 0x416, 0x436 }, /* lower */ - { 0x417, 0x437 }, /* lower */ - { 0x418, 0x438 }, /* lower */ - { 0x419, 0x439 }, /* lower */ - { 0x41a, 0x43a }, /* lower */ - { 0x41b, 0x43b }, /* lower */ - { 0x41c, 0x43c }, /* lower */ - { 0x41d, 0x43d }, /* lower */ - { 0x41e, 0x43e }, /* lower */ - { 0x41f, 0x43f }, /* lower */ - { 0x420, 0x440 }, /* lower */ - { 0x421, 0x441 }, /* lower */ - { 0x422, 0x442 }, /* lower */ - { 0x423, 0x443 }, /* lower */ - { 0x424, 0x444 }, /* lower */ - { 0x425, 0x445 }, /* lower */ - { 0x426, 0x446 }, /* lower */ - { 0x427, 0x447 }, /* lower */ - { 0x428, 0x448 }, /* lower */ - { 0x429, 0x449 }, /* lower */ - { 0x42a, 0x44a }, /* lower */ - { 0x42b, 0x44b }, /* lower */ - { 0x42c, 0x44c }, /* lower */ - { 0x42d, 0x44d }, /* lower */ - { 0x42e, 0x44e }, /* lower */ - { 0x42f, 0x44f }, /* lower */ - { 0x400, 0x450 }, /* lower */ - { 0x401, 0x451 }, /* lower */ - { 0x402, 0x452 }, /* lower */ - { 0x403, 0x453 }, /* lower */ - { 0x404, 0x454 }, /* lower */ - { 0x405, 0x455 }, /* lower */ - { 0x406, 0x456 }, /* lower */ - { 0x407, 0x457 }, /* lower */ - { 0x408, 0x458 }, /* lower */ - { 0x409, 0x459 }, /* lower */ - { 0x40a, 0x45a }, /* lower */ - { 0x40b, 0x45b }, /* lower */ - { 0x40c, 0x45c }, /* lower */ - { 0x40d, 0x45d }, /* lower */ - { 0x40e, 0x45e }, /* lower */ - { 0x40f, 0x45f }, /* lower */ - { 0x460, 0x461 }, /* upper */ - { 0x460, 0x461 }, /* lower */ - { 0x462, 0x463 }, /* upper */ - { 0x462, 0x463 }, /* lower */ - { 0x464, 0x465 }, /* upper */ - { 0x464, 0x465 }, /* lower */ - { 0x466, 0x467 }, /* upper */ - { 0x466, 0x467 }, /* lower */ - { 0x468, 0x469 }, /* upper */ - { 0x468, 0x469 }, /* lower */ - { 0x46a, 0x46b }, /* upper */ - { 0x46a, 0x46b }, /* lower */ - { 0x46c, 0x46d }, /* upper */ - { 0x46c, 0x46d }, /* lower */ - { 0x46e, 0x46f }, /* upper */ - { 0x46e, 0x46f }, /* lower */ - { 0x470, 0x471 }, /* upper */ - { 0x470, 0x471 }, /* lower */ - { 0x472, 0x473 }, /* upper */ - { 0x472, 0x473 }, /* lower */ - { 0x474, 0x475 }, /* upper */ - { 0x474, 0x475 }, /* lower */ - { 0x476, 0x477 }, /* upper */ - { 0x476, 0x477 }, /* lower */ - { 0x478, 0x479 }, /* upper */ - { 0x478, 0x479 }, /* lower */ - { 0x47a, 0x47b }, /* upper */ - { 0x47a, 0x47b }, /* lower */ - { 0x47c, 0x47d }, /* upper */ - { 0x47c, 0x47d }, /* lower */ - { 0x47e, 0x47f }, /* upper */ - { 0x47e, 0x47f }, /* lower */ - { 0x480, 0x481 }, /* upper */ - { 0x480, 0x481 }, /* lower */ - { 0x482, 0x482 }, - { 0x483, 0x483 }, - { 0x484, 0x484 }, - { 0x485, 0x485 }, - { 0x486, 0x486 }, - { 0x487, 0x487 }, - { 0x488, 0x488 }, - { 0x489, 0x489 }, - { 0x48a, 0x48b }, /* upper */ - { 0x48a, 0x48b }, /* lower */ - { 0x48c, 0x48d }, /* upper */ - { 0x48c, 0x48d }, /* lower */ - { 0x48e, 0x48f }, /* upper */ - { 0x48e, 0x48f }, /* lower */ - { 0x490, 0x491 }, /* upper */ - { 0x490, 0x491 }, /* lower */ - { 0x492, 0x493 }, /* upper */ - { 0x492, 0x493 }, /* lower */ - { 0x494, 0x495 }, /* upper */ - { 0x494, 0x495 }, /* lower */ - { 0x496, 0x497 }, /* upper */ - { 0x496, 0x497 }, /* lower */ - { 0x498, 0x499 }, /* upper */ - { 0x498, 0x499 }, /* lower */ - { 0x49a, 0x49b }, /* upper */ - { 0x49a, 0x49b }, /* lower */ - { 0x49c, 0x49d }, /* upper */ - { 0x49c, 0x49d }, /* lower */ - { 0x49e, 0x49f }, /* upper */ - { 0x49e, 0x49f }, /* lower */ - { 0x4a0, 0x4a1 }, /* upper */ - { 0x4a0, 0x4a1 }, /* lower */ - { 0x4a2, 0x4a3 }, /* upper */ - { 0x4a2, 0x4a3 }, /* lower */ - { 0x4a4, 0x4a5 }, /* upper */ - { 0x4a4, 0x4a5 }, /* lower */ - { 0x4a6, 0x4a7 }, /* upper */ - { 0x4a6, 0x4a7 }, /* lower */ - { 0x4a8, 0x4a9 }, /* upper */ - { 0x4a8, 0x4a9 }, /* lower */ - { 0x4aa, 0x4ab }, /* upper */ - { 0x4aa, 0x4ab }, /* lower */ - { 0x4ac, 0x4ad }, /* upper */ - { 0x4ac, 0x4ad }, /* lower */ - { 0x4ae, 0x4af }, /* upper */ - { 0x4ae, 0x4af }, /* lower */ - { 0x4b0, 0x4b1 }, /* upper */ - { 0x4b0, 0x4b1 }, /* lower */ - { 0x4b2, 0x4b3 }, /* upper */ - { 0x4b2, 0x4b3 }, /* lower */ - { 0x4b4, 0x4b5 }, /* upper */ - { 0x4b4, 0x4b5 }, /* lower */ - { 0x4b6, 0x4b7 }, /* upper */ - { 0x4b6, 0x4b7 }, /* lower */ - { 0x4b8, 0x4b9 }, /* upper */ - { 0x4b8, 0x4b9 }, /* lower */ - { 0x4ba, 0x4bb }, /* upper */ - { 0x4ba, 0x4bb }, /* lower */ - { 0x4bc, 0x4bd }, /* upper */ - { 0x4bc, 0x4bd }, /* lower */ - { 0x4be, 0x4bf }, /* upper */ - { 0x4be, 0x4bf }, /* lower */ - { 0x4c0, 0x4c0 }, - { 0x4c1, 0x4c2 }, /* upper */ - { 0x4c1, 0x4c2 }, /* lower */ - { 0x4c3, 0x4c4 }, /* upper */ - { 0x4c3, 0x4c4 }, /* lower */ - { 0x4c5, 0x4c6 }, /* upper */ - { 0x4c5, 0x4c6 }, /* lower */ - { 0x4c7, 0x4c8 }, /* upper */ - { 0x4c7, 0x4c8 }, /* lower */ - { 0x4c9, 0x4ca }, /* upper */ - { 0x4c9, 0x4ca }, /* lower */ - { 0x4cb, 0x4cc }, /* upper */ - { 0x4cb, 0x4cc }, /* lower */ - { 0x4cd, 0x4ce }, /* upper */ - { 0x4cd, 0x4ce }, /* lower */ - { 0x4cf, 0x4cf }, - { 0x4d0, 0x4d1 }, /* upper */ - { 0x4d0, 0x4d1 }, /* lower */ - { 0x4d2, 0x4d3 }, /* upper */ - { 0x4d2, 0x4d3 }, /* lower */ - { 0x4d4, 0x4d5 }, /* upper */ - { 0x4d4, 0x4d5 }, /* lower */ - { 0x4d6, 0x4d7 }, /* upper */ - { 0x4d6, 0x4d7 }, /* lower */ - { 0x4d8, 0x4d9 }, /* upper */ - { 0x4d8, 0x4d9 }, /* lower */ - { 0x4da, 0x4db }, /* upper */ - { 0x4da, 0x4db }, /* lower */ - { 0x4dc, 0x4dd }, /* upper */ - { 0x4dc, 0x4dd }, /* lower */ - { 0x4de, 0x4df }, /* upper */ - { 0x4de, 0x4df }, /* lower */ - { 0x4e0, 0x4e1 }, /* upper */ - { 0x4e0, 0x4e1 }, /* lower */ - { 0x4e2, 0x4e3 }, /* upper */ - { 0x4e2, 0x4e3 }, /* lower */ - { 0x4e4, 0x4e5 }, /* upper */ - { 0x4e4, 0x4e5 }, /* lower */ - { 0x4e6, 0x4e7 }, /* upper */ - { 0x4e6, 0x4e7 }, /* lower */ - { 0x4e8, 0x4e9 }, /* upper */ - { 0x4e8, 0x4e9 }, /* lower */ - { 0x4ea, 0x4eb }, /* upper */ - { 0x4ea, 0x4eb }, /* lower */ - { 0x4ec, 0x4ed }, /* upper */ - { 0x4ec, 0x4ed }, /* lower */ - { 0x4ee, 0x4ef }, /* upper */ - { 0x4ee, 0x4ef }, /* lower */ - { 0x4f0, 0x4f1 }, /* upper */ - { 0x4f0, 0x4f1 }, /* lower */ - { 0x4f2, 0x4f3 }, /* upper */ - { 0x4f2, 0x4f3 }, /* lower */ - { 0x4f4, 0x4f5 }, /* upper */ - { 0x4f4, 0x4f5 }, /* lower */ - { 0x4f6, 0x4f6 }, - { 0x4f7, 0x4f7 }, - { 0x4f8, 0x4f9 }, /* upper */ - { 0x4f8, 0x4f9 }, /* lower */ - { 0x4fa, 0x4fa }, - { 0x4fb, 0x4fb }, - { 0x4fc, 0x4fc }, - { 0x4fd, 0x4fd }, - { 0x4fe, 0x4fe }, - { 0x4ff, 0x4ff }, -}; - -static gli_case_block_t unigen_case_block_0x5[256] = { - { 0x500, 0x501 }, /* upper */ - { 0x500, 0x501 }, /* lower */ - { 0x502, 0x503 }, /* upper */ - { 0x502, 0x503 }, /* lower */ - { 0x504, 0x505 }, /* upper */ - { 0x504, 0x505 }, /* lower */ - { 0x506, 0x507 }, /* upper */ - { 0x506, 0x507 }, /* lower */ - { 0x508, 0x509 }, /* upper */ - { 0x508, 0x509 }, /* lower */ - { 0x50a, 0x50b }, /* upper */ - { 0x50a, 0x50b }, /* lower */ - { 0x50c, 0x50d }, /* upper */ - { 0x50c, 0x50d }, /* lower */ - { 0x50e, 0x50f }, /* upper */ - { 0x50e, 0x50f }, /* lower */ - { 0x510, 0x510 }, - { 0x511, 0x511 }, - { 0x512, 0x512 }, - { 0x513, 0x513 }, - { 0x514, 0x514 }, - { 0x515, 0x515 }, - { 0x516, 0x516 }, - { 0x517, 0x517 }, - { 0x518, 0x518 }, - { 0x519, 0x519 }, - { 0x51a, 0x51a }, - { 0x51b, 0x51b }, - { 0x51c, 0x51c }, - { 0x51d, 0x51d }, - { 0x51e, 0x51e }, - { 0x51f, 0x51f }, - { 0x520, 0x520 }, - { 0x521, 0x521 }, - { 0x522, 0x522 }, - { 0x523, 0x523 }, - { 0x524, 0x524 }, - { 0x525, 0x525 }, - { 0x526, 0x526 }, - { 0x527, 0x527 }, - { 0x528, 0x528 }, - { 0x529, 0x529 }, - { 0x52a, 0x52a }, - { 0x52b, 0x52b }, - { 0x52c, 0x52c }, - { 0x52d, 0x52d }, - { 0x52e, 0x52e }, - { 0x52f, 0x52f }, - { 0x530, 0x530 }, - { 0x531, 0x561 }, /* upper */ - { 0x532, 0x562 }, /* upper */ - { 0x533, 0x563 }, /* upper */ - { 0x534, 0x564 }, /* upper */ - { 0x535, 0x565 }, /* upper */ - { 0x536, 0x566 }, /* upper */ - { 0x537, 0x567 }, /* upper */ - { 0x538, 0x568 }, /* upper */ - { 0x539, 0x569 }, /* upper */ - { 0x53a, 0x56a }, /* upper */ - { 0x53b, 0x56b }, /* upper */ - { 0x53c, 0x56c }, /* upper */ - { 0x53d, 0x56d }, /* upper */ - { 0x53e, 0x56e }, /* upper */ - { 0x53f, 0x56f }, /* upper */ - { 0x540, 0x570 }, /* upper */ - { 0x541, 0x571 }, /* upper */ - { 0x542, 0x572 }, /* upper */ - { 0x543, 0x573 }, /* upper */ - { 0x544, 0x574 }, /* upper */ - { 0x545, 0x575 }, /* upper */ - { 0x546, 0x576 }, /* upper */ - { 0x547, 0x577 }, /* upper */ - { 0x548, 0x578 }, /* upper */ - { 0x549, 0x579 }, /* upper */ - { 0x54a, 0x57a }, /* upper */ - { 0x54b, 0x57b }, /* upper */ - { 0x54c, 0x57c }, /* upper */ - { 0x54d, 0x57d }, /* upper */ - { 0x54e, 0x57e }, /* upper */ - { 0x54f, 0x57f }, /* upper */ - { 0x550, 0x580 }, /* upper */ - { 0x551, 0x581 }, /* upper */ - { 0x552, 0x582 }, /* upper */ - { 0x553, 0x583 }, /* upper */ - { 0x554, 0x584 }, /* upper */ - { 0x555, 0x585 }, /* upper */ - { 0x556, 0x586 }, /* upper */ - { 0x557, 0x557 }, - { 0x558, 0x558 }, - { 0x559, 0x559 }, - { 0x55a, 0x55a }, - { 0x55b, 0x55b }, - { 0x55c, 0x55c }, - { 0x55d, 0x55d }, - { 0x55e, 0x55e }, - { 0x55f, 0x55f }, - { 0x560, 0x560 }, - { 0x531, 0x561 }, /* lower */ - { 0x532, 0x562 }, /* lower */ - { 0x533, 0x563 }, /* lower */ - { 0x534, 0x564 }, /* lower */ - { 0x535, 0x565 }, /* lower */ - { 0x536, 0x566 }, /* lower */ - { 0x537, 0x567 }, /* lower */ - { 0x538, 0x568 }, /* lower */ - { 0x539, 0x569 }, /* lower */ - { 0x53a, 0x56a }, /* lower */ - { 0x53b, 0x56b }, /* lower */ - { 0x53c, 0x56c }, /* lower */ - { 0x53d, 0x56d }, /* lower */ - { 0x53e, 0x56e }, /* lower */ - { 0x53f, 0x56f }, /* lower */ - { 0x540, 0x570 }, /* lower */ - { 0x541, 0x571 }, /* lower */ - { 0x542, 0x572 }, /* lower */ - { 0x543, 0x573 }, /* lower */ - { 0x544, 0x574 }, /* lower */ - { 0x545, 0x575 }, /* lower */ - { 0x546, 0x576 }, /* lower */ - { 0x547, 0x577 }, /* lower */ - { 0x548, 0x578 }, /* lower */ - { 0x549, 0x579 }, /* lower */ - { 0x54a, 0x57a }, /* lower */ - { 0x54b, 0x57b }, /* lower */ - { 0x54c, 0x57c }, /* lower */ - { 0x54d, 0x57d }, /* lower */ - { 0x54e, 0x57e }, /* lower */ - { 0x54f, 0x57f }, /* lower */ - { 0x550, 0x580 }, /* lower */ - { 0x551, 0x581 }, /* lower */ - { 0x552, 0x582 }, /* lower */ - { 0x553, 0x583 }, /* lower */ - { 0x554, 0x584 }, /* lower */ - { 0x555, 0x585 }, /* lower */ - { 0x556, 0x586 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x588, 0x588 }, - { 0x589, 0x589 }, - { 0x58a, 0x58a }, - { 0x58b, 0x58b }, - { 0x58c, 0x58c }, - { 0x58d, 0x58d }, - { 0x58e, 0x58e }, - { 0x58f, 0x58f }, - { 0x590, 0x590 }, - { 0x591, 0x591 }, - { 0x592, 0x592 }, - { 0x593, 0x593 }, - { 0x594, 0x594 }, - { 0x595, 0x595 }, - { 0x596, 0x596 }, - { 0x597, 0x597 }, - { 0x598, 0x598 }, - { 0x599, 0x599 }, - { 0x59a, 0x59a }, - { 0x59b, 0x59b }, - { 0x59c, 0x59c }, - { 0x59d, 0x59d }, - { 0x59e, 0x59e }, - { 0x59f, 0x59f }, - { 0x5a0, 0x5a0 }, - { 0x5a1, 0x5a1 }, - { 0x5a2, 0x5a2 }, - { 0x5a3, 0x5a3 }, - { 0x5a4, 0x5a4 }, - { 0x5a5, 0x5a5 }, - { 0x5a6, 0x5a6 }, - { 0x5a7, 0x5a7 }, - { 0x5a8, 0x5a8 }, - { 0x5a9, 0x5a9 }, - { 0x5aa, 0x5aa }, - { 0x5ab, 0x5ab }, - { 0x5ac, 0x5ac }, - { 0x5ad, 0x5ad }, - { 0x5ae, 0x5ae }, - { 0x5af, 0x5af }, - { 0x5b0, 0x5b0 }, - { 0x5b1, 0x5b1 }, - { 0x5b2, 0x5b2 }, - { 0x5b3, 0x5b3 }, - { 0x5b4, 0x5b4 }, - { 0x5b5, 0x5b5 }, - { 0x5b6, 0x5b6 }, - { 0x5b7, 0x5b7 }, - { 0x5b8, 0x5b8 }, - { 0x5b9, 0x5b9 }, - { 0x5ba, 0x5ba }, - { 0x5bb, 0x5bb }, - { 0x5bc, 0x5bc }, - { 0x5bd, 0x5bd }, - { 0x5be, 0x5be }, - { 0x5bf, 0x5bf }, - { 0x5c0, 0x5c0 }, - { 0x5c1, 0x5c1 }, - { 0x5c2, 0x5c2 }, - { 0x5c3, 0x5c3 }, - { 0x5c4, 0x5c4 }, - { 0x5c5, 0x5c5 }, - { 0x5c6, 0x5c6 }, - { 0x5c7, 0x5c7 }, - { 0x5c8, 0x5c8 }, - { 0x5c9, 0x5c9 }, - { 0x5ca, 0x5ca }, - { 0x5cb, 0x5cb }, - { 0x5cc, 0x5cc }, - { 0x5cd, 0x5cd }, - { 0x5ce, 0x5ce }, - { 0x5cf, 0x5cf }, - { 0x5d0, 0x5d0 }, - { 0x5d1, 0x5d1 }, - { 0x5d2, 0x5d2 }, - { 0x5d3, 0x5d3 }, - { 0x5d4, 0x5d4 }, - { 0x5d5, 0x5d5 }, - { 0x5d6, 0x5d6 }, - { 0x5d7, 0x5d7 }, - { 0x5d8, 0x5d8 }, - { 0x5d9, 0x5d9 }, - { 0x5da, 0x5da }, - { 0x5db, 0x5db }, - { 0x5dc, 0x5dc }, - { 0x5dd, 0x5dd }, - { 0x5de, 0x5de }, - { 0x5df, 0x5df }, - { 0x5e0, 0x5e0 }, - { 0x5e1, 0x5e1 }, - { 0x5e2, 0x5e2 }, - { 0x5e3, 0x5e3 }, - { 0x5e4, 0x5e4 }, - { 0x5e5, 0x5e5 }, - { 0x5e6, 0x5e6 }, - { 0x5e7, 0x5e7 }, - { 0x5e8, 0x5e8 }, - { 0x5e9, 0x5e9 }, - { 0x5ea, 0x5ea }, - { 0x5eb, 0x5eb }, - { 0x5ec, 0x5ec }, - { 0x5ed, 0x5ed }, - { 0x5ee, 0x5ee }, - { 0x5ef, 0x5ef }, - { 0x5f0, 0x5f0 }, - { 0x5f1, 0x5f1 }, - { 0x5f2, 0x5f2 }, - { 0x5f3, 0x5f3 }, - { 0x5f4, 0x5f4 }, - { 0x5f5, 0x5f5 }, - { 0x5f6, 0x5f6 }, - { 0x5f7, 0x5f7 }, - { 0x5f8, 0x5f8 }, - { 0x5f9, 0x5f9 }, - { 0x5fa, 0x5fa }, - { 0x5fb, 0x5fb }, - { 0x5fc, 0x5fc }, - { 0x5fd, 0x5fd }, - { 0x5fe, 0x5fe }, - { 0x5ff, 0x5ff }, -}; - -static gli_case_block_t unigen_case_block_0x1e[256] = { - { 0x1e00, 0x1e01 }, /* upper */ - { 0x1e00, 0x1e01 }, /* lower */ - { 0x1e02, 0x1e03 }, /* upper */ - { 0x1e02, 0x1e03 }, /* lower */ - { 0x1e04, 0x1e05 }, /* upper */ - { 0x1e04, 0x1e05 }, /* lower */ - { 0x1e06, 0x1e07 }, /* upper */ - { 0x1e06, 0x1e07 }, /* lower */ - { 0x1e08, 0x1e09 }, /* upper */ - { 0x1e08, 0x1e09 }, /* lower */ - { 0x1e0a, 0x1e0b }, /* upper */ - { 0x1e0a, 0x1e0b }, /* lower */ - { 0x1e0c, 0x1e0d }, /* upper */ - { 0x1e0c, 0x1e0d }, /* lower */ - { 0x1e0e, 0x1e0f }, /* upper */ - { 0x1e0e, 0x1e0f }, /* lower */ - { 0x1e10, 0x1e11 }, /* upper */ - { 0x1e10, 0x1e11 }, /* lower */ - { 0x1e12, 0x1e13 }, /* upper */ - { 0x1e12, 0x1e13 }, /* lower */ - { 0x1e14, 0x1e15 }, /* upper */ - { 0x1e14, 0x1e15 }, /* lower */ - { 0x1e16, 0x1e17 }, /* upper */ - { 0x1e16, 0x1e17 }, /* lower */ - { 0x1e18, 0x1e19 }, /* upper */ - { 0x1e18, 0x1e19 }, /* lower */ - { 0x1e1a, 0x1e1b }, /* upper */ - { 0x1e1a, 0x1e1b }, /* lower */ - { 0x1e1c, 0x1e1d }, /* upper */ - { 0x1e1c, 0x1e1d }, /* lower */ - { 0x1e1e, 0x1e1f }, /* upper */ - { 0x1e1e, 0x1e1f }, /* lower */ - { 0x1e20, 0x1e21 }, /* upper */ - { 0x1e20, 0x1e21 }, /* lower */ - { 0x1e22, 0x1e23 }, /* upper */ - { 0x1e22, 0x1e23 }, /* lower */ - { 0x1e24, 0x1e25 }, /* upper */ - { 0x1e24, 0x1e25 }, /* lower */ - { 0x1e26, 0x1e27 }, /* upper */ - { 0x1e26, 0x1e27 }, /* lower */ - { 0x1e28, 0x1e29 }, /* upper */ - { 0x1e28, 0x1e29 }, /* lower */ - { 0x1e2a, 0x1e2b }, /* upper */ - { 0x1e2a, 0x1e2b }, /* lower */ - { 0x1e2c, 0x1e2d }, /* upper */ - { 0x1e2c, 0x1e2d }, /* lower */ - { 0x1e2e, 0x1e2f }, /* upper */ - { 0x1e2e, 0x1e2f }, /* lower */ - { 0x1e30, 0x1e31 }, /* upper */ - { 0x1e30, 0x1e31 }, /* lower */ - { 0x1e32, 0x1e33 }, /* upper */ - { 0x1e32, 0x1e33 }, /* lower */ - { 0x1e34, 0x1e35 }, /* upper */ - { 0x1e34, 0x1e35 }, /* lower */ - { 0x1e36, 0x1e37 }, /* upper */ - { 0x1e36, 0x1e37 }, /* lower */ - { 0x1e38, 0x1e39 }, /* upper */ - { 0x1e38, 0x1e39 }, /* lower */ - { 0x1e3a, 0x1e3b }, /* upper */ - { 0x1e3a, 0x1e3b }, /* lower */ - { 0x1e3c, 0x1e3d }, /* upper */ - { 0x1e3c, 0x1e3d }, /* lower */ - { 0x1e3e, 0x1e3f }, /* upper */ - { 0x1e3e, 0x1e3f }, /* lower */ - { 0x1e40, 0x1e41 }, /* upper */ - { 0x1e40, 0x1e41 }, /* lower */ - { 0x1e42, 0x1e43 }, /* upper */ - { 0x1e42, 0x1e43 }, /* lower */ - { 0x1e44, 0x1e45 }, /* upper */ - { 0x1e44, 0x1e45 }, /* lower */ - { 0x1e46, 0x1e47 }, /* upper */ - { 0x1e46, 0x1e47 }, /* lower */ - { 0x1e48, 0x1e49 }, /* upper */ - { 0x1e48, 0x1e49 }, /* lower */ - { 0x1e4a, 0x1e4b }, /* upper */ - { 0x1e4a, 0x1e4b }, /* lower */ - { 0x1e4c, 0x1e4d }, /* upper */ - { 0x1e4c, 0x1e4d }, /* lower */ - { 0x1e4e, 0x1e4f }, /* upper */ - { 0x1e4e, 0x1e4f }, /* lower */ - { 0x1e50, 0x1e51 }, /* upper */ - { 0x1e50, 0x1e51 }, /* lower */ - { 0x1e52, 0x1e53 }, /* upper */ - { 0x1e52, 0x1e53 }, /* lower */ - { 0x1e54, 0x1e55 }, /* upper */ - { 0x1e54, 0x1e55 }, /* lower */ - { 0x1e56, 0x1e57 }, /* upper */ - { 0x1e56, 0x1e57 }, /* lower */ - { 0x1e58, 0x1e59 }, /* upper */ - { 0x1e58, 0x1e59 }, /* lower */ - { 0x1e5a, 0x1e5b }, /* upper */ - { 0x1e5a, 0x1e5b }, /* lower */ - { 0x1e5c, 0x1e5d }, /* upper */ - { 0x1e5c, 0x1e5d }, /* lower */ - { 0x1e5e, 0x1e5f }, /* upper */ - { 0x1e5e, 0x1e5f }, /* lower */ - { 0x1e60, 0x1e61 }, /* upper */ - { 0x1e60, 0x1e61 }, /* lower */ - { 0x1e62, 0x1e63 }, /* upper */ - { 0x1e62, 0x1e63 }, /* lower */ - { 0x1e64, 0x1e65 }, /* upper */ - { 0x1e64, 0x1e65 }, /* lower */ - { 0x1e66, 0x1e67 }, /* upper */ - { 0x1e66, 0x1e67 }, /* lower */ - { 0x1e68, 0x1e69 }, /* upper */ - { 0x1e68, 0x1e69 }, /* lower */ - { 0x1e6a, 0x1e6b }, /* upper */ - { 0x1e6a, 0x1e6b }, /* lower */ - { 0x1e6c, 0x1e6d }, /* upper */ - { 0x1e6c, 0x1e6d }, /* lower */ - { 0x1e6e, 0x1e6f }, /* upper */ - { 0x1e6e, 0x1e6f }, /* lower */ - { 0x1e70, 0x1e71 }, /* upper */ - { 0x1e70, 0x1e71 }, /* lower */ - { 0x1e72, 0x1e73 }, /* upper */ - { 0x1e72, 0x1e73 }, /* lower */ - { 0x1e74, 0x1e75 }, /* upper */ - { 0x1e74, 0x1e75 }, /* lower */ - { 0x1e76, 0x1e77 }, /* upper */ - { 0x1e76, 0x1e77 }, /* lower */ - { 0x1e78, 0x1e79 }, /* upper */ - { 0x1e78, 0x1e79 }, /* lower */ - { 0x1e7a, 0x1e7b }, /* upper */ - { 0x1e7a, 0x1e7b }, /* lower */ - { 0x1e7c, 0x1e7d }, /* upper */ - { 0x1e7c, 0x1e7d }, /* lower */ - { 0x1e7e, 0x1e7f }, /* upper */ - { 0x1e7e, 0x1e7f }, /* lower */ - { 0x1e80, 0x1e81 }, /* upper */ - { 0x1e80, 0x1e81 }, /* lower */ - { 0x1e82, 0x1e83 }, /* upper */ - { 0x1e82, 0x1e83 }, /* lower */ - { 0x1e84, 0x1e85 }, /* upper */ - { 0x1e84, 0x1e85 }, /* lower */ - { 0x1e86, 0x1e87 }, /* upper */ - { 0x1e86, 0x1e87 }, /* lower */ - { 0x1e88, 0x1e89 }, /* upper */ - { 0x1e88, 0x1e89 }, /* lower */ - { 0x1e8a, 0x1e8b }, /* upper */ - { 0x1e8a, 0x1e8b }, /* lower */ - { 0x1e8c, 0x1e8d }, /* upper */ - { 0x1e8c, 0x1e8d }, /* lower */ - { 0x1e8e, 0x1e8f }, /* upper */ - { 0x1e8e, 0x1e8f }, /* lower */ - { 0x1e90, 0x1e91 }, /* upper */ - { 0x1e90, 0x1e91 }, /* lower */ - { 0x1e92, 0x1e93 }, /* upper */ - { 0x1e92, 0x1e93 }, /* lower */ - { 0x1e94, 0x1e95 }, /* upper */ - { 0x1e94, 0x1e95 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1e60, 0x1e9b }, /* lower */ - { 0x1e9c, 0x1e9c }, - { 0x1e9d, 0x1e9d }, - { 0x1e9e, 0x1e9e }, - { 0x1e9f, 0x1e9f }, - { 0x1ea0, 0x1ea1 }, /* upper */ - { 0x1ea0, 0x1ea1 }, /* lower */ - { 0x1ea2, 0x1ea3 }, /* upper */ - { 0x1ea2, 0x1ea3 }, /* lower */ - { 0x1ea4, 0x1ea5 }, /* upper */ - { 0x1ea4, 0x1ea5 }, /* lower */ - { 0x1ea6, 0x1ea7 }, /* upper */ - { 0x1ea6, 0x1ea7 }, /* lower */ - { 0x1ea8, 0x1ea9 }, /* upper */ - { 0x1ea8, 0x1ea9 }, /* lower */ - { 0x1eaa, 0x1eab }, /* upper */ - { 0x1eaa, 0x1eab }, /* lower */ - { 0x1eac, 0x1ead }, /* upper */ - { 0x1eac, 0x1ead }, /* lower */ - { 0x1eae, 0x1eaf }, /* upper */ - { 0x1eae, 0x1eaf }, /* lower */ - { 0x1eb0, 0x1eb1 }, /* upper */ - { 0x1eb0, 0x1eb1 }, /* lower */ - { 0x1eb2, 0x1eb3 }, /* upper */ - { 0x1eb2, 0x1eb3 }, /* lower */ - { 0x1eb4, 0x1eb5 }, /* upper */ - { 0x1eb4, 0x1eb5 }, /* lower */ - { 0x1eb6, 0x1eb7 }, /* upper */ - { 0x1eb6, 0x1eb7 }, /* lower */ - { 0x1eb8, 0x1eb9 }, /* upper */ - { 0x1eb8, 0x1eb9 }, /* lower */ - { 0x1eba, 0x1ebb }, /* upper */ - { 0x1eba, 0x1ebb }, /* lower */ - { 0x1ebc, 0x1ebd }, /* upper */ - { 0x1ebc, 0x1ebd }, /* lower */ - { 0x1ebe, 0x1ebf }, /* upper */ - { 0x1ebe, 0x1ebf }, /* lower */ - { 0x1ec0, 0x1ec1 }, /* upper */ - { 0x1ec0, 0x1ec1 }, /* lower */ - { 0x1ec2, 0x1ec3 }, /* upper */ - { 0x1ec2, 0x1ec3 }, /* lower */ - { 0x1ec4, 0x1ec5 }, /* upper */ - { 0x1ec4, 0x1ec5 }, /* lower */ - { 0x1ec6, 0x1ec7 }, /* upper */ - { 0x1ec6, 0x1ec7 }, /* lower */ - { 0x1ec8, 0x1ec9 }, /* upper */ - { 0x1ec8, 0x1ec9 }, /* lower */ - { 0x1eca, 0x1ecb }, /* upper */ - { 0x1eca, 0x1ecb }, /* lower */ - { 0x1ecc, 0x1ecd }, /* upper */ - { 0x1ecc, 0x1ecd }, /* lower */ - { 0x1ece, 0x1ecf }, /* upper */ - { 0x1ece, 0x1ecf }, /* lower */ - { 0x1ed0, 0x1ed1 }, /* upper */ - { 0x1ed0, 0x1ed1 }, /* lower */ - { 0x1ed2, 0x1ed3 }, /* upper */ - { 0x1ed2, 0x1ed3 }, /* lower */ - { 0x1ed4, 0x1ed5 }, /* upper */ - { 0x1ed4, 0x1ed5 }, /* lower */ - { 0x1ed6, 0x1ed7 }, /* upper */ - { 0x1ed6, 0x1ed7 }, /* lower */ - { 0x1ed8, 0x1ed9 }, /* upper */ - { 0x1ed8, 0x1ed9 }, /* lower */ - { 0x1eda, 0x1edb }, /* upper */ - { 0x1eda, 0x1edb }, /* lower */ - { 0x1edc, 0x1edd }, /* upper */ - { 0x1edc, 0x1edd }, /* lower */ - { 0x1ede, 0x1edf }, /* upper */ - { 0x1ede, 0x1edf }, /* lower */ - { 0x1ee0, 0x1ee1 }, /* upper */ - { 0x1ee0, 0x1ee1 }, /* lower */ - { 0x1ee2, 0x1ee3 }, /* upper */ - { 0x1ee2, 0x1ee3 }, /* lower */ - { 0x1ee4, 0x1ee5 }, /* upper */ - { 0x1ee4, 0x1ee5 }, /* lower */ - { 0x1ee6, 0x1ee7 }, /* upper */ - { 0x1ee6, 0x1ee7 }, /* lower */ - { 0x1ee8, 0x1ee9 }, /* upper */ - { 0x1ee8, 0x1ee9 }, /* lower */ - { 0x1eea, 0x1eeb }, /* upper */ - { 0x1eea, 0x1eeb }, /* lower */ - { 0x1eec, 0x1eed }, /* upper */ - { 0x1eec, 0x1eed }, /* lower */ - { 0x1eee, 0x1eef }, /* upper */ - { 0x1eee, 0x1eef }, /* lower */ - { 0x1ef0, 0x1ef1 }, /* upper */ - { 0x1ef0, 0x1ef1 }, /* lower */ - { 0x1ef2, 0x1ef3 }, /* upper */ - { 0x1ef2, 0x1ef3 }, /* lower */ - { 0x1ef4, 0x1ef5 }, /* upper */ - { 0x1ef4, 0x1ef5 }, /* lower */ - { 0x1ef6, 0x1ef7 }, /* upper */ - { 0x1ef6, 0x1ef7 }, /* lower */ - { 0x1ef8, 0x1ef9 }, /* upper */ - { 0x1ef8, 0x1ef9 }, /* lower */ - { 0x1efa, 0x1efa }, - { 0x1efb, 0x1efb }, - { 0x1efc, 0x1efc }, - { 0x1efd, 0x1efd }, - { 0x1efe, 0x1efe }, - { 0x1eff, 0x1eff }, -}; - -static gli_case_block_t unigen_case_block_0x1f[256] = { - { 0x1f08, 0x1f00 }, /* lower */ - { 0x1f09, 0x1f01 }, /* lower */ - { 0x1f0a, 0x1f02 }, /* lower */ - { 0x1f0b, 0x1f03 }, /* lower */ - { 0x1f0c, 0x1f04 }, /* lower */ - { 0x1f0d, 0x1f05 }, /* lower */ - { 0x1f0e, 0x1f06 }, /* lower */ - { 0x1f0f, 0x1f07 }, /* lower */ - { 0x1f08, 0x1f00 }, /* upper */ - { 0x1f09, 0x1f01 }, /* upper */ - { 0x1f0a, 0x1f02 }, /* upper */ - { 0x1f0b, 0x1f03 }, /* upper */ - { 0x1f0c, 0x1f04 }, /* upper */ - { 0x1f0d, 0x1f05 }, /* upper */ - { 0x1f0e, 0x1f06 }, /* upper */ - { 0x1f0f, 0x1f07 }, /* upper */ - { 0x1f18, 0x1f10 }, /* lower */ - { 0x1f19, 0x1f11 }, /* lower */ - { 0x1f1a, 0x1f12 }, /* lower */ - { 0x1f1b, 0x1f13 }, /* lower */ - { 0x1f1c, 0x1f14 }, /* lower */ - { 0x1f1d, 0x1f15 }, /* lower */ - { 0x1f16, 0x1f16 }, - { 0x1f17, 0x1f17 }, - { 0x1f18, 0x1f10 }, /* upper */ - { 0x1f19, 0x1f11 }, /* upper */ - { 0x1f1a, 0x1f12 }, /* upper */ - { 0x1f1b, 0x1f13 }, /* upper */ - { 0x1f1c, 0x1f14 }, /* upper */ - { 0x1f1d, 0x1f15 }, /* upper */ - { 0x1f1e, 0x1f1e }, - { 0x1f1f, 0x1f1f }, - { 0x1f28, 0x1f20 }, /* lower */ - { 0x1f29, 0x1f21 }, /* lower */ - { 0x1f2a, 0x1f22 }, /* lower */ - { 0x1f2b, 0x1f23 }, /* lower */ - { 0x1f2c, 0x1f24 }, /* lower */ - { 0x1f2d, 0x1f25 }, /* lower */ - { 0x1f2e, 0x1f26 }, /* lower */ - { 0x1f2f, 0x1f27 }, /* lower */ - { 0x1f28, 0x1f20 }, /* upper */ - { 0x1f29, 0x1f21 }, /* upper */ - { 0x1f2a, 0x1f22 }, /* upper */ - { 0x1f2b, 0x1f23 }, /* upper */ - { 0x1f2c, 0x1f24 }, /* upper */ - { 0x1f2d, 0x1f25 }, /* upper */ - { 0x1f2e, 0x1f26 }, /* upper */ - { 0x1f2f, 0x1f27 }, /* upper */ - { 0x1f38, 0x1f30 }, /* lower */ - { 0x1f39, 0x1f31 }, /* lower */ - { 0x1f3a, 0x1f32 }, /* lower */ - { 0x1f3b, 0x1f33 }, /* lower */ - { 0x1f3c, 0x1f34 }, /* lower */ - { 0x1f3d, 0x1f35 }, /* lower */ - { 0x1f3e, 0x1f36 }, /* lower */ - { 0x1f3f, 0x1f37 }, /* lower */ - { 0x1f38, 0x1f30 }, /* upper */ - { 0x1f39, 0x1f31 }, /* upper */ - { 0x1f3a, 0x1f32 }, /* upper */ - { 0x1f3b, 0x1f33 }, /* upper */ - { 0x1f3c, 0x1f34 }, /* upper */ - { 0x1f3d, 0x1f35 }, /* upper */ - { 0x1f3e, 0x1f36 }, /* upper */ - { 0x1f3f, 0x1f37 }, /* upper */ - { 0x1f48, 0x1f40 }, /* lower */ - { 0x1f49, 0x1f41 }, /* lower */ - { 0x1f4a, 0x1f42 }, /* lower */ - { 0x1f4b, 0x1f43 }, /* lower */ - { 0x1f4c, 0x1f44 }, /* lower */ - { 0x1f4d, 0x1f45 }, /* lower */ - { 0x1f46, 0x1f46 }, - { 0x1f47, 0x1f47 }, - { 0x1f48, 0x1f40 }, /* upper */ - { 0x1f49, 0x1f41 }, /* upper */ - { 0x1f4a, 0x1f42 }, /* upper */ - { 0x1f4b, 0x1f43 }, /* upper */ - { 0x1f4c, 0x1f44 }, /* upper */ - { 0x1f4d, 0x1f45 }, /* upper */ - { 0x1f4e, 0x1f4e }, - { 0x1f4f, 0x1f4f }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1f59, 0x1f51 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1f5b, 0x1f53 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1f5d, 0x1f55 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1f5f, 0x1f57 }, /* lower */ - { 0x1f58, 0x1f58 }, - { 0x1f59, 0x1f51 }, /* upper */ - { 0x1f5a, 0x1f5a }, - { 0x1f5b, 0x1f53 }, /* upper */ - { 0x1f5c, 0x1f5c }, - { 0x1f5d, 0x1f55 }, /* upper */ - { 0x1f5e, 0x1f5e }, - { 0x1f5f, 0x1f57 }, /* upper */ - { 0x1f68, 0x1f60 }, /* lower */ - { 0x1f69, 0x1f61 }, /* lower */ - { 0x1f6a, 0x1f62 }, /* lower */ - { 0x1f6b, 0x1f63 }, /* lower */ - { 0x1f6c, 0x1f64 }, /* lower */ - { 0x1f6d, 0x1f65 }, /* lower */ - { 0x1f6e, 0x1f66 }, /* lower */ - { 0x1f6f, 0x1f67 }, /* lower */ - { 0x1f68, 0x1f60 }, /* upper */ - { 0x1f69, 0x1f61 }, /* upper */ - { 0x1f6a, 0x1f62 }, /* upper */ - { 0x1f6b, 0x1f63 }, /* upper */ - { 0x1f6c, 0x1f64 }, /* upper */ - { 0x1f6d, 0x1f65 }, /* upper */ - { 0x1f6e, 0x1f66 }, /* upper */ - { 0x1f6f, 0x1f67 }, /* upper */ - { 0x1fba, 0x1f70 }, /* lower */ - { 0x1fbb, 0x1f71 }, /* lower */ - { 0x1fc8, 0x1f72 }, /* lower */ - { 0x1fc9, 0x1f73 }, /* lower */ - { 0x1fca, 0x1f74 }, /* lower */ - { 0x1fcb, 0x1f75 }, /* lower */ - { 0x1fda, 0x1f76 }, /* lower */ - { 0x1fdb, 0x1f77 }, /* lower */ - { 0x1ff8, 0x1f78 }, /* lower */ - { 0x1ff9, 0x1f79 }, /* lower */ - { 0x1fea, 0x1f7a }, /* lower */ - { 0x1feb, 0x1f7b }, /* lower */ - { 0x1ffa, 0x1f7c }, /* lower */ - { 0x1ffb, 0x1f7d }, /* lower */ - { 0x1f7e, 0x1f7e }, - { 0x1f7f, 0x1f7f }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fb8, 0x1fb0 }, /* lower */ - { 0x1fb9, 0x1fb1 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fb5, 0x1fb5 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fb8, 0x1fb0 }, /* upper */ - { 0x1fb9, 0x1fb1 }, /* upper */ - { 0x1fba, 0x1f70 }, /* upper */ - { 0x1fbb, 0x1f71 }, /* upper */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fbd, 0x1fbd }, - { 0x399, 0x1fbe }, /* lower */ - { 0x1fbf, 0x1fbf }, - { 0x1fc0, 0x1fc0 }, - { 0x1fc1, 0x1fc1 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fc5, 0x1fc5 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fc8, 0x1f72 }, /* upper */ - { 0x1fc9, 0x1f73 }, /* upper */ - { 0x1fca, 0x1f74 }, /* upper */ - { 0x1fcb, 0x1f75 }, /* upper */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fcd, 0x1fcd }, - { 0x1fce, 0x1fce }, - { 0x1fcf, 0x1fcf }, - { 0x1fd8, 0x1fd0 }, /* lower */ - { 0x1fd9, 0x1fd1 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fd4, 0x1fd4 }, - { 0x1fd5, 0x1fd5 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fd8, 0x1fd0 }, /* upper */ - { 0x1fd9, 0x1fd1 }, /* upper */ - { 0x1fda, 0x1f76 }, /* upper */ - { 0x1fdb, 0x1f77 }, /* upper */ - { 0x1fdc, 0x1fdc }, - { 0x1fdd, 0x1fdd }, - { 0x1fde, 0x1fde }, - { 0x1fdf, 0x1fdf }, - { 0x1fe8, 0x1fe0 }, /* lower */ - { 0x1fe9, 0x1fe1 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fec, 0x1fe5 }, /* lower */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1fe8, 0x1fe0 }, /* upper */ - { 0x1fe9, 0x1fe1 }, /* upper */ - { 0x1fea, 0x1f7a }, /* upper */ - { 0x1feb, 0x1f7b }, /* upper */ - { 0x1fec, 0x1fe5 }, /* upper */ - { 0x1fed, 0x1fed }, - { 0x1fee, 0x1fee }, - { 0x1fef, 0x1fef }, - { 0x1ff0, 0x1ff0 }, - { 0x1ff1, 0x1ff1 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1ff5, 0x1ff5 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1ff8, 0x1f78 }, /* upper */ - { 0x1ff9, 0x1f79 }, /* upper */ - { 0x1ffa, 0x1f7c }, /* upper */ - { 0x1ffb, 0x1f7d }, /* upper */ - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0x1ffd, 0x1ffd }, - { 0x1ffe, 0x1ffe }, - { 0x1fff, 0x1fff }, -}; - -static gli_case_block_t unigen_case_block_0x21[256] = { - { 0x2100, 0x2100 }, - { 0x2101, 0x2101 }, - { 0x2102, 0x2102 }, - { 0x2103, 0x2103 }, - { 0x2104, 0x2104 }, - { 0x2105, 0x2105 }, - { 0x2106, 0x2106 }, - { 0x2107, 0x2107 }, - { 0x2108, 0x2108 }, - { 0x2109, 0x2109 }, - { 0x210a, 0x210a }, - { 0x210b, 0x210b }, - { 0x210c, 0x210c }, - { 0x210d, 0x210d }, - { 0x210e, 0x210e }, - { 0x210f, 0x210f }, - { 0x2110, 0x2110 }, - { 0x2111, 0x2111 }, - { 0x2112, 0x2112 }, - { 0x2113, 0x2113 }, - { 0x2114, 0x2114 }, - { 0x2115, 0x2115 }, - { 0x2116, 0x2116 }, - { 0x2117, 0x2117 }, - { 0x2118, 0x2118 }, - { 0x2119, 0x2119 }, - { 0x211a, 0x211a }, - { 0x211b, 0x211b }, - { 0x211c, 0x211c }, - { 0x211d, 0x211d }, - { 0x211e, 0x211e }, - { 0x211f, 0x211f }, - { 0x2120, 0x2120 }, - { 0x2121, 0x2121 }, - { 0x2122, 0x2122 }, - { 0x2123, 0x2123 }, - { 0x2124, 0x2124 }, - { 0x2125, 0x2125 }, - { 0x2126, 0x3c9 }, /* upper */ - { 0x2127, 0x2127 }, - { 0x2128, 0x2128 }, - { 0x2129, 0x2129 }, - { 0x212a, 0x6b }, /* upper */ - { 0x212b, 0xe5 }, /* upper */ - { 0x212c, 0x212c }, - { 0x212d, 0x212d }, - { 0x212e, 0x212e }, - { 0x212f, 0x212f }, - { 0x2130, 0x2130 }, - { 0x2131, 0x2131 }, - { 0x2132, 0x2132 }, - { 0x2133, 0x2133 }, - { 0x2134, 0x2134 }, - { 0x2135, 0x2135 }, - { 0x2136, 0x2136 }, - { 0x2137, 0x2137 }, - { 0x2138, 0x2138 }, - { 0x2139, 0x2139 }, - { 0x213a, 0x213a }, - { 0x213b, 0x213b }, - { 0x213c, 0x213c }, - { 0x213d, 0x213d }, - { 0x213e, 0x213e }, - { 0x213f, 0x213f }, - { 0x2140, 0x2140 }, - { 0x2141, 0x2141 }, - { 0x2142, 0x2142 }, - { 0x2143, 0x2143 }, - { 0x2144, 0x2144 }, - { 0x2145, 0x2145 }, - { 0x2146, 0x2146 }, - { 0x2147, 0x2147 }, - { 0x2148, 0x2148 }, - { 0x2149, 0x2149 }, - { 0x214a, 0x214a }, - { 0x214b, 0x214b }, - { 0x214c, 0x214c }, - { 0x214d, 0x214d }, - { 0x214e, 0x214e }, - { 0x214f, 0x214f }, - { 0x2150, 0x2150 }, - { 0x2151, 0x2151 }, - { 0x2152, 0x2152 }, - { 0x2153, 0x2153 }, - { 0x2154, 0x2154 }, - { 0x2155, 0x2155 }, - { 0x2156, 0x2156 }, - { 0x2157, 0x2157 }, - { 0x2158, 0x2158 }, - { 0x2159, 0x2159 }, - { 0x215a, 0x215a }, - { 0x215b, 0x215b }, - { 0x215c, 0x215c }, - { 0x215d, 0x215d }, - { 0x215e, 0x215e }, - { 0x215f, 0x215f }, - { 0x2160, 0x2170 }, /* upper */ - { 0x2161, 0x2171 }, /* upper */ - { 0x2162, 0x2172 }, /* upper */ - { 0x2163, 0x2173 }, /* upper */ - { 0x2164, 0x2174 }, /* upper */ - { 0x2165, 0x2175 }, /* upper */ - { 0x2166, 0x2176 }, /* upper */ - { 0x2167, 0x2177 }, /* upper */ - { 0x2168, 0x2178 }, /* upper */ - { 0x2169, 0x2179 }, /* upper */ - { 0x216a, 0x217a }, /* upper */ - { 0x216b, 0x217b }, /* upper */ - { 0x216c, 0x217c }, /* upper */ - { 0x216d, 0x217d }, /* upper */ - { 0x216e, 0x217e }, /* upper */ - { 0x216f, 0x217f }, /* upper */ - { 0x2160, 0x2170 }, /* lower */ - { 0x2161, 0x2171 }, /* lower */ - { 0x2162, 0x2172 }, /* lower */ - { 0x2163, 0x2173 }, /* lower */ - { 0x2164, 0x2174 }, /* lower */ - { 0x2165, 0x2175 }, /* lower */ - { 0x2166, 0x2176 }, /* lower */ - { 0x2167, 0x2177 }, /* lower */ - { 0x2168, 0x2178 }, /* lower */ - { 0x2169, 0x2179 }, /* lower */ - { 0x216a, 0x217a }, /* lower */ - { 0x216b, 0x217b }, /* lower */ - { 0x216c, 0x217c }, /* lower */ - { 0x216d, 0x217d }, /* lower */ - { 0x216e, 0x217e }, /* lower */ - { 0x216f, 0x217f }, /* lower */ - { 0x2180, 0x2180 }, - { 0x2181, 0x2181 }, - { 0x2182, 0x2182 }, - { 0x2183, 0x2183 }, - { 0x2184, 0x2184 }, - { 0x2185, 0x2185 }, - { 0x2186, 0x2186 }, - { 0x2187, 0x2187 }, - { 0x2188, 0x2188 }, - { 0x2189, 0x2189 }, - { 0x218a, 0x218a }, - { 0x218b, 0x218b }, - { 0x218c, 0x218c }, - { 0x218d, 0x218d }, - { 0x218e, 0x218e }, - { 0x218f, 0x218f }, - { 0x2190, 0x2190 }, - { 0x2191, 0x2191 }, - { 0x2192, 0x2192 }, - { 0x2193, 0x2193 }, - { 0x2194, 0x2194 }, - { 0x2195, 0x2195 }, - { 0x2196, 0x2196 }, - { 0x2197, 0x2197 }, - { 0x2198, 0x2198 }, - { 0x2199, 0x2199 }, - { 0x219a, 0x219a }, - { 0x219b, 0x219b }, - { 0x219c, 0x219c }, - { 0x219d, 0x219d }, - { 0x219e, 0x219e }, - { 0x219f, 0x219f }, - { 0x21a0, 0x21a0 }, - { 0x21a1, 0x21a1 }, - { 0x21a2, 0x21a2 }, - { 0x21a3, 0x21a3 }, - { 0x21a4, 0x21a4 }, - { 0x21a5, 0x21a5 }, - { 0x21a6, 0x21a6 }, - { 0x21a7, 0x21a7 }, - { 0x21a8, 0x21a8 }, - { 0x21a9, 0x21a9 }, - { 0x21aa, 0x21aa }, - { 0x21ab, 0x21ab }, - { 0x21ac, 0x21ac }, - { 0x21ad, 0x21ad }, - { 0x21ae, 0x21ae }, - { 0x21af, 0x21af }, - { 0x21b0, 0x21b0 }, - { 0x21b1, 0x21b1 }, - { 0x21b2, 0x21b2 }, - { 0x21b3, 0x21b3 }, - { 0x21b4, 0x21b4 }, - { 0x21b5, 0x21b5 }, - { 0x21b6, 0x21b6 }, - { 0x21b7, 0x21b7 }, - { 0x21b8, 0x21b8 }, - { 0x21b9, 0x21b9 }, - { 0x21ba, 0x21ba }, - { 0x21bb, 0x21bb }, - { 0x21bc, 0x21bc }, - { 0x21bd, 0x21bd }, - { 0x21be, 0x21be }, - { 0x21bf, 0x21bf }, - { 0x21c0, 0x21c0 }, - { 0x21c1, 0x21c1 }, - { 0x21c2, 0x21c2 }, - { 0x21c3, 0x21c3 }, - { 0x21c4, 0x21c4 }, - { 0x21c5, 0x21c5 }, - { 0x21c6, 0x21c6 }, - { 0x21c7, 0x21c7 }, - { 0x21c8, 0x21c8 }, - { 0x21c9, 0x21c9 }, - { 0x21ca, 0x21ca }, - { 0x21cb, 0x21cb }, - { 0x21cc, 0x21cc }, - { 0x21cd, 0x21cd }, - { 0x21ce, 0x21ce }, - { 0x21cf, 0x21cf }, - { 0x21d0, 0x21d0 }, - { 0x21d1, 0x21d1 }, - { 0x21d2, 0x21d2 }, - { 0x21d3, 0x21d3 }, - { 0x21d4, 0x21d4 }, - { 0x21d5, 0x21d5 }, - { 0x21d6, 0x21d6 }, - { 0x21d7, 0x21d7 }, - { 0x21d8, 0x21d8 }, - { 0x21d9, 0x21d9 }, - { 0x21da, 0x21da }, - { 0x21db, 0x21db }, - { 0x21dc, 0x21dc }, - { 0x21dd, 0x21dd }, - { 0x21de, 0x21de }, - { 0x21df, 0x21df }, - { 0x21e0, 0x21e0 }, - { 0x21e1, 0x21e1 }, - { 0x21e2, 0x21e2 }, - { 0x21e3, 0x21e3 }, - { 0x21e4, 0x21e4 }, - { 0x21e5, 0x21e5 }, - { 0x21e6, 0x21e6 }, - { 0x21e7, 0x21e7 }, - { 0x21e8, 0x21e8 }, - { 0x21e9, 0x21e9 }, - { 0x21ea, 0x21ea }, - { 0x21eb, 0x21eb }, - { 0x21ec, 0x21ec }, - { 0x21ed, 0x21ed }, - { 0x21ee, 0x21ee }, - { 0x21ef, 0x21ef }, - { 0x21f0, 0x21f0 }, - { 0x21f1, 0x21f1 }, - { 0x21f2, 0x21f2 }, - { 0x21f3, 0x21f3 }, - { 0x21f4, 0x21f4 }, - { 0x21f5, 0x21f5 }, - { 0x21f6, 0x21f6 }, - { 0x21f7, 0x21f7 }, - { 0x21f8, 0x21f8 }, - { 0x21f9, 0x21f9 }, - { 0x21fa, 0x21fa }, - { 0x21fb, 0x21fb }, - { 0x21fc, 0x21fc }, - { 0x21fd, 0x21fd }, - { 0x21fe, 0x21fe }, - { 0x21ff, 0x21ff }, -}; - -static gli_case_block_t unigen_case_block_0x24[256] = { - { 0x2400, 0x2400 }, - { 0x2401, 0x2401 }, - { 0x2402, 0x2402 }, - { 0x2403, 0x2403 }, - { 0x2404, 0x2404 }, - { 0x2405, 0x2405 }, - { 0x2406, 0x2406 }, - { 0x2407, 0x2407 }, - { 0x2408, 0x2408 }, - { 0x2409, 0x2409 }, - { 0x240a, 0x240a }, - { 0x240b, 0x240b }, - { 0x240c, 0x240c }, - { 0x240d, 0x240d }, - { 0x240e, 0x240e }, - { 0x240f, 0x240f }, - { 0x2410, 0x2410 }, - { 0x2411, 0x2411 }, - { 0x2412, 0x2412 }, - { 0x2413, 0x2413 }, - { 0x2414, 0x2414 }, - { 0x2415, 0x2415 }, - { 0x2416, 0x2416 }, - { 0x2417, 0x2417 }, - { 0x2418, 0x2418 }, - { 0x2419, 0x2419 }, - { 0x241a, 0x241a }, - { 0x241b, 0x241b }, - { 0x241c, 0x241c }, - { 0x241d, 0x241d }, - { 0x241e, 0x241e }, - { 0x241f, 0x241f }, - { 0x2420, 0x2420 }, - { 0x2421, 0x2421 }, - { 0x2422, 0x2422 }, - { 0x2423, 0x2423 }, - { 0x2424, 0x2424 }, - { 0x2425, 0x2425 }, - { 0x2426, 0x2426 }, - { 0x2427, 0x2427 }, - { 0x2428, 0x2428 }, - { 0x2429, 0x2429 }, - { 0x242a, 0x242a }, - { 0x242b, 0x242b }, - { 0x242c, 0x242c }, - { 0x242d, 0x242d }, - { 0x242e, 0x242e }, - { 0x242f, 0x242f }, - { 0x2430, 0x2430 }, - { 0x2431, 0x2431 }, - { 0x2432, 0x2432 }, - { 0x2433, 0x2433 }, - { 0x2434, 0x2434 }, - { 0x2435, 0x2435 }, - { 0x2436, 0x2436 }, - { 0x2437, 0x2437 }, - { 0x2438, 0x2438 }, - { 0x2439, 0x2439 }, - { 0x243a, 0x243a }, - { 0x243b, 0x243b }, - { 0x243c, 0x243c }, - { 0x243d, 0x243d }, - { 0x243e, 0x243e }, - { 0x243f, 0x243f }, - { 0x2440, 0x2440 }, - { 0x2441, 0x2441 }, - { 0x2442, 0x2442 }, - { 0x2443, 0x2443 }, - { 0x2444, 0x2444 }, - { 0x2445, 0x2445 }, - { 0x2446, 0x2446 }, - { 0x2447, 0x2447 }, - { 0x2448, 0x2448 }, - { 0x2449, 0x2449 }, - { 0x244a, 0x244a }, - { 0x244b, 0x244b }, - { 0x244c, 0x244c }, - { 0x244d, 0x244d }, - { 0x244e, 0x244e }, - { 0x244f, 0x244f }, - { 0x2450, 0x2450 }, - { 0x2451, 0x2451 }, - { 0x2452, 0x2452 }, - { 0x2453, 0x2453 }, - { 0x2454, 0x2454 }, - { 0x2455, 0x2455 }, - { 0x2456, 0x2456 }, - { 0x2457, 0x2457 }, - { 0x2458, 0x2458 }, - { 0x2459, 0x2459 }, - { 0x245a, 0x245a }, - { 0x245b, 0x245b }, - { 0x245c, 0x245c }, - { 0x245d, 0x245d }, - { 0x245e, 0x245e }, - { 0x245f, 0x245f }, - { 0x2460, 0x2460 }, - { 0x2461, 0x2461 }, - { 0x2462, 0x2462 }, - { 0x2463, 0x2463 }, - { 0x2464, 0x2464 }, - { 0x2465, 0x2465 }, - { 0x2466, 0x2466 }, - { 0x2467, 0x2467 }, - { 0x2468, 0x2468 }, - { 0x2469, 0x2469 }, - { 0x246a, 0x246a }, - { 0x246b, 0x246b }, - { 0x246c, 0x246c }, - { 0x246d, 0x246d }, - { 0x246e, 0x246e }, - { 0x246f, 0x246f }, - { 0x2470, 0x2470 }, - { 0x2471, 0x2471 }, - { 0x2472, 0x2472 }, - { 0x2473, 0x2473 }, - { 0x2474, 0x2474 }, - { 0x2475, 0x2475 }, - { 0x2476, 0x2476 }, - { 0x2477, 0x2477 }, - { 0x2478, 0x2478 }, - { 0x2479, 0x2479 }, - { 0x247a, 0x247a }, - { 0x247b, 0x247b }, - { 0x247c, 0x247c }, - { 0x247d, 0x247d }, - { 0x247e, 0x247e }, - { 0x247f, 0x247f }, - { 0x2480, 0x2480 }, - { 0x2481, 0x2481 }, - { 0x2482, 0x2482 }, - { 0x2483, 0x2483 }, - { 0x2484, 0x2484 }, - { 0x2485, 0x2485 }, - { 0x2486, 0x2486 }, - { 0x2487, 0x2487 }, - { 0x2488, 0x2488 }, - { 0x2489, 0x2489 }, - { 0x248a, 0x248a }, - { 0x248b, 0x248b }, - { 0x248c, 0x248c }, - { 0x248d, 0x248d }, - { 0x248e, 0x248e }, - { 0x248f, 0x248f }, - { 0x2490, 0x2490 }, - { 0x2491, 0x2491 }, - { 0x2492, 0x2492 }, - { 0x2493, 0x2493 }, - { 0x2494, 0x2494 }, - { 0x2495, 0x2495 }, - { 0x2496, 0x2496 }, - { 0x2497, 0x2497 }, - { 0x2498, 0x2498 }, - { 0x2499, 0x2499 }, - { 0x249a, 0x249a }, - { 0x249b, 0x249b }, - { 0x249c, 0x249c }, - { 0x249d, 0x249d }, - { 0x249e, 0x249e }, - { 0x249f, 0x249f }, - { 0x24a0, 0x24a0 }, - { 0x24a1, 0x24a1 }, - { 0x24a2, 0x24a2 }, - { 0x24a3, 0x24a3 }, - { 0x24a4, 0x24a4 }, - { 0x24a5, 0x24a5 }, - { 0x24a6, 0x24a6 }, - { 0x24a7, 0x24a7 }, - { 0x24a8, 0x24a8 }, - { 0x24a9, 0x24a9 }, - { 0x24aa, 0x24aa }, - { 0x24ab, 0x24ab }, - { 0x24ac, 0x24ac }, - { 0x24ad, 0x24ad }, - { 0x24ae, 0x24ae }, - { 0x24af, 0x24af }, - { 0x24b0, 0x24b0 }, - { 0x24b1, 0x24b1 }, - { 0x24b2, 0x24b2 }, - { 0x24b3, 0x24b3 }, - { 0x24b4, 0x24b4 }, - { 0x24b5, 0x24b5 }, - { 0x24b6, 0x24d0 }, /* upper */ - { 0x24b7, 0x24d1 }, /* upper */ - { 0x24b8, 0x24d2 }, /* upper */ - { 0x24b9, 0x24d3 }, /* upper */ - { 0x24ba, 0x24d4 }, /* upper */ - { 0x24bb, 0x24d5 }, /* upper */ - { 0x24bc, 0x24d6 }, /* upper */ - { 0x24bd, 0x24d7 }, /* upper */ - { 0x24be, 0x24d8 }, /* upper */ - { 0x24bf, 0x24d9 }, /* upper */ - { 0x24c0, 0x24da }, /* upper */ - { 0x24c1, 0x24db }, /* upper */ - { 0x24c2, 0x24dc }, /* upper */ - { 0x24c3, 0x24dd }, /* upper */ - { 0x24c4, 0x24de }, /* upper */ - { 0x24c5, 0x24df }, /* upper */ - { 0x24c6, 0x24e0 }, /* upper */ - { 0x24c7, 0x24e1 }, /* upper */ - { 0x24c8, 0x24e2 }, /* upper */ - { 0x24c9, 0x24e3 }, /* upper */ - { 0x24ca, 0x24e4 }, /* upper */ - { 0x24cb, 0x24e5 }, /* upper */ - { 0x24cc, 0x24e6 }, /* upper */ - { 0x24cd, 0x24e7 }, /* upper */ - { 0x24ce, 0x24e8 }, /* upper */ - { 0x24cf, 0x24e9 }, /* upper */ - { 0x24b6, 0x24d0 }, /* lower */ - { 0x24b7, 0x24d1 }, /* lower */ - { 0x24b8, 0x24d2 }, /* lower */ - { 0x24b9, 0x24d3 }, /* lower */ - { 0x24ba, 0x24d4 }, /* lower */ - { 0x24bb, 0x24d5 }, /* lower */ - { 0x24bc, 0x24d6 }, /* lower */ - { 0x24bd, 0x24d7 }, /* lower */ - { 0x24be, 0x24d8 }, /* lower */ - { 0x24bf, 0x24d9 }, /* lower */ - { 0x24c0, 0x24da }, /* lower */ - { 0x24c1, 0x24db }, /* lower */ - { 0x24c2, 0x24dc }, /* lower */ - { 0x24c3, 0x24dd }, /* lower */ - { 0x24c4, 0x24de }, /* lower */ - { 0x24c5, 0x24df }, /* lower */ - { 0x24c6, 0x24e0 }, /* lower */ - { 0x24c7, 0x24e1 }, /* lower */ - { 0x24c8, 0x24e2 }, /* lower */ - { 0x24c9, 0x24e3 }, /* lower */ - { 0x24ca, 0x24e4 }, /* lower */ - { 0x24cb, 0x24e5 }, /* lower */ - { 0x24cc, 0x24e6 }, /* lower */ - { 0x24cd, 0x24e7 }, /* lower */ - { 0x24ce, 0x24e8 }, /* lower */ - { 0x24cf, 0x24e9 }, /* lower */ - { 0x24ea, 0x24ea }, - { 0x24eb, 0x24eb }, - { 0x24ec, 0x24ec }, - { 0x24ed, 0x24ed }, - { 0x24ee, 0x24ee }, - { 0x24ef, 0x24ef }, - { 0x24f0, 0x24f0 }, - { 0x24f1, 0x24f1 }, - { 0x24f2, 0x24f2 }, - { 0x24f3, 0x24f3 }, - { 0x24f4, 0x24f4 }, - { 0x24f5, 0x24f5 }, - { 0x24f6, 0x24f6 }, - { 0x24f7, 0x24f7 }, - { 0x24f8, 0x24f8 }, - { 0x24f9, 0x24f9 }, - { 0x24fa, 0x24fa }, - { 0x24fb, 0x24fb }, - { 0x24fc, 0x24fc }, - { 0x24fd, 0x24fd }, - { 0x24fe, 0x24fe }, - { 0x24ff, 0x24ff }, -}; - -static gli_case_block_t unigen_case_block_0xfb[256] = { - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xfb07, 0xfb07 }, - { 0xfb08, 0xfb08 }, - { 0xfb09, 0xfb09 }, - { 0xfb0a, 0xfb0a }, - { 0xfb0b, 0xfb0b }, - { 0xfb0c, 0xfb0c }, - { 0xfb0d, 0xfb0d }, - { 0xfb0e, 0xfb0e }, - { 0xfb0f, 0xfb0f }, - { 0xfb10, 0xfb10 }, - { 0xfb11, 0xfb11 }, - { 0xfb12, 0xfb12 }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xfb18, 0xfb18 }, - { 0xfb19, 0xfb19 }, - { 0xfb1a, 0xfb1a }, - { 0xfb1b, 0xfb1b }, - { 0xfb1c, 0xfb1c }, - { 0xfb1d, 0xfb1d }, - { 0xfb1e, 0xfb1e }, - { 0xfb1f, 0xfb1f }, - { 0xfb20, 0xfb20 }, - { 0xfb21, 0xfb21 }, - { 0xfb22, 0xfb22 }, - { 0xfb23, 0xfb23 }, - { 0xfb24, 0xfb24 }, - { 0xfb25, 0xfb25 }, - { 0xfb26, 0xfb26 }, - { 0xfb27, 0xfb27 }, - { 0xfb28, 0xfb28 }, - { 0xfb29, 0xfb29 }, - { 0xfb2a, 0xfb2a }, - { 0xfb2b, 0xfb2b }, - { 0xfb2c, 0xfb2c }, - { 0xfb2d, 0xfb2d }, - { 0xfb2e, 0xfb2e }, - { 0xfb2f, 0xfb2f }, - { 0xfb30, 0xfb30 }, - { 0xfb31, 0xfb31 }, - { 0xfb32, 0xfb32 }, - { 0xfb33, 0xfb33 }, - { 0xfb34, 0xfb34 }, - { 0xfb35, 0xfb35 }, - { 0xfb36, 0xfb36 }, - { 0xfb37, 0xfb37 }, - { 0xfb38, 0xfb38 }, - { 0xfb39, 0xfb39 }, - { 0xfb3a, 0xfb3a }, - { 0xfb3b, 0xfb3b }, - { 0xfb3c, 0xfb3c }, - { 0xfb3d, 0xfb3d }, - { 0xfb3e, 0xfb3e }, - { 0xfb3f, 0xfb3f }, - { 0xfb40, 0xfb40 }, - { 0xfb41, 0xfb41 }, - { 0xfb42, 0xfb42 }, - { 0xfb43, 0xfb43 }, - { 0xfb44, 0xfb44 }, - { 0xfb45, 0xfb45 }, - { 0xfb46, 0xfb46 }, - { 0xfb47, 0xfb47 }, - { 0xfb48, 0xfb48 }, - { 0xfb49, 0xfb49 }, - { 0xfb4a, 0xfb4a }, - { 0xfb4b, 0xfb4b }, - { 0xfb4c, 0xfb4c }, - { 0xfb4d, 0xfb4d }, - { 0xfb4e, 0xfb4e }, - { 0xfb4f, 0xfb4f }, - { 0xfb50, 0xfb50 }, - { 0xfb51, 0xfb51 }, - { 0xfb52, 0xfb52 }, - { 0xfb53, 0xfb53 }, - { 0xfb54, 0xfb54 }, - { 0xfb55, 0xfb55 }, - { 0xfb56, 0xfb56 }, - { 0xfb57, 0xfb57 }, - { 0xfb58, 0xfb58 }, - { 0xfb59, 0xfb59 }, - { 0xfb5a, 0xfb5a }, - { 0xfb5b, 0xfb5b }, - { 0xfb5c, 0xfb5c }, - { 0xfb5d, 0xfb5d }, - { 0xfb5e, 0xfb5e }, - { 0xfb5f, 0xfb5f }, - { 0xfb60, 0xfb60 }, - { 0xfb61, 0xfb61 }, - { 0xfb62, 0xfb62 }, - { 0xfb63, 0xfb63 }, - { 0xfb64, 0xfb64 }, - { 0xfb65, 0xfb65 }, - { 0xfb66, 0xfb66 }, - { 0xfb67, 0xfb67 }, - { 0xfb68, 0xfb68 }, - { 0xfb69, 0xfb69 }, - { 0xfb6a, 0xfb6a }, - { 0xfb6b, 0xfb6b }, - { 0xfb6c, 0xfb6c }, - { 0xfb6d, 0xfb6d }, - { 0xfb6e, 0xfb6e }, - { 0xfb6f, 0xfb6f }, - { 0xfb70, 0xfb70 }, - { 0xfb71, 0xfb71 }, - { 0xfb72, 0xfb72 }, - { 0xfb73, 0xfb73 }, - { 0xfb74, 0xfb74 }, - { 0xfb75, 0xfb75 }, - { 0xfb76, 0xfb76 }, - { 0xfb77, 0xfb77 }, - { 0xfb78, 0xfb78 }, - { 0xfb79, 0xfb79 }, - { 0xfb7a, 0xfb7a }, - { 0xfb7b, 0xfb7b }, - { 0xfb7c, 0xfb7c }, - { 0xfb7d, 0xfb7d }, - { 0xfb7e, 0xfb7e }, - { 0xfb7f, 0xfb7f }, - { 0xfb80, 0xfb80 }, - { 0xfb81, 0xfb81 }, - { 0xfb82, 0xfb82 }, - { 0xfb83, 0xfb83 }, - { 0xfb84, 0xfb84 }, - { 0xfb85, 0xfb85 }, - { 0xfb86, 0xfb86 }, - { 0xfb87, 0xfb87 }, - { 0xfb88, 0xfb88 }, - { 0xfb89, 0xfb89 }, - { 0xfb8a, 0xfb8a }, - { 0xfb8b, 0xfb8b }, - { 0xfb8c, 0xfb8c }, - { 0xfb8d, 0xfb8d }, - { 0xfb8e, 0xfb8e }, - { 0xfb8f, 0xfb8f }, - { 0xfb90, 0xfb90 }, - { 0xfb91, 0xfb91 }, - { 0xfb92, 0xfb92 }, - { 0xfb93, 0xfb93 }, - { 0xfb94, 0xfb94 }, - { 0xfb95, 0xfb95 }, - { 0xfb96, 0xfb96 }, - { 0xfb97, 0xfb97 }, - { 0xfb98, 0xfb98 }, - { 0xfb99, 0xfb99 }, - { 0xfb9a, 0xfb9a }, - { 0xfb9b, 0xfb9b }, - { 0xfb9c, 0xfb9c }, - { 0xfb9d, 0xfb9d }, - { 0xfb9e, 0xfb9e }, - { 0xfb9f, 0xfb9f }, - { 0xfba0, 0xfba0 }, - { 0xfba1, 0xfba1 }, - { 0xfba2, 0xfba2 }, - { 0xfba3, 0xfba3 }, - { 0xfba4, 0xfba4 }, - { 0xfba5, 0xfba5 }, - { 0xfba6, 0xfba6 }, - { 0xfba7, 0xfba7 }, - { 0xfba8, 0xfba8 }, - { 0xfba9, 0xfba9 }, - { 0xfbaa, 0xfbaa }, - { 0xfbab, 0xfbab }, - { 0xfbac, 0xfbac }, - { 0xfbad, 0xfbad }, - { 0xfbae, 0xfbae }, - { 0xfbaf, 0xfbaf }, - { 0xfbb0, 0xfbb0 }, - { 0xfbb1, 0xfbb1 }, - { 0xfbb2, 0xfbb2 }, - { 0xfbb3, 0xfbb3 }, - { 0xfbb4, 0xfbb4 }, - { 0xfbb5, 0xfbb5 }, - { 0xfbb6, 0xfbb6 }, - { 0xfbb7, 0xfbb7 }, - { 0xfbb8, 0xfbb8 }, - { 0xfbb9, 0xfbb9 }, - { 0xfbba, 0xfbba }, - { 0xfbbb, 0xfbbb }, - { 0xfbbc, 0xfbbc }, - { 0xfbbd, 0xfbbd }, - { 0xfbbe, 0xfbbe }, - { 0xfbbf, 0xfbbf }, - { 0xfbc0, 0xfbc0 }, - { 0xfbc1, 0xfbc1 }, - { 0xfbc2, 0xfbc2 }, - { 0xfbc3, 0xfbc3 }, - { 0xfbc4, 0xfbc4 }, - { 0xfbc5, 0xfbc5 }, - { 0xfbc6, 0xfbc6 }, - { 0xfbc7, 0xfbc7 }, - { 0xfbc8, 0xfbc8 }, - { 0xfbc9, 0xfbc9 }, - { 0xfbca, 0xfbca }, - { 0xfbcb, 0xfbcb }, - { 0xfbcc, 0xfbcc }, - { 0xfbcd, 0xfbcd }, - { 0xfbce, 0xfbce }, - { 0xfbcf, 0xfbcf }, - { 0xfbd0, 0xfbd0 }, - { 0xfbd1, 0xfbd1 }, - { 0xfbd2, 0xfbd2 }, - { 0xfbd3, 0xfbd3 }, - { 0xfbd4, 0xfbd4 }, - { 0xfbd5, 0xfbd5 }, - { 0xfbd6, 0xfbd6 }, - { 0xfbd7, 0xfbd7 }, - { 0xfbd8, 0xfbd8 }, - { 0xfbd9, 0xfbd9 }, - { 0xfbda, 0xfbda }, - { 0xfbdb, 0xfbdb }, - { 0xfbdc, 0xfbdc }, - { 0xfbdd, 0xfbdd }, - { 0xfbde, 0xfbde }, - { 0xfbdf, 0xfbdf }, - { 0xfbe0, 0xfbe0 }, - { 0xfbe1, 0xfbe1 }, - { 0xfbe2, 0xfbe2 }, - { 0xfbe3, 0xfbe3 }, - { 0xfbe4, 0xfbe4 }, - { 0xfbe5, 0xfbe5 }, - { 0xfbe6, 0xfbe6 }, - { 0xfbe7, 0xfbe7 }, - { 0xfbe8, 0xfbe8 }, - { 0xfbe9, 0xfbe9 }, - { 0xfbea, 0xfbea }, - { 0xfbeb, 0xfbeb }, - { 0xfbec, 0xfbec }, - { 0xfbed, 0xfbed }, - { 0xfbee, 0xfbee }, - { 0xfbef, 0xfbef }, - { 0xfbf0, 0xfbf0 }, - { 0xfbf1, 0xfbf1 }, - { 0xfbf2, 0xfbf2 }, - { 0xfbf3, 0xfbf3 }, - { 0xfbf4, 0xfbf4 }, - { 0xfbf5, 0xfbf5 }, - { 0xfbf6, 0xfbf6 }, - { 0xfbf7, 0xfbf7 }, - { 0xfbf8, 0xfbf8 }, - { 0xfbf9, 0xfbf9 }, - { 0xfbfa, 0xfbfa }, - { 0xfbfb, 0xfbfb }, - { 0xfbfc, 0xfbfc }, - { 0xfbfd, 0xfbfd }, - { 0xfbfe, 0xfbfe }, - { 0xfbff, 0xfbff }, -}; - -static gli_case_block_t unigen_case_block_0xff[256] = { - { 0xff00, 0xff00 }, - { 0xff01, 0xff01 }, - { 0xff02, 0xff02 }, - { 0xff03, 0xff03 }, - { 0xff04, 0xff04 }, - { 0xff05, 0xff05 }, - { 0xff06, 0xff06 }, - { 0xff07, 0xff07 }, - { 0xff08, 0xff08 }, - { 0xff09, 0xff09 }, - { 0xff0a, 0xff0a }, - { 0xff0b, 0xff0b }, - { 0xff0c, 0xff0c }, - { 0xff0d, 0xff0d }, - { 0xff0e, 0xff0e }, - { 0xff0f, 0xff0f }, - { 0xff10, 0xff10 }, - { 0xff11, 0xff11 }, - { 0xff12, 0xff12 }, - { 0xff13, 0xff13 }, - { 0xff14, 0xff14 }, - { 0xff15, 0xff15 }, - { 0xff16, 0xff16 }, - { 0xff17, 0xff17 }, - { 0xff18, 0xff18 }, - { 0xff19, 0xff19 }, - { 0xff1a, 0xff1a }, - { 0xff1b, 0xff1b }, - { 0xff1c, 0xff1c }, - { 0xff1d, 0xff1d }, - { 0xff1e, 0xff1e }, - { 0xff1f, 0xff1f }, - { 0xff20, 0xff20 }, - { 0xff21, 0xff41 }, /* upper */ - { 0xff22, 0xff42 }, /* upper */ - { 0xff23, 0xff43 }, /* upper */ - { 0xff24, 0xff44 }, /* upper */ - { 0xff25, 0xff45 }, /* upper */ - { 0xff26, 0xff46 }, /* upper */ - { 0xff27, 0xff47 }, /* upper */ - { 0xff28, 0xff48 }, /* upper */ - { 0xff29, 0xff49 }, /* upper */ - { 0xff2a, 0xff4a }, /* upper */ - { 0xff2b, 0xff4b }, /* upper */ - { 0xff2c, 0xff4c }, /* upper */ - { 0xff2d, 0xff4d }, /* upper */ - { 0xff2e, 0xff4e }, /* upper */ - { 0xff2f, 0xff4f }, /* upper */ - { 0xff30, 0xff50 }, /* upper */ - { 0xff31, 0xff51 }, /* upper */ - { 0xff32, 0xff52 }, /* upper */ - { 0xff33, 0xff53 }, /* upper */ - { 0xff34, 0xff54 }, /* upper */ - { 0xff35, 0xff55 }, /* upper */ - { 0xff36, 0xff56 }, /* upper */ - { 0xff37, 0xff57 }, /* upper */ - { 0xff38, 0xff58 }, /* upper */ - { 0xff39, 0xff59 }, /* upper */ - { 0xff3a, 0xff5a }, /* upper */ - { 0xff3b, 0xff3b }, - { 0xff3c, 0xff3c }, - { 0xff3d, 0xff3d }, - { 0xff3e, 0xff3e }, - { 0xff3f, 0xff3f }, - { 0xff40, 0xff40 }, - { 0xff21, 0xff41 }, /* lower */ - { 0xff22, 0xff42 }, /* lower */ - { 0xff23, 0xff43 }, /* lower */ - { 0xff24, 0xff44 }, /* lower */ - { 0xff25, 0xff45 }, /* lower */ - { 0xff26, 0xff46 }, /* lower */ - { 0xff27, 0xff47 }, /* lower */ - { 0xff28, 0xff48 }, /* lower */ - { 0xff29, 0xff49 }, /* lower */ - { 0xff2a, 0xff4a }, /* lower */ - { 0xff2b, 0xff4b }, /* lower */ - { 0xff2c, 0xff4c }, /* lower */ - { 0xff2d, 0xff4d }, /* lower */ - { 0xff2e, 0xff4e }, /* lower */ - { 0xff2f, 0xff4f }, /* lower */ - { 0xff30, 0xff50 }, /* lower */ - { 0xff31, 0xff51 }, /* lower */ - { 0xff32, 0xff52 }, /* lower */ - { 0xff33, 0xff53 }, /* lower */ - { 0xff34, 0xff54 }, /* lower */ - { 0xff35, 0xff55 }, /* lower */ - { 0xff36, 0xff56 }, /* lower */ - { 0xff37, 0xff57 }, /* lower */ - { 0xff38, 0xff58 }, /* lower */ - { 0xff39, 0xff59 }, /* lower */ - { 0xff3a, 0xff5a }, /* lower */ - { 0xff5b, 0xff5b }, - { 0xff5c, 0xff5c }, - { 0xff5d, 0xff5d }, - { 0xff5e, 0xff5e }, - { 0xff5f, 0xff5f }, - { 0xff60, 0xff60 }, - { 0xff61, 0xff61 }, - { 0xff62, 0xff62 }, - { 0xff63, 0xff63 }, - { 0xff64, 0xff64 }, - { 0xff65, 0xff65 }, - { 0xff66, 0xff66 }, - { 0xff67, 0xff67 }, - { 0xff68, 0xff68 }, - { 0xff69, 0xff69 }, - { 0xff6a, 0xff6a }, - { 0xff6b, 0xff6b }, - { 0xff6c, 0xff6c }, - { 0xff6d, 0xff6d }, - { 0xff6e, 0xff6e }, - { 0xff6f, 0xff6f }, - { 0xff70, 0xff70 }, - { 0xff71, 0xff71 }, - { 0xff72, 0xff72 }, - { 0xff73, 0xff73 }, - { 0xff74, 0xff74 }, - { 0xff75, 0xff75 }, - { 0xff76, 0xff76 }, - { 0xff77, 0xff77 }, - { 0xff78, 0xff78 }, - { 0xff79, 0xff79 }, - { 0xff7a, 0xff7a }, - { 0xff7b, 0xff7b }, - { 0xff7c, 0xff7c }, - { 0xff7d, 0xff7d }, - { 0xff7e, 0xff7e }, - { 0xff7f, 0xff7f }, - { 0xff80, 0xff80 }, - { 0xff81, 0xff81 }, - { 0xff82, 0xff82 }, - { 0xff83, 0xff83 }, - { 0xff84, 0xff84 }, - { 0xff85, 0xff85 }, - { 0xff86, 0xff86 }, - { 0xff87, 0xff87 }, - { 0xff88, 0xff88 }, - { 0xff89, 0xff89 }, - { 0xff8a, 0xff8a }, - { 0xff8b, 0xff8b }, - { 0xff8c, 0xff8c }, - { 0xff8d, 0xff8d }, - { 0xff8e, 0xff8e }, - { 0xff8f, 0xff8f }, - { 0xff90, 0xff90 }, - { 0xff91, 0xff91 }, - { 0xff92, 0xff92 }, - { 0xff93, 0xff93 }, - { 0xff94, 0xff94 }, - { 0xff95, 0xff95 }, - { 0xff96, 0xff96 }, - { 0xff97, 0xff97 }, - { 0xff98, 0xff98 }, - { 0xff99, 0xff99 }, - { 0xff9a, 0xff9a }, - { 0xff9b, 0xff9b }, - { 0xff9c, 0xff9c }, - { 0xff9d, 0xff9d }, - { 0xff9e, 0xff9e }, - { 0xff9f, 0xff9f }, - { 0xffa0, 0xffa0 }, - { 0xffa1, 0xffa1 }, - { 0xffa2, 0xffa2 }, - { 0xffa3, 0xffa3 }, - { 0xffa4, 0xffa4 }, - { 0xffa5, 0xffa5 }, - { 0xffa6, 0xffa6 }, - { 0xffa7, 0xffa7 }, - { 0xffa8, 0xffa8 }, - { 0xffa9, 0xffa9 }, - { 0xffaa, 0xffaa }, - { 0xffab, 0xffab }, - { 0xffac, 0xffac }, - { 0xffad, 0xffad }, - { 0xffae, 0xffae }, - { 0xffaf, 0xffaf }, - { 0xffb0, 0xffb0 }, - { 0xffb1, 0xffb1 }, - { 0xffb2, 0xffb2 }, - { 0xffb3, 0xffb3 }, - { 0xffb4, 0xffb4 }, - { 0xffb5, 0xffb5 }, - { 0xffb6, 0xffb6 }, - { 0xffb7, 0xffb7 }, - { 0xffb8, 0xffb8 }, - { 0xffb9, 0xffb9 }, - { 0xffba, 0xffba }, - { 0xffbb, 0xffbb }, - { 0xffbc, 0xffbc }, - { 0xffbd, 0xffbd }, - { 0xffbe, 0xffbe }, - { 0xffbf, 0xffbf }, - { 0xffc0, 0xffc0 }, - { 0xffc1, 0xffc1 }, - { 0xffc2, 0xffc2 }, - { 0xffc3, 0xffc3 }, - { 0xffc4, 0xffc4 }, - { 0xffc5, 0xffc5 }, - { 0xffc6, 0xffc6 }, - { 0xffc7, 0xffc7 }, - { 0xffc8, 0xffc8 }, - { 0xffc9, 0xffc9 }, - { 0xffca, 0xffca }, - { 0xffcb, 0xffcb }, - { 0xffcc, 0xffcc }, - { 0xffcd, 0xffcd }, - { 0xffce, 0xffce }, - { 0xffcf, 0xffcf }, - { 0xffd0, 0xffd0 }, - { 0xffd1, 0xffd1 }, - { 0xffd2, 0xffd2 }, - { 0xffd3, 0xffd3 }, - { 0xffd4, 0xffd4 }, - { 0xffd5, 0xffd5 }, - { 0xffd6, 0xffd6 }, - { 0xffd7, 0xffd7 }, - { 0xffd8, 0xffd8 }, - { 0xffd9, 0xffd9 }, - { 0xffda, 0xffda }, - { 0xffdb, 0xffdb }, - { 0xffdc, 0xffdc }, - { 0xffdd, 0xffdd }, - { 0xffde, 0xffde }, - { 0xffdf, 0xffdf }, - { 0xffe0, 0xffe0 }, - { 0xffe1, 0xffe1 }, - { 0xffe2, 0xffe2 }, - { 0xffe3, 0xffe3 }, - { 0xffe4, 0xffe4 }, - { 0xffe5, 0xffe5 }, - { 0xffe6, 0xffe6 }, - { 0xffe7, 0xffe7 }, - { 0xffe8, 0xffe8 }, - { 0xffe9, 0xffe9 }, - { 0xffea, 0xffea }, - { 0xffeb, 0xffeb }, - { 0xffec, 0xffec }, - { 0xffed, 0xffed }, - { 0xffee, 0xffee }, - { 0xffef, 0xffef }, - { 0xfff0, 0xfff0 }, - { 0xfff1, 0xfff1 }, - { 0xfff2, 0xfff2 }, - { 0xfff3, 0xfff3 }, - { 0xfff4, 0xfff4 }, - { 0xfff5, 0xfff5 }, - { 0xfff6, 0xfff6 }, - { 0xfff7, 0xfff7 }, - { 0xfff8, 0xfff8 }, - { 0xfff9, 0xfff9 }, - { 0xfffa, 0xfffa }, - { 0xfffb, 0xfffb }, - { 0xfffc, 0xfffc }, - { 0xfffd, 0xfffd }, - { 0xfffe, 0xfffe }, - { 0xffff, 0xffff }, -}; - -static gli_case_block_t unigen_case_block_0x104[256] = { - { 0x10400, 0x10428 }, /* upper */ - { 0x10401, 0x10429 }, /* upper */ - { 0x10402, 0x1042a }, /* upper */ - { 0x10403, 0x1042b }, /* upper */ - { 0x10404, 0x1042c }, /* upper */ - { 0x10405, 0x1042d }, /* upper */ - { 0x10406, 0x1042e }, /* upper */ - { 0x10407, 0x1042f }, /* upper */ - { 0x10408, 0x10430 }, /* upper */ - { 0x10409, 0x10431 }, /* upper */ - { 0x1040a, 0x10432 }, /* upper */ - { 0x1040b, 0x10433 }, /* upper */ - { 0x1040c, 0x10434 }, /* upper */ - { 0x1040d, 0x10435 }, /* upper */ - { 0x1040e, 0x10436 }, /* upper */ - { 0x1040f, 0x10437 }, /* upper */ - { 0x10410, 0x10438 }, /* upper */ - { 0x10411, 0x10439 }, /* upper */ - { 0x10412, 0x1043a }, /* upper */ - { 0x10413, 0x1043b }, /* upper */ - { 0x10414, 0x1043c }, /* upper */ - { 0x10415, 0x1043d }, /* upper */ - { 0x10416, 0x1043e }, /* upper */ - { 0x10417, 0x1043f }, /* upper */ - { 0x10418, 0x10440 }, /* upper */ - { 0x10419, 0x10441 }, /* upper */ - { 0x1041a, 0x10442 }, /* upper */ - { 0x1041b, 0x10443 }, /* upper */ - { 0x1041c, 0x10444 }, /* upper */ - { 0x1041d, 0x10445 }, /* upper */ - { 0x1041e, 0x10446 }, /* upper */ - { 0x1041f, 0x10447 }, /* upper */ - { 0x10420, 0x10448 }, /* upper */ - { 0x10421, 0x10449 }, /* upper */ - { 0x10422, 0x1044a }, /* upper */ - { 0x10423, 0x1044b }, /* upper */ - { 0x10424, 0x1044c }, /* upper */ - { 0x10425, 0x1044d }, /* upper */ - { 0x10426, 0x1044e }, /* upper */ - { 0x10427, 0x1044f }, /* upper */ - { 0x10400, 0x10428 }, /* lower */ - { 0x10401, 0x10429 }, /* lower */ - { 0x10402, 0x1042a }, /* lower */ - { 0x10403, 0x1042b }, /* lower */ - { 0x10404, 0x1042c }, /* lower */ - { 0x10405, 0x1042d }, /* lower */ - { 0x10406, 0x1042e }, /* lower */ - { 0x10407, 0x1042f }, /* lower */ - { 0x10408, 0x10430 }, /* lower */ - { 0x10409, 0x10431 }, /* lower */ - { 0x1040a, 0x10432 }, /* lower */ - { 0x1040b, 0x10433 }, /* lower */ - { 0x1040c, 0x10434 }, /* lower */ - { 0x1040d, 0x10435 }, /* lower */ - { 0x1040e, 0x10436 }, /* lower */ - { 0x1040f, 0x10437 }, /* lower */ - { 0x10410, 0x10438 }, /* lower */ - { 0x10411, 0x10439 }, /* lower */ - { 0x10412, 0x1043a }, /* lower */ - { 0x10413, 0x1043b }, /* lower */ - { 0x10414, 0x1043c }, /* lower */ - { 0x10415, 0x1043d }, /* lower */ - { 0x10416, 0x1043e }, /* lower */ - { 0x10417, 0x1043f }, /* lower */ - { 0x10418, 0x10440 }, /* lower */ - { 0x10419, 0x10441 }, /* lower */ - { 0x1041a, 0x10442 }, /* lower */ - { 0x1041b, 0x10443 }, /* lower */ - { 0x1041c, 0x10444 }, /* lower */ - { 0x1041d, 0x10445 }, /* lower */ - { 0x1041e, 0x10446 }, /* lower */ - { 0x1041f, 0x10447 }, /* lower */ - { 0x10420, 0x10448 }, /* lower */ - { 0x10421, 0x10449 }, /* lower */ - { 0x10422, 0x1044a }, /* lower */ - { 0x10423, 0x1044b }, /* lower */ - { 0x10424, 0x1044c }, /* lower */ - { 0x10425, 0x1044d }, /* lower */ - { 0x10426, 0x1044e }, /* lower */ - { 0x10427, 0x1044f }, /* lower */ - { 0x10450, 0x10450 }, - { 0x10451, 0x10451 }, - { 0x10452, 0x10452 }, - { 0x10453, 0x10453 }, - { 0x10454, 0x10454 }, - { 0x10455, 0x10455 }, - { 0x10456, 0x10456 }, - { 0x10457, 0x10457 }, - { 0x10458, 0x10458 }, - { 0x10459, 0x10459 }, - { 0x1045a, 0x1045a }, - { 0x1045b, 0x1045b }, - { 0x1045c, 0x1045c }, - { 0x1045d, 0x1045d }, - { 0x1045e, 0x1045e }, - { 0x1045f, 0x1045f }, - { 0x10460, 0x10460 }, - { 0x10461, 0x10461 }, - { 0x10462, 0x10462 }, - { 0x10463, 0x10463 }, - { 0x10464, 0x10464 }, - { 0x10465, 0x10465 }, - { 0x10466, 0x10466 }, - { 0x10467, 0x10467 }, - { 0x10468, 0x10468 }, - { 0x10469, 0x10469 }, - { 0x1046a, 0x1046a }, - { 0x1046b, 0x1046b }, - { 0x1046c, 0x1046c }, - { 0x1046d, 0x1046d }, - { 0x1046e, 0x1046e }, - { 0x1046f, 0x1046f }, - { 0x10470, 0x10470 }, - { 0x10471, 0x10471 }, - { 0x10472, 0x10472 }, - { 0x10473, 0x10473 }, - { 0x10474, 0x10474 }, - { 0x10475, 0x10475 }, - { 0x10476, 0x10476 }, - { 0x10477, 0x10477 }, - { 0x10478, 0x10478 }, - { 0x10479, 0x10479 }, - { 0x1047a, 0x1047a }, - { 0x1047b, 0x1047b }, - { 0x1047c, 0x1047c }, - { 0x1047d, 0x1047d }, - { 0x1047e, 0x1047e }, - { 0x1047f, 0x1047f }, - { 0x10480, 0x10480 }, - { 0x10481, 0x10481 }, - { 0x10482, 0x10482 }, - { 0x10483, 0x10483 }, - { 0x10484, 0x10484 }, - { 0x10485, 0x10485 }, - { 0x10486, 0x10486 }, - { 0x10487, 0x10487 }, - { 0x10488, 0x10488 }, - { 0x10489, 0x10489 }, - { 0x1048a, 0x1048a }, - { 0x1048b, 0x1048b }, - { 0x1048c, 0x1048c }, - { 0x1048d, 0x1048d }, - { 0x1048e, 0x1048e }, - { 0x1048f, 0x1048f }, - { 0x10490, 0x10490 }, - { 0x10491, 0x10491 }, - { 0x10492, 0x10492 }, - { 0x10493, 0x10493 }, - { 0x10494, 0x10494 }, - { 0x10495, 0x10495 }, - { 0x10496, 0x10496 }, - { 0x10497, 0x10497 }, - { 0x10498, 0x10498 }, - { 0x10499, 0x10499 }, - { 0x1049a, 0x1049a }, - { 0x1049b, 0x1049b }, - { 0x1049c, 0x1049c }, - { 0x1049d, 0x1049d }, - { 0x1049e, 0x1049e }, - { 0x1049f, 0x1049f }, - { 0x104a0, 0x104a0 }, - { 0x104a1, 0x104a1 }, - { 0x104a2, 0x104a2 }, - { 0x104a3, 0x104a3 }, - { 0x104a4, 0x104a4 }, - { 0x104a5, 0x104a5 }, - { 0x104a6, 0x104a6 }, - { 0x104a7, 0x104a7 }, - { 0x104a8, 0x104a8 }, - { 0x104a9, 0x104a9 }, - { 0x104aa, 0x104aa }, - { 0x104ab, 0x104ab }, - { 0x104ac, 0x104ac }, - { 0x104ad, 0x104ad }, - { 0x104ae, 0x104ae }, - { 0x104af, 0x104af }, - { 0x104b0, 0x104b0 }, - { 0x104b1, 0x104b1 }, - { 0x104b2, 0x104b2 }, - { 0x104b3, 0x104b3 }, - { 0x104b4, 0x104b4 }, - { 0x104b5, 0x104b5 }, - { 0x104b6, 0x104b6 }, - { 0x104b7, 0x104b7 }, - { 0x104b8, 0x104b8 }, - { 0x104b9, 0x104b9 }, - { 0x104ba, 0x104ba }, - { 0x104bb, 0x104bb }, - { 0x104bc, 0x104bc }, - { 0x104bd, 0x104bd }, - { 0x104be, 0x104be }, - { 0x104bf, 0x104bf }, - { 0x104c0, 0x104c0 }, - { 0x104c1, 0x104c1 }, - { 0x104c2, 0x104c2 }, - { 0x104c3, 0x104c3 }, - { 0x104c4, 0x104c4 }, - { 0x104c5, 0x104c5 }, - { 0x104c6, 0x104c6 }, - { 0x104c7, 0x104c7 }, - { 0x104c8, 0x104c8 }, - { 0x104c9, 0x104c9 }, - { 0x104ca, 0x104ca }, - { 0x104cb, 0x104cb }, - { 0x104cc, 0x104cc }, - { 0x104cd, 0x104cd }, - { 0x104ce, 0x104ce }, - { 0x104cf, 0x104cf }, - { 0x104d0, 0x104d0 }, - { 0x104d1, 0x104d1 }, - { 0x104d2, 0x104d2 }, - { 0x104d3, 0x104d3 }, - { 0x104d4, 0x104d4 }, - { 0x104d5, 0x104d5 }, - { 0x104d6, 0x104d6 }, - { 0x104d7, 0x104d7 }, - { 0x104d8, 0x104d8 }, - { 0x104d9, 0x104d9 }, - { 0x104da, 0x104da }, - { 0x104db, 0x104db }, - { 0x104dc, 0x104dc }, - { 0x104dd, 0x104dd }, - { 0x104de, 0x104de }, - { 0x104df, 0x104df }, - { 0x104e0, 0x104e0 }, - { 0x104e1, 0x104e1 }, - { 0x104e2, 0x104e2 }, - { 0x104e3, 0x104e3 }, - { 0x104e4, 0x104e4 }, - { 0x104e5, 0x104e5 }, - { 0x104e6, 0x104e6 }, - { 0x104e7, 0x104e7 }, - { 0x104e8, 0x104e8 }, - { 0x104e9, 0x104e9 }, - { 0x104ea, 0x104ea }, - { 0x104eb, 0x104eb }, - { 0x104ec, 0x104ec }, - { 0x104ed, 0x104ed }, - { 0x104ee, 0x104ee }, - { 0x104ef, 0x104ef }, - { 0x104f0, 0x104f0 }, - { 0x104f1, 0x104f1 }, - { 0x104f2, 0x104f2 }, - { 0x104f3, 0x104f3 }, - { 0x104f4, 0x104f4 }, - { 0x104f5, 0x104f5 }, - { 0x104f6, 0x104f6 }, - { 0x104f7, 0x104f7 }, - { 0x104f8, 0x104f8 }, - { 0x104f9, 0x104f9 }, - { 0x104fa, 0x104fa }, - { 0x104fb, 0x104fb }, - { 0x104fc, 0x104fc }, - { 0x104fd, 0x104fd }, - { 0x104fe, 0x104fe }, - { 0x104ff, 0x104ff }, -}; - -#define GET_CASE_BLOCK(ch, blockptr) \ -switch ((glui32)(ch) >> 8) { \ - case 0x0: \ - *blockptr = unigen_case_block_0x0; \ - break; \ - case 0x1: \ - *blockptr = unigen_case_block_0x1; \ - break; \ - case 0x2: \ - *blockptr = unigen_case_block_0x2; \ - break; \ - case 0x3: \ - *blockptr = unigen_case_block_0x3; \ - break; \ - case 0x4: \ - *blockptr = unigen_case_block_0x4; \ - break; \ - case 0x5: \ - *blockptr = unigen_case_block_0x5; \ - break; \ - case 0x1e: \ - *blockptr = unigen_case_block_0x1e; \ - break; \ - case 0x1f: \ - *blockptr = unigen_case_block_0x1f; \ - break; \ - case 0x21: \ - *blockptr = unigen_case_block_0x21; \ - break; \ - case 0x24: \ - *blockptr = unigen_case_block_0x24; \ - break; \ - case 0xfb: \ - *blockptr = unigen_case_block_0xfb; \ - break; \ - case 0xff: \ - *blockptr = unigen_case_block_0xff; \ - break; \ - case 0x104: \ - *blockptr = unigen_case_block_0x104; \ - break; \ - default: \ - *blockptr = NULL; \ -} -static glui32 unigen_special_array[] = { - 2, 0x53, 0x53, /* 0xdf upcase */ - 1, 0xdf, /* 0xdf downcase */ - 2, 0x53, 0x73, /* 0xdf titlecase */ - 1, 0x130, /* 0x130 upcase */ - 2, 0x69, 0x307, /* 0x130 downcase */ - 1, 0x130, /* 0x130 titlecase */ - 2, 0x2bc, 0x4e, /* 0x149 upcase */ - 1, 0x149, /* 0x149 downcase */ - 2, 0x2bc, 0x4e, /* 0x149 titlecase */ - 1, 0x1c4, /* 0x1c4 upcase */ - 1, 0x1c6, /* 0x1c4 downcase */ - 1, 0x1c5, /* 0x1c4 titlecase */ - 1, 0x1c4, /* 0x1c5 upcase */ - 1, 0x1c6, /* 0x1c5 downcase */ - 1, 0x1c5, /* 0x1c5 titlecase */ - 1, 0x1c4, /* 0x1c6 upcase */ - 1, 0x1c6, /* 0x1c6 downcase */ - 1, 0x1c5, /* 0x1c6 titlecase */ - 1, 0x1c7, /* 0x1c7 upcase */ - 1, 0x1c9, /* 0x1c7 downcase */ - 1, 0x1c8, /* 0x1c7 titlecase */ - 1, 0x1c7, /* 0x1c8 upcase */ - 1, 0x1c9, /* 0x1c8 downcase */ - 1, 0x1c8, /* 0x1c8 titlecase */ - 1, 0x1c7, /* 0x1c9 upcase */ - 1, 0x1c9, /* 0x1c9 downcase */ - 1, 0x1c8, /* 0x1c9 titlecase */ - 1, 0x1ca, /* 0x1ca upcase */ - 1, 0x1cc, /* 0x1ca downcase */ - 1, 0x1cb, /* 0x1ca titlecase */ - 1, 0x1ca, /* 0x1cb upcase */ - 1, 0x1cc, /* 0x1cb downcase */ - 1, 0x1cb, /* 0x1cb titlecase */ - 1, 0x1ca, /* 0x1cc upcase */ - 1, 0x1cc, /* 0x1cc downcase */ - 1, 0x1cb, /* 0x1cc titlecase */ - 2, 0x4a, 0x30c, /* 0x1f0 upcase */ - 1, 0x1f0, /* 0x1f0 downcase */ - 2, 0x4a, 0x30c, /* 0x1f0 titlecase */ - 1, 0x1f1, /* 0x1f1 upcase */ - 1, 0x1f3, /* 0x1f1 downcase */ - 1, 0x1f2, /* 0x1f1 titlecase */ - 1, 0x1f1, /* 0x1f2 upcase */ - 1, 0x1f3, /* 0x1f2 downcase */ - 1, 0x1f2, /* 0x1f2 titlecase */ - 1, 0x1f1, /* 0x1f3 upcase */ - 1, 0x1f3, /* 0x1f3 downcase */ - 1, 0x1f2, /* 0x1f3 titlecase */ - 3, 0x399, 0x308, 0x301, /* 0x390 upcase */ - 1, 0x390, /* 0x390 downcase */ - 3, 0x399, 0x308, 0x301, /* 0x390 titlecase */ - 3, 0x3a5, 0x308, 0x301, /* 0x3b0 upcase */ - 1, 0x3b0, /* 0x3b0 downcase */ - 3, 0x3a5, 0x308, 0x301, /* 0x3b0 titlecase */ - 2, 0x535, 0x552, /* 0x587 upcase */ - 1, 0x587, /* 0x587 downcase */ - 2, 0x535, 0x582, /* 0x587 titlecase */ - 2, 0x48, 0x331, /* 0x1e96 upcase */ - 1, 0x1e96, /* 0x1e96 downcase */ - 2, 0x48, 0x331, /* 0x1e96 titlecase */ - 2, 0x54, 0x308, /* 0x1e97 upcase */ - 1, 0x1e97, /* 0x1e97 downcase */ - 2, 0x54, 0x308, /* 0x1e97 titlecase */ - 2, 0x57, 0x30a, /* 0x1e98 upcase */ - 1, 0x1e98, /* 0x1e98 downcase */ - 2, 0x57, 0x30a, /* 0x1e98 titlecase */ - 2, 0x59, 0x30a, /* 0x1e99 upcase */ - 1, 0x1e99, /* 0x1e99 downcase */ - 2, 0x59, 0x30a, /* 0x1e99 titlecase */ - 2, 0x41, 0x2be, /* 0x1e9a upcase */ - 1, 0x1e9a, /* 0x1e9a downcase */ - 2, 0x41, 0x2be, /* 0x1e9a titlecase */ - 2, 0x3a5, 0x313, /* 0x1f50 upcase */ - 1, 0x1f50, /* 0x1f50 downcase */ - 2, 0x3a5, 0x313, /* 0x1f50 titlecase */ - 3, 0x3a5, 0x313, 0x300, /* 0x1f52 upcase */ - 1, 0x1f52, /* 0x1f52 downcase */ - 3, 0x3a5, 0x313, 0x300, /* 0x1f52 titlecase */ - 3, 0x3a5, 0x313, 0x301, /* 0x1f54 upcase */ - 1, 0x1f54, /* 0x1f54 downcase */ - 3, 0x3a5, 0x313, 0x301, /* 0x1f54 titlecase */ - 3, 0x3a5, 0x313, 0x342, /* 0x1f56 upcase */ - 1, 0x1f56, /* 0x1f56 downcase */ - 3, 0x3a5, 0x313, 0x342, /* 0x1f56 titlecase */ - 2, 0x1f08, 0x399, /* 0x1f80 upcase */ - 1, 0x1f80, /* 0x1f80 downcase */ - 1, 0x1f88, /* 0x1f80 titlecase */ - 2, 0x1f09, 0x399, /* 0x1f81 upcase */ - 1, 0x1f81, /* 0x1f81 downcase */ - 1, 0x1f89, /* 0x1f81 titlecase */ - 2, 0x1f0a, 0x399, /* 0x1f82 upcase */ - 1, 0x1f82, /* 0x1f82 downcase */ - 1, 0x1f8a, /* 0x1f82 titlecase */ - 2, 0x1f0b, 0x399, /* 0x1f83 upcase */ - 1, 0x1f83, /* 0x1f83 downcase */ - 1, 0x1f8b, /* 0x1f83 titlecase */ - 2, 0x1f0c, 0x399, /* 0x1f84 upcase */ - 1, 0x1f84, /* 0x1f84 downcase */ - 1, 0x1f8c, /* 0x1f84 titlecase */ - 2, 0x1f0d, 0x399, /* 0x1f85 upcase */ - 1, 0x1f85, /* 0x1f85 downcase */ - 1, 0x1f8d, /* 0x1f85 titlecase */ - 2, 0x1f0e, 0x399, /* 0x1f86 upcase */ - 1, 0x1f86, /* 0x1f86 downcase */ - 1, 0x1f8e, /* 0x1f86 titlecase */ - 2, 0x1f0f, 0x399, /* 0x1f87 upcase */ - 1, 0x1f87, /* 0x1f87 downcase */ - 1, 0x1f8f, /* 0x1f87 titlecase */ - 2, 0x1f08, 0x399, /* 0x1f88 upcase */ - 1, 0x1f80, /* 0x1f88 downcase */ - 1, 0x1f88, /* 0x1f88 titlecase */ - 2, 0x1f09, 0x399, /* 0x1f89 upcase */ - 1, 0x1f81, /* 0x1f89 downcase */ - 1, 0x1f89, /* 0x1f89 titlecase */ - 2, 0x1f0a, 0x399, /* 0x1f8a upcase */ - 1, 0x1f82, /* 0x1f8a downcase */ - 1, 0x1f8a, /* 0x1f8a titlecase */ - 2, 0x1f0b, 0x399, /* 0x1f8b upcase */ - 1, 0x1f83, /* 0x1f8b downcase */ - 1, 0x1f8b, /* 0x1f8b titlecase */ - 2, 0x1f0c, 0x399, /* 0x1f8c upcase */ - 1, 0x1f84, /* 0x1f8c downcase */ - 1, 0x1f8c, /* 0x1f8c titlecase */ - 2, 0x1f0d, 0x399, /* 0x1f8d upcase */ - 1, 0x1f85, /* 0x1f8d downcase */ - 1, 0x1f8d, /* 0x1f8d titlecase */ - 2, 0x1f0e, 0x399, /* 0x1f8e upcase */ - 1, 0x1f86, /* 0x1f8e downcase */ - 1, 0x1f8e, /* 0x1f8e titlecase */ - 2, 0x1f0f, 0x399, /* 0x1f8f upcase */ - 1, 0x1f87, /* 0x1f8f downcase */ - 1, 0x1f8f, /* 0x1f8f titlecase */ - 2, 0x1f28, 0x399, /* 0x1f90 upcase */ - 1, 0x1f90, /* 0x1f90 downcase */ - 1, 0x1f98, /* 0x1f90 titlecase */ - 2, 0x1f29, 0x399, /* 0x1f91 upcase */ - 1, 0x1f91, /* 0x1f91 downcase */ - 1, 0x1f99, /* 0x1f91 titlecase */ - 2, 0x1f2a, 0x399, /* 0x1f92 upcase */ - 1, 0x1f92, /* 0x1f92 downcase */ - 1, 0x1f9a, /* 0x1f92 titlecase */ - 2, 0x1f2b, 0x399, /* 0x1f93 upcase */ - 1, 0x1f93, /* 0x1f93 downcase */ - 1, 0x1f9b, /* 0x1f93 titlecase */ - 2, 0x1f2c, 0x399, /* 0x1f94 upcase */ - 1, 0x1f94, /* 0x1f94 downcase */ - 1, 0x1f9c, /* 0x1f94 titlecase */ - 2, 0x1f2d, 0x399, /* 0x1f95 upcase */ - 1, 0x1f95, /* 0x1f95 downcase */ - 1, 0x1f9d, /* 0x1f95 titlecase */ - 2, 0x1f2e, 0x399, /* 0x1f96 upcase */ - 1, 0x1f96, /* 0x1f96 downcase */ - 1, 0x1f9e, /* 0x1f96 titlecase */ - 2, 0x1f2f, 0x399, /* 0x1f97 upcase */ - 1, 0x1f97, /* 0x1f97 downcase */ - 1, 0x1f9f, /* 0x1f97 titlecase */ - 2, 0x1f28, 0x399, /* 0x1f98 upcase */ - 1, 0x1f90, /* 0x1f98 downcase */ - 1, 0x1f98, /* 0x1f98 titlecase */ - 2, 0x1f29, 0x399, /* 0x1f99 upcase */ - 1, 0x1f91, /* 0x1f99 downcase */ - 1, 0x1f99, /* 0x1f99 titlecase */ - 2, 0x1f2a, 0x399, /* 0x1f9a upcase */ - 1, 0x1f92, /* 0x1f9a downcase */ - 1, 0x1f9a, /* 0x1f9a titlecase */ - 2, 0x1f2b, 0x399, /* 0x1f9b upcase */ - 1, 0x1f93, /* 0x1f9b downcase */ - 1, 0x1f9b, /* 0x1f9b titlecase */ - 2, 0x1f2c, 0x399, /* 0x1f9c upcase */ - 1, 0x1f94, /* 0x1f9c downcase */ - 1, 0x1f9c, /* 0x1f9c titlecase */ - 2, 0x1f2d, 0x399, /* 0x1f9d upcase */ - 1, 0x1f95, /* 0x1f9d downcase */ - 1, 0x1f9d, /* 0x1f9d titlecase */ - 2, 0x1f2e, 0x399, /* 0x1f9e upcase */ - 1, 0x1f96, /* 0x1f9e downcase */ - 1, 0x1f9e, /* 0x1f9e titlecase */ - 2, 0x1f2f, 0x399, /* 0x1f9f upcase */ - 1, 0x1f97, /* 0x1f9f downcase */ - 1, 0x1f9f, /* 0x1f9f titlecase */ - 2, 0x1f68, 0x399, /* 0x1fa0 upcase */ - 1, 0x1fa0, /* 0x1fa0 downcase */ - 1, 0x1fa8, /* 0x1fa0 titlecase */ - 2, 0x1f69, 0x399, /* 0x1fa1 upcase */ - 1, 0x1fa1, /* 0x1fa1 downcase */ - 1, 0x1fa9, /* 0x1fa1 titlecase */ - 2, 0x1f6a, 0x399, /* 0x1fa2 upcase */ - 1, 0x1fa2, /* 0x1fa2 downcase */ - 1, 0x1faa, /* 0x1fa2 titlecase */ - 2, 0x1f6b, 0x399, /* 0x1fa3 upcase */ - 1, 0x1fa3, /* 0x1fa3 downcase */ - 1, 0x1fab, /* 0x1fa3 titlecase */ - 2, 0x1f6c, 0x399, /* 0x1fa4 upcase */ - 1, 0x1fa4, /* 0x1fa4 downcase */ - 1, 0x1fac, /* 0x1fa4 titlecase */ - 2, 0x1f6d, 0x399, /* 0x1fa5 upcase */ - 1, 0x1fa5, /* 0x1fa5 downcase */ - 1, 0x1fad, /* 0x1fa5 titlecase */ - 2, 0x1f6e, 0x399, /* 0x1fa6 upcase */ - 1, 0x1fa6, /* 0x1fa6 downcase */ - 1, 0x1fae, /* 0x1fa6 titlecase */ - 2, 0x1f6f, 0x399, /* 0x1fa7 upcase */ - 1, 0x1fa7, /* 0x1fa7 downcase */ - 1, 0x1faf, /* 0x1fa7 titlecase */ - 2, 0x1f68, 0x399, /* 0x1fa8 upcase */ - 1, 0x1fa0, /* 0x1fa8 downcase */ - 1, 0x1fa8, /* 0x1fa8 titlecase */ - 2, 0x1f69, 0x399, /* 0x1fa9 upcase */ - 1, 0x1fa1, /* 0x1fa9 downcase */ - 1, 0x1fa9, /* 0x1fa9 titlecase */ - 2, 0x1f6a, 0x399, /* 0x1faa upcase */ - 1, 0x1fa2, /* 0x1faa downcase */ - 1, 0x1faa, /* 0x1faa titlecase */ - 2, 0x1f6b, 0x399, /* 0x1fab upcase */ - 1, 0x1fa3, /* 0x1fab downcase */ - 1, 0x1fab, /* 0x1fab titlecase */ - 2, 0x1f6c, 0x399, /* 0x1fac upcase */ - 1, 0x1fa4, /* 0x1fac downcase */ - 1, 0x1fac, /* 0x1fac titlecase */ - 2, 0x1f6d, 0x399, /* 0x1fad upcase */ - 1, 0x1fa5, /* 0x1fad downcase */ - 1, 0x1fad, /* 0x1fad titlecase */ - 2, 0x1f6e, 0x399, /* 0x1fae upcase */ - 1, 0x1fa6, /* 0x1fae downcase */ - 1, 0x1fae, /* 0x1fae titlecase */ - 2, 0x1f6f, 0x399, /* 0x1faf upcase */ - 1, 0x1fa7, /* 0x1faf downcase */ - 1, 0x1faf, /* 0x1faf titlecase */ - 2, 0x1fba, 0x399, /* 0x1fb2 upcase */ - 1, 0x1fb2, /* 0x1fb2 downcase */ - 2, 0x1fba, 0x345, /* 0x1fb2 titlecase */ - 2, 0x391, 0x399, /* 0x1fb3 upcase */ - 1, 0x1fb3, /* 0x1fb3 downcase */ - 1, 0x1fbc, /* 0x1fb3 titlecase */ - 2, 0x386, 0x399, /* 0x1fb4 upcase */ - 1, 0x1fb4, /* 0x1fb4 downcase */ - 2, 0x386, 0x345, /* 0x1fb4 titlecase */ - 2, 0x391, 0x342, /* 0x1fb6 upcase */ - 1, 0x1fb6, /* 0x1fb6 downcase */ - 2, 0x391, 0x342, /* 0x1fb6 titlecase */ - 3, 0x391, 0x342, 0x399, /* 0x1fb7 upcase */ - 1, 0x1fb7, /* 0x1fb7 downcase */ - 3, 0x391, 0x342, 0x345, /* 0x1fb7 titlecase */ - 2, 0x391, 0x399, /* 0x1fbc upcase */ - 1, 0x1fb3, /* 0x1fbc downcase */ - 1, 0x1fbc, /* 0x1fbc titlecase */ - 2, 0x1fca, 0x399, /* 0x1fc2 upcase */ - 1, 0x1fc2, /* 0x1fc2 downcase */ - 2, 0x1fca, 0x345, /* 0x1fc2 titlecase */ - 2, 0x397, 0x399, /* 0x1fc3 upcase */ - 1, 0x1fc3, /* 0x1fc3 downcase */ - 1, 0x1fcc, /* 0x1fc3 titlecase */ - 2, 0x389, 0x399, /* 0x1fc4 upcase */ - 1, 0x1fc4, /* 0x1fc4 downcase */ - 2, 0x389, 0x345, /* 0x1fc4 titlecase */ - 2, 0x397, 0x342, /* 0x1fc6 upcase */ - 1, 0x1fc6, /* 0x1fc6 downcase */ - 2, 0x397, 0x342, /* 0x1fc6 titlecase */ - 3, 0x397, 0x342, 0x399, /* 0x1fc7 upcase */ - 1, 0x1fc7, /* 0x1fc7 downcase */ - 3, 0x397, 0x342, 0x345, /* 0x1fc7 titlecase */ - 2, 0x397, 0x399, /* 0x1fcc upcase */ - 1, 0x1fc3, /* 0x1fcc downcase */ - 1, 0x1fcc, /* 0x1fcc titlecase */ - 3, 0x399, 0x308, 0x300, /* 0x1fd2 upcase */ - 1, 0x1fd2, /* 0x1fd2 downcase */ - 3, 0x399, 0x308, 0x300, /* 0x1fd2 titlecase */ - 3, 0x399, 0x308, 0x301, /* 0x1fd3 upcase */ - 1, 0x1fd3, /* 0x1fd3 downcase */ - 3, 0x399, 0x308, 0x301, /* 0x1fd3 titlecase */ - 2, 0x399, 0x342, /* 0x1fd6 upcase */ - 1, 0x1fd6, /* 0x1fd6 downcase */ - 2, 0x399, 0x342, /* 0x1fd6 titlecase */ - 3, 0x399, 0x308, 0x342, /* 0x1fd7 upcase */ - 1, 0x1fd7, /* 0x1fd7 downcase */ - 3, 0x399, 0x308, 0x342, /* 0x1fd7 titlecase */ - 3, 0x3a5, 0x308, 0x300, /* 0x1fe2 upcase */ - 1, 0x1fe2, /* 0x1fe2 downcase */ - 3, 0x3a5, 0x308, 0x300, /* 0x1fe2 titlecase */ - 3, 0x3a5, 0x308, 0x301, /* 0x1fe3 upcase */ - 1, 0x1fe3, /* 0x1fe3 downcase */ - 3, 0x3a5, 0x308, 0x301, /* 0x1fe3 titlecase */ - 2, 0x3a1, 0x313, /* 0x1fe4 upcase */ - 1, 0x1fe4, /* 0x1fe4 downcase */ - 2, 0x3a1, 0x313, /* 0x1fe4 titlecase */ - 2, 0x3a5, 0x342, /* 0x1fe6 upcase */ - 1, 0x1fe6, /* 0x1fe6 downcase */ - 2, 0x3a5, 0x342, /* 0x1fe6 titlecase */ - 3, 0x3a5, 0x308, 0x342, /* 0x1fe7 upcase */ - 1, 0x1fe7, /* 0x1fe7 downcase */ - 3, 0x3a5, 0x308, 0x342, /* 0x1fe7 titlecase */ - 2, 0x1ffa, 0x399, /* 0x1ff2 upcase */ - 1, 0x1ff2, /* 0x1ff2 downcase */ - 2, 0x1ffa, 0x345, /* 0x1ff2 titlecase */ - 2, 0x3a9, 0x399, /* 0x1ff3 upcase */ - 1, 0x1ff3, /* 0x1ff3 downcase */ - 1, 0x1ffc, /* 0x1ff3 titlecase */ - 2, 0x38f, 0x399, /* 0x1ff4 upcase */ - 1, 0x1ff4, /* 0x1ff4 downcase */ - 2, 0x38f, 0x345, /* 0x1ff4 titlecase */ - 2, 0x3a9, 0x342, /* 0x1ff6 upcase */ - 1, 0x1ff6, /* 0x1ff6 downcase */ - 2, 0x3a9, 0x342, /* 0x1ff6 titlecase */ - 3, 0x3a9, 0x342, 0x399, /* 0x1ff7 upcase */ - 1, 0x1ff7, /* 0x1ff7 downcase */ - 3, 0x3a9, 0x342, 0x345, /* 0x1ff7 titlecase */ - 2, 0x3a9, 0x399, /* 0x1ffc upcase */ - 1, 0x1ff3, /* 0x1ffc downcase */ - 1, 0x1ffc, /* 0x1ffc titlecase */ - 2, 0x46, 0x46, /* 0xfb00 upcase */ - 1, 0xfb00, /* 0xfb00 downcase */ - 2, 0x46, 0x66, /* 0xfb00 titlecase */ - 2, 0x46, 0x49, /* 0xfb01 upcase */ - 1, 0xfb01, /* 0xfb01 downcase */ - 2, 0x46, 0x69, /* 0xfb01 titlecase */ - 2, 0x46, 0x4c, /* 0xfb02 upcase */ - 1, 0xfb02, /* 0xfb02 downcase */ - 2, 0x46, 0x6c, /* 0xfb02 titlecase */ - 3, 0x46, 0x46, 0x49, /* 0xfb03 upcase */ - 1, 0xfb03, /* 0xfb03 downcase */ - 3, 0x46, 0x66, 0x69, /* 0xfb03 titlecase */ - 3, 0x46, 0x46, 0x4c, /* 0xfb04 upcase */ - 1, 0xfb04, /* 0xfb04 downcase */ - 3, 0x46, 0x66, 0x6c, /* 0xfb04 titlecase */ - 2, 0x53, 0x54, /* 0xfb05 upcase */ - 1, 0xfb05, /* 0xfb05 downcase */ - 2, 0x53, 0x74, /* 0xfb05 titlecase */ - 2, 0x53, 0x54, /* 0xfb06 upcase */ - 1, 0xfb06, /* 0xfb06 downcase */ - 2, 0x53, 0x74, /* 0xfb06 titlecase */ - 2, 0x544, 0x546, /* 0xfb13 upcase */ - 1, 0xfb13, /* 0xfb13 downcase */ - 2, 0x544, 0x576, /* 0xfb13 titlecase */ - 2, 0x544, 0x535, /* 0xfb14 upcase */ - 1, 0xfb14, /* 0xfb14 downcase */ - 2, 0x544, 0x565, /* 0xfb14 titlecase */ - 2, 0x544, 0x53b, /* 0xfb15 upcase */ - 1, 0xfb15, /* 0xfb15 downcase */ - 2, 0x544, 0x56b, /* 0xfb15 titlecase */ - 2, 0x54e, 0x546, /* 0xfb16 upcase */ - 1, 0xfb16, /* 0xfb16 downcase */ - 2, 0x54e, 0x576, /* 0xfb16 titlecase */ - 2, 0x544, 0x53d, /* 0xfb17 upcase */ - 1, 0xfb17, /* 0xfb17 downcase */ - 2, 0x544, 0x56d, /* 0xfb17 titlecase */ -}; - -static gli_case_special_t unigen_special_0xdf = { 0, 3, 5 }; -static gli_case_special_t unigen_special_0x130 = { 8, 10, 13 }; -static gli_case_special_t unigen_special_0x149 = { 15, 18, 20 }; -static gli_case_special_t unigen_special_0x1c4 = { 23, 25, 27 }; -static gli_case_special_t unigen_special_0x1c5 = { 29, 31, 33 }; -static gli_case_special_t unigen_special_0x1c6 = { 35, 37, 39 }; -static gli_case_special_t unigen_special_0x1c7 = { 41, 43, 45 }; -static gli_case_special_t unigen_special_0x1c8 = { 47, 49, 51 }; -static gli_case_special_t unigen_special_0x1c9 = { 53, 55, 57 }; -static gli_case_special_t unigen_special_0x1ca = { 59, 61, 63 }; -static gli_case_special_t unigen_special_0x1cb = { 65, 67, 69 }; -static gli_case_special_t unigen_special_0x1cc = { 71, 73, 75 }; -static gli_case_special_t unigen_special_0x1f0 = { 77, 80, 82 }; -static gli_case_special_t unigen_special_0x1f1 = { 85, 87, 89 }; -static gli_case_special_t unigen_special_0x1f2 = { 91, 93, 95 }; -static gli_case_special_t unigen_special_0x1f3 = { 97, 99, 101 }; -static gli_case_special_t unigen_special_0x390 = { 103, 107, 109 }; -static gli_case_special_t unigen_special_0x3b0 = { 113, 117, 119 }; -static gli_case_special_t unigen_special_0x587 = { 123, 126, 128 }; -static gli_case_special_t unigen_special_0x1e96 = { 131, 134, 136 }; -static gli_case_special_t unigen_special_0x1e97 = { 139, 142, 144 }; -static gli_case_special_t unigen_special_0x1e98 = { 147, 150, 152 }; -static gli_case_special_t unigen_special_0x1e99 = { 155, 158, 160 }; -static gli_case_special_t unigen_special_0x1e9a = { 163, 166, 168 }; -static gli_case_special_t unigen_special_0x1f50 = { 171, 174, 176 }; -static gli_case_special_t unigen_special_0x1f52 = { 179, 183, 185 }; -static gli_case_special_t unigen_special_0x1f54 = { 189, 193, 195 }; -static gli_case_special_t unigen_special_0x1f56 = { 199, 203, 205 }; -static gli_case_special_t unigen_special_0x1f80 = { 209, 212, 214 }; -static gli_case_special_t unigen_special_0x1f81 = { 216, 219, 221 }; -static gli_case_special_t unigen_special_0x1f82 = { 223, 226, 228 }; -static gli_case_special_t unigen_special_0x1f83 = { 230, 233, 235 }; -static gli_case_special_t unigen_special_0x1f84 = { 237, 240, 242 }; -static gli_case_special_t unigen_special_0x1f85 = { 244, 247, 249 }; -static gli_case_special_t unigen_special_0x1f86 = { 251, 254, 256 }; -static gli_case_special_t unigen_special_0x1f87 = { 258, 261, 263 }; -static gli_case_special_t unigen_special_0x1f88 = { 265, 268, 270 }; -static gli_case_special_t unigen_special_0x1f89 = { 272, 275, 277 }; -static gli_case_special_t unigen_special_0x1f8a = { 279, 282, 284 }; -static gli_case_special_t unigen_special_0x1f8b = { 286, 289, 291 }; -static gli_case_special_t unigen_special_0x1f8c = { 293, 296, 298 }; -static gli_case_special_t unigen_special_0x1f8d = { 300, 303, 305 }; -static gli_case_special_t unigen_special_0x1f8e = { 307, 310, 312 }; -static gli_case_special_t unigen_special_0x1f8f = { 314, 317, 319 }; -static gli_case_special_t unigen_special_0x1f90 = { 321, 324, 326 }; -static gli_case_special_t unigen_special_0x1f91 = { 328, 331, 333 }; -static gli_case_special_t unigen_special_0x1f92 = { 335, 338, 340 }; -static gli_case_special_t unigen_special_0x1f93 = { 342, 345, 347 }; -static gli_case_special_t unigen_special_0x1f94 = { 349, 352, 354 }; -static gli_case_special_t unigen_special_0x1f95 = { 356, 359, 361 }; -static gli_case_special_t unigen_special_0x1f96 = { 363, 366, 368 }; -static gli_case_special_t unigen_special_0x1f97 = { 370, 373, 375 }; -static gli_case_special_t unigen_special_0x1f98 = { 377, 380, 382 }; -static gli_case_special_t unigen_special_0x1f99 = { 384, 387, 389 }; -static gli_case_special_t unigen_special_0x1f9a = { 391, 394, 396 }; -static gli_case_special_t unigen_special_0x1f9b = { 398, 401, 403 }; -static gli_case_special_t unigen_special_0x1f9c = { 405, 408, 410 }; -static gli_case_special_t unigen_special_0x1f9d = { 412, 415, 417 }; -static gli_case_special_t unigen_special_0x1f9e = { 419, 422, 424 }; -static gli_case_special_t unigen_special_0x1f9f = { 426, 429, 431 }; -static gli_case_special_t unigen_special_0x1fa0 = { 433, 436, 438 }; -static gli_case_special_t unigen_special_0x1fa1 = { 440, 443, 445 }; -static gli_case_special_t unigen_special_0x1fa2 = { 447, 450, 452 }; -static gli_case_special_t unigen_special_0x1fa3 = { 454, 457, 459 }; -static gli_case_special_t unigen_special_0x1fa4 = { 461, 464, 466 }; -static gli_case_special_t unigen_special_0x1fa5 = { 468, 471, 473 }; -static gli_case_special_t unigen_special_0x1fa6 = { 475, 478, 480 }; -static gli_case_special_t unigen_special_0x1fa7 = { 482, 485, 487 }; -static gli_case_special_t unigen_special_0x1fa8 = { 489, 492, 494 }; -static gli_case_special_t unigen_special_0x1fa9 = { 496, 499, 501 }; -static gli_case_special_t unigen_special_0x1faa = { 503, 506, 508 }; -static gli_case_special_t unigen_special_0x1fab = { 510, 513, 515 }; -static gli_case_special_t unigen_special_0x1fac = { 517, 520, 522 }; -static gli_case_special_t unigen_special_0x1fad = { 524, 527, 529 }; -static gli_case_special_t unigen_special_0x1fae = { 531, 534, 536 }; -static gli_case_special_t unigen_special_0x1faf = { 538, 541, 543 }; -static gli_case_special_t unigen_special_0x1fb2 = { 545, 548, 550 }; -static gli_case_special_t unigen_special_0x1fb3 = { 553, 556, 558 }; -static gli_case_special_t unigen_special_0x1fb4 = { 560, 563, 565 }; -static gli_case_special_t unigen_special_0x1fb6 = { 568, 571, 573 }; -static gli_case_special_t unigen_special_0x1fb7 = { 576, 580, 582 }; -static gli_case_special_t unigen_special_0x1fbc = { 586, 589, 591 }; -static gli_case_special_t unigen_special_0x1fc2 = { 593, 596, 598 }; -static gli_case_special_t unigen_special_0x1fc3 = { 601, 604, 606 }; -static gli_case_special_t unigen_special_0x1fc4 = { 608, 611, 613 }; -static gli_case_special_t unigen_special_0x1fc6 = { 616, 619, 621 }; -static gli_case_special_t unigen_special_0x1fc7 = { 624, 628, 630 }; -static gli_case_special_t unigen_special_0x1fcc = { 634, 637, 639 }; -static gli_case_special_t unigen_special_0x1fd2 = { 641, 645, 647 }; -static gli_case_special_t unigen_special_0x1fd3 = { 651, 655, 657 }; -static gli_case_special_t unigen_special_0x1fd6 = { 661, 664, 666 }; -static gli_case_special_t unigen_special_0x1fd7 = { 669, 673, 675 }; -static gli_case_special_t unigen_special_0x1fe2 = { 679, 683, 685 }; -static gli_case_special_t unigen_special_0x1fe3 = { 689, 693, 695 }; -static gli_case_special_t unigen_special_0x1fe4 = { 699, 702, 704 }; -static gli_case_special_t unigen_special_0x1fe6 = { 707, 710, 712 }; -static gli_case_special_t unigen_special_0x1fe7 = { 715, 719, 721 }; -static gli_case_special_t unigen_special_0x1ff2 = { 725, 728, 730 }; -static gli_case_special_t unigen_special_0x1ff3 = { 733, 736, 738 }; -static gli_case_special_t unigen_special_0x1ff4 = { 740, 743, 745 }; -static gli_case_special_t unigen_special_0x1ff6 = { 748, 751, 753 }; -static gli_case_special_t unigen_special_0x1ff7 = { 756, 760, 762 }; -static gli_case_special_t unigen_special_0x1ffc = { 766, 769, 771 }; -static gli_case_special_t unigen_special_0xfb00 = { 773, 776, 778 }; -static gli_case_special_t unigen_special_0xfb01 = { 781, 784, 786 }; -static gli_case_special_t unigen_special_0xfb02 = { 789, 792, 794 }; -static gli_case_special_t unigen_special_0xfb03 = { 797, 801, 803 }; -static gli_case_special_t unigen_special_0xfb04 = { 807, 811, 813 }; -static gli_case_special_t unigen_special_0xfb05 = { 817, 820, 822 }; -static gli_case_special_t unigen_special_0xfb06 = { 825, 828, 830 }; -static gli_case_special_t unigen_special_0xfb13 = { 833, 836, 838 }; -static gli_case_special_t unigen_special_0xfb14 = { 841, 844, 846 }; -static gli_case_special_t unigen_special_0xfb15 = { 849, 852, 854 }; -static gli_case_special_t unigen_special_0xfb16 = { 857, 860, 862 }; -static gli_case_special_t unigen_special_0xfb17 = { 865, 868, 870 }; - -#define GET_CASE_SPECIAL(ch, specptr) \ -switch (ch) { \ - case 0xdf: \ - *specptr = unigen_special_0xdf; \ - break; \ - case 0x130: \ - *specptr = unigen_special_0x130; \ - break; \ - case 0x149: \ - *specptr = unigen_special_0x149; \ - break; \ - case 0x1c4: \ - *specptr = unigen_special_0x1c4; \ - break; \ - case 0x1c5: \ - *specptr = unigen_special_0x1c5; \ - break; \ - case 0x1c6: \ - *specptr = unigen_special_0x1c6; \ - break; \ - case 0x1c7: \ - *specptr = unigen_special_0x1c7; \ - break; \ - case 0x1c8: \ - *specptr = unigen_special_0x1c8; \ - break; \ - case 0x1c9: \ - *specptr = unigen_special_0x1c9; \ - break; \ - case 0x1ca: \ - *specptr = unigen_special_0x1ca; \ - break; \ - case 0x1cb: \ - *specptr = unigen_special_0x1cb; \ - break; \ - case 0x1cc: \ - *specptr = unigen_special_0x1cc; \ - break; \ - case 0x1f0: \ - *specptr = unigen_special_0x1f0; \ - break; \ - case 0x1f1: \ - *specptr = unigen_special_0x1f1; \ - break; \ - case 0x1f2: \ - *specptr = unigen_special_0x1f2; \ - break; \ - case 0x1f3: \ - *specptr = unigen_special_0x1f3; \ - break; \ - case 0x390: \ - *specptr = unigen_special_0x390; \ - break; \ - case 0x3b0: \ - *specptr = unigen_special_0x3b0; \ - break; \ - case 0x587: \ - *specptr = unigen_special_0x587; \ - break; \ - case 0x1e96: \ - *specptr = unigen_special_0x1e96; \ - break; \ - case 0x1e97: \ - *specptr = unigen_special_0x1e97; \ - break; \ - case 0x1e98: \ - *specptr = unigen_special_0x1e98; \ - break; \ - case 0x1e99: \ - *specptr = unigen_special_0x1e99; \ - break; \ - case 0x1e9a: \ - *specptr = unigen_special_0x1e9a; \ - break; \ - case 0x1f50: \ - *specptr = unigen_special_0x1f50; \ - break; \ - case 0x1f52: \ - *specptr = unigen_special_0x1f52; \ - break; \ - case 0x1f54: \ - *specptr = unigen_special_0x1f54; \ - break; \ - case 0x1f56: \ - *specptr = unigen_special_0x1f56; \ - break; \ - case 0x1f80: \ - *specptr = unigen_special_0x1f80; \ - break; \ - case 0x1f81: \ - *specptr = unigen_special_0x1f81; \ - break; \ - case 0x1f82: \ - *specptr = unigen_special_0x1f82; \ - break; \ - case 0x1f83: \ - *specptr = unigen_special_0x1f83; \ - break; \ - case 0x1f84: \ - *specptr = unigen_special_0x1f84; \ - break; \ - case 0x1f85: \ - *specptr = unigen_special_0x1f85; \ - break; \ - case 0x1f86: \ - *specptr = unigen_special_0x1f86; \ - break; \ - case 0x1f87: \ - *specptr = unigen_special_0x1f87; \ - break; \ - case 0x1f88: \ - *specptr = unigen_special_0x1f88; \ - break; \ - case 0x1f89: \ - *specptr = unigen_special_0x1f89; \ - break; \ - case 0x1f8a: \ - *specptr = unigen_special_0x1f8a; \ - break; \ - case 0x1f8b: \ - *specptr = unigen_special_0x1f8b; \ - break; \ - case 0x1f8c: \ - *specptr = unigen_special_0x1f8c; \ - break; \ - case 0x1f8d: \ - *specptr = unigen_special_0x1f8d; \ - break; \ - case 0x1f8e: \ - *specptr = unigen_special_0x1f8e; \ - break; \ - case 0x1f8f: \ - *specptr = unigen_special_0x1f8f; \ - break; \ - case 0x1f90: \ - *specptr = unigen_special_0x1f90; \ - break; \ - case 0x1f91: \ - *specptr = unigen_special_0x1f91; \ - break; \ - case 0x1f92: \ - *specptr = unigen_special_0x1f92; \ - break; \ - case 0x1f93: \ - *specptr = unigen_special_0x1f93; \ - break; \ - case 0x1f94: \ - *specptr = unigen_special_0x1f94; \ - break; \ - case 0x1f95: \ - *specptr = unigen_special_0x1f95; \ - break; \ - case 0x1f96: \ - *specptr = unigen_special_0x1f96; \ - break; \ - case 0x1f97: \ - *specptr = unigen_special_0x1f97; \ - break; \ - case 0x1f98: \ - *specptr = unigen_special_0x1f98; \ - break; \ - case 0x1f99: \ - *specptr = unigen_special_0x1f99; \ - break; \ - case 0x1f9a: \ - *specptr = unigen_special_0x1f9a; \ - break; \ - case 0x1f9b: \ - *specptr = unigen_special_0x1f9b; \ - break; \ - case 0x1f9c: \ - *specptr = unigen_special_0x1f9c; \ - break; \ - case 0x1f9d: \ - *specptr = unigen_special_0x1f9d; \ - break; \ - case 0x1f9e: \ - *specptr = unigen_special_0x1f9e; \ - break; \ - case 0x1f9f: \ - *specptr = unigen_special_0x1f9f; \ - break; \ - case 0x1fa0: \ - *specptr = unigen_special_0x1fa0; \ - break; \ - case 0x1fa1: \ - *specptr = unigen_special_0x1fa1; \ - break; \ - case 0x1fa2: \ - *specptr = unigen_special_0x1fa2; \ - break; \ - case 0x1fa3: \ - *specptr = unigen_special_0x1fa3; \ - break; \ - case 0x1fa4: \ - *specptr = unigen_special_0x1fa4; \ - break; \ - case 0x1fa5: \ - *specptr = unigen_special_0x1fa5; \ - break; \ - case 0x1fa6: \ - *specptr = unigen_special_0x1fa6; \ - break; \ - case 0x1fa7: \ - *specptr = unigen_special_0x1fa7; \ - break; \ - case 0x1fa8: \ - *specptr = unigen_special_0x1fa8; \ - break; \ - case 0x1fa9: \ - *specptr = unigen_special_0x1fa9; \ - break; \ - case 0x1faa: \ - *specptr = unigen_special_0x1faa; \ - break; \ - case 0x1fab: \ - *specptr = unigen_special_0x1fab; \ - break; \ - case 0x1fac: \ - *specptr = unigen_special_0x1fac; \ - break; \ - case 0x1fad: \ - *specptr = unigen_special_0x1fad; \ - break; \ - case 0x1fae: \ - *specptr = unigen_special_0x1fae; \ - break; \ - case 0x1faf: \ - *specptr = unigen_special_0x1faf; \ - break; \ - case 0x1fb2: \ - *specptr = unigen_special_0x1fb2; \ - break; \ - case 0x1fb3: \ - *specptr = unigen_special_0x1fb3; \ - break; \ - case 0x1fb4: \ - *specptr = unigen_special_0x1fb4; \ - break; \ - case 0x1fb6: \ - *specptr = unigen_special_0x1fb6; \ - break; \ - case 0x1fb7: \ - *specptr = unigen_special_0x1fb7; \ - break; \ - case 0x1fbc: \ - *specptr = unigen_special_0x1fbc; \ - break; \ - case 0x1fc2: \ - *specptr = unigen_special_0x1fc2; \ - break; \ - case 0x1fc3: \ - *specptr = unigen_special_0x1fc3; \ - break; \ - case 0x1fc4: \ - *specptr = unigen_special_0x1fc4; \ - break; \ - case 0x1fc6: \ - *specptr = unigen_special_0x1fc6; \ - break; \ - case 0x1fc7: \ - *specptr = unigen_special_0x1fc7; \ - break; \ - case 0x1fcc: \ - *specptr = unigen_special_0x1fcc; \ - break; \ - case 0x1fd2: \ - *specptr = unigen_special_0x1fd2; \ - break; \ - case 0x1fd3: \ - *specptr = unigen_special_0x1fd3; \ - break; \ - case 0x1fd6: \ - *specptr = unigen_special_0x1fd6; \ - break; \ - case 0x1fd7: \ - *specptr = unigen_special_0x1fd7; \ - break; \ - case 0x1fe2: \ - *specptr = unigen_special_0x1fe2; \ - break; \ - case 0x1fe3: \ - *specptr = unigen_special_0x1fe3; \ - break; \ - case 0x1fe4: \ - *specptr = unigen_special_0x1fe4; \ - break; \ - case 0x1fe6: \ - *specptr = unigen_special_0x1fe6; \ - break; \ - case 0x1fe7: \ - *specptr = unigen_special_0x1fe7; \ - break; \ - case 0x1ff2: \ - *specptr = unigen_special_0x1ff2; \ - break; \ - case 0x1ff3: \ - *specptr = unigen_special_0x1ff3; \ - break; \ - case 0x1ff4: \ - *specptr = unigen_special_0x1ff4; \ - break; \ - case 0x1ff6: \ - *specptr = unigen_special_0x1ff6; \ - break; \ - case 0x1ff7: \ - *specptr = unigen_special_0x1ff7; \ - break; \ - case 0x1ffc: \ - *specptr = unigen_special_0x1ffc; \ - break; \ - case 0xfb00: \ - *specptr = unigen_special_0xfb00; \ - break; \ - case 0xfb01: \ - *specptr = unigen_special_0xfb01; \ - break; \ - case 0xfb02: \ - *specptr = unigen_special_0xfb02; \ - break; \ - case 0xfb03: \ - *specptr = unigen_special_0xfb03; \ - break; \ - case 0xfb04: \ - *specptr = unigen_special_0xfb04; \ - break; \ - case 0xfb05: \ - *specptr = unigen_special_0xfb05; \ - break; \ - case 0xfb06: \ - *specptr = unigen_special_0xfb06; \ - break; \ - case 0xfb13: \ - *specptr = unigen_special_0xfb13; \ - break; \ - case 0xfb14: \ - *specptr = unigen_special_0xfb14; \ - break; \ - case 0xfb15: \ - *specptr = unigen_special_0xfb15; \ - break; \ - case 0xfb16: \ - *specptr = unigen_special_0xfb16; \ - break; \ - case 0xfb17: \ - *specptr = unigen_special_0xfb17; \ - break; \ - default: \ - *specptr = NULL; \ -} - -#define RETURN_COMBINING_CLASS(ch) \ -switch ((glui32)(ch) >> 8) { \ - case 3: \ - switch (ch) { \ - case 820: \ - case 821: \ - case 822: \ - case 823: \ - case 824: \ - return 1; \ - case 801: \ - case 802: \ - case 807: \ - case 808: \ - return 202; \ - case 795: \ - return 216; \ - case 790: \ - case 791: \ - case 792: \ - case 793: \ - case 796: \ - case 797: \ - case 798: \ - case 799: \ - case 800: \ - case 803: \ - case 804: \ - case 805: \ - case 806: \ - case 809: \ - case 810: \ - case 811: \ - case 812: \ - case 813: \ - case 814: \ - case 815: \ - case 816: \ - case 817: \ - case 818: \ - case 819: \ - case 825: \ - case 826: \ - case 827: \ - case 828: \ - case 839: \ - case 840: \ - case 841: \ - case 845: \ - case 846: \ - case 851: \ - case 852: \ - case 853: \ - case 854: \ - return 220; \ - case 768: \ - case 769: \ - case 770: \ - case 771: \ - case 772: \ - case 773: \ - case 774: \ - case 775: \ - case 776: \ - case 777: \ - case 778: \ - case 779: \ - case 780: \ - case 781: \ - case 782: \ - case 783: \ - case 784: \ - case 785: \ - case 786: \ - case 787: \ - case 788: \ - case 829: \ - case 830: \ - case 831: \ - case 832: \ - case 833: \ - case 834: \ - case 835: \ - case 836: \ - case 838: \ - case 842: \ - case 843: \ - case 844: \ - case 848: \ - case 849: \ - case 850: \ - case 855: \ - case 867: \ - case 868: \ - case 869: \ - case 870: \ - case 871: \ - case 872: \ - case 873: \ - case 874: \ - case 875: \ - case 876: \ - case 877: \ - case 878: \ - case 879: \ - return 230; \ - case 789: \ - case 794: \ - return 232; \ - case 863: \ - case 866: \ - return 233; \ - case 861: \ - case 862: \ - case 864: \ - case 865: \ - return 234; \ - case 837: \ - return 240; \ - } \ - return 0; \ - case 4: \ - switch (ch) { \ - case 1155: \ - case 1156: \ - case 1157: \ - case 1158: \ - return 230; \ - } \ - return 0; \ - case 5: \ - switch (ch) { \ - case 1456: \ - return 10; \ - case 1457: \ - return 11; \ - case 1458: \ - return 12; \ - case 1459: \ - return 13; \ - case 1460: \ - return 14; \ - case 1461: \ - return 15; \ - case 1462: \ - return 16; \ - case 1463: \ - return 17; \ - case 1464: \ - return 18; \ - case 1465: \ - return 19; \ - case 1467: \ - return 20; \ - case 1468: \ - return 21; \ - case 1469: \ - return 22; \ - case 1471: \ - return 23; \ - case 1473: \ - return 24; \ - case 1474: \ - return 25; \ - case 1425: \ - case 1430: \ - case 1435: \ - case 1443: \ - case 1444: \ - case 1445: \ - case 1446: \ - case 1447: \ - case 1450: \ - return 220; \ - case 1434: \ - case 1453: \ - return 222; \ - case 1454: \ - return 228; \ - case 1426: \ - case 1427: \ - case 1428: \ - case 1429: \ - case 1431: \ - case 1432: \ - case 1433: \ - case 1436: \ - case 1437: \ - case 1438: \ - case 1439: \ - case 1440: \ - case 1441: \ - case 1448: \ - case 1449: \ - case 1451: \ - case 1452: \ - case 1455: \ - case 1476: \ - return 230; \ - } \ - return 0; \ - case 6: \ - switch (ch) { \ - case 1611: \ - return 27; \ - case 1612: \ - return 28; \ - case 1613: \ - return 29; \ - case 1614: \ - return 30; \ - case 1615: \ - return 31; \ - case 1616: \ - return 32; \ - case 1617: \ - return 33; \ - case 1618: \ - return 34; \ - case 1648: \ - return 35; \ - case 1621: \ - case 1622: \ - case 1763: \ - case 1770: \ - case 1773: \ - return 220; \ - case 1552: \ - case 1553: \ - case 1554: \ - case 1555: \ - case 1556: \ - case 1557: \ - case 1619: \ - case 1620: \ - case 1623: \ - case 1624: \ - case 1750: \ - case 1751: \ - case 1752: \ - case 1753: \ - case 1754: \ - case 1755: \ - case 1756: \ - case 1759: \ - case 1760: \ - case 1761: \ - case 1762: \ - case 1764: \ - case 1767: \ - case 1768: \ - case 1771: \ - case 1772: \ - return 230; \ - } \ - return 0; \ - case 7: \ - switch (ch) { \ - case 1809: \ - return 36; \ - case 1841: \ - case 1844: \ - case 1847: \ - case 1848: \ - case 1849: \ - case 1851: \ - case 1852: \ - case 1854: \ - case 1858: \ - case 1860: \ - case 1862: \ - case 1864: \ - return 220; \ - case 1840: \ - case 1842: \ - case 1843: \ - case 1845: \ - case 1846: \ - case 1850: \ - case 1853: \ - case 1855: \ - case 1856: \ - case 1857: \ - case 1859: \ - case 1861: \ - case 1863: \ - case 1865: \ - case 1866: \ - return 230; \ - } \ - return 0; \ - case 9: \ - switch (ch) { \ - case 2364: \ - case 2492: \ - return 7; \ - case 2381: \ - case 2509: \ - return 9; \ - case 2386: \ - return 220; \ - case 2385: \ - case 2387: \ - case 2388: \ - return 230; \ - } \ - return 0; \ - case 10: \ - switch (ch) { \ - case 2620: \ - case 2748: \ - return 7; \ - case 2637: \ - case 2765: \ - return 9; \ - } \ - return 0; \ - case 11: \ - switch (ch) { \ - case 2876: \ - return 7; \ - case 2893: \ - case 3021: \ - return 9; \ - } \ - return 0; \ - case 12: \ - switch (ch) { \ - case 3260: \ - return 7; \ - case 3149: \ - case 3277: \ - return 9; \ - case 3157: \ - return 84; \ - case 3158: \ - return 91; \ - } \ - return 0; \ - case 13: \ - switch (ch) { \ - case 3405: \ - case 3530: \ - return 9; \ - } \ - return 0; \ - case 14: \ - switch (ch) { \ - case 3642: \ - return 9; \ - case 3640: \ - case 3641: \ - return 103; \ - case 3656: \ - case 3657: \ - case 3658: \ - case 3659: \ - return 107; \ - case 3768: \ - case 3769: \ - return 118; \ - case 3784: \ - case 3785: \ - case 3786: \ - case 3787: \ - return 122; \ - } \ - return 0; \ - case 15: \ - switch (ch) { \ - case 3972: \ - return 9; \ - case 3953: \ - return 129; \ - case 3954: \ - case 3962: \ - case 3963: \ - case 3964: \ - case 3965: \ - case 3968: \ - return 130; \ - case 3956: \ - return 132; \ - case 3897: \ - return 216; \ - case 3864: \ - case 3865: \ - case 3893: \ - case 3895: \ - case 4038: \ - return 220; \ - case 3970: \ - case 3971: \ - case 3974: \ - case 3975: \ - return 230; \ - } \ - return 0; \ - case 16: \ - switch (ch) { \ - case 4151: \ - return 7; \ - case 4153: \ - return 9; \ - } \ - return 0; \ - case 23: \ - switch (ch) { \ - case 5908: \ - case 5940: \ - case 6098: \ - return 9; \ - case 6109: \ - return 230; \ - } \ - return 0; \ - case 24: \ - switch (ch) { \ - case 6313: \ - return 228; \ - } \ - return 0; \ - case 25: \ - switch (ch) { \ - case 6459: \ - return 220; \ - case 6457: \ - return 222; \ - case 6458: \ - return 230; \ - } \ - return 0; \ - case 32: \ - switch (ch) { \ - case 8402: \ - case 8403: \ - case 8408: \ - case 8409: \ - case 8410: \ - case 8421: \ - case 8422: \ - case 8426: \ - return 1; \ - case 8424: \ - return 220; \ - case 8400: \ - case 8401: \ - case 8404: \ - case 8405: \ - case 8406: \ - case 8407: \ - case 8411: \ - case 8412: \ - case 8417: \ - case 8423: \ - case 8425: \ - return 230; \ - } \ - return 0; \ - case 48: \ - switch (ch) { \ - case 12441: \ - case 12442: \ - return 8; \ - case 12330: \ - return 218; \ - case 12333: \ - return 222; \ - case 12334: \ - case 12335: \ - return 224; \ - case 12331: \ - return 228; \ - case 12332: \ - return 232; \ - } \ - return 0; \ - case 251: \ - switch (ch) { \ - case 64286: \ - return 26; \ - } \ - return 0; \ - case 254: \ - switch (ch) { \ - case 65056: \ - case 65057: \ - case 65058: \ - case 65059: \ - return 230; \ - } \ - return 0; \ - case 465: \ - switch (ch) { \ - case 119143: \ - case 119144: \ - case 119145: \ - return 1; \ - case 119141: \ - case 119142: \ - case 119150: \ - case 119151: \ - case 119152: \ - case 119153: \ - case 119154: \ - return 216; \ - case 119163: \ - case 119164: \ - case 119165: \ - case 119166: \ - case 119167: \ - case 119168: \ - case 119169: \ - case 119170: \ - case 119178: \ - case 119179: \ - return 220; \ - case 119149: \ - return 226; \ - case 119173: \ - case 119174: \ - case 119175: \ - case 119176: \ - case 119177: \ - case 119210: \ - case 119211: \ - case 119212: \ - case 119213: \ - return 230; \ - } \ - return 0; \ -} \ -return 0; - -#define RETURN_COMPOSITION(ch1, ch2) \ -switch ((glui32)(ch1) >> 8) { \ - case 0: \ - switch (ch1) { \ - case 60: \ - switch (ch2) { \ - case 824: return 8814; \ - } \ - return 0; \ - case 61: \ - switch (ch2) { \ - case 824: return 8800; \ - } \ - return 0; \ - case 62: \ - switch (ch2) { \ - case 824: return 8815; \ - } \ - return 0; \ - case 65: \ - switch (ch2) { \ - case 768: return 192; \ - case 769: return 193; \ - case 770: return 194; \ - case 771: return 195; \ - case 772: return 256; \ - case 774: return 258; \ - case 775: return 550; \ - case 776: return 196; \ - case 777: return 7842; \ - case 778: return 197; \ - case 780: return 461; \ - case 783: return 512; \ - case 785: return 514; \ - case 803: return 7840; \ - case 805: return 7680; \ - case 808: return 260; \ - } \ - return 0; \ - case 66: \ - switch (ch2) { \ - case 775: return 7682; \ - case 803: return 7684; \ - case 817: return 7686; \ - } \ - return 0; \ - case 67: \ - switch (ch2) { \ - case 769: return 262; \ - case 770: return 264; \ - case 775: return 266; \ - case 780: return 268; \ - case 807: return 199; \ - } \ - return 0; \ - case 68: \ - switch (ch2) { \ - case 775: return 7690; \ - case 780: return 270; \ - case 803: return 7692; \ - case 807: return 7696; \ - case 813: return 7698; \ - case 817: return 7694; \ - } \ - return 0; \ - case 69: \ - switch (ch2) { \ - case 768: return 200; \ - case 769: return 201; \ - case 770: return 202; \ - case 771: return 7868; \ - case 772: return 274; \ - case 774: return 276; \ - case 775: return 278; \ - case 776: return 203; \ - case 777: return 7866; \ - case 780: return 282; \ - case 783: return 516; \ - case 785: return 518; \ - case 803: return 7864; \ - case 807: return 552; \ - case 808: return 280; \ - case 813: return 7704; \ - case 816: return 7706; \ - } \ - return 0; \ - case 70: \ - switch (ch2) { \ - case 775: return 7710; \ - } \ - return 0; \ - case 71: \ - switch (ch2) { \ - case 769: return 500; \ - case 770: return 284; \ - case 772: return 7712; \ - case 774: return 286; \ - case 775: return 288; \ - case 780: return 486; \ - case 807: return 290; \ - } \ - return 0; \ - case 72: \ - switch (ch2) { \ - case 770: return 292; \ - case 775: return 7714; \ - case 776: return 7718; \ - case 780: return 542; \ - case 803: return 7716; \ - case 807: return 7720; \ - case 814: return 7722; \ - } \ - return 0; \ - case 73: \ - switch (ch2) { \ - case 768: return 204; \ - case 769: return 205; \ - case 770: return 206; \ - case 771: return 296; \ - case 772: return 298; \ - case 774: return 300; \ - case 775: return 304; \ - case 776: return 207; \ - case 777: return 7880; \ - case 780: return 463; \ - case 783: return 520; \ - case 785: return 522; \ - case 803: return 7882; \ - case 808: return 302; \ - case 816: return 7724; \ - } \ - return 0; \ - case 74: \ - switch (ch2) { \ - case 770: return 308; \ - } \ - return 0; \ - case 75: \ - switch (ch2) { \ - case 769: return 7728; \ - case 780: return 488; \ - case 803: return 7730; \ - case 807: return 310; \ - case 817: return 7732; \ - } \ - return 0; \ - case 76: \ - switch (ch2) { \ - case 769: return 313; \ - case 780: return 317; \ - case 803: return 7734; \ - case 807: return 315; \ - case 813: return 7740; \ - case 817: return 7738; \ - } \ - return 0; \ - case 77: \ - switch (ch2) { \ - case 769: return 7742; \ - case 775: return 7744; \ - case 803: return 7746; \ - } \ - return 0; \ - case 78: \ - switch (ch2) { \ - case 768: return 504; \ - case 769: return 323; \ - case 771: return 209; \ - case 775: return 7748; \ - case 780: return 327; \ - case 803: return 7750; \ - case 807: return 325; \ - case 813: return 7754; \ - case 817: return 7752; \ - } \ - return 0; \ - case 79: \ - switch (ch2) { \ - case 768: return 210; \ - case 769: return 211; \ - case 770: return 212; \ - case 771: return 213; \ - case 772: return 332; \ - case 774: return 334; \ - case 775: return 558; \ - case 776: return 214; \ - case 777: return 7886; \ - case 779: return 336; \ - case 780: return 465; \ - case 783: return 524; \ - case 785: return 526; \ - case 795: return 416; \ - case 803: return 7884; \ - case 808: return 490; \ - } \ - return 0; \ - case 80: \ - switch (ch2) { \ - case 769: return 7764; \ - case 775: return 7766; \ - } \ - return 0; \ - case 82: \ - switch (ch2) { \ - case 769: return 340; \ - case 775: return 7768; \ - case 780: return 344; \ - case 783: return 528; \ - case 785: return 530; \ - case 803: return 7770; \ - case 807: return 342; \ - case 817: return 7774; \ - } \ - return 0; \ - case 83: \ - switch (ch2) { \ - case 769: return 346; \ - case 770: return 348; \ - case 775: return 7776; \ - case 780: return 352; \ - case 803: return 7778; \ - case 806: return 536; \ - case 807: return 350; \ - } \ - return 0; \ - case 84: \ - switch (ch2) { \ - case 775: return 7786; \ - case 780: return 356; \ - case 803: return 7788; \ - case 806: return 538; \ - case 807: return 354; \ - case 813: return 7792; \ - case 817: return 7790; \ - } \ - return 0; \ - case 85: \ - switch (ch2) { \ - case 768: return 217; \ - case 769: return 218; \ - case 770: return 219; \ - case 771: return 360; \ - case 772: return 362; \ - case 774: return 364; \ - case 776: return 220; \ - case 777: return 7910; \ - case 778: return 366; \ - case 779: return 368; \ - case 780: return 467; \ - case 783: return 532; \ - case 785: return 534; \ - case 795: return 431; \ - case 803: return 7908; \ - case 804: return 7794; \ - case 808: return 370; \ - case 813: return 7798; \ - case 816: return 7796; \ - } \ - return 0; \ - case 86: \ - switch (ch2) { \ - case 771: return 7804; \ - case 803: return 7806; \ - } \ - return 0; \ - case 87: \ - switch (ch2) { \ - case 768: return 7808; \ - case 769: return 7810; \ - case 770: return 372; \ - case 775: return 7814; \ - case 776: return 7812; \ - case 803: return 7816; \ - } \ - return 0; \ - case 88: \ - switch (ch2) { \ - case 775: return 7818; \ - case 776: return 7820; \ - } \ - return 0; \ - case 89: \ - switch (ch2) { \ - case 768: return 7922; \ - case 769: return 221; \ - case 770: return 374; \ - case 771: return 7928; \ - case 772: return 562; \ - case 775: return 7822; \ - case 776: return 376; \ - case 777: return 7926; \ - case 803: return 7924; \ - } \ - return 0; \ - case 90: \ - switch (ch2) { \ - case 769: return 377; \ - case 770: return 7824; \ - case 775: return 379; \ - case 780: return 381; \ - case 803: return 7826; \ - case 817: return 7828; \ - } \ - return 0; \ - case 97: \ - switch (ch2) { \ - case 768: return 224; \ - case 769: return 225; \ - case 770: return 226; \ - case 771: return 227; \ - case 772: return 257; \ - case 774: return 259; \ - case 775: return 551; \ - case 776: return 228; \ - case 777: return 7843; \ - case 778: return 229; \ - case 780: return 462; \ - case 783: return 513; \ - case 785: return 515; \ - case 803: return 7841; \ - case 805: return 7681; \ - case 808: return 261; \ - } \ - return 0; \ - case 98: \ - switch (ch2) { \ - case 775: return 7683; \ - case 803: return 7685; \ - case 817: return 7687; \ - } \ - return 0; \ - case 99: \ - switch (ch2) { \ - case 769: return 263; \ - case 770: return 265; \ - case 775: return 267; \ - case 780: return 269; \ - case 807: return 231; \ - } \ - return 0; \ - case 100: \ - switch (ch2) { \ - case 775: return 7691; \ - case 780: return 271; \ - case 803: return 7693; \ - case 807: return 7697; \ - case 813: return 7699; \ - case 817: return 7695; \ - } \ - return 0; \ - case 101: \ - switch (ch2) { \ - case 768: return 232; \ - case 769: return 233; \ - case 770: return 234; \ - case 771: return 7869; \ - case 772: return 275; \ - case 774: return 277; \ - case 775: return 279; \ - case 776: return 235; \ - case 777: return 7867; \ - case 780: return 283; \ - case 783: return 517; \ - case 785: return 519; \ - case 803: return 7865; \ - case 807: return 553; \ - case 808: return 281; \ - case 813: return 7705; \ - case 816: return 7707; \ - } \ - return 0; \ - case 102: \ - switch (ch2) { \ - case 775: return 7711; \ - } \ - return 0; \ - case 103: \ - switch (ch2) { \ - case 769: return 501; \ - case 770: return 285; \ - case 772: return 7713; \ - case 774: return 287; \ - case 775: return 289; \ - case 780: return 487; \ - case 807: return 291; \ - } \ - return 0; \ - case 104: \ - switch (ch2) { \ - case 770: return 293; \ - case 775: return 7715; \ - case 776: return 7719; \ - case 780: return 543; \ - case 803: return 7717; \ - case 807: return 7721; \ - case 814: return 7723; \ - case 817: return 7830; \ - } \ - return 0; \ - case 105: \ - switch (ch2) { \ - case 768: return 236; \ - case 769: return 237; \ - case 770: return 238; \ - case 771: return 297; \ - case 772: return 299; \ - case 774: return 301; \ - case 776: return 239; \ - case 777: return 7881; \ - case 780: return 464; \ - case 783: return 521; \ - case 785: return 523; \ - case 803: return 7883; \ - case 808: return 303; \ - case 816: return 7725; \ - } \ - return 0; \ - case 106: \ - switch (ch2) { \ - case 770: return 309; \ - case 780: return 496; \ - } \ - return 0; \ - case 107: \ - switch (ch2) { \ - case 769: return 7729; \ - case 780: return 489; \ - case 803: return 7731; \ - case 807: return 311; \ - case 817: return 7733; \ - } \ - return 0; \ - case 108: \ - switch (ch2) { \ - case 769: return 314; \ - case 780: return 318; \ - case 803: return 7735; \ - case 807: return 316; \ - case 813: return 7741; \ - case 817: return 7739; \ - } \ - return 0; \ - case 109: \ - switch (ch2) { \ - case 769: return 7743; \ - case 775: return 7745; \ - case 803: return 7747; \ - } \ - return 0; \ - case 110: \ - switch (ch2) { \ - case 768: return 505; \ - case 769: return 324; \ - case 771: return 241; \ - case 775: return 7749; \ - case 780: return 328; \ - case 803: return 7751; \ - case 807: return 326; \ - case 813: return 7755; \ - case 817: return 7753; \ - } \ - return 0; \ - case 111: \ - switch (ch2) { \ - case 768: return 242; \ - case 769: return 243; \ - case 770: return 244; \ - case 771: return 245; \ - case 772: return 333; \ - case 774: return 335; \ - case 775: return 559; \ - case 776: return 246; \ - case 777: return 7887; \ - case 779: return 337; \ - case 780: return 466; \ - case 783: return 525; \ - case 785: return 527; \ - case 795: return 417; \ - case 803: return 7885; \ - case 808: return 491; \ - } \ - return 0; \ - case 112: \ - switch (ch2) { \ - case 769: return 7765; \ - case 775: return 7767; \ - } \ - return 0; \ - case 114: \ - switch (ch2) { \ - case 769: return 341; \ - case 775: return 7769; \ - case 780: return 345; \ - case 783: return 529; \ - case 785: return 531; \ - case 803: return 7771; \ - case 807: return 343; \ - case 817: return 7775; \ - } \ - return 0; \ - case 115: \ - switch (ch2) { \ - case 769: return 347; \ - case 770: return 349; \ - case 775: return 7777; \ - case 780: return 353; \ - case 803: return 7779; \ - case 806: return 537; \ - case 807: return 351; \ - } \ - return 0; \ - case 116: \ - switch (ch2) { \ - case 775: return 7787; \ - case 776: return 7831; \ - case 780: return 357; \ - case 803: return 7789; \ - case 806: return 539; \ - case 807: return 355; \ - case 813: return 7793; \ - case 817: return 7791; \ - } \ - return 0; \ - case 117: \ - switch (ch2) { \ - case 768: return 249; \ - case 769: return 250; \ - case 770: return 251; \ - case 771: return 361; \ - case 772: return 363; \ - case 774: return 365; \ - case 776: return 252; \ - case 777: return 7911; \ - case 778: return 367; \ - case 779: return 369; \ - case 780: return 468; \ - case 783: return 533; \ - case 785: return 535; \ - case 795: return 432; \ - case 803: return 7909; \ - case 804: return 7795; \ - case 808: return 371; \ - case 813: return 7799; \ - case 816: return 7797; \ - } \ - return 0; \ - case 118: \ - switch (ch2) { \ - case 771: return 7805; \ - case 803: return 7807; \ - } \ - return 0; \ - case 119: \ - switch (ch2) { \ - case 768: return 7809; \ - case 769: return 7811; \ - case 770: return 373; \ - case 775: return 7815; \ - case 776: return 7813; \ - case 778: return 7832; \ - case 803: return 7817; \ - } \ - return 0; \ - case 120: \ - switch (ch2) { \ - case 775: return 7819; \ - case 776: return 7821; \ - } \ - return 0; \ - case 121: \ - switch (ch2) { \ - case 768: return 7923; \ - case 769: return 253; \ - case 770: return 375; \ - case 771: return 7929; \ - case 772: return 563; \ - case 775: return 7823; \ - case 776: return 255; \ - case 777: return 7927; \ - case 778: return 7833; \ - case 803: return 7925; \ - } \ - return 0; \ - case 122: \ - switch (ch2) { \ - case 769: return 378; \ - case 770: return 7825; \ - case 775: return 380; \ - case 780: return 382; \ - case 803: return 7827; \ - case 817: return 7829; \ - } \ - return 0; \ - case 168: \ - switch (ch2) { \ - case 768: return 8173; \ - case 769: return 901; \ - case 834: return 8129; \ - } \ - return 0; \ - case 194: \ - switch (ch2) { \ - case 768: return 7846; \ - case 769: return 7844; \ - case 771: return 7850; \ - case 777: return 7848; \ - } \ - return 0; \ - case 196: \ - switch (ch2) { \ - case 772: return 478; \ - } \ - return 0; \ - case 197: \ - switch (ch2) { \ - case 769: return 506; \ - } \ - return 0; \ - case 198: \ - switch (ch2) { \ - case 769: return 508; \ - case 772: return 482; \ - } \ - return 0; \ - case 199: \ - switch (ch2) { \ - case 769: return 7688; \ - } \ - return 0; \ - case 202: \ - switch (ch2) { \ - case 768: return 7872; \ - case 769: return 7870; \ - case 771: return 7876; \ - case 777: return 7874; \ - } \ - return 0; \ - case 207: \ - switch (ch2) { \ - case 769: return 7726; \ - } \ - return 0; \ - case 212: \ - switch (ch2) { \ - case 768: return 7890; \ - case 769: return 7888; \ - case 771: return 7894; \ - case 777: return 7892; \ - } \ - return 0; \ - case 213: \ - switch (ch2) { \ - case 769: return 7756; \ - case 772: return 556; \ - case 776: return 7758; \ - } \ - return 0; \ - case 214: \ - switch (ch2) { \ - case 772: return 554; \ - } \ - return 0; \ - case 216: \ - switch (ch2) { \ - case 769: return 510; \ - } \ - return 0; \ - case 220: \ - switch (ch2) { \ - case 768: return 475; \ - case 769: return 471; \ - case 772: return 469; \ - case 780: return 473; \ - } \ - return 0; \ - case 226: \ - switch (ch2) { \ - case 768: return 7847; \ - case 769: return 7845; \ - case 771: return 7851; \ - case 777: return 7849; \ - } \ - return 0; \ - case 228: \ - switch (ch2) { \ - case 772: return 479; \ - } \ - return 0; \ - case 229: \ - switch (ch2) { \ - case 769: return 507; \ - } \ - return 0; \ - case 230: \ - switch (ch2) { \ - case 769: return 509; \ - case 772: return 483; \ - } \ - return 0; \ - case 231: \ - switch (ch2) { \ - case 769: return 7689; \ - } \ - return 0; \ - case 234: \ - switch (ch2) { \ - case 768: return 7873; \ - case 769: return 7871; \ - case 771: return 7877; \ - case 777: return 7875; \ - } \ - return 0; \ - case 239: \ - switch (ch2) { \ - case 769: return 7727; \ - } \ - return 0; \ - case 244: \ - switch (ch2) { \ - case 768: return 7891; \ - case 769: return 7889; \ - case 771: return 7895; \ - case 777: return 7893; \ - } \ - return 0; \ - case 245: \ - switch (ch2) { \ - case 769: return 7757; \ - case 772: return 557; \ - case 776: return 7759; \ - } \ - return 0; \ - case 246: \ - switch (ch2) { \ - case 772: return 555; \ - } \ - return 0; \ - case 248: \ - switch (ch2) { \ - case 769: return 511; \ - } \ - return 0; \ - case 252: \ - switch (ch2) { \ - case 768: return 476; \ - case 769: return 472; \ - case 772: return 470; \ - case 780: return 474; \ - } \ - return 0; \ - } \ - return 0; \ - case 1: \ - switch (ch1) { \ - case 258: \ - switch (ch2) { \ - case 768: return 7856; \ - case 769: return 7854; \ - case 771: return 7860; \ - case 777: return 7858; \ - } \ - return 0; \ - case 259: \ - switch (ch2) { \ - case 768: return 7857; \ - case 769: return 7855; \ - case 771: return 7861; \ - case 777: return 7859; \ - } \ - return 0; \ - case 274: \ - switch (ch2) { \ - case 768: return 7700; \ - case 769: return 7702; \ - } \ - return 0; \ - case 275: \ - switch (ch2) { \ - case 768: return 7701; \ - case 769: return 7703; \ - } \ - return 0; \ - case 332: \ - switch (ch2) { \ - case 768: return 7760; \ - case 769: return 7762; \ - } \ - return 0; \ - case 333: \ - switch (ch2) { \ - case 768: return 7761; \ - case 769: return 7763; \ - } \ - return 0; \ - case 346: \ - switch (ch2) { \ - case 775: return 7780; \ - } \ - return 0; \ - case 347: \ - switch (ch2) { \ - case 775: return 7781; \ - } \ - return 0; \ - case 352: \ - switch (ch2) { \ - case 775: return 7782; \ - } \ - return 0; \ - case 353: \ - switch (ch2) { \ - case 775: return 7783; \ - } \ - return 0; \ - case 360: \ - switch (ch2) { \ - case 769: return 7800; \ - } \ - return 0; \ - case 361: \ - switch (ch2) { \ - case 769: return 7801; \ - } \ - return 0; \ - case 362: \ - switch (ch2) { \ - case 776: return 7802; \ - } \ - return 0; \ - case 363: \ - switch (ch2) { \ - case 776: return 7803; \ - } \ - return 0; \ - case 383: \ - switch (ch2) { \ - case 775: return 7835; \ - } \ - return 0; \ - case 416: \ - switch (ch2) { \ - case 768: return 7900; \ - case 769: return 7898; \ - case 771: return 7904; \ - case 777: return 7902; \ - case 803: return 7906; \ - } \ - return 0; \ - case 417: \ - switch (ch2) { \ - case 768: return 7901; \ - case 769: return 7899; \ - case 771: return 7905; \ - case 777: return 7903; \ - case 803: return 7907; \ - } \ - return 0; \ - case 431: \ - switch (ch2) { \ - case 768: return 7914; \ - case 769: return 7912; \ - case 771: return 7918; \ - case 777: return 7916; \ - case 803: return 7920; \ - } \ - return 0; \ - case 432: \ - switch (ch2) { \ - case 768: return 7915; \ - case 769: return 7913; \ - case 771: return 7919; \ - case 777: return 7917; \ - case 803: return 7921; \ - } \ - return 0; \ - case 439: \ - switch (ch2) { \ - case 780: return 494; \ - } \ - return 0; \ - case 490: \ - switch (ch2) { \ - case 772: return 492; \ - } \ - return 0; \ - case 491: \ - switch (ch2) { \ - case 772: return 493; \ - } \ - return 0; \ - } \ - return 0; \ - case 2: \ - switch (ch1) { \ - case 550: \ - switch (ch2) { \ - case 772: return 480; \ - } \ - return 0; \ - case 551: \ - switch (ch2) { \ - case 772: return 481; \ - } \ - return 0; \ - case 552: \ - switch (ch2) { \ - case 774: return 7708; \ - } \ - return 0; \ - case 553: \ - switch (ch2) { \ - case 774: return 7709; \ - } \ - return 0; \ - case 558: \ - switch (ch2) { \ - case 772: return 560; \ - } \ - return 0; \ - case 559: \ - switch (ch2) { \ - case 772: return 561; \ - } \ - return 0; \ - case 658: \ - switch (ch2) { \ - case 780: return 495; \ - } \ - return 0; \ - } \ - return 0; \ - case 3: \ - switch (ch1) { \ - case 776: \ - switch (ch2) { \ - case 769: return 836; \ - } \ - return 0; \ - case 913: \ - switch (ch2) { \ - case 768: return 8122; \ - case 769: return 902; \ - case 772: return 8121; \ - case 774: return 8120; \ - case 787: return 7944; \ - case 788: return 7945; \ - case 837: return 8124; \ - } \ - return 0; \ - case 917: \ - switch (ch2) { \ - case 768: return 8136; \ - case 769: return 904; \ - case 787: return 7960; \ - case 788: return 7961; \ - } \ - return 0; \ - case 919: \ - switch (ch2) { \ - case 768: return 8138; \ - case 769: return 905; \ - case 787: return 7976; \ - case 788: return 7977; \ - case 837: return 8140; \ - } \ - return 0; \ - case 921: \ - switch (ch2) { \ - case 768: return 8154; \ - case 769: return 906; \ - case 772: return 8153; \ - case 774: return 8152; \ - case 776: return 938; \ - case 787: return 7992; \ - case 788: return 7993; \ - } \ - return 0; \ - case 927: \ - switch (ch2) { \ - case 768: return 8184; \ - case 769: return 908; \ - case 787: return 8008; \ - case 788: return 8009; \ - } \ - return 0; \ - case 929: \ - switch (ch2) { \ - case 788: return 8172; \ - } \ - return 0; \ - case 933: \ - switch (ch2) { \ - case 768: return 8170; \ - case 769: return 910; \ - case 772: return 8169; \ - case 774: return 8168; \ - case 776: return 939; \ - case 788: return 8025; \ - } \ - return 0; \ - case 937: \ - switch (ch2) { \ - case 768: return 8186; \ - case 769: return 911; \ - case 787: return 8040; \ - case 788: return 8041; \ - case 837: return 8188; \ - } \ - return 0; \ - case 940: \ - switch (ch2) { \ - case 837: return 8116; \ - } \ - return 0; \ - case 942: \ - switch (ch2) { \ - case 837: return 8132; \ - } \ - return 0; \ - case 945: \ - switch (ch2) { \ - case 768: return 8048; \ - case 769: return 940; \ - case 772: return 8113; \ - case 774: return 8112; \ - case 787: return 7936; \ - case 788: return 7937; \ - case 834: return 8118; \ - case 837: return 8115; \ - } \ - return 0; \ - case 949: \ - switch (ch2) { \ - case 768: return 8050; \ - case 769: return 941; \ - case 787: return 7952; \ - case 788: return 7953; \ - } \ - return 0; \ - case 951: \ - switch (ch2) { \ - case 768: return 8052; \ - case 769: return 942; \ - case 787: return 7968; \ - case 788: return 7969; \ - case 834: return 8134; \ - case 837: return 8131; \ - } \ - return 0; \ - case 953: \ - switch (ch2) { \ - case 768: return 8054; \ - case 769: return 943; \ - case 772: return 8145; \ - case 774: return 8144; \ - case 776: return 970; \ - case 787: return 7984; \ - case 788: return 7985; \ - case 834: return 8150; \ - } \ - return 0; \ - case 959: \ - switch (ch2) { \ - case 768: return 8056; \ - case 769: return 972; \ - case 787: return 8000; \ - case 788: return 8001; \ - } \ - return 0; \ - case 961: \ - switch (ch2) { \ - case 787: return 8164; \ - case 788: return 8165; \ - } \ - return 0; \ - case 965: \ - switch (ch2) { \ - case 768: return 8058; \ - case 769: return 973; \ - case 772: return 8161; \ - case 774: return 8160; \ - case 776: return 971; \ - case 787: return 8016; \ - case 788: return 8017; \ - case 834: return 8166; \ - } \ - return 0; \ - case 969: \ - switch (ch2) { \ - case 768: return 8060; \ - case 769: return 974; \ - case 787: return 8032; \ - case 788: return 8033; \ - case 834: return 8182; \ - case 837: return 8179; \ - } \ - return 0; \ - case 970: \ - switch (ch2) { \ - case 768: return 8146; \ - case 769: return 912; \ - case 834: return 8151; \ - } \ - return 0; \ - case 971: \ - switch (ch2) { \ - case 768: return 8162; \ - case 769: return 944; \ - case 834: return 8167; \ - } \ - return 0; \ - case 974: \ - switch (ch2) { \ - case 837: return 8180; \ - } \ - return 0; \ - case 978: \ - switch (ch2) { \ - case 769: return 979; \ - case 776: return 980; \ - } \ - return 0; \ - } \ - return 0; \ - case 4: \ - switch (ch1) { \ - case 1030: \ - switch (ch2) { \ - case 776: return 1031; \ - } \ - return 0; \ - case 1040: \ - switch (ch2) { \ - case 774: return 1232; \ - case 776: return 1234; \ - } \ - return 0; \ - case 1043: \ - switch (ch2) { \ - case 769: return 1027; \ - } \ - return 0; \ - case 1045: \ - switch (ch2) { \ - case 768: return 1024; \ - case 774: return 1238; \ - case 776: return 1025; \ - } \ - return 0; \ - case 1046: \ - switch (ch2) { \ - case 774: return 1217; \ - case 776: return 1244; \ - } \ - return 0; \ - case 1047: \ - switch (ch2) { \ - case 776: return 1246; \ - } \ - return 0; \ - case 1048: \ - switch (ch2) { \ - case 768: return 1037; \ - case 772: return 1250; \ - case 774: return 1049; \ - case 776: return 1252; \ - } \ - return 0; \ - case 1050: \ - switch (ch2) { \ - case 769: return 1036; \ - } \ - return 0; \ - case 1054: \ - switch (ch2) { \ - case 776: return 1254; \ - } \ - return 0; \ - case 1059: \ - switch (ch2) { \ - case 772: return 1262; \ - case 774: return 1038; \ - case 776: return 1264; \ - case 779: return 1266; \ - } \ - return 0; \ - case 1063: \ - switch (ch2) { \ - case 776: return 1268; \ - } \ - return 0; \ - case 1067: \ - switch (ch2) { \ - case 776: return 1272; \ - } \ - return 0; \ - case 1069: \ - switch (ch2) { \ - case 776: return 1260; \ - } \ - return 0; \ - case 1072: \ - switch (ch2) { \ - case 774: return 1233; \ - case 776: return 1235; \ - } \ - return 0; \ - case 1075: \ - switch (ch2) { \ - case 769: return 1107; \ - } \ - return 0; \ - case 1077: \ - switch (ch2) { \ - case 768: return 1104; \ - case 774: return 1239; \ - case 776: return 1105; \ - } \ - return 0; \ - case 1078: \ - switch (ch2) { \ - case 774: return 1218; \ - case 776: return 1245; \ - } \ - return 0; \ - case 1079: \ - switch (ch2) { \ - case 776: return 1247; \ - } \ - return 0; \ - case 1080: \ - switch (ch2) { \ - case 768: return 1117; \ - case 772: return 1251; \ - case 774: return 1081; \ - case 776: return 1253; \ - } \ - return 0; \ - case 1082: \ - switch (ch2) { \ - case 769: return 1116; \ - } \ - return 0; \ - case 1086: \ - switch (ch2) { \ - case 776: return 1255; \ - } \ - return 0; \ - case 1091: \ - switch (ch2) { \ - case 772: return 1263; \ - case 774: return 1118; \ - case 776: return 1265; \ - case 779: return 1267; \ - } \ - return 0; \ - case 1095: \ - switch (ch2) { \ - case 776: return 1269; \ - } \ - return 0; \ - case 1099: \ - switch (ch2) { \ - case 776: return 1273; \ - } \ - return 0; \ - case 1101: \ - switch (ch2) { \ - case 776: return 1261; \ - } \ - return 0; \ - case 1110: \ - switch (ch2) { \ - case 776: return 1111; \ - } \ - return 0; \ - case 1140: \ - switch (ch2) { \ - case 783: return 1142; \ - } \ - return 0; \ - case 1141: \ - switch (ch2) { \ - case 783: return 1143; \ - } \ - return 0; \ - case 1240: \ - switch (ch2) { \ - case 776: return 1242; \ - } \ - return 0; \ - case 1241: \ - switch (ch2) { \ - case 776: return 1243; \ - } \ - return 0; \ - case 1256: \ - switch (ch2) { \ - case 776: return 1258; \ - } \ - return 0; \ - case 1257: \ - switch (ch2) { \ - case 776: return 1259; \ - } \ - return 0; \ - } \ - return 0; \ - case 5: \ - switch (ch1) { \ - case 1488: \ - switch (ch2) { \ - case 1463: return 64302; \ - case 1464: return 64303; \ - case 1468: return 64304; \ - } \ - return 0; \ - case 1489: \ - switch (ch2) { \ - case 1468: return 64305; \ - case 1471: return 64332; \ - } \ - return 0; \ - case 1490: \ - switch (ch2) { \ - case 1468: return 64306; \ - } \ - return 0; \ - case 1491: \ - switch (ch2) { \ - case 1468: return 64307; \ - } \ - return 0; \ - case 1492: \ - switch (ch2) { \ - case 1468: return 64308; \ - } \ - return 0; \ - case 1493: \ - switch (ch2) { \ - case 1465: return 64331; \ - case 1468: return 64309; \ - } \ - return 0; \ - case 1494: \ - switch (ch2) { \ - case 1468: return 64310; \ - } \ - return 0; \ - case 1496: \ - switch (ch2) { \ - case 1468: return 64312; \ - } \ - return 0; \ - case 1497: \ - switch (ch2) { \ - case 1460: return 64285; \ - case 1468: return 64313; \ - } \ - return 0; \ - case 1498: \ - switch (ch2) { \ - case 1468: return 64314; \ - } \ - return 0; \ - case 1499: \ - switch (ch2) { \ - case 1468: return 64315; \ - case 1471: return 64333; \ - } \ - return 0; \ - case 1500: \ - switch (ch2) { \ - case 1468: return 64316; \ - } \ - return 0; \ - case 1502: \ - switch (ch2) { \ - case 1468: return 64318; \ - } \ - return 0; \ - case 1504: \ - switch (ch2) { \ - case 1468: return 64320; \ - } \ - return 0; \ - case 1505: \ - switch (ch2) { \ - case 1468: return 64321; \ - } \ - return 0; \ - case 1507: \ - switch (ch2) { \ - case 1468: return 64323; \ - } \ - return 0; \ - case 1508: \ - switch (ch2) { \ - case 1468: return 64324; \ - case 1471: return 64334; \ - } \ - return 0; \ - case 1510: \ - switch (ch2) { \ - case 1468: return 64326; \ - } \ - return 0; \ - case 1511: \ - switch (ch2) { \ - case 1468: return 64327; \ - } \ - return 0; \ - case 1512: \ - switch (ch2) { \ - case 1468: return 64328; \ - } \ - return 0; \ - case 1513: \ - switch (ch2) { \ - case 1468: return 64329; \ - case 1473: return 64298; \ - case 1474: return 64299; \ - } \ - return 0; \ - case 1514: \ - switch (ch2) { \ - case 1468: return 64330; \ - } \ - return 0; \ - case 1522: \ - switch (ch2) { \ - case 1463: return 64287; \ - } \ - return 0; \ - } \ - return 0; \ - case 6: \ - switch (ch1) { \ - case 1575: \ - switch (ch2) { \ - case 1619: return 1570; \ - case 1620: return 1571; \ - case 1621: return 1573; \ - } \ - return 0; \ - case 1608: \ - switch (ch2) { \ - case 1620: return 1572; \ - } \ - return 0; \ - case 1610: \ - switch (ch2) { \ - case 1620: return 1574; \ - } \ - return 0; \ - case 1729: \ - switch (ch2) { \ - case 1620: return 1730; \ - } \ - return 0; \ - case 1746: \ - switch (ch2) { \ - case 1620: return 1747; \ - } \ - return 0; \ - case 1749: \ - switch (ch2) { \ - case 1620: return 1728; \ - } \ - return 0; \ - } \ - return 0; \ - case 9: \ - switch (ch1) { \ - case 2325: \ - switch (ch2) { \ - case 2364: return 2392; \ - } \ - return 0; \ - case 2326: \ - switch (ch2) { \ - case 2364: return 2393; \ - } \ - return 0; \ - case 2327: \ - switch (ch2) { \ - case 2364: return 2394; \ - } \ - return 0; \ - case 2332: \ - switch (ch2) { \ - case 2364: return 2395; \ - } \ - return 0; \ - case 2337: \ - switch (ch2) { \ - case 2364: return 2396; \ - } \ - return 0; \ - case 2338: \ - switch (ch2) { \ - case 2364: return 2397; \ - } \ - return 0; \ - case 2344: \ - switch (ch2) { \ - case 2364: return 2345; \ - } \ - return 0; \ - case 2347: \ - switch (ch2) { \ - case 2364: return 2398; \ - } \ - return 0; \ - case 2351: \ - switch (ch2) { \ - case 2364: return 2399; \ - } \ - return 0; \ - case 2352: \ - switch (ch2) { \ - case 2364: return 2353; \ - } \ - return 0; \ - case 2355: \ - switch (ch2) { \ - case 2364: return 2356; \ - } \ - return 0; \ - case 2465: \ - switch (ch2) { \ - case 2492: return 2524; \ - } \ - return 0; \ - case 2466: \ - switch (ch2) { \ - case 2492: return 2525; \ - } \ - return 0; \ - case 2479: \ - switch (ch2) { \ - case 2492: return 2527; \ - } \ - return 0; \ - case 2503: \ - switch (ch2) { \ - case 2494: return 2507; \ - case 2519: return 2508; \ - } \ - return 0; \ - } \ - return 0; \ - case 10: \ - switch (ch1) { \ - case 2582: \ - switch (ch2) { \ - case 2620: return 2649; \ - } \ - return 0; \ - case 2583: \ - switch (ch2) { \ - case 2620: return 2650; \ - } \ - return 0; \ - case 2588: \ - switch (ch2) { \ - case 2620: return 2651; \ - } \ - return 0; \ - case 2603: \ - switch (ch2) { \ - case 2620: return 2654; \ - } \ - return 0; \ - case 2610: \ - switch (ch2) { \ - case 2620: return 2611; \ - } \ - return 0; \ - case 2616: \ - switch (ch2) { \ - case 2620: return 2614; \ - } \ - return 0; \ - } \ - return 0; \ - case 11: \ - switch (ch1) { \ - case 2849: \ - switch (ch2) { \ - case 2876: return 2908; \ - } \ - return 0; \ - case 2850: \ - switch (ch2) { \ - case 2876: return 2909; \ - } \ - return 0; \ - case 2887: \ - switch (ch2) { \ - case 2878: return 2891; \ - case 2902: return 2888; \ - case 2903: return 2892; \ - } \ - return 0; \ - case 2962: \ - switch (ch2) { \ - case 3031: return 2964; \ - } \ - return 0; \ - case 3014: \ - switch (ch2) { \ - case 3006: return 3018; \ - case 3031: return 3020; \ - } \ - return 0; \ - case 3015: \ - switch (ch2) { \ - case 3006: return 3019; \ - } \ - return 0; \ - } \ - return 0; \ - case 12: \ - switch (ch1) { \ - case 3142: \ - switch (ch2) { \ - case 3158: return 3144; \ - } \ - return 0; \ - case 3263: \ - switch (ch2) { \ - case 3285: return 3264; \ - } \ - return 0; \ - case 3270: \ - switch (ch2) { \ - case 3266: return 3274; \ - case 3285: return 3271; \ - case 3286: return 3272; \ - } \ - return 0; \ - case 3274: \ - switch (ch2) { \ - case 3285: return 3275; \ - } \ - return 0; \ - } \ - return 0; \ - case 13: \ - switch (ch1) { \ - case 3398: \ - switch (ch2) { \ - case 3390: return 3402; \ - case 3415: return 3404; \ - } \ - return 0; \ - case 3399: \ - switch (ch2) { \ - case 3390: return 3403; \ - } \ - return 0; \ - case 3545: \ - switch (ch2) { \ - case 3530: return 3546; \ - case 3535: return 3548; \ - case 3551: return 3550; \ - } \ - return 0; \ - case 3548: \ - switch (ch2) { \ - case 3530: return 3549; \ - } \ - return 0; \ - } \ - return 0; \ - case 15: \ - switch (ch1) { \ - case 3904: \ - switch (ch2) { \ - case 4021: return 3945; \ - } \ - return 0; \ - case 3906: \ - switch (ch2) { \ - case 4023: return 3907; \ - } \ - return 0; \ - case 3916: \ - switch (ch2) { \ - case 4023: return 3917; \ - } \ - return 0; \ - case 3921: \ - switch (ch2) { \ - case 4023: return 3922; \ - } \ - return 0; \ - case 3926: \ - switch (ch2) { \ - case 4023: return 3927; \ - } \ - return 0; \ - case 3931: \ - switch (ch2) { \ - case 4023: return 3932; \ - } \ - return 0; \ - case 3953: \ - switch (ch2) { \ - case 3954: return 3955; \ - case 3956: return 3957; \ - case 3968: return 3969; \ - } \ - return 0; \ - case 3984: \ - switch (ch2) { \ - case 4021: return 4025; \ - } \ - return 0; \ - case 3986: \ - switch (ch2) { \ - case 4023: return 3987; \ - } \ - return 0; \ - case 3996: \ - switch (ch2) { \ - case 4023: return 3997; \ - } \ - return 0; \ - case 4001: \ - switch (ch2) { \ - case 4023: return 4002; \ - } \ - return 0; \ - case 4006: \ - switch (ch2) { \ - case 4023: return 4007; \ - } \ - return 0; \ - case 4011: \ - switch (ch2) { \ - case 4023: return 4012; \ - } \ - return 0; \ - case 4018: \ - switch (ch2) { \ - case 3968: return 3958; \ - } \ - return 0; \ - case 4019: \ - switch (ch2) { \ - case 3968: return 3960; \ - } \ - return 0; \ - } \ - return 0; \ - case 16: \ - switch (ch1) { \ - case 4133: \ - switch (ch2) { \ - case 4142: return 4134; \ - } \ - return 0; \ - } \ - return 0; \ - case 30: \ - switch (ch1) { \ - case 7734: \ - switch (ch2) { \ - case 772: return 7736; \ - } \ - return 0; \ - case 7735: \ - switch (ch2) { \ - case 772: return 7737; \ - } \ - return 0; \ - case 7770: \ - switch (ch2) { \ - case 772: return 7772; \ - } \ - return 0; \ - case 7771: \ - switch (ch2) { \ - case 772: return 7773; \ - } \ - return 0; \ - case 7778: \ - switch (ch2) { \ - case 775: return 7784; \ - } \ - return 0; \ - case 7779: \ - switch (ch2) { \ - case 775: return 7785; \ - } \ - return 0; \ - case 7840: \ - switch (ch2) { \ - case 770: return 7852; \ - case 774: return 7862; \ - } \ - return 0; \ - case 7841: \ - switch (ch2) { \ - case 770: return 7853; \ - case 774: return 7863; \ - } \ - return 0; \ - case 7864: \ - switch (ch2) { \ - case 770: return 7878; \ - } \ - return 0; \ - case 7865: \ - switch (ch2) { \ - case 770: return 7879; \ - } \ - return 0; \ - case 7884: \ - switch (ch2) { \ - case 770: return 7896; \ - } \ - return 0; \ - case 7885: \ - switch (ch2) { \ - case 770: return 7897; \ - } \ - return 0; \ - } \ - return 0; \ - case 31: \ - switch (ch1) { \ - case 7936: \ - switch (ch2) { \ - case 768: return 7938; \ - case 769: return 7940; \ - case 834: return 7942; \ - case 837: return 8064; \ - } \ - return 0; \ - case 7937: \ - switch (ch2) { \ - case 768: return 7939; \ - case 769: return 7941; \ - case 834: return 7943; \ - case 837: return 8065; \ - } \ - return 0; \ - case 7938: \ - switch (ch2) { \ - case 837: return 8066; \ - } \ - return 0; \ - case 7939: \ - switch (ch2) { \ - case 837: return 8067; \ - } \ - return 0; \ - case 7940: \ - switch (ch2) { \ - case 837: return 8068; \ - } \ - return 0; \ - case 7941: \ - switch (ch2) { \ - case 837: return 8069; \ - } \ - return 0; \ - case 7942: \ - switch (ch2) { \ - case 837: return 8070; \ - } \ - return 0; \ - case 7943: \ - switch (ch2) { \ - case 837: return 8071; \ - } \ - return 0; \ - case 7944: \ - switch (ch2) { \ - case 768: return 7946; \ - case 769: return 7948; \ - case 834: return 7950; \ - case 837: return 8072; \ - } \ - return 0; \ - case 7945: \ - switch (ch2) { \ - case 768: return 7947; \ - case 769: return 7949; \ - case 834: return 7951; \ - case 837: return 8073; \ - } \ - return 0; \ - case 7946: \ - switch (ch2) { \ - case 837: return 8074; \ - } \ - return 0; \ - case 7947: \ - switch (ch2) { \ - case 837: return 8075; \ - } \ - return 0; \ - case 7948: \ - switch (ch2) { \ - case 837: return 8076; \ - } \ - return 0; \ - case 7949: \ - switch (ch2) { \ - case 837: return 8077; \ - } \ - return 0; \ - case 7950: \ - switch (ch2) { \ - case 837: return 8078; \ - } \ - return 0; \ - case 7951: \ - switch (ch2) { \ - case 837: return 8079; \ - } \ - return 0; \ - case 7952: \ - switch (ch2) { \ - case 768: return 7954; \ - case 769: return 7956; \ - } \ - return 0; \ - case 7953: \ - switch (ch2) { \ - case 768: return 7955; \ - case 769: return 7957; \ - } \ - return 0; \ - case 7960: \ - switch (ch2) { \ - case 768: return 7962; \ - case 769: return 7964; \ - } \ - return 0; \ - case 7961: \ - switch (ch2) { \ - case 768: return 7963; \ - case 769: return 7965; \ - } \ - return 0; \ - case 7968: \ - switch (ch2) { \ - case 768: return 7970; \ - case 769: return 7972; \ - case 834: return 7974; \ - case 837: return 8080; \ - } \ - return 0; \ - case 7969: \ - switch (ch2) { \ - case 768: return 7971; \ - case 769: return 7973; \ - case 834: return 7975; \ - case 837: return 8081; \ - } \ - return 0; \ - case 7970: \ - switch (ch2) { \ - case 837: return 8082; \ - } \ - return 0; \ - case 7971: \ - switch (ch2) { \ - case 837: return 8083; \ - } \ - return 0; \ - case 7972: \ - switch (ch2) { \ - case 837: return 8084; \ - } \ - return 0; \ - case 7973: \ - switch (ch2) { \ - case 837: return 8085; \ - } \ - return 0; \ - case 7974: \ - switch (ch2) { \ - case 837: return 8086; \ - } \ - return 0; \ - case 7975: \ - switch (ch2) { \ - case 837: return 8087; \ - } \ - return 0; \ - case 7976: \ - switch (ch2) { \ - case 768: return 7978; \ - case 769: return 7980; \ - case 834: return 7982; \ - case 837: return 8088; \ - } \ - return 0; \ - case 7977: \ - switch (ch2) { \ - case 768: return 7979; \ - case 769: return 7981; \ - case 834: return 7983; \ - case 837: return 8089; \ - } \ - return 0; \ - case 7978: \ - switch (ch2) { \ - case 837: return 8090; \ - } \ - return 0; \ - case 7979: \ - switch (ch2) { \ - case 837: return 8091; \ - } \ - return 0; \ - case 7980: \ - switch (ch2) { \ - case 837: return 8092; \ - } \ - return 0; \ - case 7981: \ - switch (ch2) { \ - case 837: return 8093; \ - } \ - return 0; \ - case 7982: \ - switch (ch2) { \ - case 837: return 8094; \ - } \ - return 0; \ - case 7983: \ - switch (ch2) { \ - case 837: return 8095; \ - } \ - return 0; \ - case 7984: \ - switch (ch2) { \ - case 768: return 7986; \ - case 769: return 7988; \ - case 834: return 7990; \ - } \ - return 0; \ - case 7985: \ - switch (ch2) { \ - case 768: return 7987; \ - case 769: return 7989; \ - case 834: return 7991; \ - } \ - return 0; \ - case 7992: \ - switch (ch2) { \ - case 768: return 7994; \ - case 769: return 7996; \ - case 834: return 7998; \ - } \ - return 0; \ - case 7993: \ - switch (ch2) { \ - case 768: return 7995; \ - case 769: return 7997; \ - case 834: return 7999; \ - } \ - return 0; \ - case 8000: \ - switch (ch2) { \ - case 768: return 8002; \ - case 769: return 8004; \ - } \ - return 0; \ - case 8001: \ - switch (ch2) { \ - case 768: return 8003; \ - case 769: return 8005; \ - } \ - return 0; \ - case 8008: \ - switch (ch2) { \ - case 768: return 8010; \ - case 769: return 8012; \ - } \ - return 0; \ - case 8009: \ - switch (ch2) { \ - case 768: return 8011; \ - case 769: return 8013; \ - } \ - return 0; \ - case 8016: \ - switch (ch2) { \ - case 768: return 8018; \ - case 769: return 8020; \ - case 834: return 8022; \ - } \ - return 0; \ - case 8017: \ - switch (ch2) { \ - case 768: return 8019; \ - case 769: return 8021; \ - case 834: return 8023; \ - } \ - return 0; \ - case 8025: \ - switch (ch2) { \ - case 768: return 8027; \ - case 769: return 8029; \ - case 834: return 8031; \ - } \ - return 0; \ - case 8032: \ - switch (ch2) { \ - case 768: return 8034; \ - case 769: return 8036; \ - case 834: return 8038; \ - case 837: return 8096; \ - } \ - return 0; \ - case 8033: \ - switch (ch2) { \ - case 768: return 8035; \ - case 769: return 8037; \ - case 834: return 8039; \ - case 837: return 8097; \ - } \ - return 0; \ - case 8034: \ - switch (ch2) { \ - case 837: return 8098; \ - } \ - return 0; \ - case 8035: \ - switch (ch2) { \ - case 837: return 8099; \ - } \ - return 0; \ - case 8036: \ - switch (ch2) { \ - case 837: return 8100; \ - } \ - return 0; \ - case 8037: \ - switch (ch2) { \ - case 837: return 8101; \ - } \ - return 0; \ - case 8038: \ - switch (ch2) { \ - case 837: return 8102; \ - } \ - return 0; \ - case 8039: \ - switch (ch2) { \ - case 837: return 8103; \ - } \ - return 0; \ - case 8040: \ - switch (ch2) { \ - case 768: return 8042; \ - case 769: return 8044; \ - case 834: return 8046; \ - case 837: return 8104; \ - } \ - return 0; \ - case 8041: \ - switch (ch2) { \ - case 768: return 8043; \ - case 769: return 8045; \ - case 834: return 8047; \ - case 837: return 8105; \ - } \ - return 0; \ - case 8042: \ - switch (ch2) { \ - case 837: return 8106; \ - } \ - return 0; \ - case 8043: \ - switch (ch2) { \ - case 837: return 8107; \ - } \ - return 0; \ - case 8044: \ - switch (ch2) { \ - case 837: return 8108; \ - } \ - return 0; \ - case 8045: \ - switch (ch2) { \ - case 837: return 8109; \ - } \ - return 0; \ - case 8046: \ - switch (ch2) { \ - case 837: return 8110; \ - } \ - return 0; \ - case 8047: \ - switch (ch2) { \ - case 837: return 8111; \ - } \ - return 0; \ - case 8048: \ - switch (ch2) { \ - case 837: return 8114; \ - } \ - return 0; \ - case 8052: \ - switch (ch2) { \ - case 837: return 8130; \ - } \ - return 0; \ - case 8060: \ - switch (ch2) { \ - case 837: return 8178; \ - } \ - return 0; \ - case 8118: \ - switch (ch2) { \ - case 837: return 8119; \ - } \ - return 0; \ - case 8127: \ - switch (ch2) { \ - case 768: return 8141; \ - case 769: return 8142; \ - case 834: return 8143; \ - } \ - return 0; \ - case 8134: \ - switch (ch2) { \ - case 837: return 8135; \ - } \ - return 0; \ - case 8182: \ - switch (ch2) { \ - case 837: return 8183; \ - } \ - return 0; \ - case 8190: \ - switch (ch2) { \ - case 768: return 8157; \ - case 769: return 8158; \ - case 834: return 8159; \ - } \ - return 0; \ - } \ - return 0; \ - case 33: \ - switch (ch1) { \ - case 8592: \ - switch (ch2) { \ - case 824: return 8602; \ - } \ - return 0; \ - case 8594: \ - switch (ch2) { \ - case 824: return 8603; \ - } \ - return 0; \ - case 8596: \ - switch (ch2) { \ - case 824: return 8622; \ - } \ - return 0; \ - case 8656: \ - switch (ch2) { \ - case 824: return 8653; \ - } \ - return 0; \ - case 8658: \ - switch (ch2) { \ - case 824: return 8655; \ - } \ - return 0; \ - case 8660: \ - switch (ch2) { \ - case 824: return 8654; \ - } \ - return 0; \ - } \ - return 0; \ - case 34: \ - switch (ch1) { \ - case 8707: \ - switch (ch2) { \ - case 824: return 8708; \ - } \ - return 0; \ - case 8712: \ - switch (ch2) { \ - case 824: return 8713; \ - } \ - return 0; \ - case 8715: \ - switch (ch2) { \ - case 824: return 8716; \ - } \ - return 0; \ - case 8739: \ - switch (ch2) { \ - case 824: return 8740; \ - } \ - return 0; \ - case 8741: \ - switch (ch2) { \ - case 824: return 8742; \ - } \ - return 0; \ - case 8764: \ - switch (ch2) { \ - case 824: return 8769; \ - } \ - return 0; \ - case 8771: \ - switch (ch2) { \ - case 824: return 8772; \ - } \ - return 0; \ - case 8773: \ - switch (ch2) { \ - case 824: return 8775; \ - } \ - return 0; \ - case 8776: \ - switch (ch2) { \ - case 824: return 8777; \ - } \ - return 0; \ - case 8781: \ - switch (ch2) { \ - case 824: return 8813; \ - } \ - return 0; \ - case 8801: \ - switch (ch2) { \ - case 824: return 8802; \ - } \ - return 0; \ - case 8804: \ - switch (ch2) { \ - case 824: return 8816; \ - } \ - return 0; \ - case 8805: \ - switch (ch2) { \ - case 824: return 8817; \ - } \ - return 0; \ - case 8818: \ - switch (ch2) { \ - case 824: return 8820; \ - } \ - return 0; \ - case 8819: \ - switch (ch2) { \ - case 824: return 8821; \ - } \ - return 0; \ - case 8822: \ - switch (ch2) { \ - case 824: return 8824; \ - } \ - return 0; \ - case 8823: \ - switch (ch2) { \ - case 824: return 8825; \ - } \ - return 0; \ - case 8826: \ - switch (ch2) { \ - case 824: return 8832; \ - } \ - return 0; \ - case 8827: \ - switch (ch2) { \ - case 824: return 8833; \ - } \ - return 0; \ - case 8828: \ - switch (ch2) { \ - case 824: return 8928; \ - } \ - return 0; \ - case 8829: \ - switch (ch2) { \ - case 824: return 8929; \ - } \ - return 0; \ - case 8834: \ - switch (ch2) { \ - case 824: return 8836; \ - } \ - return 0; \ - case 8835: \ - switch (ch2) { \ - case 824: return 8837; \ - } \ - return 0; \ - case 8838: \ - switch (ch2) { \ - case 824: return 8840; \ - } \ - return 0; \ - case 8839: \ - switch (ch2) { \ - case 824: return 8841; \ - } \ - return 0; \ - case 8849: \ - switch (ch2) { \ - case 824: return 8930; \ - } \ - return 0; \ - case 8850: \ - switch (ch2) { \ - case 824: return 8931; \ - } \ - return 0; \ - case 8866: \ - switch (ch2) { \ - case 824: return 8876; \ - } \ - return 0; \ - case 8872: \ - switch (ch2) { \ - case 824: return 8877; \ - } \ - return 0; \ - case 8873: \ - switch (ch2) { \ - case 824: return 8878; \ - } \ - return 0; \ - case 8875: \ - switch (ch2) { \ - case 824: return 8879; \ - } \ - return 0; \ - case 8882: \ - switch (ch2) { \ - case 824: return 8938; \ - } \ - return 0; \ - case 8883: \ - switch (ch2) { \ - case 824: return 8939; \ - } \ - return 0; \ - case 8884: \ - switch (ch2) { \ - case 824: return 8940; \ - } \ - return 0; \ - case 8885: \ - switch (ch2) { \ - case 824: return 8941; \ - } \ - return 0; \ - } \ - return 0; \ - case 42: \ - switch (ch1) { \ - case 10973: \ - switch (ch2) { \ - case 824: return 10972; \ - } \ - return 0; \ - } \ - return 0; \ - case 48: \ - switch (ch1) { \ - case 12358: \ - switch (ch2) { \ - case 12441: return 12436; \ - } \ - return 0; \ - case 12363: \ - switch (ch2) { \ - case 12441: return 12364; \ - } \ - return 0; \ - case 12365: \ - switch (ch2) { \ - case 12441: return 12366; \ - } \ - return 0; \ - case 12367: \ - switch (ch2) { \ - case 12441: return 12368; \ - } \ - return 0; \ - case 12369: \ - switch (ch2) { \ - case 12441: return 12370; \ - } \ - return 0; \ - case 12371: \ - switch (ch2) { \ - case 12441: return 12372; \ - } \ - return 0; \ - case 12373: \ - switch (ch2) { \ - case 12441: return 12374; \ - } \ - return 0; \ - case 12375: \ - switch (ch2) { \ - case 12441: return 12376; \ - } \ - return 0; \ - case 12377: \ - switch (ch2) { \ - case 12441: return 12378; \ - } \ - return 0; \ - case 12379: \ - switch (ch2) { \ - case 12441: return 12380; \ - } \ - return 0; \ - case 12381: \ - switch (ch2) { \ - case 12441: return 12382; \ - } \ - return 0; \ - case 12383: \ - switch (ch2) { \ - case 12441: return 12384; \ - } \ - return 0; \ - case 12385: \ - switch (ch2) { \ - case 12441: return 12386; \ - } \ - return 0; \ - case 12388: \ - switch (ch2) { \ - case 12441: return 12389; \ - } \ - return 0; \ - case 12390: \ - switch (ch2) { \ - case 12441: return 12391; \ - } \ - return 0; \ - case 12392: \ - switch (ch2) { \ - case 12441: return 12393; \ - } \ - return 0; \ - case 12399: \ - switch (ch2) { \ - case 12441: return 12400; \ - case 12442: return 12401; \ - } \ - return 0; \ - case 12402: \ - switch (ch2) { \ - case 12441: return 12403; \ - case 12442: return 12404; \ - } \ - return 0; \ - case 12405: \ - switch (ch2) { \ - case 12441: return 12406; \ - case 12442: return 12407; \ - } \ - return 0; \ - case 12408: \ - switch (ch2) { \ - case 12441: return 12409; \ - case 12442: return 12410; \ - } \ - return 0; \ - case 12411: \ - switch (ch2) { \ - case 12441: return 12412; \ - case 12442: return 12413; \ - } \ - return 0; \ - case 12445: \ - switch (ch2) { \ - case 12441: return 12446; \ - } \ - return 0; \ - case 12454: \ - switch (ch2) { \ - case 12441: return 12532; \ - } \ - return 0; \ - case 12459: \ - switch (ch2) { \ - case 12441: return 12460; \ - } \ - return 0; \ - case 12461: \ - switch (ch2) { \ - case 12441: return 12462; \ - } \ - return 0; \ - case 12463: \ - switch (ch2) { \ - case 12441: return 12464; \ - } \ - return 0; \ - case 12465: \ - switch (ch2) { \ - case 12441: return 12466; \ - } \ - return 0; \ - case 12467: \ - switch (ch2) { \ - case 12441: return 12468; \ - } \ - return 0; \ - case 12469: \ - switch (ch2) { \ - case 12441: return 12470; \ - } \ - return 0; \ - case 12471: \ - switch (ch2) { \ - case 12441: return 12472; \ - } \ - return 0; \ - case 12473: \ - switch (ch2) { \ - case 12441: return 12474; \ - } \ - return 0; \ - case 12475: \ - switch (ch2) { \ - case 12441: return 12476; \ - } \ - return 0; \ - case 12477: \ - switch (ch2) { \ - case 12441: return 12478; \ - } \ - return 0; \ - case 12479: \ - switch (ch2) { \ - case 12441: return 12480; \ - } \ - return 0; \ - case 12481: \ - switch (ch2) { \ - case 12441: return 12482; \ - } \ - return 0; \ - case 12484: \ - switch (ch2) { \ - case 12441: return 12485; \ - } \ - return 0; \ - case 12486: \ - switch (ch2) { \ - case 12441: return 12487; \ - } \ - return 0; \ - case 12488: \ - switch (ch2) { \ - case 12441: return 12489; \ - } \ - return 0; \ - case 12495: \ - switch (ch2) { \ - case 12441: return 12496; \ - case 12442: return 12497; \ - } \ - return 0; \ - case 12498: \ - switch (ch2) { \ - case 12441: return 12499; \ - case 12442: return 12500; \ - } \ - return 0; \ - case 12501: \ - switch (ch2) { \ - case 12441: return 12502; \ - case 12442: return 12503; \ - } \ - return 0; \ - case 12504: \ - switch (ch2) { \ - case 12441: return 12505; \ - case 12442: return 12506; \ - } \ - return 0; \ - case 12507: \ - switch (ch2) { \ - case 12441: return 12508; \ - case 12442: return 12509; \ - } \ - return 0; \ - case 12527: \ - switch (ch2) { \ - case 12441: return 12535; \ - } \ - return 0; \ - case 12528: \ - switch (ch2) { \ - case 12441: return 12536; \ - } \ - return 0; \ - case 12529: \ - switch (ch2) { \ - case 12441: return 12537; \ - } \ - return 0; \ - case 12530: \ - switch (ch2) { \ - case 12441: return 12538; \ - } \ - return 0; \ - case 12541: \ - switch (ch2) { \ - case 12441: return 12542; \ - } \ - return 0; \ - } \ - return 0; \ - case 251: \ - switch (ch1) { \ - case 64329: \ - switch (ch2) { \ - case 1473: return 64300; \ - case 1474: return 64301; \ - } \ - return 0; \ - } \ - return 0; \ - case 465: \ - switch (ch1) { \ - case 119127: \ - switch (ch2) { \ - case 119141: return 119134; \ - } \ - return 0; \ - case 119128: \ - switch (ch2) { \ - case 119141: return 119135; \ - } \ - return 0; \ - case 119135: \ - switch (ch2) { \ - case 119150: return 119136; \ - case 119151: return 119137; \ - case 119152: return 119138; \ - case 119153: return 119139; \ - case 119154: return 119140; \ - } \ - return 0; \ - case 119225: \ - switch (ch2) { \ - case 119141: return 119227; \ - } \ - return 0; \ - case 119226: \ - switch (ch2) { \ - case 119141: return 119228; \ - } \ - return 0; \ - case 119227: \ - switch (ch2) { \ - case 119150: return 119229; \ - case 119151: return 119231; \ - } \ - return 0; \ - case 119228: \ - switch (ch2) { \ - case 119150: return 119230; \ - case 119151: return 119232; \ - } \ - return 0; \ - } \ - return 0; \ -} \ -return 0; - -static glui32 unigen_decomp_data[3247] = { -0x41, 0x300, 0x41, 0x301, 0x41, 0x302, 0x41, 0x303, -0x41, 0x308, 0x41, 0x30a, 0x43, 0x327, 0x45, 0x300, -0x45, 0x301, 0x45, 0x302, 0x45, 0x308, 0x49, 0x300, -0x49, 0x301, 0x49, 0x302, 0x49, 0x308, 0x4e, 0x303, -0x4f, 0x300, 0x4f, 0x301, 0x4f, 0x302, 0x4f, 0x303, -0x4f, 0x308, 0x55, 0x300, 0x55, 0x301, 0x55, 0x302, -0x55, 0x308, 0x59, 0x301, 0x61, 0x300, 0x61, 0x301, -0x61, 0x302, 0x61, 0x303, 0x61, 0x308, 0x61, 0x30a, -0x63, 0x327, 0x65, 0x300, 0x65, 0x301, 0x65, 0x302, -0x65, 0x308, 0x69, 0x300, 0x69, 0x301, 0x69, 0x302, -0x69, 0x308, 0x6e, 0x303, 0x6f, 0x300, 0x6f, 0x301, -0x6f, 0x302, 0x6f, 0x303, 0x6f, 0x308, 0x75, 0x300, -0x75, 0x301, 0x75, 0x302, 0x75, 0x308, 0x79, 0x301, -0x79, 0x308, 0x41, 0x304, 0x61, 0x304, 0x41, 0x306, -0x61, 0x306, 0x41, 0x328, 0x61, 0x328, 0x43, 0x301, -0x63, 0x301, 0x43, 0x302, 0x63, 0x302, 0x43, 0x307, -0x63, 0x307, 0x43, 0x30c, 0x63, 0x30c, 0x44, 0x30c, -0x64, 0x30c, 0x45, 0x304, 0x65, 0x304, 0x45, 0x306, -0x65, 0x306, 0x45, 0x307, 0x65, 0x307, 0x45, 0x328, -0x65, 0x328, 0x45, 0x30c, 0x65, 0x30c, 0x47, 0x302, -0x67, 0x302, 0x47, 0x306, 0x67, 0x306, 0x47, 0x307, -0x67, 0x307, 0x47, 0x327, 0x67, 0x327, 0x48, 0x302, -0x68, 0x302, 0x49, 0x303, 0x69, 0x303, 0x49, 0x304, -0x69, 0x304, 0x49, 0x306, 0x69, 0x306, 0x49, 0x328, -0x69, 0x328, 0x49, 0x307, 0x4a, 0x302, 0x6a, 0x302, -0x4b, 0x327, 0x6b, 0x327, 0x4c, 0x301, 0x6c, 0x301, -0x4c, 0x327, 0x6c, 0x327, 0x4c, 0x30c, 0x6c, 0x30c, -0x4e, 0x301, 0x6e, 0x301, 0x4e, 0x327, 0x6e, 0x327, -0x4e, 0x30c, 0x6e, 0x30c, 0x4f, 0x304, 0x6f, 0x304, -0x4f, 0x306, 0x6f, 0x306, 0x4f, 0x30b, 0x6f, 0x30b, -0x52, 0x301, 0x72, 0x301, 0x52, 0x327, 0x72, 0x327, -0x52, 0x30c, 0x72, 0x30c, 0x53, 0x301, 0x73, 0x301, -0x53, 0x302, 0x73, 0x302, 0x53, 0x327, 0x73, 0x327, -0x53, 0x30c, 0x73, 0x30c, 0x54, 0x327, 0x74, 0x327, -0x54, 0x30c, 0x74, 0x30c, 0x55, 0x303, 0x75, 0x303, -0x55, 0x304, 0x75, 0x304, 0x55, 0x306, 0x75, 0x306, -0x55, 0x30a, 0x75, 0x30a, 0x55, 0x30b, 0x75, 0x30b, -0x55, 0x328, 0x75, 0x328, 0x57, 0x302, 0x77, 0x302, -0x59, 0x302, 0x79, 0x302, 0x59, 0x308, 0x5a, 0x301, -0x7a, 0x301, 0x5a, 0x307, 0x7a, 0x307, 0x5a, 0x30c, -0x7a, 0x30c, 0x4f, 0x31b, 0x6f, 0x31b, 0x55, 0x31b, -0x75, 0x31b, 0x41, 0x30c, 0x61, 0x30c, 0x49, 0x30c, -0x69, 0x30c, 0x4f, 0x30c, 0x6f, 0x30c, 0x55, 0x30c, -0x75, 0x30c, 0x55, 0x308, 0x304, 0x75, 0x308, 0x304, -0x55, 0x308, 0x301, 0x75, 0x308, 0x301, 0x55, 0x308, -0x30c, 0x75, 0x308, 0x30c, 0x55, 0x308, 0x300, 0x75, -0x308, 0x300, 0x41, 0x308, 0x304, 0x61, 0x308, 0x304, -0x41, 0x307, 0x304, 0x61, 0x307, 0x304, 0xc6, 0x304, -0xe6, 0x304, 0x47, 0x30c, 0x67, 0x30c, 0x4b, 0x30c, -0x6b, 0x30c, 0x4f, 0x328, 0x6f, 0x328, 0x4f, 0x328, -0x304, 0x6f, 0x328, 0x304, 0x1b7, 0x30c, 0x292, 0x30c, -0x6a, 0x30c, 0x47, 0x301, 0x67, 0x301, 0x4e, 0x300, -0x6e, 0x300, 0x41, 0x30a, 0x301, 0x61, 0x30a, 0x301, -0xc6, 0x301, 0xe6, 0x301, 0xd8, 0x301, 0xf8, 0x301, -0x41, 0x30f, 0x61, 0x30f, 0x41, 0x311, 0x61, 0x311, -0x45, 0x30f, 0x65, 0x30f, 0x45, 0x311, 0x65, 0x311, -0x49, 0x30f, 0x69, 0x30f, 0x49, 0x311, 0x69, 0x311, -0x4f, 0x30f, 0x6f, 0x30f, 0x4f, 0x311, 0x6f, 0x311, -0x52, 0x30f, 0x72, 0x30f, 0x52, 0x311, 0x72, 0x311, -0x55, 0x30f, 0x75, 0x30f, 0x55, 0x311, 0x75, 0x311, -0x53, 0x326, 0x73, 0x326, 0x54, 0x326, 0x74, 0x326, -0x48, 0x30c, 0x68, 0x30c, 0x41, 0x307, 0x61, 0x307, -0x45, 0x327, 0x65, 0x327, 0x4f, 0x308, 0x304, 0x6f, -0x308, 0x304, 0x4f, 0x303, 0x304, 0x6f, 0x303, 0x304, -0x4f, 0x307, 0x6f, 0x307, 0x4f, 0x307, 0x304, 0x6f, -0x307, 0x304, 0x59, 0x304, 0x79, 0x304, 0x300, 0x301, -0x313, 0x308, 0x301, 0x2b9, 0x3b, 0xa8, 0x301, 0x391, -0x301, 0xb7, 0x395, 0x301, 0x397, 0x301, 0x399, 0x301, -0x39f, 0x301, 0x3a5, 0x301, 0x3a9, 0x301, 0x3b9, 0x308, -0x301, 0x399, 0x308, 0x3a5, 0x308, 0x3b1, 0x301, 0x3b5, -0x301, 0x3b7, 0x301, 0x3b9, 0x301, 0x3c5, 0x308, 0x301, -0x3b9, 0x308, 0x3c5, 0x308, 0x3bf, 0x301, 0x3c5, 0x301, -0x3c9, 0x301, 0x3d2, 0x301, 0x3d2, 0x308, 0x415, 0x300, -0x415, 0x308, 0x413, 0x301, 0x406, 0x308, 0x41a, 0x301, -0x418, 0x300, 0x423, 0x306, 0x418, 0x306, 0x438, 0x306, -0x435, 0x300, 0x435, 0x308, 0x433, 0x301, 0x456, 0x308, -0x43a, 0x301, 0x438, 0x300, 0x443, 0x306, 0x474, 0x30f, -0x475, 0x30f, 0x416, 0x306, 0x436, 0x306, 0x410, 0x306, -0x430, 0x306, 0x410, 0x308, 0x430, 0x308, 0x415, 0x306, -0x435, 0x306, 0x4d8, 0x308, 0x4d9, 0x308, 0x416, 0x308, -0x436, 0x308, 0x417, 0x308, 0x437, 0x308, 0x418, 0x304, -0x438, 0x304, 0x418, 0x308, 0x438, 0x308, 0x41e, 0x308, -0x43e, 0x308, 0x4e8, 0x308, 0x4e9, 0x308, 0x42d, 0x308, -0x44d, 0x308, 0x423, 0x304, 0x443, 0x304, 0x423, 0x308, -0x443, 0x308, 0x423, 0x30b, 0x443, 0x30b, 0x427, 0x308, -0x447, 0x308, 0x42b, 0x308, 0x44b, 0x308, 0x627, 0x653, -0x627, 0x654, 0x648, 0x654, 0x627, 0x655, 0x64a, 0x654, -0x6d5, 0x654, 0x6c1, 0x654, 0x6d2, 0x654, 0x928, 0x93c, -0x930, 0x93c, 0x933, 0x93c, 0x915, 0x93c, 0x916, 0x93c, -0x917, 0x93c, 0x91c, 0x93c, 0x921, 0x93c, 0x922, 0x93c, -0x92b, 0x93c, 0x92f, 0x93c, 0x9c7, 0x9be, 0x9c7, 0x9d7, -0x9a1, 0x9bc, 0x9a2, 0x9bc, 0x9af, 0x9bc, 0xa32, 0xa3c, -0xa38, 0xa3c, 0xa16, 0xa3c, 0xa17, 0xa3c, 0xa1c, 0xa3c, -0xa2b, 0xa3c, 0xb47, 0xb56, 0xb47, 0xb3e, 0xb47, 0xb57, -0xb21, 0xb3c, 0xb22, 0xb3c, 0xb92, 0xbd7, 0xbc6, 0xbbe, -0xbc7, 0xbbe, 0xbc6, 0xbd7, 0xc46, 0xc56, 0xcbf, 0xcd5, -0xcc6, 0xcd5, 0xcc6, 0xcd6, 0xcc6, 0xcc2, 0xcc6, 0xcc2, -0xcd5, 0xd46, 0xd3e, 0xd47, 0xd3e, 0xd46, 0xd57, 0xdd9, -0xdca, 0xdd9, 0xdcf, 0xdd9, 0xdcf, 0xdca, 0xdd9, 0xddf, -0xf42, 0xfb7, 0xf4c, 0xfb7, 0xf51, 0xfb7, 0xf56, 0xfb7, -0xf5b, 0xfb7, 0xf40, 0xfb5, 0xf71, 0xf72, 0xf71, 0xf74, -0xfb2, 0xf80, 0xfb3, 0xf80, 0xf71, 0xf80, 0xf92, 0xfb7, -0xf9c, 0xfb7, 0xfa1, 0xfb7, 0xfa6, 0xfb7, 0xfab, 0xfb7, -0xf90, 0xfb5, 0x1025, 0x102e, 0x41, 0x325, 0x61, 0x325, -0x42, 0x307, 0x62, 0x307, 0x42, 0x323, 0x62, 0x323, -0x42, 0x331, 0x62, 0x331, 0x43, 0x327, 0x301, 0x63, -0x327, 0x301, 0x44, 0x307, 0x64, 0x307, 0x44, 0x323, -0x64, 0x323, 0x44, 0x331, 0x64, 0x331, 0x44, 0x327, -0x64, 0x327, 0x44, 0x32d, 0x64, 0x32d, 0x45, 0x304, -0x300, 0x65, 0x304, 0x300, 0x45, 0x304, 0x301, 0x65, -0x304, 0x301, 0x45, 0x32d, 0x65, 0x32d, 0x45, 0x330, -0x65, 0x330, 0x45, 0x327, 0x306, 0x65, 0x327, 0x306, -0x46, 0x307, 0x66, 0x307, 0x47, 0x304, 0x67, 0x304, -0x48, 0x307, 0x68, 0x307, 0x48, 0x323, 0x68, 0x323, -0x48, 0x308, 0x68, 0x308, 0x48, 0x327, 0x68, 0x327, -0x48, 0x32e, 0x68, 0x32e, 0x49, 0x330, 0x69, 0x330, -0x49, 0x308, 0x301, 0x69, 0x308, 0x301, 0x4b, 0x301, -0x6b, 0x301, 0x4b, 0x323, 0x6b, 0x323, 0x4b, 0x331, -0x6b, 0x331, 0x4c, 0x323, 0x6c, 0x323, 0x4c, 0x323, -0x304, 0x6c, 0x323, 0x304, 0x4c, 0x331, 0x6c, 0x331, -0x4c, 0x32d, 0x6c, 0x32d, 0x4d, 0x301, 0x6d, 0x301, -0x4d, 0x307, 0x6d, 0x307, 0x4d, 0x323, 0x6d, 0x323, -0x4e, 0x307, 0x6e, 0x307, 0x4e, 0x323, 0x6e, 0x323, -0x4e, 0x331, 0x6e, 0x331, 0x4e, 0x32d, 0x6e, 0x32d, -0x4f, 0x303, 0x301, 0x6f, 0x303, 0x301, 0x4f, 0x303, -0x308, 0x6f, 0x303, 0x308, 0x4f, 0x304, 0x300, 0x6f, -0x304, 0x300, 0x4f, 0x304, 0x301, 0x6f, 0x304, 0x301, -0x50, 0x301, 0x70, 0x301, 0x50, 0x307, 0x70, 0x307, -0x52, 0x307, 0x72, 0x307, 0x52, 0x323, 0x72, 0x323, -0x52, 0x323, 0x304, 0x72, 0x323, 0x304, 0x52, 0x331, -0x72, 0x331, 0x53, 0x307, 0x73, 0x307, 0x53, 0x323, -0x73, 0x323, 0x53, 0x301, 0x307, 0x73, 0x301, 0x307, -0x53, 0x30c, 0x307, 0x73, 0x30c, 0x307, 0x53, 0x323, -0x307, 0x73, 0x323, 0x307, 0x54, 0x307, 0x74, 0x307, -0x54, 0x323, 0x74, 0x323, 0x54, 0x331, 0x74, 0x331, -0x54, 0x32d, 0x74, 0x32d, 0x55, 0x324, 0x75, 0x324, -0x55, 0x330, 0x75, 0x330, 0x55, 0x32d, 0x75, 0x32d, -0x55, 0x303, 0x301, 0x75, 0x303, 0x301, 0x55, 0x304, -0x308, 0x75, 0x304, 0x308, 0x56, 0x303, 0x76, 0x303, -0x56, 0x323, 0x76, 0x323, 0x57, 0x300, 0x77, 0x300, -0x57, 0x301, 0x77, 0x301, 0x57, 0x308, 0x77, 0x308, -0x57, 0x307, 0x77, 0x307, 0x57, 0x323, 0x77, 0x323, -0x58, 0x307, 0x78, 0x307, 0x58, 0x308, 0x78, 0x308, -0x59, 0x307, 0x79, 0x307, 0x5a, 0x302, 0x7a, 0x302, -0x5a, 0x323, 0x7a, 0x323, 0x5a, 0x331, 0x7a, 0x331, -0x68, 0x331, 0x74, 0x308, 0x77, 0x30a, 0x79, 0x30a, -0x17f, 0x307, 0x41, 0x323, 0x61, 0x323, 0x41, 0x309, -0x61, 0x309, 0x41, 0x302, 0x301, 0x61, 0x302, 0x301, -0x41, 0x302, 0x300, 0x61, 0x302, 0x300, 0x41, 0x302, -0x309, 0x61, 0x302, 0x309, 0x41, 0x302, 0x303, 0x61, -0x302, 0x303, 0x41, 0x323, 0x302, 0x61, 0x323, 0x302, -0x41, 0x306, 0x301, 0x61, 0x306, 0x301, 0x41, 0x306, -0x300, 0x61, 0x306, 0x300, 0x41, 0x306, 0x309, 0x61, -0x306, 0x309, 0x41, 0x306, 0x303, 0x61, 0x306, 0x303, -0x41, 0x323, 0x306, 0x61, 0x323, 0x306, 0x45, 0x323, -0x65, 0x323, 0x45, 0x309, 0x65, 0x309, 0x45, 0x303, -0x65, 0x303, 0x45, 0x302, 0x301, 0x65, 0x302, 0x301, -0x45, 0x302, 0x300, 0x65, 0x302, 0x300, 0x45, 0x302, -0x309, 0x65, 0x302, 0x309, 0x45, 0x302, 0x303, 0x65, -0x302, 0x303, 0x45, 0x323, 0x302, 0x65, 0x323, 0x302, -0x49, 0x309, 0x69, 0x309, 0x49, 0x323, 0x69, 0x323, -0x4f, 0x323, 0x6f, 0x323, 0x4f, 0x309, 0x6f, 0x309, -0x4f, 0x302, 0x301, 0x6f, 0x302, 0x301, 0x4f, 0x302, -0x300, 0x6f, 0x302, 0x300, 0x4f, 0x302, 0x309, 0x6f, -0x302, 0x309, 0x4f, 0x302, 0x303, 0x6f, 0x302, 0x303, -0x4f, 0x323, 0x302, 0x6f, 0x323, 0x302, 0x4f, 0x31b, -0x301, 0x6f, 0x31b, 0x301, 0x4f, 0x31b, 0x300, 0x6f, -0x31b, 0x300, 0x4f, 0x31b, 0x309, 0x6f, 0x31b, 0x309, -0x4f, 0x31b, 0x303, 0x6f, 0x31b, 0x303, 0x4f, 0x31b, -0x323, 0x6f, 0x31b, 0x323, 0x55, 0x323, 0x75, 0x323, -0x55, 0x309, 0x75, 0x309, 0x55, 0x31b, 0x301, 0x75, -0x31b, 0x301, 0x55, 0x31b, 0x300, 0x75, 0x31b, 0x300, -0x55, 0x31b, 0x309, 0x75, 0x31b, 0x309, 0x55, 0x31b, -0x303, 0x75, 0x31b, 0x303, 0x55, 0x31b, 0x323, 0x75, -0x31b, 0x323, 0x59, 0x300, 0x79, 0x300, 0x59, 0x323, -0x79, 0x323, 0x59, 0x309, 0x79, 0x309, 0x59, 0x303, -0x79, 0x303, 0x3b1, 0x313, 0x3b1, 0x314, 0x3b1, 0x313, -0x300, 0x3b1, 0x314, 0x300, 0x3b1, 0x313, 0x301, 0x3b1, -0x314, 0x301, 0x3b1, 0x313, 0x342, 0x3b1, 0x314, 0x342, -0x391, 0x313, 0x391, 0x314, 0x391, 0x313, 0x300, 0x391, -0x314, 0x300, 0x391, 0x313, 0x301, 0x391, 0x314, 0x301, -0x391, 0x313, 0x342, 0x391, 0x314, 0x342, 0x3b5, 0x313, -0x3b5, 0x314, 0x3b5, 0x313, 0x300, 0x3b5, 0x314, 0x300, -0x3b5, 0x313, 0x301, 0x3b5, 0x314, 0x301, 0x395, 0x313, -0x395, 0x314, 0x395, 0x313, 0x300, 0x395, 0x314, 0x300, -0x395, 0x313, 0x301, 0x395, 0x314, 0x301, 0x3b7, 0x313, -0x3b7, 0x314, 0x3b7, 0x313, 0x300, 0x3b7, 0x314, 0x300, -0x3b7, 0x313, 0x301, 0x3b7, 0x314, 0x301, 0x3b7, 0x313, -0x342, 0x3b7, 0x314, 0x342, 0x397, 0x313, 0x397, 0x314, -0x397, 0x313, 0x300, 0x397, 0x314, 0x300, 0x397, 0x313, -0x301, 0x397, 0x314, 0x301, 0x397, 0x313, 0x342, 0x397, -0x314, 0x342, 0x3b9, 0x313, 0x3b9, 0x314, 0x3b9, 0x313, -0x300, 0x3b9, 0x314, 0x300, 0x3b9, 0x313, 0x301, 0x3b9, -0x314, 0x301, 0x3b9, 0x313, 0x342, 0x3b9, 0x314, 0x342, -0x399, 0x313, 0x399, 0x314, 0x399, 0x313, 0x300, 0x399, -0x314, 0x300, 0x399, 0x313, 0x301, 0x399, 0x314, 0x301, -0x399, 0x313, 0x342, 0x399, 0x314, 0x342, 0x3bf, 0x313, -0x3bf, 0x314, 0x3bf, 0x313, 0x300, 0x3bf, 0x314, 0x300, -0x3bf, 0x313, 0x301, 0x3bf, 0x314, 0x301, 0x39f, 0x313, -0x39f, 0x314, 0x39f, 0x313, 0x300, 0x39f, 0x314, 0x300, -0x39f, 0x313, 0x301, 0x39f, 0x314, 0x301, 0x3c5, 0x313, -0x3c5, 0x314, 0x3c5, 0x313, 0x300, 0x3c5, 0x314, 0x300, -0x3c5, 0x313, 0x301, 0x3c5, 0x314, 0x301, 0x3c5, 0x313, -0x342, 0x3c5, 0x314, 0x342, 0x3a5, 0x314, 0x3a5, 0x314, -0x300, 0x3a5, 0x314, 0x301, 0x3a5, 0x314, 0x342, 0x3c9, -0x313, 0x3c9, 0x314, 0x3c9, 0x313, 0x300, 0x3c9, 0x314, -0x300, 0x3c9, 0x313, 0x301, 0x3c9, 0x314, 0x301, 0x3c9, -0x313, 0x342, 0x3c9, 0x314, 0x342, 0x3a9, 0x313, 0x3a9, -0x314, 0x3a9, 0x313, 0x300, 0x3a9, 0x314, 0x300, 0x3a9, -0x313, 0x301, 0x3a9, 0x314, 0x301, 0x3a9, 0x313, 0x342, -0x3a9, 0x314, 0x342, 0x3b1, 0x300, 0x3b1, 0x301, 0x3b5, -0x300, 0x3b5, 0x301, 0x3b7, 0x300, 0x3b7, 0x301, 0x3b9, -0x300, 0x3b9, 0x301, 0x3bf, 0x300, 0x3bf, 0x301, 0x3c5, -0x300, 0x3c5, 0x301, 0x3c9, 0x300, 0x3c9, 0x301, 0x3b1, -0x313, 0x345, 0x3b1, 0x314, 0x345, 0x3b1, 0x313, 0x300, -0x345, 0x3b1, 0x314, 0x300, 0x345, 0x3b1, 0x313, 0x301, -0x345, 0x3b1, 0x314, 0x301, 0x345, 0x3b1, 0x313, 0x342, -0x345, 0x3b1, 0x314, 0x342, 0x345, 0x391, 0x313, 0x345, -0x391, 0x314, 0x345, 0x391, 0x313, 0x300, 0x345, 0x391, -0x314, 0x300, 0x345, 0x391, 0x313, 0x301, 0x345, 0x391, -0x314, 0x301, 0x345, 0x391, 0x313, 0x342, 0x345, 0x391, -0x314, 0x342, 0x345, 0x3b7, 0x313, 0x345, 0x3b7, 0x314, -0x345, 0x3b7, 0x313, 0x300, 0x345, 0x3b7, 0x314, 0x300, -0x345, 0x3b7, 0x313, 0x301, 0x345, 0x3b7, 0x314, 0x301, -0x345, 0x3b7, 0x313, 0x342, 0x345, 0x3b7, 0x314, 0x342, -0x345, 0x397, 0x313, 0x345, 0x397, 0x314, 0x345, 0x397, -0x313, 0x300, 0x345, 0x397, 0x314, 0x300, 0x345, 0x397, -0x313, 0x301, 0x345, 0x397, 0x314, 0x301, 0x345, 0x397, -0x313, 0x342, 0x345, 0x397, 0x314, 0x342, 0x345, 0x3c9, -0x313, 0x345, 0x3c9, 0x314, 0x345, 0x3c9, 0x313, 0x300, -0x345, 0x3c9, 0x314, 0x300, 0x345, 0x3c9, 0x313, 0x301, -0x345, 0x3c9, 0x314, 0x301, 0x345, 0x3c9, 0x313, 0x342, -0x345, 0x3c9, 0x314, 0x342, 0x345, 0x3a9, 0x313, 0x345, -0x3a9, 0x314, 0x345, 0x3a9, 0x313, 0x300, 0x345, 0x3a9, -0x314, 0x300, 0x345, 0x3a9, 0x313, 0x301, 0x345, 0x3a9, -0x314, 0x301, 0x345, 0x3a9, 0x313, 0x342, 0x345, 0x3a9, -0x314, 0x342, 0x345, 0x3b1, 0x306, 0x3b1, 0x304, 0x3b1, -0x300, 0x345, 0x3b1, 0x345, 0x3b1, 0x301, 0x345, 0x3b1, -0x342, 0x3b1, 0x342, 0x345, 0x391, 0x306, 0x391, 0x304, -0x391, 0x300, 0x391, 0x301, 0x391, 0x345, 0x3b9, 0xa8, -0x342, 0x3b7, 0x300, 0x345, 0x3b7, 0x345, 0x3b7, 0x301, -0x345, 0x3b7, 0x342, 0x3b7, 0x342, 0x345, 0x395, 0x300, -0x395, 0x301, 0x397, 0x300, 0x397, 0x301, 0x397, 0x345, -0x1fbf, 0x300, 0x1fbf, 0x301, 0x1fbf, 0x342, 0x3b9, 0x306, -0x3b9, 0x304, 0x3b9, 0x308, 0x300, 0x3b9, 0x308, 0x301, -0x3b9, 0x342, 0x3b9, 0x308, 0x342, 0x399, 0x306, 0x399, -0x304, 0x399, 0x300, 0x399, 0x301, 0x1ffe, 0x300, 0x1ffe, -0x301, 0x1ffe, 0x342, 0x3c5, 0x306, 0x3c5, 0x304, 0x3c5, -0x308, 0x300, 0x3c5, 0x308, 0x301, 0x3c1, 0x313, 0x3c1, -0x314, 0x3c5, 0x342, 0x3c5, 0x308, 0x342, 0x3a5, 0x306, -0x3a5, 0x304, 0x3a5, 0x300, 0x3a5, 0x301, 0x3a1, 0x314, -0xa8, 0x300, 0xa8, 0x301, 0x60, 0x3c9, 0x300, 0x345, -0x3c9, 0x345, 0x3c9, 0x301, 0x345, 0x3c9, 0x342, 0x3c9, -0x342, 0x345, 0x39f, 0x300, 0x39f, 0x301, 0x3a9, 0x300, -0x3a9, 0x301, 0x3a9, 0x345, 0xb4, 0x2002, 0x2003, 0x3a9, -0x4b, 0x41, 0x30a, 0x2190, 0x338, 0x2192, 0x338, 0x2194, -0x338, 0x21d0, 0x338, 0x21d4, 0x338, 0x21d2, 0x338, 0x2203, -0x338, 0x2208, 0x338, 0x220b, 0x338, 0x2223, 0x338, 0x2225, -0x338, 0x223c, 0x338, 0x2243, 0x338, 0x2245, 0x338, 0x2248, -0x338, 0x3d, 0x338, 0x2261, 0x338, 0x224d, 0x338, 0x3c, -0x338, 0x3e, 0x338, 0x2264, 0x338, 0x2265, 0x338, 0x2272, -0x338, 0x2273, 0x338, 0x2276, 0x338, 0x2277, 0x338, 0x227a, -0x338, 0x227b, 0x338, 0x2282, 0x338, 0x2283, 0x338, 0x2286, -0x338, 0x2287, 0x338, 0x22a2, 0x338, 0x22a8, 0x338, 0x22a9, -0x338, 0x22ab, 0x338, 0x227c, 0x338, 0x227d, 0x338, 0x2291, -0x338, 0x2292, 0x338, 0x22b2, 0x338, 0x22b3, 0x338, 0x22b4, -0x338, 0x22b5, 0x338, 0x3008, 0x3009, 0x2add, 0x338, 0x304b, -0x3099, 0x304d, 0x3099, 0x304f, 0x3099, 0x3051, 0x3099, 0x3053, -0x3099, 0x3055, 0x3099, 0x3057, 0x3099, 0x3059, 0x3099, 0x305b, -0x3099, 0x305d, 0x3099, 0x305f, 0x3099, 0x3061, 0x3099, 0x3064, -0x3099, 0x3066, 0x3099, 0x3068, 0x3099, 0x306f, 0x3099, 0x306f, -0x309a, 0x3072, 0x3099, 0x3072, 0x309a, 0x3075, 0x3099, 0x3075, -0x309a, 0x3078, 0x3099, 0x3078, 0x309a, 0x307b, 0x3099, 0x307b, -0x309a, 0x3046, 0x3099, 0x309d, 0x3099, 0x30ab, 0x3099, 0x30ad, -0x3099, 0x30af, 0x3099, 0x30b1, 0x3099, 0x30b3, 0x3099, 0x30b5, -0x3099, 0x30b7, 0x3099, 0x30b9, 0x3099, 0x30bb, 0x3099, 0x30bd, -0x3099, 0x30bf, 0x3099, 0x30c1, 0x3099, 0x30c4, 0x3099, 0x30c6, -0x3099, 0x30c8, 0x3099, 0x30cf, 0x3099, 0x30cf, 0x309a, 0x30d2, -0x3099, 0x30d2, 0x309a, 0x30d5, 0x3099, 0x30d5, 0x309a, 0x30d8, -0x3099, 0x30d8, 0x309a, 0x30db, 0x3099, 0x30db, 0x309a, 0x30a6, -0x3099, 0x30ef, 0x3099, 0x30f0, 0x3099, 0x30f1, 0x3099, 0x30f2, -0x3099, 0x30fd, 0x3099, 0x8c48, 0x66f4, 0x8eca, 0x8cc8, 0x6ed1, -0x4e32, 0x53e5, 0x9f9c, 0x9f9c, 0x5951, 0x91d1, 0x5587, 0x5948, -0x61f6, 0x7669, 0x7f85, 0x863f, 0x87ba, 0x88f8, 0x908f, 0x6a02, -0x6d1b, 0x70d9, 0x73de, 0x843d, 0x916a, 0x99f1, 0x4e82, 0x5375, -0x6b04, 0x721b, 0x862d, 0x9e1e, 0x5d50, 0x6feb, 0x85cd, 0x8964, -0x62c9, 0x81d8, 0x881f, 0x5eca, 0x6717, 0x6d6a, 0x72fc, 0x90ce, -0x4f86, 0x51b7, 0x52de, 0x64c4, 0x6ad3, 0x7210, 0x76e7, 0x8001, -0x8606, 0x865c, 0x8def, 0x9732, 0x9b6f, 0x9dfa, 0x788c, 0x797f, -0x7da0, 0x83c9, 0x9304, 0x9e7f, 0x8ad6, 0x58df, 0x5f04, 0x7c60, -0x807e, 0x7262, 0x78ca, 0x8cc2, 0x96f7, 0x58d8, 0x5c62, 0x6a13, -0x6dda, 0x6f0f, 0x7d2f, 0x7e37, 0x964b, 0x52d2, 0x808b, 0x51dc, -0x51cc, 0x7a1c, 0x7dbe, 0x83f1, 0x9675, 0x8b80, 0x62cf, 0x6a02, -0x8afe, 0x4e39, 0x5be7, 0x6012, 0x7387, 0x7570, 0x5317, 0x78fb, -0x4fbf, 0x5fa9, 0x4e0d, 0x6ccc, 0x6578, 0x7d22, 0x53c3, 0x585e, -0x7701, 0x8449, 0x8aaa, 0x6bba, 0x8fb0, 0x6c88, 0x62fe, 0x82e5, -0x63a0, 0x7565, 0x4eae, 0x5169, 0x51c9, 0x6881, 0x7ce7, 0x826f, -0x8ad2, 0x91cf, 0x52f5, 0x5442, 0x5973, 0x5eec, 0x65c5, 0x6ffe, -0x792a, 0x95ad, 0x9a6a, 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77, -0x8f62, 0x5e74, 0x6190, 0x6200, 0x649a, 0x6f23, 0x7149, 0x7489, -0x79ca, 0x7df4, 0x806f, 0x8f26, 0x84ee, 0x9023, 0x934a, 0x5217, -0x52a3, 0x54bd, 0x70c8, 0x88c2, 0x8aaa, 0x5ec9, 0x5ff5, 0x637b, -0x6bae, 0x7c3e, 0x7375, 0x4ee4, 0x56f9, 0x5be7, 0x5dba, 0x601c, -0x73b2, 0x7469, 0x7f9a, 0x8046, 0x9234, 0x96f6, 0x9748, 0x9818, -0x4f8b, 0x79ae, 0x91b4, 0x96b8, 0x60e1, 0x4e86, 0x50da, 0x5bee, -0x5c3f, 0x6599, 0x6a02, 0x71ce, 0x7642, 0x84fc, 0x907c, 0x9f8d, -0x6688, 0x962e, 0x5289, 0x677b, 0x67f3, 0x6d41, 0x6e9c, 0x7409, -0x7559, 0x786b, 0x7d10, 0x985e, 0x516d, 0x622e, 0x9678, 0x502b, -0x5d19, 0x6dea, 0x8f2a, 0x5f8b, 0x6144, 0x6817, 0x7387, 0x9686, -0x5229, 0x540f, 0x5c65, 0x6613, 0x674e, 0x68a8, 0x6ce5, 0x7406, -0x75e2, 0x7f79, 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x533f, 0x6eba, -0x541d, 0x71d0, 0x7498, 0x85fa, 0x96a3, 0x9c57, 0x9e9f, 0x6797, -0x6dcb, 0x81e8, 0x7acb, 0x7b20, 0x7c92, 0x72c0, 0x7099, 0x8b58, -0x4ec0, 0x8336, 0x523a, 0x5207, 0x5ea6, 0x62d3, 0x7cd6, 0x5b85, -0x6d1e, 0x66b4, 0x8f3b, 0x884c, 0x964d, 0x898b, 0x5ed3, 0x5140, -0x55c0, 0x585a, 0x6674, 0x51de, 0x732a, 0x76ca, 0x793c, 0x795e, -0x7965, 0x798f, 0x9756, 0x7cbe, 0x7fbd, 0x8612, 0x8af8, 0x9038, -0x90fd, 0x98ef, 0x98fc, 0x9928, 0x9db4, 0x4fae, 0x50e7, 0x514d, -0x52c9, 0x52e4, 0x5351, 0x559d, 0x5606, 0x5668, 0x5840, 0x58a8, -0x5c64, 0x5c6e, 0x6094, 0x6168, 0x618e, 0x61f2, 0x654f, 0x65e2, -0x6691, 0x6885, 0x6d77, 0x6e1a, 0x6f22, 0x716e, 0x722b, 0x7422, -0x7891, 0x793e, 0x7949, 0x7948, 0x7950, 0x7956, 0x795d, 0x798d, -0x798e, 0x7a40, 0x7a81, 0x7bc0, 0x7df4, 0x7e09, 0x7e41, 0x7f72, -0x8005, 0x81ed, 0x8279, 0x8279, 0x8457, 0x8910, 0x8996, 0x8b01, -0x8b39, 0x8cd3, 0x8d08, 0x8fb6, 0x9038, 0x96e3, 0x97ff, 0x983b, -0x5d9, 0x5b4, 0x5f2, 0x5b7, 0x5e9, 0x5c1, 0x5e9, 0x5c2, -0x5e9, 0x5bc, 0x5c1, 0x5e9, 0x5bc, 0x5c2, 0x5d0, 0x5b7, -0x5d0, 0x5b8, 0x5d0, 0x5bc, 0x5d1, 0x5bc, 0x5d2, 0x5bc, -0x5d3, 0x5bc, 0x5d4, 0x5bc, 0x5d5, 0x5bc, 0x5d6, 0x5bc, -0x5d8, 0x5bc, 0x5d9, 0x5bc, 0x5da, 0x5bc, 0x5db, 0x5bc, -0x5dc, 0x5bc, 0x5de, 0x5bc, 0x5e0, 0x5bc, 0x5e1, 0x5bc, -0x5e3, 0x5bc, 0x5e4, 0x5bc, 0x5e6, 0x5bc, 0x5e7, 0x5bc, -0x5e8, 0x5bc, 0x5e9, 0x5bc, 0x5ea, 0x5bc, 0x5d5, 0x5b9, -0x5d1, 0x5bf, 0x5db, 0x5bf, 0x5e4, 0x5bf, 0x1d157, 0x1d165, -0x1d158, 0x1d165, 0x1d158, 0x1d165, 0x1d16e, 0x1d158, 0x1d165, 0x1d16f, -0x1d158, 0x1d165, 0x1d170, 0x1d158, 0x1d165, 0x1d171, 0x1d158, 0x1d165, -0x1d172, 0x1d1b9, 0x1d165, 0x1d1ba, 0x1d165, 0x1d1b9, 0x1d165, 0x1d16e, -0x1d1ba, 0x1d165, 0x1d16e, 0x1d1b9, 0x1d165, 0x1d16f, 0x1d1ba, 0x1d165, -0x1d16f, 0x4e3d, 0x4e38, 0x4e41, 0x20122, 0x4f60, 0x4fae, 0x4fbb, -0x5002, 0x507a, 0x5099, 0x50e7, 0x50cf, 0x349e, 0x2063a, 0x514d, -0x5154, 0x5164, 0x5177, 0x2051c, 0x34b9, 0x5167, 0x518d, 0x2054b, -0x5197, 0x51a4, 0x4ecc, 0x51ac, 0x51b5, 0x291df, 0x51f5, 0x5203, -0x34df, 0x523b, 0x5246, 0x5272, 0x5277, 0x3515, 0x52c7, 0x52c9, -0x52e4, 0x52fa, 0x5305, 0x5306, 0x5317, 0x5349, 0x5351, 0x535a, -0x5373, 0x537d, 0x537f, 0x537f, 0x537f, 0x20a2c, 0x7070, 0x53ca, -0x53df, 0x20b63, 0x53eb, 0x53f1, 0x5406, 0x549e, 0x5438, 0x5448, -0x5468, 0x54a2, 0x54f6, 0x5510, 0x5553, 0x5563, 0x5584, 0x5584, -0x5599, 0x55ab, 0x55b3, 0x55c2, 0x5716, 0x5606, 0x5717, 0x5651, -0x5674, 0x5207, 0x58ee, 0x57ce, 0x57f4, 0x580d, 0x578b, 0x5832, -0x5831, 0x58ac, 0x214e4, 0x58f2, 0x58f7, 0x5906, 0x591a, 0x5922, -0x5962, 0x216a8, 0x216ea, 0x59ec, 0x5a1b, 0x5a27, 0x59d8, 0x5a66, -0x36ee, 0x36fc, 0x5b08, 0x5b3e, 0x5b3e, 0x219c8, 0x5bc3, 0x5bd8, -0x5be7, 0x5bf3, 0x21b18, 0x5bff, 0x5c06, 0x5f53, 0x5c22, 0x3781, -0x5c60, 0x5c6e, 0x5cc0, 0x5c8d, 0x21de4, 0x5d43, 0x21de6, 0x5d6e, -0x5d6b, 0x5d7c, 0x5de1, 0x5de2, 0x382f, 0x5dfd, 0x5e28, 0x5e3d, -0x5e69, 0x3862, 0x22183, 0x387c, 0x5eb0, 0x5eb3, 0x5eb6, 0x5eca, -0x2a392, 0x5efe, 0x22331, 0x22331, 0x8201, 0x5f22, 0x5f22, 0x38c7, -0x232b8, 0x261da, 0x5f62, 0x5f6b, 0x38e3, 0x5f9a, 0x5fcd, 0x5fd7, -0x5ff9, 0x6081, 0x393a, 0x391c, 0x6094, 0x226d4, 0x60c7, 0x6148, -0x614c, 0x614e, 0x614c, 0x617a, 0x618e, 0x61b2, 0x61a4, 0x61af, -0x61de, 0x61f2, 0x61f6, 0x6210, 0x621b, 0x625d, 0x62b1, 0x62d4, -0x6350, 0x22b0c, 0x633d, 0x62fc, 0x6368, 0x6383, 0x63e4, 0x22bf1, -0x6422, 0x63c5, 0x63a9, 0x3a2e, 0x6469, 0x647e, 0x649d, 0x6477, -0x3a6c, 0x654f, 0x656c, 0x2300a, 0x65e3, 0x66f8, 0x6649, 0x3b19, -0x6691, 0x3b08, 0x3ae4, 0x5192, 0x5195, 0x6700, 0x669c, 0x80ad, -0x43d9, 0x6717, 0x671b, 0x6721, 0x675e, 0x6753, 0x233c3, 0x3b49, -0x67fa, 0x6785, 0x6852, 0x6885, 0x2346d, 0x688e, 0x681f, 0x6914, -0x3b9d, 0x6942, 0x69a3, 0x69ea, 0x6aa8, 0x236a3, 0x6adb, 0x3c18, -0x6b21, 0x238a7, 0x6b54, 0x3c4e, 0x6b72, 0x6b9f, 0x6bba, 0x6bbb, -0x23a8d, 0x21d0b, 0x23afa, 0x6c4e, 0x23cbc, 0x6cbf, 0x6ccd, 0x6c67, -0x6d16, 0x6d3e, 0x6d77, 0x6d41, 0x6d69, 0x6d78, 0x6d85, 0x23d1e, -0x6d34, 0x6e2f, 0x6e6e, 0x3d33, 0x6ecb, 0x6ec7, 0x23ed1, 0x6df9, -0x6f6e, 0x23f5e, 0x23f8e, 0x6fc6, 0x7039, 0x701e, 0x701b, 0x3d96, -0x704a, 0x707d, 0x7077, 0x70ad, 0x20525, 0x7145, 0x24263, 0x719c, -0x243ab, 0x7228, 0x7235, 0x7250, 0x24608, 0x7280, 0x7295, 0x24735, -0x24814, 0x737a, 0x738b, 0x3eac, 0x73a5, 0x3eb8, 0x3eb8, 0x7447, -0x745c, 0x7471, 0x7485, 0x74ca, 0x3f1b, 0x7524, 0x24c36, 0x753e, -0x24c92, 0x7570, 0x2219f, 0x7610, 0x24fa1, 0x24fb8, 0x25044, 0x3ffc, -0x4008, 0x76f4, 0x250f3, 0x250f2, 0x25119, 0x25133, 0x771e, 0x771f, -0x771f, 0x774a, 0x4039, 0x778b, 0x4046, 0x4096, 0x2541d, 0x784e, -0x788c, 0x78cc, 0x40e3, 0x25626, 0x7956, 0x2569a, 0x256c5, 0x798f, -0x79eb, 0x412f, 0x7a40, 0x7a4a, 0x7a4f, 0x2597c, 0x25aa7, 0x25aa7, -0x7aee, 0x4202, 0x25bab, 0x7bc6, 0x7bc9, 0x4227, 0x25c80, 0x7cd2, -0x42a0, 0x7ce8, 0x7ce3, 0x7d00, 0x25f86, 0x7d63, 0x4301, 0x7dc7, -0x7e02, 0x7e45, 0x4334, 0x26228, 0x26247, 0x4359, 0x262d9, 0x7f7a, -0x2633e, 0x7f95, 0x7ffa, 0x8005, 0x264da, 0x26523, 0x8060, 0x265a8, -0x8070, 0x2335f, 0x43d5, 0x80b2, 0x8103, 0x440b, 0x813e, 0x5ab5, -0x267a7, 0x267b5, 0x23393, 0x2339c, 0x8201, 0x8204, 0x8f9e, 0x446b, -0x8291, 0x828b, 0x829d, 0x52b3, 0x82b1, 0x82b3, 0x82bd, 0x82e6, -0x26b3c, 0x82e5, 0x831d, 0x8363, 0x83ad, 0x8323, 0x83bd, 0x83e7, -0x8457, 0x8353, 0x83ca, 0x83cc, 0x83dc, 0x26c36, 0x26d6b, 0x26cd5, -0x452b, 0x84f1, 0x84f3, 0x8516, 0x273ca, 0x8564, 0x26f2c, 0x455d, -0x4561, 0x26fb1, 0x270d2, 0x456b, 0x8650, 0x865c, 0x8667, 0x8669, -0x86a9, 0x8688, 0x870e, 0x86e2, 0x8779, 0x8728, 0x876b, 0x8786, -0x45d7, 0x87e1, 0x8801, 0x45f9, 0x8860, 0x8863, 0x27667, 0x88d7, -0x88de, 0x4635, 0x88fa, 0x34bb, 0x278ae, 0x27966, 0x46be, 0x46c7, -0x8aa0, 0x8aed, 0x8b8a, 0x8c55, 0x27ca8, 0x8cab, 0x8cc1, 0x8d1b, -0x8d77, 0x27f2f, 0x20804, 0x8dcb, 0x8dbc, 0x8df0, 0x208de, 0x8ed4, -0x8f38, 0x285d2, 0x285ed, 0x9094, 0x90f1, 0x9111, 0x2872e, 0x911b, -0x9238, 0x92d7, 0x92d8, 0x927c, 0x93f9, 0x9415, 0x28bfa, 0x958b, -0x4995, 0x95b7, 0x28d77, 0x49e6, 0x96c3, 0x5db2, 0x9723, 0x29145, -0x2921a, 0x4a6e, 0x4a76, 0x97e0, 0x2940a, 0x4ab2, 0x29496, 0x980b, -0x980b, 0x9829, 0x295b6, 0x98e2, 0x4b33, 0x9929, 0x99a7, 0x99c2, -0x99fe, 0x4bce, 0x29b30, 0x9b12, 0x9c40, 0x9cfd, 0x4cce, 0x4ced, -0x9d67, 0x2a0ce, 0x4cf8, 0x2a105, 0x2a20e, 0x2a291, 0x9ebb, 0x4d56, -0x9ef9, 0x9efe, 0x9f05, 0x9f0f, 0x9f16, 0x9f3b, 0x2a600, }; - -static gli_decomp_block_t unigen_decomp_block_0x0[256] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 0 }, - { 2, 2 }, - { 2, 4 }, - { 2, 6 }, - { 2, 8 }, - { 2, 10 }, - { 0, 0 }, - { 2, 12 }, - { 2, 14 }, - { 2, 16 }, - { 2, 18 }, - { 2, 20 }, - { 2, 22 }, - { 2, 24 }, - { 2, 26 }, - { 2, 28 }, - { 0, 0 }, - { 2, 30 }, - { 2, 32 }, - { 2, 34 }, - { 2, 36 }, - { 2, 38 }, - { 2, 40 }, - { 0, 0 }, - { 0, 0 }, - { 2, 42 }, - { 2, 44 }, - { 2, 46 }, - { 2, 48 }, - { 2, 50 }, - { 0, 0 }, - { 0, 0 }, - { 2, 52 }, - { 2, 54 }, - { 2, 56 }, - { 2, 58 }, - { 2, 60 }, - { 2, 62 }, - { 0, 0 }, - { 2, 64 }, - { 2, 66 }, - { 2, 68 }, - { 2, 70 }, - { 2, 72 }, - { 2, 74 }, - { 2, 76 }, - { 2, 78 }, - { 2, 80 }, - { 0, 0 }, - { 2, 82 }, - { 2, 84 }, - { 2, 86 }, - { 2, 88 }, - { 2, 90 }, - { 2, 92 }, - { 0, 0 }, - { 0, 0 }, - { 2, 94 }, - { 2, 96 }, - { 2, 98 }, - { 2, 100 }, - { 2, 102 }, - { 0, 0 }, - { 2, 104 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x1[256] = { - { 2, 106 }, - { 2, 108 }, - { 2, 110 }, - { 2, 112 }, - { 2, 114 }, - { 2, 116 }, - { 2, 118 }, - { 2, 120 }, - { 2, 122 }, - { 2, 124 }, - { 2, 126 }, - { 2, 128 }, - { 2, 130 }, - { 2, 132 }, - { 2, 134 }, - { 2, 136 }, - { 0, 0 }, - { 0, 0 }, - { 2, 138 }, - { 2, 140 }, - { 2, 142 }, - { 2, 144 }, - { 2, 146 }, - { 2, 148 }, - { 2, 150 }, - { 2, 152 }, - { 2, 154 }, - { 2, 156 }, - { 2, 158 }, - { 2, 160 }, - { 2, 162 }, - { 2, 164 }, - { 2, 166 }, - { 2, 168 }, - { 2, 170 }, - { 2, 172 }, - { 2, 174 }, - { 2, 176 }, - { 0, 0 }, - { 0, 0 }, - { 2, 178 }, - { 2, 180 }, - { 2, 182 }, - { 2, 184 }, - { 2, 186 }, - { 2, 188 }, - { 2, 190 }, - { 2, 192 }, - { 2, 194 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 196 }, - { 2, 198 }, - { 2, 200 }, - { 2, 202 }, - { 0, 0 }, - { 2, 204 }, - { 2, 206 }, - { 2, 208 }, - { 2, 210 }, - { 2, 212 }, - { 2, 214 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 216 }, - { 2, 218 }, - { 2, 220 }, - { 2, 222 }, - { 2, 224 }, - { 2, 226 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 228 }, - { 2, 230 }, - { 2, 232 }, - { 2, 234 }, - { 2, 236 }, - { 2, 238 }, - { 0, 0 }, - { 0, 0 }, - { 2, 240 }, - { 2, 242 }, - { 2, 244 }, - { 2, 246 }, - { 2, 248 }, - { 2, 250 }, - { 2, 252 }, - { 2, 254 }, - { 2, 256 }, - { 2, 258 }, - { 2, 260 }, - { 2, 262 }, - { 2, 264 }, - { 2, 266 }, - { 2, 268 }, - { 2, 270 }, - { 2, 272 }, - { 2, 274 }, - { 0, 0 }, - { 0, 0 }, - { 2, 276 }, - { 2, 278 }, - { 2, 280 }, - { 2, 282 }, - { 2, 284 }, - { 2, 286 }, - { 2, 288 }, - { 2, 290 }, - { 2, 292 }, - { 2, 294 }, - { 2, 296 }, - { 2, 298 }, - { 2, 300 }, - { 2, 302 }, - { 2, 304 }, - { 2, 306 }, - { 2, 308 }, - { 2, 310 }, - { 2, 312 }, - { 2, 314 }, - { 2, 316 }, - { 2, 318 }, - { 2, 320 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 322 }, - { 2, 324 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 326 }, - { 2, 328 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 330 }, - { 2, 332 }, - { 2, 334 }, - { 2, 336 }, - { 2, 338 }, - { 2, 340 }, - { 2, 342 }, - { 2, 344 }, - { 3, 346 }, - { 3, 349 }, - { 3, 352 }, - { 3, 355 }, - { 3, 358 }, - { 3, 361 }, - { 3, 364 }, - { 3, 367 }, - { 0, 0 }, - { 3, 370 }, - { 3, 373 }, - { 3, 376 }, - { 3, 379 }, - { 2, 382 }, - { 2, 384 }, - { 0, 0 }, - { 0, 0 }, - { 2, 386 }, - { 2, 388 }, - { 2, 390 }, - { 2, 392 }, - { 2, 394 }, - { 2, 396 }, - { 3, 398 }, - { 3, 401 }, - { 2, 404 }, - { 2, 406 }, - { 2, 408 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 410 }, - { 2, 412 }, - { 0, 0 }, - { 0, 0 }, - { 2, 414 }, - { 2, 416 }, - { 3, 418 }, - { 3, 421 }, - { 2, 424 }, - { 2, 426 }, - { 2, 428 }, - { 2, 430 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x2[256] = { - { 2, 432 }, - { 2, 434 }, - { 2, 436 }, - { 2, 438 }, - { 2, 440 }, - { 2, 442 }, - { 2, 444 }, - { 2, 446 }, - { 2, 448 }, - { 2, 450 }, - { 2, 452 }, - { 2, 454 }, - { 2, 456 }, - { 2, 458 }, - { 2, 460 }, - { 2, 462 }, - { 2, 464 }, - { 2, 466 }, - { 2, 468 }, - { 2, 470 }, - { 2, 472 }, - { 2, 474 }, - { 2, 476 }, - { 2, 478 }, - { 2, 480 }, - { 2, 482 }, - { 2, 484 }, - { 2, 486 }, - { 0, 0 }, - { 0, 0 }, - { 2, 488 }, - { 2, 490 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 492 }, - { 2, 494 }, - { 2, 496 }, - { 2, 498 }, - { 3, 500 }, - { 3, 503 }, - { 3, 506 }, - { 3, 509 }, - { 2, 512 }, - { 2, 514 }, - { 3, 516 }, - { 3, 519 }, - { 2, 522 }, - { 2, 524 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x3[256] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 1, 526 }, - { 1, 527 }, - { 0, 0 }, - { 1, 528 }, - { 2, 529 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 1, 531 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 1, 532 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 533 }, - { 2, 535 }, - { 1, 537 }, - { 2, 538 }, - { 2, 540 }, - { 2, 542 }, - { 0, 0 }, - { 2, 544 }, - { 0, 0 }, - { 2, 546 }, - { 2, 548 }, - { 3, 550 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 553 }, - { 2, 555 }, - { 2, 557 }, - { 2, 559 }, - { 2, 561 }, - { 2, 563 }, - { 3, 565 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 568 }, - { 2, 570 }, - { 2, 572 }, - { 2, 574 }, - { 2, 576 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 578 }, - { 2, 580 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x4[256] = { - { 2, 582 }, - { 2, 584 }, - { 0, 0 }, - { 2, 586 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 588 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 590 }, - { 2, 592 }, - { 2, 594 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 596 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 598 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 600 }, - { 2, 602 }, - { 0, 0 }, - { 2, 604 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 606 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 608 }, - { 2, 610 }, - { 2, 612 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 614 }, - { 2, 616 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 618 }, - { 2, 620 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 622 }, - { 2, 624 }, - { 2, 626 }, - { 2, 628 }, - { 0, 0 }, - { 0, 0 }, - { 2, 630 }, - { 2, 632 }, - { 0, 0 }, - { 0, 0 }, - { 2, 634 }, - { 2, 636 }, - { 2, 638 }, - { 2, 640 }, - { 2, 642 }, - { 2, 644 }, - { 0, 0 }, - { 0, 0 }, - { 2, 646 }, - { 2, 648 }, - { 2, 650 }, - { 2, 652 }, - { 2, 654 }, - { 2, 656 }, - { 0, 0 }, - { 0, 0 }, - { 2, 658 }, - { 2, 660 }, - { 2, 662 }, - { 2, 664 }, - { 2, 666 }, - { 2, 668 }, - { 2, 670 }, - { 2, 672 }, - { 2, 674 }, - { 2, 676 }, - { 2, 678 }, - { 2, 680 }, - { 0, 0 }, - { 0, 0 }, - { 2, 682 }, - { 2, 684 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x1e[256] = { - { 2, 828 }, - { 2, 830 }, - { 2, 832 }, - { 2, 834 }, - { 2, 836 }, - { 2, 838 }, - { 2, 840 }, - { 2, 842 }, - { 3, 844 }, - { 3, 847 }, - { 2, 850 }, - { 2, 852 }, - { 2, 854 }, - { 2, 856 }, - { 2, 858 }, - { 2, 860 }, - { 2, 862 }, - { 2, 864 }, - { 2, 866 }, - { 2, 868 }, - { 3, 870 }, - { 3, 873 }, - { 3, 876 }, - { 3, 879 }, - { 2, 882 }, - { 2, 884 }, - { 2, 886 }, - { 2, 888 }, - { 3, 890 }, - { 3, 893 }, - { 2, 896 }, - { 2, 898 }, - { 2, 900 }, - { 2, 902 }, - { 2, 904 }, - { 2, 906 }, - { 2, 908 }, - { 2, 910 }, - { 2, 912 }, - { 2, 914 }, - { 2, 916 }, - { 2, 918 }, - { 2, 920 }, - { 2, 922 }, - { 2, 924 }, - { 2, 926 }, - { 3, 928 }, - { 3, 931 }, - { 2, 934 }, - { 2, 936 }, - { 2, 938 }, - { 2, 940 }, - { 2, 942 }, - { 2, 944 }, - { 2, 946 }, - { 2, 948 }, - { 3, 950 }, - { 3, 953 }, - { 2, 956 }, - { 2, 958 }, - { 2, 960 }, - { 2, 962 }, - { 2, 964 }, - { 2, 966 }, - { 2, 968 }, - { 2, 970 }, - { 2, 972 }, - { 2, 974 }, - { 2, 976 }, - { 2, 978 }, - { 2, 980 }, - { 2, 982 }, - { 2, 984 }, - { 2, 986 }, - { 2, 988 }, - { 2, 990 }, - { 3, 992 }, - { 3, 995 }, - { 3, 998 }, - { 3, 1001 }, - { 3, 1004 }, - { 3, 1007 }, - { 3, 1010 }, - { 3, 1013 }, - { 2, 1016 }, - { 2, 1018 }, - { 2, 1020 }, - { 2, 1022 }, - { 2, 1024 }, - { 2, 1026 }, - { 2, 1028 }, - { 2, 1030 }, - { 3, 1032 }, - { 3, 1035 }, - { 2, 1038 }, - { 2, 1040 }, - { 2, 1042 }, - { 2, 1044 }, - { 2, 1046 }, - { 2, 1048 }, - { 3, 1050 }, - { 3, 1053 }, - { 3, 1056 }, - { 3, 1059 }, - { 3, 1062 }, - { 3, 1065 }, - { 2, 1068 }, - { 2, 1070 }, - { 2, 1072 }, - { 2, 1074 }, - { 2, 1076 }, - { 2, 1078 }, - { 2, 1080 }, - { 2, 1082 }, - { 2, 1084 }, - { 2, 1086 }, - { 2, 1088 }, - { 2, 1090 }, - { 2, 1092 }, - { 2, 1094 }, - { 3, 1096 }, - { 3, 1099 }, - { 3, 1102 }, - { 3, 1105 }, - { 2, 1108 }, - { 2, 1110 }, - { 2, 1112 }, - { 2, 1114 }, - { 2, 1116 }, - { 2, 1118 }, - { 2, 1120 }, - { 2, 1122 }, - { 2, 1124 }, - { 2, 1126 }, - { 2, 1128 }, - { 2, 1130 }, - { 2, 1132 }, - { 2, 1134 }, - { 2, 1136 }, - { 2, 1138 }, - { 2, 1140 }, - { 2, 1142 }, - { 2, 1144 }, - { 2, 1146 }, - { 2, 1148 }, - { 2, 1150 }, - { 2, 1152 }, - { 2, 1154 }, - { 2, 1156 }, - { 2, 1158 }, - { 2, 1160 }, - { 2, 1162 }, - { 2, 1164 }, - { 2, 1166 }, - { 0, 0 }, - { 2, 1168 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1170 }, - { 2, 1172 }, - { 2, 1174 }, - { 2, 1176 }, - { 3, 1178 }, - { 3, 1181 }, - { 3, 1184 }, - { 3, 1187 }, - { 3, 1190 }, - { 3, 1193 }, - { 3, 1196 }, - { 3, 1199 }, - { 3, 1202 }, - { 3, 1205 }, - { 3, 1208 }, - { 3, 1211 }, - { 3, 1214 }, - { 3, 1217 }, - { 3, 1220 }, - { 3, 1223 }, - { 3, 1226 }, - { 3, 1229 }, - { 3, 1232 }, - { 3, 1235 }, - { 2, 1238 }, - { 2, 1240 }, - { 2, 1242 }, - { 2, 1244 }, - { 2, 1246 }, - { 2, 1248 }, - { 3, 1250 }, - { 3, 1253 }, - { 3, 1256 }, - { 3, 1259 }, - { 3, 1262 }, - { 3, 1265 }, - { 3, 1268 }, - { 3, 1271 }, - { 3, 1274 }, - { 3, 1277 }, - { 2, 1280 }, - { 2, 1282 }, - { 2, 1284 }, - { 2, 1286 }, - { 2, 1288 }, - { 2, 1290 }, - { 2, 1292 }, - { 2, 1294 }, - { 3, 1296 }, - { 3, 1299 }, - { 3, 1302 }, - { 3, 1305 }, - { 3, 1308 }, - { 3, 1311 }, - { 3, 1314 }, - { 3, 1317 }, - { 3, 1320 }, - { 3, 1323 }, - { 3, 1326 }, - { 3, 1329 }, - { 3, 1332 }, - { 3, 1335 }, - { 3, 1338 }, - { 3, 1341 }, - { 3, 1344 }, - { 3, 1347 }, - { 3, 1350 }, - { 3, 1353 }, - { 2, 1356 }, - { 2, 1358 }, - { 2, 1360 }, - { 2, 1362 }, - { 3, 1364 }, - { 3, 1367 }, - { 3, 1370 }, - { 3, 1373 }, - { 3, 1376 }, - { 3, 1379 }, - { 3, 1382 }, - { 3, 1385 }, - { 3, 1388 }, - { 3, 1391 }, - { 2, 1394 }, - { 2, 1396 }, - { 2, 1398 }, - { 2, 1400 }, - { 2, 1402 }, - { 2, 1404 }, - { 2, 1406 }, - { 2, 1408 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x1f[256] = { - { 2, 1410 }, - { 2, 1412 }, - { 3, 1414 }, - { 3, 1417 }, - { 3, 1420 }, - { 3, 1423 }, - { 3, 1426 }, - { 3, 1429 }, - { 2, 1432 }, - { 2, 1434 }, - { 3, 1436 }, - { 3, 1439 }, - { 3, 1442 }, - { 3, 1445 }, - { 3, 1448 }, - { 3, 1451 }, - { 2, 1454 }, - { 2, 1456 }, - { 3, 1458 }, - { 3, 1461 }, - { 3, 1464 }, - { 3, 1467 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1470 }, - { 2, 1472 }, - { 3, 1474 }, - { 3, 1477 }, - { 3, 1480 }, - { 3, 1483 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1486 }, - { 2, 1488 }, - { 3, 1490 }, - { 3, 1493 }, - { 3, 1496 }, - { 3, 1499 }, - { 3, 1502 }, - { 3, 1505 }, - { 2, 1508 }, - { 2, 1510 }, - { 3, 1512 }, - { 3, 1515 }, - { 3, 1518 }, - { 3, 1521 }, - { 3, 1524 }, - { 3, 1527 }, - { 2, 1530 }, - { 2, 1532 }, - { 3, 1534 }, - { 3, 1537 }, - { 3, 1540 }, - { 3, 1543 }, - { 3, 1546 }, - { 3, 1549 }, - { 2, 1552 }, - { 2, 1554 }, - { 3, 1556 }, - { 3, 1559 }, - { 3, 1562 }, - { 3, 1565 }, - { 3, 1568 }, - { 3, 1571 }, - { 2, 1574 }, - { 2, 1576 }, - { 3, 1578 }, - { 3, 1581 }, - { 3, 1584 }, - { 3, 1587 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1590 }, - { 2, 1592 }, - { 3, 1594 }, - { 3, 1597 }, - { 3, 1600 }, - { 3, 1603 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1606 }, - { 2, 1608 }, - { 3, 1610 }, - { 3, 1613 }, - { 3, 1616 }, - { 3, 1619 }, - { 3, 1622 }, - { 3, 1625 }, - { 0, 0 }, - { 2, 1628 }, - { 0, 0 }, - { 3, 1630 }, - { 0, 0 }, - { 3, 1633 }, - { 0, 0 }, - { 3, 1636 }, - { 2, 1639 }, - { 2, 1641 }, - { 3, 1643 }, - { 3, 1646 }, - { 3, 1649 }, - { 3, 1652 }, - { 3, 1655 }, - { 3, 1658 }, - { 2, 1661 }, - { 2, 1663 }, - { 3, 1665 }, - { 3, 1668 }, - { 3, 1671 }, - { 3, 1674 }, - { 3, 1677 }, - { 3, 1680 }, - { 2, 1683 }, - { 2, 1685 }, - { 2, 1687 }, - { 2, 1689 }, - { 2, 1691 }, - { 2, 1693 }, - { 2, 1695 }, - { 2, 1697 }, - { 2, 1699 }, - { 2, 1701 }, - { 2, 1703 }, - { 2, 1705 }, - { 2, 1707 }, - { 2, 1709 }, - { 0, 0 }, - { 0, 0 }, - { 3, 1711 }, - { 3, 1714 }, - { 4, 1717 }, - { 4, 1721 }, - { 4, 1725 }, - { 4, 1729 }, - { 4, 1733 }, - { 4, 1737 }, - { 3, 1741 }, - { 3, 1744 }, - { 4, 1747 }, - { 4, 1751 }, - { 4, 1755 }, - { 4, 1759 }, - { 4, 1763 }, - { 4, 1767 }, - { 3, 1771 }, - { 3, 1774 }, - { 4, 1777 }, - { 4, 1781 }, - { 4, 1785 }, - { 4, 1789 }, - { 4, 1793 }, - { 4, 1797 }, - { 3, 1801 }, - { 3, 1804 }, - { 4, 1807 }, - { 4, 1811 }, - { 4, 1815 }, - { 4, 1819 }, - { 4, 1823 }, - { 4, 1827 }, - { 3, 1831 }, - { 3, 1834 }, - { 4, 1837 }, - { 4, 1841 }, - { 4, 1845 }, - { 4, 1849 }, - { 4, 1853 }, - { 4, 1857 }, - { 3, 1861 }, - { 3, 1864 }, - { 4, 1867 }, - { 4, 1871 }, - { 4, 1875 }, - { 4, 1879 }, - { 4, 1883 }, - { 4, 1887 }, - { 2, 1891 }, - { 2, 1893 }, - { 3, 1895 }, - { 2, 1898 }, - { 3, 1900 }, - { 0, 0 }, - { 2, 1903 }, - { 3, 1905 }, - { 2, 1908 }, - { 2, 1910 }, - { 2, 1912 }, - { 2, 1914 }, - { 2, 1916 }, - { 0, 0 }, - { 1, 1918 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1919 }, - { 3, 1921 }, - { 2, 1924 }, - { 3, 1926 }, - { 0, 0 }, - { 2, 1929 }, - { 3, 1931 }, - { 2, 1934 }, - { 2, 1936 }, - { 2, 1938 }, - { 2, 1940 }, - { 2, 1942 }, - { 2, 1944 }, - { 2, 1946 }, - { 2, 1948 }, - { 2, 1950 }, - { 2, 1952 }, - { 3, 1954 }, - { 3, 1957 }, - { 0, 0 }, - { 0, 0 }, - { 2, 1960 }, - { 3, 1962 }, - { 2, 1965 }, - { 2, 1967 }, - { 2, 1969 }, - { 2, 1971 }, - { 0, 0 }, - { 2, 1973 }, - { 2, 1975 }, - { 2, 1977 }, - { 2, 1979 }, - { 2, 1981 }, - { 3, 1983 }, - { 3, 1986 }, - { 2, 1989 }, - { 2, 1991 }, - { 2, 1993 }, - { 3, 1995 }, - { 2, 1998 }, - { 2, 2000 }, - { 2, 2002 }, - { 2, 2004 }, - { 2, 2006 }, - { 2, 2008 }, - { 2, 2010 }, - { 1, 2012 }, - { 0, 0 }, - { 0, 0 }, - { 3, 2013 }, - { 2, 2016 }, - { 3, 2018 }, - { 0, 0 }, - { 2, 2021 }, - { 3, 2023 }, - { 2, 2026 }, - { 2, 2028 }, - { 2, 2030 }, - { 2, 2032 }, - { 2, 2034 }, - { 1, 2036 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x22[256] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2055 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2057 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2059 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2061 }, - { 0, 0 }, - { 2, 2063 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2065 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2067 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2069 }, - { 0, 0 }, - { 2, 2071 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2073 }, - { 0, 0 }, - { 2, 2075 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2077 }, - { 2, 2079 }, - { 2, 2081 }, - { 2, 2083 }, - { 2, 2085 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2087 }, - { 2, 2089 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2091 }, - { 2, 2093 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2095 }, - { 2, 2097 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2099 }, - { 2, 2101 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2103 }, - { 2, 2105 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2107 }, - { 2, 2109 }, - { 2, 2111 }, - { 2, 2113 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2115 }, - { 2, 2117 }, - { 2, 2119 }, - { 2, 2121 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2123 }, - { 2, 2125 }, - { 2, 2127 }, - { 2, 2129 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x30[256] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2135 }, - { 0, 0 }, - { 2, 2137 }, - { 0, 0 }, - { 2, 2139 }, - { 0, 0 }, - { 2, 2141 }, - { 0, 0 }, - { 2, 2143 }, - { 0, 0 }, - { 2, 2145 }, - { 0, 0 }, - { 2, 2147 }, - { 0, 0 }, - { 2, 2149 }, - { 0, 0 }, - { 2, 2151 }, - { 0, 0 }, - { 2, 2153 }, - { 0, 0 }, - { 2, 2155 }, - { 0, 0 }, - { 2, 2157 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2159 }, - { 0, 0 }, - { 2, 2161 }, - { 0, 0 }, - { 2, 2163 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2165 }, - { 2, 2167 }, - { 0, 0 }, - { 2, 2169 }, - { 2, 2171 }, - { 0, 0 }, - { 2, 2173 }, - { 2, 2175 }, - { 0, 0 }, - { 2, 2177 }, - { 2, 2179 }, - { 0, 0 }, - { 2, 2181 }, - { 2, 2183 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2185 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2187 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2189 }, - { 0, 0 }, - { 2, 2191 }, - { 0, 0 }, - { 2, 2193 }, - { 0, 0 }, - { 2, 2195 }, - { 0, 0 }, - { 2, 2197 }, - { 0, 0 }, - { 2, 2199 }, - { 0, 0 }, - { 2, 2201 }, - { 0, 0 }, - { 2, 2203 }, - { 0, 0 }, - { 2, 2205 }, - { 0, 0 }, - { 2, 2207 }, - { 0, 0 }, - { 2, 2209 }, - { 0, 0 }, - { 2, 2211 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2213 }, - { 0, 0 }, - { 2, 2215 }, - { 0, 0 }, - { 2, 2217 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2219 }, - { 2, 2221 }, - { 0, 0 }, - { 2, 2223 }, - { 2, 2225 }, - { 0, 0 }, - { 2, 2227 }, - { 2, 2229 }, - { 0, 0 }, - { 2, 2231 }, - { 2, 2233 }, - { 0, 0 }, - { 2, 2235 }, - { 2, 2237 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2239 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2241 }, - { 2, 2243 }, - { 2, 2245 }, - { 2, 2247 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2249 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0xf9[256] = { - { 1, 2251 }, - { 1, 2252 }, - { 1, 2253 }, - { 1, 2254 }, - { 1, 2255 }, - { 1, 2256 }, - { 1, 2257 }, - { 1, 2258 }, - { 1, 2259 }, - { 1, 2260 }, - { 1, 2261 }, - { 1, 2262 }, - { 1, 2263 }, - { 1, 2264 }, - { 1, 2265 }, - { 1, 2266 }, - { 1, 2267 }, - { 1, 2268 }, - { 1, 2269 }, - { 1, 2270 }, - { 1, 2271 }, - { 1, 2272 }, - { 1, 2273 }, - { 1, 2274 }, - { 1, 2275 }, - { 1, 2276 }, - { 1, 2277 }, - { 1, 2278 }, - { 1, 2279 }, - { 1, 2280 }, - { 1, 2281 }, - { 1, 2282 }, - { 1, 2283 }, - { 1, 2284 }, - { 1, 2285 }, - { 1, 2286 }, - { 1, 2287 }, - { 1, 2288 }, - { 1, 2289 }, - { 1, 2290 }, - { 1, 2291 }, - { 1, 2292 }, - { 1, 2293 }, - { 1, 2294 }, - { 1, 2295 }, - { 1, 2296 }, - { 1, 2297 }, - { 1, 2298 }, - { 1, 2299 }, - { 1, 2300 }, - { 1, 2301 }, - { 1, 2302 }, - { 1, 2303 }, - { 1, 2304 }, - { 1, 2305 }, - { 1, 2306 }, - { 1, 2307 }, - { 1, 2308 }, - { 1, 2309 }, - { 1, 2310 }, - { 1, 2311 }, - { 1, 2312 }, - { 1, 2313 }, - { 1, 2314 }, - { 1, 2315 }, - { 1, 2316 }, - { 1, 2317 }, - { 1, 2318 }, - { 1, 2319 }, - { 1, 2320 }, - { 1, 2321 }, - { 1, 2322 }, - { 1, 2323 }, - { 1, 2324 }, - { 1, 2325 }, - { 1, 2326 }, - { 1, 2327 }, - { 1, 2328 }, - { 1, 2329 }, - { 1, 2330 }, - { 1, 2331 }, - { 1, 2332 }, - { 1, 2333 }, - { 1, 2334 }, - { 1, 2335 }, - { 1, 2336 }, - { 1, 2337 }, - { 1, 2338 }, - { 1, 2339 }, - { 1, 2340 }, - { 1, 2341 }, - { 1, 2342 }, - { 1, 2343 }, - { 1, 2344 }, - { 1, 2345 }, - { 1, 2346 }, - { 1, 2347 }, - { 1, 2348 }, - { 1, 2349 }, - { 1, 2350 }, - { 1, 2351 }, - { 1, 2352 }, - { 1, 2353 }, - { 1, 2354 }, - { 1, 2355 }, - { 1, 2356 }, - { 1, 2357 }, - { 1, 2358 }, - { 1, 2359 }, - { 1, 2360 }, - { 1, 2361 }, - { 1, 2362 }, - { 1, 2363 }, - { 1, 2364 }, - { 1, 2365 }, - { 1, 2366 }, - { 1, 2367 }, - { 1, 2368 }, - { 1, 2369 }, - { 1, 2370 }, - { 1, 2371 }, - { 1, 2372 }, - { 1, 2373 }, - { 1, 2374 }, - { 1, 2375 }, - { 1, 2376 }, - { 1, 2377 }, - { 1, 2378 }, - { 1, 2379 }, - { 1, 2380 }, - { 1, 2381 }, - { 1, 2382 }, - { 1, 2383 }, - { 1, 2384 }, - { 1, 2385 }, - { 1, 2386 }, - { 1, 2387 }, - { 1, 2388 }, - { 1, 2389 }, - { 1, 2390 }, - { 1, 2391 }, - { 1, 2392 }, - { 1, 2393 }, - { 1, 2394 }, - { 1, 2395 }, - { 1, 2396 }, - { 1, 2397 }, - { 1, 2398 }, - { 1, 2399 }, - { 1, 2400 }, - { 1, 2401 }, - { 1, 2402 }, - { 1, 2403 }, - { 1, 2404 }, - { 1, 2405 }, - { 1, 2406 }, - { 1, 2407 }, - { 1, 2408 }, - { 1, 2409 }, - { 1, 2410 }, - { 1, 2411 }, - { 1, 2412 }, - { 1, 2413 }, - { 1, 2414 }, - { 1, 2415 }, - { 1, 2416 }, - { 1, 2417 }, - { 1, 2418 }, - { 1, 2419 }, - { 1, 2420 }, - { 1, 2421 }, - { 1, 2422 }, - { 1, 2423 }, - { 1, 2424 }, - { 1, 2425 }, - { 1, 2426 }, - { 1, 2427 }, - { 1, 2428 }, - { 1, 2429 }, - { 1, 2430 }, - { 1, 2431 }, - { 1, 2432 }, - { 1, 2433 }, - { 1, 2434 }, - { 1, 2435 }, - { 1, 2436 }, - { 1, 2437 }, - { 1, 2438 }, - { 1, 2439 }, - { 1, 2440 }, - { 1, 2441 }, - { 1, 2442 }, - { 1, 2443 }, - { 1, 2444 }, - { 1, 2445 }, - { 1, 2446 }, - { 1, 2447 }, - { 1, 2448 }, - { 1, 2449 }, - { 1, 2450 }, - { 1, 2451 }, - { 1, 2452 }, - { 1, 2453 }, - { 1, 2454 }, - { 1, 2455 }, - { 1, 2456 }, - { 1, 2457 }, - { 1, 2458 }, - { 1, 2459 }, - { 1, 2460 }, - { 1, 2461 }, - { 1, 2462 }, - { 1, 2463 }, - { 1, 2464 }, - { 1, 2465 }, - { 1, 2466 }, - { 1, 2467 }, - { 1, 2468 }, - { 1, 2469 }, - { 1, 2470 }, - { 1, 2471 }, - { 1, 2472 }, - { 1, 2473 }, - { 1, 2474 }, - { 1, 2475 }, - { 1, 2476 }, - { 1, 2477 }, - { 1, 2478 }, - { 1, 2479 }, - { 1, 2480 }, - { 1, 2481 }, - { 1, 2482 }, - { 1, 2483 }, - { 1, 2484 }, - { 1, 2485 }, - { 1, 2486 }, - { 1, 2487 }, - { 1, 2488 }, - { 1, 2489 }, - { 1, 2490 }, - { 1, 2491 }, - { 1, 2492 }, - { 1, 2493 }, - { 1, 2494 }, - { 1, 2495 }, - { 1, 2496 }, - { 1, 2497 }, - { 1, 2498 }, - { 1, 2499 }, - { 1, 2500 }, - { 1, 2501 }, - { 1, 2502 }, - { 1, 2503 }, - { 1, 2504 }, - { 1, 2505 }, - { 1, 2506 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0xfa[256] = { - { 1, 2507 }, - { 1, 2508 }, - { 1, 2509 }, - { 1, 2510 }, - { 1, 2511 }, - { 1, 2512 }, - { 1, 2513 }, - { 1, 2514 }, - { 1, 2515 }, - { 1, 2516 }, - { 1, 2517 }, - { 1, 2518 }, - { 1, 2519 }, - { 1, 2520 }, - { 0, 0 }, - { 0, 0 }, - { 1, 2521 }, - { 0, 0 }, - { 1, 2522 }, - { 0, 0 }, - { 0, 0 }, - { 1, 2523 }, - { 1, 2524 }, - { 1, 2525 }, - { 1, 2526 }, - { 1, 2527 }, - { 1, 2528 }, - { 1, 2529 }, - { 1, 2530 }, - { 1, 2531 }, - { 1, 2532 }, - { 0, 0 }, - { 1, 2533 }, - { 0, 0 }, - { 1, 2534 }, - { 0, 0 }, - { 0, 0 }, - { 1, 2535 }, - { 1, 2536 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 1, 2537 }, - { 1, 2538 }, - { 1, 2539 }, - { 1, 2540 }, - { 0, 0 }, - { 0, 0 }, - { 1, 2541 }, - { 1, 2542 }, - { 1, 2543 }, - { 1, 2544 }, - { 1, 2545 }, - { 1, 2546 }, - { 1, 2547 }, - { 1, 2548 }, - { 1, 2549 }, - { 1, 2550 }, - { 1, 2551 }, - { 1, 2552 }, - { 1, 2553 }, - { 1, 2554 }, - { 1, 2555 }, - { 1, 2556 }, - { 1, 2557 }, - { 1, 2558 }, - { 1, 2559 }, - { 1, 2560 }, - { 1, 2561 }, - { 1, 2562 }, - { 1, 2563 }, - { 1, 2564 }, - { 1, 2565 }, - { 1, 2566 }, - { 1, 2567 }, - { 1, 2568 }, - { 1, 2569 }, - { 1, 2570 }, - { 1, 2571 }, - { 1, 2572 }, - { 1, 2573 }, - { 1, 2574 }, - { 1, 2575 }, - { 1, 2576 }, - { 1, 2577 }, - { 1, 2578 }, - { 1, 2579 }, - { 1, 2580 }, - { 1, 2581 }, - { 1, 2582 }, - { 1, 2583 }, - { 1, 2584 }, - { 1, 2585 }, - { 1, 2586 }, - { 1, 2587 }, - { 1, 2588 }, - { 1, 2589 }, - { 1, 2590 }, - { 1, 2591 }, - { 1, 2592 }, - { 1, 2593 }, - { 1, 2594 }, - { 1, 2595 }, - { 1, 2596 }, - { 1, 2597 }, - { 1, 2598 }, - { 1, 2599 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0xfb[256] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2600 }, - { 0, 0 }, - { 2, 2602 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 2, 2604 }, - { 2, 2606 }, - { 3, 2608 }, - { 3, 2611 }, - { 2, 2614 }, - { 2, 2616 }, - { 2, 2618 }, - { 2, 2620 }, - { 2, 2622 }, - { 2, 2624 }, - { 2, 2626 }, - { 2, 2628 }, - { 2, 2630 }, - { 0, 0 }, - { 2, 2632 }, - { 2, 2634 }, - { 2, 2636 }, - { 2, 2638 }, - { 2, 2640 }, - { 0, 0 }, - { 2, 2642 }, - { 0, 0 }, - { 2, 2644 }, - { 2, 2646 }, - { 0, 0 }, - { 2, 2648 }, - { 2, 2650 }, - { 0, 0 }, - { 2, 2652 }, - { 2, 2654 }, - { 2, 2656 }, - { 2, 2658 }, - { 2, 2660 }, - { 2, 2662 }, - { 2, 2664 }, - { 2, 2666 }, - { 2, 2668 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x2f8[256] = { - { 1, 2705 }, - { 1, 2706 }, - { 1, 2707 }, - { 1, 2708 }, - { 1, 2709 }, - { 1, 2710 }, - { 1, 2711 }, - { 1, 2712 }, - { 1, 2713 }, - { 1, 2714 }, - { 1, 2715 }, - { 1, 2716 }, - { 1, 2717 }, - { 1, 2718 }, - { 1, 2719 }, - { 1, 2720 }, - { 1, 2721 }, - { 1, 2722 }, - { 1, 2723 }, - { 1, 2724 }, - { 1, 2725 }, - { 1, 2726 }, - { 1, 2727 }, - { 1, 2728 }, - { 1, 2729 }, - { 1, 2730 }, - { 1, 2731 }, - { 1, 2732 }, - { 1, 2733 }, - { 1, 2734 }, - { 1, 2735 }, - { 1, 2736 }, - { 1, 2737 }, - { 1, 2738 }, - { 1, 2739 }, - { 1, 2740 }, - { 1, 2741 }, - { 1, 2742 }, - { 1, 2743 }, - { 1, 2744 }, - { 1, 2745 }, - { 1, 2746 }, - { 1, 2747 }, - { 1, 2748 }, - { 1, 2749 }, - { 1, 2750 }, - { 1, 2751 }, - { 1, 2752 }, - { 1, 2753 }, - { 1, 2754 }, - { 1, 2755 }, - { 1, 2756 }, - { 1, 2757 }, - { 1, 2758 }, - { 1, 2759 }, - { 1, 2760 }, - { 1, 2761 }, - { 1, 2762 }, - { 1, 2763 }, - { 1, 2764 }, - { 1, 2765 }, - { 1, 2766 }, - { 1, 2767 }, - { 1, 2768 }, - { 1, 2769 }, - { 1, 2770 }, - { 1, 2771 }, - { 1, 2772 }, - { 1, 2773 }, - { 1, 2774 }, - { 1, 2775 }, - { 1, 2776 }, - { 1, 2777 }, - { 1, 2778 }, - { 1, 2779 }, - { 1, 2780 }, - { 1, 2781 }, - { 1, 2782 }, - { 1, 2783 }, - { 1, 2784 }, - { 1, 2785 }, - { 1, 2786 }, - { 1, 2787 }, - { 1, 2788 }, - { 1, 2789 }, - { 1, 2790 }, - { 1, 2791 }, - { 1, 2792 }, - { 1, 2793 }, - { 1, 2794 }, - { 1, 2795 }, - { 1, 2796 }, - { 1, 2797 }, - { 1, 2798 }, - { 1, 2799 }, - { 1, 2800 }, - { 1, 2801 }, - { 1, 2802 }, - { 1, 2803 }, - { 1, 2804 }, - { 1, 2805 }, - { 1, 2806 }, - { 1, 2807 }, - { 1, 2808 }, - { 1, 2809 }, - { 1, 2810 }, - { 1, 2811 }, - { 1, 2812 }, - { 1, 2813 }, - { 1, 2814 }, - { 1, 2815 }, - { 1, 2816 }, - { 1, 2817 }, - { 1, 2818 }, - { 1, 2819 }, - { 1, 2820 }, - { 1, 2821 }, - { 1, 2822 }, - { 1, 2823 }, - { 1, 2824 }, - { 1, 2825 }, - { 1, 2826 }, - { 1, 2827 }, - { 1, 2828 }, - { 1, 2829 }, - { 1, 2830 }, - { 1, 2831 }, - { 1, 2832 }, - { 1, 2833 }, - { 1, 2834 }, - { 1, 2835 }, - { 1, 2836 }, - { 1, 2837 }, - { 1, 2838 }, - { 1, 2839 }, - { 1, 2840 }, - { 1, 2841 }, - { 1, 2842 }, - { 1, 2843 }, - { 1, 2844 }, - { 1, 2845 }, - { 1, 2846 }, - { 1, 2847 }, - { 1, 2848 }, - { 1, 2849 }, - { 1, 2850 }, - { 1, 2851 }, - { 1, 2852 }, - { 1, 2853 }, - { 1, 2854 }, - { 1, 2855 }, - { 1, 2856 }, - { 1, 2857 }, - { 1, 2858 }, - { 1, 2859 }, - { 1, 2860 }, - { 1, 2861 }, - { 1, 2862 }, - { 1, 2863 }, - { 1, 2864 }, - { 1, 2865 }, - { 1, 2866 }, - { 1, 2867 }, - { 1, 2868 }, - { 1, 2869 }, - { 1, 2870 }, - { 1, 2871 }, - { 1, 2872 }, - { 1, 2873 }, - { 1, 2874 }, - { 1, 2875 }, - { 1, 2876 }, - { 1, 2877 }, - { 1, 2878 }, - { 1, 2879 }, - { 1, 2880 }, - { 1, 2881 }, - { 1, 2882 }, - { 1, 2883 }, - { 1, 2884 }, - { 1, 2885 }, - { 1, 2886 }, - { 1, 2887 }, - { 1, 2888 }, - { 1, 2889 }, - { 1, 2890 }, - { 1, 2891 }, - { 1, 2892 }, - { 1, 2893 }, - { 1, 2894 }, - { 1, 2895 }, - { 1, 2896 }, - { 1, 2897 }, - { 1, 2898 }, - { 1, 2899 }, - { 1, 2900 }, - { 1, 2901 }, - { 1, 2902 }, - { 1, 2903 }, - { 1, 2904 }, - { 1, 2905 }, - { 1, 2906 }, - { 1, 2907 }, - { 1, 2908 }, - { 1, 2909 }, - { 1, 2910 }, - { 1, 2911 }, - { 1, 2912 }, - { 1, 2913 }, - { 1, 2914 }, - { 1, 2915 }, - { 1, 2916 }, - { 1, 2917 }, - { 1, 2918 }, - { 1, 2919 }, - { 1, 2920 }, - { 1, 2921 }, - { 1, 2922 }, - { 1, 2923 }, - { 1, 2924 }, - { 1, 2925 }, - { 1, 2926 }, - { 1, 2927 }, - { 1, 2928 }, - { 1, 2929 }, - { 1, 2930 }, - { 1, 2931 }, - { 1, 2932 }, - { 1, 2933 }, - { 1, 2934 }, - { 1, 2935 }, - { 1, 2936 }, - { 1, 2937 }, - { 1, 2938 }, - { 1, 2939 }, - { 1, 2940 }, - { 1, 2941 }, - { 1, 2942 }, - { 1, 2943 }, - { 1, 2944 }, - { 1, 2945 }, - { 1, 2946 }, - { 1, 2947 }, - { 1, 2948 }, - { 1, 2949 }, - { 1, 2950 }, - { 1, 2951 }, - { 1, 2952 }, - { 1, 2953 }, - { 1, 2954 }, - { 1, 2955 }, - { 1, 2956 }, - { 1, 2957 }, - { 1, 2958 }, - { 1, 2959 }, - { 1, 2960 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x2f9[256] = { - { 1, 2961 }, - { 1, 2962 }, - { 1, 2963 }, - { 1, 2964 }, - { 1, 2965 }, - { 1, 2966 }, - { 1, 2967 }, - { 1, 2968 }, - { 1, 2969 }, - { 1, 2970 }, - { 1, 2971 }, - { 1, 2972 }, - { 1, 2973 }, - { 1, 2974 }, - { 1, 2975 }, - { 1, 2976 }, - { 1, 2977 }, - { 1, 2978 }, - { 1, 2979 }, - { 1, 2980 }, - { 1, 2981 }, - { 1, 2982 }, - { 1, 2983 }, - { 1, 2984 }, - { 1, 2985 }, - { 1, 2986 }, - { 1, 2987 }, - { 1, 2988 }, - { 1, 2989 }, - { 1, 2990 }, - { 1, 2991 }, - { 1, 2992 }, - { 1, 2993 }, - { 1, 2994 }, - { 1, 2995 }, - { 1, 2996 }, - { 1, 2997 }, - { 1, 2998 }, - { 1, 2999 }, - { 1, 3000 }, - { 1, 3001 }, - { 1, 3002 }, - { 1, 3003 }, - { 1, 3004 }, - { 1, 3005 }, - { 1, 3006 }, - { 1, 3007 }, - { 1, 3008 }, - { 1, 3009 }, - { 1, 3010 }, - { 1, 3011 }, - { 1, 3012 }, - { 1, 3013 }, - { 1, 3014 }, - { 1, 3015 }, - { 1, 3016 }, - { 1, 3017 }, - { 1, 3018 }, - { 1, 3019 }, - { 1, 3020 }, - { 1, 3021 }, - { 1, 3022 }, - { 1, 3023 }, - { 1, 3024 }, - { 1, 3025 }, - { 1, 3026 }, - { 1, 3027 }, - { 1, 3028 }, - { 1, 3029 }, - { 1, 3030 }, - { 1, 3031 }, - { 1, 3032 }, - { 1, 3033 }, - { 1, 3034 }, - { 1, 3035 }, - { 1, 3036 }, - { 1, 3037 }, - { 1, 3038 }, - { 1, 3039 }, - { 1, 3040 }, - { 1, 3041 }, - { 1, 3042 }, - { 1, 3043 }, - { 1, 3044 }, - { 1, 3045 }, - { 1, 3046 }, - { 1, 3047 }, - { 1, 3048 }, - { 1, 3049 }, - { 1, 3050 }, - { 1, 3051 }, - { 1, 3052 }, - { 1, 3053 }, - { 1, 3054 }, - { 1, 3055 }, - { 1, 3056 }, - { 1, 3057 }, - { 1, 3058 }, - { 1, 3059 }, - { 1, 3060 }, - { 1, 3061 }, - { 1, 3062 }, - { 1, 3063 }, - { 1, 3064 }, - { 1, 3065 }, - { 1, 3066 }, - { 1, 3067 }, - { 1, 3068 }, - { 1, 3069 }, - { 1, 3070 }, - { 1, 3071 }, - { 1, 3072 }, - { 1, 3073 }, - { 1, 3074 }, - { 1, 3075 }, - { 1, 3076 }, - { 1, 3077 }, - { 1, 3078 }, - { 1, 3079 }, - { 1, 3080 }, - { 1, 3081 }, - { 1, 3082 }, - { 1, 3083 }, - { 1, 3084 }, - { 1, 3085 }, - { 1, 3086 }, - { 1, 3087 }, - { 1, 3088 }, - { 1, 3089 }, - { 1, 3090 }, - { 1, 3091 }, - { 1, 3092 }, - { 1, 3093 }, - { 1, 3094 }, - { 1, 3095 }, - { 1, 3096 }, - { 1, 3097 }, - { 1, 3098 }, - { 1, 3099 }, - { 1, 3100 }, - { 1, 3101 }, - { 1, 3102 }, - { 1, 3103 }, - { 1, 3104 }, - { 1, 3105 }, - { 1, 3106 }, - { 1, 3107 }, - { 1, 3108 }, - { 1, 3109 }, - { 1, 3110 }, - { 1, 3111 }, - { 1, 3112 }, - { 1, 3113 }, - { 1, 3114 }, - { 1, 3115 }, - { 1, 3116 }, - { 1, 3117 }, - { 1, 3118 }, - { 1, 3119 }, - { 1, 3120 }, - { 1, 3121 }, - { 1, 3122 }, - { 1, 3123 }, - { 1, 3124 }, - { 1, 3125 }, - { 1, 3126 }, - { 1, 3127 }, - { 1, 3128 }, - { 1, 3129 }, - { 1, 3130 }, - { 1, 3131 }, - { 1, 3132 }, - { 1, 3133 }, - { 1, 3134 }, - { 1, 3135 }, - { 1, 3136 }, - { 1, 3137 }, - { 1, 3138 }, - { 1, 3139 }, - { 1, 3140 }, - { 1, 3141 }, - { 1, 3142 }, - { 1, 3143 }, - { 1, 3144 }, - { 1, 3145 }, - { 1, 3146 }, - { 1, 3147 }, - { 1, 3148 }, - { 1, 3149 }, - { 1, 3150 }, - { 1, 3151 }, - { 1, 3152 }, - { 1, 3153 }, - { 1, 3154 }, - { 1, 3155 }, - { 1, 3156 }, - { 1, 3157 }, - { 1, 3158 }, - { 1, 3159 }, - { 1, 3160 }, - { 1, 3161 }, - { 1, 3162 }, - { 1, 3163 }, - { 1, 3164 }, - { 1, 3165 }, - { 1, 3166 }, - { 1, 3167 }, - { 1, 3168 }, - { 1, 3169 }, - { 1, 3170 }, - { 1, 3171 }, - { 1, 3172 }, - { 1, 3173 }, - { 1, 3174 }, - { 1, 3175 }, - { 1, 3176 }, - { 1, 3177 }, - { 1, 3178 }, - { 1, 3179 }, - { 1, 3180 }, - { 1, 3181 }, - { 1, 3182 }, - { 1, 3183 }, - { 1, 3184 }, - { 1, 3185 }, - { 1, 3186 }, - { 1, 3187 }, - { 1, 3188 }, - { 1, 3189 }, - { 1, 3190 }, - { 1, 3191 }, - { 1, 3192 }, - { 1, 3193 }, - { 1, 3194 }, - { 1, 3195 }, - { 1, 3196 }, - { 1, 3197 }, - { 1, 3198 }, - { 1, 3199 }, - { 1, 3200 }, - { 1, 3201 }, - { 1, 3202 }, - { 1, 3203 }, - { 1, 3204 }, - { 1, 3205 }, - { 1, 3206 }, - { 1, 3207 }, - { 1, 3208 }, - { 1, 3209 }, - { 1, 3210 }, - { 1, 3211 }, - { 1, 3212 }, - { 1, 3213 }, - { 1, 3214 }, - { 1, 3215 }, - { 1, 3216 }, -}; - -static gli_decomp_block_t unigen_decomp_block_0x2fa[256] = { - { 1, 3217 }, - { 1, 3218 }, - { 1, 3219 }, - { 1, 3220 }, - { 1, 3221 }, - { 1, 3222 }, - { 1, 3223 }, - { 1, 3224 }, - { 1, 3225 }, - { 1, 3226 }, - { 1, 3227 }, - { 1, 3228 }, - { 1, 3229 }, - { 1, 3230 }, - { 1, 3231 }, - { 1, 3232 }, - { 1, 3233 }, - { 1, 3234 }, - { 1, 3235 }, - { 1, 3236 }, - { 1, 3237 }, - { 1, 3238 }, - { 1, 3239 }, - { 1, 3240 }, - { 1, 3241 }, - { 1, 3242 }, - { 1, 3243 }, - { 1, 3244 }, - { 1, 3245 }, - { 1, 3246 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -#define GET_DECOMP_BLOCK(ch, blockptr) \ -switch ((glui32)(ch) >> 8) { \ - case 0x0: \ - *blockptr = unigen_decomp_block_0x0; \ - break; \ - case 0x1: \ - *blockptr = unigen_decomp_block_0x1; \ - break; \ - case 0x2: \ - *blockptr = unigen_decomp_block_0x2; \ - break; \ - case 0x3: \ - *blockptr = unigen_decomp_block_0x3; \ - break; \ - case 0x4: \ - *blockptr = unigen_decomp_block_0x4; \ - break; \ - case 0x1e: \ - *blockptr = unigen_decomp_block_0x1e; \ - break; \ - case 0x1f: \ - *blockptr = unigen_decomp_block_0x1f; \ - break; \ - case 0x22: \ - *blockptr = unigen_decomp_block_0x22; \ - break; \ - case 0x30: \ - *blockptr = unigen_decomp_block_0x30; \ - break; \ - case 0xf9: \ - *blockptr = unigen_decomp_block_0xf9; \ - break; \ - case 0xfa: \ - *blockptr = unigen_decomp_block_0xfa; \ - break; \ - case 0xfb: \ - *blockptr = unigen_decomp_block_0xfb; \ - break; \ - case 0x2f8: \ - *blockptr = unigen_decomp_block_0x2f8; \ - break; \ - case 0x2f9: \ - *blockptr = unigen_decomp_block_0x2f9; \ - break; \ - case 0x2fa: \ - *blockptr = unigen_decomp_block_0x2fa; \ - break; \ - default: \ - *blockptr = NULL; \ -} - -#define GET_DECOMP_SPECIAL(ch, countptr, posptr) \ -switch (ch) { \ - case 0x622: \ - *countptr = 2; *posptr = 686; \ - break; \ - case 0x623: \ - *countptr = 2; *posptr = 688; \ - break; \ - case 0x624: \ - *countptr = 2; *posptr = 690; \ - break; \ - case 0x625: \ - *countptr = 2; *posptr = 692; \ - break; \ - case 0x626: \ - *countptr = 2; *posptr = 694; \ - break; \ - case 0x6c0: \ - *countptr = 2; *posptr = 696; \ - break; \ - case 0x6c2: \ - *countptr = 2; *posptr = 698; \ - break; \ - case 0x6d3: \ - *countptr = 2; *posptr = 700; \ - break; \ - case 0x929: \ - *countptr = 2; *posptr = 702; \ - break; \ - case 0x931: \ - *countptr = 2; *posptr = 704; \ - break; \ - case 0x934: \ - *countptr = 2; *posptr = 706; \ - break; \ - case 0x958: \ - *countptr = 2; *posptr = 708; \ - break; \ - case 0x959: \ - *countptr = 2; *posptr = 710; \ - break; \ - case 0x95a: \ - *countptr = 2; *posptr = 712; \ - break; \ - case 0x95b: \ - *countptr = 2; *posptr = 714; \ - break; \ - case 0x95c: \ - *countptr = 2; *posptr = 716; \ - break; \ - case 0x95d: \ - *countptr = 2; *posptr = 718; \ - break; \ - case 0x95e: \ - *countptr = 2; *posptr = 720; \ - break; \ - case 0x95f: \ - *countptr = 2; *posptr = 722; \ - break; \ - case 0x9cb: \ - *countptr = 2; *posptr = 724; \ - break; \ - case 0x9cc: \ - *countptr = 2; *posptr = 726; \ - break; \ - case 0x9dc: \ - *countptr = 2; *posptr = 728; \ - break; \ - case 0x9dd: \ - *countptr = 2; *posptr = 730; \ - break; \ - case 0x9df: \ - *countptr = 2; *posptr = 732; \ - break; \ - case 0xa33: \ - *countptr = 2; *posptr = 734; \ - break; \ - case 0xa36: \ - *countptr = 2; *posptr = 736; \ - break; \ - case 0xa59: \ - *countptr = 2; *posptr = 738; \ - break; \ - case 0xa5a: \ - *countptr = 2; *posptr = 740; \ - break; \ - case 0xa5b: \ - *countptr = 2; *posptr = 742; \ - break; \ - case 0xa5e: \ - *countptr = 2; *posptr = 744; \ - break; \ - case 0xb48: \ - *countptr = 2; *posptr = 746; \ - break; \ - case 0xb4b: \ - *countptr = 2; *posptr = 748; \ - break; \ - case 0xb4c: \ - *countptr = 2; *posptr = 750; \ - break; \ - case 0xb5c: \ - *countptr = 2; *posptr = 752; \ - break; \ - case 0xb5d: \ - *countptr = 2; *posptr = 754; \ - break; \ - case 0xb94: \ - *countptr = 2; *posptr = 756; \ - break; \ - case 0xbca: \ - *countptr = 2; *posptr = 758; \ - break; \ - case 0xbcb: \ - *countptr = 2; *posptr = 760; \ - break; \ - case 0xbcc: \ - *countptr = 2; *posptr = 762; \ - break; \ - case 0xc48: \ - *countptr = 2; *posptr = 764; \ - break; \ - case 0xcc0: \ - *countptr = 2; *posptr = 766; \ - break; \ - case 0xcc7: \ - *countptr = 2; *posptr = 768; \ - break; \ - case 0xcc8: \ - *countptr = 2; *posptr = 770; \ - break; \ - case 0xcca: \ - *countptr = 2; *posptr = 772; \ - break; \ - case 0xccb: \ - *countptr = 3; *posptr = 774; \ - break; \ - case 0xd4a: \ - *countptr = 2; *posptr = 777; \ - break; \ - case 0xd4b: \ - *countptr = 2; *posptr = 779; \ - break; \ - case 0xd4c: \ - *countptr = 2; *posptr = 781; \ - break; \ - case 0xdda: \ - *countptr = 2; *posptr = 783; \ - break; \ - case 0xddc: \ - *countptr = 2; *posptr = 785; \ - break; \ - case 0xddd: \ - *countptr = 3; *posptr = 787; \ - break; \ - case 0xdde: \ - *countptr = 2; *posptr = 790; \ - break; \ - case 0xf43: \ - *countptr = 2; *posptr = 792; \ - break; \ - case 0xf4d: \ - *countptr = 2; *posptr = 794; \ - break; \ - case 0xf52: \ - *countptr = 2; *posptr = 796; \ - break; \ - case 0xf57: \ - *countptr = 2; *posptr = 798; \ - break; \ - case 0xf5c: \ - *countptr = 2; *posptr = 800; \ - break; \ - case 0xf69: \ - *countptr = 2; *posptr = 802; \ - break; \ - case 0xf73: \ - *countptr = 2; *posptr = 804; \ - break; \ - case 0xf75: \ - *countptr = 2; *posptr = 806; \ - break; \ - case 0xf76: \ - *countptr = 2; *posptr = 808; \ - break; \ - case 0xf78: \ - *countptr = 2; *posptr = 810; \ - break; \ - case 0xf81: \ - *countptr = 2; *posptr = 812; \ - break; \ - case 0xf93: \ - *countptr = 2; *posptr = 814; \ - break; \ - case 0xf9d: \ - *countptr = 2; *posptr = 816; \ - break; \ - case 0xfa2: \ - *countptr = 2; *posptr = 818; \ - break; \ - case 0xfa7: \ - *countptr = 2; *posptr = 820; \ - break; \ - case 0xfac: \ - *countptr = 2; *posptr = 822; \ - break; \ - case 0xfb9: \ - *countptr = 2; *posptr = 824; \ - break; \ - case 0x1026: \ - *countptr = 2; *posptr = 826; \ - break; \ - case 0x2000: \ - *countptr = 1; *posptr = 2037; \ - break; \ - case 0x2001: \ - *countptr = 1; *posptr = 2038; \ - break; \ - case 0x2126: \ - *countptr = 1; *posptr = 2039; \ - break; \ - case 0x212a: \ - *countptr = 1; *posptr = 2040; \ - break; \ - case 0x212b: \ - *countptr = 2; *posptr = 2041; \ - break; \ - case 0x219a: \ - *countptr = 2; *posptr = 2043; \ - break; \ - case 0x219b: \ - *countptr = 2; *posptr = 2045; \ - break; \ - case 0x21ae: \ - *countptr = 2; *posptr = 2047; \ - break; \ - case 0x21cd: \ - *countptr = 2; *posptr = 2049; \ - break; \ - case 0x21ce: \ - *countptr = 2; *posptr = 2051; \ - break; \ - case 0x21cf: \ - *countptr = 2; *posptr = 2053; \ - break; \ - case 0x2329: \ - *countptr = 1; *posptr = 2131; \ - break; \ - case 0x232a: \ - *countptr = 1; *posptr = 2132; \ - break; \ - case 0x2adc: \ - *countptr = 2; *posptr = 2133; \ - break; \ - case 0x1d15e: \ - *countptr = 2; *posptr = 2670; \ - break; \ - case 0x1d15f: \ - *countptr = 2; *posptr = 2672; \ - break; \ - case 0x1d160: \ - *countptr = 3; *posptr = 2674; \ - break; \ - case 0x1d161: \ - *countptr = 3; *posptr = 2677; \ - break; \ - case 0x1d162: \ - *countptr = 3; *posptr = 2680; \ - break; \ - case 0x1d163: \ - *countptr = 3; *posptr = 2683; \ - break; \ - case 0x1d164: \ - *countptr = 3; *posptr = 2686; \ - break; \ - case 0x1d1bb: \ - *countptr = 2; *posptr = 2689; \ - break; \ - case 0x1d1bc: \ - *countptr = 2; *posptr = 2691; \ - break; \ - case 0x1d1bd: \ - *countptr = 3; *posptr = 2693; \ - break; \ - case 0x1d1be: \ - *countptr = 3; *posptr = 2696; \ - break; \ - case 0x1d1bf: \ - *countptr = 3; *posptr = 2699; \ - break; \ - case 0x1d1c0: \ - *countptr = 3; *posptr = 2702; \ - break; \ - default: \ - *countptr = 0; \ -} - diff --git a/textworld/thirdparty/glulx/cheapglk/cgwindow.c b/textworld/thirdparty/glulx/cheapglk/cgwindow.c deleted file mode 100644 index 8e3edddb..00000000 --- a/textworld/thirdparty/glulx/cheapglk/cgwindow.c +++ /dev/null @@ -1,556 +0,0 @@ -#include -#include -#include "glk.h" -#include "cheapglk.h" - -/* Since we're not using any kind of cursor movement or terminal - emulation, we're dreadfully limited in what kind of windows we - support. In fact, we can only support one window at a time, - and that must be a wintype_TextBuffer. Printing to this window - simply means printing to stdout, and reading from it means - reading from stdin. (The input code is in glk_select(), and - the output is in glk_put_char() etc.) */ - -static window_t *mainwin = NULL; - -window_t *gli_new_window(glui32 rock) -{ - window_t *win = (window_t *)malloc(sizeof(window_t)); - if (!win) - return NULL; - - win->magicnum = MAGIC_WINDOW_NUM; - win->rock = rock; - - win->str = gli_new_stream(strtype_Window, FALSE, TRUE, 0); - win->str->win = win; - win->echostr = NULL; - - win->line_request = FALSE; - win->char_request = FALSE; - win->line_request_uni = FALSE; - win->char_request_uni = FALSE; - win->linebuf = NULL; - win->linebuflen = 0; - - if (gli_register_obj) - win->disprock = (*gli_register_obj)(win, gidisp_Class_Window); - else - win->disprock.ptr = NULL; - - return win; -} - -void gli_delete_window(window_t *win) -{ - if (win->linebuf) { - if (gli_unregister_arr) { - (*gli_unregister_arr)(win->linebuf, win->linebuflen, "&+#!Cn", - win->inarrayrock); - } - win->linebuf = NULL; - } - - if (gli_unregister_obj) { - (*gli_unregister_obj)(win, gidisp_Class_Window, win->disprock); - win->disprock.ptr = NULL; - } - - win->magicnum = 0; - - /* Close window's stream. */ - gli_delete_stream(mainwin->str); - mainwin->str = NULL; - - /* The window doesn't own its echostr; closing the window doesn't close - the echostr. */ - win->echostr = NULL; - - free(win); -} - -winid_t glk_window_open(winid_t split, glui32 method, glui32 size, - glui32 wintype, glui32 rock) -{ - window_t *win; - - if (mainwin || split) { - /* This cheap library only allows you to open a window if there - aren't any other windows. But it's legal for the program to - ask for multiple windows. So we don't print a warning; we just - return NULL. */ - return NULL; - } - - if (wintype != wintype_TextBuffer) { - /* This cheap library only allows you to open text buffer windows. - Again, don't print a warning. */ - return NULL; - } - - win = gli_new_window(rock); - if (!win) { - gli_strict_warning("window_open: unable to create window."); - return NULL; - } - - mainwin = win; - return mainwin; -} - -void glk_window_close(window_t *win, stream_result_t *result) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_close: invalid id."); - return; - } - - gli_stream_fill_result(mainwin->str, result); - - gli_delete_window(mainwin); - mainwin = NULL; -} - -window_t *gli_window_get() -{ - return mainwin; -} - -winid_t glk_window_get_root() -{ - /* If there's a window, it's the root window. */ - if (mainwin) - return mainwin; - else - return NULL; -} - -winid_t glk_window_iterate(window_t *win, glui32 *rockptr) -{ - /* Iteration is really simple when there can only be one window. */ - - if (!win) { - /* They're asking for the first window. Return the main window - if it exists, or 0 if there is none. */ - if (!mainwin) { - if (rockptr) - *rockptr = 0; - return NULL; - } - - if (rockptr) - *rockptr = mainwin->rock; - return mainwin; - } - else if (win == mainwin) { - /* They're asking for the next window. There is none. */ - if (rockptr) - *rockptr = 0; - return NULL; - } - else { - gli_strict_warning("window_iterate: invalid id."); - return NULL; - } -} - -glui32 glk_window_get_rock(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_get_rock: invalid id."); - return 0; - } - - return mainwin->rock; -} - -glui32 glk_window_get_type(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_get_type: invalid id."); - return 0; - } - - return wintype_TextBuffer; -} - -winid_t glk_window_get_parent(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_get_parent: invalid id."); - return NULL; - } - - return NULL; -} - -winid_t glk_window_get_sibling(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_get_sibling: invalid id."); - return NULL; - } - - return NULL; -} - -strid_t glk_window_get_stream(window_t *win) -{ - stream_t *str; - - if (!win || win != mainwin) { - gli_strict_warning("window_get_stream: invalid id."); - return NULL; - } - - str = mainwin->str; - - return str; -} - -void glk_window_set_echo_stream(window_t *win, stream_t *str) -{ - if (!win || win != mainwin) { - gli_strict_warning("window_set_echo_stream: invalid window id."); - return; - } - - mainwin->echostr = str; -} - -strid_t glk_window_get_echo_stream(window_t *win) -{ - stream_t *str; - - if (!win || win != mainwin) { - gli_strict_warning("window_get_echo_stream: invalid id."); - return NULL; - } - - str = mainwin->echostr; - - if (str) - return str; - else - return NULL; -} - -void glk_set_window(window_t *win) -{ - if (!win) { - gli_stream_set_current(NULL); - } - else { - if (win != mainwin) { - gli_strict_warning("set_window: invalid id."); - return; - } - gli_stream_set_current(mainwin->str); - } -} - -void glk_request_char_event(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("request_char_event: invalid id"); - return; - } - - if (mainwin->char_request || mainwin->line_request) { - gli_strict_warning("request_char_event: window already has keyboard request"); - return; - } - - mainwin->char_request = TRUE; - mainwin->char_request_uni = FALSE; -} - -void glk_request_line_event(window_t *win, char *buf, glui32 maxlen, - glui32 initlen) -{ - if (!win || win != mainwin) { - gli_strict_warning("request_line_event: invalid id"); - return; - } - - if (mainwin->char_request || mainwin->line_request) { - gli_strict_warning("request_line_event: window already has keyboard request"); - return; - } - - mainwin->line_request = TRUE; - mainwin->line_request_uni = FALSE; - mainwin->linebuf = buf; - mainwin->linebuflen = maxlen; - - if (gli_register_arr) { - win->inarrayrock = (*gli_register_arr)(buf, maxlen, "&+#!Cn"); - } -} - -#ifdef GLK_MODULE_UNICODE - -void glk_request_char_event_uni(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("request_char_event: invalid id"); - return; - } - - if (mainwin->char_request || mainwin->line_request) { - gli_strict_warning("request_char_event: window already has keyboard request"); - return; - } - - mainwin->char_request = TRUE; - mainwin->char_request_uni = TRUE; -} - -void glk_request_line_event_uni(window_t *win, glui32 *buf, glui32 maxlen, - glui32 initlen) -{ - if (!win || win != mainwin) { - gli_strict_warning("request_line_event: invalid id"); - return; - } - - if (mainwin->char_request || mainwin->line_request) { - gli_strict_warning("request_line_event: window already has keyboard request"); - return; - } - - mainwin->line_request = TRUE; - mainwin->line_request_uni = TRUE; - mainwin->linebuf = buf; - mainwin->linebuflen = maxlen; - - if (gli_register_arr) { - win->inarrayrock = (*gli_register_arr)(buf, maxlen, "&+#!Iu"); - } -} - -#endif /* GLK_MODULE_UNICODE */ - -void glk_request_mouse_event(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("request_mouse_event: invalid id"); - return; - } - /* Yeah, right */ - return; -} - -void glk_cancel_char_event(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("cancel_char_event: invalid id"); - return; - } - - mainwin->char_request = FALSE; -} - -void glk_cancel_line_event(window_t *win, event_t *ev) -{ - event_t dummyev; - - if (!ev) { - ev = &dummyev; - } - - gli_event_clearevent(ev); - - if (!win || win != mainwin) { - gli_strict_warning("cancel_line_event: invalid id"); - return; - } - - if (mainwin->line_request) { - if (gli_unregister_arr) { - /* This could be a char array or a glui32 array. */ - char *typedesc = (mainwin->line_request_uni ? "&+#!Iu" : "&+#!Cn"); - (*gli_unregister_arr)(mainwin->linebuf, mainwin->linebuflen, - typedesc, mainwin->inarrayrock); - } - - mainwin->line_request = FALSE; - mainwin->linebuf = NULL; - mainwin->linebuflen = 0; - - /* Since there's only one window and no arrangement events, - once a glk_select() starts, it can only end with actual - line or character input. But it's possible that the - program will set a line input request and then immediately - cancel it. In that case, no input has occurred, so we - set val1 to zero. */ - - ev->type = evtype_LineInput; - ev->val1 = 0; - ev->val2 = 0; - ev->win = mainwin; - } -} - -void glk_cancel_mouse_event(window_t *win) -{ - if (!win || win != mainwin) { - gli_strict_warning("cancel_mouse_event: invalid id"); - return; - } - /* Yeah, right */ - return; -} - -void glk_window_clear(window_t *win) -{ - int ix; - - if (!win || win != mainwin) { - gli_strict_warning("window_clear: invalid id."); - return; - } - - if (mainwin->line_request) { - gli_strict_warning("window_clear: window has pending line request"); - return; - } - - for (ix=0; ix - http://eblong.com/zarf/glk/index.html -*/ - -#define LIBRARY_VERSION "1.0.6" - -#include "gi_dispa.h" -#include "gi_debug.h" - -/* First, we define our own TRUE and FALSE and NULL, because ANSI - is a strange world. */ -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef NULL -#define NULL 0 -#endif - -/* This macro is called whenever the library code catches an error - or illegal operation from the game program. */ - -#define gli_strict_warning(msg) \ - (printf("Glk library error: %s\n", msg)) - -/* The overall screen size, as set by command-line options. A - better implementation would check the real screen size - somehow. */ -extern int gli_screenwidth, gli_screenheight; -/* Should we assume that the terminal (or whatever is handling our - stdin/stdout) is expecting UTF-8 encoding? Normally input and output - will be the same, but they don't have to be. */ -extern int gli_utf8output, gli_utf8input; - -#if GIDEBUG_LIBRARY_SUPPORT -/* Has the user requested debug support? */ -extern int gli_debugger; -#else /* GIDEBUG_LIBRARY_SUPPORT */ -#define gli_debugger (0) -#endif /* GIDEBUG_LIBRARY_SUPPORT */ - -/* Callbacks necessary for the dispatch layer. */ -extern gidispatch_rock_t (*gli_register_obj)(void *obj, glui32 objclass); -extern void (*gli_unregister_obj)(void *obj, glui32 objclass, - gidispatch_rock_t objrock); -extern gidispatch_rock_t (*gli_register_arr)(void *array, glui32 len, - char *typecode); -extern void (*gli_unregister_arr)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock); - -/* Some useful type declarations. */ - -typedef struct glk_window_struct window_t; -typedef struct glk_stream_struct stream_t; -typedef struct glk_fileref_struct fileref_t; - -#define MAGIC_WINDOW_NUM (9876) -#define MAGIC_STREAM_NUM (8769) -#define MAGIC_FILEREF_NUM (7698) - -struct glk_window_struct { - glui32 magicnum; - glui32 rock; - gidispatch_rock_t disprock; - - stream_t *str; /* the window stream. */ - stream_t *echostr; /* the window's echo stream, if any. */ - - int line_request; - int line_request_uni; - int char_request; - int char_request_uni; - - void *linebuf; - glui32 linebuflen; - gidispatch_rock_t inarrayrock; -}; - -#define strtype_File (1) -#define strtype_Window (2) -#define strtype_Memory (3) -#define strtype_Resource (4) - -struct glk_stream_struct { - glui32 magicnum; - glui32 rock; - - int type; /* file, window, or memory stream */ - int unicode; /* one-byte or four-byte chars? Not meaningful for windows */ - - glui32 readcount, writecount; - int readable, writable; - - /* for strtype_Window */ - window_t *win; - - /* for strtype_File */ - FILE *file; - glui32 lastop; /* 0, filemode_Write, or filemode_Read */ - - /* for strtype_Resource */ - int isbinary; - - /* for strtype_Memory and strtype_Resource. Separate pointers for - one-byte and four-byte streams */ - unsigned char *buf; - unsigned char *bufptr; - unsigned char *bufend; - unsigned char *bufeof; - glui32 *ubuf; - glui32 *ubufptr; - glui32 *ubufend; - glui32 *ubufeof; - glui32 buflen; - gidispatch_rock_t arrayrock; - - gidispatch_rock_t disprock; - stream_t *next, *prev; /* in the big linked list of streams */ -}; - -struct glk_fileref_struct { - glui32 magicnum; - glui32 rock; - - char *filename; - int filetype; - int textmode; - - gidispatch_rock_t disprock; - fileref_t *next, *prev; /* in the big linked list of filerefs */ -}; - -typedef glui32 gli_case_block_t[2]; /* upper, lower */ -/* If both are 0xFFFFFFFF, you have to look at the special-case table. */ - -typedef glui32 gli_case_special_t[3]; /* upper, lower, title */ -/* Each of these points to a subarray of the unigen_special_array - (in cgunicode.c). In that subarray, element zero is the length, - and that's followed by length unicode values. */ - -typedef glui32 gli_decomp_block_t[2]; /* count, position */ -/* The position points to a subarray of the unigen_decomp_array. - If the count is zero, there is no decomposition. */ - -/* Declarations of library internal functions. */ - -extern void gli_initialize_misc(void); - -extern window_t *gli_new_window(glui32 rock); -extern void gli_delete_window(window_t *win); -extern window_t *gli_window_get(void); - -extern stream_t *gli_new_stream(int type, int readable, int writable, - glui32 rock); -extern void gli_delete_stream(stream_t *str); -extern strid_t gli_stream_open_pathname(char *pathname, int writemode, - int textmode, glui32 rock); -extern void gli_stream_set_current(stream_t *str); -extern void gli_stream_fill_result(stream_t *str, - stream_result_t *result); -extern void gli_stream_echo_line(stream_t *str, char *buf, glui32 len); -extern void gli_stream_echo_line_uni(stream_t *str, glui32 *buf, glui32 len); - -extern fileref_t *gli_new_fileref(char *filename, glui32 usage, - glui32 rock); -extern void gli_delete_fileref(fileref_t *fref); - -extern void gli_putchar_utf8(glui32 val, FILE *fl); -extern int gli_encode_utf8(glui32 val, char *buf, int len); -extern glui32 gli_parse_utf8(unsigned char *buf, glui32 buflen, - glui32 *out, glui32 outlen); - -/* A macro that I can't think of anywhere else to put it. */ - -#define gli_event_clearevent(evp) \ - ((evp)->type = evtype_None, \ - (evp)->win = NULL, \ - (evp)->val1 = 0, \ - (evp)->val2 = 0) - -/* A macro which reads and decodes one character of UTF-8. Needs no - explanation, I'm sure. - - Oh, okay. The character will be written to *chptr (so pass in "&ch", - where ch is a glui32 variable). eofcond should be a condition to - evaluate end-of-stream -- true if no more characters are readable. - nextch is a function which reads the next character; this is invoked - exactly as many times as necessary. - - val0, val1, val2, val3 should be glui32 scratch variables. The macro - needs these. Just define them, you don't need to pay attention to them - otherwise. - - The macro itself evaluates to true if ch was successfully set, or - false if something went wrong. (Not enough characters, or an - invalid byte sequence.) - - This is not the worst macro I've ever written, but I forget what the - other one was. -*/ - -#define UTF8_DECODE_INLINE(chptr, eofcond, nextch, val0, val1, val2, val3) ( \ - (eofcond ? 0 : ( \ - (((val0=nextch) < 0x80) ? (*chptr=val0, 1) : ( \ - (eofcond ? 0 : ( \ - (((val1=nextch) & 0xC0) != 0x80) ? 0 : ( \ - (((val0 & 0xE0) == 0xC0) ? (*chptr=((val0 & 0x1F) << 6) | (val1 & 0x3F), 1) : ( \ - (eofcond ? 0 : ( \ - (((val2=nextch) & 0xC0) != 0x80) ? 0 : ( \ - (((val0 & 0xF0) == 0xE0) ? (*chptr=(((val0 & 0xF)<<12) & 0x0000F000) | (((val1 & 0x3F)<<6) & 0x00000FC0) | (((val2 & 0x3F)) & 0x0000003F), 1) : ( \ - (((val0 & 0xF0) != 0xF0 || eofcond) ? 0 : (\ - (((val3=nextch) & 0xC0) != 0x80) ? 0 : (*chptr=(((val0 & 0x7)<<18) & 0x1C0000) | (((val1 & 0x3F)<<12) & 0x03F000) | (((val2 & 0x3F)<<6) & 0x000FC0) | (((val3 & 0x3F)) & 0x00003F), 1) \ - )) \ - )) \ - )) \ - )) \ - )) \ - )) \ - )) \ - )) \ - ) - -#endif /* CHEAPGLK_H */ diff --git a/textworld/thirdparty/glulx/cheapglk/gi_blorb.c b/textworld/thirdparty/glulx/cheapglk/gi_blorb.c deleted file mode 100644 index 6eb0a8f7..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_blorb.c +++ /dev/null @@ -1,767 +0,0 @@ -/* gi_blorb.c: Blorb library layer for Glk API. - gi_blorb version 1.6.1. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 1998-2017 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -#include "glk.h" -#include "gi_blorb.h" - -#ifndef NULL -#define NULL 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* The magic macro of endian conversion. */ - -#define giblorb_native4(v) \ - ( (((glui32)((v)[3]) ) & 0x000000ff) \ - | (((glui32)((v)[2]) << 8) & 0x0000ff00) \ - | (((glui32)((v)[1]) << 16) & 0x00ff0000) \ - | (((glui32)((v)[0]) << 24) & 0xff000000)) - -/* More four-byte constants. */ - -#define giblorb_ID_FORM (giblorb_make_id('F', 'O', 'R', 'M')) -#define giblorb_ID_IFRS (giblorb_make_id('I', 'F', 'R', 'S')) -#define giblorb_ID_RIdx (giblorb_make_id('R', 'I', 'd', 'x')) - -/* giblorb_chunkdesc_t: Describes one chunk of the Blorb file. */ -typedef struct giblorb_chunkdesc_struct { - glui32 type; - glui32 len; - glui32 startpos; /* start of chunk header */ - glui32 datpos; /* start of data (either startpos or startpos+8) */ - - void *ptr; /* pointer to malloc'd data, if loaded */ - int auxdatnum; /* entry in the auxsound/auxpict array; -1 if none. - This only applies to chunks that represent resources. - (Currently, only images.) */ - -} giblorb_chunkdesc_t; - -/* giblorb_resdesc_t: Describes one resource in the Blorb file. */ -typedef struct giblorb_resdesc_struct { - glui32 usage; - glui32 resnum; - glui32 chunknum; -} giblorb_resdesc_t; - -/* giblorb_auxpict_t: Extra information about an image. */ -typedef struct giblorb_auxpict_struct { - int loaded; - glui32 width; - glui32 height; - char *alttext; -} giblorb_auxpict_t; - -/* giblorb_map_t: Holds the complete description of an open Blorb file. */ -struct giblorb_map_struct { - glui32 inited; /* holds giblorb_Inited_Magic if the map structure is - valid */ - strid_t file; - - int numchunks; - giblorb_chunkdesc_t *chunks; /* list of chunk descriptors */ - - int numresources; - giblorb_resdesc_t *resources; /* list of resource descriptors */ - giblorb_resdesc_t **ressorted; /* list of pointers to descriptors - in map->resources -- sorted by usage and resource number. */ - - giblorb_auxpict_t *auxpict; -}; - -#define giblorb_Inited_Magic (0xB7012BED) - -/* Static variables. */ - -static int lib_inited = FALSE; - -static giblorb_err_t giblorb_initialize(void); -static giblorb_err_t giblorb_initialize_map(giblorb_map_t *map); -static giblorb_err_t giblorb_image_get_size_jpeg(unsigned char *ptr, glui32 length, giblorb_auxpict_t *auxpict); -static giblorb_err_t giblorb_image_get_size_png(unsigned char *ptr, glui32 length, giblorb_auxpict_t *auxpict); -static void giblorb_qsort(giblorb_resdesc_t **list, int len); -static giblorb_resdesc_t *giblorb_bsearch(giblorb_resdesc_t *sample, - giblorb_resdesc_t **list, int len); -static void *giblorb_malloc(glui32 len); -static void *giblorb_realloc(void *ptr, glui32 len); -static void giblorb_free(void *ptr); - -static giblorb_err_t giblorb_initialize() -{ - return giblorb_err_None; -} - -giblorb_err_t giblorb_create_map(strid_t file, giblorb_map_t **newmap) -{ - giblorb_err_t err; - giblorb_map_t *map; - glui32 readlen; - glui32 nextpos, totallength; - giblorb_chunkdesc_t *chunks; - int chunks_size, numchunks; - char buffer[16]; - - *newmap = NULL; - - if (!lib_inited) { - err = giblorb_initialize(); - if (err) - return err; - lib_inited = TRUE; - } - - /* First, chew through the file and index the chunks. */ - - glk_stream_set_position(file, 0, seekmode_Start); - - readlen = glk_get_buffer_stream(file, buffer, 12); - if (readlen != 12) - return giblorb_err_Read; - - if (giblorb_native4(buffer+0) != giblorb_ID_FORM) - return giblorb_err_Format; - if (giblorb_native4(buffer+8) != giblorb_ID_IFRS) - return giblorb_err_Format; - - totallength = giblorb_native4(buffer+4) + 8; - nextpos = 12; - - chunks_size = 8; - numchunks = 0; - chunks = (giblorb_chunkdesc_t *)giblorb_malloc(sizeof(giblorb_chunkdesc_t) - * chunks_size); - - while (nextpos < totallength) { - glui32 type, len; - int chunum; - giblorb_chunkdesc_t *chu; - - glk_stream_set_position(file, nextpos, seekmode_Start); - - readlen = glk_get_buffer_stream(file, buffer, 8); - if (readlen != 8) { - giblorb_free(chunks); - return giblorb_err_Read; - } - - type = giblorb_native4(buffer+0); - len = giblorb_native4(buffer+4); - - if (numchunks >= chunks_size) { - chunks_size *= 2; - chunks = (giblorb_chunkdesc_t *)giblorb_realloc(chunks, - sizeof(giblorb_chunkdesc_t) * chunks_size); - } - - chunum = numchunks; - chu = &(chunks[chunum]); - numchunks++; - - chu->type = type; - chu->startpos = nextpos; - if (type == giblorb_ID_FORM) { - chu->datpos = nextpos; - chu->len = len+8; - } - else { - chu->datpos = nextpos+8; - chu->len = len; - } - chu->ptr = NULL; - chu->auxdatnum = -1; - - nextpos = nextpos + len + 8; - if (nextpos & 1) - nextpos++; - - if (nextpos > totallength) { - giblorb_free(chunks); - return giblorb_err_Format; - } - } - - /* The basic IFF structure seems to be ok, and we have a list of - chunks. Now we allocate the map structure itself. */ - - map = (giblorb_map_t *)giblorb_malloc(sizeof(giblorb_map_t)); - if (!map) { - giblorb_free(chunks); - return giblorb_err_Alloc; - } - - map->inited = giblorb_Inited_Magic; - map->file = file; - map->chunks = chunks; - map->numchunks = numchunks; - map->resources = NULL; - map->ressorted = NULL; - map->numresources = 0; - /*map->releasenum = 0; - map->zheader = NULL; - map->resolution = NULL; - map->palettechunk = -1; - map->palette = NULL; - map->auxsound = NULL;*/ - map->auxpict = NULL; - - /* Now we do everything else involved in loading the Blorb file, - such as building resource lists. */ - - err = giblorb_initialize_map(map); - if (err) { - giblorb_destroy_map(map); - return err; - } - - *newmap = map; - return giblorb_err_None; -} - -static giblorb_err_t giblorb_initialize_map(giblorb_map_t *map) -{ - /* It is important that the map structure be kept valid during this - function. If this returns an error, giblorb_destroy_map() will - be called. */ - - int ix, jx; - giblorb_result_t chunkres; - giblorb_err_t err; - char *ptr; - glui32 len; - glui32 numres; - int gotindex = FALSE; - int pictcount = 0; - - for (ix=0; ixnumchunks; ix++) { - giblorb_chunkdesc_t *chu = &map->chunks[ix]; - - switch (chu->type) { - - case giblorb_ID_RIdx: - /* Resource index chunk: build the resource list and - sort it. */ - - if (gotindex) - return giblorb_err_Format; /* duplicate index chunk */ - err = giblorb_load_chunk_by_number(map, giblorb_method_Memory, - &chunkres, ix); - if (err) - return err; - - ptr = chunkres.data.ptr; - len = chunkres.length; - numres = giblorb_native4(ptr+0); - - if (numres) { - int ix2; - giblorb_resdesc_t *resources = NULL; - giblorb_resdesc_t **ressorted = NULL; - - if (len != numres*12+4) - return giblorb_err_Format; /* bad length field */ - - resources = (giblorb_resdesc_t *)giblorb_malloc(numres - * sizeof(giblorb_resdesc_t)); - if (!resources) { - return giblorb_err_Alloc; - } - ressorted = (giblorb_resdesc_t **)giblorb_malloc(numres - * sizeof(giblorb_resdesc_t *)); - if (!ressorted) { - giblorb_free(resources); - return giblorb_err_Alloc; - } - - ix2 = 0; - for (jx=0; jxusage = giblorb_native4(ptr+jx*12+4); - res->resnum = giblorb_native4(ptr+jx*12+8); - respos = giblorb_native4(ptr+jx*12+12); - - while (ix2 < map->numchunks - && map->chunks[ix2].startpos < respos) - ix2++; - - if (ix2 >= map->numchunks - || map->chunks[ix2].startpos != respos) { - /* start pos does not match a real chunk */ - giblorb_free(resources); - giblorb_free(ressorted); - return giblorb_err_Format; - } - - res->chunknum = ix2; - - ressorted[jx] = res; - } - - /* Sort a resource list (actually a list of pointers to - structures in map->resources.) This makes it easy - to find resources by usage and resource number. */ - giblorb_qsort(ressorted, numres); - - map->numresources = numres; - map->resources = resources; - map->ressorted = ressorted; - } - - giblorb_unload_chunk(map, ix); - gotindex = TRUE; - break; - - case giblorb_ID_JPEG: - case giblorb_ID_PNG: - chu->auxdatnum = pictcount; - pictcount++; - break; - - } - } - - if (pictcount) { - map->auxpict = (giblorb_auxpict_t *)giblorb_malloc(pictcount - * sizeof(giblorb_auxpict_t)); - if (!map->auxpict) - return giblorb_err_Alloc; - for (ix=0; ixauxpict[ix]); - auxpict->loaded = FALSE; - auxpict->width = 0; - auxpict->height = 0; - auxpict->alttext = NULL; - } - } - - return giblorb_err_None; -} - -giblorb_err_t giblorb_destroy_map(giblorb_map_t *map) -{ - int ix; - - if (!map || !map->chunks || map->inited != giblorb_Inited_Magic) - return giblorb_err_NotAMap; - - if (map->auxpict) { - giblorb_free(map->auxpict); - map->auxpict = NULL; - } - - for (ix=0; ixnumchunks; ix++) { - giblorb_chunkdesc_t *chu = &(map->chunks[ix]); - if (chu->ptr) { - giblorb_free(chu->ptr); - chu->ptr = NULL; - } - } - - if (map->chunks) { - giblorb_free(map->chunks); - map->chunks = NULL; - } - - map->numchunks = 0; - - if (map->resources) { - giblorb_free(map->resources); - map->resources = NULL; - } - - if (map->ressorted) { - giblorb_free(map->ressorted); - map->ressorted = NULL; - } - - map->numresources = 0; - - map->file = NULL; - map->inited = 0; - - giblorb_free(map); - - return giblorb_err_None; -} - -/* Chunk-handling functions. */ - -giblorb_err_t giblorb_load_chunk_by_type(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 type, - glui32 count) -{ - int ix; - - for (ix=0; ix < map->numchunks; ix++) { - if (map->chunks[ix].type == type) { - if (count == 0) - break; - count--; - } - } - - if (ix >= map->numchunks) { - return giblorb_err_NotFound; - } - - return giblorb_load_chunk_by_number(map, method, res, ix); -} - -giblorb_err_t giblorb_load_chunk_by_number(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunknum) -{ - giblorb_chunkdesc_t *chu; - - if (chunknum >= map->numchunks) - return giblorb_err_NotFound; - - chu = &(map->chunks[chunknum]); - - switch (method) { - - case giblorb_method_DontLoad: - /* do nothing */ - break; - - case giblorb_method_FilePos: - res->data.startpos = chu->datpos; - break; - - case giblorb_method_Memory: - if (!chu->ptr) { - glui32 readlen; - void *dat = giblorb_malloc(chu->len); - - if (!dat) - return giblorb_err_Alloc; - - glk_stream_set_position(map->file, chu->datpos, - seekmode_Start); - - readlen = glk_get_buffer_stream(map->file, dat, - chu->len); - if (readlen != chu->len) - return giblorb_err_Read; - - chu->ptr = dat; - } - res->data.ptr = chu->ptr; - break; - } - - res->chunknum = chunknum; - res->length = chu->len; - res->chunktype = chu->type; - - return giblorb_err_None; -} - -giblorb_err_t giblorb_load_resource(giblorb_map_t *map, glui32 method, - giblorb_result_t *res, glui32 usage, glui32 resnum) -{ - giblorb_resdesc_t sample; - giblorb_resdesc_t *found; - - sample.usage = usage; - sample.resnum = resnum; - - found = giblorb_bsearch(&sample, map->ressorted, map->numresources); - - if (!found) - return giblorb_err_NotFound; - - return giblorb_load_chunk_by_number(map, method, res, found->chunknum); -} - -giblorb_err_t giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum) -{ - giblorb_chunkdesc_t *chu; - - if (chunknum >= map->numchunks) - return giblorb_err_NotFound; - - chu = &(map->chunks[chunknum]); - - if (chu->ptr) { - giblorb_free(chu->ptr); - chu->ptr = NULL; - } - - return giblorb_err_None; -} - -giblorb_err_t giblorb_count_resources(giblorb_map_t *map, glui32 usage, - glui32 *num, glui32 *min, glui32 *max) -{ - int ix; - int count; - glui32 val; - glui32 minval, maxval; - - count = 0; - minval = 0; - maxval = 0; - - for (ix=0; ixnumresources; ix++) { - if (map->resources[ix].usage == usage) { - val = map->resources[ix].resnum; - if (count == 0) { - count++; - minval = val; - maxval = val; - } - else { - count++; - if (val < minval) - minval = val; - if (val > maxval) - maxval = val; - } - } - } - - if (num) - *num = count; - if (min) - *min = minval; - if (max) - *max = maxval; - - return giblorb_err_None; -} - -giblorb_err_t giblorb_load_image_info(giblorb_map_t *map, - glui32 resnum, giblorb_image_info_t *res) -{ - giblorb_resdesc_t sample; - giblorb_resdesc_t *found; - glui32 chunknum; - giblorb_chunkdesc_t *chu; - giblorb_auxpict_t *auxpict; - - sample.usage = giblorb_ID_Pict; - sample.resnum = resnum; - - found = giblorb_bsearch(&sample, map->ressorted, map->numresources); - - if (!found) - return giblorb_err_NotFound; - - chunknum = found->chunknum; - if (chunknum >= map->numchunks) - return giblorb_err_NotFound; - - chu = &(map->chunks[chunknum]); - if (chu->auxdatnum < 0) - return giblorb_err_NotFound; - - auxpict = &(map->auxpict[chu->auxdatnum]); - if (!auxpict->loaded) { - giblorb_result_t res; - giblorb_err_t err = giblorb_load_chunk_by_number(map, giblorb_method_Memory, &res, chunknum); - if (err) - return err; - - if (chu->type == giblorb_ID_JPEG) - err = giblorb_image_get_size_jpeg(res.data.ptr, res.length, auxpict); - else if (chu->type == giblorb_ID_PNG) - err = giblorb_image_get_size_png(res.data.ptr, res.length, auxpict); - else - err = giblorb_err_Format; - - giblorb_unload_chunk(map, chunknum); - - if (err) - return err; - - auxpict->loaded = TRUE; - } - - res->chunktype = chu->type; - res->width = auxpict->width; - res->height = auxpict->height; - res->alttext = auxpict->alttext; - return giblorb_err_None; -} - -static giblorb_err_t giblorb_image_get_size_jpeg(unsigned char *arr, glui32 length, giblorb_auxpict_t *auxpict) -{ - int pos = 0; - while (pos < length) { - unsigned char marker; - int chunklen; - if (arr[pos] != 0xFF) { - /* error: find_dimensions_jpeg: marker is not 0xFF */ - return giblorb_err_Format; - } - while (arr[pos] == 0xFF) - pos += 1; - marker = arr[pos]; - pos += 1; - if (marker == 0x01 || (marker >= 0xD0 && marker <= 0xD9)) { - /* marker type has no data */ - continue; - } - chunklen = (arr[pos+0] << 8) | (arr[pos+1]); - if (marker >= 0xC0 && marker <= 0xCF && marker != 0xC8) { - if (chunklen < 7) { - /* error: find_dimensions_jpeg: SOF block is too small */ - return giblorb_err_Format; - } - auxpict->height = (arr[pos+3] << 8) | (arr[pos+4]); - auxpict->width = (arr[pos+5] << 8) | (arr[pos+6]); - return giblorb_err_None; - } - pos += chunklen; - } - - /* error: find_dimensions_jpeg: no SOF marker found */ - return giblorb_err_Format; -} - -static giblorb_err_t giblorb_image_get_size_png(unsigned char *arr, glui32 length, giblorb_auxpict_t *auxpict) -{ - int pos = 0; - if (length < 8) - return giblorb_err_Format; - if (arr[0] != 0x89 || arr[1] != 'P' || arr[2] != 'N' || arr[3] != 'G') { - /* error: find_dimensions_png: PNG signature does not match */ - return giblorb_err_Format; - } - pos += 8; - while (pos < length) { - glui32 chunklen = giblorb_native4(arr+pos); - glui32 chunktype; - pos += 4; - chunktype = giblorb_native4(arr+pos); - pos += 4; - if (chunktype == giblorb_make_id('I', 'H', 'D', 'R')) { - auxpict->width = giblorb_native4(arr+pos); - pos += 4; - auxpict->height = giblorb_native4(arr+pos); - pos += 4; - return giblorb_err_None; - } - pos += chunklen; - pos += 4; /* skip CRC */ - } - - /* error: find_dimensions_png: no PNG header block found */ - return giblorb_err_Format; -} - -/* Sorting and searching. */ - -static int sortsplot(giblorb_resdesc_t *v1, giblorb_resdesc_t *v2) -{ - if (v1->usage < v2->usage) - return -1; - if (v1->usage > v2->usage) - return 1; - if (v1->resnum < v2->resnum) - return -1; - if (v1->resnum > v2->resnum) - return 1; - return 0; -} - -static void giblorb_qsort(giblorb_resdesc_t **list, int len) -{ - int ix, jx, res; - giblorb_resdesc_t *tmpptr, *pivot; - - if (len < 6) { - /* The list is short enough for a bubble-sort. */ - for (jx=len-1; jx>0; jx--) { - for (ix=0; ix 0) { - tmpptr = list[ix]; - list[ix] = list[ix+1]; - list[ix+1] = tmpptr; - } - } - } - } - else { - /* Split the list. */ - pivot = list[len/2]; - ix=0; - jx=len; - while (1) { - while (ix < jx-1 && sortsplot(list[ix], pivot) < 0) - ix++; - while (ix < jx-1 && sortsplot(list[jx-1], pivot) > 0) - jx--; - if (ix >= jx-1) - break; - tmpptr = list[ix]; - list[ix] = list[jx-1]; - list[jx-1] = tmpptr; - } - ix++; - /* Sort the halves. */ - giblorb_qsort(list+0, ix); - giblorb_qsort(list+ix, len-ix); - } -} - -giblorb_resdesc_t *giblorb_bsearch(giblorb_resdesc_t *sample, - giblorb_resdesc_t **list, int len) -{ - int top, bot, val, res; - - bot = 0; - top = len; - - while (bot < top) { - val = (top+bot) / 2; - res = sortsplot(list[val], sample); - if (res == 0) - return list[val]; - if (res < 0) { - bot = val+1; - } - else { - top = val; - } - } - - return NULL; -} - - -/* Boring utility functions. If your platform doesn't support ANSI - malloc(), feel free to edit these however you like. */ - -#include /* The OS-native header file -- you can edit - this too. */ - -static void *giblorb_malloc(glui32 len) -{ - return malloc(len); -} - -static void *giblorb_realloc(void *ptr, glui32 len) -{ - return realloc(ptr, len); -} - -static void giblorb_free(void *ptr) -{ - free(ptr); -} - - diff --git a/textworld/thirdparty/glulx/cheapglk/gi_blorb.h b/textworld/thirdparty/glulx/cheapglk/gi_blorb.h deleted file mode 100644 index 16dc1170..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_blorb.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef _GI_BLORB_H -#define _GI_BLORB_H - -/* gi_blorb.h: Blorb library layer for Glk API. - gi_blorb version 1.6.1. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 1998-2017 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -/* Error type and error codes */ -typedef glui32 giblorb_err_t; -#define giblorb_err_None (0) -#define giblorb_err_CompileTime (1) -#define giblorb_err_Alloc (2) -#define giblorb_err_Read (3) -#define giblorb_err_NotAMap (4) -#define giblorb_err_Format (5) -#define giblorb_err_NotFound (6) - -/* Methods for loading a chunk */ -#define giblorb_method_DontLoad (0) -#define giblorb_method_Memory (1) -#define giblorb_method_FilePos (2) - -/* Four-byte constants */ - -#define giblorb_make_id(c1, c2, c3, c4) \ - (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) - -#define giblorb_ID_Exec (giblorb_make_id('E', 'x', 'e', 'c')) -#define giblorb_ID_Snd (giblorb_make_id('S', 'n', 'd', ' ')) -#define giblorb_ID_Pict (giblorb_make_id('P', 'i', 'c', 't')) -#define giblorb_ID_Data (giblorb_make_id('D', 'a', 't', 'a')) -#define giblorb_ID_Copyright (giblorb_make_id('(', 'c', ')', ' ')) -#define giblorb_ID_AUTH (giblorb_make_id('A', 'U', 'T', 'H')) -#define giblorb_ID_ANNO (giblorb_make_id('A', 'N', 'N', 'O')) -#define giblorb_ID_TEXT (giblorb_make_id('T', 'E', 'X', 'T')) -#define giblorb_ID_BINA (giblorb_make_id('B', 'I', 'N', 'A')) -#define giblorb_ID_JPEG (giblorb_make_id('J', 'P', 'E', 'G')) -#define giblorb_ID_PNG (giblorb_make_id('P', 'N', 'G', ' ')) - -/* giblorb_map_t: Holds the complete description of an open Blorb - file. This type is opaque for normal interpreter use. */ -typedef struct giblorb_map_struct giblorb_map_t; - -/* giblorb_result_t: Result when you try to load a chunk. */ -typedef struct giblorb_result_struct { - glui32 chunknum; /* The chunk number (for use in - giblorb_unload_chunk(), etc.) */ - union { - void *ptr; /* A pointer to the data (if you used - giblorb_method_Memory) */ - glui32 startpos; /* The position in the file (if you - used giblorb_method_FilePos) */ - } data; - glui32 length; /* The length of the data */ - glui32 chunktype; /* The type of the chunk. */ -} giblorb_result_t; - -typedef struct giblorb_image_info_struct { - glui32 chunktype; - glui32 width; - glui32 height; - char *alttext; -} giblorb_image_info_t; - -extern giblorb_err_t giblorb_create_map(strid_t file, - giblorb_map_t **newmap); -extern giblorb_err_t giblorb_destroy_map(giblorb_map_t *map); - -extern giblorb_err_t giblorb_load_chunk_by_type(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunktype, - glui32 count); -extern giblorb_err_t giblorb_load_chunk_by_number(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunknum); -extern giblorb_err_t giblorb_unload_chunk(giblorb_map_t *map, - glui32 chunknum); - -extern giblorb_err_t giblorb_load_resource(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 usage, - glui32 resnum); -extern giblorb_err_t giblorb_count_resources(giblorb_map_t *map, - glui32 usage, glui32 *num, glui32 *min, glui32 *max); - -extern giblorb_err_t giblorb_load_image_info(giblorb_map_t *map, - glui32 resnum, giblorb_image_info_t *res); - -/* The following functions are part of the Glk library itself, not - the Blorb layer (whose code is in gi_blorb.c). These functions - are necessarily implemented in platform-dependent code. -*/ -extern giblorb_err_t giblorb_set_resource_map(strid_t file); -extern giblorb_map_t *giblorb_get_resource_map(void); - -#endif /* _GI_BLORB_H */ diff --git a/textworld/thirdparty/glulx/cheapglk/gi_debug.c b/textworld/thirdparty/glulx/cheapglk/gi_debug.c deleted file mode 100644 index dec31e8b..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_debug.c +++ /dev/null @@ -1,48 +0,0 @@ -/* gi_debug.c: Debug feature layer for Glk API. - gi_debug version 0.9.5. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 2014-7 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -#include "glk.h" -#include "gi_debug.h" - -#ifndef NULL -#define NULL 0 -#endif - -static gidebug_cmd_handler debug_cmd_handler = NULL; -static gidebug_cycle_handler debug_cycle_handler = NULL; - -void gidebug_debugging_available(gidebug_cmd_handler cmdhandler, gidebug_cycle_handler cyclehandler) -{ - debug_cmd_handler = cmdhandler; - debug_cycle_handler = cyclehandler; -} - -int gidebug_debugging_is_available() -{ - return (debug_cmd_handler != NULL); -} - -void gidebug_announce_cycle(gidebug_cycle cycle) -{ - if (debug_cycle_handler) - debug_cycle_handler(cycle); -} - -int gidebug_perform_command(char *cmd) -{ - if (!gidebug_debugging_is_available()) { -#if GIDEBUG_LIBRARY_SUPPORT - gidebug_output("The interpreter does not have a debug feature."); -#endif /* GIDEBUG_LIBRARY_SUPPORT */ - return 1; - } - - return debug_cmd_handler(cmd); -} - diff --git a/textworld/thirdparty/glulx/cheapglk/gi_debug.h b/textworld/thirdparty/glulx/cheapglk/gi_debug.h deleted file mode 100644 index 91ef697b..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_debug.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef _GI_DEBUG_H -#define _GI_DEBUG_H - -/* gi_debug.h: Debug feature layer for Glk API. - gi_debug version 0.9.5. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 2014-7 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. - - ------------------------------------------------ - - The debug module allows a Glk library to send out-of-band debug - commands to the game program it's linked to. The program returns - debug output to the library, which can then display it. - - (Note: 98% of the time, the "game program" is an IF interpreter - such as Glulxe. In such cases, debug commands are handled by the - interpreter; they do *not* get passed through to the interpreted - game file. Debug commands may do things like pause, inspect, or - change the state of the interpreted game.) - - As with all UI decision, the interface of the debug feature is - left up to the Glk library. Abstractly, we imagine a "debug - console" window with its own input line and scrolling text output. - - (If at all possible, avoid trying to parse debug commands out of - regular game input! The CheapGlk library does this, but that's - because it's cheap. It's much better to provide a separate window - outside the regular game UI.) - - * Configuration - - The debug feature is cooperative: both the library and the game - must support it for debug commands to work. This requires a dance - of #ifdefs to make sure that everything builds in all - configurations. - - (This is why the gi_debug.c and .h files are so tiny! All they do - is glue together Glk library and game (interpreter) code.) - - Library side: If the library supports debugging, the - GIDEBUG_LIBRARY_SUPPORT #define in this header (gi_debug.h) will - be present (not commented out). By doing this, the library - declares that it offers the functions gidebug_output() and - gidebug_pause(). - - Older Glk libraries do not include this header at all. Therefore, - a game (interpreter) should have its own configuration option. - For example, in Glulxe, you define VM_DEBUGGER when compiling with - a library that has this header and GIDEBUG_LIBRARY_SUPPORT defined. - When building with an older library (or a library which comments - out the GIDEBUG_LIBRARY_SUPPORT line), you don't define VM_DEBUGGER, - and then the interpreter does not attempt to call debug APIs. - - Game (interpreter) side: If the interpreter supports debug commands, - it should call gidebug_debugging_available() in its startup code. - (See unixstrt.c in the Glulxe source.) If it does not do this, the - library knows that debug commands cannot be handled; it should - disable or hide the "debug console" UI. - - * Game responsibilities - - When the game calls gidebug_debugging_available(), it passes two - callbacks: one to handle debug commands, and one to be notified - at various points in the game's life-cycle. (See below.) - - The command callback should execute the command. The syntax of - debug commands is entirely up to the game. Any results should be - reported via gidebug_output(), which will display them in the - debug console. - - The cycle callback is optional. The game might use it to compute - command timing and report it via gidebug_output(). - - The game may call gidebug_output() at any time; it doesn't have to - be the result of a command. For example, a game crash message could - be reported this way. However, remember that not all Glk libraries - support the debug console; even if it exists, the player might not - be watching it. Assume that game authors know about the debug system, - but players in general do not. - - The game may call gidebug_pause() to stop execution for debugging. - (Glulxe does this on any crash, or if the game hits a @debugtrap - opcode.) This function accepts and executes debugging commands - until the user signals that it's time to continue execution. - - * Library responsibilities - - The library must implement gidebug_output(), to send a line of - text to the debug console, and gidebug_pause(), to stop and handle - debug commands, as described above. - - When the user enters a command in the debug console, the library - should pass it (as a string) to gidebug_perform_command(). It - will be relayed to the game's command callback. - - The library should call gidebug_announce_cycle() at various points - in the game's life-cycle. The argument will be relayed to the - game's cycle callback. - - The library should call and pass... - - - gidebug_cycle_Start: just before glk_main() begins - - gidebug_cycle_End: when glk_exit() is called or glk_main() returns - - gidebug_cycle_InputWait: when glk_select() begins - - gidebug_cycle_InputAccept: when glk_select() returns - - gidebug_cycle_DebugPause: when gidebug_pause() begins - - gidebug_cycle_DebugUnpause: when gidebug_pause() ends - -*/ - - -/* Uncomment if the library supports a UI for debug commands. - Comment it out if the library doesn't. */ -#define GIDEBUG_LIBRARY_SUPPORT (1) - -typedef enum gidebug_cycle_enum { - gidebug_cycle_Start = 1, - gidebug_cycle_End = 2, - gidebug_cycle_InputWait = 3, - gidebug_cycle_InputAccept = 4, - gidebug_cycle_DebugPause = 5, - gidebug_cycle_DebugUnpause = 6, -} gidebug_cycle; - -typedef int (*gidebug_cmd_handler)(char *text); -typedef void (*gidebug_cycle_handler)(int cycle); - -/* The gidebug-layer functions are always available (assuming this header - exists!) The game should have a compile-time option (e.g. VM_DEBUGGER) - so as not to rely on this header. */ - -/* The game calls this if it offers debug commands. (The library may - or may not make use of them.) - - The cmdhandler argument must be a function that accepts a debug - command (a UTF-8 string) and executes it, displaying output via - gidebug_output(). The function should return nonzero for a "continue" - command (only relevant inside gidebug_pause()). - - The cyclehandler argument should be a function to be notified - when the game starts, stops, and blocks for input. (This is optional; - pass NULL if not needed.) -*/ -extern void gidebug_debugging_available(gidebug_cmd_handler cmdhandler, gidebug_cycle_handler cyclehandler); - -/* The library calls this to check whether the game accepts debug commands. - (Returns nonzero if the game has called gidebug_debugging_available(). - If this returns zero, the library should disable or hide the debug - console.) -*/ -extern int gidebug_debugging_is_available(void); - -/* The library calls this when the user enters a command in the debug - console. The command will be passed along to the game's cmdhandler, - if one was supplied. This will return nonzero for a "continue" - command (only relevant inside gidebug_pause()). - - This may only be called when the game is waiting for input! This - means one of two circumstances: while inside glk_select(), or - while inside gidebug_pause(). If you call it at any other time, - you've made some kind of horrible threading mistake. -*/ -extern int gidebug_perform_command(char *cmd); - -/* The library calls this at various points in the game's life-cycle. - The argument will be passed along to the game's cyclehandler, - if one was supplied. -*/ -extern void gidebug_announce_cycle(gidebug_cycle cycle); - -#if GIDEBUG_LIBRARY_SUPPORT - -/* These functions must be implemented in the library. (If the library - has declared debug support.) */ - -/* Send a line of text to the debug console. The text will be a single line - (no newlines), in UTF-8. -*/ -extern void gidebug_output(char *text); - -/* Block and wait for debug commands. The library should accept debug - commands and pass them to gidebug_perform_command(), repeatedly, - until that function returns nonzero. It may also stop of its own - accord (say, when an "unpause" menu item is triggered). - - This should call gidebug_announce_cycle(gidebug_cycle_DebugPause) - upon entry, and the same with gidebug_cycle_DebugUnpause upon exit. -*/ -extern void gidebug_pause(void); - -#endif /* GIDEBUG_LIBRARY_SUPPORT */ - -#endif /* _GI_DEBUG_H */ diff --git a/textworld/thirdparty/glulx/cheapglk/gi_dispa.c b/textworld/thirdparty/glulx/cheapglk/gi_dispa.c deleted file mode 100644 index f33e427d..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_dispa.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* gi_dispa.c: Dispatch layer for Glk API, version 0.7.5. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 1998-2017 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -/* This code should be linked into every Glk library, without change. - Get the latest version from the URL above. */ - -#include "glk.h" -#include "gi_dispa.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define NUMCLASSES \ - (sizeof(class_table) / sizeof(gidispatch_intconst_t)) - -#define NUMINTCONSTANTS \ - (sizeof(intconstant_table) / sizeof(gidispatch_intconst_t)) - -#define NUMFUNCTIONS \ - (sizeof(function_table) / sizeof(gidispatch_function_t)) - -/* The constants in this table must be ordered alphabetically. */ -static gidispatch_intconst_t class_table[] = { - { "fileref", (2) }, /* "Qc" */ - { "schannel", (3) }, /* "Qd" */ - { "stream", (1) }, /* "Qb" */ - { "window", (0) }, /* "Qa" */ -}; - -/* The constants in this table must be ordered alphabetically. */ -static gidispatch_intconst_t intconstant_table[] = { - { "evtype_Arrange", (5) }, - { "evtype_CharInput", (2) }, - { "evtype_Hyperlink", (8) }, - { "evtype_LineInput", (3) }, - { "evtype_MouseInput", (4) }, - { "evtype_None", (0) }, - { "evtype_Redraw", (6) }, - { "evtype_SoundNotify", (7) }, - { "evtype_Timer", (1) }, - { "evtype_VolumeNotify", (9) }, - - { "filemode_Read", (0x02) }, - { "filemode_ReadWrite", (0x03) }, - { "filemode_Write", (0x01) }, - { "filemode_WriteAppend", (0x05) }, - - { "fileusage_BinaryMode", (0x000) }, - { "fileusage_Data", (0x00) }, - { "fileusage_InputRecord", (0x03) }, - { "fileusage_SavedGame", (0x01) }, - { "fileusage_TextMode", (0x100) }, - { "fileusage_Transcript", (0x02) }, - { "fileusage_TypeMask", (0x0f) }, - - { "gestalt_CharInput", (1) }, - { "gestalt_CharOutput", (3) }, - { "gestalt_CharOutput_ApproxPrint", (1) }, - { "gestalt_CharOutput_CannotPrint", (0) }, - { "gestalt_CharOutput_ExactPrint", (2) }, - { "gestalt_DateTime", (20) }, - { "gestalt_DrawImage", (7) }, - { "gestalt_Graphics", (6) }, - { "gestalt_GraphicsCharInput", (23) }, - { "gestalt_GraphicsTransparency", (14) }, - { "gestalt_HyperlinkInput", (12) }, - { "gestalt_Hyperlinks", (11) }, - { "gestalt_LineInput", (2) }, - { "gestalt_LineInputEcho", (17) }, - { "gestalt_LineTerminatorKey", (19) }, - { "gestalt_LineTerminators", (18) }, - { "gestalt_MouseInput", (4) }, - { "gestalt_ResourceStream", (22) }, - { "gestalt_Sound", (8) }, - { "gestalt_Sound2", (21) }, - { "gestalt_SoundMusic", (13) }, - { "gestalt_SoundNotify", (10) }, - { "gestalt_SoundVolume", (9) }, - { "gestalt_Timer", (5) }, - { "gestalt_Unicode", (15) }, - { "gestalt_UnicodeNorm", (16) }, - { "gestalt_Version", (0) }, - - { "imagealign_InlineCenter", (0x03) }, - { "imagealign_InlineDown", (0x02) }, - { "imagealign_MarginLeft", (0x04) }, - { "imagealign_MarginRight", (0x05) }, - { "imagealign_InlineUp", (0x01) }, - - { "keycode_Delete", (0xfffffff9) }, - { "keycode_Down", (0xfffffffb) }, - { "keycode_End", (0xfffffff3) }, - { "keycode_Escape", (0xfffffff8) }, - { "keycode_Func1", (0xffffffef) }, - { "keycode_Func10", (0xffffffe6) }, - { "keycode_Func11", (0xffffffe5) }, - { "keycode_Func12", (0xffffffe4) }, - { "keycode_Func2", (0xffffffee) }, - { "keycode_Func3", (0xffffffed) }, - { "keycode_Func4", (0xffffffec) }, - { "keycode_Func5", (0xffffffeb) }, - { "keycode_Func6", (0xffffffea) }, - { "keycode_Func7", (0xffffffe9) }, - { "keycode_Func8", (0xffffffe8) }, - { "keycode_Func9", (0xffffffe7) }, - { "keycode_Home", (0xfffffff4) }, - { "keycode_Left", (0xfffffffe) }, - { "keycode_MAXVAL", (28) }, - { "keycode_PageDown", (0xfffffff5) }, - { "keycode_PageUp", (0xfffffff6) }, - { "keycode_Return", (0xfffffffa) }, - { "keycode_Right", (0xfffffffd) }, - { "keycode_Tab", (0xfffffff7) }, - { "keycode_Unknown", (0xffffffff) }, - { "keycode_Up", (0xfffffffc) }, - - { "seekmode_Current", (1) }, - { "seekmode_End", (2) }, - { "seekmode_Start", (0) }, - - { "style_Alert", (5) }, - { "style_BlockQuote", (7) }, - { "style_Emphasized", (1) }, - { "style_Header", (3) }, - { "style_Input", (8) }, - { "style_NUMSTYLES", (11) }, - { "style_Normal", (0) }, - { "style_Note", (6) }, - { "style_Preformatted", (2) }, - { "style_Subheader", (4) }, - { "style_User1", (9) }, - { "style_User2", (10) }, - { "stylehint_BackColor", (8) }, - { "stylehint_Indentation", (0) }, - { "stylehint_Justification", (2) }, - { "stylehint_NUMHINTS", (10) }, - { "stylehint_Oblique", (5) }, - { "stylehint_ParaIndentation", (1) }, - { "stylehint_Proportional", (6) }, - { "stylehint_ReverseColor", (9) }, - { "stylehint_Size", (3) }, - { "stylehint_TextColor", (7) }, - { "stylehint_Weight", (4) }, - { "stylehint_just_Centered", (2) }, - { "stylehint_just_LeftFlush", (0) }, - { "stylehint_just_LeftRight", (1) }, - { "stylehint_just_RightFlush", (3) }, - - { "winmethod_Above", (0x02) }, - { "winmethod_Below", (0x03) }, - { "winmethod_Border", (0x000) }, - { "winmethod_BorderMask", (0x100) }, - { "winmethod_DirMask", (0x0f) }, - { "winmethod_DivisionMask", (0xf0) }, - { "winmethod_Fixed", (0x10) }, - { "winmethod_Left", (0x00) }, - { "winmethod_NoBorder", (0x100) }, - { "winmethod_Proportional", (0x20) }, - { "winmethod_Right", (0x01) }, - - { "wintype_AllTypes", (0) }, - { "wintype_Blank", (2) }, - { "wintype_Graphics", (5) }, - { "wintype_Pair", (1) }, - { "wintype_TextBuffer", (3) }, - { "wintype_TextGrid", (4) }, -}; - -/* The functions in this table must be ordered by id. */ -static gidispatch_function_t function_table[] = { - { 0x0001, glk_exit, "exit" }, - { 0x0002, glk_set_interrupt_handler, "set_interrupt_handler" }, - { 0x0003, glk_tick, "tick" }, - { 0x0004, glk_gestalt, "gestalt" }, - { 0x0005, glk_gestalt_ext, "gestalt_ext" }, - { 0x0020, glk_window_iterate, "window_iterate" }, - { 0x0021, glk_window_get_rock, "window_get_rock" }, - { 0x0022, glk_window_get_root, "window_get_root" }, - { 0x0023, glk_window_open, "window_open" }, - { 0x0024, glk_window_close, "window_close" }, - { 0x0025, glk_window_get_size, "window_get_size" }, - { 0x0026, glk_window_set_arrangement, "window_set_arrangement" }, - { 0x0027, glk_window_get_arrangement, "window_get_arrangement" }, - { 0x0028, glk_window_get_type, "window_get_type" }, - { 0x0029, glk_window_get_parent, "window_get_parent" }, - { 0x002A, glk_window_clear, "window_clear" }, - { 0x002B, glk_window_move_cursor, "window_move_cursor" }, - { 0x002C, glk_window_get_stream, "window_get_stream" }, - { 0x002D, glk_window_set_echo_stream, "window_set_echo_stream" }, - { 0x002E, glk_window_get_echo_stream, "window_get_echo_stream" }, - { 0x002F, glk_set_window, "set_window" }, - { 0x0030, glk_window_get_sibling, "window_get_sibling" }, - { 0x0040, glk_stream_iterate, "stream_iterate" }, - { 0x0041, glk_stream_get_rock, "stream_get_rock" }, - { 0x0042, glk_stream_open_file, "stream_open_file" }, - { 0x0043, glk_stream_open_memory, "stream_open_memory" }, - { 0x0044, glk_stream_close, "stream_close" }, - { 0x0045, glk_stream_set_position, "stream_set_position" }, - { 0x0046, glk_stream_get_position, "stream_get_position" }, - { 0x0047, glk_stream_set_current, "stream_set_current" }, - { 0x0048, glk_stream_get_current, "stream_get_current" }, - { 0x0060, glk_fileref_create_temp, "fileref_create_temp" }, - { 0x0061, glk_fileref_create_by_name, "fileref_create_by_name" }, - { 0x0062, glk_fileref_create_by_prompt, "fileref_create_by_prompt" }, - { 0x0063, glk_fileref_destroy, "fileref_destroy" }, - { 0x0064, glk_fileref_iterate, "fileref_iterate" }, - { 0x0065, glk_fileref_get_rock, "fileref_get_rock" }, - { 0x0066, glk_fileref_delete_file, "fileref_delete_file" }, - { 0x0067, glk_fileref_does_file_exist, "fileref_does_file_exist" }, - { 0x0068, glk_fileref_create_from_fileref, "fileref_create_from_fileref" }, - { 0x0080, glk_put_char, "put_char" }, - { 0x0081, glk_put_char_stream, "put_char_stream" }, - { 0x0082, glk_put_string, "put_string" }, - { 0x0083, glk_put_string_stream, "put_string_stream" }, - { 0x0084, glk_put_buffer, "put_buffer" }, - { 0x0085, glk_put_buffer_stream, "put_buffer_stream" }, - { 0x0086, glk_set_style, "set_style" }, - { 0x0087, glk_set_style_stream, "set_style_stream" }, - { 0x0090, glk_get_char_stream, "get_char_stream" }, - { 0x0091, glk_get_line_stream, "get_line_stream" }, - { 0x0092, glk_get_buffer_stream, "get_buffer_stream" }, - { 0x00A0, glk_char_to_lower, "char_to_lower" }, - { 0x00A1, glk_char_to_upper, "char_to_upper" }, - { 0x00B0, glk_stylehint_set, "stylehint_set" }, - { 0x00B1, glk_stylehint_clear, "stylehint_clear" }, - { 0x00B2, glk_style_distinguish, "style_distinguish" }, - { 0x00B3, glk_style_measure, "style_measure" }, - { 0x00C0, glk_select, "select" }, - { 0x00C1, glk_select_poll, "select_poll" }, - { 0x00D0, glk_request_line_event, "request_line_event" }, - { 0x00D1, glk_cancel_line_event, "cancel_line_event" }, - { 0x00D2, glk_request_char_event, "request_char_event" }, - { 0x00D3, glk_cancel_char_event, "cancel_char_event" }, - { 0x00D4, glk_request_mouse_event, "request_mouse_event" }, - { 0x00D5, glk_cancel_mouse_event, "cancel_mouse_event" }, - { 0x00D6, glk_request_timer_events, "request_timer_events" }, -#ifdef GLK_MODULE_IMAGE - { 0x00E0, glk_image_get_info, "image_get_info" }, - { 0x00E1, glk_image_draw, "image_draw" }, - { 0x00E2, glk_image_draw_scaled, "image_draw_scaled" }, - { 0x00E8, glk_window_flow_break, "window_flow_break" }, - { 0x00E9, glk_window_erase_rect, "window_erase_rect" }, - { 0x00EA, glk_window_fill_rect, "window_fill_rect" }, - { 0x00EB, glk_window_set_background_color, "window_set_background_color" }, -#endif /* GLK_MODULE_IMAGE */ -#ifdef GLK_MODULE_SOUND - { 0x00F0, glk_schannel_iterate, "schannel_iterate" }, - { 0x00F1, glk_schannel_get_rock, "schannel_get_rock" }, - { 0x00F2, glk_schannel_create, "schannel_create" }, - { 0x00F3, glk_schannel_destroy, "schannel_destroy" }, - { 0x00F8, glk_schannel_play, "schannel_play" }, - { 0x00F9, glk_schannel_play_ext, "schannel_play_ext" }, - { 0x00FA, glk_schannel_stop, "schannel_stop" }, - { 0x00FB, glk_schannel_set_volume, "schannel_set_volume" }, - { 0x00FC, glk_sound_load_hint, "sound_load_hint" }, -#ifdef GLK_MODULE_SOUND2 - { 0x00F4, glk_schannel_create_ext, "schannel_create_ext" }, - { 0x00F7, glk_schannel_play_multi, "schannel_play_multi" }, - { 0x00FD, glk_schannel_set_volume_ext, "schannel_set_volume_ext" }, - { 0x00FE, glk_schannel_pause, "schannel_pause" }, - { 0x00FF, glk_schannel_unpause, "schannel_unpause" }, -#endif /* GLK_MODULE_SOUND2 */ -#endif /* GLK_MODULE_SOUND */ -#ifdef GLK_MODULE_HYPERLINKS - { 0x0100, glk_set_hyperlink, "set_hyperlink" }, - { 0x0101, glk_set_hyperlink_stream, "set_hyperlink_stream" }, - { 0x0102, glk_request_hyperlink_event, "request_hyperlink_event" }, - { 0x0103, glk_cancel_hyperlink_event, "cancel_hyperlink_event" }, -#endif /* GLK_MODULE_HYPERLINKS */ -#ifdef GLK_MODULE_UNICODE - { 0x0120, glk_buffer_to_lower_case_uni, "buffer_to_lower_case_uni" }, - { 0x0121, glk_buffer_to_upper_case_uni, "buffer_to_upper_case_uni" }, - { 0x0122, glk_buffer_to_title_case_uni, "buffer_to_title_case_uni" }, - { 0x0128, glk_put_char_uni, "put_char_uni" }, - { 0x0129, glk_put_string_uni, "put_string_uni" }, - { 0x012A, glk_put_buffer_uni, "put_buffer_uni" }, - { 0x012B, glk_put_char_stream_uni, "put_char_stream_uni" }, - { 0x012C, glk_put_string_stream_uni, "put_string_stream_uni" }, - { 0x012D, glk_put_buffer_stream_uni, "put_buffer_stream_uni" }, - { 0x0130, glk_get_char_stream_uni, "get_char_stream_uni" }, - { 0x0131, glk_get_buffer_stream_uni, "get_buffer_stream_uni" }, - { 0x0132, glk_get_line_stream_uni, "get_line_stream_uni" }, - { 0x0138, glk_stream_open_file_uni, "stream_open_file_uni" }, - { 0x0139, glk_stream_open_memory_uni, "stream_open_memory_uni" }, - { 0x0140, glk_request_char_event_uni, "request_char_event_uni" }, - { 0x0141, glk_request_line_event_uni, "request_line_event_uni" }, -#endif /* GLK_MODULE_UNICODE */ -#ifdef GLK_MODULE_UNICODE_NORM - { 0x0123, glk_buffer_canon_decompose_uni, "buffer_canon_decompose_uni" }, - { 0x0124, glk_buffer_canon_normalize_uni, "buffer_canon_normalize_uni" }, -#endif /* GLK_MODULE_UNICODE_NORM */ -#ifdef GLK_MODULE_LINE_ECHO - { 0x0150, glk_set_echo_line_event, "set_echo_line_event" }, -#endif /* GLK_MODULE_LINE_ECHO */ -#ifdef GLK_MODULE_LINE_TERMINATORS - { 0x0151, glk_set_terminators_line_event, "set_terminators_line_event" }, -#endif /* GLK_MODULE_LINE_TERMINATORS */ -#ifdef GLK_MODULE_DATETIME - { 0x0160, glk_current_time, "current_time" }, - { 0x0161, glk_current_simple_time, "current_simple_time" }, - { 0x0168, glk_time_to_date_utc, "time_to_date_utc" }, - { 0x0169, glk_time_to_date_local, "time_to_date_local" }, - { 0x016A, glk_simple_time_to_date_utc, "simple_time_to_date_utc" }, - { 0x016B, glk_simple_time_to_date_local, "simple_time_to_date_local" }, - { 0x016C, glk_date_to_time_utc, "date_to_time_utc" }, - { 0x016D, glk_date_to_time_local, "date_to_time_local" }, - { 0x016E, glk_date_to_simple_time_utc, "date_to_simple_time_utc" }, - { 0x016F, glk_date_to_simple_time_local, "date_to_simple_time_local" }, -#endif /* GLK_MODULE_DATETIME */ -#ifdef GLK_MODULE_RESOURCE_STREAM - { 0x0049, glk_stream_open_resource, "stream_open_resource" }, - { 0x013A, glk_stream_open_resource_uni, "stream_open_resource_uni" }, -#endif /* GLK_MODULE_RESOURCE_STREAM */ -}; - -glui32 gidispatch_count_classes() -{ - return NUMCLASSES; -} - -gidispatch_intconst_t *gidispatch_get_class(glui32 index) -{ - if (index >= NUMCLASSES) - return NULL; - return &(class_table[index]); -} - -glui32 gidispatch_count_intconst() -{ - return NUMINTCONSTANTS; -} - -gidispatch_intconst_t *gidispatch_get_intconst(glui32 index) -{ - if (index >= NUMINTCONSTANTS) - return NULL; - return &(intconstant_table[index]); -} - -glui32 gidispatch_count_functions() -{ - return NUMFUNCTIONS; -} - -gidispatch_function_t *gidispatch_get_function(glui32 index) -{ - if (index >= NUMFUNCTIONS) - return NULL; - return &(function_table[index]); -} - -gidispatch_function_t *gidispatch_get_function_by_id(glui32 id) -{ - int top, bot, val; - gidispatch_function_t *func; - - bot = 0; - top = NUMFUNCTIONS; - - while (1) { - val = (top+bot) / 2; - func = &(function_table[val]); - if (func->id == id) - return func; - if (bot >= top-1) - break; - if (func->id < id) { - bot = val+1; - } - else { - top = val; - } - } - - return NULL; -} - -char *gidispatch_prototype(glui32 funcnum) -{ - switch (funcnum) { - case 0x0001: /* exit */ - return "0:"; - case 0x0002: /* set_interrupt_handler */ - /* cannot be invoked through dispatch layer */ - return NULL; - case 0x0003: /* tick */ - return "0:"; - case 0x0004: /* gestalt */ - return "3IuIu:Iu"; - case 0x0005: /* gestalt_ext */ - return "4IuIu&#Iu:Iu"; - case 0x0020: /* window_iterate */ - return "3Qa+#Cn:"; - case 0x0085: /* put_buffer_stream */ - return "2Qb>+#Cn:"; - case 0x0086: /* set_style */ - return "1Iu:"; - case 0x0087: /* set_style_stream */ - return "2QbIu:"; - case 0x0090: /* get_char_stream */ - return "2Qb:Is"; - case 0x0091: /* get_line_stream */ - return "3Qb<+#Cn:Iu"; - case 0x0092: /* get_buffer_stream */ - return "3Qb<+#Cn:Iu"; - case 0x00A0: /* char_to_lower */ - return "2Cu:Cu"; - case 0x00A1: /* char_to_upper */ - return "2Cu:Cu"; - case 0x00B0: /* stylehint_set */ - return "4IuIuIuIs:"; - case 0x00B1: /* stylehint_clear */ - return "3IuIuIu:"; - case 0x00B2: /* style_distinguish */ - return "4QaIuIu:Iu"; - case 0x00B3: /* style_measure */ - return "5QaIuIu+#Qd>+#IuIu:Iu"; - case 0x00FD: /* schannel_set_volume_ext */ - return "4QdIuIuIu:"; - case 0x00FE: /* schannel_pause */ - return "1Qd:"; - case 0x00FF: /* schannel_unpause */ - return "1Qd:"; -#endif /* GLK_MODULE_SOUND2 */ -#endif /* GLK_MODULE_SOUND */ - -#ifdef GLK_MODULE_HYPERLINKS - case 0x0100: /* set_hyperlink */ - return "1Iu:"; - case 0x0101: /* set_hyperlink_stream */ - return "2QbIu:"; - case 0x0102: /* request_hyperlink_event */ - return "1Qa:"; - case 0x0103: /* cancel_hyperlink_event */ - return "1Qa:"; -#endif /* GLK_MODULE_HYPERLINKS */ - -#ifdef GLK_MODULE_UNICODE - case 0x0120: /* buffer_to_lower_case_uni */ - return "3&+#IuIu:Iu"; - case 0x0121: /* buffer_to_upper_case_uni */ - return "3&+#IuIu:Iu"; - case 0x0122: /* buffer_to_title_case_uni */ - return "4&+#IuIuIu:Iu"; - case 0x0128: /* put_char_uni */ - return "1Iu:"; - case 0x0129: /* put_string_uni */ - return "1U:"; - case 0x012A: /* put_buffer_uni */ - return "1>+#Iu:"; - case 0x012B: /* put_char_stream_uni */ - return "2QbIu:"; - case 0x012C: /* put_string_stream_uni */ - return "2QbU:"; - case 0x012D: /* put_buffer_stream_uni */ - return "2Qb>+#Iu:"; - case 0x0130: /* get_char_stream_uni */ - return "2Qb:Is"; - case 0x0131: /* get_buffer_stream_uni */ - return "3Qb<+#Iu:Iu"; - case 0x0132: /* get_line_stream_uni */ - return "3Qb<+#Iu:Iu"; - case 0x0138: /* stream_open_file_uni */ - return "4QcIuIu:Qb"; - case 0x0139: /* stream_open_memory_uni */ - return "4&#!IuIuIu:Qb"; - case 0x0140: /* request_char_event_uni */ - return "1Qa:"; - case 0x0141: /* request_line_event_uni */ - return "3Qa&+#!IuIu:"; -#endif /* GLK_MODULE_UNICODE */ - -#ifdef GLK_MODULE_UNICODE_NORM - case 0x0123: /* buffer_canon_decompose_uni */ - return "3&+#IuIu:Iu"; - case 0x0124: /* buffer_canon_normalize_uni */ - return "3&+#IuIu:Iu"; -#endif /* GLK_MODULE_UNICODE_NORM */ - -#ifdef GLK_MODULE_LINE_ECHO - case 0x0150: /* set_echo_line_event */ - return "2QaIu:"; -#endif /* GLK_MODULE_LINE_ECHO */ - -#ifdef GLK_MODULE_LINE_TERMINATORS - case 0x0151: /* set_terminators_line_event */ - return "2Qa>#Iu:"; -#endif /* GLK_MODULE_LINE_TERMINATORS */ - -#ifdef GLK_MODULE_DATETIME - case 0x0160: /* current_time */ - return "1<+[3IsIuIs]:"; - case 0x0161: /* current_simple_time */ - return "2Iu:Is"; - case 0x0168: /* time_to_date_utc */ - return "2>+[3IsIuIs]<+[8IsIsIsIsIsIsIsIs]:"; - case 0x0169: /* time_to_date_local */ - return "2>+[3IsIuIs]<+[8IsIsIsIsIsIsIsIs]:"; - case 0x016A: /* simple_time_to_date_utc */ - return "3IsIu<+[8IsIsIsIsIsIsIsIs]:"; - case 0x016B: /* simple_time_to_date_local */ - return "3IsIu<+[8IsIsIsIsIsIsIsIs]:"; - case 0x016C: /* date_to_time_utc */ - return "2>+[8IsIsIsIsIsIsIsIs]<+[3IsIuIs]:"; - case 0x016D: /* date_to_time_local */ - return "2>+[8IsIsIsIsIsIsIsIs]<+[3IsIuIs]:"; - case 0x016E: /* date_to_simple_time_utc */ - return "3>+[8IsIsIsIsIsIsIsIs]Iu:Is"; - case 0x016F: /* date_to_simple_time_local */ - return "3>+[8IsIsIsIsIsIsIsIs]Iu:Is"; -#endif /* GLK_MODULE_DATETIME */ - -#ifdef GLK_MODULE_RESOURCE_STREAM - case 0x0049: /* stream_open_resource */ - return "3IuIu:Qb"; - case 0x013A: /* stream_open_resource_uni */ - return "3IuIu:Qb"; -#endif /* GLK_MODULE_RESOURCE_STREAM */ - -#ifdef GLK_EXTEND_PROTOTYPE - GLK_EXTEND_PROTOTYPE -#endif /* GLK_EXTEND_PROTOTYPE */ - - default: - return NULL; - } -} - -void gidispatch_call(glui32 funcnum, glui32 numargs, gluniversal_t *arglist) -{ - switch (funcnum) { - case 0x0001: /* exit */ - glk_exit(); - break; - case 0x0002: /* set_interrupt_handler */ - /* cannot be invoked through dispatch layer */ - break; - case 0x0003: /* tick */ - glk_tick(); - break; - case 0x0004: /* gestalt */ - arglist[3].uint = glk_gestalt(arglist[0].uint, arglist[1].uint); - break; - case 0x0005: /* gestalt_ext */ - if (arglist[2].ptrflag) { - arglist[6].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint, - arglist[3].array, arglist[4].uint); - } - else { - arglist[4].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint, - NULL, 0); - } - break; - case 0x0020: /* window_iterate */ - if (arglist[1].ptrflag) - arglist[4].opaqueref = glk_window_iterate(arglist[0].opaqueref, &arglist[2].uint); - else - arglist[3].opaqueref = glk_window_iterate(arglist[0].opaqueref, NULL); - break; - case 0x0021: /* window_get_rock */ - arglist[2].uint = glk_window_get_rock(arglist[0].opaqueref); - break; - case 0x0022: /* window_get_root */ - arglist[1].opaqueref = glk_window_get_root(); - break; - case 0x0023: /* window_open */ - arglist[6].opaqueref = glk_window_open(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint, arglist[3].uint, arglist[4].uint); - break; - case 0x0024: /* window_close */ - if (arglist[1].ptrflag) { - stream_result_t dat; - glk_window_close(arglist[0].opaqueref, &dat); - arglist[2].uint = dat.readcount; - arglist[3].uint = dat.writecount; - } - else { - glk_window_close(arglist[0].opaqueref, NULL); - } - break; - case 0x0025: /* window_get_size */ - { - int ix = 1; - glui32 *ptr1, *ptr2; - if (!arglist[ix].ptrflag) { - ptr1 = NULL; - } - else { - ix++; - ptr1 = &(arglist[ix].uint); - } - ix++; - if (!arglist[ix].ptrflag) { - ptr2 = NULL; - } - else { - ix++; - ptr2 = &(arglist[ix].uint); - } - ix++; - glk_window_get_size(arglist[0].opaqueref, ptr1, ptr2); - } - break; - case 0x0026: /* window_set_arrangement */ - glk_window_set_arrangement(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint, arglist[3].opaqueref); - break; - case 0x0027: /* window_get_arrangement */ - { - int ix = 1; - glui32 *ptr1, *ptr2; - winid_t *ptr3; - if (!arglist[ix].ptrflag) { - ptr1 = NULL; - } - else { - ix++; - ptr1 = &(arglist[ix].uint); - } - ix++; - if (!arglist[ix].ptrflag) { - ptr2 = NULL; - } - else { - ix++; - ptr2 = &(arglist[ix].uint); - } - ix++; - if (!arglist[ix].ptrflag) { - ptr3 = NULL; - } - else { - ix++; - ptr3 = (winid_t *)(&(arglist[ix].opaqueref)); - } - ix++; - glk_window_get_arrangement(arglist[0].opaqueref, ptr1, ptr2, ptr3); - } - break; - case 0x0028: /* window_get_type */ - arglist[2].uint = glk_window_get_type(arglist[0].opaqueref); - break; - case 0x0029: /* window_get_parent */ - arglist[2].opaqueref = glk_window_get_parent(arglist[0].opaqueref); - break; - case 0x002A: /* window_clear */ - glk_window_clear(arglist[0].opaqueref); - break; - case 0x002B: /* window_move_cursor */ - glk_window_move_cursor(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint); - break; - case 0x002C: /* window_get_stream */ - arglist[2].opaqueref = glk_window_get_stream(arglist[0].opaqueref); - break; - case 0x002D: /* window_set_echo_stream */ - glk_window_set_echo_stream(arglist[0].opaqueref, arglist[1].opaqueref); - break; - case 0x002E: /* window_get_echo_stream */ - arglist[2].opaqueref = glk_window_get_echo_stream(arglist[0].opaqueref); - break; - case 0x002F: /* set_window */ - glk_set_window(arglist[0].opaqueref); - break; - case 0x0030: /* window_get_sibling */ - arglist[2].opaqueref = glk_window_get_sibling(arglist[0].opaqueref); - break; - case 0x0040: /* stream_iterate */ - if (arglist[1].ptrflag) - arglist[4].opaqueref = glk_stream_iterate(arglist[0].opaqueref, &arglist[2].uint); - else - arglist[3].opaqueref = glk_stream_iterate(arglist[0].opaqueref, NULL); - break; - case 0x0041: /* stream_get_rock */ - arglist[2].uint = glk_stream_get_rock(arglist[0].opaqueref); - break; - case 0x0042: /* stream_open_file */ - arglist[4].opaqueref = glk_stream_open_file(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint); - break; - case 0x0043: /* stream_open_memory */ - if (arglist[0].ptrflag) - arglist[6].opaqueref = glk_stream_open_memory(arglist[1].array, - arglist[2].uint, arglist[3].uint, arglist[4].uint); - else - arglist[4].opaqueref = glk_stream_open_memory(NULL, - 0, arglist[1].uint, arglist[2].uint); - break; - case 0x0044: /* stream_close */ - if (arglist[1].ptrflag) { - stream_result_t dat; - glk_stream_close(arglist[0].opaqueref, &dat); - arglist[2].uint = dat.readcount; - arglist[3].uint = dat.writecount; - } - else { - glk_stream_close(arglist[0].opaqueref, NULL); - } - break; - case 0x0045: /* stream_set_position */ - glk_stream_set_position(arglist[0].opaqueref, arglist[1].sint, - arglist[2].uint); - break; - case 0x0046: /* stream_get_position */ - arglist[2].uint = glk_stream_get_position(arglist[0].opaqueref); - break; - case 0x0047: /* stream_set_current */ - glk_stream_set_current(arglist[0].opaqueref); - break; - case 0x0048: /* stream_get_current */ - arglist[1].opaqueref = glk_stream_get_current(); - break; - case 0x0060: /* fileref_create_temp */ - arglist[3].opaqueref = glk_fileref_create_temp(arglist[0].uint, - arglist[1].uint); - break; - case 0x0061: /* fileref_create_by_name */ - arglist[4].opaqueref = glk_fileref_create_by_name(arglist[0].uint, - arglist[1].charstr, arglist[2].uint); - break; - case 0x0062: /* fileref_create_by_prompt */ - arglist[4].opaqueref = glk_fileref_create_by_prompt(arglist[0].uint, - arglist[1].uint, arglist[2].uint); - break; - case 0x0063: /* fileref_destroy */ - glk_fileref_destroy(arglist[0].opaqueref); - break; - case 0x0064: /* fileref_iterate */ - if (arglist[1].ptrflag) - arglist[4].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, &arglist[2].uint); - else - arglist[3].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, NULL); - break; - case 0x0065: /* fileref_get_rock */ - arglist[2].uint = glk_fileref_get_rock(arglist[0].opaqueref); - break; - case 0x0066: /* fileref_delete_file */ - glk_fileref_delete_file(arglist[0].opaqueref); - break; - case 0x0067: /* fileref_does_file_exist */ - arglist[2].uint = glk_fileref_does_file_exist(arglist[0].opaqueref); - break; - case 0x0068: /* fileref_create_from_fileref */ - arglist[4].opaqueref = glk_fileref_create_from_fileref(arglist[0].uint, - arglist[1].opaqueref, arglist[2].uint); - break; - case 0x0080: /* put_char */ - glk_put_char(arglist[0].uch); - break; - case 0x0081: /* put_char_stream */ - glk_put_char_stream(arglist[0].opaqueref, arglist[1].uch); - break; - case 0x0082: /* put_string */ - glk_put_string(arglist[0].charstr); - break; - case 0x0083: /* put_string_stream */ - glk_put_string_stream(arglist[0].opaqueref, arglist[1].charstr); - break; - case 0x0084: /* put_buffer */ - if (arglist[0].ptrflag) - glk_put_buffer(arglist[1].array, arglist[2].uint); - else - glk_put_buffer(NULL, 0); - break; - case 0x0085: /* put_buffer_stream */ - if (arglist[1].ptrflag) - glk_put_buffer_stream(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - glk_put_buffer_stream(arglist[0].opaqueref, - NULL, 0); - break; - case 0x0086: /* set_style */ - glk_set_style(arglist[0].uint); - break; - case 0x0087: /* set_style_stream */ - glk_set_style_stream(arglist[0].opaqueref, arglist[1].uint); - break; - case 0x0090: /* get_char_stream */ - arglist[2].sint = glk_get_char_stream(arglist[0].opaqueref); - break; - case 0x0091: /* get_line_stream */ - if (arglist[1].ptrflag) - arglist[5].uint = glk_get_line_stream(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - arglist[3].uint = glk_get_line_stream(arglist[0].opaqueref, - NULL, 0); - break; - case 0x0092: /* get_buffer_stream */ - if (arglist[1].ptrflag) - arglist[5].uint = glk_get_buffer_stream(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - arglist[3].uint = glk_get_buffer_stream(arglist[0].opaqueref, - NULL, 0); - break; - case 0x00A0: /* char_to_lower */ - arglist[2].uch = glk_char_to_lower(arglist[0].uch); - break; - case 0x00A1: /* char_to_upper */ - arglist[2].uch = glk_char_to_upper(arglist[0].uch); - break; - case 0x00B0: /* stylehint_set */ - glk_stylehint_set(arglist[0].uint, arglist[1].uint, - arglist[2].uint, arglist[3].sint); - break; - case 0x00B1: /* stylehint_clear */ - glk_stylehint_clear(arglist[0].uint, arglist[1].uint, - arglist[2].uint); - break; - case 0x00B2: /* style_distinguish */ - arglist[4].uint = glk_style_distinguish(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint); - break; - case 0x00B3: /* style_measure */ - if (arglist[3].ptrflag) - arglist[6].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint, &(arglist[4].uint)); - else - arglist[5].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint, NULL); - break; - case 0x00C0: /* select */ - if (arglist[0].ptrflag) { - event_t dat; - glk_select(&dat); - arglist[1].uint = dat.type; - arglist[2].opaqueref = dat.win; - arglist[3].uint = dat.val1; - arglist[4].uint = dat.val2; - } - else { - glk_select(NULL); - } - break; - case 0x00C1: /* select_poll */ - if (arglist[0].ptrflag) { - event_t dat; - glk_select_poll(&dat); - arglist[1].uint = dat.type; - arglist[2].opaqueref = dat.win; - arglist[3].uint = dat.val1; - arglist[4].uint = dat.val2; - } - else { - glk_select_poll(NULL); - } - break; - case 0x00D0: /* request_line_event */ - if (arglist[1].ptrflag) - glk_request_line_event(arglist[0].opaqueref, arglist[2].array, - arglist[3].uint, arglist[4].uint); - else - glk_request_line_event(arglist[0].opaqueref, NULL, - 0, arglist[2].uint); - break; - case 0x00D1: /* cancel_line_event */ - if (arglist[1].ptrflag) { - event_t dat; - glk_cancel_line_event(arglist[0].opaqueref, &dat); - arglist[2].uint = dat.type; - arglist[3].opaqueref = dat.win; - arglist[4].uint = dat.val1; - arglist[5].uint = dat.val2; - } - else { - glk_cancel_line_event(arglist[0].opaqueref, NULL); - } - break; - case 0x00D2: /* request_char_event */ - glk_request_char_event(arglist[0].opaqueref); - break; - case 0x00D3: /* cancel_char_event */ - glk_cancel_char_event(arglist[0].opaqueref); - break; - case 0x00D4: /* request_mouse_event */ - glk_request_mouse_event(arglist[0].opaqueref); - break; - case 0x00D5: /* cancel_mouse_event */ - glk_cancel_mouse_event(arglist[0].opaqueref); - break; - case 0x00D6: /* request_timer_events */ - glk_request_timer_events(arglist[0].uint); - break; - -#ifdef GLK_MODULE_IMAGE - case 0x00E0: /* image_get_info */ - { - int ix = 1; - glui32 *ptr1, *ptr2; - if (!arglist[ix].ptrflag) { - ptr1 = NULL; - } - else { - ix++; - ptr1 = &(arglist[ix].uint); - } - ix++; - if (!arglist[ix].ptrflag) { - ptr2 = NULL; - } - else { - ix++; - ptr2 = &(arglist[ix].uint); - } - ix++; - ix++; - arglist[ix].uint = glk_image_get_info(arglist[0].uint, ptr1, ptr2); - } - break; - case 0x00E1: /* image_draw */ - arglist[5].uint = glk_image_draw(arglist[0].opaqueref, - arglist[1].uint, - arglist[2].sint, arglist[3].sint); - break; - case 0x00E2: /* image_draw_scaled */ - arglist[7].uint = glk_image_draw_scaled(arglist[0].opaqueref, - arglist[1].uint, - arglist[2].sint, arglist[3].sint, - arglist[4].uint, arglist[5].uint); - break; - case 0x00E8: /* window_flow_break */ - glk_window_flow_break(arglist[0].opaqueref); - break; - case 0x00E9: /* window_erase_rect */ - glk_window_erase_rect(arglist[0].opaqueref, - arglist[1].sint, arglist[2].sint, - arglist[3].uint, arglist[4].uint); - break; - case 0x00EA: /* window_fill_rect */ - glk_window_fill_rect(arglist[0].opaqueref, arglist[1].uint, - arglist[2].sint, arglist[3].sint, - arglist[4].uint, arglist[5].uint); - break; - case 0x00EB: /* window_set_background_color */ - glk_window_set_background_color(arglist[0].opaqueref, arglist[1].uint); - break; -#endif /* GLK_MODULE_IMAGE */ - -#ifdef GLK_MODULE_SOUND - case 0x00F0: /* schannel_iterate */ - if (arglist[1].ptrflag) - arglist[4].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, &arglist[2].uint); - else - arglist[3].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, NULL); - break; - case 0x00F1: /* schannel_get_rock */ - arglist[2].uint = glk_schannel_get_rock(arglist[0].opaqueref); - break; - case 0x00F2: /* schannel_create */ - arglist[2].opaqueref = glk_schannel_create(arglist[0].uint); - break; - case 0x00F3: /* schannel_destroy */ - glk_schannel_destroy(arglist[0].opaqueref); - break; - case 0x00F8: /* schannel_play */ - arglist[3].uint = glk_schannel_play(arglist[0].opaqueref, arglist[1].uint); - break; - case 0x00F9: /* schannel_play_ext */ - arglist[5].uint = glk_schannel_play_ext(arglist[0].opaqueref, - arglist[1].uint, arglist[2].uint, arglist[3].uint); - break; - case 0x00FA: /* schannel_stop */ - glk_schannel_stop(arglist[0].opaqueref); - break; - case 0x00FB: /* schannel_set_volume */ - glk_schannel_set_volume(arglist[0].opaqueref, arglist[1].uint); - break; - case 0x00FC: /* sound_load_hint */ - glk_sound_load_hint(arglist[0].uint, arglist[1].uint); - break; - -#ifdef GLK_MODULE_SOUND2 - case 0x00F4: /* schannel_create_ext */ - arglist[3].opaqueref = glk_schannel_create_ext(arglist[0].uint, arglist[1].uint); - break; - case 0x00F7: /* schannel_play_multi */ - if (arglist[0].ptrflag && arglist[3].ptrflag) - arglist[8].uint = glk_schannel_play_multi(arglist[1].array, arglist[2].uint, arglist[4].array, arglist[5].uint, arglist[6].uint); - else if (arglist[0].ptrflag) - arglist[6].uint = glk_schannel_play_multi(arglist[1].array, arglist[2].uint, NULL, 0, arglist[4].uint); - else if (arglist[1].ptrflag) - arglist[6].uint = glk_schannel_play_multi(NULL, 0, arglist[2].array, arglist[3].uint, arglist[4].uint); - else - arglist[4].uint = glk_schannel_play_multi(NULL, 0, NULL, 0, arglist[2].uint); - break; - case 0x00FD: /* schannel_set_volume_ext */ - glk_schannel_set_volume_ext(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].uint); - break; - case 0x00FE: /* schannel_pause */ - glk_schannel_pause(arglist[0].opaqueref); - break; - case 0x00FF: /* schannel_unpause */ - glk_schannel_unpause(arglist[0].opaqueref); - break; -#endif /* GLK_MODULE_SOUND2 */ -#endif /* GLK_MODULE_SOUND */ - -#ifdef GLK_MODULE_HYPERLINKS - case 0x0100: /* set_hyperlink */ - glk_set_hyperlink(arglist[0].uint); - break; - case 0x0101: /* set_hyperlink_stream */ - glk_set_hyperlink_stream(arglist[0].opaqueref, arglist[1].uint); - break; - case 0x0102: /* request_hyperlink_event */ - glk_request_hyperlink_event(arglist[0].opaqueref); - break; - case 0x0103: /* cancel_hyperlink_event */ - glk_cancel_hyperlink_event(arglist[0].opaqueref); - break; -#endif /* GLK_MODULE_HYPERLINKS */ - -#ifdef GLK_MODULE_UNICODE - case 0x0120: /* buffer_to_lower_case_uni */ - if (arglist[0].ptrflag) - arglist[5].uint = glk_buffer_to_lower_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); - else - arglist[3].uint = glk_buffer_to_lower_case_uni(NULL, 0, arglist[1].uint); - break; - case 0x0121: /* buffer_to_upper_case_uni */ - if (arglist[0].ptrflag) - arglist[5].uint = glk_buffer_to_upper_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); - else - arglist[3].uint = glk_buffer_to_upper_case_uni(NULL, 0, arglist[1].uint); - break; - case 0x0122: /* buffer_to_title_case_uni */ - if (arglist[0].ptrflag) - arglist[6].uint = glk_buffer_to_title_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); - else - arglist[4].uint = glk_buffer_to_title_case_uni(NULL, 0, arglist[1].uint, arglist[2].uint); - break; - case 0x0128: /* put_char_uni */ - glk_put_char_uni(arglist[0].uint); - break; - case 0x0129: /* put_string_uni */ - glk_put_string_uni(arglist[0].unicharstr); - break; - case 0x012A: /* put_buffer_uni */ - if (arglist[0].ptrflag) - glk_put_buffer_uni(arglist[1].array, arglist[2].uint); - else - glk_put_buffer_uni(NULL, 0); - break; - case 0x012B: /* put_char_stream_uni */ - glk_put_char_stream_uni(arglist[0].opaqueref, arglist[1].uint); - break; - case 0x012C: /* put_string_stream_uni */ - glk_put_string_stream_uni(arglist[0].opaqueref, arglist[1].unicharstr); - break; - case 0x012D: /* put_buffer_stream_uni */ - if (arglist[1].ptrflag) - glk_put_buffer_stream_uni(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - glk_put_buffer_stream_uni(arglist[0].opaqueref, - NULL, 0); - break; - case 0x0130: /* get_char_stream_uni */ - arglist[2].sint = glk_get_char_stream_uni(arglist[0].opaqueref); - break; - case 0x0131: /* get_buffer_stream_uni */ - if (arglist[1].ptrflag) - arglist[5].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - arglist[3].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, - NULL, 0); - break; - case 0x0132: /* get_line_stream_uni */ - if (arglist[1].ptrflag) - arglist[5].uint = glk_get_line_stream_uni(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - arglist[3].uint = glk_get_line_stream_uni(arglist[0].opaqueref, - NULL, 0); - break; - case 0x0138: /* stream_open_file_uni */ - arglist[4].opaqueref = glk_stream_open_file_uni(arglist[0].opaqueref, arglist[1].uint, - arglist[2].uint); - break; - case 0x0139: /* stream_open_memory_uni */ - if (arglist[0].ptrflag) - arglist[6].opaqueref = glk_stream_open_memory_uni(arglist[1].array, - arglist[2].uint, arglist[3].uint, arglist[4].uint); - else - arglist[4].opaqueref = glk_stream_open_memory_uni(NULL, - 0, arglist[1].uint, arglist[2].uint); - break; - case 0x0140: /* request_char_event_uni */ - glk_request_char_event_uni(arglist[0].opaqueref); - break; - case 0x0141: /* request_line_event_uni */ - if (arglist[1].ptrflag) - glk_request_line_event_uni(arglist[0].opaqueref, arglist[2].array, - arglist[3].uint, arglist[4].uint); - else - glk_request_line_event_uni(arglist[0].opaqueref, NULL, - 0, arglist[2].uint); - break; -#endif /* GLK_MODULE_UNICODE */ - -#ifdef GLK_MODULE_UNICODE_NORM - case 0x0123: /* buffer_canon_decompose_uni */ - if (arglist[0].ptrflag) - arglist[5].uint = glk_buffer_canon_decompose_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); - else - arglist[3].uint = glk_buffer_canon_decompose_uni(NULL, 0, arglist[1].uint); - break; - case 0x0124: /* buffer_canon_normalize_uni */ - if (arglist[0].ptrflag) - arglist[5].uint = glk_buffer_canon_normalize_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); - else - arglist[3].uint = glk_buffer_canon_normalize_uni(NULL, 0, arglist[1].uint); - break; -#endif /* GLK_MODULE_UNICODE_NORM */ - -#ifdef GLK_MODULE_LINE_ECHO - case 0x0150: /* set_echo_line_event */ - glk_set_echo_line_event(arglist[0].opaqueref, arglist[1].uint); - break; -#endif /* GLK_MODULE_LINE_ECHO */ - -#ifdef GLK_MODULE_LINE_TERMINATORS - case 0x0151: /* set_terminators_line_event */ - if (arglist[1].ptrflag) - glk_set_terminators_line_event(arglist[0].opaqueref, - arglist[2].array, arglist[3].uint); - else - glk_set_terminators_line_event(arglist[0].opaqueref, - NULL, 0); - break; -#endif /* GLK_MODULE_LINE_TERMINATORS */ - -#ifdef GLK_MODULE_DATETIME - case 0x0160: /* current_time */ - if (arglist[0].ptrflag) { - glktimeval_t dat; - glk_current_time(&dat); - arglist[1].sint = dat.high_sec; - arglist[2].uint = dat.low_sec; - arglist[3].sint = dat.microsec; - } - else { - glk_current_time(NULL); - } - break; - case 0x0161: /* current_simple_time */ - arglist[2].sint = glk_current_simple_time(arglist[0].uint); - break; - case 0x0168: /* time_to_date_utc */ { - glktimeval_t timeval; - glktimeval_t *timeptr = NULL; - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - timeptr = &timeval; - timeval.high_sec = arglist[ix++].sint; - timeval.low_sec = arglist[ix++].uint; - timeval.microsec = arglist[ix++].sint; - } - if (arglist[ix++].ptrflag) { - dateptr = &date; - } - glk_time_to_date_utc(timeptr, dateptr); - if (dateptr) { - arglist[ix++].sint = date.year; - arglist[ix++].sint = date.month; - arglist[ix++].sint = date.day; - arglist[ix++].sint = date.weekday; - arglist[ix++].sint = date.hour; - arglist[ix++].sint = date.minute; - arglist[ix++].sint = date.second; - arglist[ix++].sint = date.microsec; - } - } - break; - case 0x0169: /* time_to_date_local */ { - glktimeval_t timeval; - glktimeval_t *timeptr = NULL; - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - timeptr = &timeval; - timeval.high_sec = arglist[ix++].sint; - timeval.low_sec = arglist[ix++].uint; - timeval.microsec = arglist[ix++].sint; - } - if (arglist[ix++].ptrflag) { - dateptr = &date; - } - glk_time_to_date_local(timeptr, dateptr); - if (dateptr) { - arglist[ix++].sint = date.year; - arglist[ix++].sint = date.month; - arglist[ix++].sint = date.day; - arglist[ix++].sint = date.weekday; - arglist[ix++].sint = date.hour; - arglist[ix++].sint = date.minute; - arglist[ix++].sint = date.second; - arglist[ix++].sint = date.microsec; - } - } - break; - case 0x016A: /* simple_time_to_date_utc */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 2; - if (arglist[ix++].ptrflag) { - dateptr = &date; - } - glk_simple_time_to_date_utc(arglist[0].sint, arglist[1].uint, dateptr); - if (dateptr) { - arglist[ix++].sint = date.year; - arglist[ix++].sint = date.month; - arglist[ix++].sint = date.day; - arglist[ix++].sint = date.weekday; - arglist[ix++].sint = date.hour; - arglist[ix++].sint = date.minute; - arglist[ix++].sint = date.second; - arglist[ix++].sint = date.microsec; - } - } - break; - case 0x016B: /* simple_time_to_date_local */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 2; - if (arglist[ix++].ptrflag) { - dateptr = &date; - } - glk_simple_time_to_date_local(arglist[0].sint, arglist[1].uint, dateptr); - if (dateptr) { - arglist[ix++].sint = date.year; - arglist[ix++].sint = date.month; - arglist[ix++].sint = date.day; - arglist[ix++].sint = date.weekday; - arglist[ix++].sint = date.hour; - arglist[ix++].sint = date.minute; - arglist[ix++].sint = date.second; - arglist[ix++].sint = date.microsec; - } - } - break; - case 0x016C: /* date_to_time_utc */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - glktimeval_t timeval; - glktimeval_t *timeptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - dateptr = &date; - date.year = arglist[ix++].sint; - date.month = arglist[ix++].sint; - date.day = arglist[ix++].sint; - date.weekday = arglist[ix++].sint; - date.hour = arglist[ix++].sint; - date.minute = arglist[ix++].sint; - date.second = arglist[ix++].sint; - date.microsec = arglist[ix++].sint; - } - if (arglist[ix++].ptrflag) { - timeptr = &timeval; - } - glk_date_to_time_utc(dateptr, timeptr); - if (timeptr) { - arglist[ix++].sint = timeval.high_sec; - arglist[ix++].uint = timeval.low_sec; - arglist[ix++].sint = timeval.microsec; - } - } - break; - case 0x016D: /* date_to_time_local */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - glktimeval_t timeval; - glktimeval_t *timeptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - dateptr = &date; - date.year = arglist[ix++].sint; - date.month = arglist[ix++].sint; - date.day = arglist[ix++].sint; - date.weekday = arglist[ix++].sint; - date.hour = arglist[ix++].sint; - date.minute = arglist[ix++].sint; - date.second = arglist[ix++].sint; - date.microsec = arglist[ix++].sint; - } - if (arglist[ix++].ptrflag) { - timeptr = &timeval; - } - glk_date_to_time_local(dateptr, timeptr); - if (timeptr) { - arglist[ix++].sint = timeval.high_sec; - arglist[ix++].uint = timeval.low_sec; - arglist[ix++].sint = timeval.microsec; - } - } - break; - case 0x016E: /* date_to_simple_time_utc */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - dateptr = &date; - date.year = arglist[ix++].sint; - date.month = arglist[ix++].sint; - date.day = arglist[ix++].sint; - date.weekday = arglist[ix++].sint; - date.hour = arglist[ix++].sint; - date.minute = arglist[ix++].sint; - date.second = arglist[ix++].sint; - date.microsec = arglist[ix++].sint; - } - arglist[ix+2].sint = glk_date_to_simple_time_utc(dateptr, arglist[ix].uint); - } - break; - case 0x016F: /* date_to_simple_time_local */ { - glkdate_t date; - glkdate_t *dateptr = NULL; - int ix = 0; - if (arglist[ix++].ptrflag) { - dateptr = &date; - date.year = arglist[ix++].sint; - date.month = arglist[ix++].sint; - date.day = arglist[ix++].sint; - date.weekday = arglist[ix++].sint; - date.hour = arglist[ix++].sint; - date.minute = arglist[ix++].sint; - date.second = arglist[ix++].sint; - date.microsec = arglist[ix++].sint; - } - arglist[ix+2].sint = glk_date_to_simple_time_local(dateptr, arglist[ix].uint); - } - break; -#endif /* GLK_MODULE_DATETIME */ - -#ifdef GLK_MODULE_RESOURCE_STREAM - case 0x0049: /* stream_open_resource */ - arglist[3].opaqueref = glk_stream_open_resource(arglist[0].uint, arglist[1].uint); - break; - case 0x013A: /* stream_open_resource_uni */ - arglist[3].opaqueref = glk_stream_open_resource_uni(arglist[0].uint, arglist[1].uint); - break; -#endif /* GLK_MODULE_RESOURCE_STREAM */ - -#ifdef GLK_EXTEND_CALL - GLK_EXTEND_CALL -#endif /* GLK_EXTEND_CALL */ - - default: - /* do nothing */ - break; - } -} - -#ifdef GI_DISPA_GAME_ID_AVAILABLE - -static char *(*game_id_hook)(void) = NULL; - -/* Set a function for getting a game ID string. The Glk library may - call the supplied function when creating files, so that the files - can be put in a game-specific location. - - The function must have the form: char *func(void); - - It should return NULL or a pointer to a (null-terminated) string. - (The string will be copied, so it may be in a temporary buffer.) -*/ -void gidispatch_set_game_id_hook(char *(*hook)(void)) -{ - game_id_hook = hook; -} - -/* Retrieve a game ID string for the current game. - - If not NULL, this string may be in a temporary buffer, so the caller - must copy it! -*/ -char *gidispatch_get_game_id(void) -{ - if (!game_id_hook) - return NULL; - return game_id_hook(); -} - -#endif /* GI_DISPA_GAME_ID_AVAILABLE */ diff --git a/textworld/thirdparty/glulx/cheapglk/gi_dispa.h b/textworld/thirdparty/glulx/cheapglk/gi_dispa.h deleted file mode 100644 index ab36dc64..00000000 --- a/textworld/thirdparty/glulx/cheapglk/gi_dispa.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _GI_DISPA_H -#define _GI_DISPA_H - -/* gi_dispa.h: Header file for dispatch layer of Glk API, version 0.7.5. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/index.html - - This file is copyright 1998-2017 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -/* These constants define the classes of opaque objects. It's a bit ugly - to put them in this header file, since more classes may be added in - the future. But if you find yourself stuck with an obsolete version - of this file, adding new class definitions will be easy enough -- - they will be numbered sequentially, and the numeric constants can be - found in the Glk specification. */ -#define gidisp_Class_Window (0) -#define gidisp_Class_Stream (1) -#define gidisp_Class_Fileref (2) -#define gidisp_Class_Schannel (3) - -typedef union gluniversal_union { - glui32 uint; /* Iu */ - glsi32 sint; /* Is */ - void *opaqueref; /* Qa, Qb, Qc... */ - unsigned char uch; /* Cu */ - signed char sch; /* Cs */ - char ch; /* Cn */ - char *charstr; /* S */ - glui32 *unicharstr; /* U */ - void *array; /* all # arguments */ - glui32 ptrflag; /* [ ... ] or *? */ -} gluniversal_t; - -/* Some well-known structures: - event_t : [4IuQaIuIu] - stream_result_t : [2IuIu] -*/ - -typedef struct gidispatch_function_struct { - glui32 id; - void *fnptr; - char *name; -} gidispatch_function_t; - -typedef struct gidispatch_intconst_struct { - char *name; - glui32 val; -} gidispatch_intconst_t; - -typedef union glk_objrock_union { - glui32 num; - void *ptr; -} gidispatch_rock_t; - -/* The following functions are part of the Glk library itself, not the dispatch - layer (whose code is in gi_dispa.c). These functions are necessarily - implemented in platform-dependent code. -*/ -extern void gidispatch_set_object_registry( - gidispatch_rock_t (*regi)(void *obj, glui32 objclass), - void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock)); -extern gidispatch_rock_t gidispatch_get_objrock(void *obj, glui32 objclass); -extern void gidispatch_set_retained_registry( - gidispatch_rock_t (*regi)(void *array, glui32 len, char *typecode), - void (*unregi)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock)); - -/* This function is also part of the Glk library, but it only exists - on libraries that support autorestore. (Only iosglk, currently.) - Only call this if GIDISPATCH_AUTORESTORE_REGISTRY is defined. -*/ -#define GIDISPATCH_AUTORESTORE_REGISTRY -extern void gidispatch_set_autorestore_registry( - long (*locatearr)(void *array, glui32 len, char *typecode, - gidispatch_rock_t objrock, int *elemsizeref), - gidispatch_rock_t (*restorearr)(long bufkey, glui32 len, - char *typecode, void **arrayref)); - -/* The following functions make up the Glk dispatch layer. Although they are - distributed as part of each Glk library (linked into the library file), - their code is in gi_dispa.c, which is platform-independent and identical - in every Glk library. -*/ -extern void gidispatch_call(glui32 funcnum, glui32 numargs, - gluniversal_t *arglist); -extern char *gidispatch_prototype(glui32 funcnum); -extern glui32 gidispatch_count_classes(void); -extern gidispatch_intconst_t *gidispatch_get_class(glui32 index); -extern glui32 gidispatch_count_intconst(void); -extern gidispatch_intconst_t *gidispatch_get_intconst(glui32 index); -extern glui32 gidispatch_count_functions(void); -extern gidispatch_function_t *gidispatch_get_function(glui32 index); -extern gidispatch_function_t *gidispatch_get_function_by_id(glui32 id); - -#define GI_DISPA_GAME_ID_AVAILABLE -/* These function is not part of Glk dispatching per se; they allow the - game to provide an identifier string for the Glk library to use. - The functions themselves are in gi_dispa.c. - - The game should test ifdef GI_DISPA_GAME_ID_AVAILABLE to ensure that - these functions exist. (They are a late addition to gi_dispa.c, so - older Glk library distributions will lack them.) -*/ -#ifdef GI_DISPA_GAME_ID_AVAILABLE -extern void gidispatch_set_game_id_hook(char *(*hook)(void)); -extern char *gidispatch_get_game_id(void); -#endif /* GI_DISPA_GAME_ID_AVAILABLE */ - -#endif /* _GI_DISPA_H */ diff --git a/textworld/thirdparty/glulx/cheapglk/glk.h b/textworld/thirdparty/glulx/cheapglk/glk.h deleted file mode 100644 index 3b6581ae..00000000 --- a/textworld/thirdparty/glulx/cheapglk/glk.h +++ /dev/null @@ -1,449 +0,0 @@ -#ifndef GLK_H -#define GLK_H - -/* glk.h: Header file for Glk API, version 0.7.5. - Designed by Andrew Plotkin - http://eblong.com/zarf/glk/ - - This file is copyright 1998-2017 by Andrew Plotkin. It is - distributed under the MIT license; see the "LICENSE" file. -*/ - -/* If your system does not have , you'll have to remove this - include line. Then edit the definition of glui32 to make sure it's - really a 32-bit unsigned integer type, and glsi32 to make sure - it's really a 32-bit signed integer type. If they're not, horrible - things will happen. */ -#include -typedef uint32_t glui32; -typedef int32_t glsi32; - -/* These are the compile-time conditionals that reveal various Glk optional - modules. Note that if GLK_MODULE_SOUND2 is defined, GLK_MODULE_SOUND - must be also. */ -#define GLK_MODULE_LINE_ECHO -#define GLK_MODULE_LINE_TERMINATORS -#define GLK_MODULE_UNICODE -#define GLK_MODULE_UNICODE_NORM -#define GLK_MODULE_IMAGE -#define GLK_MODULE_SOUND -#define GLK_MODULE_SOUND2 -#define GLK_MODULE_HYPERLINKS -#define GLK_MODULE_DATETIME -#define GLK_MODULE_RESOURCE_STREAM - -/* Define a macro for a function attribute that indicates a function that - never returns. (E.g., glk_exit().) We try to do this only in C compilers - that support it. If this is causing you problems, comment all this out - and simply "#define GLK_ATTRIBUTE_NORETURN". */ -#if defined(__GNUC__) || defined(__clang__) -#define GLK_ATTRIBUTE_NORETURN __attribute__((__noreturn__)) -#endif /* defined(__GNUC__) || defined(__clang__) */ -#ifndef GLK_ATTRIBUTE_NORETURN -#define GLK_ATTRIBUTE_NORETURN -#endif /* GLK_ATTRIBUTE_NORETURN */ - -/* These types are opaque object identifiers. They're pointers to opaque - C structures, which are defined differently by each library. */ -typedef struct glk_window_struct *winid_t; -typedef struct glk_stream_struct *strid_t; -typedef struct glk_fileref_struct *frefid_t; -typedef struct glk_schannel_struct *schanid_t; - -#define gestalt_Version (0) -#define gestalt_CharInput (1) -#define gestalt_LineInput (2) -#define gestalt_CharOutput (3) -#define gestalt_CharOutput_CannotPrint (0) -#define gestalt_CharOutput_ApproxPrint (1) -#define gestalt_CharOutput_ExactPrint (2) -#define gestalt_MouseInput (4) -#define gestalt_Timer (5) -#define gestalt_Graphics (6) -#define gestalt_DrawImage (7) -#define gestalt_Sound (8) -#define gestalt_SoundVolume (9) -#define gestalt_SoundNotify (10) -#define gestalt_Hyperlinks (11) -#define gestalt_HyperlinkInput (12) -#define gestalt_SoundMusic (13) -#define gestalt_GraphicsTransparency (14) -#define gestalt_Unicode (15) -#define gestalt_UnicodeNorm (16) -#define gestalt_LineInputEcho (17) -#define gestalt_LineTerminators (18) -#define gestalt_LineTerminatorKey (19) -#define gestalt_DateTime (20) -#define gestalt_Sound2 (21) -#define gestalt_ResourceStream (22) -#define gestalt_GraphicsCharInput (23) - -#define evtype_None (0) -#define evtype_Timer (1) -#define evtype_CharInput (2) -#define evtype_LineInput (3) -#define evtype_MouseInput (4) -#define evtype_Arrange (5) -#define evtype_Redraw (6) -#define evtype_SoundNotify (7) -#define evtype_Hyperlink (8) -#define evtype_VolumeNotify (9) - -typedef struct event_struct { - glui32 type; - winid_t win; - glui32 val1, val2; -} event_t; - -#define keycode_Unknown (0xffffffff) -#define keycode_Left (0xfffffffe) -#define keycode_Right (0xfffffffd) -#define keycode_Up (0xfffffffc) -#define keycode_Down (0xfffffffb) -#define keycode_Return (0xfffffffa) -#define keycode_Delete (0xfffffff9) -#define keycode_Escape (0xfffffff8) -#define keycode_Tab (0xfffffff7) -#define keycode_PageUp (0xfffffff6) -#define keycode_PageDown (0xfffffff5) -#define keycode_Home (0xfffffff4) -#define keycode_End (0xfffffff3) -#define keycode_Func1 (0xffffffef) -#define keycode_Func2 (0xffffffee) -#define keycode_Func3 (0xffffffed) -#define keycode_Func4 (0xffffffec) -#define keycode_Func5 (0xffffffeb) -#define keycode_Func6 (0xffffffea) -#define keycode_Func7 (0xffffffe9) -#define keycode_Func8 (0xffffffe8) -#define keycode_Func9 (0xffffffe7) -#define keycode_Func10 (0xffffffe6) -#define keycode_Func11 (0xffffffe5) -#define keycode_Func12 (0xffffffe4) -/* The last keycode is always (0x100000000 - keycode_MAXVAL) */ -#define keycode_MAXVAL (28) - -#define style_Normal (0) -#define style_Emphasized (1) -#define style_Preformatted (2) -#define style_Header (3) -#define style_Subheader (4) -#define style_Alert (5) -#define style_Note (6) -#define style_BlockQuote (7) -#define style_Input (8) -#define style_User1 (9) -#define style_User2 (10) -#define style_NUMSTYLES (11) - -typedef struct stream_result_struct { - glui32 readcount; - glui32 writecount; -} stream_result_t; - -#define wintype_AllTypes (0) -#define wintype_Pair (1) -#define wintype_Blank (2) -#define wintype_TextBuffer (3) -#define wintype_TextGrid (4) -#define wintype_Graphics (5) - -#define winmethod_Left (0x00) -#define winmethod_Right (0x01) -#define winmethod_Above (0x02) -#define winmethod_Below (0x03) -#define winmethod_DirMask (0x0f) - -#define winmethod_Fixed (0x10) -#define winmethod_Proportional (0x20) -#define winmethod_DivisionMask (0xf0) - -#define winmethod_Border (0x000) -#define winmethod_NoBorder (0x100) -#define winmethod_BorderMask (0x100) - -#define fileusage_Data (0x00) -#define fileusage_SavedGame (0x01) -#define fileusage_Transcript (0x02) -#define fileusage_InputRecord (0x03) -#define fileusage_TypeMask (0x0f) - -#define fileusage_TextMode (0x100) -#define fileusage_BinaryMode (0x000) - -#define filemode_Write (0x01) -#define filemode_Read (0x02) -#define filemode_ReadWrite (0x03) -#define filemode_WriteAppend (0x05) - -#define seekmode_Start (0) -#define seekmode_Current (1) -#define seekmode_End (2) - -#define stylehint_Indentation (0) -#define stylehint_ParaIndentation (1) -#define stylehint_Justification (2) -#define stylehint_Size (3) -#define stylehint_Weight (4) -#define stylehint_Oblique (5) -#define stylehint_Proportional (6) -#define stylehint_TextColor (7) -#define stylehint_BackColor (8) -#define stylehint_ReverseColor (9) -#define stylehint_NUMHINTS (10) - -#define stylehint_just_LeftFlush (0) -#define stylehint_just_LeftRight (1) -#define stylehint_just_Centered (2) -#define stylehint_just_RightFlush (3) - -/* glk_main() is the top-level function which you define. The Glk library - calls it. */ -extern void glk_main(void); - -extern void glk_exit(void) GLK_ATTRIBUTE_NORETURN; -extern void glk_set_interrupt_handler(void (*func)(void)); -extern void glk_tick(void); - -extern glui32 glk_gestalt(glui32 sel, glui32 val); -extern glui32 glk_gestalt_ext(glui32 sel, glui32 val, glui32 *arr, - glui32 arrlen); - -extern unsigned char glk_char_to_lower(unsigned char ch); -extern unsigned char glk_char_to_upper(unsigned char ch); - -extern winid_t glk_window_get_root(void); -extern winid_t glk_window_open(winid_t split, glui32 method, glui32 size, - glui32 wintype, glui32 rock); -extern void glk_window_close(winid_t win, stream_result_t *result); -extern void glk_window_get_size(winid_t win, glui32 *widthptr, - glui32 *heightptr); -extern void glk_window_set_arrangement(winid_t win, glui32 method, - glui32 size, winid_t keywin); -extern void glk_window_get_arrangement(winid_t win, glui32 *methodptr, - glui32 *sizeptr, winid_t *keywinptr); -extern winid_t glk_window_iterate(winid_t win, glui32 *rockptr); -extern glui32 glk_window_get_rock(winid_t win); -extern glui32 glk_window_get_type(winid_t win); -extern winid_t glk_window_get_parent(winid_t win); -extern winid_t glk_window_get_sibling(winid_t win); -extern void glk_window_clear(winid_t win); -extern void glk_window_move_cursor(winid_t win, glui32 xpos, glui32 ypos); - -extern strid_t glk_window_get_stream(winid_t win); -extern void glk_window_set_echo_stream(winid_t win, strid_t str); -extern strid_t glk_window_get_echo_stream(winid_t win); -extern void glk_set_window(winid_t win); - -extern strid_t glk_stream_open_file(frefid_t fileref, glui32 fmode, - glui32 rock); -extern strid_t glk_stream_open_memory(char *buf, glui32 buflen, glui32 fmode, - glui32 rock); -extern void glk_stream_close(strid_t str, stream_result_t *result); -extern strid_t glk_stream_iterate(strid_t str, glui32 *rockptr); -extern glui32 glk_stream_get_rock(strid_t str); -extern void glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode); -extern glui32 glk_stream_get_position(strid_t str); -extern void glk_stream_set_current(strid_t str); -extern strid_t glk_stream_get_current(void); - -extern void glk_put_char(unsigned char ch); -extern void glk_put_char_stream(strid_t str, unsigned char ch); -extern void glk_put_string(char *s); -extern void glk_put_string_stream(strid_t str, char *s); -extern void glk_put_buffer(char *buf, glui32 len); -extern void glk_put_buffer_stream(strid_t str, char *buf, glui32 len); -extern void glk_set_style(glui32 styl); -extern void glk_set_style_stream(strid_t str, glui32 styl); - -extern glsi32 glk_get_char_stream(strid_t str); -extern glui32 glk_get_line_stream(strid_t str, char *buf, glui32 len); -extern glui32 glk_get_buffer_stream(strid_t str, char *buf, glui32 len); - -extern void glk_stylehint_set(glui32 wintype, glui32 styl, glui32 hint, - glsi32 val); -extern void glk_stylehint_clear(glui32 wintype, glui32 styl, glui32 hint); -extern glui32 glk_style_distinguish(winid_t win, glui32 styl1, glui32 styl2); -extern glui32 glk_style_measure(winid_t win, glui32 styl, glui32 hint, - glui32 *result); - -extern frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock); -extern frefid_t glk_fileref_create_by_name(glui32 usage, char *name, - glui32 rock); -extern frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, - glui32 rock); -extern frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, - glui32 rock); -extern void glk_fileref_destroy(frefid_t fref); -extern frefid_t glk_fileref_iterate(frefid_t fref, glui32 *rockptr); -extern glui32 glk_fileref_get_rock(frefid_t fref); -extern void glk_fileref_delete_file(frefid_t fref); -extern glui32 glk_fileref_does_file_exist(frefid_t fref); - -extern void glk_select(event_t *event); -extern void glk_select_poll(event_t *event); - -extern void glk_request_timer_events(glui32 millisecs); - -extern void glk_request_line_event(winid_t win, char *buf, glui32 maxlen, - glui32 initlen); -extern void glk_request_char_event(winid_t win); -extern void glk_request_mouse_event(winid_t win); - -extern void glk_cancel_line_event(winid_t win, event_t *event); -extern void glk_cancel_char_event(winid_t win); -extern void glk_cancel_mouse_event(winid_t win); - -#ifdef GLK_MODULE_LINE_ECHO -extern void glk_set_echo_line_event(winid_t win, glui32 val); -#endif /* GLK_MODULE_LINE_ECHO */ - -#ifdef GLK_MODULE_LINE_TERMINATORS -extern void glk_set_terminators_line_event(winid_t win, glui32 *keycodes, - glui32 count); -#endif /* GLK_MODULE_LINE_TERMINATORS */ - -#ifdef GLK_MODULE_UNICODE - -extern glui32 glk_buffer_to_lower_case_uni(glui32 *buf, glui32 len, - glui32 numchars); -extern glui32 glk_buffer_to_upper_case_uni(glui32 *buf, glui32 len, - glui32 numchars); -extern glui32 glk_buffer_to_title_case_uni(glui32 *buf, glui32 len, - glui32 numchars, glui32 lowerrest); - -extern void glk_put_char_uni(glui32 ch); -extern void glk_put_string_uni(glui32 *s); -extern void glk_put_buffer_uni(glui32 *buf, glui32 len); -extern void glk_put_char_stream_uni(strid_t str, glui32 ch); -extern void glk_put_string_stream_uni(strid_t str, glui32 *s); -extern void glk_put_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len); - -extern glsi32 glk_get_char_stream_uni(strid_t str); -extern glui32 glk_get_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len); -extern glui32 glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len); - -extern strid_t glk_stream_open_file_uni(frefid_t fileref, glui32 fmode, - glui32 rock); -extern strid_t glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, - glui32 fmode, glui32 rock); - -extern void glk_request_char_event_uni(winid_t win); -extern void glk_request_line_event_uni(winid_t win, glui32 *buf, - glui32 maxlen, glui32 initlen); - -#endif /* GLK_MODULE_UNICODE */ - -#ifdef GLK_MODULE_UNICODE_NORM - -extern glui32 glk_buffer_canon_decompose_uni(glui32 *buf, glui32 len, - glui32 numchars); -extern glui32 glk_buffer_canon_normalize_uni(glui32 *buf, glui32 len, - glui32 numchars); - -#endif /* GLK_MODULE_UNICODE_NORM */ - -#ifdef GLK_MODULE_IMAGE - -#define imagealign_InlineUp (0x01) -#define imagealign_InlineDown (0x02) -#define imagealign_InlineCenter (0x03) -#define imagealign_MarginLeft (0x04) -#define imagealign_MarginRight (0x05) - -extern glui32 glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2); -extern glui32 glk_image_draw_scaled(winid_t win, glui32 image, - glsi32 val1, glsi32 val2, glui32 width, glui32 height); -extern glui32 glk_image_get_info(glui32 image, glui32 *width, glui32 *height); - -extern void glk_window_flow_break(winid_t win); - -extern void glk_window_erase_rect(winid_t win, - glsi32 left, glsi32 top, glui32 width, glui32 height); -extern void glk_window_fill_rect(winid_t win, glui32 color, - glsi32 left, glsi32 top, glui32 width, glui32 height); -extern void glk_window_set_background_color(winid_t win, glui32 color); - -#endif /* GLK_MODULE_IMAGE */ - -#ifdef GLK_MODULE_SOUND - -extern schanid_t glk_schannel_create(glui32 rock); -extern void glk_schannel_destroy(schanid_t chan); -extern schanid_t glk_schannel_iterate(schanid_t chan, glui32 *rockptr); -extern glui32 glk_schannel_get_rock(schanid_t chan); - -extern glui32 glk_schannel_play(schanid_t chan, glui32 snd); -extern glui32 glk_schannel_play_ext(schanid_t chan, glui32 snd, glui32 repeats, - glui32 notify); -extern void glk_schannel_stop(schanid_t chan); -extern void glk_schannel_set_volume(schanid_t chan, glui32 vol); - -extern void glk_sound_load_hint(glui32 snd, glui32 flag); - -#ifdef GLK_MODULE_SOUND2 -/* Note that this section is nested inside the #ifdef GLK_MODULE_SOUND. - GLK_MODULE_SOUND must be defined if GLK_MODULE_SOUND2 is. */ - -extern schanid_t glk_schannel_create_ext(glui32 rock, glui32 volume); -extern glui32 glk_schannel_play_multi(schanid_t *chanarray, glui32 chancount, - glui32 *sndarray, glui32 soundcount, glui32 notify); -extern void glk_schannel_pause(schanid_t chan); -extern void glk_schannel_unpause(schanid_t chan); -extern void glk_schannel_set_volume_ext(schanid_t chan, glui32 vol, - glui32 duration, glui32 notify); - -#endif /* GLK_MODULE_SOUND2 */ -#endif /* GLK_MODULE_SOUND */ - -#ifdef GLK_MODULE_HYPERLINKS - -extern void glk_set_hyperlink(glui32 linkval); -extern void glk_set_hyperlink_stream(strid_t str, glui32 linkval); -extern void glk_request_hyperlink_event(winid_t win); -extern void glk_cancel_hyperlink_event(winid_t win); - -#endif /* GLK_MODULE_HYPERLINKS */ - -#ifdef GLK_MODULE_DATETIME - -typedef struct glktimeval_struct { - glsi32 high_sec; - glui32 low_sec; - glsi32 microsec; -} glktimeval_t; - -typedef struct glkdate_struct { - glsi32 year; /* full (four-digit) year */ - glsi32 month; /* 1-12, 1 is January */ - glsi32 day; /* 1-31 */ - glsi32 weekday; /* 0-6, 0 is Sunday */ - glsi32 hour; /* 0-23 */ - glsi32 minute; /* 0-59 */ - glsi32 second; /* 0-59, maybe 60 during a leap second */ - glsi32 microsec; /* 0-999999 */ -} glkdate_t; - -extern void glk_current_time(glktimeval_t *time); -extern glsi32 glk_current_simple_time(glui32 factor); -extern void glk_time_to_date_utc(glktimeval_t *time, glkdate_t *date); -extern void glk_time_to_date_local(glktimeval_t *time, glkdate_t *date); -extern void glk_simple_time_to_date_utc(glsi32 time, glui32 factor, - glkdate_t *date); -extern void glk_simple_time_to_date_local(glsi32 time, glui32 factor, - glkdate_t *date); -extern void glk_date_to_time_utc(glkdate_t *date, glktimeval_t *time); -extern void glk_date_to_time_local(glkdate_t *date, glktimeval_t *time); -extern glsi32 glk_date_to_simple_time_utc(glkdate_t *date, glui32 factor); -extern glsi32 glk_date_to_simple_time_local(glkdate_t *date, glui32 factor); - -#endif /* GLK_MODULE_DATETIME */ - -#ifdef GLK_MODULE_RESOURCE_STREAM - -extern strid_t glk_stream_open_resource(glui32 filenum, glui32 rock); -extern strid_t glk_stream_open_resource_uni(glui32 filenum, glui32 rock); - -#endif /* GLK_MODULE_RESOURCE_STREAM */ - -#endif /* GLK_H */ diff --git a/textworld/thirdparty/glulx/cheapglk/glkstart.c b/textworld/thirdparty/glulx/cheapglk/glkstart.c deleted file mode 100644 index e9baf360..00000000 --- a/textworld/thirdparty/glulx/cheapglk/glkstart.c +++ /dev/null @@ -1,24 +0,0 @@ -/* glkstart.c: Unix-specific startup code -- sample file. - Designed by Andrew Plotkin - http://www.eblong.com/zarf/glk/index.html - - This is Unix startup code for the simplest possible kind of Glk - program -- no command-line arguments; no startup files; no nothing. - - Remember, this is a sample file. You should copy it into the Glk - program you are compiling, and modify it to your needs. This should - *not* be compiled into the Glk library itself. -*/ - -#include "glk.h" -#include "glkstart.h" - -glkunix_argumentlist_t glkunix_arguments[] = { - { NULL, glkunix_arg_End, NULL } -}; - -int glkunix_startup_code(glkunix_startup_t *data) -{ - return TRUE; -} - diff --git a/textworld/thirdparty/glulx/cheapglk/glkstart.h b/textworld/thirdparty/glulx/cheapglk/glkstart.h deleted file mode 100644 index 18266b0a..00000000 --- a/textworld/thirdparty/glulx/cheapglk/glkstart.h +++ /dev/null @@ -1,59 +0,0 @@ -/* glkstart.h: Unix-specific header file for GlkTerm, CheapGlk, and XGlk - (Unix implementations of the Glk API). - Designed by Andrew Plotkin - http://www.eblong.com/zarf/glk/index.html -*/ - -/* This header defines an interface that must be used by program linked - with the various Unix Glk libraries -- at least, the three I wrote. - (I encourage anyone writing a Unix Glk library to use this interface, - but it's not part of the Glk spec.) - - Because Glk is *almost* perfectly portable, this interface *almost* - doesn't have to exist. In practice, it's small. -*/ - -#ifndef GT_START_H -#define GT_START_H - -/* We define our own TRUE and FALSE and NULL, because ANSI - is a strange world. */ -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef NULL -#define NULL 0 -#endif - -#define glkunix_arg_End (0) -#define glkunix_arg_ValueFollows (1) -#define glkunix_arg_NoValue (2) -#define glkunix_arg_ValueCanFollow (3) -#define glkunix_arg_NumberValue (4) - -typedef struct glkunix_argumentlist_struct { - char *name; - int argtype; - char *desc; -} glkunix_argumentlist_t; - -typedef struct glkunix_startup_struct { - int argc; - char **argv; -} glkunix_startup_t; - -extern glkunix_argumentlist_t glkunix_arguments[]; - -extern int glkunix_startup_code(glkunix_startup_t *data); - -extern void glkunix_set_base_file(char *filename); -extern strid_t glkunix_stream_open_pathname_gen(char *pathname, - glui32 writemode, glui32 textmode, glui32 rock); -extern strid_t glkunix_stream_open_pathname(char *pathname, glui32 textmode, - glui32 rock); - -#endif /* GT_START_H */ - diff --git a/textworld/thirdparty/glulx/cheapglk/main.c b/textworld/thirdparty/glulx/cheapglk/main.c deleted file mode 100644 index 7ddc8e8f..00000000 --- a/textworld/thirdparty/glulx/cheapglk/main.c +++ /dev/null @@ -1,271 +0,0 @@ -#include -#include -#include -#include "glk.h" -#include "gi_debug.h" -#include "cheapglk.h" -#include "glkstart.h" -#include "agent.h" - -int gli_screenwidth = 80; -int gli_screenheight = 24; -int gli_utf8output = FALSE; -int gli_utf8input = FALSE; -#if GIDEBUG_LIBRARY_SUPPORT -int gli_debugger = FALSE; -#endif /* GIDEBUG_LIBRARY_SUPPORT */ - -static int inittime = FALSE; - -int main(int argc, char *argv[]) -{ - int ix, jx, val; - int display_version = TRUE; - char* glk_mq_name = NULL; - - int errflag = FALSE; - glkunix_startup_t startdata; - - /* Test for compile-time errors. If one of these spouts off, you - must edit glk.h and recompile. */ - if (sizeof(glui32) != 4) { - printf("Compile-time error: glui32 is not a 32-bit value. Please fix glk.h.\n"); - return 1; - } - if ((glui32)(-1) < 0) { - printf("Compile-time error: glui32 is not unsigned. Please fix glk.h.\n"); - return 1; - } - - /* Now some argument-parsing. This is probably going to hurt. */ - startdata.argc = 0; - startdata.argv = (char **)malloc(argc * sizeof(char *)); - - /* Copy in the program name. */ - startdata.argv[startdata.argc] = argv[0]; - startdata.argc++; - - for (ix=1; ixargtype != glkunix_arg_End && !errflag; - argform++) { - - if (argform->name[0] == '\0') { - if (argv[ix][0] != '-') { - startdata.argv[startdata.argc] = argv[ix]; - startdata.argc++; - inarglist = TRUE; - } - } - else if ((argform->argtype == glkunix_arg_NumberValue) - && !strncmp(argv[ix], argform->name, strlen(argform->name)) - && (cx = argv[ix] + strlen(argform->name)) - && (atoi(cx) != 0 || cx[0] == '0')) { - startdata.argv[startdata.argc] = argv[ix]; - startdata.argc++; - inarglist = TRUE; - } - else if (!strcmp(argv[ix], argform->name)) { - int numeat = 0; - - if (argform->argtype == glkunix_arg_ValueFollows) { - if (ix+1 >= argc) { - printf("%s: %s must be followed by a value\n\n", - argv[0], argform->name); - errflag = TRUE; - break; - } - numeat = 2; - } - else if (argform->argtype == glkunix_arg_NoValue) { - numeat = 1; - } - else if (argform->argtype == glkunix_arg_ValueCanFollow) { - if (ix+1 < argc && argv[ix+1][0] != '-') { - numeat = 2; - } - else { - numeat = 1; - } - } - else if (argform->argtype == glkunix_arg_NumberValue) { - if (ix+1 >= argc - || (atoi(argv[ix+1]) == 0 && argv[ix+1][0] != '0')) { - printf("%s: %s must be followed by a number\n\n", - argv[0], argform->name); - errflag = TRUE; - break; - } - numeat = 2; - } - else { - errflag = TRUE; - break; - } - - for (jx=0; jxargtype != glkunix_arg_End; - argform++) { - if (strlen(argform->name) == 0) - printf(" %s\n", argform->desc); - else if (argform->argtype == glkunix_arg_ValueFollows) - printf(" %s val: %s\n", argform->name, argform->desc); - else if (argform->argtype == glkunix_arg_NumberValue) - printf(" %s val: %s\n", argform->name, argform->desc); - else if (argform->argtype == glkunix_arg_ValueCanFollow) - printf(" %s [val]: %s\n", argform->name, argform->desc); - else - printf(" %s: %s\n", argform->name, argform->desc); - } - } - return 1; - } - - /* Initialize things. */ - gli_initialize_misc(); - - inittime = TRUE; - if (!glkunix_startup_code(&startdata)) { - glk_exit(); - } - inittime = FALSE; - - if (display_version) { - char *debugoption = ""; -#if GIDEBUG_LIBRARY_SUPPORT - if (gli_debugger) - debugoption = " Debug support is on."; -#endif /* GIDEBUG_LIBRARY_SUPPORT */ - printf("Welcome to the Cheap Glk Implementation, library version %s.%s\n\n", - LIBRARY_VERSION, debugoption); - } - - if (gli_debugger) - gidebug_announce_cycle(gidebug_cycle_Start); - - agent_init(glk_mq_name); - glk_main(); - glk_exit(); - - /* glk_exit() doesn't return, but the compiler may kvetch if main() - doesn't seem to return a value. */ - return 0; -} - -/* This opens a file for reading or writing. (You cannot open a file - for appending using this call.) - - This should be used only by glkunix_startup_code(). -*/ -strid_t glkunix_stream_open_pathname_gen(char *pathname, glui32 writemode, - glui32 textmode, glui32 rock) -{ - if (!inittime) - return 0; - return gli_stream_open_pathname(pathname, (writemode != 0), (textmode != 0), rock); -} - -/* This opens a file for reading. It is a less-general form of - glkunix_stream_open_pathname_gen(), preserved for backwards - compatibility. - - This should be used only by glkunix_startup_code(). -*/ -strid_t glkunix_stream_open_pathname(char *pathname, glui32 textmode, - glui32 rock) -{ - if (!inittime) - return 0; - return gli_stream_open_pathname(pathname, FALSE, (textmode != 0), rock); -} diff --git a/textworld/version.py b/textworld/version.py index 4a9b9788..9fd1ca43 100644 --- a/textworld/version.py +++ b/textworld/version.py @@ -1 +1 @@ -__version__ = '1.6.2' +__version__ = '1.7.0rc1' diff --git a/tools/package.sh b/tools/package.sh index 6728be72..2c392880 100755 --- a/tools/package.sh +++ b/tools/package.sh @@ -19,8 +19,6 @@ fi #rm -rf textworld/thirdparty/I7* textworld/thirdparty/inform7-6M62 mkdir -p /tmp/tw_release_bkp mv textworld/thirdparty/I7* textworld/thirdparty/inform7-6M62 /tmp/tw_release_bkp/ -make -C textworld/thirdparty/glulx/Git-Glulx clean -make -C textworld/thirdparty/glulx/cheapglk clean rm -rf build *.egg-info # Check if we are doing a prerelease. @@ -43,4 +41,3 @@ echo -e "\e[33mpython -m twine upload dist/textworld-`sed -r "s/[^']*'(.*)'/\1/" if [[ ! -z $TEXTWORLD_PRERELEASE ]]; then mv /tmp/tw_release_bkp/version.py textworld/ fi -