├── .github └── workflows │ └── main.yml ├── .gitignore ├── .travis.yml ├── .travis ├── setup.sh └── test.sh ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── SECURITY.md ├── docs ├── Makefile ├── make.bat ├── requirements.txt └── source │ ├── conf.py │ ├── defines.rst │ ├── dictionary.rst │ ├── frotz_env.rst │ ├── imgs │ └── jericho.png │ ├── index.rst │ ├── object_tree.rst │ ├── template_action_generator.rst │ ├── tutorial_quick.rst │ └── util.rst ├── frotz ├── AUTHORS ├── BUGS ├── COPYING ├── ChangeLog ├── DOSBUILD.txt ├── DUMB ├── HOW_TO_PLAY ├── INSTALL ├── Makefile ├── Makefile.tc ├── README ├── README.1st ├── TODO ├── build.bat ├── build_test.sh ├── doc │ ├── dfrotz.6 │ ├── frotz.6 │ ├── frotz.conf-big │ └── frotz.conf-small ├── frotz.prj ├── graph.pdf ├── src │ ├── blorb │ │ ├── blorb.h │ │ ├── blorblib.c │ │ └── blorblow.h │ ├── common │ │ ├── .#hotkey.c │ │ ├── buffer.c │ │ ├── defines.h │ │ ├── err.c │ │ ├── fastmem.c │ │ ├── files.c │ │ ├── frotz.h │ │ ├── getopt.c │ │ ├── git_hash.h │ │ ├── hotkey.c │ │ ├── input.c │ │ ├── main.c │ │ ├── math.c │ │ ├── object.c │ │ ├── process.c │ │ ├── quetzal.c │ │ ├── random.c │ │ ├── redirect.c │ │ ├── screen.c │ │ ├── setup.h │ │ ├── sound.c │ │ ├── squetzal.c │ │ ├── stream.c │ │ ├── table.c │ │ ├── text.c │ │ ├── unused.h │ │ └── variable.c │ ├── curses │ │ ├── ux_audio.c │ │ ├── ux_audio_none.c │ │ ├── ux_audio_oss.c │ │ ├── ux_blorb.c │ │ ├── ux_blorb.h │ │ ├── ux_frotz.h │ │ ├── ux_init.c │ │ ├── ux_input.c │ │ ├── ux_locks.c │ │ ├── ux_locks.h │ │ ├── ux_params.txt │ │ ├── ux_pic.c │ │ ├── ux_resource.c │ │ ├── ux_screen.c │ │ ├── ux_setup.h │ │ └── ux_text.c │ ├── dos │ │ ├── bcblorb.c │ │ ├── bcblorb.h │ │ ├── bcfrotz.h │ │ ├── bcinit.c │ │ ├── bcinput.c │ │ ├── bcmouse.c │ │ ├── bcparams.txt │ │ ├── bcpic.c │ │ ├── bcsample.c │ │ ├── bcscreen.c │ │ ├── bctext.c │ │ ├── blorb.h │ │ ├── blorblow.h │ │ └── fontdata.h │ ├── dumb │ │ ├── dumb_blorb.c │ │ ├── dumb_blorb.h │ │ ├── dumb_frotz.h │ │ ├── dumb_init.c │ │ ├── dumb_input.c │ │ ├── dumb_output.c │ │ ├── dumb_params.txt │ │ └── dumb_pic.c │ ├── games │ │ ├── acorncourt.c │ │ ├── advent.c │ │ ├── adventureland.c │ │ ├── afflicted.c │ │ ├── anchor.c │ │ ├── awaken.c │ │ ├── balances.c │ │ ├── ballyhoo.c │ │ ├── curses.c │ │ ├── cutthroat.c │ │ ├── deephome.c │ │ ├── default.c │ │ ├── detective.c │ │ ├── dragon.c │ │ ├── enchanter.c │ │ ├── enter.c │ │ ├── games.h │ │ ├── gold.c │ │ ├── hhgg.c │ │ ├── hollywood.c │ │ ├── huntdark.c │ │ ├── infidel.c │ │ ├── inhumane.c │ │ ├── jewel.c │ │ ├── karn.c │ │ ├── library.c │ │ ├── loose.c │ │ ├── lostpig.c │ │ ├── ludicorp.c │ │ ├── lurking.c │ │ ├── moonlit.c │ │ ├── murdac.c │ │ ├── night.c │ │ ├── nine05.c │ │ ├── omniquest.c │ │ ├── partyfoul.c │ │ ├── pentari.c │ │ ├── planetfall.c │ │ ├── plundered.c │ │ ├── reverb.c │ │ ├── seastalker.c │ │ ├── sherbet.c │ │ ├── sherlock.c │ │ ├── snacktime.c │ │ ├── sorcerer.c │ │ ├── spellbrkr.c │ │ ├── spirit.c │ │ ├── temple.c │ │ ├── textworld.c │ │ ├── theatre.c │ │ ├── trinity.c │ │ ├── tryst.c │ │ ├── weapon.c │ │ ├── wishbringer.c │ │ ├── yomomma.c │ │ ├── zenon.c │ │ ├── zork1.c │ │ ├── zork2.c │ │ ├── zork3.c │ │ └── ztuu.c │ ├── interface │ │ ├── frotz_interface.c │ │ ├── frotz_interface.h │ │ └── md5.c │ ├── misc │ │ ├── findsound.sh │ │ └── twocol.pl │ ├── sdl │ │ ├── samplerate.h │ │ ├── sf_aiffwav.c │ │ ├── sf_deffont.c │ │ ├── sf_font3.c │ │ ├── sf_fonts.c │ │ ├── sf_frotz.h │ │ ├── sf_ftype.c │ │ ├── sf_images.c │ │ ├── sf_msg_en.c │ │ ├── sf_osfdlg.c │ │ ├── sf_resample.c │ │ ├── sf_resource.c │ │ ├── sf_sig.c │ │ ├── sf_sound.c │ │ ├── sf_util.c │ │ └── sf_video.c │ ├── test │ │ ├── README │ │ ├── crashme.inf │ │ ├── crashme.z5 │ │ ├── etude │ │ │ ├── Makefile │ │ │ ├── README │ │ │ ├── accentin.inc │ │ │ ├── accents.inc │ │ │ ├── color.inc │ │ │ ├── division.inc │ │ │ ├── etude.inf │ │ │ ├── etude.z5 │ │ │ ├── exittext.inc │ │ │ ├── givenin.inc │ │ │ ├── header.inc │ │ │ ├── styles.inc │ │ │ ├── timedch.inc │ │ │ ├── timedstr.inc │ │ │ └── undo.inc │ │ ├── gntests.inf │ │ ├── gntests.z5 │ │ ├── random.inf │ │ ├── random.z5 │ │ ├── strictz.inf │ │ ├── strictz.z5 │ │ ├── unicode.inf │ │ └── unicode.z5 │ └── ztools │ │ ├── getopt.c │ │ ├── infinfo.c │ │ ├── infodump.c │ │ ├── inforead.c │ │ ├── makefile │ │ ├── showdict.c │ │ ├── showhead.c │ │ ├── showobj.c │ │ ├── showverb.c │ │ ├── symbols.c │ │ ├── tx.h │ │ ├── txd.c │ │ ├── txio.c │ │ └── ztools.h └── test.c ├── jericho ├── __init__.py ├── clubfloyd_verb_counts.json ├── defines.py ├── examples │ └── random_agent.py ├── game_info.py ├── jericho.py ├── template_action_generator.py ├── util.py └── version.py ├── requirements.txt ├── setup.py ├── tests ├── benchmarks.py ├── data │ ├── 905.z5 │ ├── dummy.z8 │ ├── tw-cooking-recipe3+cook+cut-2057SPdQu0mWiv0k.z8 │ └── tw-game.z8 ├── test_jericho.py ├── test_textworld_games.py ├── test_unsupported_game.py └── test_valid_actions.py └── tools ├── find_walkthrough.py └── test_games.py /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: "Tests" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [ "master" ] 9 | schedule: 10 | - cron: '20 17 * * 5' 11 | 12 | jobs: 13 | tests: 14 | name: Test on ${{ matrix.os }} with ${{ matrix.python_version }} and ${{ matrix.compiler }} 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: [ubuntu-latest, macos-latest] 20 | python_version: ['3.12'] #['3.9', '3.10', '3.11', '3.12'] 21 | compiler: ['clang', 'gcc', 'clang-15'] 22 | exclude: 23 | - os: ubuntu-latest 24 | compiler: 'clang-15' 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v3 29 | - name: Set up python 30 | uses: actions/setup-python@v4 31 | with: 32 | python-version: ${{ matrix.python_version }} 33 | - name: Install dependencies 34 | env: 35 | CC: ${{ matrix.compiler }} 36 | run: | 37 | python -m pip install --upgrade pip pytest pytest-asyncio 38 | pip install -vv -e '.' 39 | if: matrix.compiler != 'clang-15' 40 | - name: Install dependencies (clang-15) 41 | env: 42 | CC: clang 43 | run: | 44 | ln -s $(brew --prefix llvm@15)/bin/clang /usr/local/bin/clang 45 | python -m pip install --upgrade pip pytest pytest-asyncio 46 | pip install -vv -e '.' 47 | if: matrix.compiler == 'clang-15' 48 | - name: Test with pytest 49 | run: | 50 | pytest -vv tests/ 51 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: python 4 | 5 | matrix: 6 | include: 7 | - os: linux 8 | python: "3.5" 9 | - os: linux 10 | python: "3.6" 11 | - os: osx 12 | language: generic 13 | 14 | install: 15 | - ./.travis/setup.sh 16 | 17 | script: 18 | - ./.travis/test.sh 19 | -------------------------------------------------------------------------------- /.travis/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ $TRAVIS_OS_NAME == "osx" ]]; then 6 | pip3 install virtualenv 7 | virtualenv -p python3 venv 8 | . ./venv/bin/activate 9 | fi 10 | 11 | pip install . 12 | pip install nose coverage 13 | python -m spacy download en_core_web_sm 14 | -------------------------------------------------------------------------------- /.travis/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ $TRAVIS_OS_NAME == "osx" ]]; then 6 | . ./venv/bin/activate 7 | fi 8 | 9 | nosetests -sv 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to 4 | agree to a Contributor License Agreement (CLA) declaring that you have the right to, 5 | and actually do, grant us the rights to use your contribution. For details, visit 6 | https://cla.microsoft.com. 7 | 8 | When you submit a pull request, a CLA-bot will automatically determine whether you need 9 | to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the 10 | instructions provided by the bot. You will only need to do this once across all repositories using our CLA. 11 | 12 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 13 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 14 | or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include frotz * 2 | include jericho/clubfloyd_verb_counts.json 3 | include requirements.txt -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | Cython 2 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | import sphinx_rtd_theme 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'jericho' 23 | copyright = '2019, Matthew Hausknecht' 24 | author = 'Matthew Hausknecht' 25 | 26 | # The full version, including alpha/beta/rc tags 27 | release = '1.3.1' 28 | 29 | import os 30 | import sys 31 | sys.path.insert(0, os.path.abspath('..')) 32 | 33 | master_doc = 'index' 34 | 35 | # -- General configuration --------------------------------------------------- 36 | 37 | # Add any Sphinx extension module names here, as strings. They can be 38 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 39 | # ones. 40 | extensions = ['sphinx.ext.autodoc'] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # List of patterns, relative to source directory, that match files and 46 | # directories to ignore when looking for source files. 47 | # This pattern also affects html_static_path and html_extra_path. 48 | exclude_patterns = [] 49 | 50 | 51 | # -- Options for HTML output ------------------------------------------------- 52 | 53 | # The theme to use for HTML and HTML Help pages. See the documentation for 54 | # a list of builtin themes. 55 | # 56 | html_theme = 'sphinx_rtd_theme' 57 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 58 | 59 | # Add any paths that contain custom static files (such as style sheets) here, 60 | # relative to this directory. They are copied after the builtin static files, 61 | # so a file named "default.css" will overwrite the builtin "default.css". 62 | html_static_path = ['_static'] 63 | -------------------------------------------------------------------------------- /docs/source/defines.rst: -------------------------------------------------------------------------------- 1 | Defines 2 | ======= 3 | 4 | .. automodule:: jericho.defines 5 | 6 | .. autodata:: jericho.defines.ILLEGAL_ACTIONS 7 | :annotation: 8 | 9 | .. autodata:: jericho.defines.BASIC_ACTIONS 10 | 11 | .. autodata:: jericho.defines.NO_EFFECT_ACTIONS 12 | 13 | .. autodata:: jericho.defines.UNRECOGNIZED_REGEXPS 14 | :annotation: 15 | 16 | .. autodata:: jericho.defines.ABBRV_DICT 17 | 18 | .. autoclass:: jericho.defines.TemplateAction 19 | -------------------------------------------------------------------------------- /docs/source/dictionary.rst: -------------------------------------------------------------------------------- 1 | Game Dictionary 2 | =============== 3 | 4 | Jericho allows access to the dictionary of a game through :meth:`jericho.FrotzEnv.get_dictionary`. The dictionary contains a list of :class:`jericho.DictionaryWord` that are recognized by the game's parser. 5 | 6 | .. autoclass:: jericho.DictionaryWord 7 | :members: 8 | -------------------------------------------------------------------------------- /docs/source/frotz_env.rst: -------------------------------------------------------------------------------- 1 | Frotz Environment 2 | ================= 3 | 4 | The Frotz Environment is the interface between a learning agent and an interactive fiction game. 5 | 6 | .. autoclass:: jericho.FrotzEnv 7 | :members: 8 | -------------------------------------------------------------------------------- /docs/source/imgs/jericho.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/docs/source/imgs/jericho.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. jericho documentation master file, created by 2 | sphinx-quickstart on Wed Sep 25 14:27:03 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Jericho documentation 7 | =================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | :caption: Tutorials 12 | 13 | tutorial_quick 14 | 15 | .. toctree:: 16 | :maxdepth: 1 17 | :caption: Core Library 18 | 19 | frotz_env 20 | object_tree 21 | dictionary 22 | template_action_generator 23 | util 24 | defines 25 | 26 | 27 | Indices and tables 28 | ================== 29 | 30 | * :ref:`genindex` 31 | * :ref:`modindex` 32 | * :ref:`search` 33 | -------------------------------------------------------------------------------- /docs/source/object_tree.rst: -------------------------------------------------------------------------------- 1 | Object Tree 2 | =========== 3 | 4 | The Object Tree is an internal representation of all locations and objects present in a Z-machine game, including the player and their inventory. 5 | 6 | Each object has *parent*, *child*, and *sibling* object. Parent objects typically contain the child objects. For example if we have a parent object *Treasure Chest*, it may contain a child object *Cutlass* that has a sibling object *Eye Patch*. And the treasure chest may have a parent object *Sandy Beach* corresponding to the location of the chest. If and when the player reaches the Sandy Beach, the object tree will be rearranged so that the player-object's sibling will become the Treasure Chest. 7 | 8 | Objects additionally have attributes which are set and unset to keep track of the state of an object. For example a *window* can either be in the open or closed position; this is tracked through its attributes. 9 | Finally, the *properties* of an object are numerical values that determine how the object may be interacted with. 10 | 11 | For a great tutorial on the Object Tree, see `Z-Machine Standards `_. 12 | 13 | In Jericho, the full object tree can be accessed with :meth:`jericho.FrotzEnv.get_world_objects`. Jericho also provides shortcuts to particular objects of interest such as the player :meth:`jericho.FrotzEnv.get_player_object`, the player's location :meth:`jericho.FrotzEnv.get_player_location`, and the player's inventory :meth:`jericho.FrotzEnv.get_inventory`. 14 | 15 | ZObject 16 | ------- 17 | 18 | Jericho's ZObject is a ctypes structure that providing access to the name, parent, sibling, child, attributes, and properties of an object. 19 | 20 | .. autoclass:: jericho.ZObject 21 | :members: 22 | -------------------------------------------------------------------------------- /docs/source/template_action_generator.rst: -------------------------------------------------------------------------------- 1 | Template Action Generator 2 | ========================= 3 | 4 | The TemplateActionGenerator is designed to facilitate action generation using a game-specific template-action space. 5 | 6 | .. autoclass:: jericho.template_action_generator.TemplateActionGenerator 7 | :members: 8 | -------------------------------------------------------------------------------- /docs/source/util.rst: -------------------------------------------------------------------------------- 1 | Utilities 2 | ========= 3 | 4 | .. automodule:: jericho.util 5 | :members: 6 | -------------------------------------------------------------------------------- /frotz/AUTHORS: -------------------------------------------------------------------------------- 1 | Original Frotz reference code: 2 | Stefan Jokisch 3 | 4 | Original Unix port: 5 | Galen Hazelwood 6 | 7 | Current Custodian: 8 | David Griffith 9 | 10 | Other Authors: 11 | Alembic Petrofsky 12 | Jim Dunleavy 13 | 14 | 15 | Thanks also to those who posted to rec.arts.int-fiction and 16 | intfiction.org feedback on what I was doing with Unix Frotz, people who 17 | checked the betas for bugs, and sent in patches. These include, but are 18 | not limited to: 19 | 20 | Torbjorn Anderson, Timo Korvola, Martin Frost, Mihail Milushev, David 21 | Picton, Archturiat Baumann, Leonard Richardson, Stephen Kitt, Paul E 22 | Coad, Paul Janzen, Brad Town, Jason C Penney, Denis Hirschfeldt, Jacob 23 | Nevins, Matteo De Luigi, Steven Frank, Thomas Troeger, David Kinder, and 24 | others that I've forgotten. 25 | 26 | Michael Edmonson (author of Rezrov) and Evin Robertson (author of Nitfol) 27 | deserve recognition for the ideas that I've borrowed from their programs. 28 | 29 | Thanks goes to Erik de Castro Lopo, author of libsndfile and 30 | libsamplerate for putting up with my numerous questions about audio 31 | programming and gently nudging me towards how to do things the right 32 | way. 33 | -------------------------------------------------------------------------------- /frotz/DOSBUILD.txt: -------------------------------------------------------------------------------- 1 | =========================================================================== 2 | --------------------------------------------------------------------------- 3 | | READ THIS FILE ALL THE WAY THROUGH BEFORE ATTEMPTING TO INSTALL FROTZ | 4 | --------------------------------------------------------------------------- 5 | =========================================================================== 6 | 7 | Frotz was originally written specifically for MS/PC DOS. When it began 8 | to be ported to other machines and operating systems, the DOS port 9 | lagged behind. This has been fixed to the extent that DOS is capable of 10 | the new enhancements. For instance, DOS Frotz is now capable of using 11 | Blorb files to get audio and graphical data. The old Infocom-style 12 | mechanism of doing this has been removed. Sound is supported through 13 | Soundblaster compatible sound cards. Graphic levels from Hercules to 14 | MCGA are supported. 15 | 16 | To compile DOS Frotz, you need the following: 17 | * Borland Turbo C++ 3.00. This is the latest version I'm aware 18 | of capable of building 16-bit DOS applications. 19 | * PC-DOS, MS-DOS, or DR-DOS version 5.0 or higher. 20 | FreeDOS works well too. 21 | 22 | ============== 23 | Compilation || 24 | ============== 25 | 26 | Turbo C++ is typically installed to C:\tc. Make sure your path contains 27 | C:\tc\bin. When this is done, type "make". Did Borland's make program 28 | run? Now type "tcc". If those two commands work, then you should be 29 | ready to compile. 30 | 31 | Somehow get the source tree onto your DOS machine or into a DOS 32 | emulation environment. If you're using emulation, this should be as 33 | simple as copying the tree you're in now into the proper directory. For 34 | real hardware, a floppy disk will do. 35 | 36 | To compile, go into the Frotz directory and type "build". That will 37 | invoke "build.bat", a batch file that simply executes "make -f 38 | makefile.tc". The reason for this is a bit of syntactic sugar to deal 39 | with the fact that it is impractical to have one Makefile build both 40 | Unix and DOS versions. After about a minute, you should have FROTZ.EXE. 41 | This file is all you need to run Frotz. Put it somewhere in your path 42 | and go to wherever you keep your Infocom games. Type "frotz zork1.dat" 43 | or whatever and there you go. 44 | 45 | ======================== 46 | Hardware Requirements || 47 | ======================== 48 | 49 | The exact hardware requirements of DOS Frotz are yet to be determined. 50 | Please send me reports of what Zcode works and what doesn't. 51 | -------------------------------------------------------------------------------- /frotz/DUMB: -------------------------------------------------------------------------------- 1 | The dumb interface was mainly intended for those who wanted to play 2 | Interactive Fiction, but had just a C compiler and that's it. You get 3 | no screen control; everything is just printed to the terminal line by 4 | line. The terminal handles all the scrolling. While this can be an 5 | annoying way to play IF, it might be the best you can do for a 6 | particular machine, especially when the curses library is inadequate and 7 | installing ncurses isn't an option. It's also good for getting Frotz to 8 | run when you have a C compiler and know nothing else of how to do 9 | things. This way you can run Frotz on VMS, MVS, VM/CMS and all those 10 | other stodgy operating system. More on that later. Maybe you'd like to 11 | experience what it's like to play Adventure on a teletype. 12 | 13 | A much cooler use for compiling Frotz with the dumb interface is that it 14 | can be wrapped in CGI scripting, PHP, and the like to allow people to 15 | play games on webpages. It can also be made into a chat bot. 16 | 17 | Games that move the write little windows of text over the main body of 18 | text are hard to read because with the dumb interface, Frotz doesn't 19 | know how to produce inverse text. Games that make use of timed-input 20 | can be played, but you must manually increment the timer (see the dfrotz 21 | manpage). Games that move the cursor around a lot are probably 22 | unplayable. These include games like Andrew Plotkin's "Freefall" and 23 | Torbjorn Andersson's "Robots". 24 | 25 | The dumb interface code was created by Alembic Petrofsky 26 | in 1997 for Frotz 2.32. 27 | -------------------------------------------------------------------------------- /frotz/Makefile.tc: -------------------------------------------------------------------------------- 1 | # This file is used to build Frotz for DOS using Borland Turbo C++ 3.00. 2 | # The resulting executable runs as a 16-bit program. 3 | # -O or higher optimization causes problems in quetzal.c 4 | # 5 | 6 | CC = tcc 7 | CFLAGS = -ml -N 8 | TLIB = tlib 9 | CP = copy 10 | RM = del 11 | RENAME = ren 12 | 13 | 14 | BINNAME = frotz.exe 15 | LIBRARY = frotz.lib 16 | 17 | SOUND_DEF = -DSOUND_SUPPORT 18 | DOS_DEF = -DMSDOS_16BIT 19 | 20 | DEFS = $(SOUND_DEF) $(DOS_DEF) 21 | 22 | DOS_DIR = src\dos 23 | DOS_OBJECTS = $(DOS_DIR)\bcinit.o \ 24 | $(DOS_DIR)\bcinput.o \ 25 | $(DOS_DIR)\bcmouse.o \ 26 | $(DOS_DIR)\bcpic.o \ 27 | $(DOS_DIR)\bcsample.o \ 28 | $(DOS_DIR)\bcscreen.o \ 29 | $(DOS_DIR)\bctext.o \ 30 | $(DOS_DIR)\bcblorb.o 31 | 32 | CORE_DIR = src\common 33 | CORE_OBJECTS = $(CORE_DIR)\buffer.o \ 34 | $(CORE_DIR)\fastmem.o \ 35 | $(CORE_DIR)\files.o \ 36 | $(CORE_DIR)\getopt.o \ 37 | $(CORE_DIR)\hotkey.o \ 38 | $(CORE_DIR)\input.o \ 39 | $(CORE_DIR)\main.o \ 40 | $(CORE_DIR)\math.o \ 41 | $(CORE_DIR)\object.o \ 42 | $(CORE_DIR)\process.o \ 43 | $(CORE_DIR)\random.o \ 44 | $(CORE_DIR)\redirect.o \ 45 | $(CORE_DIR)\screen.o \ 46 | $(CORE_DIR)\sound.o \ 47 | $(CORE_DIR)\stream.o \ 48 | $(CORE_DIR)\table.o \ 49 | $(CORE_DIR)\text.o \ 50 | $(CORE_DIR)\variable.o \ 51 | $(CORE_DIR)\quetzal.o \ 52 | $(CORE_DIR)\err.o 53 | 54 | .SUFFIXES: .c .o .h 55 | 56 | .c.o: 57 | $(CC) $(CFLAGS) $(DEFS) -I$(DOS_DIR) -I$(CORE_DIR) -c -o$@ $< 58 | $(TLIB) $(LIBRARY) +-$@ 59 | 60 | all: frotz 61 | 62 | clean: 63 | $(RM) $(CORE_DIR)\*.o 64 | $(RM) $(DOS_DIR)\*.o 65 | $(RM) *.lib 66 | $(RM) *.exe 67 | $(RM) *.bak 68 | 69 | frotz: $(DOS_OBJECTS) $(CORE_OBJECTS) 70 | $(CC) $(CFLAGS) -e$(BINNAME) $(LIBRARY) 71 | -------------------------------------------------------------------------------- /frotz/README: -------------------------------------------------------------------------------- 1 | FROTZ V2.45pre - An interpreter for all Infocom and other Z-machine games. 2 | Complies with standard 1.0 of Graham Nelson's specification. 3 | 4 | Originally written by Stefan Jokisch in 1995-1997. 5 | Ported to Unix by Galen Hazelwood. 6 | Reference code and Unix port currently maintained by David Griffith. 7 | 8 | - Compiles and runs on most common flavors of Unix, both open source and not. 9 | - Plays all Z-code games including V6. 10 | - Old-style sound support through OSS driver. 11 | - Config files. 12 | - Configurable error checking. 13 | - Distributed under the GNU Public License. 14 | 15 | 16 | For information on what Interactive Fiction is and how to play it, see the 17 | file "HOW_TO_PLAY". 18 | 19 | For installation information, see the file "INSTALL". 20 | 21 | For update history, see the file "Changelog". 22 | 23 | For information on known bugs in Frotz, see the file "BUGS". 24 | 25 | For bug reports, check the Unix Frotz website to see if there's a new 26 | release. If not, send your bug report to me at dave@661.org. 27 | 28 | The latest information on and source code of Unix Frotz is available at 29 | https://github.com/DavidGriffith/frotz 30 | 31 | The latest release of Unix Frotz is available from the Interactive 32 | Fiction Archive at: 33 | http://www.ifarchive.org/if-archive/infocom/interpreters/frotz/ 34 | frotz-.tar.gz 35 | and 36 | ftp://ftp.ifarchive.org/if-archive/infocom/interpreters/frotz/ 37 | frotz-.tar.gz 38 | 39 | 40 | The Interactive Fiction Archive has several mirrors which may be better 41 | choices depending on where you live. Here is a partial list. 42 | 43 | in the USA: http://mirror.ifarchive.org/ 44 | http://ifarchive.jmac.org/ 45 | http://ifmirror.russotto.net/ 46 | http://ifarchive.flavorplex.com/ 47 | http://ifarchive.smallwhitehouse.org/ 48 | http://ifarchive.wurb.com/ 49 | http://ifarchive.plover.net/ 50 | http://www.ifarchive.info/ 51 | http://ifarchive.ifreviews.org/ 52 | http://mirrors.ibiblio.org/interactive-fiction/ 53 | in Ireland: http://ifarchive.heanet.ie/ 54 | in Austria: http://ifarchive.giga.or.at/ 55 | 56 | FTP based mirrors are also available: 57 | 58 | in the USA: ftp://ifarchive.ifreviews.org/if-archive/ 59 | in Austria: ftp://ftp.giga.or.at/pub/ifarchive/ 60 | in Finland: ftp://ftp.funet.fi/pub/mirrors/ftp.ifarchive.org/if-archive/ 61 | 62 | And via Gopher: 63 | 64 | in the USA: gopher://gopher.feedle.net/1/if-archive/ 65 | -------------------------------------------------------------------------------- /frotz/README.1st: -------------------------------------------------------------------------------- 1 | What are all these files for? 2 | 3 | AUTHORS People who've had a hand in making Frotz what it is. 4 | BUGS A list of known bugs and workarounds (if known). 5 | build.bat A batch file for building Frotz for PC/MS DOS. 6 | COPYING Full text of the GNU General Public License. 7 | ChangeLog Summary of changes from one version to another. 8 | DOSBUILD.txt How to build and install Frotz for PC/MS DOS. 9 | DUMB Description of the dumb-interface version of Frotz. 10 | HOW_TO_PLAY How to play Interactive Fiction. 11 | INSTALL How to build and install Frotz. 12 | Makefile The Makefile (the INSTALL file tells you about this). 13 | Makefile.tc Makefile for building Frotz for DOS. 14 | PORTING Notes about porting Frotz to new machines and operating systems. 15 | README An overview of Frotz. 16 | README.1st This file. 17 | TODO Stuff to do in no particular order. 18 | 19 | doc/ Manpages and sample config files. 20 | src/ Source code to Frotz. 21 | -------------------------------------------------------------------------------- /frotz/TODO: -------------------------------------------------------------------------------- 1 | Redo how the core and interfaces use the f_setup structure. Failure to 2 | do this properly led to a segfault when dumb frotz saves a game. 3 | Look at using a memset() or calloc() there. 4 | 5 | 6 | Rework os_process_arguments() in src/curses/ux_init.c to make Frotz more 7 | convenient to use as a BBS door or MUD module. 8 | 9 | Add mouse support through. Not sure how useful this would be, but 10 | someone did ask. 11 | 12 | Remove debug options from command line. They should be set through the 13 | hotkey menu instead 14 | 15 | Hotkey menu needs work. 16 | 17 | Blink the screen instead of ringing the bell when in quiet mode. 18 | 19 | Add zlib support to allow Frotz to read gzipped story files. 20 | 21 | Add support for debug verbs (teleport, pilfer, bamf, (frotz|futz|lumen), 22 | tail, travis, lummox, systolic, lingo, spiel, rooms, items, omap, 23 | embezzle). I really like the Rezrov's cheat functions. 24 | 25 | Give the hotmenu a full ncurses-based interface. This would allow MUCH 26 | more flexibility in configuring Frotz. 27 | 28 | More sensible handling of saves, transcripts, and game files. 29 | 30 | Curses menu to select desired game. Current working code heavily 31 | borrowed from Alan Shutko's "int-fiction" 32 | frontend program. 33 | 34 | An X11 graphical interface using GTK widgets (thus allowing V6 full support). 35 | 36 | Cocoa support for OSX. 37 | -------------------------------------------------------------------------------- /frotz/build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM This batch file is for compiling Frotz using Turbo C++ 3.00 for DOS. 3 | REM It's just a bit of syntactic sugar so I don't have to always 4 | REM remember that I need to specify the other Makefile for DOS 5 | REM compilation. DG 6 | make -f makefile.tc %1 7 | -------------------------------------------------------------------------------- /frotz/build_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gcc -g -o test test.c -I src/interface/ -I src/ztools/ -Wl,-rpath=src -Lsrc -lfrotz 4 | -------------------------------------------------------------------------------- /frotz/doc/frotz.conf-big: -------------------------------------------------------------------------------- 1 | # This is a sample Unix Frotz configuration file which contains examples 2 | # of all supported options. 3 | 4 | # If this is actually $HOME/.frotzrc instead of the systemwide 5 | # configuration file, $HOME/.frotzrc will override. These options are 6 | # explained in more detail in the Unix Frotz README file and the manpage. 7 | 8 | 9 | ############################################################ 10 | # These options control some basic characteristics of Frotz. 11 | 12 | # Use color text (default "yes" if supported) 13 | color yes 14 | 15 | # Set foreground color (default "white" if in color mode) 16 | foreground white 17 | 18 | # Set background color (default "blue" if in color mode) 19 | background blue 20 | 21 | # Set error-reporting mode (default "once") 22 | errormode once 23 | 24 | # Set path to search for game files (no default) 25 | zcode_path /usr/local/games/zcode 26 | 27 | # Use plain ASCII only (default "no") 28 | ascii no 29 | 30 | # Turn sound on or off (default "on") 31 | sound on 32 | 33 | 34 | ############################################ 35 | # These are some less-commonly used options. 36 | 37 | # Set random number seed (default comes from the Unix epoch) 38 | randseed 1234 39 | 40 | # Set number of undo slots (default 500) 41 | undo_slots 500 42 | 43 | # Set Tandy bit (default "no") 44 | tandy no 45 | 46 | # Alter piracy opcode (default "no") 47 | piracy no 48 | 49 | # Expand abbreviations (default "no") 50 | expand_abb no 51 | 52 | 53 | ######################################################################### 54 | # These options are useful for weird terminals or if you want to force a 55 | # certain mode. 56 | 57 | # Force color mode (default "no") 58 | # Useful for use with supposedly current flavors of Unix that still don't 59 | # understand what the "xterm-color" terminal type is. 60 | force_color no 61 | 62 | # Set screen height (default is detected height) 63 | screen_height 24 64 | 65 | # Set screen width (default is detected screen width) 66 | screen_width 80 67 | 68 | # Set script width (default is screen width) 69 | script_width 80 70 | 71 | # Set context lines (default "0") 72 | context_lines 0 73 | 74 | # Set left margin (default "0") 75 | left_margin 0 76 | 77 | # Set right margin (default "0") 78 | right_margin 0 79 | 80 | 81 | ############################################################# 82 | # These options are mainly useful for debugging and cheating. 83 | 84 | # Watch attribute setting (default "no") 85 | attrib_set no 86 | 87 | # Watch attribute testing (default "no") 88 | attrib_test no 89 | 90 | # Watch object movement (default "no") 91 | obj_move no 92 | 93 | # Watch object locating (default "no") 94 | obj_loc no 95 | -------------------------------------------------------------------------------- /frotz/doc/frotz.conf-small: -------------------------------------------------------------------------------- 1 | # This is a basic sample Unix Frotz configuration file. It contains some 2 | # a few options the average user is likely to want to change. 3 | 4 | # If this is actually $HOME/.frotzrc instead of the systemwide 5 | # configuration file, $HOME/.frotzrc will override. These options are 6 | # explained in more detail in the Unix Frotz README file and the manpage. 7 | 8 | 9 | color yes 10 | foreground white 11 | backgrounnd black 12 | zcode_path /usr/local/games/zcode 13 | errormode once 14 | ascii no 15 | sound on 16 | 17 | -------------------------------------------------------------------------------- /frotz/frotz.prj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/frotz.prj -------------------------------------------------------------------------------- /frotz/graph.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/graph.pdf -------------------------------------------------------------------------------- /frotz/src/blorb/blorblow.h: -------------------------------------------------------------------------------- 1 | #ifndef BLORBLOW_H 2 | #define BLORBLOW_H 3 | 4 | /* blorblow.h: Low-level header file for Blorb library, version 1.0.2. 5 | Designed by Andrew Plotkin 6 | http://www.eblong.com/zarf/blorb/index.html 7 | 8 | This header is generally of interest only to the Blorb library code 9 | itself (blorblib.c); it defines things internal to the library. 10 | An interpreter shouldn't have to include this file. The only time you 11 | might need to include this is if you're writing a Blorb file analysis 12 | tool (such as blorbscan), or a transformation tool, or some such thing. 13 | */ 14 | 15 | /* More four-byte constants. */ 16 | 17 | #define bb_ID_FORM (bb_make_id('F', 'O', 'R', 'M')) 18 | #define bb_ID_IFRS (bb_make_id('I', 'F', 'R', 'S')) 19 | #define bb_ID_RIdx (bb_make_id('R', 'I', 'd', 'x')) 20 | #define bb_ID_IFhd (bb_make_id('I', 'F', 'h', 'd')) 21 | #define bb_ID_Reso (bb_make_id('R', 'e', 's', 'o')) 22 | #define bb_ID_Loop (bb_make_id('L', 'o', 'o', 'p')) 23 | #define bb_ID_RelN (bb_make_id('R', 'e', 'l', 'N')) 24 | #define bb_ID_Plte (bb_make_id('P', 'l', 't', 'e')) 25 | 26 | /* bb_chunkdesc_t: Describes one chunk of the Blorb file. */ 27 | typedef struct bb_chunkdesc_struct { 28 | uint32 type; 29 | uint32 len; 30 | uint32 startpos; /* start of chunk header */ 31 | uint32 datpos; /* start of data (either startpos or startpos+8) */ 32 | 33 | void *ptr; /* pointer to malloc'd data, if loaded */ 34 | int auxdatnum; /* entry in the auxsound/auxpict array; -1 if none. 35 | This only applies to chunks that represent resources; */ 36 | 37 | } bb_chunkdesc_t; 38 | 39 | /* bb_resdesc_t: Describes one resource in the Blorb file. */ 40 | typedef struct bb_resdesc_struct { 41 | uint32 usage; 42 | int resnum; 43 | int chunknum; 44 | } bb_resdesc_t; 45 | 46 | /* bb_map_t: Holds the complete description of an open Blorb file. */ 47 | struct bb_map_struct { 48 | uint32 inited; /* holds bb_Inited_Magic if the map structure is valid */ 49 | FILE *file; 50 | 51 | int numchunks; 52 | bb_chunkdesc_t *chunks; /* list of chunk descriptors */ 53 | 54 | int numresources; 55 | bb_resdesc_t *resources; /* list of resource descriptors */ 56 | bb_resdesc_t **ressorted; /* list of pointers to descriptors 57 | in map->resources -- sorted by usage and resource number. */ 58 | 59 | bb_zheader_t *zheader; 60 | int releasenum; 61 | bb_resolution_t *resolution; 62 | int palettechunk; /* chunk number of palette, or -1 if there is none. */ 63 | bb_palette_t *palette; 64 | bb_aux_sound_t *auxsound; /* extra information about sounds */ 65 | bb_aux_pict_t *auxpict; /* extra information about pictures */ 66 | }; 67 | 68 | #define bb_Inited_Magic (0xB7012BED) 69 | 70 | extern char *bb_id_to_string(uint32 id); 71 | 72 | #endif /* BLORBLOW_H */ 73 | -------------------------------------------------------------------------------- /frotz/src/common/.#hotkey.c: -------------------------------------------------------------------------------- 1 | matthew@cantor.25864:1512989276 -------------------------------------------------------------------------------- /frotz/src/common/defines.h: -------------------------------------------------------------------------------- 1 | #define VERSION "2.45pre" 2 | -------------------------------------------------------------------------------- /frotz/src/common/getopt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * getopt.c 3 | * 4 | * Replacement for a Unix style getopt function 5 | * 6 | * Quick, clean, and portable to funky systems that don't have getopt() 7 | * for whatever reason. 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #ifndef MSDOS_16BIT 15 | #define cdecl 16 | #endif 17 | 18 | int optind = 1; 19 | int optopt = 0; 20 | 21 | const char *optarg = NULL; 22 | 23 | int cdecl getopt (int argc, char *argv[], const char *options) 24 | { 25 | static int pos = 1; 26 | 27 | const char *p; 28 | 29 | if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == 0) 30 | return EOF; 31 | 32 | optopt = argv[optind][pos++]; 33 | optarg = NULL; 34 | 35 | if (argv[optind][pos] == 0) 36 | { pos = 1; optind++; } 37 | 38 | p = strchr (options, optopt); 39 | 40 | if (optopt == ':' || p == NULL) { 41 | 42 | fputs ("illegal option -- ", stdout); 43 | goto error; 44 | 45 | } else if (p[1] == ':') { 46 | 47 | if (optind >= argc) { 48 | 49 | fputs ("option requires an argument -- ", stdout); 50 | goto error; 51 | 52 | } else { 53 | 54 | optarg = argv[optind]; 55 | 56 | if (pos != 1) 57 | optarg += pos; 58 | 59 | pos = 1; optind++; 60 | 61 | } 62 | } 63 | return optopt; 64 | 65 | error: 66 | 67 | fputc (optopt, stdout); 68 | fputc ('\n', stdout); 69 | 70 | return '?'; 71 | 72 | }/* getopt */ 73 | -------------------------------------------------------------------------------- /frotz/src/common/git_hash.h: -------------------------------------------------------------------------------- 1 | #define GIT_HASH "f31bcb937c45d45ad3136f6459621edca2f949a6" 2 | #define GIT_HASH_SHORT "f31bcb9" 3 | #define GIT_TAG "" 4 | #define GIT_BRANCH "master" 5 | -------------------------------------------------------------------------------- /frotz/src/common/random.c: -------------------------------------------------------------------------------- 1 | /* random.c - Z-machine random number generator 2 | * Copyright (c) 1995-1997 Stefan Jokisch 3 | * 4 | * This file is part of Frotz. 5 | * 6 | * Frotz is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Frotz is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 | */ 20 | 21 | #include "frotz.h" 22 | 23 | static long A = 1; 24 | 25 | static int interval = 0; 26 | static int counter = 0; 27 | 28 | 29 | /* 30 | * Functions to get the state of the random number generator. 31 | * 32 | */ 33 | 34 | long getRngA() { 35 | return A; 36 | } 37 | 38 | int getRngInterval() { 39 | return interval; 40 | } 41 | 42 | int getRngCounter() { 43 | return counter; 44 | } 45 | 46 | 47 | /* 48 | * set_rng 49 | * 50 | * Set the state of the random number generator. 51 | * 52 | */ 53 | void setRng(long p_A, int p_interval, int p_counter) { 54 | A = p_A; 55 | interval = p_interval; 56 | counter = p_counter; 57 | } 58 | 59 | 60 | /* 61 | * seed_random 62 | * 63 | * Set the seed value for the random number generator. 64 | * 65 | */ 66 | void seed_random (int value) 67 | { 68 | 69 | if (value == 0) { /* ask interface for seed value */ 70 | A = os_random_seed (); 71 | interval = 0; 72 | } else if (value < 1000) { /* special seed value */ 73 | counter = 0; 74 | interval = value; 75 | } else { /* standard seed value */ 76 | A = value; 77 | interval = 0; 78 | } 79 | 80 | }/* seed_random */ 81 | 82 | 83 | /* 84 | * z_random, store a random number or set the random number seed. 85 | * 86 | * zargs[0] = range (positive) or seed value (negative) 87 | * 88 | */ 89 | void z_random () 90 | { 91 | if ((short) zargs[0] <= 0) { /* set random seed */ 92 | 93 | seed_random (- (short) zargs[0]); 94 | store (0); 95 | 96 | } else { /* generate random number */ 97 | 98 | zword result; 99 | 100 | if (interval != 0) { /* ...in special mode */ 101 | result = counter++; 102 | if (counter == interval) counter = 0; 103 | } else { /* ...in standard mode */ 104 | A = 0x015a4e35L * A + 1; 105 | result = (A >> 16) & 0x7fff; 106 | } 107 | 108 | store ((zword) (result % zargs[0] + 1)); 109 | } 110 | 111 | }/* z_random */ 112 | -------------------------------------------------------------------------------- /frotz/src/common/setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Various status thingies for the interpreter and interface. 3 | * 4 | */ 5 | 6 | typedef struct frotz_setup_struct { 7 | int attribute_assignment; /* done */ 8 | int attribute_testing; /* done */ 9 | int context_lines; /* done */ 10 | int object_locating; /* done */ 11 | int object_movement; /* done */ 12 | int left_margin; /* done */ 13 | int right_margin; /* done */ 14 | int ignore_errors; /* done */ 15 | int interpreter_number; /* Just dumb frotz now */ 16 | int piracy; /* done */ 17 | int undo_slots; /* done */ 18 | int expand_abbreviations; /* done */ 19 | int script_cols; /* done */ 20 | int sound; /* done */ 21 | int err_report_mode; /* done */ 22 | 23 | char *story_file; 24 | char *story_name; 25 | char *story_base; 26 | char *script_name; 27 | char *command_name; 28 | char *save_name; 29 | char *tmp_save_name; 30 | char *aux_name; 31 | char *story_path; 32 | char *zcode_path; 33 | void *story_rom; 34 | size_t story_rom_size; 35 | char *restricted_path; 36 | int restore_mode; /* for a save file passed from command line*/ 37 | 38 | bool use_blorb; 39 | bool exec_in_blorb; 40 | } f_setup_t; 41 | 42 | extern f_setup_t f_setup; 43 | 44 | /*** Story file header data ***/ 45 | /* 46 | typedef struct zcode_header_struct { 47 | zbyte version; 48 | zbyte config; 49 | zword release; 50 | zword resident_size; 51 | zword start_pc; 52 | zword dictionary; 53 | zword objects; 54 | zword globals; 55 | zword dynamic_size; 56 | zword flags; 57 | zbyte serial[6]; 58 | zword abbreviations; 59 | zword file_size; 60 | zword checksum; 61 | zbyte interpreter_number; 62 | zbyte interpreter_version; 63 | zbyte screen_rows; 64 | zbyte screen_cols; 65 | zword screen_width; 66 | zword screen_height; 67 | zbyte font_height; 68 | zbyte font_width; 69 | zword functions_offset; 70 | zword strings_offset; 71 | zbyte default_background; 72 | zbyte default_foreground; 73 | zword terminating_keys; 74 | zword line_width; 75 | zbyte standard_high; 76 | zbyte standard_low; 77 | zword alphabet; 78 | zword extension_table; 79 | zbyte user_name[8]; 80 | 81 | zword hx_table_size; 82 | zword hx_mouse_x; 83 | zword hx_mouse_y; 84 | zword hx_unicode_table; 85 | } z_header_t; 86 | extern z_header_t z_header; 87 | */ 88 | -------------------------------------------------------------------------------- /frotz/src/common/unused.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Insired by code from Martin Pool. 3 | */ 4 | 5 | #ifndef COMMON_UNUSED_H 6 | #define COMMON_UNUSED_H 7 | 8 | #ifdef UNUSED 9 | #elif defined (__GNUC__) 10 | # define UNUSED(x) UNUSED_ ## x __attribute__ ((unused)) 11 | #elif defined (__LCLINT__) 12 | # define UNUSED(x) /*@unused@*/ x 13 | #else 14 | # define UNUSED(x) x 15 | #endif 16 | 17 | #ifdef __GNUC__ 18 | # define WARN_UNUSED __attribute__ ((warn_unused_result)) 19 | #else 20 | # define WARN_UNUSED 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_blorb.h: -------------------------------------------------------------------------------- 1 | 2 | #include "../blorb/blorb.h" 3 | #include "../blorb/blorblow.h" 4 | 5 | 6 | typedef struct sampledata_struct { 7 | unsigned short channels; 8 | unsigned long samples; 9 | unsigned short bits; 10 | double rate; 11 | } sampledata_t; 12 | 13 | 14 | /* 15 | * The bb_result_t struct lacks a few members that would make things a 16 | * bit easier. The myresource struct takes encapsulates the bb_result_t 17 | * struct and adds a type member and a filepointer. I would like to 18 | * convince Andrew Plotkin to make a change in the reference Blorb code 19 | * to add these members. 20 | * 21 | */ 22 | typedef struct { 23 | bb_result_t bbres; 24 | // ulong type; 25 | unsigned long type; 26 | FILE *fp; 27 | } myresource; 28 | 29 | extern bb_err_t blorb_err; 30 | extern bb_map_t *blorb_map; 31 | extern bb_result_t blorb_res; 32 | extern FILE *blorb_fp; 33 | 34 | bb_err_t ux_blorb_init(char *); 35 | void ux_blorb_stop(void); 36 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_frotz.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ux_frotz.h 3 | * 4 | * Unix interface, declarations, definitions, and defaults 5 | * 6 | */ 7 | 8 | #include "defines.h" 9 | #include "../common/frotz.h" 10 | #include "../blorb/blorb.h" 11 | #include "../blorb/blorblow.h" 12 | #include "ux_setup.h" 13 | 14 | #ifndef rindex 15 | #define rindex strrchr 16 | #endif 17 | 18 | #define MASTER_CONFIG "frotz.conf" 19 | #define USER_CONFIG ".frotzrc" 20 | #define ASCII_DEF 1 21 | #define ATTRIB_ASSIG_DEF 0 22 | #define ATTRIB_TEST_DEF 0 23 | #define COLOR_DEF 1 24 | #define ERROR_HALT_DEF 0 25 | #define EXPAND_DEF 0 26 | #define PIRACY_DEF 0 27 | #define TANDY_DEF 0 28 | #define OBJ_MOVE_DEF 0 29 | #define OBJ_LOC_DEF 0 30 | #define BACKGROUND_DEF BLACK_COLOUR 31 | #define FOREGROUND_DEF WHITE_COLOUR 32 | #define HEIGHT_DEF -1 /* let curses figure it out */ 33 | #define CONTEXTLINES_DEF 0 34 | #define WIDTH_DEF 80 35 | #define TWIDTH_DEF 80 36 | #define SEED_DEF -1 37 | #define SLOTS_DEF MAX_UNDO_SLOTS 38 | #define LMARGIN_DEF 0 39 | #define RMARGIN_DEF 0 40 | #define ERR_REPORT_DEF ERR_REPORT_ONCE 41 | #define QUETZAL_DEF 1 42 | #define SAVEDIR_DEF "if-saves" 43 | #define ZCODEPATH_DEF "/usr/games/zcode:/usr/local/games/zcode" 44 | 45 | 46 | #define LINELEN 256 /* for getconfig() */ 47 | #define COMMENT '#' /* for config files */ 48 | #define PATHSEP ':' /* for pathopen() */ 49 | #define DIRSEP '/' /* for pathopen() */ 50 | 51 | #define EDITMODE_EMACS 0 52 | #define EDITMODE_VI 1 53 | 54 | #define PIC_NUMBER 0 55 | #define PIC_WIDTH 2 56 | #define PIC_HEIGHT 4 57 | #define PIC_FLAGS 6 58 | #define PIC_DATA 8 59 | #define PIC_COLOUR 11 60 | 61 | 62 | /* Paths where z-files may be found */ 63 | #define PATH1 "ZCODE_PATH" 64 | #define PATH2 "INFOCOM_PATH" 65 | 66 | 67 | /* Some regular curses (not ncurses) libraries don't do this correctly. */ 68 | #ifndef getmaxyx 69 | #define getmaxyx(w, y, x) (y) = getmaxy(w), (x) = getmaxx(w) 70 | #endif 71 | 72 | extern bool color_enabled; /* ux_text */ 73 | 74 | extern char stripped_story_name[FILENAME_MAX+1]; 75 | extern char semi_stripped_story_name[FILENAME_MAX+1]; 76 | extern char *progname; 77 | extern char *gamepath; /* use to find sound files */ 78 | 79 | extern f_setup_t f_setup; 80 | extern u_setup_t u_setup; 81 | 82 | /*** Functions specific to the Unix port of Frotz ***/ 83 | 84 | bool unix_init_pictures(void); /* ux_pic.c */ 85 | bool unix_init_pictures(void); /* ux_pic.c */ 86 | void unix_init_scrollback(void); /* ux_screen.c */ 87 | void unix_save_screen(int); /* ux_screen.c */ 88 | void unix_do_scrollback(void); /* ux_screen.c */ 89 | 90 | #ifdef NO_STRRCHR 91 | char *strrchr(const char *, int); 92 | #endif 93 | 94 | #ifdef NO_MEMMOVE 95 | void *memmove(void *, void *); 96 | #endif 97 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_locks.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "ux_locks.h" 6 | 7 | static bool music_playing = false; 8 | static pthread_mutex_t music_playing_mutex = PTHREAD_MUTEX_INITIALIZER; 9 | 10 | static int musicnum = 0; 11 | static pthread_mutex_t musicnum_mutex = PTHREAD_MUTEX_INITIALIZER; 12 | 13 | bool 14 | get_music_playing (void) 15 | { 16 | bool value; 17 | 18 | pthread_mutex_lock (&music_playing_mutex); 19 | value = music_playing; 20 | pthread_mutex_unlock (&music_playing_mutex); 21 | return value; 22 | } 23 | 24 | 25 | bool 26 | set_music_playing (bool new_value) 27 | { 28 | bool old_value; 29 | 30 | pthread_mutex_lock (&music_playing_mutex); 31 | old_value = music_playing; 32 | music_playing = new_value; 33 | pthread_mutex_unlock (&music_playing_mutex); 34 | return old_value; 35 | } 36 | 37 | 38 | int 39 | get_musicnum (void) 40 | { 41 | int value; 42 | 43 | pthread_mutex_lock (&musicnum_mutex); 44 | value = musicnum; 45 | pthread_mutex_unlock (&musicnum_mutex); 46 | return value; 47 | } 48 | 49 | 50 | int 51 | set_musicnum (int new_value) 52 | { 53 | int old_value; 54 | 55 | pthread_mutex_lock (&musicnum_mutex); 56 | old_value = musicnum; 57 | musicnum = new_value; 58 | pthread_mutex_unlock (&musicnum_mutex); 59 | return old_value; 60 | } 61 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_locks.h: -------------------------------------------------------------------------------- 1 | bool get_music_playing (void); 2 | bool set_music_playing (bool new_value); 3 | 4 | int get_musicnum (void); 5 | int set_musicnum (int new_value); 6 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_params.txt: -------------------------------------------------------------------------------- 1 | -a watch attribute setting 2 | -A watch attribute testing 3 | -b background color 4 | -c # context lines 5 | -d disable color 6 | -e enable sound 7 | -f foreground color 8 | -F Force color mode 9 | -h # screen height 10 | -i ignore fatal errors 11 | -l # left margin 12 | -L load this save file 13 | -o watch object movement 14 | -O watch object locating 15 | -p plain ASCII output only 16 | -P alter piracy opcode 17 | -q quiet (disable sound effects) 18 | -r # right margin 19 | -R restricted read/write 20 | -s # random number seed value 21 | -S # transcript width 22 | -t set Tandy bit 23 | -u # slots for multiple undo 24 | -v show version information 25 | -w # screen width 26 | -x expand abbreviations g/x/z 27 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_resource.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "ux_frotz.h" 7 | #include "ux_blorb.h" 8 | 9 | bb_map_t *blorb_map; 10 | 11 | 12 | /* 13 | * ux_getresource 14 | * 15 | * Load a bb_result_t struct (encapsulated within myresource struct) 16 | * with information about a resource. We need two other facts about the 17 | * chunk to do something intelligent later: a filepointer and type 18 | * (gotten from the bb_map_t struct). I'll have to talk to Zarf about 19 | * possibly modifying the bb_result_t struct in the reference version of 20 | * the Blorb library. 21 | * 22 | */ 23 | int ux_getresource( int num, int ispic, int method, myresource * res) 24 | { 25 | int st; 26 | // ulong usage; 27 | unsigned long usage; 28 | 29 | res->bbres.data.ptr = NULL; 30 | res->fp = NULL; 31 | 32 | if (!blorb_map) return bb_err_NotFound; 33 | 34 | if (ispic) 35 | usage = bb_ID_Pict; 36 | else 37 | usage = bb_ID_Snd; 38 | 39 | st = bb_load_resource(blorb_map, method, (bb_result_t *) res, usage, num); 40 | 41 | if (st == bb_err_None) { 42 | res->type = blorb_map->chunks[res->bbres.chunknum].type; 43 | if (method == bb_method_FilePos) 44 | res->fp = blorb_fp; 45 | } 46 | return st; 47 | } 48 | 49 | 50 | /* 51 | * ux_freeresource 52 | * 53 | * Destroys a myresource struct and returns the memory to the heap. 54 | * 55 | */ 56 | int ux_freeresource(myresource *res) 57 | { 58 | if (res == NULL) 59 | return 0; 60 | 61 | if (blorb_map != NULL) 62 | return bb_unload_chunk(blorb_map, res->bbres.chunknum); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /frotz/src/curses/ux_setup.h: -------------------------------------------------------------------------------- 1 | typedef struct unix_setup_struct { 2 | int disable_color; 3 | int force_color; 4 | int foreground_color; 5 | int background_color; 6 | int screen_width; 7 | int screen_height; 8 | int random_seed; 9 | int tandy_bit; 10 | int current_text_style; /* also in ux_text.c and ux_screen.c */ 11 | int curses_active; 12 | int plain_ascii; 13 | int current_color; /* ux_text.c ux_screen.c */ 14 | bool color_enabled; /* ux_init.c ux_pic.c ux_text.c */ 15 | int interpreter; /* see frotz.h */ 16 | } u_setup_t; 17 | 18 | extern u_setup_t u_setup; 19 | 20 | -------------------------------------------------------------------------------- /frotz/src/dos/bcblorb.h: -------------------------------------------------------------------------------- 1 | #include "blorb.h" 2 | #include "blorblow.h" 3 | 4 | 5 | typedef struct sampledata_struct { 6 | unsigned short channels; 7 | unsigned long samples; 8 | unsigned short bits; 9 | double rate; 10 | } sampledata_t; 11 | 12 | 13 | bb_err_t blorb_err; 14 | bb_map_t *blorb_map; 15 | bb_result_t blorb_res; 16 | 17 | 18 | /* uint32 *findchunk(uint32 *data, char *chunkID, int length); */ 19 | char *findchunk(char *pstart, char *fourcc, int n); 20 | unsigned short ReadShort(const unsigned char *bytes); 21 | unsigned long ReadLong(const unsigned char *bytes); 22 | double ReadExtended(const unsigned char *bytes); 23 | 24 | #define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0) 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /frotz/src/dos/bcfrotz.h: -------------------------------------------------------------------------------- 1 | /* 2 | * "BCfrotz.h" 3 | * 4 | * Borland C interface, declarations 5 | * 6 | */ 7 | 8 | #define MASK_LINEAR(addr) (addr & 0x000FFFFF) 9 | #define RM_TO_LINEAR(addr) (((addr & 0xFFFF0000) >> 12) + (addr & 0xFFFF)) 10 | #define RM_OFFSET(addr) (addr & 0xF) 11 | #define RM_SEGMENT(addr) ((addr >> 4) & 0xFFFF) 12 | 13 | #define OS_PATHSEP ';' 14 | 15 | #define byte0(v) ((byte *)&v)[0] 16 | #define byte1(v) ((byte *)&v)[1] 17 | #define byte2(v) ((byte *)&v)[2] 18 | #define byte3(v) ((byte *)&v)[3] 19 | #define word0(v) ((word *)&v)[0] 20 | #define word1(v) ((word *)&v)[1] 21 | 22 | #ifndef HISTORY_MIN_ENTRY 23 | #define HISTORY_MIN_ENTRY 1 24 | #endif 25 | 26 | #define SPECIAL_KEY_MIN 256 27 | #define SPECIAL_KEY_HOME 256 28 | #define SPECIAL_KEY_END 257 29 | #define SPECIAL_KEY_WORD_LEFT 258 30 | #define SPECIAL_KEY_WORD_RIGHT 259 31 | #define SPECIAL_KEY_DELETE 260 32 | #define SPECIAL_KEY_INSERT 261 33 | #define SPECIAL_KEY_PAGE_UP 262 34 | #define SPECIAL_KEY_PAGE_DOWN 263 35 | #define SPECIAL_KEY_TAB 264 36 | #define SPECIAL_KEY_MAX 264 37 | 38 | #define _MONO_ 0 39 | #define _TEXT_ 1 40 | #define _CGA_ 2 41 | #define _MCGA_ 3 42 | #define _EGA_ 4 43 | #define _AMIGA_ 5 44 | 45 | typedef unsigned char byte; 46 | typedef unsigned short word; 47 | 48 | extern display; 49 | 50 | extern cursor_x; 51 | extern cursor_y; 52 | 53 | extern char latin1_to_ibm[]; 54 | extern char latin1_to_ascii[]; 55 | 56 | extern byte text_bg; 57 | extern byte text_fg; 58 | 59 | extern byte scrn_attr; 60 | 61 | extern user_background; 62 | extern user_foreground; 63 | extern user_emphasis; 64 | extern user_reverse_bg; 65 | extern user_reverse_fg; 66 | extern user_screen_height; 67 | extern user_screen_width; 68 | extern user_tandy_bit; 69 | extern user_bold_typing; 70 | extern user_random_seed; 71 | extern user_font; 72 | 73 | extern char stripped_story_name[]; 74 | extern char *prog_name; 75 | 76 | extern current_bg; 77 | extern current_fg; 78 | extern current_style; 79 | extern current_font; 80 | 81 | extern scaler; 82 | 83 | #ifdef SOUND_SUPPORT 84 | extern volatile int end_of_sound_flag; 85 | #endif 86 | 87 | /* BCinit */ int dectoi (const char *); 88 | /* BCinit */ int hextoi (const char *); 89 | /* BCmouse */ bool detect_mouse (void); 90 | /* BCmouse */ int read_mouse (void); 91 | /* BCpic */ bool init_pictures (void); 92 | /* BCpic */ void reset_pictures (void); 93 | 94 | #ifdef SOUND_SUPPORT 95 | /* BCsmpl */ bool dos_init_sound (void); 96 | /* BCsmpl */ void dos_reset_sound (void); 97 | /* BCinput */ void end_of_sound(void); 98 | #endif 99 | /* BCtext */ void switch_scrn_attr (bool); 100 | /* BCtext */ void load_fonts (void); 101 | -------------------------------------------------------------------------------- /frotz/src/dos/bcmouse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * file "BCmouse.c" 3 | * 4 | * Borland C front end, mouse support 5 | * 6 | */ 7 | 8 | #include 9 | #include "frotz.h" 10 | #include "bcfrotz.h" 11 | 12 | /* 13 | * detect_mouse 14 | * 15 | * Return true if a mouse driver is present. 16 | * 17 | */ 18 | 19 | bool detect_mouse (void) 20 | { 21 | 22 | asm xor ax,ax 23 | asm int 0x33 24 | 25 | return _AX; 26 | 27 | }/* detect_mouse */ 28 | 29 | /* 30 | * read_mouse 31 | * 32 | * Report any mouse clicks. Return 2 for a double click, 1 for a single 33 | * click or 0 if there was no mouse activity at all. 34 | * 35 | */ 36 | 37 | int read_mouse (void) 38 | { 39 | int click; 40 | 41 | /* Read the current mouse status */ 42 | 43 | for (click = 0; click < 2; click++) { 44 | 45 | if (click == 1) 46 | delay (222); 47 | 48 | asm mov ax,6 49 | asm xor bx,bx 50 | asm int 0x33 51 | 52 | if (_BX == 0) 53 | break; 54 | 55 | mouse_x = _CX; 56 | mouse_y = _DX; 57 | 58 | if (display <= _TEXT_) { 59 | mouse_x /= 8; 60 | mouse_y /= 8; 61 | } 62 | 63 | if (display == _MCGA_) 64 | mouse_x /= 2; 65 | 66 | mouse_x++; 67 | mouse_y++; 68 | 69 | } 70 | 71 | /* Return single or double click */ 72 | 73 | return click; 74 | 75 | }/* read_mouse */ 76 | -------------------------------------------------------------------------------- /frotz/src/dos/bcparams.txt: -------------------------------------------------------------------------------- 1 | -a watch attribute setting 2 | -A watch attribute testing 3 | -b # background colour 4 | -B # reverse background colour 5 | -c # context lines 6 | -d # display mode (see below) 7 | -e # emphasis colour [mode 1] 8 | -f # foreground colour 9 | -F # reverse foreground colour 10 | -g # font [mode 5] (see below) 11 | -h # screen height 12 | -i ignore runtime errors 13 | -l # left margin 14 | -o watch object movement 15 | -O watch object locating 16 | -p alter piracy opcode 17 | -r # right margin 18 | -R restricted read/write 19 | -s # random number seed value 20 | -S # transscript width 21 | -t set Tandy bit 22 | -T bold typing [modes 2+4+5] 23 | -u # slots for multiple undo 24 | -w # screen width 25 | -x expand abbreviations g/x/z 26 | -Z # error checking (see below) 27 | -------------------------------------------------------------------------------- /frotz/src/dos/blorblow.h: -------------------------------------------------------------------------------- 1 | #ifndef BLORBLOW_H 2 | #define BLORBLOW_H 3 | 4 | /* blorblow.h: Low-level header file for Blorb library, version 1.0.2. 5 | Designed by Andrew Plotkin 6 | http://www.eblong.com/zarf/blorb/index.html 7 | 8 | This header is generally of interest only to the Blorb library code 9 | itself (blorblib.c); it defines things internal to the library. 10 | An interpreter shouldn't have to include this file. The only time you 11 | might need to include this is if you're writing a Blorb file analysis 12 | tool (such as blorbscan), or a transformation tool, or some such thing. 13 | */ 14 | 15 | /* More four-byte constants. */ 16 | 17 | #define bb_ID_FORM 1179603533 18 | #define bb_ID_IFRS 1229345363 19 | #define bb_ID_RIdx 1380541560 20 | #define bb_ID_IFhd 1229351012 21 | #define bb_ID_Reso 1382380399 22 | #define bb_ID_Loop 1282371440 23 | #define bb_ID_RelN 1382378574 24 | #define bb_ID_Plte 1349284965 25 | 26 | /* bb_chunkdesc_t: Describes one chunk of the Blorb file. */ 27 | typedef struct bb_chunkdesc_struct { 28 | uint32 type; 29 | uint32 len; 30 | uint32 startpos; /* start of chunk header */ 31 | uint32 datpos; /* start of data (either startpos or startpos+8) */ 32 | 33 | void *ptr; /* pointer to malloc'd data, if loaded */ 34 | int auxdatnum; /* entry in the auxsound/auxpict array; -1 if none. 35 | This only applies to chunks that represent resources; */ 36 | 37 | } bb_chunkdesc_t; 38 | 39 | /* bb_resdesc_t: Describes one resource in the Blorb file. */ 40 | typedef struct bb_resdesc_struct { 41 | uint32 usage; 42 | int resnum; 43 | int chunknum; 44 | } bb_resdesc_t; 45 | 46 | /* bb_map_t: Holds the complete description of an open Blorb file. */ 47 | struct bb_map_struct { 48 | uint32 inited; /* holds bb_Inited_Magic if the map structure is valid */ 49 | FILE *file; 50 | 51 | int numchunks; 52 | bb_chunkdesc_t *chunks; /* list of chunk descriptors */ 53 | 54 | int numresources; 55 | bb_resdesc_t *resources; /* list of resource descriptors */ 56 | bb_resdesc_t **ressorted; /* list of pointers to descriptors 57 | in map->resources -- sorted by usage and resource number. */ 58 | 59 | bb_zheader_t *zheader; 60 | int releasenum; 61 | bb_resolution_t *resolution; 62 | int palettechunk; /* chunk number of palette, or -1 if there is none. */ 63 | bb_palette_t *palette; 64 | bb_aux_sound_t *auxsound; /* extra information about sounds */ 65 | bb_aux_pict_t *auxpict; /* extra information about pictures */ 66 | }; 67 | 68 | #define bb_Inited_Magic (0xB7012BED) 69 | 70 | extern char *bb_id_to_string(uint32 id); 71 | 72 | #endif /* BLORBLOW_H */ 73 | -------------------------------------------------------------------------------- /frotz/src/dumb/dumb_blorb.h: -------------------------------------------------------------------------------- 1 | #include "../blorb/blorb.h" 2 | #include "../blorb/blorblow.h" 3 | 4 | 5 | typedef struct sampledata_struct { 6 | unsigned short channels; 7 | unsigned long samples; 8 | unsigned short bits; 9 | double rate; 10 | } sampledata_t; 11 | 12 | 13 | /* 14 | * The bb_result_t struct lacks a few members that would make things a 15 | * bit easier. The myresource struct takes encapsulates the bb_result_t 16 | * struct and adds a type member and a filepointer. I would like to 17 | * convince Andrew Plotkin to make a change in the reference Blorb code 18 | * to add these members. 19 | * 20 | */ 21 | typedef struct { 22 | bb_result_t bbres; 23 | unsigned long type; 24 | FILE *fp; 25 | } myresource; 26 | 27 | extern bb_err_t blorb_err; 28 | extern bb_map_t *blorb_map; 29 | extern bb_result_t blorb_res; 30 | extern FILE *blorb_fp; 31 | 32 | bb_err_t dumb_blorb_init(char *); 33 | void dumb_blorb_stop(void); 34 | -------------------------------------------------------------------------------- /frotz/src/dumb/dumb_frotz.h: -------------------------------------------------------------------------------- 1 | #ifndef dumb_frotz_h__ 2 | #define dumb_frotz_h__ 3 | 4 | /* dumb-frotz.h 5 | * 6 | * Frotz os functions for a standard C library and a dumb terminal. 7 | * Now you can finally play Zork Zero on your Teletype. 8 | * 9 | * Copyright 1997, 1998 Alembic Petrofsky . 10 | * Any use permitted provided this notice stays intact. 11 | */ 12 | #include "../common/frotz.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* from ../common/setup.h */ 21 | extern f_setup_t f_setup; 22 | 23 | extern bool do_more_prompts; 24 | 25 | /* From input.c. */ 26 | bool is_terminator (zchar); 27 | 28 | /* dumb-input.c */ 29 | bool dumb_handle_setting(const char *setting, bool show_cursor, bool startup); 30 | void dumb_init_input(void); 31 | void load_story(char *s); 32 | 33 | /* dumb-output.c */ 34 | void dumb_init_output(void); 35 | bool dumb_output_handle_setting(const char *setting, bool show_cursor, 36 | bool startup); 37 | void dumb_show_screen(bool show_cursor); 38 | void dumb_show_prompt(bool show_cursor, char line_type); 39 | void dumb_dump_screen(void); 40 | void dumb_display_user_input(char *); 41 | void dumb_discard_old_input(int num_chars); 42 | void dumb_elide_more_prompt(void); 43 | void dumb_set_picture_cell(int row, int col, char c); 44 | void dumb_row_to_str(char *s); 45 | void dumb_clear_output(void); 46 | char* dumb_get_screen(void); 47 | void dumb_clear_screen(void); 48 | 49 | /* dumb-pic.c */ 50 | void dumb_init_pictures(char *graphics_filename); 51 | 52 | void dumb_set_next_action(char *s); 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /frotz/src/dumb/dumb_params.txt: -------------------------------------------------------------------------------- 1 | -a watch attribute setting 2 | -A watch attribute testing 3 | -h # screen height 4 | -i ignore fatal errors 5 | -I # interpreter number 6 | -o watch object movement 7 | -O watch object locating 8 | -L load this save file 9 | -m turn off MORE prompts 10 | -p plain ASCII output only 11 | -P alter piracy opcode 12 | -R restricted read/write 13 | -s # random number seed value 14 | -S # transcript width 15 | -t set Tandy bit 16 | -u # slots for multiple undo 17 | -v show version information 18 | -w # screen width 19 | -x expand abbreviations g/x/z 20 | -------------------------------------------------------------------------------- /frotz/src/games/advent.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Adventure: http://ifdb.tads.org/viewgame?id=fft6pu91j85y4acv 26 | 27 | const zword advent_special_ram_addrs[5] = { 28 | 15198, // Kill dragon 29 | 15191, // Pour water on plant 30 | 15287, // Give food to bear 31 | 15282, // Bear following you 32 | 15642, // FEE/FIE/FOE/FOO 33 | }; 34 | 35 | zword* advent_ram_addrs(int *n) { 36 | *n = 5; 37 | return advent_special_ram_addrs; 38 | } 39 | 40 | char** advent_intro_actions(int *n) { 41 | *n = 0; 42 | return NULL; 43 | } 44 | 45 | char* advent_clean_observation(char* obs) { 46 | char* pch; 47 | pch = strchr(obs, '>'); 48 | if (pch != NULL) { 49 | *(pch-2) = '\0'; 50 | } 51 | return obs+1; 52 | } 53 | 54 | int advent_victory() { 55 | char *victory_text = "*** You have won ***"; 56 | if (strstr(world, victory_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int advent_game_over() { 63 | char *death_text = "Do you want me to try to reincarnate you?"; 64 | if (strstr(world, death_text)) { 65 | return 1; 66 | } 67 | return 0; 68 | } 69 | 70 | int advent_get_self_object_num() { 71 | return 20; 72 | } 73 | 74 | int advent_get_moves() { 75 | return (((short) zmp[15361]) << 8) | zmp[15362]; // Also 15342 76 | } 77 | 78 | short advent_get_score() { 79 | return (((short) zmp[15371]) << 8) | zmp[15372]; // Also 15374, 15340 80 | } 81 | 82 | int advent_max_score() { 83 | return 350; 84 | } 85 | 86 | int advent_get_num_world_objs() { 87 | return 255; 88 | } 89 | 90 | int advent_ignore_moved_obj(zword obj_num, zword dest_num) { 91 | return 0; 92 | } 93 | 94 | int advent_ignore_attr_diff(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | int advent_ignore_attr_clr(zword obj_num, zword attr_idx) { 101 | if (attr_idx == 25) 102 | return 1; 103 | return 0; 104 | } 105 | 106 | void advent_clean_world_objs(zobject* objs) { 107 | } 108 | -------------------------------------------------------------------------------- /frotz/src/games/adventureland.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Adventureland: http://ifdb.tads.org/viewgame?id=dy4ok8sdlut6ddj7 26 | 27 | const zword adventureland_special_ram_addrs[1] = { 28 | 1231 // Activated take/drink water 29 | }; 30 | 31 | zword* adventureland_ram_addrs(int *n) { 32 | *n = 1; 33 | return adventureland_special_ram_addrs; 34 | } 35 | 36 | char** adventureland_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* adventureland_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '>'); 44 | if (pch != NULL) { 45 | *(pch-2) = '\0'; 46 | } 47 | return obs+1; 48 | } 49 | 50 | int adventureland_victory() { 51 | char *death_text = "*** You have won ***"; 52 | if (strstr(world, death_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int adventureland_game_over() { 59 | char *death_text = "*** You have died ***"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int adventureland_get_self_object_num() { 67 | return 20; 68 | } 69 | 70 | int adventureland_get_moves() { 71 | return (((short) zmp[5320]) << 8) | zmp[5321]; // Also 5331 72 | } 73 | 74 | short adventureland_get_score() { 75 | return zmp[5319]; // Also 5329, 5345 76 | } 77 | 78 | int adventureland_max_score() { 79 | return 100; 80 | } 81 | 82 | int adventureland_get_num_world_objs() { 83 | return 106; 84 | } 85 | 86 | int adventureland_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int adventureland_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | if (attr_idx == 2 || attr_idx == 25) 92 | return 1; 93 | return 0; 94 | } 95 | 96 | int adventureland_ignore_attr_clr(zword obj_num, zword attr_idx) { 97 | if (attr_idx == 2 || attr_idx == 25) 98 | return 1; 99 | return 0; 100 | } 101 | 102 | void adventureland_clean_world_objs(zobject* objs) { 103 | int i; 104 | char mask; 105 | mask = ~(1 << 6) & ~(1 << 7); 106 | // Clear attr 24 & 25 107 | for (i=1; i<=adventureland_get_num_world_objs(); ++i) { 108 | objs[i].attr[3] &= mask; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /frotz/src/games/afflicted.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Afflicted: http://ifdb.tads.org/viewgame?id=epl4q2933rczoo9x 26 | 27 | int score = 0; 28 | 29 | zword* afflicted_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** afflicted_intro_actions(int *n) { 35 | *n = 0; 36 | return NULL; 37 | } 38 | 39 | void parse_score(char* obs) { 40 | char* pch = obs; 41 | char* old = pch; 42 | while (TRUE) { 43 | pch = strchr(pch, ':'); 44 | if (pch == NULL) { 45 | break; 46 | } 47 | pch++; 48 | old = pch; 49 | } 50 | score = -strtol(old, &old, 10); 51 | } 52 | 53 | char* afflicted_clean_observation(char* obs) { 54 | parse_score(obs); 55 | char* pch; 56 | pch = strchr(obs, '>'); 57 | if (pch != NULL) { 58 | *(pch-2) = '\0'; 59 | } 60 | return obs+1; 61 | } 62 | 63 | int afflicted_victory() { 64 | char *death_text = "*** You have won ***"; 65 | if (strstr(world, death_text)) { 66 | return 1; 67 | } 68 | return 0; 69 | } 70 | 71 | int afflicted_game_over() { 72 | char *death_text = "*** You've been convicted. ***"; 73 | if (strstr(world, death_text)) { 74 | return 1; 75 | } 76 | return 0; 77 | } 78 | 79 | int afflicted_get_self_object_num() { 80 | return 57; 81 | } 82 | 83 | int afflicted_get_moves() { 84 | return (((short) zmp[24991]) << 8) | zmp[24992]; // 25032, 25034 85 | } 86 | 87 | short afflicted_get_score() { 88 | return score; 89 | } 90 | 91 | int afflicted_max_score() { 92 | return 75; 93 | } 94 | 95 | int afflicted_get_num_world_objs() { 96 | return 237; 97 | } 98 | 99 | int afflicted_ignore_moved_obj(zword obj_num, zword dest_num) { 100 | return 0; 101 | } 102 | 103 | int afflicted_ignore_attr_diff(zword obj_num, zword attr_idx) { 104 | if (attr_idx == 30 || attr_idx == 11 || attr_idx == 34 || attr_idx == 21) 105 | return 1; 106 | return 0; 107 | } 108 | 109 | int afflicted_ignore_attr_clr(zword obj_num, zword attr_idx) { 110 | if (attr_idx == 30) 111 | return 1; 112 | return 0; 113 | } 114 | 115 | void afflicted_clean_world_objs(zobject* objs) { 116 | } 117 | -------------------------------------------------------------------------------- /frotz/src/games/anchor.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Anchorhead: http://ifdb.tads.org/viewgame?id=op0uw1gn1tjqmjt7 26 | 27 | const char *anchor_intro[] = { "\n", "\n", "\n" }; 28 | 29 | const zword anchor_special_ram_addrs[4] = { 30 | 21922, // Combination lock 31 | 40660, // Bathe 32 | 38470, // Transitions between days 33 | 37992, // Sleep 34 | }; 35 | 36 | zword* anchor_ram_addrs(int *n) { 37 | *n = 4; 38 | return anchor_special_ram_addrs; 39 | } 40 | 41 | char** anchor_intro_actions(int *n) { 42 | *n = 3; 43 | return anchor_intro; 44 | } 45 | 46 | char* anchor_clean_observation(char* obs) { 47 | char* pch; 48 | pch = strchr(obs, '>'); 49 | if (pch != NULL) { 50 | *(pch-2) = '\0'; 51 | } 52 | return obs+1; 53 | } 54 | 55 | int anchor_victory() { 56 | char *death_text = "**** You have won ****"; 57 | if (strstr(world, death_text)) { 58 | return 1; 59 | } 60 | return 0; 61 | } 62 | 63 | int anchor_game_over() { 64 | char *death_text = "Do you want me to try to reincarnate you?"; 65 | char *death_text2 = "Would you like to RESTART, RESTORE a saved game, UNDO"; 66 | if (strstr(world, death_text) || strstr(world, death_text2)) { 67 | return 1; 68 | } 69 | return 0; 70 | } 71 | 72 | int anchor_get_self_object_num() { 73 | return 20; 74 | } 75 | 76 | int anchor_get_moves() { 77 | return (((short) zmp[37999]) << 8) | zmp[38000]; //38012 78 | } 79 | 80 | short anchor_get_score() { 81 | return zmp[38024]; //37998, 38022 82 | } 83 | 84 | int anchor_max_score() { 85 | return 100; 86 | } 87 | 88 | int anchor_get_num_world_objs() { 89 | return 764; 90 | } 91 | 92 | int anchor_ignore_moved_obj(zword obj_num, zword dest_num) { 93 | return 0; 94 | } 95 | 96 | int anchor_ignore_attr_diff(zword obj_num, zword attr_idx) { 97 | if (attr_idx == 25) 98 | return 1; 99 | return 0; 100 | } 101 | 102 | int anchor_ignore_attr_clr(zword obj_num, zword attr_idx) { 103 | if (attr_idx == 25) 104 | return 1; 105 | return 0; 106 | } 107 | 108 | void anchor_clean_world_objs(zobject* objs) { 109 | } 110 | -------------------------------------------------------------------------------- /frotz/src/games/awaken.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Awakening: http://www.ifwiki.org/index.php/The_Awakening 26 | 27 | zword* awaken_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** awaken_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* awaken_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '>'); 40 | if (pch != NULL) { 41 | *(pch-2) = '\0'; 42 | } 43 | return obs+1; 44 | } 45 | 46 | int awaken_victory() { 47 | char *death_text = "*** You have won ***"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int awaken_game_over() { 55 | char *death_text = "*** You have died ***"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int awaken_get_self_object_num() { 63 | return 20; 64 | } 65 | 66 | int awaken_get_moves() { 67 | return (((short) zmp[10667]) << 8) | zmp[10668]; //10680 68 | } 69 | 70 | short awaken_get_score() { 71 | return zmp[10666]; //10690, 10692 72 | } 73 | 74 | int awaken_max_score() { 75 | return 50; 76 | } 77 | 78 | int awaken_get_num_world_objs() { 79 | return 184; 80 | } 81 | 82 | int awaken_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int awaken_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | if (attr_idx == 25) 88 | return 1; 89 | return 0; 90 | } 91 | 92 | int awaken_ignore_attr_clr(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 25) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | void awaken_clean_world_objs(zobject* objs) { 99 | int i; 100 | char mask; 101 | mask = ~(1 << 7); 102 | // Clear attr 24 103 | for (i=1; i<=awaken_get_num_world_objs(); ++i) { 104 | objs[i].attr[3] &= mask; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /frotz/src/games/cutthroat.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Cutthroats: http://ifdb.tads.org/viewgame?id=4ao65o1u0xuvj8jf 26 | 27 | zword* cutthroat_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** cutthroat_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* cutthroat_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '\n'); 40 | if (pch != NULL) { 41 | return pch+1; 42 | } 43 | return obs; 44 | } 45 | 46 | int cutthroat_victory() { 47 | char *death_text = "Good job, matey!"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int cutthroat_game_over() { 55 | char *death_text = "RESTART, RESTORE, or QUIT"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int cutthroat_get_self_object_num() { 63 | return 184; 64 | } 65 | 66 | int cutthroat_get_moves() { 67 | return (((short) zmp[8644]) << 8) | zmp[8645]; //9041 68 | } 69 | 70 | short cutthroat_get_score() { 71 | return zmp[8871]; //8873 72 | } 73 | 74 | int cutthroat_max_score() { 75 | return 250; 76 | } 77 | 78 | int cutthroat_get_num_world_objs() { 79 | return 220; 80 | } 81 | 82 | int cutthroat_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int cutthroat_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | return 0; 88 | } 89 | 90 | int cutthroat_ignore_attr_clr(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | void cutthroat_clean_world_objs(zobject* objs) { 95 | char mask; 96 | int i; 97 | zobject* weasel_obj; 98 | zobject* weasel_loc; 99 | weasel_obj = &objs[9]; 100 | weasel_loc = &objs[weasel_obj->parent]; 101 | if (weasel_loc->child == 9) { 102 | weasel_loc->child = weasel_obj->sibling; 103 | } 104 | weasel_obj->parent = 0; 105 | weasel_obj->sibling = 0; 106 | weasel_obj->child = 0; 107 | } 108 | -------------------------------------------------------------------------------- /frotz/src/games/default.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | zword* default_ram_addrs(int *n) { 26 | *n = 0; 27 | return NULL; 28 | } 29 | 30 | char** default_intro_actions(int *n) { 31 | *n = 0; 32 | return NULL; 33 | } 34 | 35 | char* default_clean_observation(char* obs) { 36 | return obs; 37 | } 38 | 39 | int default_victory() { 40 | char *death_text = "**** You have won ****"; 41 | if (strstr(world, death_text)) { 42 | return 1; 43 | } 44 | return 0; 45 | } 46 | 47 | int default_game_over() { 48 | char *death_text = "**** You have died ****"; 49 | if (strstr(world, death_text)) { 50 | return 1; 51 | } 52 | return 0; 53 | } 54 | 55 | int default_get_self_object_num() { 56 | return 20; 57 | } 58 | 59 | int default_get_moves() { 60 | return 0; 61 | } 62 | 63 | short default_get_score() { 64 | return 0; 65 | } 66 | 67 | int default_max_score() { 68 | return 0; 69 | } 70 | 71 | int default_get_num_world_objs() { 72 | return 0; 73 | } 74 | 75 | int default_ignore_moved_obj(zword obj_num, zword dest_num) { 76 | return 0; 77 | } 78 | 79 | int default_ignore_attr_diff(zword obj_num, zword attr_idx) { 80 | return 0; 81 | } 82 | 83 | int default_ignore_attr_clr(zword obj_num, zword attr_idx) { 84 | return 0; 85 | } 86 | 87 | void default_clean_world_objs(zobject* objs) { 88 | } 89 | -------------------------------------------------------------------------------- /frotz/src/games/detective.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Detective: http://ifdb.tads.org/viewgame?id=1po9rgq2xssupefw 26 | 27 | zword* detective_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** detective_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* detective_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strstr(obs, "> "); 40 | if (pch != NULL) { 41 | *(pch-1) = '\0'; 42 | } 43 | return obs; 44 | } 45 | 46 | int detective_victory() { 47 | char *death_text = "*** You have won ***"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int detective_game_over() { 55 | char *death_text = "*** You have died ***"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int detective_get_self_object_num() { 63 | return 90; 64 | } 65 | 66 | int detective_get_moves() { 67 | return (((short) zmp[6777]) << 8) | zmp[6778]; // 6792 68 | } 69 | 70 | short detective_get_score() { 71 | return (((short) zmp[6801]) << 8) | zmp[6802]; // Also 6776, 6804 72 | } 73 | 74 | int detective_max_score() { 75 | return 360; 76 | } 77 | 78 | int detective_get_num_world_objs() { 79 | return 101; 80 | } 81 | 82 | int detective_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | // Detective has an issue where if you select invalid movement 84 | // actions any location, it re-moves the player object to that 85 | // location. 86 | return 0; 87 | } 88 | 89 | int detective_ignore_attr_diff(zword obj_num, zword attr_idx) { 90 | if (attr_idx == 26) 91 | return 1; 92 | return 0; 93 | } 94 | 95 | int detective_ignore_attr_clr(zword obj_num, zword attr_idx) { 96 | if (attr_idx == 26) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | void detective_clean_world_objs(zobject* objs) { 102 | int i; 103 | char mask; 104 | mask = ~(1 << 6) & ~(1 << 5); 105 | // Clear attr 25 & 26 106 | for (i=1; i<=detective_get_num_world_objs(); ++i) { 107 | objs[i].attr[3] &= mask; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /frotz/src/games/enchanter.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Enchanter: http://ifdb.tads.org/viewgame?id=vu4xhul3abknifcr 26 | 27 | zword* enchanter_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** enchanter_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* enchanter_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '\n'); 40 | if (pch != NULL) { 41 | return pch+1; 42 | } 43 | return obs; 44 | } 45 | 46 | int enchanter_victory() { 47 | char *death_text = "Here ends the first chapter of the Enchanter saga"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int enchanter_game_over() { 55 | char *death_text = "**** You have died ****"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int enchanter_get_self_object_num() { 63 | return 55; 64 | } 65 | 66 | int enchanter_get_moves() { 67 | return (((short) zmp[8767]) << 8) | zmp[8768]; //9080 68 | } 69 | 70 | short enchanter_get_score() { 71 | return (((short) zmp[8765]) << 8 ) | zmp[8766]; 72 | } 73 | 74 | int enchanter_max_score() { 75 | return 400; 76 | } 77 | 78 | int enchanter_get_num_world_objs() { 79 | return 255; 80 | } 81 | 82 | int enchanter_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int enchanter_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | return 0; 88 | } 89 | 90 | int enchanter_ignore_attr_clr(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | void enchanter_clean_world_objs(zobject* objs) { 95 | int i; 96 | char mask; 97 | mask = ~1; 98 | // Clear attr 15 99 | for (i=1; i<=enchanter_get_num_world_objs(); ++i) { 100 | objs[i].attr[1] &= mask; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /frotz/src/games/enter.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Enterprise Incidents: http://ifdb.tads.org/viewgame?id=ld1f3t5epeagilfz 26 | 27 | const zword enter_special_ram_addrs[6] = { 28 | 9667, // Say -120 to garrulous 29 | 10249, //Take candygram / talk to queenie 30 | 11607, // Put gram in basket 31 | 11219, // Talk to Emperius / take jar 32 | 10644, // Say firefly to jim 33 | 10259, // Ask Queenie to dance; Also 10264 34 | }; 35 | 36 | zword* enter_ram_addrs(int *n) { 37 | *n = 6; 38 | return enter_special_ram_addrs; 39 | } 40 | 41 | char** enter_intro_actions(int *n) { 42 | *n = 0; 43 | return NULL; 44 | } 45 | 46 | char* enter_clean_observation(char* obs) { 47 | char* pch; 48 | pch = strchr(obs, '>'); 49 | if (pch != NULL) { 50 | *(pch-2) = '\0'; 51 | } 52 | return obs+1; 53 | } 54 | 55 | int enter_victory() { 56 | char *death_text = "*** You have won ***"; 57 | if (strstr(world, death_text)) { 58 | return 1; 59 | } 60 | return 0; 61 | } 62 | 63 | int enter_game_over() { 64 | char *death_text = "Would you like to RESTART"; 65 | if (strstr(world, death_text)) { 66 | return 1; 67 | } 68 | return 0; 69 | } 70 | 71 | int enter_get_self_object_num() { 72 | return 20; 73 | } 74 | 75 | int enter_get_moves() { 76 | return (((short) zmp[11070]) << 8) | zmp[11071]; 77 | } 78 | 79 | short enter_get_score() { 80 | return zmp[11069]; // 11095 81 | } 82 | 83 | int enter_max_score() { 84 | return 20; 85 | } 86 | 87 | int enter_get_num_world_objs() { 88 | return 183; 89 | } 90 | 91 | int enter_ignore_moved_obj(zword obj_num, zword dest_num) { 92 | return 0; 93 | } 94 | 95 | int enter_ignore_attr_diff(zword obj_num, zword attr_idx) { 96 | return 0; 97 | } 98 | 99 | int enter_ignore_attr_clr(zword obj_num, zword attr_idx) { 100 | return 0; 101 | } 102 | 103 | void enter_clean_world_objs(zobject* objs) { 104 | } 105 | -------------------------------------------------------------------------------- /frotz/src/games/gold.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Goldilocks is a FOX!: http://ifdb.tads.org/viewgame?id=59ztsy9p01avd6wp 26 | 27 | const zword gold_special_ram_addrs[9] = { 28 | 1025, // Eating porridge 29 | 20672, // Move wardrobe (Also 23313) 30 | 18314, // Oil secateurs 31 | 8251, // TV Channel 32 | 17125, // Unplug TV 33 | 20747, // Toaster lever (Also 3307) 34 | 23342, // Kiss frog (Also 2697, 2709) 35 | 20722, // Give pumpkin to fairy godmother (Also 23331) 36 | 20762, // Say Alakazam (Also 20403, 21927, 19416) 37 | }; 38 | 39 | zword* gold_ram_addrs(int *n) { 40 | *n = 9; 41 | return gold_special_ram_addrs; 42 | } 43 | 44 | char** gold_intro_actions(int *n) { 45 | *n = 0; 46 | return NULL; 47 | } 48 | 49 | char* gold_clean_observation(char* obs) { 50 | char* pch; 51 | pch = strchr(obs, '>'); 52 | if (pch != NULL) { 53 | *(pch-2) = '\0'; 54 | } 55 | return obs+1; 56 | } 57 | 58 | int gold_victory() { 59 | char *death_text = "The important thing is, our plan worked!"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int gold_game_over() { 67 | char *death_text = "Would I like to RESTART"; 68 | if (strstr(world, death_text)) { 69 | return 1; 70 | } 71 | return 0; 72 | } 73 | 74 | int gold_get_self_object_num() { 75 | return 85; 76 | } 77 | 78 | int gold_get_moves() { 79 | return (((short) zmp[20789]) << 8) | zmp[20790]; 80 | } 81 | 82 | short gold_get_score() { 83 | return zmp[20768]; // 20800, 20802 84 | } 85 | 86 | int gold_max_score() { 87 | return 100; 88 | } 89 | 90 | int gold_get_num_world_objs() { 91 | return 255; 92 | } 93 | 94 | int gold_ignore_moved_obj(zword obj_num, zword dest_num) { 95 | return 0; 96 | } 97 | 98 | int gold_ignore_attr_diff(zword obj_num, zword attr_idx) { 99 | if (attr_idx == 25 || attr_idx == 31) 100 | return 1; 101 | return 0; 102 | } 103 | 104 | int gold_ignore_attr_clr(zword obj_num, zword attr_idx) { 105 | if (attr_idx == 25 || attr_idx == 31) 106 | return 1; 107 | return 0; 108 | } 109 | 110 | void gold_clean_world_objs(zobject* objs) { 111 | } 112 | -------------------------------------------------------------------------------- /frotz/src/games/infidel.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Infidel: http://ifdb.tads.org/viewgame?id=anu79a4n1jedg5mm 26 | 27 | const zword infidel_special_ram_addrs[2] = { 28 | 4333, // Dig in sand 29 | 9512 // Activated by 'eat beef' 30 | }; 31 | 32 | zword* infidel_ram_addrs(int *n) { 33 | *n = 2; 34 | return infidel_special_ram_addrs; 35 | } 36 | 37 | char** infidel_intro_actions(int *n) { 38 | *n = 0; 39 | return NULL; 40 | } 41 | 42 | char* infidel_clean_observation(char* obs) { 43 | char* pch; 44 | pch = strchr(obs, '\n'); 45 | if (pch != NULL) { 46 | return pch+1; 47 | } 48 | return obs; 49 | } 50 | 51 | int infidel_victory() { 52 | char *death_text = "Well, someday, someone will discover your bones here. And then you will get your fame."; 53 | if (strstr(world, death_text)) { 54 | return 1; 55 | } 56 | return 0; 57 | } 58 | 59 | int infidel_game_over() { 60 | char *death_text = "**** You have died ****"; 61 | if (strstr(world, death_text)) { 62 | return 1; 63 | } 64 | return 0; 65 | } 66 | 67 | int infidel_get_self_object_num() { 68 | return 223; 69 | } 70 | 71 | int infidel_get_moves() { 72 | return (((short) zmp[8913]) << 8) | zmp[8914]; //9014 73 | } 74 | 75 | short infidel_get_score() { 76 | return (((short) zmp[8911]) << 8) | zmp[8912]; 77 | } 78 | 79 | int infidel_max_score() { 80 | return 400; 81 | } 82 | 83 | int infidel_get_num_world_objs() { 84 | return 246; 85 | } 86 | 87 | int infidel_ignore_moved_obj(zword obj_num, zword dest_num) { 88 | return 0; 89 | } 90 | 91 | int infidel_ignore_attr_diff(zword obj_num, zword attr_idx) { 92 | return 0; 93 | } 94 | 95 | int infidel_ignore_attr_clr(zword obj_num, zword attr_idx) { 96 | return 0; 97 | } 98 | 99 | void infidel_clean_world_objs(zobject* objs) { 100 | } 101 | -------------------------------------------------------------------------------- /frotz/src/games/inhumane.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Inhumane: http://ifdb.tads.org/viewgame?id=wvs2vmbigm9unlpd 26 | 27 | const zword inhumane_special_ram_addrs[1] = { 28 | 4376, // Track rotation of wheel 29 | }; 30 | 31 | zword* inhumane_ram_addrs(int *n) { 32 | *n = 1; 33 | return inhumane_special_ram_addrs; 34 | } 35 | 36 | char** inhumane_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* inhumane_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '>'); 44 | if (pch != NULL) { 45 | *(pch-2) = '\0'; 46 | } 47 | return obs+1; 48 | } 49 | 50 | int inhumane_victory() { 51 | char *victory_text = "--end of session--"; 52 | if (strstr(world, victory_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int inhumane_game_over() { 59 | // You have to die 9 times to solve this one 60 | return 0; 61 | } 62 | 63 | int inhumane_get_self_object_num() { 64 | return 15; 65 | } 66 | 67 | int inhumane_get_moves() { 68 | return (((short) zmp[4788]) << 8) | zmp[4789]; // 4799 69 | /* return zmp[4789]; //4799 */ 70 | } 71 | 72 | short inhumane_get_score() { 73 | return zmp[4787]; // 4797 74 | } 75 | 76 | int inhumane_max_score() { 77 | return 90; 78 | } 79 | 80 | int inhumane_get_num_world_objs() { 81 | return 108; 82 | } 83 | 84 | int inhumane_ignore_moved_obj(zword obj_num, zword dest_num) { 85 | return 0; 86 | } 87 | 88 | int inhumane_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 27) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int inhumane_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 27) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void inhumane_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 5); 104 | // Clear attr 26 105 | for (i=1; i<=inhumane_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/jewel.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Jewel of Knowledge: http://ifdb.tads.org/viewgame?id=hu60gp1bgkhlo5yx 26 | 27 | const char *jewel_intro[] = { "bypass\n", "yes\n" }; 28 | 29 | zword* jewel_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** jewel_intro_actions(int *n) { 35 | *n = 2; 36 | return jewel_intro; 37 | } 38 | 39 | char* jewel_clean_observation(char* obs) { 40 | char* pch; 41 | pch = strchr(obs, '>'); 42 | if (pch != NULL) { 43 | *(pch-2) = '\0'; 44 | } 45 | return obs+1; 46 | } 47 | 48 | int jewel_victory() { 49 | char *victory_text = "*** You have won ***"; 50 | if (strstr(world, victory_text)) { 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | int jewel_game_over() { 57 | char *death_text = "*** You have died ***"; 58 | if (strstr(world, death_text)) { 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | int jewel_get_self_object_num() { 65 | return 211; 66 | } 67 | 68 | int jewel_get_moves() { 69 | return (((short) zmp[9971]) << 8) | zmp[9972]; // 9984 70 | } 71 | 72 | short jewel_get_score() { 73 | return zmp[9970]; //9996,9994 74 | } 75 | 76 | int jewel_max_score() { 77 | return 90; 78 | } 79 | 80 | int jewel_get_num_world_objs() { 81 | return 211; 82 | } 83 | 84 | int jewel_ignore_moved_obj(zword obj_num, zword dest_num) { 85 | return 0; 86 | } 87 | 88 | int jewel_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 25) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int jewel_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void jewel_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 7); 104 | // Clear attr 24 105 | for (i=1; i<=jewel_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/karn.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Return to Karn: http://ifdb.tads.org/viewgame?id=bx8118ggp6j7nslo 26 | 27 | const zword karn_special_ram_addrs[3] = { 28 | 14066, // Tardis flying/grounded 29 | 13050, // Color sequence 30 | 1213, // k9 following player 31 | }; 32 | 33 | zword* karn_ram_addrs(int *n) { 34 | *n = 3; 35 | return karn_special_ram_addrs; 36 | } 37 | 38 | char** karn_intro_actions(int *n) { 39 | *n = 0; 40 | return NULL; 41 | } 42 | 43 | char* karn_clean_observation(char* obs) { 44 | char* pch; 45 | pch = strchr(obs, '>'); 46 | if (pch != NULL) { 47 | *(pch-2) = '\0'; 48 | } 49 | return obs+1; 50 | } 51 | 52 | int karn_victory() { 53 | char *victory_text = "*** You have won ***"; 54 | if (strstr(world, victory_text)) { 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int karn_game_over() { 61 | char *death_text = "*** You have died ***"; 62 | if (strstr(world, death_text)) { 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | 68 | int karn_get_self_object_num() { 69 | return 20; 70 | } 71 | 72 | int karn_get_moves() { 73 | return (((short) zmp[13817]) << 8) | zmp[13818]; // 13828 74 | } 75 | 76 | short karn_get_score() { 77 | return zmp[13816]; // 13826, 13842 78 | } 79 | 80 | int karn_max_score() { 81 | return 170; 82 | } 83 | 84 | int karn_get_num_world_objs() { 85 | return 255; 86 | } 87 | 88 | int karn_ignore_moved_obj(zword obj_num, zword dest_num) { 89 | return 0; 90 | } 91 | 92 | int karn_ignore_attr_diff(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 25) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | int karn_ignore_attr_clr(zword obj_num, zword attr_idx) { 99 | if (attr_idx == 25) 100 | return 1; 101 | return 0; 102 | } 103 | 104 | void karn_clean_world_objs(zobject* objs) { 105 | int i; 106 | char mask; 107 | mask = ~(1 << 7); 108 | // Clear attr 24 109 | for (i=1; i<=karn_get_num_world_objs(); ++i) { 110 | objs[i].attr[3] &= mask; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /frotz/src/games/library.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // All Quiet on the Library Front: http://ifdb.tads.org/viewgame?id=400zakqderzjnu1i 26 | 27 | const char *library_intro[] = { "\n" }; 28 | 29 | zword* library_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** library_intro_actions(int *n) { 35 | *n = 1; 36 | return library_intro; 37 | } 38 | 39 | char* library_clean_observation(char* obs) { 40 | char* pch; 41 | pch = strchr(obs, '>'); 42 | if (pch != NULL) { 43 | *(pch-2) = '\0'; 44 | } 45 | return obs+1; 46 | } 47 | 48 | int library_victory() { 49 | char *victory_text = "*** You have won ***"; 50 | if (strstr(world, victory_text)) { 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | int library_game_over() { 57 | char *death_text = "Would you like to RESTART, RESTORE a saved game"; 58 | if (strstr(world, death_text)) { 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | int library_get_self_object_num() { 65 | return 15; 66 | } 67 | 68 | int library_get_moves() { 69 | return (((short) zmp[3611]) << 8) | zmp[3612]; 70 | } 71 | 72 | short library_get_score() { 73 | return zmp[3610]; //3626 74 | } 75 | 76 | int library_max_score() { 77 | return 30; 78 | } 79 | 80 | int library_get_num_world_objs() { 81 | return 76; 82 | } 83 | 84 | int library_ignore_moved_obj(zword obj_num, zword dest_num) { 85 | return 0; 86 | } 87 | 88 | int library_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 25) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int library_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void library_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 7) & ~(1 << 6); 104 | // Clear attr 24 & 25 105 | for (i=1; i<=library_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/loose.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Mother Loose: http://ifdb.tads.org/viewgame?id=4wd3lyaxi4thp8qi 26 | 27 | const char *loose_intro[] = { "\n" }; 28 | 29 | zword* loose_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** loose_intro_actions(int *n) { 35 | *n = 1; 36 | return loose_intro; 37 | } 38 | 39 | char* loose_clean_observation(char* obs) { 40 | char* pch; 41 | pch = strchr(obs, '>'); 42 | if (pch != NULL) { 43 | *(pch-2) = '\0'; 44 | } 45 | return obs+1; 46 | } 47 | 48 | int loose_victory() { 49 | char *death_text = "*** You have won ***"; 50 | if (strstr(world, death_text)) { 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | int loose_game_over() { 57 | char *death_text = "Would you like to RESTART, RESTORE a saved game"; 58 | if (strstr(world, death_text)) { 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | int loose_get_self_object_num() { 65 | return 34; 66 | } 67 | 68 | int loose_get_moves() { 69 | return (((short) zmp[10392]) << 8) | zmp[10393]; // 10405 70 | } 71 | 72 | short loose_get_score() { 73 | return zmp[10391]; // 10415, 10417 74 | } 75 | 76 | int loose_max_score() { 77 | return 50; 78 | } 79 | 80 | int loose_get_num_world_objs() { 81 | return 178; 82 | } 83 | 84 | int loose_ignore_moved_obj(zword obj_num, zword dest_num) { 85 | return 0; 86 | } 87 | 88 | int loose_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 25) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int loose_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void loose_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 7) & ~(1 << 6); 104 | // Clear attr 24 & 25 105 | for (i=1; i<=loose_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/ludicorp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Ludicorp Mystery: http://ifdb.tads.org/viewgame?id=r6g7pflngn3uxbam 26 | 27 | const zword ludicorp_special_ram_addrs[2] = { 28 | 24139, // Tracks button presses 29 | 24158, // Tracks punch card 30 | }; 31 | 32 | 33 | zword* ludicorp_ram_addrs(int *n) { 34 | *n = 2; 35 | return ludicorp_special_ram_addrs; 36 | } 37 | 38 | char** ludicorp_intro_actions(int *n) { 39 | *n = 0; 40 | return NULL; 41 | } 42 | 43 | char* ludicorp_clean_observation(char* obs) { 44 | char* pch; 45 | pch = strchr(obs, '>'); 46 | if (pch != NULL) { 47 | *(pch-2) = '\0'; 48 | } 49 | return obs+1; 50 | } 51 | 52 | int ludicorp_victory() { 53 | char *victory_text = "*** You have won ***"; 54 | if (strstr(world, victory_text)) { 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int ludicorp_game_over() { 61 | char *death_text = "*** You have died ***"; 62 | if (strstr(world, death_text)) { 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | 68 | int ludicorp_get_self_object_num() { 69 | return 20; 70 | } 71 | 72 | int ludicorp_get_moves() { 73 | return (((short) zmp[24205]) << 8) | zmp[24206]; //24194 74 | } 75 | 76 | short ludicorp_get_score() { 77 | return zmp[24216]; //24192, 24218 78 | } 79 | 80 | int ludicorp_max_score() { 81 | return 150; 82 | } 83 | 84 | int ludicorp_get_num_world_objs() { 85 | return 392; 86 | } 87 | 88 | int ludicorp_ignore_moved_obj(zword obj_num, zword dest_num) { 89 | return 0; 90 | } 91 | 92 | int ludicorp_ignore_attr_diff(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 25) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | int ludicorp_ignore_attr_clr(zword obj_num, zword attr_idx) { 99 | if (attr_idx == 25) 100 | return 1; 101 | return 0; 102 | } 103 | 104 | void ludicorp_clean_world_objs(zobject* objs) { 105 | int i; 106 | char mask; 107 | mask = ~(1 << 7); 108 | // Clear attr 24 109 | for (i=1; i<=ludicorp_get_num_world_objs(); ++i) { 110 | objs[i].attr[3] &= mask; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /frotz/src/games/moonlit.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Moonlit Tower - http://ifdb.tads.org/viewgame?id=10387w68qlwehbyq 26 | 27 | const zword moonlit_special_ram_addrs[3] = { 28 | 7517, // Activated by setting constellation to horse, Also 7516 29 | }; 30 | 31 | zword* moonlit_ram_addrs(int *n) { 32 | *n = 1; 33 | return moonlit_special_ram_addrs; 34 | } 35 | 36 | char** moonlit_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* moonlit_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strstr(obs, "> "); 44 | if (pch != NULL) { 45 | *(pch-2) = '\0'; 46 | } 47 | return obs+1; 48 | } 49 | 50 | int moonlit_victory() { 51 | char *victory_text = "*** You have won ***"; 52 | if (strstr(world, victory_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int moonlit_game_over() { 59 | char *death_text = "*** You have died ***"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int moonlit_get_self_object_num() { 67 | return 20; 68 | } 69 | 70 | int moonlit_get_moves() { 71 | return (((short) zmp[10551]) << 8) | zmp[10552]; 72 | } 73 | 74 | short moonlit_get_score() { 75 | if (moonlit_victory()) { 76 | return 1; 77 | } 78 | return 0; 79 | } 80 | 81 | int moonlit_max_score() { 82 | return 1; 83 | } 84 | 85 | int moonlit_get_num_world_objs() { 86 | return 198; 87 | } 88 | 89 | int moonlit_ignore_moved_obj(zword obj_num, zword dest_num) { 90 | return 0; 91 | } 92 | 93 | int moonlit_ignore_attr_diff(zword obj_num, zword attr_idx) { 94 | if (attr_idx == 25 || attr_idx == 31) 95 | return 1; 96 | return 0; 97 | } 98 | 99 | int moonlit_ignore_attr_clr(zword obj_num, zword attr_idx) { 100 | if (attr_idx == 25 || attr_idx == 31) 101 | return 1; 102 | return 0; 103 | } 104 | 105 | void moonlit_clean_world_objs(zobject* objs) { 106 | int i; 107 | char mask; 108 | mask = ~(1 << 7) & ~1; 109 | // Clear attr 24 & 31 110 | for (i=1; i<=moonlit_get_num_world_objs(); ++i) { 111 | objs[i].attr[3] &= mask; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /frotz/src/games/night.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Night at the Computer Center: http://ifdb.tads.org/viewgame?id=ydhwa11st460g9u3 26 | 27 | zword* night_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** night_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* night_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '>'); 40 | if (pch != NULL) { 41 | *(pch-2) = '\0'; 42 | } 43 | return obs+1; 44 | } 45 | 46 | int night_victory() { 47 | char *victory_text = "*** You have saved your job ***"; 48 | if (strstr(world, victory_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int night_game_over() { 55 | char *death_text = "*** You have died ***"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int night_get_self_object_num() { 63 | return 15; 64 | } 65 | 66 | int night_get_moves() { 67 | return (((short) zmp[5295]) << 8) | zmp[5296]; //5306 68 | } 69 | 70 | short night_get_score() { 71 | return zmp[5294]; //5304, 5320 72 | } 73 | 74 | int night_max_score() { 75 | return 10; 76 | } 77 | 78 | int night_get_num_world_objs() { 79 | return 113; 80 | } 81 | 82 | int night_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int night_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | if (attr_idx == 25) 88 | return 1; 89 | return 0; 90 | } 91 | 92 | int night_ignore_attr_clr(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 25) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | void night_clean_world_objs(zobject* objs) { 99 | int i; 100 | char mask; 101 | mask = ~(1 << 7); 102 | // Clear attr 24 103 | for (i=1; i<=night_get_num_world_objs(); ++i) { 104 | objs[i].attr[3] &= mask; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /frotz/src/games/nine05.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // 9:05 - http://ifdb.tads.org/viewgame?id=qzftg3j8nh5f34i2 26 | 27 | zword* nine05_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** nine05_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* nine05_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strstr(obs, "> "); 40 | if (pch != NULL) { 41 | *(pch-2) = '\0'; 42 | } 43 | return obs+1; 44 | } 45 | 46 | int nine05_victory() { 47 | char *death_text = "*** You have left Las Mesas ***"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int nine05_game_over() { 55 | char *death_text = "*** You have died ***"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int nine05_get_self_object_num() { 63 | return 28; 64 | } 65 | 66 | int nine05_get_moves() { 67 | return ((((short) zmp[4295]) << 8) | zmp[4296]) - 545; 68 | } 69 | 70 | short nine05_get_score() { 71 | if (nine05_victory()) { 72 | return 1; 73 | } 74 | return 0; 75 | } 76 | 77 | int nine05_max_score() { 78 | return 1; 79 | } 80 | 81 | int nine05_get_num_world_objs() { 82 | return 84; 83 | } 84 | 85 | int nine05_ignore_moved_obj(zword obj_num, zword dest_num) { 86 | return 0; 87 | } 88 | 89 | int nine05_ignore_attr_diff(zword obj_num, zword attr_idx) { 90 | if (attr_idx == 25) 91 | return 1; 92 | return 0; 93 | } 94 | 95 | int nine05_ignore_attr_clr(zword obj_num, zword attr_idx) { 96 | if (attr_idx == 25) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | void nine05_clean_world_objs(zobject* objs) { 102 | } 103 | -------------------------------------------------------------------------------- /frotz/src/games/omniquest.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Omniquest: http://ifdb.tads.org/viewgame?id=mygqz9tzxqvryead 26 | 27 | const zword omniquest_special_ram_addrs[1] = { 28 | 2123 // Keep track of whether you've given sushi to samurai; Also 2135. 29 | }; 30 | 31 | zword* omniquest_ram_addrs(int *n) { 32 | *n = 1; 33 | return omniquest_special_ram_addrs; 34 | } 35 | 36 | char** omniquest_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* omniquest_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '>'); 44 | if (pch != NULL) { 45 | *(pch-2) = '\0'; 46 | } 47 | return obs+1; 48 | } 49 | 50 | int omniquest_victory() { 51 | char *victory_text = "*** You have won ***"; 52 | if (strstr(world, victory_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int omniquest_game_over() { 59 | char *death_text = "*** You have died ***"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int omniquest_get_self_object_num() { 67 | return 20; 68 | } 69 | 70 | int omniquest_get_moves() { 71 | return (((short) zmp[5980]) << 8) | zmp[5981]; //5995 72 | } 73 | 74 | short omniquest_get_score() { 75 | return zmp[5979]; //6005, 6007 76 | } 77 | 78 | int omniquest_max_score() { 79 | return 50; 80 | } 81 | 82 | int omniquest_get_num_world_objs() { 83 | return 138; 84 | } 85 | 86 | int omniquest_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int omniquest_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | if (attr_idx == 25) 92 | return 1; 93 | return 0; 94 | } 95 | 96 | int omniquest_ignore_attr_clr(zword obj_num, zword attr_idx) { 97 | if (attr_idx == 25) 98 | return 1; 99 | return 0; 100 | } 101 | 102 | void omniquest_clean_world_objs(zobject* objs) { 103 | int i; 104 | char mask; 105 | mask = ~(1 << 7); 106 | // Clear attr 24 107 | for (i=1; i<=omniquest_get_num_world_objs(); ++i) { 108 | objs[i].attr[3] &= mask; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /frotz/src/games/partyfoul.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Party Foul - http://ifdb.tads.org/viewgame?id=cqwq699i9qiqdju 26 | 27 | const char *partyfoul_intro[] = { "\n", 28 | "no\n" }; 29 | 30 | zword* partyfoul_ram_addrs(int *n) { 31 | *n = 0; 32 | return NULL; 33 | } 34 | 35 | char** partyfoul_intro_actions(int *n) { 36 | *n = 2; 37 | return partyfoul_intro; 38 | } 39 | 40 | char* partyfoul_clean_observation(char* obs) { 41 | char* pch; 42 | pch = strstr(obs, "> "); 43 | if (pch != NULL) { 44 | *(pch-2) = '\0'; 45 | } 46 | return obs+1; 47 | } 48 | 49 | int partyfoul_victory() { 50 | char *victory_text = "*** You have won ***"; 51 | if (strstr(world, victory_text)) { 52 | return 1; 53 | } 54 | return 0; 55 | } 56 | 57 | int partyfoul_game_over() { 58 | char *death_text = "*** You have died ***"; 59 | if (strstr(world, death_text)) { 60 | return 1; 61 | } 62 | return 0; 63 | } 64 | 65 | int partyfoul_get_self_object_num() { 66 | return 48; 67 | } 68 | 69 | int partyfoul_get_moves() { 70 | return (((short) zmp[15810]) << 8) | zmp[15811]; 71 | } 72 | 73 | short partyfoul_get_score() { 74 | if (partyfoul_victory()) { 75 | return 1; 76 | } 77 | return 0; 78 | } 79 | 80 | int partyfoul_max_score() { 81 | return 1; 82 | } 83 | 84 | int partyfoul_get_num_world_objs() { 85 | return 141; 86 | } 87 | 88 | int partyfoul_ignore_moved_obj(zword obj_num, zword dest_num) { 89 | return 0; 90 | } 91 | 92 | int partyfoul_ignore_attr_diff(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 35 || attr_idx == 29) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | int partyfoul_ignore_attr_clr(zword obj_num, zword attr_idx) { 99 | if (attr_idx == 35) 100 | return 1; 101 | return 0; 102 | } 103 | 104 | void partyfoul_clean_world_objs(zobject* objs) { 105 | } 106 | -------------------------------------------------------------------------------- /frotz/src/games/pentari.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Pentari: http://ifdb.tads.org/viewgame?id=llchvog0ukwrphih 26 | 27 | zword* pentari_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** pentari_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* pentari_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '>'); 40 | if (pch != NULL) { 41 | *(pch-2) = '\0'; 42 | } 43 | return obs+1; 44 | } 45 | 46 | int pentari_victory() { 47 | char *death_text = "*** You have won ***"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int pentari_game_over() { 55 | char *death_text = "*** You have died ***"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int pentari_get_self_object_num() { 63 | return 20; 64 | } 65 | 66 | int pentari_get_moves() { 67 | return (((short) zmp[4939]) << 8) | zmp[4940]; //4952 68 | } 69 | 70 | short pentari_get_score() { 71 | return zmp[4938];//4962, 4964 72 | } 73 | 74 | int pentari_max_score() { 75 | return 70; 76 | } 77 | 78 | int pentari_get_num_world_objs() { 79 | return 104; 80 | } 81 | 82 | int pentari_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | if (obj_num == 103) 84 | return 1; 85 | return 0; 86 | } 87 | 88 | int pentari_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 25) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int pentari_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void pentari_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 7); 104 | // Clear attr 24 105 | for (i=1; i<=pentari_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/planetfall.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Planetfall: http://ifdb.tads.org/viewgame?id=xe6kb3cuqwie2q38 26 | 27 | const zword planetfall_special_ram_addrs[13] = { 28 | 10741, // Blue button 29 | 10234, // Enable elevator 30 | 10218, // Pour fluid in hole 31 | 10408, // Hunger 32 | 10711, // Red button 33 | 10420, // Pull lever 34 | 10404, // Sickness 35 | 10444, // Teleportation Card 36 | 10642, // Miniaturization card 37 | 10058, // Dial 38 | 10052, // Laser 39 | 10060, // Bye laser 40 | 10612, // Emergency button 41 | }; 42 | 43 | zword* planetfall_ram_addrs(int *n) { 44 | *n = 13; 45 | return planetfall_special_ram_addrs; 46 | } 47 | 48 | char** planetfall_intro_actions(int *n) { 49 | *n = 0; 50 | return NULL; 51 | } 52 | 53 | char* planetfall_clean_observation(char* obs) { 54 | char* pch; 55 | pch = strchr(obs, '\n'); 56 | if (pch != NULL) { 57 | return pch+1; 58 | } 59 | return obs; 60 | } 61 | 62 | int planetfall_victory() { 63 | char *death_text = "Cryo-Anteroom"; 64 | if (strstr(world, death_text)) { 65 | return 1; 66 | } 67 | return 0; 68 | } 69 | 70 | int planetfall_game_over() { 71 | char *death_text = "**** You have died ****"; 72 | if (strstr(world, death_text)) { 73 | return 1; 74 | } 75 | return 0; 76 | } 77 | 78 | int planetfall_get_self_object_num() { 79 | return 236; 80 | } 81 | 82 | int planetfall_get_moves() { 83 | return (((short) zmp[10473]) << 8) | zmp[10474]; 84 | } 85 | 86 | short planetfall_get_score() { 87 | return zmp[10026]; 88 | } 89 | 90 | int planetfall_max_score() { 91 | return 80; 92 | } 93 | 94 | int planetfall_get_num_world_objs() { 95 | return 252; 96 | } 97 | 98 | int planetfall_ignore_moved_obj(zword obj_num, zword dest_num) { 99 | return 0; 100 | } 101 | 102 | int planetfall_ignore_attr_diff(zword obj_num, zword attr_idx) { 103 | return 0; 104 | } 105 | 106 | int planetfall_ignore_attr_clr(zword obj_num, zword attr_idx) { 107 | return 0; 108 | } 109 | 110 | void planetfall_clean_world_objs(zobject* objs) { 111 | } 112 | -------------------------------------------------------------------------------- /frotz/src/games/plundered.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Plundered Hearts: http://ifdb.tads.org/viewgame?id=ddagftras22bnz8h 26 | 27 | const zword plundered_special_ram_addrs[1] = { 28 | 729, // Tracks how far you have climbed the ladder 29 | }; 30 | 31 | zword* plundered_ram_addrs(int *n) { 32 | *n = 1; 33 | return plundered_special_ram_addrs; 34 | } 35 | 36 | char** plundered_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* plundered_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '\n'); 44 | if (pch != NULL) { 45 | return pch+1; 46 | } 47 | return obs; 48 | } 49 | 50 | int plundered_victory() { 51 | char *death_text = "Thus you have finished the story of PLUNDERED HEARTS"; 52 | if (strstr(world, death_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int plundered_game_over() { 59 | char *death_text = "*** You have died ***"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int plundered_get_self_object_num() { 67 | return 192; 68 | } 69 | 70 | int plundered_get_moves() { 71 | return (((short) zmp[678]) << 8) | zmp[679]; 72 | } 73 | 74 | short plundered_get_score() { 75 | return zmp[677]; 76 | } 77 | 78 | int plundered_max_score() { 79 | return 25; 80 | } 81 | 82 | int plundered_get_num_world_objs() { 83 | return 223; 84 | } 85 | 86 | int plundered_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int plundered_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | int plundered_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | return 0; 96 | } 97 | 98 | void plundered_clean_world_objs(zobject* objs) { 99 | } 100 | -------------------------------------------------------------------------------- /frotz/src/games/reverb.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Reverberations: http://ifdb.tads.org/viewgame?id=dop7nbjl90r5zmf9 26 | 27 | const zword reverb_special_ram_addrs[1] = { 28 | 5927 // Tracks kicking thug 29 | }; 30 | 31 | zword* reverb_ram_addrs(int *n) { 32 | *n = 1; 33 | return reverb_special_ram_addrs; 34 | } 35 | 36 | char** reverb_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* reverb_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '>'); 44 | if (pch != NULL) { 45 | *(pch-2) = '\0'; 46 | } 47 | return obs+1; 48 | } 49 | 50 | int reverb_victory() { 51 | char *victory_text = "*** You Rule! The game's totally over! ***"; 52 | if (strstr(world, victory_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int reverb_game_over() { 59 | char *death_text = "Would you like to RESTART, RESTORE a saved game or QUIT"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int reverb_get_self_object_num() { 67 | return 20; 68 | } 69 | 70 | int reverb_get_moves() { 71 | return (((short) zmp[5840]) << 8) | zmp[5841]; //5853 72 | } 73 | 74 | short reverb_get_score() { 75 | return zmp[5839]; //5863, 5865 76 | } 77 | 78 | int reverb_max_score() { 79 | return 50; 80 | } 81 | 82 | int reverb_get_num_world_objs() { 83 | return 120; 84 | } 85 | 86 | int reverb_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int reverb_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | if (attr_idx == 31 || obj_num == 24) 92 | return 1; 93 | return 0; 94 | } 95 | 96 | int reverb_ignore_attr_clr(zword obj_num, zword attr_idx) { 97 | if (attr_idx == 31) 98 | return 1; 99 | return 0; 100 | } 101 | 102 | void reverb_clean_world_objs(zobject* objs) { 103 | } 104 | -------------------------------------------------------------------------------- /frotz/src/games/sherbet.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Meteor, the Stone and a Long Glass of Sherbet: http://ifdb.tads.org/viewgame?id=273o81yvg64m4pkz 26 | 27 | const char *sherbet_intro[] = { " \n" }; 28 | 29 | zword* sherbet_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** sherbet_intro_actions(int *n) { 35 | *n = 1; 36 | return sherbet_intro; 37 | } 38 | 39 | char* sherbet_clean_observation(char* obs) { 40 | char* pch; 41 | pch = strchr(obs, '>'); 42 | if (pch != NULL) { 43 | *(pch-2) = '\0'; 44 | } 45 | return obs+1; 46 | } 47 | 48 | int sherbet_victory() { 49 | char *death_text = "**** You have won ****"; 50 | if (strstr(world, death_text)) { 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | int sherbet_game_over() { 57 | char *death_text = "**** You have died ****"; 58 | if (strstr(world, death_text)) { 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | int sherbet_get_self_object_num() { 65 | return 40; 66 | } 67 | 68 | int sherbet_get_moves() { 69 | return (((short) zmp[12378]) << 8) | zmp[12379]; //12391 70 | } 71 | 72 | short sherbet_get_score() { 73 | return zmp[12377]; //12401, 12403 74 | } 75 | 76 | int sherbet_max_score() { 77 | return 30; 78 | } 79 | 80 | int sherbet_get_num_world_objs() { 81 | return 230; 82 | } 83 | 84 | int sherbet_ignore_moved_obj(zword obj_num, zword dest_num) { 85 | return 0; 86 | } 87 | 88 | int sherbet_ignore_attr_diff(zword obj_num, zword attr_idx) { 89 | if (attr_idx == 25) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | int sherbet_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | if (attr_idx == 25) 96 | return 1; 97 | return 0; 98 | } 99 | 100 | void sherbet_clean_world_objs(zobject* objs) { 101 | } 102 | -------------------------------------------------------------------------------- /frotz/src/games/sherlock.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Sherlock: http://ifdb.tads.org/viewgame?id=ug3qu521hze8bsvz 26 | 27 | const char *sherlock_intro[] = { "\n" }; 28 | 29 | zword* sherlock_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** sherlock_intro_actions(int *n) { 35 | *n = 1; 36 | return sherlock_intro; 37 | } 38 | 39 | char* sherlock_clean_observation(char* obs) { 40 | return obs; 41 | } 42 | 43 | int sherlock_victory() { 44 | char *death_text = "Once again, Mr Holmes, we find ourselves in your debt."; 45 | if (strstr(world, death_text)) { 46 | return 1; 47 | } 48 | return 0; 49 | } 50 | 51 | int sherlock_game_over() { 52 | char *death_text = "The game is no longer afoot"; 53 | if (strstr(world, death_text)) { 54 | return 1; 55 | } 56 | return 0; 57 | } 58 | 59 | int sherlock_get_self_object_num() { 60 | return 232; 61 | } 62 | 63 | int sherlock_get_moves() { 64 | return (((short) zmp[1002]) << 8) | zmp[1003]; 65 | } 66 | 67 | short sherlock_get_score() { 68 | return zmp[739]; //993 69 | } 70 | 71 | int sherlock_max_score() { 72 | return 100; 73 | } 74 | 75 | int sherlock_get_num_world_objs() { 76 | return 314; 77 | } 78 | 79 | int sherlock_ignore_moved_obj(zword obj_num, zword dest_num) { 80 | return 0; 81 | } 82 | 83 | int sherlock_ignore_attr_diff(zword obj_num, zword attr_idx) { 84 | return 0; 85 | } 86 | 87 | int sherlock_ignore_attr_clr(zword obj_num, zword attr_idx) { 88 | return 0; 89 | } 90 | 91 | void sherlock_clean_world_objs(zobject* objs) { 92 | } 93 | -------------------------------------------------------------------------------- /frotz/src/games/sorcerer.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Sorcerer: http://ifdb.tads.org/viewgame?id=lidg5nx9ig0bwk55 26 | 27 | const zword sorcerer_special_ram_addrs[1] = { 28 | 9807, // Inside glass maze 29 | }; 30 | 31 | zword* sorcerer_ram_addrs(int *n) { 32 | *n = 1; 33 | return sorcerer_special_ram_addrs; 34 | } 35 | 36 | char** sorcerer_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* sorcerer_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '\n'); 44 | if (pch != NULL) { 45 | return pch+1; 46 | } 47 | return obs; 48 | } 49 | 50 | int sorcerer_victory() { 51 | char *death_text = "Once again, this young Enchanter has done a matchless service to the Guild"; 52 | if (strstr(world, death_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int sorcerer_game_over() { 59 | char *death_text = "**** You have died ****"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int sorcerer_get_self_object_num() { 67 | return 223; 68 | } 69 | 70 | int sorcerer_get_moves() { 71 | return (((short) zmp[9700]) << 8) | zmp[9701]; 72 | } 73 | 74 | short sorcerer_get_score() { 75 | return (((short) zmp[9698]) << 8) | zmp[9699]; 76 | } 77 | 78 | int sorcerer_max_score() { 79 | return 400; 80 | } 81 | 82 | int sorcerer_get_num_world_objs() { 83 | return 255; 84 | } 85 | 86 | int sorcerer_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int sorcerer_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | int sorcerer_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | return 0; 96 | } 97 | 98 | void sorcerer_clean_world_objs(zobject* objs) { 99 | int i; 100 | char mask; 101 | mask = ~(1 << 5); 102 | // Clear attr 18 103 | for (i=1; i<=sorcerer_get_num_world_objs(); ++i) { 104 | objs[i].attr[2] &= mask; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /frotz/src/games/spellbrkr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Spellbreaker: http://ifdb.tads.org/viewgame?id=wqsmrahzozosu3r 26 | 27 | zword* spellbrkr_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** spellbrkr_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* spellbrkr_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '\n'); 40 | if (pch != NULL) { 41 | return pch+1; 42 | } 43 | return obs; 44 | } 45 | 46 | int spellbrkr_victory() { 47 | char *victory_text = "The age of magic is ended, as it must, for as magic can confer absolute power, so it can also produce absolute evil. We may defeat this evil when it appears, but if wizardry builds it anew, we can never ultimately win. The new world will be strange, but in time it will serve us better"; 48 | if (strstr(world, victory_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int spellbrkr_game_over() { 55 | char *death_text = "**** You have died ****"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int spellbrkr_get_self_object_num() { 63 | return 52; 64 | } 65 | 66 | int spellbrkr_get_moves() { 67 | return (((short) zmp[8726]) << 8) | zmp[8727]; 68 | } 69 | 70 | short spellbrkr_get_score() { 71 | return (((short) zmp[8724]) << 8) | zmp[8725]; 72 | } 73 | 74 | int spellbrkr_max_score() { 75 | return 600; 76 | } 77 | 78 | int spellbrkr_get_num_world_objs() { 79 | return 249; 80 | } 81 | 82 | int spellbrkr_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int spellbrkr_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | return 0; 88 | } 89 | 90 | int spellbrkr_ignore_attr_clr(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | void spellbrkr_clean_world_objs(zobject* objs) { 95 | } 96 | -------------------------------------------------------------------------------- /frotz/src/games/theatre.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Theatre: http://ifdb.tads.org/viewgame?id=bv8of8y9xeo7307g 26 | 27 | const zword theatre_special_ram_addrs[2] = { 28 | 17830, // Tracks dial location 29 | 17834, // Track watch hand 30 | }; 31 | 32 | const char *theatre_intro[] = { "\n" }; 33 | 34 | zword* theatre_ram_addrs(int *n) { 35 | *n = 2; 36 | return theatre_special_ram_addrs; 37 | } 38 | 39 | char** theatre_intro_actions(int *n) { 40 | *n = 1; 41 | return theatre_intro; 42 | } 43 | 44 | char* theatre_clean_observation(char* obs) { 45 | char* pch; 46 | pch = strchr(obs, '>'); 47 | if (pch != NULL) { 48 | *(pch-2) = '\0'; 49 | } 50 | return obs+1; 51 | } 52 | 53 | int theatre_victory() { 54 | char *victory_text = "*** You have won ***"; 55 | if (strstr(world, victory_text)) { 56 | return 1; 57 | } 58 | return 0; 59 | } 60 | 61 | int theatre_game_over() { 62 | char *death_text = "*** You have died ***"; 63 | if (strstr(world, death_text)) { 64 | return 1; 65 | } 66 | return 0; 67 | } 68 | 69 | int theatre_get_self_object_num() { 70 | return 15; 71 | } 72 | 73 | int theatre_get_moves() { 74 | return (((short) zmp[17579]) << 8) | zmp[17580]; //17590 75 | } 76 | 77 | short theatre_get_score() { 78 | return (((short) zmp[17577]) << 8) | zmp[17578]; //17588, 17604 79 | } 80 | 81 | int theatre_max_score() { 82 | return 50; 83 | } 84 | 85 | int theatre_get_num_world_objs() { 86 | return 255; 87 | } 88 | 89 | int theatre_ignore_moved_obj(zword obj_num, zword dest_num) { 90 | return 0; 91 | } 92 | 93 | int theatre_ignore_attr_diff(zword obj_num, zword attr_idx) { 94 | if (attr_idx == 27) 95 | return 1; 96 | return 0; 97 | } 98 | 99 | int theatre_ignore_attr_clr(zword obj_num, zword attr_idx) { 100 | if (attr_idx == 27) 101 | return 1; 102 | return 0; 103 | } 104 | 105 | void theatre_clean_world_objs(zobject* objs) { 106 | int i; 107 | char mask; 108 | mask = ~(1 << 5) & ~(1 << 4); 109 | // Clear attr 26 & 27 110 | for (i=1; i<=theatre_get_num_world_objs(); ++i) { 111 | objs[i].attr[3] &= mask; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /frotz/src/games/trinity.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Trinity: http://ifdb.tads.org/viewgame?id=j18kjz80hxjtyayw 26 | 27 | const char *trinity_intro[] = { "\n" }; 28 | 29 | zword* trinity_ram_addrs(int *n) { 30 | *n = 0; 31 | return NULL; 32 | } 33 | 34 | char** trinity_intro_actions(int *n) { 35 | *n = 1; 36 | return trinity_intro; 37 | } 38 | 39 | char* trinity_clean_observation(char* obs) { 40 | return obs+2; 41 | } 42 | 43 | int trinity_victory() { 44 | char *victory_text = "You've completed the story of TRINITY"; 45 | if (strstr(world, victory_text)) { 46 | return 1; 47 | } 48 | return 0; 49 | } 50 | 51 | int trinity_game_over() { 52 | char *death_text = "[Type RESTART, RESTORE or QUIT.]"; 53 | if (strstr(world, death_text)) { 54 | return 1; 55 | } 56 | return 0; 57 | } 58 | 59 | int trinity_get_self_object_num() { 60 | return 103; 61 | } 62 | 63 | int trinity_get_moves() { 64 | return (((short) zmp[34172]) << 8) | zmp[34173]; 65 | } 66 | 67 | short trinity_get_score() { 68 | return (((short) zmp[34214]) << 8) | zmp[34215]; 69 | } 70 | 71 | int trinity_max_score() { 72 | return 100; 73 | } 74 | 75 | int trinity_get_num_world_objs() { 76 | return 593; 77 | } 78 | 79 | int trinity_ignore_moved_obj(zword obj_num, zword dest_num) { 80 | if (dest_num == 483) 81 | return 1; 82 | return 0; 83 | } 84 | 85 | int trinity_ignore_attr_diff(zword obj_num, zword attr_idx) { 86 | return 0; 87 | } 88 | 89 | int trinity_ignore_attr_clr(zword obj_num, zword attr_idx) { 90 | return 0; 91 | } 92 | 93 | void trinity_clean_world_objs(zobject* objs) { 94 | int i; 95 | char mask; 96 | mask = ~1; 97 | // Clear attr 23 98 | for (i=1; i<=trinity_get_num_world_objs(); ++i) { 99 | objs[i].attr[2] &= mask; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /frotz/src/games/weapon.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // The Weapon: http://ifdb.tads.org/viewgame?id=tcebhl79rlxo3qrk 26 | 27 | const zword weapon_special_ram_addrs[3] = { 28 | 6349, // Access panel open/closed 29 | 6295, // Project status stud 30 | 6685, // Tool stud 31 | }; 32 | 33 | zword* weapon_ram_addrs(int *n) { 34 | *n = 3; 35 | return weapon_special_ram_addrs; 36 | } 37 | 38 | char** weapon_intro_actions(int *n) { 39 | *n = 0; 40 | return NULL; 41 | } 42 | 43 | char* weapon_clean_observation(char* obs) { 44 | char* pch; 45 | pch = strstr(obs, "> "); 46 | if (pch != NULL) { 47 | *(pch-2) = '\0'; 48 | } 49 | return obs+1; 50 | } 51 | 52 | int weapon_victory() { 53 | char *victory_text = "*** You have won ***"; 54 | if (strstr(world, victory_text)) { 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int weapon_game_over() { 61 | char *death_text = "*** You have lost ***"; 62 | if (strstr(world, death_text)) { 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | 68 | int weapon_get_self_object_num() { 69 | return 20; 70 | } 71 | 72 | int weapon_get_moves() { 73 | return (((short) zmp[31354]) << 8) | zmp[31355]; 74 | } 75 | 76 | short weapon_get_score() { 77 | if (weapon_victory()) { 78 | return 1; 79 | } 80 | return 0; 81 | } 82 | 83 | int weapon_max_score() { 84 | return 1; 85 | } 86 | 87 | int weapon_get_num_world_objs() { 88 | return 455; 89 | } 90 | 91 | int weapon_ignore_moved_obj(zword obj_num, zword dest_num) { 92 | return 0; 93 | } 94 | 95 | int weapon_ignore_attr_diff(zword obj_num, zword attr_idx) { 96 | if (attr_idx == 25 || attr_idx == 14) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | int weapon_ignore_attr_clr(zword obj_num, zword attr_idx) { 102 | if (attr_idx == 25) 103 | return 1; 104 | return 0; 105 | } 106 | 107 | void weapon_clean_world_objs(zobject* objs) { 108 | int i; 109 | char mask; 110 | mask = ~(1 << 1); 111 | // Clear attr 14 112 | for (i=1; i<=weapon_get_num_world_objs(); ++i) { 113 | objs[i].attr[1] &= mask; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /frotz/src/games/wishbringer.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Wishbringer: http://ifdb.tads.org/viewgame?id=z02joykzh66wfhcl 26 | 27 | const zword wishbringer_special_ram_addrs[3] = { 28 | 9384, // Insert wishbringer into statue 29 | 9678, // Yes/No questions 30 | 11154, // Press button in arcade 31 | }; 32 | 33 | zword* wishbringer_ram_addrs(int *n) { 34 | *n = 3; 35 | return wishbringer_special_ram_addrs; 36 | } 37 | 38 | char** wishbringer_intro_actions(int *n) { 39 | *n = 0; 40 | return NULL; 41 | } 42 | 43 | char* wishbringer_clean_observation(char* obs) { 44 | char* pch; 45 | pch = strchr(obs, '\n'); 46 | if (pch != NULL) { 47 | return pch+1; 48 | } 49 | return obs; 50 | } 51 | 52 | int wishbringer_victory() { 53 | char *death_text = "Congratulations! You've finished the story of Wishbringer!"; 54 | if (strstr(world, death_text)) { 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int wishbringer_game_over() { 61 | char *death_text = "Type RESTART, RESTORE or QUIT"; 62 | if (strstr(world, death_text)) { 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | 68 | int wishbringer_get_self_object_num() { 69 | return 238; 70 | } 71 | 72 | int wishbringer_get_moves() { 73 | return (((short) zmp[9495]) << 8) | zmp[9496]; 74 | } 75 | 76 | short wishbringer_get_score() { 77 | return zmp[9498]; 78 | } 79 | 80 | int wishbringer_max_score() { 81 | return 100; 82 | } 83 | 84 | int wishbringer_get_num_world_objs() { 85 | return 247; 86 | } 87 | 88 | int wishbringer_ignore_moved_obj(zword obj_num, zword dest_num) { 89 | return 0; 90 | } 91 | 92 | int wishbringer_ignore_attr_diff(zword obj_num, zword attr_idx) { 93 | return 0; 94 | } 95 | 96 | int wishbringer_ignore_attr_clr(zword obj_num, zword attr_idx) { 97 | return 0; 98 | } 99 | 100 | void wishbringer_clean_world_objs(zobject* objs) { 101 | int i; 102 | char mask; 103 | mask = ~(1 << 3); 104 | // Clear attr 28 105 | for (i=1; i<=wishbringer_get_num_world_objs(); ++i) { 106 | objs[i].attr[3] &= mask; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frotz/src/games/yomomma.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Raising the Flag on Mount Yomomma - http://ifdb.tads.org/viewgame?id=1iqmpkn009h9gbug 26 | 27 | const zword yomomma_special_ram_addrs[3] = { 28 | 21060, // Climb on stage 29 | 16005, // Counts stage victories 30 | 36238, // Discovered Ralph's secrets 31 | }; 32 | 33 | zword* yomomma_ram_addrs(int *n) { 34 | *n = 3; 35 | return yomomma_special_ram_addrs; 36 | } 37 | 38 | char** yomomma_intro_actions(int *n) { 39 | *n = 0; 40 | return NULL; 41 | } 42 | 43 | char* yomomma_clean_observation(char* obs) { 44 | char* pch; 45 | pch = strstr(obs, "> "); 46 | if (pch != NULL) { 47 | *(pch-2) = '\0'; 48 | } 49 | return obs+1; 50 | } 51 | 52 | int yomomma_victory() { 53 | char *victory_text = "*** You have won ***"; 54 | if (strstr(world, victory_text)) { 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int yomomma_game_over() { 61 | char *death_text = "***GAME OVER***"; 62 | if (strstr(world, death_text)) { 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | 68 | int yomomma_get_self_object_num() { 69 | return 59; 70 | } 71 | 72 | int yomomma_get_moves() { 73 | return (((short) zmp[15532]) << 8) | zmp[15533]; 74 | } 75 | 76 | short yomomma_get_score() { 77 | return zmp[15531]; 78 | } 79 | 80 | int yomomma_max_score() { 81 | return 35; 82 | } 83 | 84 | int yomomma_get_num_world_objs() { 85 | return 139; 86 | } 87 | 88 | int yomomma_ignore_moved_obj(zword obj_num, zword dest_num) { 89 | return 0; 90 | } 91 | 92 | int yomomma_ignore_attr_diff(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 30) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | int yomomma_ignore_attr_clr(zword obj_num, zword attr_idx) { 99 | if (attr_idx == 30) 100 | return 1; 101 | return 0; 102 | } 103 | 104 | void yomomma_clean_world_objs(zobject* objs) { 105 | int i; 106 | char mask; 107 | mask = ~(1 << 2); 108 | // Clear attr 21 109 | for (i=1; i<=yomomma_get_num_world_objs(); ++i) { 110 | objs[i].attr[2] &= mask; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /frotz/src/games/zork2.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Zork II: http://ifdb.tads.org/viewgame?id=yzzm4puxyjakk8c4 26 | 27 | const zword zork2_special_ram_addrs[1] = { 28 | 9346, // Say float 29 | }; 30 | 31 | zword* zork2_ram_addrs(int *n) { 32 | *n = 1; 33 | return zork2_special_ram_addrs; 34 | } 35 | 36 | char** zork2_intro_actions(int *n) { 37 | *n = 0; 38 | return NULL; 39 | } 40 | 41 | char* zork2_clean_observation(char* obs) { 42 | char* pch; 43 | pch = strchr(obs, '\n'); 44 | if (pch != NULL) { 45 | return pch+1; 46 | } 47 | return obs; 48 | } 49 | 50 | int zork2_victory() { 51 | char *death_text = "The ultimate adventure concludes in \"Zork III: The Dungeon Master\"."; 52 | if (strstr(world, death_text)) { 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | 58 | int zork2_game_over() { 59 | char *death_text = "**** You have died ****"; 60 | if (strstr(world, death_text)) { 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | int zork2_get_self_object_num() { 67 | return 4; 68 | } 69 | 70 | int zork2_get_moves() { 71 | return (((short) zmp[8937]) << 8) | zmp[8938]; 72 | } 73 | 74 | short zork2_get_score() { 75 | return (((short) zmp[8935]) << 8) | zmp[8936]; // 9110 76 | } 77 | 78 | int zork2_max_score() { 79 | return 400; 80 | } 81 | 82 | int zork2_get_num_world_objs() { 83 | return 250; 84 | } 85 | 86 | int zork2_ignore_moved_obj(zword obj_num, zword dest_num) { 87 | return 0; 88 | } 89 | 90 | int zork2_ignore_attr_diff(zword obj_num, zword attr_idx) { 91 | return 0; 92 | } 93 | 94 | int zork2_ignore_attr_clr(zword obj_num, zword attr_idx) { 95 | return 0; 96 | } 97 | 98 | void zork2_clean_world_objs(zobject* objs) { 99 | int i; 100 | char mask; 101 | mask = ~(1 << 5); 102 | // Clear attr 2 103 | for (i=1; i<=zork2_get_num_world_objs(); ++i) { 104 | objs[i].attr[0] &= mask; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /frotz/src/games/ztuu.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #include 21 | #include "frotz.h" 22 | #include "games.h" 23 | #include "frotz_interface.h" 24 | 25 | // Zork: The Undiscovered Underground: http://ifdb.tads.org/viewgame?id=40hswtkhap88gzvn 26 | 27 | zword* ztuu_ram_addrs(int *n) { 28 | *n = 0; 29 | return NULL; 30 | } 31 | 32 | char** ztuu_intro_actions(int *n) { 33 | *n = 0; 34 | return NULL; 35 | } 36 | 37 | char* ztuu_clean_observation(char* obs) { 38 | char* pch; 39 | pch = strchr(obs, '>'); 40 | if (pch != NULL) { 41 | *(pch-2) = '\0'; 42 | } 43 | return obs+1; 44 | } 45 | 46 | int ztuu_victory() { 47 | char *death_text = "*** You have won ***"; 48 | if (strstr(world, death_text)) { 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | 54 | int ztuu_game_over() { 55 | char *death_text = "Would you like to RESTART"; 56 | if (strstr(world, death_text)) { 57 | return 1; 58 | } 59 | return 0; 60 | } 61 | 62 | int ztuu_get_self_object_num() { 63 | return 20; 64 | } 65 | 66 | int ztuu_get_moves() { 67 | return zmp[8857]; //8867 68 | } 69 | 70 | short ztuu_get_score() { 71 | return zmp[8855]; //8881, 8865 72 | } 73 | 74 | int ztuu_max_score() { 75 | return 100; 76 | } 77 | 78 | int ztuu_get_num_world_objs() { 79 | return 180; 80 | } 81 | 82 | int ztuu_ignore_moved_obj(zword obj_num, zword dest_num) { 83 | return 0; 84 | } 85 | 86 | int ztuu_ignore_attr_diff(zword obj_num, zword attr_idx) { 87 | if (attr_idx == 25) 88 | return 1; 89 | return 0; 90 | } 91 | 92 | int ztuu_ignore_attr_clr(zword obj_num, zword attr_idx) { 93 | if (attr_idx == 25) 94 | return 1; 95 | return 0; 96 | } 97 | 98 | void ztuu_clean_world_objs(zobject* objs) { 99 | int i; 100 | char mask; 101 | mask = ~(1 << 7); 102 | // Clear attr 24 103 | for (i=1; i<=ztuu_get_num_world_objs(); ++i) { 104 | objs[i].attr[3] &= mask; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /frotz/src/interface/frotz_interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2018 Microsoft Corporation 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | 20 | #ifndef frotz_interface_h__ 21 | #define frotz_interface_h__ 22 | 23 | typedef struct { 24 | unsigned int num; 25 | char name[64]; 26 | int parent; 27 | int sibling; 28 | int child; 29 | char attr[4]; 30 | unsigned char properties[16]; 31 | } zobject; 32 | 33 | extern char* setup(char *story_file, int seed, void* rom, size_t rom_size); 34 | 35 | extern void shutdown(); 36 | 37 | extern char* step(char *next_action); 38 | 39 | extern int save(char *filename); 40 | 41 | extern int restore(char *filename); 42 | 43 | extern int undo(); 44 | 45 | extern int getRAMSize(); 46 | 47 | extern void getRAM(unsigned char *ram); 48 | 49 | int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword *diff_array); 50 | 51 | extern char world[8192]; 52 | 53 | extern int tw_max_score; 54 | 55 | extern int tw_player_obj_num; 56 | 57 | extern int tw_num_world_objs; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /frotz/src/misc/findsound.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This thing is intended primarily to find soundcard.h for use with the 4 | # OSS soundcard driver. 5 | # 6 | # Linux typically has 7 | # NetBSD and OpenBSD have 8 | # FreeBSD seems to have 9 | # 10 | # This script will be replaced with something more decent when support for 11 | # more sound drivers is added. This file will be executed during compile 12 | # even if you aren't using sound. 13 | 14 | INCLUDE1="/usr/include/sys" 15 | INCLUDE2="/usr/include" 16 | INCLUDE3="/usr/include/machine" 17 | INCLUDE4="/usr/include/linux" 18 | 19 | SOUNDCARD_H="soundcard.h" 20 | OUTFILE="$1/soundcard.h" 21 | 22 | echo "checking for $SOUNDCARD_H" 23 | 24 | #if [ -f $OUTFILE ] ; then 25 | # echo "$SOUNDCARD_H already made." 26 | # exit 0 27 | #fi 28 | 29 | cat << EOF > $OUTFILE 30 | /* 31 | * This file automatically generated by findsound.sh which run by the 32 | * Makefile found in the Unix Frotz 2.43 source distribution. 33 | * Copying this nasty hack to find headers which may be in any of several 34 | * places is not recommended. I don't want to use autoconf just yet for 35 | * this project. 36 | * 37 | */ 38 | 39 | EOF 40 | 41 | FILE=$INCLUDE1/$SOUNDCARD_H 42 | if [ -f $FILE ] ; then 43 | echo "I see we have $FILE..." 44 | echo 45 | if [ -r $FILE ] ; then 46 | echo '#include ' >> $OUTFILE 47 | else 48 | echo "=====================================" 49 | echo "Oops... Can't read $FILE!" 50 | echo "=====================================" 51 | exit 1 52 | fi 53 | exit 0 54 | fi 55 | 56 | # I'm too lazy to iterate properly right now 57 | 58 | FILE=$INCLUDE2/$SOUNDCARD_H 59 | if [ -f $FILE ] ; then 60 | echo "I see we have $FILE..." 61 | echo 62 | if [ -r $FILE ] ; then 63 | echo '#include ' >> $OUTFILE 64 | else 65 | echo "=====================================" 66 | echo "Oops... Can't read $FILE!" 67 | echo "=====================================" 68 | exit 2 69 | fi 70 | exit 0 71 | fi 72 | 73 | 74 | # I'm too lazy to iterate properly right now 75 | 76 | FILE=$INCLUDE3/$SOUNDCARD_H 77 | if [ -f $FILE ] ; then 78 | echo "I see we have $FILE..." 79 | echo 80 | if [ -r $FILE ] ; then 81 | echo '#include ' >> $OUTFILE 82 | else 83 | echo "=====================================" 84 | echo "Oops... Can't read $FILE!" 85 | echo "=====================================" 86 | exit 3 87 | fi 88 | exit 0 89 | fi 90 | 91 | 92 | 93 | FILE=$INCLUDE4/$SOUNDCARD_H 94 | if [ -f $FILE ] ; then 95 | echo "I see we have $FILE..." 96 | echo 97 | if [ -r $FILE ] ; then 98 | echo '#include ' >> $OUTFILE 99 | else 100 | echo "=====================================" 101 | echo "Oops... Can't read $FILE!" 102 | echo "=====================================" 103 | exit 3 104 | fi 105 | exit 0 106 | fi 107 | -------------------------------------------------------------------------------- /frotz/src/misc/twocol.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # This script is intended to speed up the process of adding new command 4 | # line parameters to the "help" output of text-mode programs. Most 5 | # people want to have the progression of parameters go down the left 6 | # column and then down the right. Prior to using this script, put your 7 | # parameter descriptions in a text file, one parameter per line. Figure 8 | # out where you want the column to end and put that number in $middle. 9 | # This will cause the output to skip over that many spaces and then the 10 | # second column will begin. 11 | # 12 | # When you're all set up, run this script and give the filename of your 13 | # parameter text file. Your parameters, formatted into two columns with 14 | # a '\t' for the tab in the middle, will be printed to STDOUT. Now you 15 | # can put that text into a #define or a really long printf(). 16 | # 17 | # In short, if your parameters file looks like this: 18 | # A 19 | # B 20 | # C 21 | # D 22 | # You'll get this: 23 | # A \t C\n\ 24 | # B \t D\n\ 25 | # 26 | # I've seen scripts that do this before and forgot where they were, so I 27 | # made this one from scratch. Wherever you find it, please feel free to 28 | # incorporate it into whatever project you feel appropriate. I release 29 | # all rights to it to the public domain. 30 | # 31 | # Written in June 2017 by David Griffith 32 | # 33 | 34 | use POSIX; 35 | 36 | my @lines; 37 | my $leftside; 38 | my $middle = 34; # put a tab in the 35th column 39 | my $skip; 40 | 41 | open(INFILE, "<$ARGV[0]"); 42 | chomp(@lines = ); 43 | close(INFILE); 44 | 45 | @lines = grep(/\S/, @lines); 46 | 47 | if (scalar @lines % 2 == 1) { push @lines, ""; } 48 | 49 | $leftsize = ceil(scalar @lines / 2); 50 | for (my $i = 0; $i < $leftsize; $i++) { 51 | $skip = $middle - (2 + length($lines[$i])); 52 | print " $lines[$i]"; 53 | if ($lines[$i + $leftsize] eq "") { 54 | print "\\n\n"; 55 | } else { 56 | print " " x $skip . "\\t $lines[$i + $leftsize]\\n\\\n"; 57 | } 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /frotz/src/sdl/sf_msg_en.c: -------------------------------------------------------------------------------- 1 | #include "sf_frotz.h" 2 | 3 | const char * sf_msgstring( int id) 4 | { 5 | const char *p = ""; 6 | switch (id) 7 | { 8 | case IDS_BLORB_GLULX: 9 | p = "unsupported Glulx code\n\nYou have attempted to load a Blorb file containing a Glulx game.\n" 10 | "For this game you need a Glulx interpreter instead."; 11 | break; 12 | case IDS_BLORB_NOEXEC: 13 | p = "no Z code\n\nYou have attempted to load a Blorb file that does not contain any\n" 14 | "recognized game data. It may be a Blorb file containing just graphics or\n" 15 | "sound data for a game, with the game in a separate file.\nCheck for a " 16 | "file with the same name but an extension of .z5, .z6 or .z8\nand try " 17 | "loading that into Frotz instead."; 18 | break; 19 | case IDS_MORE: 20 | p = "[More]"; 21 | break; 22 | case IDS_HIT_KEY_EXIT: 23 | p = "[Hit any key to exit.]"; 24 | break; 25 | case IDS_TITLE: 26 | p = "SDL Frotz"; 27 | break; 28 | case IDS_FATAL: 29 | p = "Frotz Fatal Error"; 30 | break; 31 | case IDS_FROTZ: 32 | p = "Frotz"; 33 | break; 34 | case IDS_FAIL_DIRECTSOUND: 35 | p = "Failed to initialize DirectSound"; 36 | break; 37 | case IDS_FAIL_MODPLUG: 38 | p = "Failed to initialize MODPlug"; 39 | break; 40 | case IDS_ABOUT_INFO: 41 | p = "{\\rtf1\\ansi{\\b Windows Frotz 1.10, written by David Kinder.\\line Another fine product of the Frobozz Magic Z-code Interpreter Company.}{\\line\\super{ }\\par}Windows Frotz is released under the terms of the GNU General Public License. See the file COPYING that is included with this program for details.{\\line\\super{ }\\par}Windows Frotz copyright David Kinder 2002-2006.\\line Frotz copyright Stefan Jokisch 1995-1997.{\\line\\super{ }\\par}Frotz was written by Stefan Jokisch, with additions by Jim Dunleavy and David Griffith. Windows Frotz uses 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; ModPlug by Olivier Lapicque; and libogg and libvorbis by the Xiph.org Foundation.}"; 42 | break; 43 | case IDS_SAVE_TITLE: 44 | p = "Save the current game"; 45 | break; 46 | case IDS_RESTORE_TITLE: 47 | p = "Restore a saved game"; 48 | break; 49 | case IDS_LOAD_AUX_TITLE: 50 | p = "Load a portion of z-machine memory"; 51 | break; 52 | case IDS_SAVE_AUX_TITLE: 53 | p = "Save a portion of z-machine memory"; 54 | break; 55 | case IDS_AUX_FILTER: 56 | p = "*|Any file"; 57 | break; 58 | case IDS_SAVE_FILTER: 59 | p = "*.sav|Saved games"; 60 | break; 61 | case IDS_RECORD_TITLE: 62 | p = "Record input to a file"; 63 | break; 64 | case IDS_PLAYBACK_TITLE: 65 | p = "Play back recorded input"; 66 | break; 67 | case IDS_RECORD_FILTER: 68 | p = "*.rec|Record Files"; 69 | break; 70 | case IDS_SCRIPT_TITLE: 71 | p = "Write out a script"; 72 | break; 73 | case IDS_SCRIPT_FILTER: 74 | p = "*.log|Transcript Log Files"; 75 | break; 76 | default: 77 | break; 78 | } 79 | 80 | return p; 81 | } 82 | -------------------------------------------------------------------------------- /frotz/src/sdl/sf_resample.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "sf_frotz.h" 8 | 9 | #include "samplerate.h" 10 | 11 | static int myconv( CONV *conv, FILE *f, void *dest, int nin, int eod) 12 | { 13 | int nbrd, i, j, v=0; 14 | float *sdata; 15 | unsigned char c1, c2; char c; 16 | SRC_DATA src; 17 | sdata = src.data_in = conv->inbuf; src.data_out = conv->outbuf; 18 | src.input_frames = nin; src.output_frames = conv->maxout; 19 | src.src_ratio = conv->ratio; 20 | src.end_of_input = eod; 21 | // load input data 22 | nbrd = conv->bytespersam; 23 | switch (conv->bytespersam) 24 | { 25 | case 1: 26 | for (i=0;ichannels;i++) 27 | { 28 | c = fgetc(f); 29 | *sdata++ = (((short)c) << 8)/32768.0; 30 | } 31 | break; 32 | case 2: 33 | for (i=0;ichannels;i++) 34 | { 35 | c1 = fgetc(f); 36 | c2 = fgetc(f); 37 | *sdata++ = ((short)(((unsigned short)c1) << 8 + (unsigned short)c2)) 38 | / 32768.0; 39 | } 40 | } 41 | // do conversion 42 | src_process ((SRC_STATE *)conv->aux, &src); 43 | // save output 44 | nbrd = src.output_frames_gen; 45 | src_float_to_short_array (conv->outbuf, (short *)dest, nbrd*conv->channels) ; 46 | 47 | return nbrd; 48 | } 49 | 50 | static void finish( CONV *conv) 51 | { 52 | if (conv->inbuf) free(conv->inbuf); 53 | if (conv->outbuf) free(conv->outbuf); 54 | if (conv->aux) src_delete(conv->aux); 55 | conv->inbuf = conv->outbuf = NULL; 56 | conv->aux = NULL; 57 | } 58 | 59 | extern int (*sfx_exinitconv)( CONV *conv); 60 | 61 | static int my_exinitconv( CONV *conv) 62 | { 63 | int err; 64 | if (!conv) return 0; 65 | conv->inbuf = malloc(conv->maxin*conv->channels*sizeof(float)); 66 | if (!conv->inbuf) return 0; 67 | conv->outbuf = malloc(conv->maxout*conv->channels*sizeof(float)); 68 | if (!conv->outbuf) { free(conv->inbuf); return 0;} 69 | conv->aux = src_new(SRC_SINC_FASTEST,conv->channels,&err); 70 | if (!conv->aux){ finish(conv); return 0;} 71 | conv->finishCONV = finish; 72 | conv->doCONV = myconv; 73 | return 1; 74 | } 75 | 76 | static void MyInitFunc(void) __attribute__ ((constructor)); 77 | static void MyInitFunc(void) 78 | { 79 | sfx_exinitconv = my_exinitconv; 80 | } 81 | -------------------------------------------------------------------------------- /frotz/src/test/README: -------------------------------------------------------------------------------- 1 | These programs are intended to excercise the interpreter that it is 2 | functioning according to spec. As far as I can determine, the programs 3 | are in the public domain or made freely available with no restrictions. 4 | Copyrights are retained by the original authors where noted. 5 | 6 | 7 | crashme.inf Self-modifying reproducing Z-code. Generates random junk 8 | to see how the interpreter behaves. A good interpreter 9 | shouldn't die except on fatal errors. 10 | Written by Evin Robertson in 1999. 11 | 12 | etude/ TerpEtude (etude.z5). Exercises the Z-machine for proper 13 | behavior. Does not test error-handling. 14 | Written by Andrew Plotkin in 1997 15 | 16 | gntests.inf Assorted tests for checking proper handling of fonts, 17 | accents, input codes, colors, header, and timed input. 18 | Conforms to the Z-Spec 0.99 by Graham Nelson. Something 19 | of a weaker version of TerpEtude (above). 20 | Written by Graham Nelson as a collection of sample 21 | programs and unified by Andrew Plotkin in 1997. 22 | 23 | random.inf Inform Randomization Test v1.0. 24 | Assorted tests for checking the performance of the 25 | interpreter's random number generator. 26 | Written by David Griffith in 2002. 27 | 28 | strictz.inf Tests an interpreter's error-checking by attempting to 29 | cause all possible non-fatal errors. 30 | Written by Torbjorn Andersson in 1998. 31 | 32 | unicode.inf Unicode Test v1.0. 33 | Creates assorted unicode characters. 34 | Written by David Kinder in 2002. 35 | -------------------------------------------------------------------------------- /frotz/src/test/crashme.inf: -------------------------------------------------------------------------------- 1 | ! Self-modifying reproducing Z-code. 2 | ! 3 | ! Generates random junk and sees how the interpreter behaves. If it's clever 4 | ! it shouldn't die except for @quit and stack overflow. 5 | ! 6 | ! inform \$MAX_STATIC_DATA=40000 crashme.inf 7 | ! 8 | ! Written by Evin Robertson 1999. Placed in public domain. 9 | 10 | Array randstuff -> 32767; 11 | Array checkfix -> 257; 12 | 13 | Global replay = 0; 14 | 15 | Array filename string "CRASHME.MEM"; 16 | 17 | #iftrue (#version_number <= 3); 18 | Constant Granularity = 2; 19 | Constant FileMult = 2; 20 | #endif; 21 | 22 | #iftrue (#version_number >= 4 && #version_number <= 5); 23 | Constant Granularity = 4; 24 | Constant FileMult = 4; 25 | #endif; 26 | 27 | #iftrue (#version_number >= 6 && #version_number <= 7); 28 | Constant Granularity = 4; 29 | Constant FileMult = 8; 30 | #endif; 31 | 32 | #iftrue (#version_number == 8); 33 | Constant Granularity = 8; 34 | Constant FileMult = 8; 35 | #endif; 36 | 37 | 38 | [ Main i a g r c l t game_size checksum; 39 | game_size = FileMult * (0-->13); ! game size 40 | 41 | r = randstuff % Granularity; 42 | if(r) 43 | r = Granularity - r; 44 | 45 | a = randstuff + r; 46 | c = a / Granularity; 47 | l = 32767 - r; 48 | 49 | if(replay) { 50 | print "You are running crashme's output. This will repeat the test run which generated this output.^"; 51 | } else { 52 | print "This program generates random Z-code which is run to test the robustness of your Z-machine interpreter. Most likely this will infinite loop. Do not run if you can't kill your interpreter when it is tightly looping.^Will attempt to write CRASHME.MEM which should be a valid Z-machine game which contains the same code that will be run.^"; 53 | } 54 | print "Press 'q' to abort.^"; 55 | @read_char 1 -> i; 56 | if(i == 'Q' or 'q') 57 | @quit; 58 | 59 | replay++; 60 | 61 | 62 | if(replay == 1) { 63 | for(i=0: i < l: i++) 64 | a->i = random(256) - 1; 65 | for(i=0: i < 13: i++) 66 | a->i = (emptyfunc * Granularity)->i; 67 | 68 | checksum = 0; 69 | for(i=0: i < l: i++) 70 | checksum = checksum + a->i; 71 | g = 0-->6; ! globals location 72 | for(i=0: i < 480: i++) 73 | checksum = checksum + g->i; 74 | 75 | for(i=0: i < 257: i++) { 76 | if(-255 <= checksum && checksum <= 0) { 77 | checkfix->i = -checksum; 78 | break; 79 | } else { 80 | checkfix->i = 255; 81 | checksum = checksum + 255; 82 | } 83 | } 84 | #IFV5; @save 0 game_size filename -> t; #ENDIF; 85 | } 86 | 87 | ! reduce the chances that it'll attempt to write over the same file 88 | for(i=0: i <= 11: i++) 89 | filename->i = 0; 90 | 91 | @call_vn c; 92 | print "^Done.^"; 93 | ]; 94 | 95 | [ emptyfunc; 96 | print "starting...^"; 97 | ]; 98 | -------------------------------------------------------------------------------- /frotz/src/test/crashme.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/crashme.z5 -------------------------------------------------------------------------------- /frotz/src/test/etude/Makefile: -------------------------------------------------------------------------------- 1 | 2 | etude.z5: etude.inf header.inc styles.inc color.inc \ 3 | accents.inc accentin.inc division.inc timedch.inc \ 4 | timedstr.inc givenin.inc undo.inc exittext.inc 5 | inform etude.inf etude.z5 6 | 7 | gntests.z5: gntests.inf 8 | inform gntests.inf gntests.z5 9 | 10 | go: etude.z5 11 | xzip etude.z5 12 | 13 | fgo: etude.z5 14 | frotz etude.z5 15 | 16 | jgo: etude.z5 17 | jzip etude.z5 18 | -------------------------------------------------------------------------------- /frotz/src/test/etude/README: -------------------------------------------------------------------------------- 1 | This archive contains the TerpEtude game file (etude.z5). 2 | 3 | It also contains all the Inform 6 source code for TerpEtude: 4 | 5 | etude.inf 6 | accents.inc 7 | accentin.inc 8 | color.inc 9 | division.inc 10 | exittext.inc 11 | givenin.inc 12 | graham.inf 13 | header.inc 14 | styles.inc 15 | timedch.inc 16 | timedstr.inc 17 | undo.inc 18 | 19 | I strongly recommend that TerpEtude only be distributed in this 20 | format -- that is, with game file and source code together. A 21 | programmer who wants to test his interpreter can't really know 22 | what he's doing unless he sees exactly what the tests are. 23 | 24 | I've also thrown in gntests.z5 and gntests.inf; this program 25 | comprises the six test programs that Graham appended to the 26 | Z-Spec TeX document. (Taken from the 0.99 spec.tex file.) 27 | 28 | -------------------------------------------------------------------------------- /frotz/src/test/etude/color.inc: -------------------------------------------------------------------------------- 1 | 2 | Array colortab --> 3 | "" "" "Black" "Red" "Green" "Yellow" "Blue" "Magenta" "Cyan" "White"; 4 | 5 | [ TestColor val fg bg claim; 6 | 7 | val = $0->1; 8 | 9 | if (val & 1) { 10 | print "Interpreter claims that colored text IS available.^"; 11 | claim = 1; 12 | } 13 | else { 14 | print "Interpreter claims that colored text IS NOT available.^"; 15 | claim = 0; 16 | } 17 | 18 | if (claim) 19 | print "^In the square below, you should see"; 20 | else 21 | print "^If it was, in the square below, you would see"; 22 | 23 | print " vertical stripes of background color (matching the column 24 | headers) and horizontal rows of foreground color (that is, all 25 | # marks in a row the same color.)^"; 26 | 27 | font off; 28 | 29 | new_line; 30 | print "Bk Rd Gr Yl Bl Mg Cy Wh^"; 31 | for (fg=2:fg<10:fg++) { 32 | for (bg=2:bg<10:bg++) { 33 | @set_colour fg bg; 34 | print "## "; 35 | } 36 | @set_colour 1 1; 37 | print ": ", (string)colortab-->fg, "^"; 38 | } 39 | 40 | font on; 41 | 42 | ]; 43 | -------------------------------------------------------------------------------- /frotz/src/test/etude/division.inc: -------------------------------------------------------------------------------- 1 | 2 | [ TestDivLine str answer correct; 3 | print (string) str, " = ", answer; 4 | if (answer == correct) { 5 | print " (ok)^"; 6 | } 7 | else { 8 | print " (ERROR, should be ", correct, "!)^"; 9 | errflag = 1; 10 | } 11 | ]; 12 | 13 | [ TestDiv x y z; 14 | print "This tests signed multiplication, division, and modulo 15 | operations. All these operations are supposed to be 16 | signed. (The Z-Spec 0.2 erroneously says they are unsigned; this is 17 | corrected in 0.99.)^^"; 18 | 19 | print "I am assuming the convention that division always rounds towards 20 | zero (not towards negative infinity), and (A % B) always has the 21 | same sign as A. These conventions seem to be common among existing 22 | C/C++ compilers. The Infocom interpreters also follow these conventions. 23 | (But they are not guaranteed by the C and C++ standards. Those only 24 | require that (A/B)*B + (A%B) == A, for all A and all nonzero B.)^^"; 25 | 26 | errflag = 0; 27 | 28 | x = 13; y = 5; z = x * y; 29 | TestDivLine("13 * 5", z, 65); 30 | x = 13; y = -5; z = x * y; 31 | TestDivLine("13 * -5", z, -65); 32 | x = -13; y = 5; z = x * y; 33 | TestDivLine("-13 * 5", z, -65); 34 | x = -13; y = -5; z = x * y; 35 | TestDivLine("-13 * -5", z, 65); 36 | 37 | x = 13; y = 5; z = x / y; 38 | TestDivLine("13 / 5", z, 2); 39 | x = 13; y = -5; z = x / y; 40 | TestDivLine("13 / -5", z, -2); 41 | x = -13; y = 5; z = x / y; 42 | TestDivLine("-13 / 5", z, -2); 43 | x = -13; y = -5; z = x / y; 44 | TestDivLine("-13 / -5", z, 2); 45 | 46 | x = 13; y = 5; z = x % y; 47 | TestDivLine("13 % 5", z, 3); 48 | x = 13; y = -5; z = x % y; 49 | TestDivLine("13 % -5", z, 3); 50 | x = -13; y = 5; z = x % y; 51 | TestDivLine("-13 % 5", z, -3); 52 | x = -13; y = -5; z = x % y; 53 | TestDivLine("-13 % -5", z, -3); 54 | 55 | if (errflag == 0) { 56 | print "^", (string)SectionOk; 57 | } 58 | else { 59 | print "^", (string)SectionBad; 60 | } 61 | ]; 62 | -------------------------------------------------------------------------------- /frotz/src/test/etude/etude.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/etude/etude.z5 -------------------------------------------------------------------------------- /frotz/src/test/etude/exittext.inc: -------------------------------------------------------------------------------- 1 | 2 | [ TestExitText ix; 3 | 4 | print "This tests if you can read text which is displayed 5 | immediately before the program quits. (It is not clear whether 6 | this is covered by the Z-Spec. However, some games -- including some 7 | original Infocom games -- display important closing text and then 8 | immediately quit.)^^"; 9 | print "Hit ~.~ to return to the main menu, or any other key to print a 10 | line of text and then quit. If the line of text does not appear, 11 | or appears and vanishes too quickly to read, your interpreter will 12 | have trouble with those games.^^"; 13 | 14 | print "ClosingText> "; 15 | ix = GetKey(); 16 | if (ix == '.') { 17 | print "^Test aborted.^"; 18 | return; 19 | } 20 | 21 | print "^^This is a final line of text. Goodbye.^"; 22 | quit; 23 | 24 | ]; 25 | -------------------------------------------------------------------------------- /frotz/src/test/etude/givenin.inc: -------------------------------------------------------------------------------- 1 | 2 | [ TestGivenInput ix inbufvar; 3 | 4 | print "This tests whether your interpreter supports being handed 5 | input by the game file. (For example, after a function key is hit 6 | in Beyond Zork, the command prompt appears with text already in 7 | place -- whatever text you had typed before you interrupted it 8 | with the function key.)^^"; 9 | 10 | print "The command prompt below should appear with the word 11 | ~Given~ already visible after it. You should be able to type 12 | more characters, or go back and edit the given character as if 13 | you had typed them yourself.^^"; 14 | 15 | print "If you see the word ~Given~ twice, your interpreter is 16 | printing the given characters, which it shouldn't (that's 17 | the responsibility of the game file.)^^"; 18 | 19 | print "Preload> Given"; 20 | inbuf->0 = (INBUFSIZE-3); 21 | inbuf->1 = 5; 22 | 23 | inbuf->2 = 'G'; 24 | inbuf->3 = 'i'; 25 | inbuf->4 = 'v'; 26 | inbuf->5 = 'e'; 27 | inbuf->6 = 'n'; 28 | 29 | inbufvar = inbuf; 30 | ix = 0; 31 | @aread inbufvar ix; 32 | 33 | if (inbuf->1 == 0) 34 | print "You just typed a blank line.^"; 35 | else { 36 | print "You just typed ~"; 37 | for (ix=0: ix1: ix++) 38 | print (char)(inbuf->(2+ix)); 39 | print "~.^"; 40 | } 41 | 42 | ]; 43 | -------------------------------------------------------------------------------- /frotz/src/test/etude/header.inc: -------------------------------------------------------------------------------- 1 | 2 | [ TestHeader val val2; 3 | 4 | val = $32->0; 5 | val2 = $32->1; 6 | if (val == 0 && val2 == 0) { 7 | print "Your interpreter does not claim to follow any particular version 8 | of the Z-Spec.^^"; 9 | } 10 | else { 11 | print "Your interpreter claims to follow revision ", val, ".", val2, 12 | " of the Z-Spec.^^"; 13 | } 14 | 15 | val = $0->1; 16 | 17 | if (val & 1) { 18 | print "Interpreter claims that colored text IS available.^"; 19 | } 20 | else { 21 | print "Interpreter claims that colored text IS NOT available.^"; 22 | } 23 | 24 | if (val & 4) { 25 | print "Interpreter claims that emphasized (bold) text IS 26 | available.^"; 27 | } 28 | else { 29 | print "Interpreter claims that emphasized (bold) text IS NOT 30 | available.^"; 31 | } 32 | 33 | if (val & 8) { 34 | print "Interpreter claims that italic (or underlined) text IS 35 | available.^"; 36 | } 37 | else { 38 | print "Interpreter claims that italic (or underlined) text IS 39 | NOT available.^"; 40 | } 41 | 42 | if (val & 16) { 43 | print "Interpreter claims that fixed-width text IS available.^"; 44 | } 45 | else { 46 | print "Interpreter claims that fixed-width text IS NOT 47 | available.^"; 48 | } 49 | 50 | if (val & 32) { 51 | print "Interpreter claims that sound effects ARE available.^"; 52 | } 53 | else { 54 | print "Interpreter claims that sound effects ARE NOT available.^"; 55 | } 56 | 57 | if (val & 128) { 58 | print "Interpreter claims that timed input IS available.^"; 59 | } 60 | else { 61 | print "Interpreter claims that timed input IS NOT available.^"; 62 | } 63 | 64 | new_line; 65 | val = $10->1; 66 | 67 | if (val & 16) { 68 | print "Interpreter claims that ~undo~ IS available.^"; 69 | } 70 | else { 71 | print "Interpreter claims that ~undo~ IS NOT available.^"; 72 | } 73 | ]; 74 | -------------------------------------------------------------------------------- /frotz/src/test/etude/timedch.inc: -------------------------------------------------------------------------------- 1 | 2 | Global timedcharflag; 3 | Global timedcharcounter; 4 | 5 | [ TestTimedChar claim ix; 6 | 7 | ix = $0->1; 8 | if (ix & 128) { 9 | claim = 1; 10 | print "Your interpreter claims (by its header bit) that it DOES 11 | support timed input.^^"; 12 | } 13 | else { 14 | claim = 0; 15 | print "Your interpreter claims (by its header bit) that it DOES 16 | NOT support timed input.^^"; 17 | } 18 | 19 | print "When you begin this test, asterisks should appear at the rate 20 | of one per second. If they appear at the rate of one every ten 21 | seconds, your interpreter is using the incorrect timing rate 22 | caused by an old bug in ZIP. If an entire line of ten asterisks 23 | appears all at once every ten seconds, your interpreter is not 24 | properly flushing its buffer.^^"; 25 | 26 | while (1) { 27 | print "Hit ~.~ to return to the main menu, or any other key to begin 28 | the test. Hit any key to stop the test while it is running.^^"; 29 | 30 | print "TimedKey> "; 31 | ix = GetKey(); 32 | if (ix == '.') 33 | return; 34 | new_line; 35 | 36 | timedcharcounter = 0; 37 | timedcharflag = -93; 38 | @read_char 1 10 TimedCharSplot ix; 39 | new_line; 40 | 41 | if (timedcharflag == -93) { 42 | print "The timing interrupt function was not called at 43 | all. Either your interpreter does not support timed input, or 44 | you terminated the test before one second elapsed. (Or your 45 | interpreter has the ~slow~ bug and you terminated the test 46 | before ten seconds elapsed.)^^"; 47 | if (claim == 0) 48 | print "Your interpreter claims to not support timed 49 | input. ", (string)SectionOk; 50 | else 51 | print "Your interpreter claims to support timed input. ", 52 | (string)SectionBad; 53 | } 54 | else { 55 | if (timedcharflag == 0) { 56 | print "Your interpreter calls the timing interrupt function 57 | with no arguments. "; 58 | if (claim == 0) 59 | print "This is correct, except that your interpreter claims 60 | not to support timed input at all. ", (string)SectionBad; 61 | else 62 | print (string)SectionOk; 63 | } 64 | else { 65 | print "Your interpreter calls the timing interrupt function 66 | with an argument. ", (string)SectionBad; 67 | } 68 | } 69 | new_line; 70 | } 71 | ]; 72 | 73 | [ TimedCharSplot arg; 74 | timedcharflag = arg; 75 | print "* "; 76 | timedcharcounter++; 77 | if (timedcharcounter == 10) { 78 | new_line; 79 | timedcharcounter = 0; 80 | } 81 | return 0; 82 | ]; 83 | -------------------------------------------------------------------------------- /frotz/src/test/gntests.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/gntests.z5 -------------------------------------------------------------------------------- /frotz/src/test/random.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/random.z5 -------------------------------------------------------------------------------- /frotz/src/test/strictz.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/strictz.z5 -------------------------------------------------------------------------------- /frotz/src/test/unicode.inf: -------------------------------------------------------------------------------- 1 | ! Unicode Test v1.0 2 | ! 3 | ! David Kinder, 2002. 4 | ! 5 | 6 | Switches xv5; 7 | Release 1; 8 | 9 | Zcharacter table + '@{a9}' '@{2122}' '@{20ac}'; 10 | 11 | [ main; 12 | 13 | print "^Unicode Test v1.0, by David Kinder^"; 14 | new_line; 15 | 16 | print "Testing the Unicode table. This sentence should end with Euro, copyright and trademark symbols @{20ac} @{a9} @{2122}^"; 17 | new_line; 18 | 19 | print "Now, testing print_unicode()...^"; 20 | charsets(); 21 | new_line; 22 | 23 | print "Now, testing input (ESC to quit)...^"; 24 | input_unicode(); 25 | ]; 26 | 27 | [ input_unicode key; 28 | 29 | print "Try inputing a character. Since the Euro symbol is declared in this file's Zcharacter table, "; 30 | print "it can be input even though it is not part of ISO Latin-1.^"; 31 | while (1) 32 | { 33 | @read_char 1 -> key; 34 | 35 | if (key == $1b) 36 | quit; 37 | 38 | font off; 39 | print "ZSCII $", (hex) key, " = "; 40 | font on; 41 | 42 | switch (key) 43 | { 44 | 8: print "delete"; 45 | 13: print "return"; 46 | 129: print "cursor up"; 47 | 130: print "cursor down"; 48 | 131: print "cursor left"; 49 | 132: print "cursor right"; 50 | 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144: print "function key ", key-132; 51 | 145, 146, 147, 148, 149, 150, 151, 152, 153, 154: print "keypad key ", key-145; 52 | 252: print "menu click"; 53 | 253: print "mouse double-click"; 54 | 254: print "mouse single-click"; 55 | default: print (char) key; 56 | } 57 | new_line; 58 | } 59 | ]; 60 | 61 | [ charsets; 62 | 63 | charset("Basic Latin",$0020,3); 64 | charset("Latin-1 Supplement",$00a0,3); 65 | charset("Latin Extended-A",$0100,4); 66 | charset("Greek and Coptic",$0360,5); 67 | charset("Cyrillic",$0400,8); 68 | charset("Arabic",$0600,8); 69 | ]; 70 | 71 | [ charset title start lines i; 72 | 73 | font off; 74 | new_line; 75 | print (string) title; 76 | new_line; 77 | 78 | for (i = 0: i < lines: i++) 79 | charrow(start+(i*32)); 80 | font on; 81 | ]; 82 | 83 | [ charrow start i; 84 | 85 | print (hex) start, " : "; 86 | for (i = 0: i < 32: i++) 87 | charout(start+i); 88 | new_line; 89 | ]; 90 | 91 | [ charout c exist; 92 | 93 | @"EXT:12S" c -> exist; 94 | if (exist & 1) 95 | @"EXT:11" c; 96 | else 97 | print (char) ' '; 98 | ]; 99 | 100 | [ hex x y; 101 | 102 | y = (x & $7f00) / $100; 103 | if (x < 0) 104 | y = y + $80; 105 | x = x & $ff; 106 | print (hexdigit) y/$10, (hexdigit) y, (hexdigit) x/$10, (hexdigit) x; 107 | ]; 108 | 109 | [ hexdigit x; 110 | 111 | x = x % $10; 112 | switch (x) 113 | { 114 | 0 to 9: print x; 115 | 10: print "a"; 116 | 11: print "b"; 117 | 12: print "c"; 118 | 13: print "d"; 119 | 14: print "e"; 120 | 15: print "f"; 121 | } 122 | ]; 123 | 124 | -------------------------------------------------------------------------------- /frotz/src/test/unicode.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/frotz/src/test/unicode.z5 -------------------------------------------------------------------------------- /frotz/src/ztools/getopt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ERR(s, c) \ 5 | if (opterr) {\ 6 | char errbuf[2];\ 7 | errbuf[0] = (char) c; errbuf[1] = '\n';\ 8 | (void) fwrite (argv[0], strlen (argv[0]), 1, stderr);\ 9 | (void) fwrite (s, strlen (s), 1, stderr);\ 10 | (void) fwrite (errbuf, 2, 1, stderr);\ 11 | } 12 | 13 | int opterr = 1; 14 | int optind = 1; 15 | int optopt; 16 | const char *optarg; 17 | 18 | #ifdef __STDC__ 19 | int getopt (int argc, char *argv[], const char *opts) 20 | #else 21 | int getopt (argc, argv, opts) 22 | int argc; 23 | char *argv[]; 24 | const char *opts; 25 | #endif 26 | { 27 | static int sp = 1; 28 | int c; 29 | char *cp; 30 | 31 | if (sp == 1) 32 | if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') 33 | return (EOF); 34 | else if (strcmp (argv[optind], "--") == 0) { 35 | optind++; 36 | return (EOF); 37 | } 38 | optopt = c = argv[optind][sp]; 39 | if (c == ':' || (cp = strchr (opts, c)) == NULL) { 40 | ERR (": illegal option -- ", c); 41 | if (argv[optind][++sp] == '\0') { 42 | optind++; 43 | sp = 1; 44 | } 45 | return ('?'); 46 | } 47 | if (*++cp == ':') { 48 | if (argv[optind][sp+1] != '\0') 49 | optarg = &argv[optind++][sp+1]; 50 | else if (++optind >= argc) { 51 | ERR (": option requires an argument -- ", c); 52 | sp = 1; 53 | return ('?'); 54 | } else 55 | optarg = argv[optind++]; 56 | sp = 1; 57 | } else { 58 | if (argv[optind][++sp] == '\0') { 59 | sp = 1; 60 | optind++; 61 | } 62 | optarg = NULL; 63 | } 64 | 65 | return (c); 66 | 67 | }/* getopt */ 68 | -------------------------------------------------------------------------------- /frotz/src/ztools/makefile: -------------------------------------------------------------------------------- 1 | # Unix C makefile for the Infocom tools 2 | 3 | # Use gcc if CC is not defined 4 | CC ?= gcc 5 | 6 | #Some systems declare getopt, others do not. Pick whichever works 7 | #CFLAGS = -O -DHAS_GETOPT 8 | CFLAGS = -O 9 | LDFLAGS = 10 | LIBS = 11 | 12 | 13 | .SUFFIXES: .c .h 14 | 15 | IINC = tx.h 16 | IOBJS = infodump.o showhead.o showdict.o showobj.o showverb.o txio.o infinfo.o symbols.o 17 | 18 | TINC = tx.h 19 | TOBJS = txd.o txio.o showverb.o infinfo.o symbols.o showobj.o 20 | 21 | all : infodump txd 22 | 23 | infodump : $(IOBJS) 24 | $(CC) -o $@ $(LDFLAGS) $(IOBJS) $(LIBS) 25 | 26 | $(IOBJS) : $(IINC) 27 | 28 | $(POBJS) : $(PINC) 29 | 30 | txd : $(TOBJS) 31 | $(CC) -o $@ $(LDFLAGS) $(TOBJS) $(LIBS) 32 | 33 | $(TOBJS) : $(TINC) 34 | 35 | clean : 36 | -rm *.o infodump txd 37 | -------------------------------------------------------------------------------- /frotz/src/ztools/ztools.h: -------------------------------------------------------------------------------- 1 | #ifndef ztools_h__ 2 | #define ztools_h__ 3 | 4 | void print_dictionary(const char *rom_file); 5 | void print_verbs (const char *rom_file); 6 | void disassemble (const char *rom_file); 7 | void ztools_cleanup (); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /frotz/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "frotz_interface.h" 3 | #include "tx.h" 4 | 5 | int main (int argc, char *argv[]) 6 | { 7 | // Init 8 | unsigned char s[8192] = ""; 9 | dict_word_t dict[1024]; 10 | int dict_size; 11 | setup("/home/matthew/workspace/text_agents/roms/zork1.z5", 0); 12 | 13 | for (int i=0; i<100; ++i) { 14 | shutdown(); 15 | setup("/home/matthew/workspace/text_agents/roms/zork1.z5", 0); 16 | dict_size = get_dictionary_word_count("/home/matthew/workspace/text_agents/roms/zork1.z5"); 17 | get_dictionary(dict, dict_size); 18 | ztools_cleanup(); 19 | step("look\n"); 20 | save_str(&s); 21 | step("s\n"); 22 | restore_str(&s); 23 | } 24 | 25 | shutdown(); 26 | 27 | /* printf("World Changed %d\n", world_changed()); */ 28 | /* test(); */ 29 | /* printf("%s\n", step("look\n")); */ 30 | /* printf("World Changed %d\n", world_changed()); */ 31 | /* test(); */ 32 | /* printf("%s\n", step("look\n")); */ 33 | /* printf("World Changed %d\n", world_changed()); */ 34 | /* test(); */ 35 | /* save("test.qzl"); */ 36 | /* save_str(&s); */ 37 | /* printf("\n\nAfter Save: %s\n", step("s\n")); */ 38 | /* restore("test.qzl"); */ 39 | /* restore_str(&s); */ 40 | /* printf("\n\nFirst: %s\n", step("look\n")); */ 41 | /* printf("%s\n", step("save\n")); */ 42 | } 43 | -------------------------------------------------------------------------------- /jericho/__init__.py: -------------------------------------------------------------------------------- 1 | from .jericho import * 2 | from .version import __version__ 3 | -------------------------------------------------------------------------------- /jericho/examples/random_agent.py: -------------------------------------------------------------------------------- 1 | """ 2 | Use jericho's template action generator to select random actions 3 | """ 4 | import argparse 5 | import random 6 | from termcolor import colored 7 | 8 | from jericho import FrotzEnv 9 | 10 | 11 | # Create the environment, optionally specifying a random seed 12 | def parse_args(): 13 | parser = argparse.ArgumentParser() 14 | 15 | parser.add_argument("rom_path", help="Path to a Z-Machine game.", type=str, 16 | default="../../z-machine-games-master/jericho-game-suite/905.z5") 17 | parser.add_argument( "--max_iterations", type=int, 18 | help="Maximum number of iterations to allow the agent to run.", default=100) 19 | parser.add_argument( "--debug", action="store_true", help="Launch ipdb.") 20 | parser.add_argument("-v", "--verbose", action="store_true", 21 | help="Print the last observation when not achieving max score.") 22 | return parser.parse_args() 23 | 24 | 25 | def get_random_action(env, args): 26 | valid_actions = env.get_valid_actions() 27 | chosen_action = random.choice(valid_actions) 28 | if args.verbose: 29 | print(colored(("valid actions:", valid_actions), 'green')) 30 | print(colored(("chosen action:", chosen_action), 'red')) 31 | return chosen_action 32 | 33 | 34 | args = parse_args() 35 | env = FrotzEnv(args.rom_path) 36 | obs, info = env.reset() 37 | done = False 38 | 39 | while not done: 40 | if args.debug: 41 | import ipdb; ipdb.set_trace() 42 | args.max_iterations -= 1 43 | if (args.max_iterations < 1): 44 | print(colored('Max Iterations Exceeded -- BREAK', 'red')) 45 | break 46 | 47 | # Use TemplateActionGenerator to select an action 48 | chosen_action = get_random_action(env, args) 49 | 50 | # Take an action in the environment using the step fuction. 51 | # The resulting text-observation, reward, and game-over indicator is returned. 52 | observation, reward, done, info = env.step(chosen_action) 53 | # Total score and move-count are returned in the info dictionary 54 | if args.verbose: 55 | print(observation) 56 | print('Total Score', info['score'], 'Moves', info['moves']) 57 | print('Scored', info['score'], 'out of', env.get_max_score()) 58 | -------------------------------------------------------------------------------- /jericho/version.py: -------------------------------------------------------------------------------- 1 | __version__ = '3.3.0' 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | numpy 3 | spacy>=2.1.0 4 | termcolor 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018 Microsoft Corporation 2 | 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License 5 | # as published by the Free Software Foundation; either version 2 6 | # of the License, or (at your option) any later version. 7 | 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 | 17 | from setuptools import setup 18 | from distutils.core import setup 19 | import os.path, sys 20 | import subprocess 21 | 22 | BASEPATH = os.path.dirname(os.path.abspath(__file__)) 23 | FROTZPATH = os.path.join(BASEPATH, 'frotz') 24 | subprocess.check_call(['make', 'clean'], cwd=FROTZPATH) 25 | subprocess.check_call(['make', 'library', '-j', '4'], cwd=FROTZPATH) 26 | 27 | frotz_c_lib = 'jericho/libfrotz.so' 28 | if not os.path.isfile(frotz_c_lib): 29 | print('ERROR: Unable to find required library %s.'%(frotz_c_lib)) 30 | sys.exit(1) 31 | 32 | exec(open('jericho/version.py').read()) 33 | setup(name='jericho', 34 | version=__version__, 35 | install_requires=open('requirements.txt').readlines(), 36 | description='A python interface to text-based adventure games.', 37 | author='Matthew Hausknecht', 38 | packages=['jericho'], 39 | python_requires='>=3.9', 40 | include_package_data=True, 41 | test_suite='pytest', 42 | tests_require=[ 43 | 'pytest', 44 | ], 45 | package_dir={'jericho': 'jericho'}, 46 | package_data={'jericho': ['libfrotz.so', 'clubfloyd_verb_counts.json']}, 47 | classifiers=[ 48 | "Programming Language :: Python :: 3", 49 | "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", 50 | "Operating System :: POSIX :: Linux", 51 | ] 52 | ) 53 | -------------------------------------------------------------------------------- /tests/benchmarks.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from os.path import join as pjoin 4 | 5 | import jericho 6 | 7 | 8 | DATA_PATH = os.path.abspath(pjoin(__file__, '..', "data")) 9 | 10 | 11 | def bench_loading_speed(): 12 | REPEAT = 1000 13 | 14 | start = time.time() 15 | rom = pjoin(DATA_PATH, "905.z5") 16 | for _ in range(REPEAT): 17 | env = jericho.FrotzEnv(rom) 18 | env.reset() 19 | env.close() 20 | 21 | duration1 = time.time() - start 22 | print("Calling FrotzEnv({}) {} times in {:6.2f} secs.".format(rom, REPEAT, duration1)) 23 | del env 24 | 25 | start = time.time() 26 | env = jericho.FrotzEnv(rom) 27 | for _ in range(REPEAT - 1): 28 | env.load(rom) 29 | env.reset() 30 | env.close() 31 | 32 | duration2 = time.time() - start 33 | print("Calling env.load({}) {} times in {:6.2f} secs.".format(rom, REPEAT, duration2)) 34 | print("Speedup: {}x.".format(duration1 / duration2)) 35 | 36 | 37 | if __name__ == "__main__": 38 | bench_loading_speed() 39 | -------------------------------------------------------------------------------- /tests/data/905.z5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/tests/data/905.z5 -------------------------------------------------------------------------------- /tests/data/dummy.z8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/tests/data/dummy.z8 -------------------------------------------------------------------------------- /tests/data/tw-cooking-recipe3+cook+cut-2057SPdQu0mWiv0k.z8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/tests/data/tw-cooking-recipe3+cook+cut-2057SPdQu0mWiv0k.z8 -------------------------------------------------------------------------------- /tests/data/tw-game.z8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/jericho/3e8d5b7a6a54a23ed0312fa36d677f607d591da0/tests/data/tw-game.z8 -------------------------------------------------------------------------------- /tests/test_unsupported_game.py: -------------------------------------------------------------------------------- 1 | import os 2 | import warnings 3 | from os.path import join as pjoin 4 | 5 | import jericho 6 | from jericho import UnsupportedGameWarning 7 | 8 | DATA_PATH = os.path.abspath(pjoin(__file__, '..', "data")) 9 | 10 | 11 | def test_loading_unsupported_game(): 12 | # Note: dummy.z8 is the same as tw-game.z8. 13 | gamefile = "dummy.z8" 14 | with warnings.catch_warnings(record=True) as w: 15 | env = jericho.FrotzEnv(pjoin(DATA_PATH, gamefile)) 16 | warnings.simplefilter("always") 17 | assert len(w) == 1 18 | assert issubclass(w[-1].category, UnsupportedGameWarning) 19 | assert gamefile in str(w[-1].message) 20 | 21 | state, info = env.reset() 22 | assert env.get_score() == 0 23 | assert env.get_max_score() == 0 # Instead of 3. 24 | 25 | state, score, done, _ = env.step("go east") 26 | state, score, done, _ = env.step("insert carrot into chest") 27 | assert score == 0 # Instead of 2. 28 | state, score, done, _ = env.step("close chest") 29 | assert score == 0 # Instead of 3. 30 | 31 | assert "The End" in state 32 | assert not done # Instead of True 33 | assert not env.victory() # Instead of True 34 | 35 | state, info = env.reset() 36 | state, score, done, _ = env.step("eat carrot") 37 | assert "You lost" in state 38 | assert not done # Instead of True 39 | assert not env.game_over() # Instead of True 40 | -------------------------------------------------------------------------------- /tests/test_valid_actions.py: -------------------------------------------------------------------------------- 1 | import os 2 | from os.path import join as pjoin 3 | import jericho 4 | 5 | DATA_PATH = os.path.abspath(pjoin(__file__, '..', "data")) 6 | 7 | def test_valid_action_identification(): 8 | rom_path = pjoin(DATA_PATH, '905.z5') 9 | env = jericho.FrotzEnv(rom_path) 10 | obs, info = env.reset() 11 | valid = env.get_valid_actions() 12 | assert 'take wallet' in valid 13 | assert 'open wallet' in valid 14 | assert 'take keys' in valid 15 | assert 'get up' in valid 16 | assert 'take phone' in valid 17 | -------------------------------------------------------------------------------- /tools/find_walkthrough.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | import argparse 5 | import readline 6 | 7 | import jericho 8 | 9 | 10 | def parse_args(): 11 | parser = argparse.ArgumentParser() 12 | 13 | parser.add_argument("filename", 14 | help="Path to a Z-Machine game.") 15 | parser.add_argument("--walkthrough", 16 | help="External walkthrough (one command per line). Default: use Jericho's one, if it exists.") 17 | parser.add_argument("--skip-to", type=int, default=0, 18 | help="Auto-play walkthrough until the nth command before dropping into interactive mode.") 19 | 20 | return parser.parse_args() 21 | 22 | args = parse_args() 23 | 24 | history = [] 25 | env = jericho.FrotzEnv(args.filename) 26 | obs, info = env.reset() 27 | 28 | history.append(env.get_state()) 29 | 30 | STEP_BY_STEP_WALKTRHOUGH = True 31 | 32 | walkthrough = env.get_walkthrough() 33 | if args.walkthrough: 34 | walkthrough = [] 35 | for line in open(args.walkthrough): 36 | cmd = line.split("#")[0].strip() 37 | if cmd: 38 | walkthrough.append(cmd) 39 | 40 | obs_list = [obs] 41 | commands = [] 42 | cpt = 0 43 | while True: 44 | if STEP_BY_STEP_WALKTRHOUGH and cpt < len(walkthrough): 45 | cmd = walkthrough[cpt] 46 | print(obs) 47 | if cpt >= args.skip_to: 48 | alt = input("{}. [{}] > ".format(cpt, cmd)) 49 | if alt: 50 | cmd = alt 51 | else: 52 | print("{}. [{}]".format(cpt, cmd)) 53 | else: 54 | print(obs) 55 | cmd = input("{}. > ".format(cpt)) 56 | 57 | if cmd == "undo": 58 | history = history[:-1] 59 | commands = commands[:-1] 60 | obs_list = obs_list[:-1] 61 | env.set_state(history[-1]) 62 | obs = obs_list[-1] 63 | cpt -= 1 64 | elif cmd == "debug": 65 | from ipdb import set_trace; set_trace() 66 | elif cmd == "break": 67 | break 68 | else: 69 | obs, rew, done, info = env.step(cmd) 70 | commands.append(cmd) 71 | obs_list.append(obs) 72 | history.append(env.get_state()) 73 | cpt += 1 74 | 75 | print() 76 | print("/".join(commands).replace('"', '\\"')) 77 | -------------------------------------------------------------------------------- /tools/test_games.py: -------------------------------------------------------------------------------- 1 | import os 2 | import textwrap 3 | import argparse 4 | 5 | from termcolor import colored 6 | import jericho 7 | 8 | 9 | def parse_args(): 10 | parser = argparse.ArgumentParser() 11 | 12 | parser.add_argument("filenames", nargs="+", 13 | help="Path to a Z-Machine game(s).") 14 | parser.add_argument("--debug", action="store_true", 15 | help="Launch ipdb on FAIL.") 16 | parser.add_argument("-v", "--verbose", action="store_true", 17 | help="Print the last observation when not achieving max score.") 18 | return parser.parse_args() 19 | 20 | args = parse_args() 21 | 22 | filename_max_length = max(map(len, args.filenames)) 23 | for filename in sorted(args.filenames): 24 | print(filename.ljust(filename_max_length), end=" ") 25 | 26 | env = jericho.FrotzEnv(filename) 27 | if not env.is_fully_supported: 28 | print(colored("SKIP\tUnsupported game", 'yellow')) 29 | continue 30 | 31 | if "walkthrough" not in env.bindings: 32 | print(colored("SKIP\tMissing walkthrough", 'yellow')) 33 | continue 34 | 35 | env.reset() 36 | 37 | #walkthrough = bindings['walkthrough'].split('/') 38 | for cmd in env.get_walkthrough(): 39 | obs, rew, done, info = env.step(cmd) 40 | 41 | if not done: 42 | print(colored("FAIL", 'red')) 43 | if args.debug: 44 | from ipdb import set_trace; set_trace() 45 | elif info["score"] != env.get_max_score(): 46 | msg = "FAIL\tDone but score {}/{}".format(info["score"], env.get_max_score()) 47 | print(colored(msg, 'red')) 48 | if args.verbose: 49 | print(textwrap.indent(obs, prefix=" ")) 50 | 51 | if args.debug: 52 | from ipdb import set_trace; set_trace() 53 | else: 54 | print(colored("PASS", 'green')) 55 | --------------------------------------------------------------------------------