games/NXDoom: Initial port of Chocolate DOOM to NuttX.

This commit includes a (highly) modified version of Chocolate DOOM which
can run on NuttX. The majority of the modifications were made to pass
the NuttX style check. Some small modifications have been added to
support keyboard input, render graphics to frame buffers and directly
use the POSIX interfaces NuttX supplies, stripping out Windows/Mac stuff
and any references to SDL.

NOTE: Sound is currently not supported in any capacity, nor is the
networking stuff. A lot of Chocolate DOOM code was stripped out since it
was unused. If there is a need/desire to add it back later, the original
Chocolate DOOM source can be used as a reference.

WARNING: The NuttX keyboard codec is incredibly non-standard and so
there are problems translating from X11 keys to NuttX ones to play DOOM.
Right now, the CTRL key for firing doesn't work because the NuttX codec
has no concept of it. The NuttX codec should be modified (and other
input devices supported), but at the time of this port I am not
sufficiently comfortable doing so since I am afraid of breaking other
things in the kernel.

NOTE: This port (and likely the original DOOM) seems to be written with
32-bit computers in mind. As such, most things are given the type of
natural `int`, even when a single byte might do. There are significant
size optimizations that could be made to make this more suited to
embedded devices that NuttX typically runs on.

Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
This commit is contained in:
Matteo Golin 2026-06-30 10:24:29 -04:00 committed by Alan C. Assis
parent 53ca441b32
commit 073188b50d
722 changed files with 81215 additions and 314155 deletions

View file

@ -1,4 +0,0 @@
*.xauth
wads/
prefs/
share/

View file

@ -1,39 +0,0 @@
FROM ubuntu
######### Apt dependencies
ARG system_apt_dependencies="build-essential gdb automake autoconf libtool git pkg-config python3 python3-pip sudo"
ARG choco_apt_dependencies="gcc make libsdl2-dev libsdl2-net-dev libsdl2-mixer-dev"
ARG choco_apt_dependencies_optional="libflac-dev libfluidsynth-dev libpng-dev libsamplerate-dev libvorbis-dev"
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -qq $system_apt_dependencies $choco_apt_dependencies $choco_apt_dependencies_optional
########## Install Pillow (PIL) via pip, not apt
ARG choco_pip_dependencies="pillow"
RUN pip install $choco_pip_dependencies
########## Container user setup
ARG USERNAME=chocodev
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
# Add sudo support
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# Add the user to the audio group, to have ALSA sound access
# TODO: pulseaudio, so this isn't necessary?
RUN addgroup $USERNAME audio
# Use bash, not sh. Yuck.
RUN chsh $USERNAME -s /bin/bash
USER $USERNAME
# Make sure we actually own our own local share stuff
RUN mkdir -p /home/$USERNAME/.local/share && \
chown -R $USERNAME:$USERNAME /home/$USERNAME/.local

View file

@ -1,45 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/docker-existing-dockerfile
{
"name": "Doom Dev Container",
"context": "..",
"dockerFile": "./Dockerfile",
"extensions": [
"yzhang.markdown-all-in-one",
"bierner.markdown-preview-github-styles",
"dotjoshjohnson.xml",
"eamodio.gitlens",
"npxms.hide-gitignored", // Note: need to run its command manually
// Build tooling
"ms-vscode.cpptools",
"cschlosser.doxdocgen",
"austin.code-gnu-global",
"jeff-hykin.better-cpp-syntax", // Note: runs locally
"ms-vscode.cpptools-themes", // Note: runs locally
],
// Required to not bleed "root" permission files into the host volume
"containerUser": "chocodev",
// VSCode on Linux specific, for creating X11 and sound forwarding
// Comment out manually if working on non-Linux
"initializeCommand": "${localWorkspaceFolder}/.devcontainer/initialize-linux.sh",
"mounts": [
"source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind",
"source=${localWorkspaceFolder}/.devcontainer/prefs,target=/home/chocodev/.local/share/chocolate-doom,type=bind",
],
"containerEnv": {
"DISPLAY": "${localEnv:DISPLAY}",
"XAUTHORITY": "${containerWorkspaceFolder}/.devcontainer/share/devcontainer.xauth",
},
"runArgs": [
// "--gpus", "all", // Uncomment for GPU support
"--device", "/dev/snd",
// TODO: pulseaudio? https://github.com/mviereck/x11docker/wiki/Container-sound:-ALSA-or-Pulseaudio
]
// TODO: X11/sound forwarding configs for MacOS (XQuartz) and Windows (Xming)
}

View file

@ -1,9 +0,0 @@
#!/bin/bash
HERE=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
### Create the xauth file allowing the container to interact with a forwarded X11
XAUTH="$HERE/share/devcontainer.xauth";
touch "$XAUTH"
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
### TODO: pulseaudio pasthrough

View file

@ -1,101 +0,0 @@
Thanks for contributing to Chocolate Doom! Whatever your contribution,
whether it's code or just a bug report, it's greatly appreciated.
The project is governed by the
[Contributor Covenant](http://contributor-covenant.org/version/1/4/)
version 1.4. By contributing to the project you agree to abide by its
terms. To report violations, please send an email to fraggle@gmail.com.
### Reporting bugs
Before reporting a bug, it's worth checking if this really is a bug.
Chocolate Doom's mission is to reproduce the Vanilla (DOS) versions of
the Doom engine games, bugs and all. Check out the
[NOT-BUGS](../NOT-BUGS.md) file for a list of common issues which aren't
really bugs at all. You might also try searching [the GitHub issues
list](https://github.com/chocolate-doom/chocolate-doom/issues) to see
if your bug has already been reported.
If you're confident that you've found a real bug (or even if you're
not sure!) please go ahead and [file an issue on
GitHub](https://github.com/chocolate-doom/chocolate-doom/issues/new).
You'll need a GitHub account, but it's pretty easy to sign up.
Please try to give as much information as possible:
* What version of Chocolate Doom are you using? Check the title bar of
the window for the version number.
* Chocolate Doom runs on many different operating systems (not just
Windows!). Please say which operating system and what version of it
you're using.
* Please say which game you're playing (Doom 1, Doom 2, Heretic,
Hexen, Strife, etc.) and if you're using any fan-made WADs or mods,
please say which mods (and where they can be downloaded!). It helps
to give the full command line you're using to start the game.
* Please mention if you have any special configuration you think may be
relevant, too.
### Feature requests
Chocolate Doom is always open to new feature requests; however, please
be aware that the project is designed around a deliberately limited
[philosophy](../PHILOSOPHY.md), and many features common in other source
ports will not be accepted. Here are a few common requests which are
often rejected:
* "High resolution" rendering (greater than 320x200 display).
* An option to disable Vanilla limits, such as the visplane rendering
limit.
* Ability to play "No Rest For The Living", the expansion pack which
comes with the XBLA / BFG Edition of Doom.
If you're not sure whether your feature is in line with the project
philosophy, don't worry - just ask anyway!
To make a feature request, [file an issue on
GitHub](https://github.com/chocolate-doom/chocolate-doom/issues/new).
### Bug fixes / code submission
Thank you for contributing code to Chocolate Doom! Please check the
following guidelines before opening a pull request:
* All code must be licensed under [the GNU General Public License,
version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
Please don't reuse code that isn't GPL, or that is GPLv3 licensed.
Be aware that by submitting your code to the project, you're agreeing
to license it under the GPL.
* Please follow the coding style guidelines described in the
[HACKING](../HACKING.md) file.
* Please don't make unnecessary changes which just change formatting
without any actual change to program logic. While being consistent
is nice, such changes destroy the ability to use the `git blame`
command to see when code was last changed.
* The guidelines given above in the "feature requests" section also
apply here. New features which aren't in line with the project
philosophy are likely to be rejected. If you're not sure, open a
feature request first and ask before you start implementing your
feature.
* Follow the guidelines for [how to write a Git commit
message](http://chris.beams.io/posts/git-commit/). In short: the
first line should be a short summary; keep to an 80 column limit;
use the imperative mood ("fix bug X", rather than "fixed bug X" or
"fixing bug X"). If your change fixes a particular subsystem,
prefix the summary with that subsystem: eg. "doom: Fix bug X" or
"textscreen: Change size of X".
* If you're making a change related to a bug, reference the GitHub
issue number in the commit message, eg. "This is a partial fix
for #646". This will link your commit into the issue comments. If
your change is a fix for the bug, put the word "fixes" before the
issue number to automatically close the issue once your change
is merged.

View file

@ -1,28 +0,0 @@
<!--
Thank you for reporting a bug in Chocolate Doom. Please complete
the following template so that we can better diagnose the source
of your problem.
To save yourself some time, you may want to check the FAQ and the
NOT-BUGS list for solutions to some common problems:
https://www.chocolate-doom.org/wiki/index.php/FAQ
https://www.chocolate-doom.org/not-bugs
-->
### Background
Version of Chocolate Doom:
Operating System and version:
Game: (Doom/Heretic/Hexen/Strife/other)
Any loaded WADs and mods (please include full command line):
### Bug description
Observed behavior:
Expected behavior:

View file

@ -1,54 +0,0 @@
# Workflow syntax:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: cpp-linter
on:
pull_request:
types: [opened, reopened, synchronize]
push:
branches:
- master
jobs:
cpp-linter:
strategy:
matrix:
compiler: [clang]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install libfluidsynth-dev libpng-dev libsamplerate0-dev libsdl2-dev libsdl2-mixer-dev libsdl2-net-dev ninja-build
- name: Run cmake to generate compilation database
run: cmake -S . -B . -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=1
- uses: cpp-linter/cpp-linter-action@v2
id: linter
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
style: file
lines-changed-only: true
version: 16
tidy-checks: >-
boost-*
,bugprone-*
,performance-*
,readability-*
,portability-*
,modernize-*
,clang-analyzer-*
,cppcoreguidelines-*
,-cppcoreguidelines-avoid-magic-numbers
,-cppcoreguidelines-init-variables
,-readability-identifier-length
,-readability-isolate-declaration
,-readability-magic-numbers
- name: Fail fast?!
if: steps.linter.outputs.checks-failed > 0
run: |
echo "Some files failed the linting checks! Fail fast disabled until false positive issue is fixed"
- name: Check no extern used in .c files
run: |
./check-extern.sh

View file

@ -1,23 +0,0 @@
name: cppcheck
on:
pull_request:
types: [opened, reopened, synchronize]
push:
branches:
- master
jobs:
cppcheck:
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install cppcheck
- uses: actions/checkout@v6
- name: Run cppcheck
env:
ANALYZE: true
run: $GITHUB_WORKSPACE/.travis.sh

View file

@ -1,152 +0,0 @@
name: Continuous Integration
on:
push:
branches:
- "master"
tags:
- "*"
paths-ignore:
- "**.md"
pull_request:
branches:
- "master"
paths-ignore:
- "**.md"
workflow_dispatch:
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
defaults:
run:
shell: ${{ matrix.config.shell }}
strategy:
fail-fast: false
matrix:
config:
- name: Linux GCC
os: ubuntu-latest
compiler: gcc
shell: bash
- name: macOS Clang
os: macos-latest
compiler: clang
shell: bash
- name: macOS x86 Clang
os: macos-15-intel
compiler: clang
shell: bash
- name: MSYS2 UCRT64
os: windows-latest
compiler: gcc
shell: 'msys2 {0}'
msystem: ucrt64
msys-env: mingw-w64-ucrt-x86_64
artifacts: true
pkg-path: pkg/win32/*.zip
pkg-dir: pkg/win32
steps:
- name: Install pandoc
if: runner.os == 'Windows'
shell: cmd
run: choco install pandoc
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install \
libsdl2-dev \
libsdl2-mixer-dev \
libsdl2-net-dev \
libpng-dev \
libsamplerate0-dev \
libfluidsynth-dev
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install \
automake \
sdl2 \
sdl2_mixer \
sdl2_net \
libpng \
libsamplerate \
fluid-synth
- name: Install dependencies (MSYS2)
if: runner.os == 'Windows'
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.config.msystem }}
update: true
path-type: inherit
install: >-
autotools
zip
${{ matrix.config.msys-env }}-python-pip
${{ matrix.config.msys-env }}-gcc
${{ matrix.config.msys-env }}-SDL2
${{ matrix.config.msys-env }}-SDL2_mixer
${{ matrix.config.msys-env }}-SDL2_net
${{ matrix.config.msys-env }}-libpng
${{ matrix.config.msys-env }}-libsamplerate
${{ matrix.config.msys-env }}-fluidsynth
- uses: actions/checkout@v6
with:
submodules: true
- name: Configure
env:
CC: ${{ matrix.config.compiler }}
run: |
./autogen.sh
- name: Build
run: make -j4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Test
run: |
pip install pyyaml
PREFIX=`sed -n '/PROGRAM_PREFIX/p' ${PWD}/config.h | cut -d '"' -f 2`
make -j4 -C quickcheck check SOURCE_PORT=$PWD/src/${PREFIX}doom
- name: Package
if: ${{ matrix.config.artifacts }}
run: |
cd ${{ matrix.config.pkg-dir }}
make
- name: Upload artifacts
if: ${{ matrix.config.artifacts }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.config.name }}
path: ${{ matrix.config.pkg-path }}
- name: Extract Package String
if: ${{ contains(github.ref, 'tags') }}
run: |
PACKAGE_STRING=`sed -n '/PACKAGE_STRING/p' ${PWD}/config.h | cut -d '"' -f 2`
echo "PACKAGE_STRING=${PACKAGE_STRING}" >> $GITHUB_ENV
- name: Release
if: ${{ contains(github.ref, 'tags') && matrix.config.artifacts }}
uses: ncipollo/release-action@v1
with:
name: ${{ env.PACKAGE_STRING }}
bodyFile: RELEASE_NOTES.md
allowUpdates: true
artifacts: ${{ matrix.config.pkg-path }}

View file

@ -1,13 +1,12 @@
CMDLINE
INSTALL
Makefile
Makefile.in
Make.dep
TAGS
aclocal.m4
autom4te.cache
autotools
bin
config.h
config.hin
config.log
config.status
@ -36,7 +35,11 @@ STRIFE*.pcx
/out
# These are the default patterns globally ignored by Subversion:
.depend
.built
*.o
*.gcno
*.gcda
*.lo
*.la
*.al

View file

@ -1,3 +0,0 @@
[submodule "quickcheck"]
path = quickcheck
url = https://github.com/chocolate-doom/quickcheck.git

View file

@ -1,32 +0,0 @@
" Local vimrc configuration file. Install the localvimrc.vim vim script.
set expandtab
set tabstop=8
set softtabstop=4
set shiftwidth=4
" Add all tag files to tags path.
let topdir = findfile("configure.ac", ".;")
let topdir = substitute(topdir, "configure.ac", "", "")
" Check tags file in current dir:
set tags+=tags
" Add tag files in parent directories:
let tagfiles = findfile("tags", ".;", -1)
" Add tag files for libraries:
call add(tagfiles, topdir . "opl/tags")
call add(tagfiles, topdir . "pcsound/tags")
call add(tagfiles, topdir . "textscreen/tags")
for tagfile in tagfiles
" Don't go beyond the project top level when adding parent dirs:
if stridx(tagfile, topdir) >= 0
exec "set tags+=" . tagfile
endif
endfor
unlet topdir
unlet tagfiles

View file

@ -1,19 +0,0 @@
#!/bin/sh
if [ "$ANALYZE" = "true" ] ; then
# -D__GNUC__ is required for cppcheck to know about noreturn functions
cppcheck --error-exitcode=1 -j2 -UTESTING -D__GNUC__ -Iopl -Isrc -Isrc/setup opl pcsound src textscreen 2> stderr.txt
RET=$?
if [ -s stderr.txt ]
then
cat stderr.txt
fi
exit $RET
else
set -e
./autogen.sh --enable-werror
make -j4
make install DESTDIR=/tmp/whatever
make dist
PREFIX=`sed -n '/PROGRAM_PREFIX/p' ${PWD}/config.h | cut -d '"' -f 2`
make -j4 -C quickcheck check SOURCE_PORT=$PWD/src/${PREFIX}doom
fi

View file

@ -1,105 +0,0 @@
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
cmake_minimum_required(VERSION 3.7.2)
project("Chocolate Doom" VERSION 3.1.1 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
# Autotools variables
set(top_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
set(top_builddir ${CMAKE_CURRENT_BINARY_DIR})
# AC_INIT variables
set(PACKAGE_NAME "${PROJECT_NAME}")
set(PACKAGE_TARNAME "chocolate-doom")
set(PACKAGE_VERSION "${PROJECT_VERSION}")
set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(PACKAGE_BUGREPORT "chocolate-doom-dev-list@chocolate-doom.org")
string(REGEX REPLACE " Doom$" "" PACKAGE_SHORTNAME "${PACKAGE_NAME}")
set(PACKAGE_COPYRIGHT "Copyright (C) 1993-2025")
set(PACKAGE_LICENSE "GNU General Public License, version 2")
# Any settings that should apply to all targets in this directory and all
# subdirectories should go here. Use judiciously.
if(MSVC)
add_definitions("/D_CRT_SECURE_NO_WARNINGS" "/D_CRT_SECURE_NO_DEPRECATE"
"/D_CRT_NONSTDC_NO_DEPRECATE")
else()
add_compile_options("-Wall" "-Wdeclaration-after-statement"
"-Wredundant-decls")
endif()
option(CMAKE_FIND_PACKAGE_PREFER_CONFIG
"Lookup package config files before using find modules" On)
option(ENABLE_SDL2_NET "Enable SDL2_net" On)
option(ENABLE_SDL2_MIXER "Enable SDL2_mixer" On)
if (NOT DEFINED EMSCRIPTEN)
find_package(SDL2 2.0.14)
endif()
if(ENABLE_SDL2_MIXER)
if (NOT DEFINED EMSCRIPTEN)
find_package(SDL2_mixer 2.0.2)
endif()
else()
add_compile_definitions(DISABLE_SDL2MIXER=1)
endif()
if(ENABLE_SDL2_NET)
if (NOT DEFINED EMSCRIPTEN)
find_package(SDL2_net 2.0.0)
endif()
else()
add_compile_definitions(DISABLE_SDL2NET=1)
endif()
# Check for libsamplerate.
find_package(SampleRate)
if(SampleRate_FOUND)
set(HAVE_LIBSAMPLERATE TRUE)
endif()
# Check for libpng.
find_package(PNG)
if(PNG_FOUND)
set(HAVE_LIBPNG TRUE)
endif()
# Check for FluidSynth.
find_package(FluidSynth 2.2.0)
if(FluidSynth_FOUND AND ENABLE_SDL2_MIXER)
set(HAVE_FLUIDSYNTH TRUE)
endif()
find_package(m)
include(CheckSymbolExists)
include(CheckIncludeFile)
check_symbol_exists(strcasecmp "strings.h" HAVE_DECL_STRCASECMP)
check_symbol_exists(strncasecmp "strings.h" HAVE_DECL_STRNCASECMP)
check_include_file("dirent.h" HAVE_DIRENT_H)
string(CONCAT WINDOWS_RC_VERSION "${PROJECT_VERSION_MAJOR}, "
"${PROJECT_VERSION_MINOR}, ${PROJECT_VERSION_PATCH}, 0")
# Without a hyphen. This is used for the bash-completion scripts.
string(TOLOWER "${PACKAGE_SHORTNAME}" PROGRAM_SPREFIX)
# With a hyphen, used almost everywhere else.
set(PROGRAM_PREFIX "${PROGRAM_SPREFIX}-")
configure_file(cmake/config.h.cin config.h)
configure_file(src/doom-res.rc.in src/doom-res.rc)
configure_file(src/heretic-res.rc.in src/heretic-res.rc)
configure_file(src/hexen-res.rc.in src/hexen-res.rc)
configure_file(src/setup-res.rc.in src/setup-res.rc)
configure_file(src/setup/setup-manifest.xml.in src/setup/setup-manifest.xml)
configure_file(src/strife-res.rc.in src/strife-res.rc)
foreach(SUBDIR textscreen opl pcsound src)
add_subdirectory("${SUBDIR}")
endforeach()

View file

@ -1,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at fraggle@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View file

@ -1,5 +0,0 @@
Chocolate Doom's version history is stored in Git. For a full
change log, clone the repository on Github:
https://github.com/chocolate-doom/chocolate-doom

View file

@ -1,256 +0,0 @@
# Coding style guidelines
The coding style guidelines for Chocolate Doom are designed to keep the
style of the original source code. This maintains consistency throughout
the program, and does not require the original code to be changed. Some
of these guidelines are stricter than what was done in the original
source; follow these when writing new code only: there is no need to
change existing code to fit them.
You should set tabs to *display* as eight spaces, not four. However,
*indentation* should be four spaces. If possible, do not use tab
characters at all. There is a utility called “expand” which will remove
tab characters. For the reasoning behind this, see:
http://www.jwz.org/doc/tabs-vs-spaces.html
Please write code to an 80 column limit so that it fits within a standard
80 column terminal. Do not leave trailing whitespace at the end of lines.
Functions should be named like this: `AB_FunctionName`. The `AB` prefix
denotes the subsystem (`AM_` for automap, `G_` for game, etc). If a
function is static, you can omit the prefix and just name it like
`FunctionName`. Functions and global variables should always be made
static if possible.
Put `_t` on the end of types created with typedef. Type names like this
should be all lowercase and have the subsystem name at the start. An
example of this is `txt_window_t`. When creating structures, always
typedef them.
Do not use Hungarian notation.
Do not use the goto statement.
Use C++-style comments, ie. `//` comments, not `/* ... */` comments.
I dont care that this isnt standard ANSI C.
Variables should be named like this: `my_variable_name`, not like this:
`MyVariableName`. In pointer variable declarations, place the `*` next
to the variable name, not the type.
When casting variables from one type to another, put a space after the
last closing brace.
When using an if, do, while, or for statement, always use the { } braces
even when they are not necessary. For example, do this:
```c
if (condition)
{
body;
}
```
Not this:
```c
if (condition) // NO
body;
```
Write code like this:
```c
typedef struct
{
int member1;
char *member2;
} my_structure_t;
void FunctionName(int argument, int arg2, int arg3, int arg4, int arg5,
int arg6, int arg7)
{
int assign_var;
assign_var = arg2 + arg3 * arg4 * (arg5 + arg6);
if (foo && !bar || baz && qux || !(foo && bar && baz))
{
body;
}
else if (xyz + 4 < abc * 4 + 3)
{
body;
}
else
{
body;
}
if (very_long_condition_like_this_one_that_forces_a_line_break
&& other_condition)
{
body;
}
switch (argument)
{
case FIRST:
code;
break;
case SECOND:
code;
break;
default:
break;
}
for (a = 0; a < 10; ++a)
{
FunctionCall(arg1, arg2, arg3, arg4,
arg_split_onto_second_line);
}
while (a < 10)
{
loop_body;
}
do
{
} while (condition);
}
```
## Editor-specific default settings
If you use vim, you can put this into your `.vimrc` (or install the
`localvimrc` script):
```
set expandtab
set tabstop=8
set softtabstop=4
set shiftwidth=4
```
Or, if you use Emacs, put this in your `.emacs`:
```lisp
(add-hook 'c-mode-hook (lambda ()
(when (and buffer-file-name
(string-match "chocolate-doom" buffer-file-name))
(c-set-style "bsd")
(setq indent-tabs-mode nil)
(setq tab-width 8)
(setq c-basic-offset 4))))
```
## Security
The C standard library has a number of unsafe functions that should be
avoided when writing code for Chocolate Doom. These are:
Unsafe function | Safer alternative
------------------|------------------------
`gets()` | `fgets(.., stdin)`
`sprintf` | `M_snprintf()`
`snprintf` | `M_snprintf()`
`vsprintf` | `M_vsnprintf()`
`vsnprintf` | `M_vsnprintf()`
`strcpy()` | `M_StringCopy()`
`strncpy()` | `M_StringCopy()`
`strcat()` | `M_StringConcat()`
`strncat()` | `M_StringConcat()`
`strdup()` | `M_StringDuplicate()`
`realloc()` | `I_Realloc()`
Lots of the code includes calls to DEH_String() to simulate string
replacement by the Dehacked tool. Be careful when using Dehacked
replacements of printf format strings. For example, do not do this:
```c
printf(DEH_String("foo %s"), s);
sprintf(mybuf, DEH_String("bar %s"), t);
```
Instead do this:
```c
DEH_printf("foo %s", s);
DEH_snprintf(mybuf, sizeof(mybuf), "bar %s", t);
```
This does the format string replacement safely in a way that checks
the arguments securely.
## Portability
Chocolate Doom is designed to be cross-platform and work on different
Operating Systems and processors. Bear this in mind when writing code.
Do not use the `long` type (its size differs across platforms; use
`int` or `int64_t` depending on which you want).
Use Dooms byte data type for byte data. `int` is assumed to be a
32-bit integer, and `short` is a 16-bit integer. You can also use the
ISO C99 data types: `intN_t` and `uintN_t` where N is 8, 16, 32, 64.
Be careful with platform dependencies: do not use Windows API
functions, for example. Use SDL where possible.
Preprocessor `#defines` are set that can be used to identify the OS
if necessary: `_WIN32` for Windows and `__MACOSX__` for Mac OS X. Others
are set through SDL. Try to avoid this if possible.
Be careful of endianness! Doom has `SHORT()` and `LONG()` macros that
do endianness conversion. Never assume that integer types have a
particular byte ordering. Similarly, never assume that fields
inside a structure are aligned in a particular way. This is most
relevant when reading or writing data to a file or a network pipe.
For signed integers, you shouldnt assume that `(i >> n)` is the same as
`(i / (1 << n))`. However, most processors handle bitshifts of signed
integers properly, so its not a huge problem.
Due to Microsoft implementation of the Unicode support in C standard
library you should use these wrappers to support non-latin paths and
filenames on Windows.
C library function | Wrapper
-------------------|-------------------
`fopen()` | `M_fopen()`
`remove()` | `M_remove()`
`rename()` | `M_rename()`
`stat()` | `M_stat()`
`mkdir()` | `M_MakeDirectory()`
`getenv()` | `M_getenv()`
## GNU GPL and licensing
All code submitted to the project must be licensed under the GNU GPLv2 or a
compatible license. If you use code that you havent 100% written
yourself, say so. Add a copyright header to the start of every file. Use
this template:
```
//
// Copyright(C) YEAR Author's name
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// *File description goes here*
//
```

187
games/NXDoom/Kconfig Normal file
View file

@ -0,0 +1,187 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config GAMES_NXDOOM
bool "NXDoom"
default n
depends on ALLOW_GPL_COMPONENTS
depends on VIDEO_FB
depends on CRYPTO
---help---
Play DOOM on NuttX!
if GAMES_NXDOOM
comment "Program options"
config GAMES_NXDOOM_PRIORITY
int "Priority"
default 100
---help---
The task priority for the NXDoom application.
config GAMES_NXDOOM_STACKSIZE
int "Stack size"
default 4096
---help---
The stack size for the NXDoom application.
comment "General game options"
choice # Language
prompt "Game language"
default GAMES_NXDOOM_LANG_EN
config GAMES_NXDOOM_LANG_EN
bool "English"
---help---
English language support (original).
config GAMES_NXDOOM_LANG_FR
bool "French"
---help---
French language support.
endchoice # Language
config GAMES_NXDOOM_PREFDIR
string "DOOM data directory"
default "/data"
---help---
Directory where DOOM WAD files are stored.
config GAMES_NXDOOM_ENDOOM
bool "Show ENDOOM"
default n
---help---
Show the ENDOOM screen (https://www.doomwiki.org/wiki/ENDOOM).
comment "Networking options"
config GAMES_NXDOOM_NET
bool "Enable network features"
default n
---help---
Not ported! Will not work.
if GAMES_NXDOOM_NET
config GAMES_NXDOOM_NET_LOGS
bool "Enable network logging"
default n
---help---
Enables log information from the network features.
config GAMES_NXDOOM_NET_MAXPLAYERS
int "Maximum number of players"
default 6
---help---
The maximum number of players, multiplayer/networking.
This is the maximum supported by the networking code; individual games
have their own values for MAXPLAYERS that can be smaller.
ChocolateDOOM default was 8.
config GAMES_NXDOOM_NET_BACKUPTICS
int "Maximum number of backup tics"
default 32
---help---
The maximum number of backup tics to store locally during a net game.
ChocalateDOOM default was 128.
config GAMES_NXDOOM_NET_MAXPLAYERNAME
int "Maximum player name length"
default 16
---help---
The maximum number of characters in a player name for netgames.
ChocalateDOOM default was 30.
endif # GAMES_NXDOOM_NET
comment "Sound options"
config GAMES_NXDOOM_SOUND
bool "Enable sound features"
default n
---help---
Not ported! Will not work.
comment "Graphics options"
config GAMES_NXDOOM_FBPATH
string "Framebuffer path"
default "/dev/fb0"
---help---
Path to the framebuffer character driver to use for rendering.
comment "Input options"
choice # Input method
prompt "NXDoom input method"
default GAMES_NXDOOM_KEYBOARD
config GAMES_NXDOOM_KEYBOARD
bool "Keyboard"
---help---
Use a NuttX keyboard character driver.
endchoice # Input method
if GAMES_NXDOOM_KEYBOARD
config GAMES_NXDOOM_KBDPATH
string "Keyboard device path"
default "/dev/kbd0"
---help---
Path to the keyboard device to use as input.
endif # GAMES_NXDOOM_KEYBOARD
comment "Optimizations"
config GAMES_NXDOOM_MAXVISPLANES
int "Maximum number of visplanes"
default 96
---help---
DOOM allocates a static number of 'visplanes' to use for gameplay. The
original ChocolateDOOM source uses 128 of these. They take a significant
amount of memory, so you may reduce the number. However, too few planes
may cause 'visplane overflow' errors, which is more common in complex
levels.
config GAMES_NXDOOM_MAXOPENINGS
int "Maximum number of openings"
default 32
---help---
DOOM allocates a static number of 'openings' to use for gameplay. These
are defined as multiples of the SCREENWIDTH (320). The original
ChocolateDOOM source uses 64 as the multiplier. They take a significant
amount of memory, so you may reduce the number. However, too few
openings will cause 'opening overflow' errors.
config GAMES_NXDOOM_MAXVISSPRITES
int "Maximum number of visible sprites"
default 96
---help---
DOOM allocates a static number of 'vissprites' to use for gameplay. The
original ChocolateDOOM source uses 128. They take a significant amount
of memory, so you may reduce the number. However, too few will cause
overflow errors.
config GAMES_NXDOOM_MAXDRAWSEGS
int "Maximum number of drawsegs"
default 192
---help---
DOOM allocates a static number of 'drawsegs' to use for gameplay. The
original ChocolateDOOM source uses 256. They take a significant amount of
memory, so you may reduce the number. However, too few will cause
rendering issues (overflow is checked to avoid crashes).
config GAMES_NXDOOM_RANGECHECK
bool "Perform range checks"
default y
---help---
The ChocolateDOOM source includes the ability to optionally exclude
range checking on some array operations.
endif # GAMES_NXDOOM

3
games/NXDoom/Make.defs Normal file
View file

@ -0,0 +1,3 @@
ifneq ($(CONFIG_GAMES_NXDOOM),)
CONFIGURED_APPS += $(APPDIR)/games/NXDoom
endif

203
games/NXDoom/Makefile Normal file
View file

@ -0,0 +1,203 @@
include $(APPDIR)/Make.defs
# Program options
MODULE = $(CONFIG_GAMES_NXDOOM)
PRIORITY = $(CONFIG_GAMES_NXDOOM_PRIORITY)
STACKSIZE = $(CONFIG_GAMES_NXDOOM_STACKSIZE)
PROGNAME = nxdoom
# Source files
COMMONSRCDIR = src
TEXTSCREENSRCDIR = textscreen
DOOMSRCDIR = $(COMMONSRCDIR)/doom
PCSOUNDSRCDIR = pcsound
# Includes
CFLAGS += -I$(COMMONSRCDIR) -I$(DOOMSRCDIR) -I$(TEXTSCREENSRCDIR)
CFLAGS += -I$(PCSOUNDSRCDIR)
# Source files
COMMONSRCS = i_system.c m_argv.c m_misc.c # Excluding i_main.c
COMMONSRCS += z_native.c # Native memory allocation
DEHACKEDSRCS = deh_io.c deh_main.c deh_mapping.c deh_text.c
BASESRCS = \
aes_prng.c \
d_event.c \
d_iwad.c \
d_loop.c \
d_mode.c \
deh_str.c \
gusconf.c \
i_glob.c \
i_input.c \
i_joystick.c \
i_timer.c \
i_video.c \
m_bbox.c \
m_cheat.c \
m_config.c \
m_controls.c \
m_fixed.c \
p_rejectpad.c \
memio.c \
tables.c \
v_diskicon.c \
v_video.c \
w_checksum.c \
w_main.c \
w_wad.c \
w_file.c \
w_file_stdc.c \
w_merge.c \
# Only add ENDOOM stuff if the user wants it
ifeq ($(CONFIG_GAMES_NXDOOM_ENDOOM),y)
BASESRCS += i_endoom.c
endif
NETSRCS = \
net_client.c \
net_common.c \
net_dedicated.c \
net_gui.c \
net_io.c \
net_loop.c \
net_packet.c \
net_query.c \
net_sdl.c \
net_server.c \
net_structrw.c \
DOOMSRCS = \
am_map.c \
deh_ammo.c \
deh_bexstr.c \
deh_cheat.c \
deh_doom.c \
deh_frame.c \
deh_misc.c \
deh_ptr.c \
deh_thing.c \
deh_weapon.c \
d_items.c \
d_main.c \
d_net.c \
doomdef.c \
doomstat.c \
dstrings.c \
f_finale.c \
f_wipe.c \
g_game.c \
hu_lib.c \
hu_stuff.c \
info.c \
m_menu.c \
m_random.c \
p_ceilng.c \
p_doors.c \
p_enemy.c \
p_floor.c \
p_inter.c \
p_lights.c \
p_map.c \
p_maputl.c \
p_mobj.c \
p_plats.c \
p_pspr.c \
p_saveg.c \
p_setup.c \
p_sight.c \
p_spec.c \
p_switch.c \
p_telept.c \
p_tick.c \
p_user.c \
r_bsp.c \
r_data.c \
r_draw.c \
r_main.c \
r_plane.c \
r_segs.c \
r_sky.c \
r_things.c \
statdump.c \
st_lib.c \
st_stuff.c \
wi_stuff.c
TXTSCREENSRCS = \
txt_conditional.c \
txt_checkbox.c \
txt_desktop.c \
txt_dropdown.c \
txt_fileselect.c \
txt_gui.c \
txt_inputbox.c \
txt_io.c \
txt_button.c \
txt_label.c \
txt_radiobutton.c \
txt_scrollpane.c \
txt_separator.c \
txt_spinctrl.c \
txt_sdl.c \
txt_strut.c \
txt_table.c \
txt_utf8.c \
txt_widget.c \
txt_window.c \
txt_window_action.c
CSRCS += $(patsubst %,$(COMMONSRCDIR)/%,$(COMMONSRCS))
CSRCS += $(patsubst %,$(COMMONSRCDIR)/%,$(DEHACKEDSRCS))
CSRCS += $(patsubst %,$(COMMONSRCDIR)/%,$(BASESRCS))
CSRCS += $(patsubst %,$(DOOMSRCDIR)/%,$(DOOMSRCS))
# Textscreen stuff only needs to be included for networking stuff
# or if the user wants to see ENDOOM
ifeq ($(CONFIG_GAMES_NXDOOM_ENDOOM),y)
ADDTXTSCREEN = y
endif
ifeq ($(CONFIG_GAMES_NXDOOM_NET),y)
ADDTXTSCREEN = y
endif
# Only include textscreen code if needed
ifeq ($(ADDTXTSCREEN),y)
CSRCS += $(patsubst %,$(TEXTSCREENSRCDIR)/%,$(TXTSCREENSRCS))
endif
# Only include networking logic if enabled
ifeq ($(CONFIG_GAMES_NXDOOM_NET),y)
CSRCS += $(patsubst %,$(COMMONSRCDIR)/%,$(NETSRCS))
endif
# Only include sound logic if enabled
ifeq ($(CONFIG_GAMES_NXDOOM_SOUND),y)
CSRCS += $(COMMONSRCDIR)/i_musicpack.c
CSRCS += $(COMMONSRCDIR)/i_pcsound.c
CSRCS += $(COMMONSRCDIR)/i_sdlmusic.c
CSRCS += $(COMMONSRCDIR)/i_sound.c
CSRCS += $(COMMONSRCDIR)/midifile.c
CSRCS += $(COMMONSRCDIR)/mus2mid.c
CSRCS += $(DOOMSRCDIR)/sounds.c
CSRCS += $(DOOMSRCDIR)/s_sound.c
CSRCS += $(DOOMSRCDIR)/deh_sound.c
endif
MAINSRC = $(COMMONSRCDIR)/i_main.c
include $(APPDIR)/Application.mk

View file

@ -1,62 +0,0 @@
AUX_DIST_GEN = \
$(ac_aux_dir)/install-sh \
$(ac_aux_dir)/missing
CMAKE_FILES= \
CMakeLists.txt \
cmake/FindSDL2.cmake \
cmake/FindSDL2_mixer.cmake \
cmake/FindSDL2_net.cmake \
cmake/FindFluidSynth.cmake \
cmake/Findm.cmake \
cmake/FindSampleRate.cmake \
cmake/config.h.cin
DOC_FILES= \
COPYING.md \
README.md \
README.Music.md \
NEWS.md \
PHILOSOPHY.md \
ChangeLog
EXTRA_DIST= \
$(AUX_DIST_GEN) \
$(CMAKE_FILES) \
$(DOC_FILES) \
NOT-BUGS.md \
README.Strife.md \
.lvimrc \
HACKING.md \
TODO.md \
rpm.spec \
win32/win_opendir.c \
win32/win_opendir.h
doomdocsdir = ${docdir}/../${PROGRAM_PREFIX}doom
doomdocs_DATA = $(DOC_FILES) NOT-BUGS.md
hereticdocsdir = ${docdir}/../${PROGRAM_PREFIX}heretic
hereticdocs_DATA = $(DOC_FILES)
hexendocsdir = ${docdir}/../${PROGRAM_PREFIX}hexen
hexendocs_DATA = $(DOC_FILES)
strifedocsdir = ${docdir}/../${PROGRAM_PREFIX}strife
strifedocs_DATA = $(DOC_FILES) README.Strife.md
MAINTAINERCLEANFILES = $(AUX_DIST_GEN)
SUBDIRS=textscreen opl pcsound data src man
DIST_SUBDIRS=pkg $(SUBDIRS)
if HAVE_DOC
INSTALL : man/INSTALL.template man/simplecpp
$(srcdir)/man/simplecpp -DDOOM -DHERETIC -DHEXEN -DSTRIFE \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Doom" \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@doom" \
< $(srcdir)/man/INSTALL.template > $@
endif

File diff suppressed because it is too large Load diff

View file

@ -1,149 +0,0 @@
The aim of Chocolate Doom is to behave as closely to Vanilla Doom as
possible. As a result, you may experience problems that you would
also experience when using Vanilla Doom. These are not “bugs” as
Chocolate Doom is behaving as intended.
This is not intended to be a comprehensive list of Vanilla Doom bugs.
For more information, consult the “engine bugs” page of the Doom Wiki.
## Game exits after title screen with message about game version
The game may exit after the title screen is shown, with a message like
the following:
Demo is from a different game version!
(read 2, should be 109)
*** You may need to upgrade your version of Doom to v1.9. ***
See: https://www.doomworld.com/classicdoom/info/patches.php
This appears to be v1.0/v1.1/v1.2.
This usually indicates that your IWAD file that you are using to play
the game (usually named doom.wad or doom2.wad) is out of date.
Chocolate Doom only supports versions 1.666 through 1.9.
To fix the problem, you must upgrade your IWAD file, preferably
to 1.9. The URL in the message has downloadable upgrade patches that
you can use to upgrade.
## Game exits in demo loop when playing Final Doom
When playing with the Final Doom IWAD files (tnt.wad, plutonia.wad),
if you leave the game at the title screen to play through the demo
loop, it will eventually exit with the following error message:
W_GetNumForName: demo4 not found!
This is the same behavior as the Vanilla executables that were
bundled with Final Doom. When Ultimate Doom was developed, a fourth
demo was added to the demo loop, and this change was retained in the
Final Doom version of the executable. However, the Final Doom IWADs
do not include a fourth demo, so the game crashes.
An alternate version of Final Doom was included in the Id Anthology
boxed set, and this version of the game fixed this bug. However, this
version also changes the teleport behavior, so the default is to
emulate the most commonly distributed version of the game. To use
the alternate version, run with:
chocolate-doom -gameversion final2
## Game exits when accessing the options menu
The game may exit with the message “Bad V_DrawPatch” when accessing
the options menu, if you have your mouse sensitivity set high.
The Doom options menu has a slider that allows the mouse sensitivity
to be controlled; however, it has only a very limited range. It is
common for experienced players to set a mouse sensitivity that is much
higher than what can be set via the options menu. The setup program
allows a larger range of values to be set.
However, setting very high sensitivity values causes the game to exit
when accessing the options menu under Vanilla Doom. Because Chocolate
Doom aims to emulate Vanilla Doom as closely as possible, it does the
same thing.
One solution to the problem is to set a lower mouse sensitivity.
Alternatively, all of the settings in the options menu can be
controlled through Dooms key bindings anyway:
Option | Key
---------------------------|-----
End game | F7
Messages on/off | F8
Graphic detail high/low | F5
Screen size smaller/larger | -/+
Sound volume menu | F4
## Game exits with “Savegame buffer overrun” when saving the game
If you are playing on a particularly large level, it is possible that
when you save the game, the game will quit with the message “Savegame
buffer overrun”.
Vanilla Doom has a limited size memory buffer that it uses for saving
games. If you are playing on a large level, the buffer may be too
small for the entire savegame to fit. Chocolate Doom allows the limit
to be disabled: in the setup tool, go to the “compatibility” menu and
disable the “Vanilla savegame limit” option.
If this error happens to you, your game has not been lost! A file
named temp.dsg is saved; rename this to doomsav0.dsg to make it appear
in the first slot in the “load game” menu. (On Unix systems, you will
need to look in the .chocolate-doom/savegames directory in your home
directory)
## Game ends suddenly when recording a demo
If you are recording a very long demo, the game may exit suddenly.
Vanilla Doom has a limited size memory buffer that it uses to save the
demo into. When the buffer is full, the game exits. You can tell if
this happens, as the demo file will be around 131,072 bytes in size.
You can work around this by using the -maxdemo command line parameter
to specify a larger buffer size. Alternatively, the limit can be
disabled: in the setup tool, go to the compatibility menu and disable
the “Vanilla demo limit” option.
## Game exits with a message about “visplanes”
The game may exit with one of these messages:
R_FindPlane: no more visplanes
R_DrawPlanes: visplane overflow (129)
This is known as the “visplane overflow” limit and is one of the most
well-known Vanilla Doom engine limits. You should only ever experience
this when trying to play an add-on level. The level you are trying to
play is too complex; it was most likely designed to work with a limit
removing source port.
More information can be found here (archived link): https://archive.is/s6h7V
## IDMUS## cheat doesnt work with shareware/registered Doom IWADs
The IDMUS cheat allows the in-game music to be changed. However, in
the original v1.9 this cheat didnt work properly when playing with
the Doom 1 (shareware and registered) IWADs. This bug was fixed in
the Ultimate Doom and Final Doom executables.
Chocolate Doom emulates this bug. When playing with the shareware or
registered Doom IWADs, the IDMUS cheat therefore does not work
properly. If you are playing with the Ultimate Doom IWAD, the
Ultimate Doom executable is emulated by default, so the cheat works
properly.
## Some graphics are wrong when playing with BFG Edition IWADs
If you are playing using the IWAD files from Doom 3: BFG Edition, you
may notice that certain graphics appear strange or wrong. This
includes the title screen, and parts of the options menu.
The IWAD files in the new BFG Edition have had some significant
changes from the IWAD files in older releases. Some of the graphics
lumps have been removed or changed, and the Doom 2 secret levels are
also censored. Chocolate Doom includes some small workarounds that
allow the game to run, but for the best experience, its best to get a
copy of the classic versions of the IWADs. These are still available
to buy from Steam or GOG.com.

View file

@ -1,214 +0,0 @@
Chocolate Doom has been designed around a careful and deliberate
philosophy that attempts to recreate the original (“Vanilla”) DOS
executables for Doom, Heretic, Hexen and Strife. This document
describes some of that philosophy and the reasoning behind it.
This document is descriptive, not proscriptive.
# Vanilla behavior
Ideally Chocolate Doom aims to recreate the behavior of the Vanilla
binaries, but different aspects of Vanilla behavior are held to
varying degrees of importance. It can be imagined as different “tiers”
of compatibility:
* The game and gameplay itself is of central importance. Here, the
Vanilla behavior ought to be maintained as accurately as possible.
This includes the look, feel and sound, and things like demo
compatibility.
* The surrounding aspects of the game that arent part of the central
gameplay experience can be extended as long as theres a good
reason and Vanilla behavior is respected.
* The setup tool is not required to reproduce the behavior of the
Vanilla setup tool, even though it reproduces its look and feel.
“Vanilla” is defined as:
* DOS Doom 1.9 (although there are actually multiple “1.9”s).
* DOS Heretic 1.3.
* DOS Hexen 1.1 (although there are actually two known “1.1”s).
* DOS Strife 1.31.
* DOS Chex Quest.
Compatibility with older versions of the DOS binaries is also a
secondary goal (though not pre-release versions). Other ports (either
official or unofficial) are out of scope: this includes console ports,
non-DOS ports, Doom 95 and Doom 3: BFG Edition.
# Compatibility
Chocolate Doom aims to be compatible with Vanilla Doom in several
different ways. Examples are:
* Bug compatibility: the aim is to emulate compatibility of the
original game down to bugs that were present in the DOS
executables. This includes maintaining the limitations of the
original engine: for example, the infamous “visplane overflow” bug
is intentionally still present, where other source ports have
removed it; this allows mappers targeting Vanilla Doom to use
Chocolate Doom as a faithful substitute.
* Demo compatibility: Doom was one of the first games to develop a
speedrunning community, and thousands of recordings of Doom
gameplay (`.lmp` demo files) exist in the Compet-N archive. Chocolate
Doom aims for the highest standard of demo compatibility with
Vanilla Doom, a goal that is often complicated by obscure behavior
that can be difficult to reproduce.
* Configuration file compatibility: Chocolate Doom uses the same
configuration file format as Vanilla Doom, such that a user should
be able to reuse their existing Vanilla configuration file without
making any changes. Extra non-Vanilla options are stored in a
separate configuration file.
* Savegame file compatibility: Chocolate Doom uses the same savegame
file format as Vanilla, such that it should be possible to import
and use existing savegame files.
# DOS tools
Chocolate Doom includes some features that arent part of Vanilla Doom
but exist for compatibility with DOS tools that interact with it.
These are considered part of the Vanilla experience and ought to be
treated as such. Some examples are:
* The novert setting, which reproduces the functionality of
`novert.exe`.
* The `-deh` parameter, which loads Dehacked patches like dehacked.exe
does under DOS. Chocolate Doom imposes the same limitations that
Vanilla Dehacked does.
# Exceptions
Chocolate Doom differs from Vanilla Doom in a number of ways. In most
cases these are subtle, minor differences. Nonetheless they deserve
some explanation and justification. Here are some examples of
situations where changes are considered acceptable:
1. Vanilla behavior can be broken that is harmful, eg. can damage the
players computer, or is just outright misleading. For example:
- Vanilla uses unbounded sprintf and strcpy (security issue).
- Vanilla has crashes that force the user to reboot the machine.
- Vanilla has an out of memory message that recommends tweaking
CONFIG.SYS. As Chocolate Doom doesnt run under DOS, reproducing
this message would not be helpful.
2. Subtly extending behavior is okay where its not clear what the
Vanilla behavior is anyway. For example:
- Opening the menu releases mouse grab in Chocolate Doom.
- Chocolate Hexens graphical startup screen runs in a window.
3. Supporting obsolete technology is not a goal: its considered
acceptable that Chocolate Doom does not support every type of
hardware from 1993. However, Chocolate Doom should aim to recreate
the functionality in a modern way. Examples of technologies that
arent supported are:
- No support for IPX networks, but TCP/IP is supported instead.
- No support for dial-up/serial connections; modern operating
systems have features that do that for you.
- No MS-DOS version.
4. Changes are acceptable that allow the player to be able play the
game. For example:
- There are new key bindings for actions that cant be rebound with
Vanilla Doom, because its useful for portability to machines
that dont have a full keyboard.
- There are additional mouse and joystick button bindings that let
you perform actions with them that can only be done with the
keyboard in Vanilla Doom.
- Chocolate Doom includes some hacks to support the Doom 3: BFG
Edition IWAD files. The assumption is that being able to at least
play is better than nothing, even if its not Vanilla behavior.
- Chocolate Strife does not emulate the save bug from
Vanilla 1.31, which could corrupt saves when overwriting a slot,
if the old slot was not part of the current games progression.
Vanilla behavior is unexpected and potentially devastating.
5. Adding extra options to Vanilla functionality is acceptable as long
as the defaults match Vanilla, it doesnt change gameplay and
theres a good reason for it. For example:
- PNG screenshots are supported because PCX is an obsolete format.
- Chocolate Doom has the vanilla_keyboard_mapping option that
allows the user to use the native keyboard mapping for their
computer, rather than always assuming a US layout.
6. Changing configuration file defaults is acceptable where theres a
very good reason. For example:
- Vanilla Doom defaults to no sound or music if a configuration
file is not found. Chocolate Doom defaults to having sound
effects and music turned on by default, because modern computers
support these; theres no need to configure hardware IRQ settings
to get sound working.
7. Things can be changed if theyre really just inconsequential. For
example:
- The startup messages in Chocolate Doom are not identical to
Vanilla Doom and are not necessarily in the same order.
- Vanilla Doom has command line options named `-comdev`, `-shdev`
and `-regdev` used by id internally for development; these have
been removed.
8. Expansions to the vanilla demo formats are allowed, to make
recording and playback of vanilla gameplay more convenient, with
the following restrictions:
- Such expansions are not supported in WAD files (they are not
an editing feature for WAD authors to use).
- Support for these features can be completely disabled using the
`-strictdemos` command line argument.
- A warning is shown to the user on the console (stdout) when a
demo using one of these features is recorded or played back.
A good litmus test of when its acceptable to break from Vanilla
behavior is to ask the question: “Although this is Vanilla behavior,
is there anyone who would want this?”
For example, emulating Vanilla bugs like the visplane overflow bug is
something that is useful for people making Vanilla format maps. On the
other hand, painstakingly emulating Vanilla Doom by starting with no
sound or music by default is not helpful to anyone.
# Minimalism
Chocolate Doom aims to be minimalist and straightforward to configure;
in particular, the setup tool should have a sane interface. Part of
the inspiration for Chocolate Doom came from Booms complicated maze
of options menus (and a desire to avoid them). Too many preferences
lead to a bad user interface; see Havoc Penningtons essay on Free
Software UI:
http://ometer.com/free-software-ui.html
Chocolate Doom has some options that are quite obscure and only really
of interest to a small number of people. In these cases, the options
are hidden away in configuration files and deliberately not exposed in
the setup tool. The assumption is that if you care enough about those
obscure features, editing a configuration file by hand should not be a
huge problem for you.
Also inspirational was the README file from Havocs Metacity window
manager, where the list of features begins:
> Boring window manager for the adult in you. Many window managers
> are like Marshmallow Froot Loops; Metacity is like Cheerios.
Id like to think that Chocolate Dooms philosophy towards features is
similar. The idea is for a source port that is boring. I find the best
software - both proprietary and open source - is software that is
“egoless”: it does a job well without pretentions about its importance
or delusions of grandeur. A couple of other notable examples of
software that I feel embody this spirit of design in a beautiful way
are Marco Pesenti Grittis Epiphany web browser and Evince PDF viewer.
# Other philosophical aspects
Chocolate Doom aims for maximal portability. That includes running on
many different CPUs, different operating systems and different devices
(ie. not just a desktop machine with a keyboard and mouse).
Chocolate Doom is and will always remain Free Software. It will never
include code that is not compatible with the GNU GPL.

View file

@ -1,173 +0,0 @@
Doom has a memorable and atmospheric soundtrack. Like many games of
the era, it is MIDI-based. Chocolate Doom includes a number of
different options for music playback, detailed below.
# Native MIDI playback
Most modern operating systems have some kind of built-in support for
MIDI playback; some have very good quality MIDI playback (Mac OS X for
example). To use this, choose “Native MIDI” in the sound configuration
dialog in the setup tool.
# Timidity
Timidity is a software-based MIDI synthesizer, and a version of it is
included in the SDL2_mixer library used by Chocolate Doom. To use
Timidity for MIDI playback, first download a sound font. An example of
a good quality sound font is the eawpats font, which can be downloaded
from the idgames archive as sounds/eawpats.zip:
https://www.doomworld.com/idgames/sounds/eawpats
Having installed a sound font, select “Native MIDI” in the sound
configuration dialog in the setup tool, and use the “Timidity
configuration file” widget below to enter the path to the Timidity
configuration file (normally named timidity.cfg).
# Gravis Ultrasound (GUS)
The Gravis Ultrasound (GUS) was a PC sound card popular in the 90s,
notable for having wavetable synthesis that provided MIDI playback
that was superior to most other cards of the era. Chocolate Doom
includes a “pseudo-GUS emulation” feature that simulates the GUS
(using Timidity, under the hood).
To use this feature you need a copy of the GUS patch files that were
distributed with the original GUS patches. If you have Doom 3: BFG
Edition, these patches are included with its version of classic Doom,
and are automatically detected. Otherwise, they can be downloaded
from the idgames archive as music/dgguspat.zip:
https://www.doomworld.com/idgames/music/dgguspat
Having downloaded the patches, select “GUS (emulated)” in the sound
configuration dialog in the setup tool, and use the “GUS patch path”
widget to enter the path to the directory containing the patch files.
For the music not to sound weird, you will almost certainly want to
load gusgonna.wad (sounds/gusgonna.zip in the idgames archive) when
you run the game, to work around a bug in vanilla Doom's instrument
mappings parser:
https://www.doomworld.com/idgames/sounds/gusgonna
By default a GUS card with 1024KB is simulated; to simulate a 256KB,
512KB or 768KB card instead, change the gus_ram_kb option in
chocolate-doom.cfg.
# OPL (Soundblaster / Adlib)
Most people playing Doom in the 90s had Soundblaster-compatible sound
cards, which used the Yamaha OPL series of chips for FM-based MIDI
synthesis. Chocolate Doom includes the ability to emulate these chips
for a retro experience. OPL emulation is the default MIDI playback,
but can be selected in the setup tool as “OPL (Adlib/SB)”.
Most modern computers do not include an OPL chip any more, as CPUs are
fast enough to do decent software MIDI synthesis. However, no software
emulator sounds exactly like a real (hardware) OPL chip, and a few
cards do have real hardware OPL. If you have such a card, heres how
to configure Chocolate Doom to use it.
## Sound cards with OPL chips
If you have an ISA sound card, it almost certainly includes an OPL
chip. Modern computers dont have slots for ISA cards though, so you
must be running a pretty old machine.
If you have a PCI sound card, you probably dont have an OPL chip.
However, there are some exceptions to this. The following cards are
known to include “legacy” OPL support:
* C-Media CMI8738 (*)
* Forte Media FM801
* Cards based on the Yamaha YMF724 (*)
Other cards that apparently have OPL support but have not been tested:
* S3 SonicVibes
* AZTech PCI 168 (AZT 3328 chipset)
* ESS Solo-1 sound cards (ES1938, ES1946, ES1969 chipset)
* Conexant Riptide Audio/Modem combo cards
* Cards based on the Crystal Semiconductors CS4281
* Cards based on the Avance Logic ALS300
* Cards based on the Avance Logic ALS4000
If you desperately want hardware OPL music, you may be able to find
one of these cards for sale cheap on eBay.
For the cards listed above with (\*) next to them, OPL support is
disabled by default and must be explictly enabled in software. See
sections below for operating system-specific instructions on how you
may be able to do this.
If your machine is not a PC, you dont have an OPL chip, and you will
have to use the software OPL.
## Operating System support
If youre certain that you have a sound card with hardware OPL, you
may need to take extra steps to configure your operating system to
allow access to it. To do hardware OPL, Chocolate Doom must access
the chip directly, which is usually not possible in modern operating
systems unless you are running as the superuser (root/Administrator).
### Microsoft Windows
On modern Windows systems it is not possible to directly access the
OPL chip, even when running as Administrator. Fortunately, it is
possible to use the “ioperm.sys” driver developed for Cygwin (look for
iopermsys-0.2.1.tar.bz2):
http://openwince.sourceforge.net/ioperm/
It is not necessary to have Cygwin installed to use this. Copy the
ioperm.sys file into the same directory as the Chocolate Doom
executable and it should be automatically loaded.
You can confirm that hardware OPL is working by checking for this
message in stdout.txt:
OPL_Init: Using driver 'Win32'.
If you have a C-Media CMI8738, you may need to enable the `FM_EN`
flag in Windows Device Manager to access hardware OPL output. See
[this](http://www.vogons.org/viewtopic.php?f=46&t=36445) thread on
vogons.org for some more information.
### Linux
If you are using a system based on the Linux kernel, you can access
the OPL chip directly, but you must be running as root. You can
confirm that hardware OPL is working, by checking for this message on
startup:
OPL_Init: Using driver 'Linux'.
If you are using one of the PCI cards in the list above with a (*)
next to it, you may need to manually enable FM legacy support. Add
the following to your /etc/modprobe.conf file to do this:
options snd-ymfpci fm_port=0x388
options snd-cmipci fm_port=0x388
### OpenBSD/NetBSD
You must be running as root to access the hardware OPL directly. You
can confirm that hardware OPL is working by checking for this message
on startup:
OPL_Init: Using driver 'OpenBSD'.
There is no native OPL backend for FreeBSD yet. Sorry!
# Other options
If you have some other favorite MIDI playback option that isnt
listed above, you can set a hook to invoke an external command for
MIDI playback using the snd_musiccmd configuration file option. For
example, set:
snd_musiccmd "aplaymidi -p 128:0"
in your chocolate-doom.cfg file.

View file

@ -1,124 +0,0 @@
````````````````````````````````````````````````````````````````````````
Samuel Kaiser Villarreal and James Quasar Haley Present
C H O C O L A T E
______________________________._________________________
/ _____/\__ ___/\______ \ \_ _____/\_ _____/
\_____ \ | | | _/ || __) | __)_
/ \ | | | | \ || \ | \
/_______ / |____| |____|_ /___|\___ / /_______ /
\/ \/ \/ \/
````````````````````````````````````````````````````````````````````````
## What is it?
Chocolate Strife is the most accurate and complete recreation of Rogue
Entertainments “Strife: Quest for the Sigil.” It was created through more
than four years of reverse engineering effort with the blessings of the
original programmers of the game.
## Why?
The source code for Strife was lost, which means, unlike the code for all the
other commercial DOOM-engine games, it cannot be released. The only access we
have to the code is the binary executable file. Tools such as IDA Pro have
been employed to disassemble and decompile the executable, which was cross-
referenced against the Linux DOOM and DOS Heretic sources and painstakingly
combed over multiple times, instruction-by-instruction, to ensure that the
resulting Chocolate Doom-based executable is as close as possible to the
original.
## Is it Legal?
Chocolate Strife was originally reverse-engineered from the DOS Strife
binaries. Although reverse engineering is legally a protected activity, this
nonetheless left some open questions about its legal status.
In 2014, a new commercial release of Strife was published (Strife: Veteran
Edition) based on the Chocolate Strife code, and developed by the authors of
Chocolate Strife under commercial license. The release of Strife: Veteran
Edition, along with its GPL-licensed source code, constitutes tacit approval
for the legal status of Chocolate Strife by its current copyright holder.
## Is it Perfect?
Almost, but not entirely! Thats where you come in. Help us by reporting any
discrepancies you may notice between this executable and the vanilla DOS
program!
However, do *not* report any glitch that you can replicate in the vanilla EXE
as a bug. The point of Chocolate Strife, like Chocolate Doom before it, is to
be as bug-compatible with the original game as possible. Also be aware that
some glitches are impossible to compatibly recreate, and wherever this is the
case, Chocolate Strife has erred on the side of not crashing the program,
for example by initializing pointers to NULL rather than using them without
setting a value first.
## What are some known problems?
The demo version is *not* supported, and there are not any current plans to
support it in the future, due to the vast number of differences (the demo
version of Strife is based on an earlier version of Rogues
codebase).
The commercial Strife IWAD version 1.1 may run, but also exhibit issues. Like
the demo version, there are no current plans to fully support it. Make sure
your copy is updated to at least 1.2. Strife: Veteran Edition already
includes the required version.
## How do I use it?
From the Run box or a command line, issue a command to Chocolate Strife just
like you would run Chocolate Doom. Most of the same command line parameters
are supported.
voices.wad will be read from the same directory as the IWAD, if it can be
found. If it is not found, then voices will be disabled just as would happen
with the vanilla executable. Do not add voices.wad using -file, as that is
redundant and unnecessary.
Some new command-line parameters in Chocolate Strife include the following:
- -nograph
- Disables the graphical introduction sequence. -devparm implies this.
- -novoice
- Disables voices even if voices.wad can be found.
- -work
- Enables Rogues playtesting mode. Automatic godmode, and pressing the
inventory drop key will toggle noclipping.
- -flip
- Flips player gun graphics. This is buggy, however, because it does not
reverse the graphics x offsets (this is an accurate emulation of the
vanilla engines behavior).
- -random
- Randomizes the timing and location of item respawns in deathmatch, when
item respawning is enabled.
## Copyright
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful,but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
See the “COPYING” file for the full license text. The source code for this
program is available from the same location where you downloaded this package.
Aside from Chocolate Doom, portions of the code are derived from the Eternity
Engine, Copyright 2011 Team Eternity, as published under the GNU GPL.

View file

@ -1,102 +0,0 @@
# Chocolate Doom
Chocolate Doom aims to accurately reproduce the original DOS version of
Doom and other games based on the Doom engine in a form that can be
run on modern computers.
Originally, Chocolate Doom was only a Doom source port. The project
now includes ports of Heretic and Hexen, and Strife.
Chocolate Dooms aims are:
* To always be 100% Free and Open Source software.
* Portability to as many different operating systems as possible.
* Accurate reproduction of the original DOS versions of the games,
including bugs.
* Compatibility with the DOS demo, configuration and savegame files.
* To provide an accurate retro “feel” (display and input should
behave the same).
More information about the philosophy and design behind Chocolate Doom
can be found in the PHILOSOPHY file distributed with the source code.
## Setting up gameplay
For instructions on how to set up Chocolate Doom for play, see the
INSTALL file.
## Configuration File
Chocolate Doom is compatible with the DOS Doom configuration file
(normally named `default.cfg`). Existing configuration files for DOS
Doom should therefore simply work out of the box. However, Chocolate
Doom also provides some extra settings. These are stored in a
separate file named `chocolate-doom.cfg`.
The configuration can be edited using the chocolate-setup tool.
## Command line options
Chocolate Doom supports a number of command line parameters, including
some extras that were not originally suported by the DOS versions. For
binary distributions, see the CMDLINE file included with your
download; more information is also available on the Chocolate Doom
website.
## Playing TCs
With Vanilla Doom there is no way to include sprites in PWAD files.
Chocolate Dooms -file command line option behaves exactly the same
as Vanilla Doom, and trying to play TCs by adding the WAD files using
-file will not work.
Many Total Conversions (TCs) are distributed as a PWAD file which must
be merged into the main IWAD. Typically a copy of DEUSF.EXE is
included which performs this merge. Chocolate Doom includes a new
option, -merge, which will simulate this merge. Essentially, the
WAD directory is merged in memory, removing the need to modify the
IWAD on disk.
To play TCs using Chocolate Doom, run like this:
```
chocolate-doom -merge thetc.wad
```
Here are some examples:
```
chocolate-doom -merge batman.wad -deh batman.deh vbatman.deh (Batman Doom)
chocolate-doom -merge aoddoom1.wad -deh aoddoom1.deh (Army of Darkness Doom)
```
## Other information
* Chocolate Doom includes a number of different options for music
playback. See the README.Music file for more details.
* More information, including information about how to play various
classic TCs, is available on the Chocolate Doom website:
https://www.chocolate-doom.org/
You are encouraged to sign up and contribute any useful information
you may have regarding the port!
* Chocolate Doom is not perfect. Although it aims to accurately
emulate and reproduce the DOS executables, some behavior can be very
difficult to reproduce. Because of the nature of the project, you
may also encounter Vanilla Doom bugs; these are intentionally
present; see the NOT-BUGS file for more information.
New bug reports, feedback, questions or suggestions can be submitted
to the issue tracker on Github:
https://github.com/chocolate-doom/chocolate-doom/issues
* Source code patches are welcome, but please follow the style
guidelines - see the file named HACKING included with the source
distribution.
* Chocolate Doom is distributed under the GNU GPL. See the COPYING
file for more information.

View file

@ -1,35 +0,0 @@
## 3.1.1 (2025-08-14)
### General
* Fix compilation on GCC 15 (thanks Fabian).
* Hide public IP addresses for privacy.
* Use native OpenGL texture format for better performance (thanks Fabian).
* Improved directory handling on Windows (thank Roman Fomin):
* Fixes problems with postfix "." for non-relative paths.
* Support for long NTFS paths (up to 32768 characters).
* Fixed metainfo files for latest AppStream spec compliance (thanks Fabian).
* Add option to enable or disable smooth pixel scaling (thanks StevenSYS).
* Allow spaces in GUS patch folder path (thanks Michael Day).
* Add support for non-US backslash key (thanks Michael Day).
* Never let SDL Mixer use native midi on Windows (thanks Michael Day).
* Use $TMPDIR to find tempdir on Unix (thanks Mr. Myth).
* Improve man page formatting (thanks g-branden-robinson).
### Build systems
* Can now be built with Emscripten (thanks James Baicoianu).
* Misc. improvements (thanks suve, Emmanuel Ferdman, Gabriele Simoni, et al.)
### Setup
* Use correct EGA palette colors (thanks Henrique Jorge).
### Doom
* Initial support for Doom version 1.5 (thanks Michael Francis).
### Heretic
* Fix crash after loading too many saved games (thanks Noseey).
### Hexen
* Fix crash with Heresiarch fireballs if player has never touched a wall (thank Noseey).
### Strife
* Initialize floor->type and floor->crush fields in EV_BuildStairs() (thanks Fabian).

View file

@ -1,36 +0,0 @@
This is Chocolate Dooms “to do” list. Note that this is kind of an arbitrary
and unstructured wish list of features and improvements. The bug tracker
(http://chocolate-doom.org/bugs) has more feature requests.
* Multiplayer:
- Use UPnP to automatically configure port forwarding for NATed
networks.
- Multiplayer options and configuration file (server name, etc)
* Improve multiplayer startup:
- Select an IWAD automatically from the servers game type rather than
all players having to specify -iwad.
- Send list of WADs to load instead of all clients having to specify -file.
- Same applies to dehacked patches and wad merging parameters.
* Portability improvements:
- Test on and fix for architectures where `((-2) >> 1) != -1`
- Use size-specific types (eg. `int32_t` instead of int)
- Dont make structure packing assumptions when loading levels.
- Port to every OS and architecture under the sun
- Port to Emscripten and release a web-based version.
* Video capture mode
- Real-time recording of gameplay
- Batch conversion of demos into videos
* Heretic/Hexen/Strife:
- Merge r_draw.c to common version and delete duplicates
- Heretic v1.2 emulation (if possible)
- Hexen v1.0 emulation (if possible/necessary)
- Strife v1.1 emulation (for demo IWAD support)
- Screensaver mode
Crazy pie in the sky ideas:
* Automatic WAD installer - download and run TCs from a list automatically
(automating the current “instructions on wiki” system).
* Textscreen interface to the Compet-N database: menu driven system to
automatically download and play speedruns.
* DWANGO-like interface for finding players and setting up games.

View file

@ -1,4 +0,0 @@
#!/bin/sh
autoreconf -fi
./configure "$@"

View file

@ -1,6 +0,0 @@
#!/bin/sh
EXTERN="$(grep -e 'extern[^A-Za-z0-9_]' $(find . -name *.c))"
if [ -n "$EXTERN" ] ; then
echo "extern found in .c files:\n${EXTERN}"
exit 1
fi

View file

@ -1,106 +0,0 @@
# FindFluidSynth
# ---------
#
# Try to find the FluidSynth library.
#
# This will define the following variables:
#
# ``FluidSynth_FOUND``
# System has FluidSynth.
#
# ``FluidSynth_VERSION``
# The version of FluidSynth.
#
# ``FluidSynth_INCLUDE_DIRS``
# This should be passed to target_include_directories() if
# the target is not used for linking.
#
# ``FluidSynth_LIBRARIES``
# The FluidSynth library.
# This can be passed to target_link_libraries() instead of
# the ``FluidSynth::libfluidsynth`` target
#
# If ``FluidSynth_FOUND`` is TRUE, the following imported target
# will be available:
#
# ``FluidSynth::libfluidsynth``
# The FluidSynth library
#
#=============================================================================
# Copyright 2018 Christophe Giboudeaux <christophe@krop.fr>
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# Cache variable that allows you to point CMake at a directory containing
# an extracted development library.
set(FluidSynth_DIR "${FluidSynth_DIR}"
CACHE PATH "Location of FluidSynth library directory")
find_package(PkgConfig QUIET)
pkg_check_modules(PC_FluidSynth QUIET fluidsynth>=${FluidSynth_FIND_VERSION})
find_library(FluidSynth_LIBRARIES
NAMES fluidsynth
HINTS
"${FluidSynth_DIR}/lib"
${PC_FluidSynth_LIBDIR}
)
find_path(FluidSynth_INCLUDE_DIRS
NAMES fluidsynth.h
HINTS
"${FluidSynth_DIR}/include"
${PC_FluidSynth_INCLUDEDIR}
)
if(NOT FluidSynth_VERSION)
if(EXISTS "${FluidSynth_INCLUDE_DIRS}/fluidsynth/version.h")
file(STRINGS "${FluidSynth_INCLUDE_DIRS}/fluidsynth/version.h" _FLUIDSYNTH_VERSION_H
REGEX "^#define[ ]+FLUIDSYNTH_VERSION[ ]+\"[0-9].[0-9].[0-9]\"")
string(REGEX REPLACE "^#define[ ]+FLUIDSYNTH_VERSION[ ]+\"([0-9].[0-9].[0-9])\".*" "\\1" FluidSynth_VERSION "${_FLUIDSYNTH_VERSION_H}")
unset(_FLUIDSYNTH_VERSION_H)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FluidSynth
FOUND_VAR FluidSynth_FOUND
REQUIRED_VARS FluidSynth_LIBRARIES FluidSynth_INCLUDE_DIRS
VERSION_VAR FluidSynth_VERSION
)
if(FluidSynth_FOUND AND NOT TARGET FluidSynth::libfluidsynth)
add_library(FluidSynth::libfluidsynth UNKNOWN IMPORTED)
set_target_properties(FluidSynth::libfluidsynth PROPERTIES
IMPORTED_LOCATION "${FluidSynth_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${FluidSynth_INCLUDE_DIRS}"
)
if(WIN32 AND FluidSynth_DIR)
# On Windows, we need to figure out the location of our library files
# so we can copy and package them.
set(FluidSynth_DLL_DIR "${FluidSynth_DIR}/bin" CACHE INTERNAL "")
endif()
endif()

View file

@ -1,114 +0,0 @@
# FindSDL2.cmake
#
# Copyright (c) 2018, Alex Mayfield <alexmax2742@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Currently works with the following generators:
# - Unix Makefiles (Linux, MSYS2)
# - Ninja (Linux, MSYS2)
# - Visual Studio
# Cache variable that allows you to point CMake at a directory containing
# an extracted development library.
set(SDL2_DIR "${SDL2_DIR}" CACHE PATH "Location of SDL2 library directory")
# Use pkg-config to find library locations in *NIX environments.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_search_module(PC_SDL2 QUIET sdl2)
endif()
# Find the include directory.
find_path(SDL2_INCLUDE_DIR "SDL_version.h"
HINTS "${SDL2_DIR}/include" ${PC_SDL2_INCLUDE_DIRS})
# Find the version. Taken and modified from CMake's FindSDL.cmake.
if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
set(SDL2_VERSION "${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH}")
unset(SDL2_VERSION_MAJOR_LINE)
unset(SDL2_VERSION_MINOR_LINE)
unset(SDL2_VERSION_PATCH_LINE)
unset(SDL2_VERSION_MAJOR)
unset(SDL2_VERSION_MINOR)
unset(SDL2_VERSION_PATCH)
endif()
# Find the SDL2 and SDL2main libraries
if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
find_library(SDL2_LIBRARY "SDL2"
HINTS "${SDL2_DIR}/lib/x64" ${PC_SDL2_LIBRARY_DIRS})
find_library(SDL2_MAIN_LIBRARY "SDL2main"
HINTS "${SDL2_DIR}/lib/x64" ${PC_SDL2_LIBRARY_DIRS})
else()
find_library(SDL2_LIBRARY "SDL2"
HINTS "${SDL2_DIR}/lib/x86" ${PC_SDL2_LIBRARY_DIRS})
find_library(SDL2_MAIN_LIBRARY "SDL2main"
HINTS "${SDL2_DIR}/lib/x86" ${PC_SDL2_LIBRARY_DIRS})
endif()
set(SDL2_LIBRARIES "${SDL2_MAIN_LIBRARY}" "${SDL2_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2
FOUND_VAR SDL2_FOUND
REQUIRED_VARS SDL2_INCLUDE_DIR SDL2_LIBRARIES
VERSION_VAR SDL2_VERSION
)
if(SDL2_FOUND)
# SDL2 imported target.
add_library(SDL2::SDL2 UNKNOWN IMPORTED)
set_target_properties(SDL2::SDL2 PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_SDL2_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
IMPORTED_LOCATION "${SDL2_LIBRARY}")
# SDL2main imported target.
if(MINGW)
# Gross hack to get mingw32 first in the linker order.
add_library(SDL2::_SDL2main_detail UNKNOWN IMPORTED)
set_target_properties(SDL2::_SDL2main_detail PROPERTIES
IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}")
# Ensure that SDL2main comes before SDL2 in the linker order. CMake
# isn't smart enough to keep proper ordering for indirect dependencies
# so we have to spell it out here.
target_link_libraries(SDL2::_SDL2main_detail INTERFACE SDL2::SDL2)
add_library(SDL2::SDL2main INTERFACE IMPORTED)
set_target_properties(SDL2::SDL2main PROPERTIES
IMPORTED_LIBNAME mingw32)
target_link_libraries(SDL2::SDL2main INTERFACE SDL2::_SDL2main_detail)
else()
add_library(SDL2::SDL2main UNKNOWN IMPORTED)
set_target_properties(SDL2::SDL2main PROPERTIES
IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}")
endif()
endif()

View file

@ -1,88 +0,0 @@
# FindSDL2_mixer.cmake
#
# Copyright (c) 2018, Alex Mayfield <alexmax2742@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Currently works with the following generators:
# - Unix Makefiles (Linux, MSYS2)
# - Ninja (Linux, MSYS2)
# - Visual Studio
# Cache variable that allows you to point CMake at a directory containing
# an extracted development library.
set(SDL2_MIXER_DIR "${SDL2_MIXER_DIR}" CACHE PATH "Location of SDL2_mixer library directory")
# Use pkg-config to find library locations in *NIX environments.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_search_module(PC_SDL2_MIXER QUIET SDL2_mixer)
endif()
# Find the include directory.
find_path(SDL2_MIXER_INCLUDE_DIR "SDL_mixer.h"
HINTS "${SDL2_MIXER_DIR}/include" ${PC_SDL2_MIXER_INCLUDE_DIRS})
# Find the version. Taken and modified from CMake's FindSDL.cmake.
if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h")
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
set(SDL2_MIXER_VERSION "${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH}")
unset(SDL2_MIXER_VERSION_MAJOR_LINE)
unset(SDL2_MIXER_VERSION_MINOR_LINE)
unset(SDL2_MIXER_VERSION_PATCH_LINE)
unset(SDL2_MIXER_VERSION_MAJOR)
unset(SDL2_MIXER_VERSION_MINOR)
unset(SDL2_MIXER_VERSION_PATCH)
endif()
# Find the library.
if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
find_library(SDL2_MIXER_LIBRARY "SDL2_mixer"
HINTS "${SDL2_MIXER_DIR}/lib/x64" ${PC_SDL2_MIXER_LIBRARY_DIRS})
else()
find_library(SDL2_MIXER_LIBRARY "SDL2_mixer"
HINTS "${SDL2_MIXER_DIR}/lib/x86" ${PC_SDL2_MIXER_LIBRARY_DIRS})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2_mixer
FOUND_VAR SDL2_MIXER_FOUND
REQUIRED_VARS SDL2_MIXER_INCLUDE_DIR SDL2_MIXER_LIBRARY
VERSION_VAR SDL2_MIXER_VERSION
)
if(SDL2_MIXER_FOUND)
# Imported target.
add_library(SDL2_mixer::SDL2_mixer UNKNOWN IMPORTED)
set_target_properties(SDL2_mixer::SDL2_mixer PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_SDL2_MIXER_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_MIXER_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES SDL2::SDL2
IMPORTED_LOCATION "${SDL2_MIXER_LIBRARY}")
endif()

View file

@ -1,88 +0,0 @@
# FindSDL2_net.cmake
#
# Copyright (c) 2018, Alex Mayfield <alexmax2742@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Currently works with the following generators:
# - Unix Makefiles (Linux, MSYS2)
# - Ninja (Linux, MSYS2)
# - Visual Studio
# Cache variable that allows you to point CMake at a directory containing
# an extracted development library.
set(SDL2_NET_DIR "${SDL2_NET_DIR}" CACHE PATH "Location of SDL2_net library directory")
# Use pkg-config to find library locations in *NIX environments.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_search_module(PC_SDL2_NET QUIET SDL2_net)
endif()
# Find the include directory.
find_path(SDL2_NET_INCLUDE_DIR "SDL_net.h"
HINTS "${SDL2_NET_DIR}/include" ${PC_SDL2_NET_INCLUDE_DIRS})
# Find the version. Taken and modified from CMake's FindSDL.cmake.
if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
set(SDL2_NET_VERSION "${SDL2_NET_VERSION_MAJOR}.${SDL2_NET_VERSION_MINOR}.${SDL2_NET_VERSION_PATCH}")
unset(SDL2_NET_VERSION_MAJOR_LINE)
unset(SDL2_NET_VERSION_MINOR_LINE)
unset(SDL2_NET_VERSION_PATCH_LINE)
unset(SDL2_NET_VERSION_MAJOR)
unset(SDL2_NET_VERSION_MINOR)
unset(SDL2_NET_VERSION_PATCH)
endif()
# Find the library.
if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
find_library(SDL2_NET_LIBRARY "SDL2_net"
HINTS "${SDL2_NET_DIR}/lib/x64" ${PC_SDL2_NET_LIBRARY_DIRS})
else()
find_library(SDL2_NET_LIBRARY "SDL2_net"
HINTS "${SDL2_NET_DIR}/lib/x86" ${PC_SDL2_NET_LIBRARY_DIRS})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2_net
FOUND_VAR SDL2_NET_FOUND
REQUIRED_VARS SDL2_NET_INCLUDE_DIR SDL2_NET_LIBRARY
VERSION_VAR SDL2_NET_VERSION
)
if(SDL2_NET_FOUND)
# Imported target.
add_library(SDL2_net::SDL2_net UNKNOWN IMPORTED)
set_target_properties(SDL2_net::SDL2_net PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_SDL2_NET_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_NET_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES SDL2::SDL2
IMPORTED_LOCATION "${SDL2_NET_LIBRARY}")
endif()

View file

@ -1,67 +0,0 @@
# Findsamplerate.cmake
#
# Copyright (c) 2018, Alex Mayfield <alexmax2742@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Currently works with the following generators:
# - Unix Makefiles (Linux, MSYS2)
# - Ninja (Linux, MSYS2)
# - Visual Studio
# Use pkg-config to find library locations in *NIX environments.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_search_module(PC_SAMPLERATE QUIET samplerate)
endif()
# Find the include directory.
find_path(SAMPLERATE_INCLUDE_DIR "samplerate.h"
HINTS ${PC_SAMPLERATE_INCLUDE_DIRS})
# Find the version. I don't know if there is a correct way to find this on
# Windows - the config.h in the tarball is wrong for 0.1.19.
if(PC_SAMPLERATE_VERSION)
set(SAMPLERATE_VERSION "${PC_SAMPLERATE_VERSION}")
endif()
# Find the library.
find_library(SAMPLERATE_LIBRARY "samplerate"
HINTS ${PC_SAMPLERATE_LIBRARY_DIRS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SampleRate
FOUND_VAR SampleRate_FOUND
REQUIRED_VARS SAMPLERATE_INCLUDE_DIR SAMPLERATE_LIBRARY
VERSION_VAR SAMPLERATE_VERSION
)
if(SampleRate_FOUND)
# Imported target.
add_library(SampleRate::samplerate UNKNOWN IMPORTED)
set_target_properties(SampleRate::samplerate PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_SAMPLERATE_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${SAMPLERATE_INCLUDE_DIR}"
IMPORTED_LOCATION "${SAMPLERATE_LIBRARY}")
endif()

View file

@ -1,36 +0,0 @@
# Findm.cmake
#
# Copyright (c) 2018, Alex Mayfield <alexmax2742@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Finds libm, so we can link against it for math functions. If libm doesn't
# exist, linking against the m target will have no effect.
find_library(M_LIBRARY m)
add_library(m INTERFACE)
if(M_LIBRARY)
target_link_libraries(m INTERFACE "${M_LIBRARY}")
endif()

View file

@ -1,12 +0,0 @@
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@"
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
#cmakedefine PROGRAM_PREFIX "@PROGRAM_PREFIX@"
#cmakedefine HAVE_FLUIDSYNTH
#cmakedefine HAVE_LIBSAMPLERATE
#cmakedefine HAVE_LIBPNG
#cmakedefine HAVE_DIRENT_H
#cmakedefine01 HAVE_DECL_STRCASECMP
#cmakedefine01 HAVE_DECL_STRNCASECMP

View file

@ -1,335 +0,0 @@
AC_INIT(Chocolate Doom, 3.1.1,
chocolate-doom-dev-list@chocolate-doom.org, chocolate-doom)
PACKAGE_SHORTNAME=${PACKAGE_NAME% Doom}
PACKAGE_SHORTDESC="Conservative source port"
PACKAGE_COPYRIGHT="Copyright (C) 1993-2025"
PACKAGE_LICENSE="GNU General Public License, version 2"
PACKAGE_MAINTAINER="Simon Howard"
PACKAGE_URL="https://www.chocolate-doom.org/"
PACKAGE_RDNS="org.chocolate_doom"
PACKAGE_BUGREPORT="https://github.com/chocolate-doom/chocolate-doom/issues"
dnl Check for Emscripten environment so we can set necessary environment variables
AC_ARG_ENABLE(
[emscripten],
[AS_HELP_STRING([--enable-emscripten=@<:@no/yes@:>@],[compile to JavaScript using Emscripten])],,
[AS_CASE([$CC],
[*emcc.py], [enable_emscripten="yes"],
[*emcc], [enable_emscripten="yes"],
[enable_emscripten="no"]
)
]
)
AS_IF([test "x$enable_emscripten" = "xyes"],
AC_MSG_NOTICE([auto-detected use of Emscripten])
SDL_CFLAGS="-s USE_SDL=2"
SDL_LIBS="-s USE_SDL=2"
SDLMIXER_CFLAGS="-s USE_SDL=2 -s USE_SDL_MIXER=2"
SDLMIXER_LIBS="-s USE_SDL=2 -s USE_SDL_MIXER=2"
SDLNET_CFLAGS="-s USE_SDL=2 -s USE_SDL_NET=2"
SDLNET_LIBS="-s USE_SDL=2 -s USE_SDL_NET=2"
EM_LDFLAGS="-s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY=1 -s EXPORTED_RUNTIME_METHODS=[ccall,cwrap,FS,ENV,PATH,ERRNO_CODES] -s FORCE_FILESYSTEM"
)
AC_CONFIG_AUX_DIR(autotools)
AC_CANONICAL_HOST
orig_CFLAGS="$CFLAGS"
AM_PROG_AR
AC_PROG_CC_C99
AC_PROG_RANLIB
AC_CHECK_PROG(HAVE_PYTHON, python3, true, false)
OPT_LEVEL=2
# If this is gcc, we have some options we'd like to turn on. Turn on
# optimisation and debugging symbols.
if test "$GCC" = "yes"
then
WARNINGS="-Wall -Wdeclaration-after-statement -Wredundant-decls"
CFLAGS="-O$OPT_LEVEL -g $WARNINGS $orig_CFLAGS"
fi
AC_CANONICAL_TARGET
TARGET_OS=""
AS_CASE([$target_cpu],
[x86_64],
[
TARGET_OS="x64"
],
[aarch64*|arm*],
[
TARGET_OS="arm"
],
[i?86|arm*],
[
TARGET_OS="32"
])
AC_SUBST([TARGET_OS])
PKG_CHECK_MODULES(SDL, [sdl2 >= 2.0.14])
# Check for SDL2_mixer
AC_ARG_ENABLE([sdl2mixer],
AS_HELP_STRING([--disable-sdl2mixer], [Disable SDL2_mixer support])
)
AS_IF([test "x$enable_sdl2mixer" != xno], [
PKG_CHECK_MODULES(SDLMIXER, [SDL2_mixer >= 2.0.2])], [
AC_DEFINE([DISABLE_SDL2MIXER], [1], [SDL2_mixer disabled])
])
# Check for networking
AC_ARG_ENABLE([sdl2net],
AS_HELP_STRING([--disable-sdl2net], [Disable SDL2_net support])
)
AS_IF([test "x$enable_sdl2net" != xno], [
PKG_CHECK_MODULES(SDLNET, [SDL2_net >= 2.0.0])], [
AC_DEFINE([DISABLE_SDL2NET], [1], [SDL2_net disabled])
])
# Check for bash-completion.
AC_ARG_ENABLE([bash-completion],
AS_HELP_STRING([--disable-bash-completion], [Disable bash-completion])
)
AS_IF([test "x$enable_bash_completion" != xno], [
AS_IF([test "x$HAVE_PYTHON" = xfalse], [
AC_MSG_WARN([Building bash-completion requires Python, but Python not found])
enable_bash_completion=no
])
])
# Check for doc.
AC_ARG_ENABLE([doc],
AS_HELP_STRING([--disable-doc], [Disable documentation])
)
AS_IF([test "x$enable_doc" != xno], [
AS_IF([test "x$HAVE_PYTHON" = xfalse], [
AC_MSG_WARN([Building documentation requires Python, but Python not found])
enable_doc=no
])
])
# Check for fonts.
AC_ARG_ENABLE([fonts],
AS_HELP_STRING([--disable-fonts], [Disable fonts])
)
AS_IF([test "x$enable_fonts" != xno], [
AS_IF([test "x$HAVE_PYTHON" = xfalse], [
AC_MSG_WARN([Building fonts require Python, but Python not found])
enable_fonts=no
])
])
# Check for icons.
AC_ARG_ENABLE([icons],
AS_HELP_STRING([--disable-icons], [Disable icons])
)
AS_IF([test "x$enable_icons" != xno], [
AS_IF([test "x$HAVE_PYTHON" = xfalse], [
AC_MSG_WARN([Building icons require Python, but Python not found])
enable_icons=no
])
])
# Check for memory pool debugging.
AC_ARG_ENABLE([zpool],
AS_HELP_STRING([--disable-zpool], [Disable memory pools for debugging])
)
AS_IF([test "x$enable_zpool" != xno], [], [
AC_DEFINE([DISABLE_ZPOOL], [1], [Memory pooling disabled])
])
# Check for libsamplerate.
AC_ARG_WITH([libsamplerate],
AS_HELP_STRING([--without-libsamplerate],
[Build without libsamplerate @<:@default=check@:>@]),
[],
[
[with_libsamplerate=check]
])
AS_IF([test "x$with_libsamplerate" != xno], [
PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.1.8, [
AC_DEFINE([HAVE_LIBSAMPLERATE], [1], [libsamplerate installed])
], [
AS_IF([test "x$with_libsamplerate" != xcheck], [AC_MSG_FAILURE(
[--with-libsamplerate was given, but test for libsamplerate failed])
])
])
])
# Check for libpng.
AC_ARG_WITH([libpng],
AS_HELP_STRING([--without-libpng],
[Build without libpng @<:@default=check@:>@]),
[],
[
[with_libpng=check]
])
AS_IF([test "x$with_libpng" != xno], [
PKG_CHECK_MODULES(PNG, libpng >= 1.2.50, [
AC_DEFINE([HAVE_LIBPNG], [1], [libpng installed])
], [
AS_IF([test "x$with_libpng" != xcheck], [AC_MSG_FAILURE(
[--with-libpng was given, but test for libpng failed])
])
])
])
# Check for fluidsynth.
AC_ARG_WITH([fluidsynth],
AS_HELP_STRING([--without-fluidsynth],
[Build without fluidsynth @<:@default=check@:>@]),
[],
[
[with_fluidsynth=check]
])
AS_IF([test "x$with_fluidsynth" != xno] && [test "x$enable_sdl2mixer" != xno], [
PKG_CHECK_MODULES(FLUIDSYNTH, fluidsynth >= 2.2.0, [
AC_DEFINE([HAVE_FLUIDSYNTH], [1], [fluidsynth installed])
], [
AS_IF([test "x$with_fluidsynth" != xcheck], [AC_MSG_FAILURE(
[--with-fluidsynth was given, but test for fluidsynth failed])
])
])
])
# TODO: We currently link everything against libraries that don't need it.
# Use the specific library CFLAGS/LIBS variables instead of setting them here.
CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-} ${PNG_CFLAGS:-} ${FLUIDSYNTH_CFLAGS:-}"
LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-} ${PNG_LIBS:-} ${FLUIDSYNTH_LIBS:-}"
case "$host" in
*-*-mingw* | *-*-cygwin* | *-*-msvc* )
LDFLAGS="$LDFLAGS -lwinmm -lshlwapi"
;;
*)
esac
AC_CHECK_LIB(m, log)
AC_CHECK_HEADERS([dirent.h linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
AC_CHECK_FUNCS(mmap ioperm)
AC_CHECK_DECLS([strcasecmp, strncasecmp], [], [], [[#include <strings.h>]])
# OpenBSD I/O i386 library for I/O port access.
# (64 bit has the same thing with a different name!)
AC_CHECK_LIB(i386, i386_iopl)
AC_CHECK_LIB(amd64, amd64_iopl)
case "$host" in
*-*-mingw* | *-*-cygwin* | *-*-msvc* )
AC_CHECK_TOOL(WINDRES, windres, )
;;
*)
WINDRES=
;;
esac
AC_CHECK_TOOL(OBJDUMP, objdump, )
AC_CHECK_TOOL(STRIP, strip, )
AC_ARG_ENABLE([werror], AS_HELP_STRING([--enable-werror], [Treat warnings as errors]))
AS_IF([test "x$enable_werror" = "xyes"], [
CFLAGS="$CFLAGS -Werror"
])
AM_CONDITIONAL(HAVE_WINDRES, test "$WINDRES" != "")
AM_CONDITIONAL(HAVE_BASH_COMPLETION, [test "x$enable_bash_completion" != xno])
AM_CONDITIONAL(HAVE_DOC, [test "x$enable_doc" != xno])
AM_CONDITIONAL(HAVE_FONTS, [test "x$enable_fonts" != xno])
AM_CONDITIONAL(HAVE_ICONS, [test "x$enable_icons" != xno])
AM_CONDITIONAL(HAVE_ZPOOL, [test "x$enable_zpool" != xno])
dnl Automake v1.8.0 is required, please upgrade!
AM_INIT_AUTOMAKE([1.8.0 foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
WINDOWS_RC_VERSION=`echo $PACKAGE_VERSION | sed 's/-.*//; s/\./, /g; s/$/, 0/'`
dnl Without a hyphen. This is used for the bash-completion scripts.
PROGRAM_SPREFIX=$(echo $PACKAGE_SHORTNAME | tr A-Z a-z)
dnl With a hyphen, used almost everywhere else.
PROGRAM_PREFIX=${PROGRAM_SPREFIX}-
AC_SUBST(PROGRAM_PREFIX)
AC_DEFINE_UNQUOTED(PROGRAM_PREFIX, "$PROGRAM_PREFIX",
Change this when you create your awesome forked version)
AC_SUBST(PROGRAM_SPREFIX)
AC_CONFIG_HEADERS(config.h:config.hin)
AC_SUBST(WINDOWS_RC_VERSION)
AC_SUBST(SDLMIXER_CFLAGS)
AC_SUBST(SDLMIXER_LIBS)
AC_SUBST(EM_LDFLAGS)
AC_SUBST(SDLNET_CFLAGS)
AC_SUBST(SDLNET_LIBS)
AC_SUBST(ac_aux_dir)
AC_SUBST(PACKAGE_SHORTNAME)
AC_SUBST(PACKAGE_SHORTDESC)
AC_SUBST(PACKAGE_COPYRIGHT)
AC_SUBST(PACKAGE_LICENSE)
AC_SUBST(PACKAGE_MAINTAINER)
AC_SUBST(PACKAGE_URL)
AC_SUBST(PACKAGE_RDNS)
AC_SUBST(PACKAGE_BUGREPORT)
dnl Shut up the datarootdir warnings.
AC_DEFUN([AC_DATAROOTDIR_CHECKED])
AS_IF([test "x$enable_emscripten" = "xyes"],
EXEEXT=".html"
)
AC_CONFIG_FILES([
Makefile
man/Makefile
man/bash-completion/Makefile
man/bash-completion/doom.template
man/bash-completion/heretic.template
man/bash-completion/hexen.template
man/bash-completion/strife.template
opl/Makefile
opl/examples/Makefile
pcsound/Makefile
pkg/Makefile
pkg/config.make
pkg/osx/Info.plist
rpm.spec
data/Makefile
src/Makefile
src/doom-res.rc
src/Doom.metainfo.xml
src/Doom.desktop
src/Doom_Screensaver.desktop
src/doom/Makefile
src/heretic-res.rc
src/Heretic.metainfo.xml
src/Heretic.desktop
src/heretic/Makefile
src/hexen-res.rc
src/Hexen.metainfo.xml
src/Hexen.desktop
src/hexen/Makefile
src/setup-res.rc
src/setup/Makefile
src/setup/Setup.desktop
src/setup/setup-manifest.xml
src/strife-res.rc
src/Strife.metainfo.xml
src/Strife.desktop
src/strife/Makefile
textscreen/Makefile
textscreen/examples/Makefile
textscreen/fonts/Makefile
])
AC_OUTPUT

View file

@ -1,7 +0,0 @@
Makefile.in
Makefile
*-doom.png
*-heretic.png
*-hexen.png
*-setup.png
*-strife.png

View file

@ -1,39 +0,0 @@
EXTRA_DIST= \
README \
doom.ico \
doom.png \
heretic.ico \
heretic.png \
hexen.ico \
hexen.png \
setup.ico \
setup.png \
strife.ico \
strife.png \
wadfile.png \
convert-icon
iconsdir = $(prefix)/share/icons/hicolor/128x128/apps
icons_DATA = @PROGRAM_PREFIX@doom.png \
@PROGRAM_PREFIX@heretic.png \
@PROGRAM_PREFIX@hexen.png \
@PROGRAM_PREFIX@setup.png \
@PROGRAM_PREFIX@strife.png
@PROGRAM_PREFIX@doom.png : doom.png
cp $(top_srcdir)/data/doom.png $@
@PROGRAM_PREFIX@heretic.png : heretic.png
cp $(top_srcdir)/data/heretic.png $@
@PROGRAM_PREFIX@hexen.png : hexen.png
cp $(top_srcdir)/data/hexen.png $@
@PROGRAM_PREFIX@setup.png : setup.png
cp $(top_srcdir)/data/setup.png $@
@PROGRAM_PREFIX@strife.png : strife.png
cp $(top_srcdir)/data/strife.png $@
CLEANFILES = $(icons_DATA)

View file

@ -1,16 +0,0 @@
The Chocolate Doom icon is based on an image by Chris Metcalf
(http://www.chrismetcalf.org/) which is copyrighted to him:
http://www.flickr.com/photos/laffy4k/448920776/
Chris has kindly agreed that the Chocolate Doom icon may be used under
the GNU GPL, so the copyright status of the icon is the same as that of
the rest of the project.
The "foo8.ico" files are 8-bit depth only, while the "foo.ico" files
contain full 32-bit versions, scaled to different sizes and with proper
alpha masks (as well as the 8-bit versions). The 8-bit versions are
used when setting the icon within SDL, as SDL under Windows displays
full color icons in a very poor quality. The full-color versions are
used in the resource files.

View file

@ -1,72 +0,0 @@
#!/usr/bin/env python3
#
# Copyright(C) 2005-2014 Simon Howard
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# Converts images into C structures to be inserted in programs
#
import sys
import os
import re
try:
import Image
except ImportError:
try:
from PIL import Image
except ImportError:
print("WARNING: Could not update %s. "
"Please install the Python Imaging library or Pillow."
% sys.argv[2])
sys.exit(0)
def convert_image(filename, output_filename):
im = Image.open(filename)
outfile = open(output_filename, "w")
size = im.size
struct_name = os.path.basename(output_filename)
struct_name = re.sub(re.compile("\\..*$"), "", struct_name)
struct_name = re.sub(re.compile("\W"), "_", struct_name)
outfile.write("static int %s_w = %i;\n" % (struct_name, size[0]))
outfile.write("static int %s_h = %i;\n" % (struct_name, size[1]))
outfile.write("\n")
outfile.write("static const unsigned int %s_data[] = {\n" % (struct_name))
elements_on_line = 0
outfile.write(" ")
for y in range(size[1]):
for x in range(size[0]):
val = im.getpixel((x, y))
outfile.write("0x%02x%02x%02x%02x, " % val)
elements_on_line += 1
if elements_on_line >= 6:
elements_on_line = 0
outfile.write("\n")
outfile.write(" ")
outfile.write("\n")
outfile.write("};\n")
convert_image(sys.argv[1], sys.argv[2])

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View file

@ -1,16 +0,0 @@
CMDLINE.doom
CMDLINE.doom.md
CMDLINE.heretic
CMDLINE.heretic.md
CMDLINE.hexen
CMDLINE.hexen.md
CMDLINE.strife
CMDLINE.strife.md
INSTALL.doom
INSTALL.heretic
INSTALL.hexen
INSTALL.strife
Makefile.in
Makefile
*.6
*.5

View file

@ -1,8 +0,0 @@
== Command line parameters ==
This is a full list of the supported command line parameters. A number of
additional parameters are supported in addition to those present in the DOS
version.
@content

View file

@ -1,8 +0,0 @@
# Command line parameters
This is a full list of the supported command line parameters. A number of
additional parameters are supported in addition to those present in the DOS
version.
@content

View file

@ -1,316 +0,0 @@
#ifdef DOOM
#define DEFAULT_IWAD doom2.wad
#elif HERETIC
#define DEFAULT_IWAD heretic.wad
#elif HEXEN
#define DEFAULT_IWAD hexen.wad
#elif STRIFE
#define DEFAULT_IWAD strife1.wad
#endif
# LONG_GAME_NAME installation
These are instructions for how to install and set up LONG_GAME_NAME
for play.
#if !PRECOMPILED
# Building LONG_GAME_NAME
Before you can play LONG_GAME_NAME, you need to compile a binary that
you can run. For compilation, LONG_GAME_NAME requires the following
to be installed:
* A C compiler (gcc is recommended)
* make (GNU make is recommended)
* SDL2 (see https://www.libsdl.org/)
* SDL2_mixer (see https://www.libsdl.org/projects/SDL_mixer/)
* SDL2_net (see https://www.libsdl.org/projects/SDL_net/)
* Python (optional)
Follow the standard instructions for installing an autotools-based
package:
1. Run `./configure` to initialize the package.
2. Run `make` to compile the package.
3. Run `make install` to install the package.
An automated build script is available that installs the necessary
dependencies and builds the source code automatically. See the build
instructions on the website.
Advanced topics such as cross-compilation are beyond the scope of this
document. Please see the GNU autoconf / automake documentation for more
information.
#endif
# Obtaining an IWAD file
To play, you need an IWAD file. This file contains the game data
(graphics, sounds, etc). The full versions of the games are
proprietary and need to be bought. The IWAD file has one of the
following names:
| IWAD | Game |
| -------------------------- | ------------------------------- |
#if DOOM
| doom1.wad | Shareware Doom |
| doom.wad | Registered / Ultimate Doom |
| doom2.wad | Doom 2 |
| tnt.wad | Final Doom: TNT: Evilution |
| plutonia.wad | Final Doom: Plutonia Experiment |
| chex.wad | Chex Quest |
| freedoom1.wad | Freedoom: Phase 1 |
| freedoom2.wad | Freedoom: Phase 2 |
| freedm.wad | FreeDM |
#endif
#if HERETIC
| heretic1.wad | Shareware Heretic |
| heretic.wad | Registered / Commercial Heretic |
#endif
#if HEXEN
| hexen.wad | Hexen |
#endif
#if STRIFE
| strife1.wad (+voices.wad) | Strife |
#endif
#if DOOM
If you dont have a copy of a commercial version, you can download
the shareware version of Doom (extract the file named doom1.wad):
* https://www.doomworld.com/idgames/idstuff/doom/win95/doom95
(idstuff/doom/win95/doom95.zip in your nearest /idgames mirror)
#endif
If you have a commercial version on a CD-ROM, obtaining the IWAD
file is usually straightforward. Simply locate the IWAD file on the
disc and copy it off.
#if !__MACOSX__
#if DOOM
The Doom games are available to purchase for download on Steam
(https://store.steampowered.com/), all releases containing the classic
games including Doom 3: BFG Edition are supported.
#endif
#if HERETIC
Heretic is available to purchase for download on Steam
(https://store.steampowered.com/).
#endif
#if HEXEN
Hexen and its expansion pack are available to purchase for download on
Steam (https://store.steampowered.com/).
#endif
#if STRIFE
Strife: Veteran Edition is available to purchase for download on Steam
(https://store.steampowered.com/).
#endif
#if !_WIN32
For Steam on Linux, you need to enable “Steam Play” for all titles in
order to install the games. You may do this from the Steam menu,
Setup, and the Steam Play tab.
#endif
LONG_GAME_NAME will autodetect IWADs installed by Steam and you do not
need to do anything.
#else
The Doom, Heretic, Hexen, and Strife games are available to purchase
for download on Steam (https://store.steampowered.com/), but are only
available for Windows. To find the IWAD files on a Windows or Wine
system, look in the Steam directory (usually within “Program Files”),
under the “steamapps/common” path.
#endif
#if DOOM || STRIFE
The Doom and Strife: Veteran Edition games are available for purchase
on GOG.com (https://www.gog.com/).
#if _WIN32
LONG_GAME_NAME will autodetect IWADs from the standalone or GOG Galaxy
installers and you do not need to do anything.
#else
The games are only available for Windows, but you may find the IWAD
files on a Windows or Wine system, typically within the “C:\GOG Games”
or “C:\Program Files\GOG Galaxy” directories.
#endif
#endif
#if DOOM || HERETIC
Older floppy disk versions are harder to deal with. The easiest way
to install from floppies is to run the original installer program
inside an emulator such as DOSbox (https://www.dosbox.com/).
As an alternative to using an emulator, it is possible to extract the
files manually. On the install disk(s), you will find several files
with numbered extensions (eg. “doom_se.1”).
From the command line it is possible to combine these files into a
single large file, using a command similar to the following:
#if _WIN32
copy doom_se.1+doom_se.2+doom_se.3+doom_se.4+doom_se.5 doom_se.lzh
#else
cat doom_se.1 doom_se.2 doom_se.3 doom_se.4 doom_se.5 > doom_se.lzh
#endif
The resulting file is an LHA archive file, and it can be extracted
using an LHA archive tool (there is one available for almost every
operating system).
#endif
# Running the game
#if __MACOSX__
Once you have an IWAD file, you can specify its location within the
graphical launcher program. Click the “Configure...” button, and then
click “Set...” for each IWAD to choose its location. From the main
launcher dialog you can then choose which game you want to play and
click the “Launch” button to start the game.
If you are an advanced user and like to run Doom from the command
line, you can use the “Command Prompt...” menu item to open a Terminal
window. The DOOMWADPATH environment variable is preconfigured
to point to the locations of the IWAD files set within the launcher.
You can launch the game with a specific IWAD file by typing, for
example:
LONG_EXE_NAME -iwad tnt.wad
#else
LONG_GAME_NAME needs to know where to find your IWAD file. To do this,
do one of the following:
#if _WIN32
* Within Explorer, simply place the IWAD file in the same folder as
the LONG_GAME_NAME files, and double-click `LONG_EXE_NAME.exe`.
* Run LONG_GAME_NAME from the command prompt with the `-iwad` command
line parameter to specify the IWAD file to use, eg.
LONG_EXE_NAME -iwad c:\games\DEFAULT_IWAD
* Set the environment variable DOOMWADDIR to the location of a
directory containing your IWAD files.
* If you have multiple IWADs in different directories, set the
environment variable DOOMWADPATH to be a semicolon-separated list
of directories to search (similar to the PATH environment
variable).
#else
* Run LONG_GAME_NAME from the Unix console with the `-iwad` command
line parameter to specify the IWAD file to use, eg.
LONG_EXE_NAME -iwad /root/DEFAULT_IWAD
* Put the file into one of the following directories:
$HOME/.local/share/games/doom
/usr/share/doom
/usr/share/games/doom
/usr/local/share/doom
/usr/local/share/games/doom
* Set the environment variable DOOMWADDIR to specify the path to a
directory containing your IWAD files.
* If you have multiple IWADs in different directories, set the
environment variable DOOMWADPATH to be a colon-separated list of
directories to search (similar to the Unix PATH environment
variable).
#endif
#endif
#if DOOM
# Playing with Freedoom
Freedoom is an open content project to create a Doom engine-based game
that is entirely free software. The website can be found here:
https://freedoom.github.io/
Check out the [Chocolate Doom wikis page on
Freedoom](https://www.chocolate-doom.org/wiki/index.php/Freedoom)
for more information.
# Playing with Chex Quest
Chex Quest is a game based on Doom with some minor modifications that
was distributed with boxes of Chex cereal in 1997. It is possible to
play Chex Quest using LONG_GAME_NAME. To do this, the following files
are needed:
* The IWAD file “chex.wad”, from the Chex Quest CD.
* The dehacked patch “chex.deh”, which can be found here:
https://www.doomworld.com/idgames/themes/chex/chexdeh
(themes/chex/chexdeh.zip in your nearest /idgames mirror)
Copy these files into a directory together and use the `-iwad` command
line parameter to specify the Chex Quest IWAD file:
LONG_EXE_NAME -iwad chex.wad
#endif
# Installing upgrades
#if DOOM
LONG_GAME_NAME requires a version 1.9 IWAD file. Generally, if you
install a recent version of Doom you should have a version 1.9 IWAD.
#elif HERETIC
LONG_GAME_NAME requires a version 1.2 (Shareware) or version 1.3
(Shadow of the Serpent Riders) IWAD file. Generally, if you install a
recent version of Heretic you should have a version 1.2 or 1.3 IWAD.
#elif HEXEN
LONG_GAME_NAME requires a version 1.1 IWAD file. Generally, if you
install a recent version of Hexen you should have a version 1.1 IWAD.
#elif STRIFE
LONG_GAME_NAME requires a version 1.2 IWAD file. Generally, if you
install a recent version of Strife you should have a version 1.2 IWAD.
Please note that Strife version 1.3 does not update the IWAD, if your
version.txt file says “STRIFE(TM) VERSION 1.3”, you are still good.
#endif
However, if you are installing from a very old CD version or from
floppy disks, you might find you have an older version.
The most obvious symptom of an out of date IWAD file is that the game
will exit at the title screen before the demo starts, with the message
“Demo is from a different game version!”. If this happens, your IWAD
file is out of date and you need to upgrade.
Upgrade patches are available that will update your game to the latest
version, the following sites have the patches:
#if DOOM
* http://www.doom2.net/doom2/utils.html
* http://www.gamers.org/pub/idgames/idstuff/doom
* http://www.gamers.org/pub/idgames/idstuff/doom2
#elif HERETIC
* http://www.gamers.org/pub/idgames/idstuff/heretic
#elif HEXEN
* http://www.gamers.org/pub/idgames/idstuff/hexen
#elif STRIFE
* http://www.gamers.org/pub/idgames/roguestuff
#endif
Please see the
[Doom Wikis page on game patches](https://doomwiki.org/wiki/Game_patch)
for more information.
#if _WIN32
As the patches are binary patches that run as DOS executables, on
recent 64-bit versions of Windows you will need to use a DOS emulator
(such as DOSBox) to run them.
#else
As the patches are binary patches that run as DOS executables, you
will need to use a DOS emulator (such as DOSBox) to run them.
#endif
# Music support
LONG_GAME_NAME includes OPL emulation code that accurately reproduces
the way that the in-game music sounded under DOS when using an
Adlib/Soundblaster card. This is, however, not to everyones taste.
LONG_GAME_NAME includes a number of different options for better
quality MIDI playback; see the file README.Music for more details of
how to set these up.
#if !PRECOMPILED
When compiling from source, be sure to compile and install Timidity
before installing SDL2_mixer.
#endif

View file

@ -1,226 +0,0 @@
SUBDIRS = bash-completion
MANPAGE_GEN_FILES = environ.man \
iwad_paths.man \
doom.template \
heretic.template \
hexen.template \
strife.template \
docgen \
default.cfg.template \
extra.cfg.template \
server.template \
setup.template
doomdocsdir = ${docdir}/../${PROGRAM_PREFIX}doom
hereticdocsdir = ${docdir}/../${PROGRAM_PREFIX}heretic
hexendocsdir = ${docdir}/../${PROGRAM_PREFIX}hexen
strifedocsdir = ${docdir}/../${PROGRAM_PREFIX}strife
if HAVE_DOC
GENERATED_MAN_PAGES = \
@PROGRAM_PREFIX@doom.6 \
default.cfg.5 \
@PROGRAM_PREFIX@doom.cfg.5 \
@PROGRAM_PREFIX@heretic.6 \
heretic.cfg.5 \
@PROGRAM_PREFIX@heretic.cfg.5 \
@PROGRAM_PREFIX@hexen.6 \
hexen.cfg.5 \
@PROGRAM_PREFIX@hexen.cfg.5 \
@PROGRAM_PREFIX@strife.6 \
strife.cfg.5 \
@PROGRAM_PREFIX@strife.cfg.5 \
@PROGRAM_PREFIX@server.6
SETUP_MAN_PAGES = \
@PROGRAM_PREFIX@doom-setup.6 \
@PROGRAM_PREFIX@heretic-setup.6 \
@PROGRAM_PREFIX@hexen-setup.6 \
@PROGRAM_PREFIX@strife-setup.6
man_MANS = $(GENERATED_MAN_PAGES) \
$(SETUP_MAN_PAGES)
doomdocs_DATA = INSTALL.doom CMDLINE.doom
hereticdocs_DATA = INSTALL.heretic CMDLINE.heretic
hexendocs_DATA = INSTALL.hexen CMDLINE.hexen
strifedocs_DATA = INSTALL.strife CMDLINE.strife
if HAVE_WINDRES
WIN32=-D_WIN32
doomdocs_DATA += CMDLINE.doom.md
hereticdocs_DATA += CMDLINE.heretic.md
hexendocs_DATA += CMDLINE.hexen.md
strifedocs_DATA += CMDLINE.strife.md
endif
CLEANFILES = $(GENERATED_MAN_PAGES) $(SETUP_MAN_PAGES) \
$(doomdocs_DATA) $(hereticdocs_DATA) \
$(hexendocs_DATA) $(strifedocs_DATA)
DOCGEN = $(srcdir)/docgen
DOCGEN_COMMON_ARGS = -n "@PROGRAM_SPREFIX@" \
-s "@PACKAGE_NAME@" \
-z "@PACKAGE_SHORTNAME@" \
-v "@VERSION@"
@PROGRAM_PREFIX@doom.6: $(top_srcdir)/src $(MANPAGE_GEN_FILES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g doom -m $(srcdir)/doom.template \
$(top_srcdir)/src $(top_srcdir)/src/doom > $@
default.cfg.5: $(top_srcdir)/src $(srcdir)/default.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g doom -m $(srcdir)/default.cfg.template \
-c default $(top_srcdir)/src/m_config.c > $@
@PROGRAM_PREFIX@doom.cfg.5: $(top_srcdir)/src extra.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g doom -m $(srcdir)/extra.cfg.template \
-c extended $(top_srcdir)/src/m_config.c > $@
CMDLINE.doom : CMDLINE.template $(top_srcdir)/src $(top_srcdir)/src/doom
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-p $(srcdir)/CMDLINE.template \
$(top_srcdir)/src/ $(top_srcdir)/src/doom/ > $@
CMDLINE.doom.md : CMDLINE.template.md $(top_srcdir)/src $(top_srcdir)/src/doom
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-M $(srcdir)/CMDLINE.template.md \
$(top_srcdir)/src/ $(top_srcdir)/src/doom/ > $@
CMDLINE.doom.wikitext : $(top_srcdir)/src $(top_srcdir)/src/doom
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-w $(top_srcdir)/src/ $(top_srcdir)/src/doom/ > $@
INSTALL.doom: INSTALL.template
$(srcdir)/simplecpp -DDOOM $(WIN32) \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Doom" \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@doom" \
-DPRECOMPILED < $(srcdir)/INSTALL.template > $@
@PROGRAM_PREFIX@heretic.6: $(top_srcdir)/src $(MANPAGE_GEN_FILES) heretic.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g heretic -m $(srcdir)/heretic.template \
$(top_srcdir)/src $(top_srcdir)/src/heretic > $@
heretic.cfg.5: $(top_srcdir)/src $(srcdir)/default.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g heretic -m $(srcdir)/default.cfg.template \
-c default $(top_srcdir)/src/m_config.c > $@
@PROGRAM_PREFIX@heretic.cfg.5: $(top_srcdir)/src extra.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g heretic -m $(srcdir)/extra.cfg.template \
-c extended $(top_srcdir)/src/m_config.c > $@
CMDLINE.heretic : CMDLINE.template $(top_srcdir)/src $(top_srcdir)/src/heretic
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-p $(srcdir)/CMDLINE.template \
$(top_srcdir)/src/ $(top_srcdir)/src/heretic/ > $@
CMDLINE.heretic.md : CMDLINE.template.md $(top_srcdir)/src $(top_srcdir)/src/heretic
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-M $(srcdir)/CMDLINE.template.md \
$(top_srcdir)/src/ $(top_srcdir)/src/heretic/ > $@
INSTALL.heretic: INSTALL.template
$(srcdir)/simplecpp -DHERETIC $(WIN32) \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Heretic" \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@heretic" \
-DPRECOMPILED < $(srcdir)/INSTALL.template > $@
@PROGRAM_PREFIX@hexen.6: $(top_srcdir)/src $(MANPAGE_GEN_FILES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g hexen -m $(srcdir)/hexen.template \
$(top_srcdir)/src $(top_srcdir)/src/hexen > $@
hexen.cfg.5: $(top_srcdir)/src default.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g hexen -m $(srcdir)/default.cfg.template \
-c default $(top_srcdir)/src/m_config.c > $@
@PROGRAM_PREFIX@hexen.cfg.5: $(top_srcdir)/src extra.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g hexen -m $(srcdir)/extra.cfg.template \
-c extended $(top_srcdir)/src/m_config.c > $@
CMDLINE.hexen : CMDLINE.template $(top_srcdir)/src $(top_srcdir)/src/hexen
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-p $(srcdir)/CMDLINE.template \
$(top_srcdir)/src/ $(top_srcdir)/src/hexen/ > $@
CMDLINE.hexen.md : CMDLINE.template.md $(top_srcdir)/src $(top_srcdir)/src/hexen
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-M $(srcdir)/CMDLINE.template.md \
$(top_srcdir)/src/ $(top_srcdir)/src/hexen/ > $@
INSTALL.hexen: INSTALL.template
$(srcdir)/simplecpp -DHEXEN $(WIN32) \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Hexen" \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@hexen" \
-DPRECOMPILED < $(srcdir)/INSTALL.template > $@
@PROGRAM_PREFIX@strife.6: $(top_srcdir)/src $(MANPAGE_GEN_FILES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g strife -m $(srcdir)/strife.template \
$(top_srcdir)/src $(top_srcdir)/src/strife > $@
@PROGRAM_PREFIX@server.6: $(top_srcdir)/src $(MANPAGE_GEN_FILES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g server -m $(srcdir)/server.template \
$(top_srcdir)/src > $@
$(SETUP_MAN_PAGES): $(top_srcdir)/src $(MANPAGE_GEN_FILES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g $(patsubst @PROGRAM_PREFIX@%-setup.6,%,$@) \
-m $(srcdir)/setup.template \
$(top_srcdir)/src > $@
strife.cfg.5: $(top_srcdir)/src default.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g strife -m $(srcdir)/default.cfg.template \
-c default $(top_srcdir)/src/m_config.c > $@
@PROGRAM_PREFIX@strife.cfg.5: $(top_srcdir)/src extra.cfg.template
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g strife -m $(srcdir)/extra.cfg.template \
-c extended $(top_srcdir)/src/m_config.c > $@
CMDLINE.strife : CMDLINE.template $(top_srcdir)/src $(top_srcdir)/src/strife
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-p $(srcdir)/CMDLINE.template \
$(top_srcdir)/src/ $(top_srcdir)/src/strife/ > $@
CMDLINE.strife.md : CMDLINE.template.md $(top_srcdir)/src $(top_srcdir)/src/strife
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-M $(srcdir)/CMDLINE.template.md \
$(top_srcdir)/src/ $(top_srcdir)/src/strife/ > $@
INSTALL.strife: INSTALL.template
$(srcdir)/simplecpp -DSTRIFE $(WIN32) \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@strife" \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Strife" \
-DPRECOMPILED < $(srcdir)/INSTALL.template > $@
INSTALL: INSTALL.template
$(srcdir)//simplecpp -DDOOM -DHERETIC -DHEXEN -DSTRIFE \
-DLONG_GAME_NAME="@PACKAGE_SHORTNAME@ Doom" \
-DLONG_EXE_NAME="@PROGRAM_PREFIX@doom" \
-DPRECOMPILED < $(srcdir)/INSTALL.template > $@
endif
EXTRA_DIST = $(man_MANS) $(MANPAGE_GEN_FILES) \
wikipages \
CMDLINE.template \
CMDLINE.template.md \
INSTALL.template \
simplecpp

View file

@ -1,5 +0,0 @@
*doom
*heretic
*hexen
*strife
*.template

View file

@ -1,52 +0,0 @@
bashcompletiondir=@datadir@/bash-completion/completions
BASH_COMPLETION_TEMPLATES = \
doom.template \
heretic.template \
hexen.template \
strife.template
if HAVE_BASH_COMPLETION
BASH_COMPLETION_SCRIPTLETS = \
@PROGRAM_PREFIX@doom \
@PROGRAM_PREFIX@heretic \
@PROGRAM_PREFIX@hexen \
@PROGRAM_PREFIX@strife
bashcompletion_DATA = $(BASH_COMPLETION_SCRIPTLETS)
CLEANFILES = $(BASH_COMPLETION_SCRIPTLETS)
DOCGEN = $(top_srcdir)/man/docgen
DOCGEN_COMMON_ARGS = -n "@PROGRAM_SPREFIX@" -s "@PACKAGE_NAME@" -z "@PACKAGE_SHORTNAME@"
@PROGRAM_PREFIX@doom: $(top_srcdir)/src $(DOCGEN) $(BASH_COMPLETION_TEMPLATES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g doom -b doom.template \
$(top_srcdir)/src $(top_srcdir)/src/doom > $@
@PROGRAM_PREFIX@heretic: $(top_srcdir)/src $(DOCGEN) $(BASH_COMPLETION_TEMPLATES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g heretic -b heretic.template \
$(top_srcdir)/src $(top_srcdir)/src/heretic > $@
@PROGRAM_PREFIX@hexen: $(top_srcdir)/src $(DOCGEN) $(BASH_COMPLETION_TEMPLATES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g hexen -b hexen.template \
$(top_srcdir)/src $(top_srcdir)/src/hexen > $@
@PROGRAM_PREFIX@strife: $(top_srcdir)/src $(DOCGEN) $(BASH_COMPLETION_TEMPLATES)
$(DOCGEN) $(DOCGEN_COMMON_ARGS) \
-g strife -b strife.template \
$(top_srcdir)/src $(top_srcdir)/src/strife > $@
EXTRA_DIST = \
$(BASH_COMPLETION_TEMPLATES) \
$(BASH_COMPLETION_SCRIPTLETS)
else
EXTRA_DIST = \
$(BASH_COMPLETION_TEMPLATES)
endif

View file

@ -1,51 +0,0 @@
# bash completion for @PACKAGE_SHORTNAME@ Doom -*- shell-script -*-
_@PROGRAM_SPREFIX@_doom()
{
local cur prev words cword
_init_completion || return
# Save the previous switch on the command line in the prevsw variable
local i prevsw=""
for (( i=1; $cword > 1 && i <= $cword; i++ )); do
if [[ ${words[i]} == -* ]]; then
prevsw=${words[i]}
fi
done
# Allow adding more than one file with the same extension to the same switch
case $prevsw in
-config|-extraconfig)
_filedir cfg
;;
-file|-iwad|-aa|-af|-as|-merge|-nwtmerge)
_filedir wad
;;
-playdemo|-timedemo)
_filedir lmp
;;
-deh)
_filedir '@(bex|deh)'
;;
esac
case $prev in
-pack)
COMPREPLY=(doom2 tnt plutonia)
;;
-gameversion)
COMPREPLY=(1.666 1.7 1.8 1.9 ultimate final final2 hacx chex)
;;
-setmem)
COMPREPLY=(dos622 dos71 dosbox)
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=( $( compgen -W '@content' -- "$cur" ) )
fi
} &&
complete -F _@PROGRAM_SPREFIX@_doom @PROGRAM_PREFIX@doom
# ex: ts=4 sw=4 et filetype=sh

View file

@ -1,48 +0,0 @@
# bash completion for @PACKAGE_SHORTNAME@ Heretic -*- shell-script -*-
_@PROGRAM_SPREFIX@_heretic()
{
local cur prev words cword
_init_completion || return
# Save the previous switch on the command line in the prevsw variable
local i prevsw=""
for (( i=1; $cword > 1 && i <= $cword; i++ )); do
if [[ ${words[i]} == -* ]]; then
prevsw=${words[i]}
fi
done
# Allow adding more than one file with the same extension to the same switch
case $prevsw in
-config|-extraconfig)
_filedir cfg
;;
-file|-iwad|-aa|-af|-as|-merge|-nwtmerge)
_filedir wad
;;
-playdemo|-timedemo)
_filedir lmp
;;
-deh)
_filedir hhe
;;
esac
case $prev in
-hhever)
COMPREPLY=(1.0 1.2 1.3)
;;
-setmem)
COMPREPLY=(dos622 dos71 dosbox)
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=( $( compgen -W '@content' -- "$cur" ) )
fi
} &&
complete -F _@PROGRAM_SPREFIX@_heretic @PROGRAM_PREFIX@heretic
# ex: ts=4 sw=4 et filetype=sh

View file

@ -1,45 +0,0 @@
# bash completion for @PACKAGE_SHORTNAME@ Hexen -*- shell-script -*-
_@PROGRAM_SPREFIX@_hexen()
{
local cur prev words cword
_init_completion || return
# Save the previous switch on the command line in the prevsw variable
local i prevsw=""
for (( i=1; $cword > 1 && i <= $cword; i++ )); do
if [[ ${words[i]} == -* ]]; then
prevsw=${words[i]}
fi
done
# Allow adding more than one file with the same extension to the same switch
case $prevsw in
-config|-extraconfig)
_filedir cfg
;;
-file|-iwad|-aa|-af|-as|-merge|-nwtmerge)
_filedir wad
;;
-playdemo|-timedemo)
_filedir lmp
;;
esac
case $prev in
-gameversion)
COMPREPLY=(1.1 1.1r2)
;;
-setmem)
COMPREPLY=(dos622 dos71 dosbox)
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=( $( compgen -W '@content' -- "$cur" ) )
fi
} &&
complete -F _@PROGRAM_SPREFIX@_hexen @PROGRAM_PREFIX@hexen
# ex: ts=4 sw=4 et filetype=sh

View file

@ -1,48 +0,0 @@
# bash completion for @PACKAGE_SHORTNAME@ Strife -*- shell-script -*-
_@PROGRAM_SPREFIX@_strife()
{
local cur prev words cword
_init_completion || return
# Save the previous switch on the command line in the prevsw variable
local i prevsw=""
for (( i=1; $cword > 1 && i <= $cword; i++ )); do
if [[ ${words[i]} == -* ]]; then
prevsw=${words[i]}
fi
done
# Allow adding more than one file with the same extension to the same switch
case $prevsw in
-config|-extraconfig)
_filedir cfg
;;
-file|-iwad|-aa|-af|-as|-merge|-nwtmerge)
_filedir wad
;;
-playdemo|-timedemo)
_filedir lmp
;;
-deh)
_filedir seh
;;
esac
case $prev in
-gameversion)
COMPREPLY=(1.2 1.31)
;;
-setmem)
COMPREPLY=(dos622 dos71 dosbox)
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=( $( compgen -W '@content' -- "$cur" ) )
fi
} &&
complete -F _@PROGRAM_SPREFIX@_strife @PROGRAM_PREFIX@strife
# ex: ts=4 sw=4 et filetype=sh

View file

@ -1,50 +0,0 @@
.TH @CFGFILE@ 5 2017-11-30 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@CFGFILE@ \- @PACKAGE_SHORTNAME@ @GAME_UPPER@ configuration file
.SH DESCRIPTION
.PP
\fI@CFGFILE@\fR
is the configuration file for \fB@PROGRAM_SPREFIX@\-@GAME@\fR(6). The configuration
options stored in the file are the same as those stored in the
original DOS Vanilla @GAME_UPPER@.
Extra @PACKAGE_SHORTNAME@ @GAME_UPPER@-specific options are stored in a separate
configuration file, \fB@PROGRAM_SPREFIX@\-@GAME@.cfg\fR.
.PP
\fI@CFGFILE@\fR is normally stored in the user's home directory,
as \fI~/.local/share/@PROGRAM_SPREFIX@\-@GAME@/@CFGFILE@\fR. The path can be
overridden using the \fBXDG_DATA_HOME\fR environment variable (see the XDG
Base Directory Specification).
.PP
The \fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6) tool provides a simple to use front-end
for editing \fI@CFGFILE@\fR.
.SH FILE FORMAT
The file is a plain-text file, consisting of a list of configuration
options and their values, separated by whitespace. Each option is stored
on a separate line. Options have different types; an option may have
either an integer, floating point or string value. If the option is
of a string type, the value is surrounded by quotes (").
.PP
For example:
.RS
.PP
.EX
integer_value 1
integer_value2 1
floating_point_value 4.2
string_value "hello world"
.EE
.RE
.PP
Invalid lines or comments in the file will be ignored, but it is advisable
not to put them in the file; the file is rewritten from scratch every time
the game exits, so any invalid lines or comments will be lost.
.PP
Some options are used for keyboard key bindings; these are stored as
integer values containing the keyboard scan code of the key to be bound to.
Boolean values are also stored as integers, with a value of zero usually
indicating "false" and a non-zero value indicating "true".
@content
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-@GAME@\fR(6),
\fB@PROGRAM_SPREFIX@\-@GAME@.cfg\fR(5),
\fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6)

View file

@ -1,624 +0,0 @@
#!/usr/bin/env python3
#
# Chocolate Doom self-documentation tool. This works similar to javadoc
# or doxygen, but documents command line parameters and configuration
# file values, generating documentation in Unix manpage, wikitext and
# plain text forms.
#
# Comments are read from the source code in the following form:
#
# //!
# // @arg <extra arguments>
# // @category Category
# // @platform <some platform that the parameter is specific to>
# //
# // Long description of the parameter
# //
#
# something_involving = M_CheckParm("-param");
#
# For configuration file values:
#
# //! @begin_config_file myconfig
#
# //!
# // Description of the configuration file value.
# //
#
# CONFIG_VARIABLE_INT(my_variable, c_variable),
#
import io
import sys
import os
import re
import glob
import getopt
TEXT_WRAP_WIDTH = 78
INCLUDE_STATEMENT_RE = re.compile(r"@include\s+(\S+)")
# Use appropriate stdout function for Python 2 or 3
def stdout(buf):
if sys.version_info.major < 3:
sys.stdout.write(buf)
else:
sys.stdout.buffer.write(buf)
# Find the maximum width of a list of parameters (for plain text output)
def parameter_list_width(params):
w = 0
for p in params:
pw = len(p.name) + 5
if p.args:
pw += len(p.args)
if pw > w:
w = pw
return w
class ConfigFile:
def __init__(self, filename):
self.filename = filename
self.variables = []
def add_variable(self, variable):
self.variables.append(variable)
def manpage_output(self):
result = ".SH CONFIGURATION VARIABLES\n"
for v in self.variables:
result += ".TP\n"
result += v.manpage_output()
return result
def plaintext_output(self):
result = ""
w = parameter_list_width(self.variables)
for p in self.variables:
result += p.plaintext_output(w)
result = result.rstrip() + "\n"
return result
class Category:
def __init__(self, description):
self.description = description
self.params = []
def add_param(self, param):
self.params.append(param)
# Plain text output
def plaintext_output(self):
result = "=== %s ===\n\n" % self.description
self.params.sort()
w = parameter_list_width(self.params)
for p in self.params:
if p.should_show():
result += p.plaintext_output(w)
result = result.rstrip() + "\n"
return result
def markdown_output(self):
result = "## %s\n\n| Parameter | Description |\n| - | - |\n" % self.description
self.params.sort()
for p in self.params:
if p.should_show():
result += p.markdown_output()
result = result.rstrip() + "\n"
return result
def completion_output(self):
result = ""
self.params.sort()
for p in self.params:
if p.should_show():
result += p.completion_output(0)
result = result.rstrip()
return result
def manpage_output(self):
result = ".SH " + self.description.upper() + "\n"
self.params.sort()
for p in self.params:
if p.should_show():
result += ".TP\n"
result += p.manpage_output()
return result
def wiki_output(self):
result = "=== %s ===\n" % self.description
self.params.sort()
for p in self.params:
if p.should_show():
result += "; " + p.wiki_output() + "\n"
# Escape special HTML characters
result = result.replace("&", "&amp;")
result = result.replace("<", "&lt;")
result = result.replace(">", "&gt;")
return result
categories = (
(None, Category("General options")),
("game", Category("Game start options")),
("video", Category("Display options")),
("net", Category("Networking options")),
("mod", Category("Dehacked and WAD merging")),
("demo", Category("Demo options")),
("compat", Category("Compatibility")),
("obscure", Category("Obscure and less-used options")),
)
wikipages = []
config_files = {}
# Show options that are in Vanilla Doom? Or only new options?
show_vanilla_options = True
class Parameter:
def __lt__(self, other):
return self.name < other.name
def __init__(self):
self.text = ""
self.name = ""
self.args = None
self.platform = None
self.category = None
self.vanilla_option = False
self.games = None
def should_show(self):
return not self.vanilla_option or show_vanilla_options
def add_text(self, text):
if len(text) <= 0:
pass
elif text[0] == "@":
match = re.match(r'@(\S+)\s*(.*)', text)
if not match:
raise "Malformed option line: %s" % text
option_type = match.group(1)
data = match.group(2)
if option_type == "arg":
self.args = data
elif option_type == "platform":
self.platform = data
elif option_type == "category":
self.category = data
elif option_type == "vanilla":
self.vanilla_option = True
elif option_type == "game":
self.games = re.split(r'\s+', data.strip())
else:
raise "Unknown option type '%s'" % option_type
else:
self.text += text + " "
def _games_only_text(self, pattern="(%s only)"):
if not match_game and self.games:
games_list = ", ".join(map(str.capitalize, self.games))
return " " + (pattern % games_list)
else:
return ""
def manpage_output(self):
if self.args:
# Special cases -- GBR is not proud.
if self.args == "[<x> <y> | <xy>]":
result = ".BR " + self.name + " \\~\\c\n" \
+ ".RI [ x\\~y | xy ]\n"
elif self.args == "<WxH>":
result = ".BI " + self.name + "\\~ W x H\n"
elif self.args == "<x> <y>":
result = ".BI " + self.name + "\\~ \"x y\"\n"
elif self.args == "<files>":
result = ".BI " + self.name + "\\~ \"file\\~\\c\n" \
+ "\\&.\\|.\\|.\n"
elif self.args == "<save-num> <demo-name>":
result = ".BI " + self.name \
+ "\\~ \"save-num demo-name\"\n"
else:
self.args = re.sub(r'[<>]', '', self.args)
result = ".BI " + self.name + "\\~ " + self.args + "\n"
else:
result = ".B " + self.name + "\n"
if self.platform:
result += "[%s only] " % self.platform
escaped = re.sub(r'\\', r'\\\\', self.text)
result += escaped + self._games_only_text() + "\n"
return result
def wiki_output(self):
result = self.name
if self.args:
result += " " + self.args
result += ": "
result += add_wiki_links(self.text)
if self.platform:
result += "'''(%s only)'''" % self.platform
result += self._games_only_text("'''(%s only)'''")
return result
def markdown_output(self):
if self.args:
name = "%s %s" % (self.name, self.args)
else:
name = "%s" % self.name
name = name.replace("|", "\\|")
text = self.text
if self.platform:
text += " (%s only)" % self.platform
text = text.replace("|", "\\|")
result = "| %s | %s |\n" % (name, text)
# html escape
result = result.replace("<", "&lt;")
result = result.replace(">", "&gt;")
return result
def plaintext_output(self, indent):
# Build the first line, with the argument on
start = " " + self.name
if self.args:
start += " " + self.args
# pad up to the plaintext width
start += " " * (indent - len(start))
# Build the description text
description = self.text
if self.platform:
description += " (%s only)" % self.platform
description += self._games_only_text()
# Build the complete text for the argument
# Split the description into words and add a word at a time
result = ""
words = [word for word in re.split(r'\s+', description) if word]
maxlen = TEXT_WRAP_WIDTH - indent
outlines = [[]]
for word in words:
linelen = sum(len(w) + 1 for w in outlines[-1])
if linelen + len(word) > maxlen:
outlines.append([])
outlines[-1].append(word)
linesep = "\n" + " " * indent
return (start +
linesep.join(" ".join(line) for line in outlines) +
"\n\n")
def completion_output(self, w):
result = self.name + " "
return result
# Read list of wiki pages
def read_wikipages():
f = io.open("wikipages", encoding='UTF-8')
try:
for line in f:
line = line.rstrip()
line = re.sub(r'\#.*$', '', line)
if not re.match(r'^\s*$', line):
wikipages.append(line)
finally:
f.close()
# Add wiki page links
def add_wiki_links(text):
def replace_name(m):
linktext = m.group(1)
if linktext == pagename:
return '[[%s]]' % pagename
else:
return '[[%s|%s]]' % (pagename, linktext)
for pagename in wikipages:
text = re.sub(r'\b(%s)\b' % re.escape(pagename), replace_name,
text, count=0, flags=re.IGNORECASE)
return text
def add_parameter(param, line, config_file):
# If we're only targeting a particular game, check this is one of
# the ones we're targeting.
if match_game and param.games and match_game not in param.games:
return
# Is this documenting a command line parameter?
match = re.search(r'(M_CheckParm(WithArgs)|M_ParmExists)?\s*\(\s*"(.*?)"',
line)
if match:
param.name = match.group(3)
category = dict(categories)[param.category]
category.add_param(param)
return
# Documenting a configuration file variable?
match = re.search(r'CONFIG_VARIABLE_\S+\s*\(\s*(\S+?)\),', line)
if match:
param.name = match.group(1)
config_file.add_variable(param)
return
raise Exception(param.text)
def process_file(filename):
current_config_file = None
f = io.open(filename, encoding='UTF-8')
try:
param = None
waiting_for_checkparm = False
for line in f:
line = line.rstrip()
# Ignore empty lines
if re.match(r'\s*$', line):
continue
# Currently reading a doc comment?
if param:
# End of doc comment
if not re.match(r'\s*//', line):
waiting_for_checkparm = True
# The first non-empty line after the documentation comment
# ends must contain the thing being documented.
if waiting_for_checkparm:
add_parameter(param, line, current_config_file)
param = None
else:
# More documentation text
munged_line = re.sub(r'\s*\/\/\s*', '', line, count=1)
munged_line = re.sub(r'\s*$', '', munged_line)
param.add_text(munged_line)
# Check for start of a doc comment
if re.search("//!", line):
match = re.search(r"@begin_config_file\s*(\S+)", line)
if match:
# Beginning a configuration file
tagname = match.group(1)
current_config_file = ConfigFile(tagname)
config_files[tagname] = current_config_file
else:
# Start of a normal comment
param = Parameter()
waiting_for_checkparm = False
finally:
f.close()
def process_files(path):
# Process all C source files.
if os.path.isdir(path):
files = glob.glob(path + "/*.c")
for filename in files:
process_file(filename)
else:
# Special case to allow a single file to be specified as a target
process_file(path)
def print_template(template_file, substs, content):
f = io.open(template_file, encoding='UTF-8')
try:
for line in f:
match = INCLUDE_STATEMENT_RE.search(line)
if match:
filename = match.group(1)
filename = os.path.join(os.path.dirname(template_file),
filename)
print_template(filename, substs, content)
else:
line = line.replace("@content", content)
for k,v in substs.items():
line = line.replace(k,v)
stdout(line.rstrip().encode('UTF-8') + b'\n')
finally:
f.close()
def manpage_output(targets, substs, template_file):
content = ""
for t in targets:
content += t.manpage_output()
content = content.replace("-", "\\-")
print_template(template_file, substs, content)
def wiki_output(targets, _, template):
read_wikipages()
for t in targets:
stdout(t.wiki_output().encode('UTF-8') + b'\n')
def markdown_output(targets, substs, template_file):
content = ""
for t in targets:
content += t.markdown_output() + "\n"
print_template(template_file, substs, content)
def plaintext_output(targets, substs, template_file):
content = ""
for t in targets:
content += t.plaintext_output() + "\n"
print_template(template_file, substs, content)
def completion_output(targets, substs, template_file):
content = ""
for t in targets:
content += t.completion_output() + "\n"
print_template(template_file, substs, content)
def usage():
print("Usage: %s [-V] [-c tag] [-g game] -n program_name -s package_name [ -z shortname ] ( -M | -m | -w | -p ) <dir>..." \
% sys.argv[0])
print(" -c : Provide documentation for the specified configuration file")
print(" (matches the given tag name in the source file)")
print(" -s : Package name, e.g. Chocolate Doom (for substitution)")
print(" -z : Package short-name, e.g. Chocolate (for substitution)")
print(" -v : Package version, e.g. 7.0 (for substitution)")
print(" -n : Program name, e.g. chocolate (for substitution)")
print(" -M : Markdown output")
print(" -m : Manpage output")
print(" -w : Wikitext output")
print(" -p : Plaintext output")
print(" -b : Bash-Completion output")
print(" -V : Don't show Vanilla Doom options")
print(" -g : Only document options for specified game.")
sys.exit(0)
# Parse command line
opts, args = getopt.getopt(sys.argv[1:], "n:s:z:v:M:m:wp:b:c:g:V")
output_function = None
template = None
doc_config_file = None
match_game = None
substs = {}
for opt in opts:
if opt[0] == "-n":
substs["@PROGRAM_SPREFIX@"] = opt[1]
if opt[0] == "-s":
substs["@PACKAGE_NAME@"] = opt[1]
if opt[0] == "-z":
substs["@PACKAGE_SHORTNAME@"] = opt[1]
if opt[0] == "-v":
substs["@VERSION@"] = opt[1]
if opt[0] == "-m":
output_function = manpage_output
template = opt[1]
elif opt[0] == "-M":
output_function = markdown_output
template = opt[1]
elif opt[0] == "-w":
output_function = wiki_output
elif opt[0] == "-p":
output_function = plaintext_output
template = opt[1]
elif opt[0] == "-b":
output_function = completion_output
template = opt[1]
elif opt[0] == "-V":
show_vanilla_options = False
elif opt[0] == "-c":
doc_config_file = opt[1]
elif opt[0] == "-g":
match_game = opt[1]
substs["@GAME@"] = opt[1]
substs["@GAME_UPPER@"] = opt[1].title()
if "doom" == opt[1]:
substs["@CFGFILE@"] = "default.cfg"
else:
substs["@CFGFILE@"] = opt[1] + ".cfg"
if output_function == None or len(args) < 1:
usage()
else:
# Process specified files
for path in args:
process_files(path)
# Build a list of things to document
if doc_config_file:
documentation_targets = [config_files[doc_config_file]]
else:
documentation_targets = [c for _, c in categories]
# Generate the output
output_function(documentation_targets, substs, template)

View file

@ -1,45 +0,0 @@
.TH @PROGRAM_SPREFIX@\-doom 6 2018-01-09 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-doom \- historically compatible Doom engine
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-doom
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_SHORTNAME@ Doom is a port of Id Software's 1993 game
.I Doom
that is designed to behave as similarly to the original DOS version of
Doom as is possible.
@content
.SH IWAD SEARCH PATHS
@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control
@PACKAGE_SHORTNAME@ Doom's behavior.
@include environ.man
.SH FILES
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/default.cfg
The main configuration file for @PACKAGE_NAME@.
See \fBdefault.cfg\fR(5).
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/@PROGRAM_SPREFIX@\-doom.cfg
Extra configuration values that are specific to @PACKAGE_NAME@ and not
present in Vanilla Doom.
See \fB@PROGRAM_SPREFIX@\-doom.cfg\fR(5).
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-server\fR(6),
\fB@PROGRAM_SPREFIX@\-setup\fR(6),
\fB@PROGRAM_SPREFIX@\-heretic\fR(6),
\fB@PROGRAM_SPREFIX@\-hexen\fR(6),
\fB@PROGRAM_SPREFIX@\-strife\fR(6)
.SH AUTHOR
Chocolate Doom is written and maintained by Simon Howard.
It is based on the LinuxDoom source code, released by Id Software.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co 2005-2016 Simon Howard.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,34 +0,0 @@
.TP
.I DOOMWADDIR
.TQ
.I DOOMWADPATH
See section \(lqIWAD SEARCH PATHS\(rq above.
.TP
.I PCSOUND_DRIVER
When running in PC speaker sound effect mode, this environment variable
specifies a PC speaker driver to use for sound effect playback.
Valid options are
.RB \(lq Linux \(rq
for the Linux console mode driver,
.RB \(lq BSD \(rq
for the NetBSD/OpenBSD PC speaker driver,
and
.RB \(lq SDL \(rq
for SDL-based emulated PC speaker playback (using the digital output).
.TP
.I OPL_DRIVER
When using OPL MIDI playback, this environment variable specifies an
OPL backend driver to use.
Valid options are
.RB \(lq SDL \(rq
for an SDL-based software emulated OPL chip,
.RB \(lq Linux \(rq
for the Linux hardware OPL driver,
and
.RB \(lq OpenBSD \(rq
for the OpenBSD/NetBSD hardware OPL driver.
.IP
Generally speaking, a real hardware OPL chip sounds better than software
emulation; however, modern machines do not often include one.
If present, it may still require extra work to set up and elevated
security privileges to access.

View file

@ -1,28 +0,0 @@
.TH @PROGRAM_SPREFIX@\-@GAME@.cfg 5 2024-01-23 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-@GAME@.cfg \- @PACKAGE_SHORTNAME@ @GAME_UPPER@ configuration file
.SH DESCRIPTION
.PP
\fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR
is a configuration file for \fB@PROGRAM_SPREFIX@\-@GAME@\fR(6). This file acts
as an auxiliary configuration file; the main configuration options
are stored in \fB@CFGFILE@\fR, which contains the same configuration
options as Vanilla @GAME_UPPER@ (for compatibility). \fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR
contains configuration options that are specific to @PACKAGE_SHORTNAME@\-@GAME_UPPER@
only.
.PP
\fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR is normally stored in the user's home directory,
as \fI~/.local/share/@PROGRAM_SPREFIX@\-@GAME@/@PROGRAM_SPREFIX@\-@GAME@.cfg\fR. The path can be
overridden using the \fBXDG_DATA_HOME\fR environment variable (see the XDG
Base Directory Specification).
.PP
The \fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6) tool provides a simple to use front-end
for editing \fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR.
.SH FILE FORMAT
.PP
The file format is the same as that used for \fB@CFGFILE@\fR(5).
@content
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-@GAME@\fR(6),
\fB@CFGFILE@\fR(5),
\fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6)

View file

@ -1,47 +0,0 @@
.TH @PROGRAM_SPREFIX@\-heretic 6 2017-11-27 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-heretic \- historically compatible Heretic engine
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-heretic
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_SHORTNAME@ Heretic is a port of Raven Software's 1994 game
.I Heretic
that aims to behave as similar to the original DOS version of Heretic as
possible.
@content
.SH IWAD SEARCH PATHS
@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control
@PACKAGE_SHORTNAME@ Heretic's behavior.
@include environ.man
.SH FILES
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/heretic.cfg
The main configuration file for @PACKAGE_SHORTNAME@ Heretic.
See \fBheretic.cfg\fR(5).
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/@PROGRAM_SPREFIX@\-heretic.cfg
Extra configuration values that are specific to @PACKAGE_SHORTNAME@ Heretic and not
present in Vanilla Heretic.
See \fB@PROGRAM_SPREFIX@\-heretic.cfg\fR(5).
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-doom\fR(6),
\fB@PROGRAM_SPREFIX@\-hexen\fR(6),
\fB@PROGRAM_SPREFIX@\-server\fR(6),
\fB@PROGRAM_SPREFIX@\-setup\fR(6)
.SH AUTHOR
Chocolate Heretic is part of the Chocolate Doom project, written and
maintained by Simon Howard.
It is based on the Heretic source code,
released by Raven Software.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co Raven Software Inc.
Copyright \(co 2005-2013 Simon Howard.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,47 +0,0 @@
.TH @PROGRAM_SPREFIX@\-hexen 6 2017-11-27 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-hexen \- historically compatible Hexen engine
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-hexen
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_SHORTNAME@ Hexen is a port of Raven Software's 1995 game
.I Hexen
that aims to behave as similar to the original DOS version of Hexen as
possible.
@content
.SH IWAD SEARCH PATHS
@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control
@PACKAGE_SHORTNAME@ Hexen's behavior.
@include environ.man
.SH FILES
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/hexen.cfg
The main configuration file for @PACKAGE_SHORTNAME@ Hexen.
See \fBhexen.cfg\fR(5).
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/@PROGRAM_SPREFIX@\-hexen.cfg
Extra configuration values that are specific to @PACKAGE_SHORTNAME@
Hexen and not present in Vanilla Hexen.
See \fB@PROGRAM_SPREFIX@\-hexen.cfg\fR(5).
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-doom\fR(6),
\fB@PROGRAM_SPREFIX@\-heretic\fR(6),
\fB@PROGRAM_SPREFIX@\-server\fR(6),
\fB@PROGRAM_SPREFIX@\-setup\fR(6)
.SH AUTHOR
Chocolate Hexen is part of the Chocolate Doom project, written and
maintained by Simon Howard.
It is based on the Hexen source code,
released by Raven Software.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co Raven Software Inc.
Copyright \(co 2005-2013 Simon Howard.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,73 +0,0 @@
To play, an IWAD file is needed.
This is a large file containing all of the levels, graphics,
sound effects, music and other material that make up the game.
IWAD files are named according to the game; the standard names are:
.TP
.IR doom.wad ,\~\c
.IR doom1.wad ,\~\c
.IR doom2.wad ,\~\c
.IR tnt.wad ,\~\c
.I plutonia.wad
Doom, Doom II, Final Doom
.TP
.IR heretic.wad ,\~\c
.IR hexen.wad ,\~\c
.I strife.wad
Heretic, Hexen and Strife (commercial Doom engine games).
.TP
.IR hacx.wad ,\~\c
.I chex.wad
Hacx and Chex Quest - more obscure games based on the Doom engine.
.TP
.IR freedm.wad ,\~\c
.IR freedoom1.wad ,\~\c
.I freedoom2.wad
The Freedoom open content IWAD files.
.LP
The following directory paths are searched in order to find an IWAD:
.TP
Current working directory
Any IWAD files found in the current working directory will be used in
preference to IWADs found in any other directories.
.TP
.I DOOMWADDIR
This environment variable can be set to contain a path to a single
directory in which to look for IWAD files.
This environment variable is supported by most Doom source ports.
.TP
.I DOOMWADPATH
This environment variable, if set, can contain a colon-separated list of
directories in which to look for IWAD files, or alternatively full paths to
specific IWAD files.
.TP
.I $HOME/.local/share/games/doom
Writeable directory in the user's home directory.
The path can be overridden using the
.I \%XDG_DATA_HOME
environment variable (see the XDG Base Directory Specification).
.TP
.I /usr/local/share/doom
.TQ
.I /usr/local/share/games/doom
.TQ
.I /usr/share/doom
.TQ
.I /usr/share/games/doom
System-wide locations that can be accessed by all users.
The path
.I /usr/share/games/doom
is a standard path that is supported by most Doom source ports.
These paths can be overridden using the
.I \%XDG_DATA_DIRS
environment variable (see the XDG Base Directory Specification).
.LP
The above can be overridden on a one-time basis by using the
.B \-iwad
command line parameter to provide the path to an IWAD file to use.This
parameter can also be used to specify the name of a particular IWAD to use
from one of the above paths.
For example,
.RB \(lq "\-iwad doom.wad" \(rq
will search the above paths for the file
.I doom.wad
to use.

View file

@ -1,55 +0,0 @@
.TH @PROGRAM_SPREFIX@\-server 6 2018-01-15 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-server \- dedicated server for @PROGRAM_SPREFIX@\-doom
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-server
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_NAME@ is a modern Doom engine designed to behave
as similarly to the original Doom game as is possible.
.PP
.I \%@PROGRAM_SPREFIX@\-server
is a dedicated server for @PACKAGE_SHORTNAME@.
It is equivalent to running
\fB@PROGRAM_SPREFIX@-doom\fR(6)
with the
.B \%\-dedicated
option.
.PP
Game options are not specified to the server, which merely acts to
retransmit data between players in the game; parameters for the
game should be specified by the first player to connect to the server,
who is designated the controlling player.
.SH OPTIONS
.TP
.B \-ignoreversion
Ignore version mismatches between the server and the client.
Using this option may cause game desyncs to occur,
or differences in protocol may mean the netgame will simply not function
at all.
.TP
.BI \-port\~ n
Use UDP port
.I n
for communications instead of the default (2342).
.TP
.B \-privateserver
Don't register with the global master server.
.TP
.BI \-servername\~ name
Specify a name for the server.
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@-doom\fR(6),
\fB@PROGRAM_SPREFIX@-setup\fR(6)
.SH AUTHOR
Chocolate Doom is written and maintained by Simon Howard.
.PP
This manual was written by Jonathan Dowland.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co 2005-8 Simon Howard.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,46 +0,0 @@
.TH @PROGRAM_SPREFIX@\-@GAME@-setup 6 2017-11-30 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-@GAME@-setup \- configuration tool for @PROGRAM_SPREFIX@\-@GAME@
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-@GAME@-setup
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_SHORTNAME@ @GAME_UPPER@ is a modern @GAME_UPPER@ engine
designed to behave as similarly to the original @GAME_UPPER@ game as is
possible.
.PP
.I @PROGRAM_SPREFIX@\-@GAME@-setup
is a tool for configuring @PACKAGE_SHORTNAME@ @GAME_UPPER@.
It provides a menu-based interface for the display, joystick, keyboard,
mouse, sound and compatibility settings.
.PP
.I @PROGRAM_SPREFIX@\-@GAME@-setup
can also be used to start and join network games.
.PP
.SH OPTIONS
.TP
.BI \-config\~ file
Load configuration from the specified file,
instead of
.IR @CFGFILE@ .
.TP
.BI \-extraconfig\~ file
Load extra configuration from the specified file,
instead of
.IR @PROGRAM_SPREFIX@\-@GAME@.cfg .
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-@GAME@\fR(6),
\fBdefault.cfg\fR(5),
\fB@PROGRAM_SPREFIX@\-@GAME@.cfg\fR(5)
.SH AUTHOR
Chocolate Doom is written and maintained by Simon Howard.
.PP
This manual was written by Jonathan Dowland.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co 2005-8 Simon Howard.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,228 +0,0 @@
#!/usr/bin/env python3
#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Contributors to the Freedoom project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the freedoom project nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# simple cpp-style preprocessor
#
# Understands most features of the C preprocessor, including:
# #if .. #elif .. #else .. #endif
# - with expressions
# #ifdef
# #define
# #include
#
import collections
import io
import sys
import re
debug = False
defines = collections.defaultdict(lambda: False)
command_re = re.compile(r"\#(\w+)(\s+(.*))?")
include_re = re.compile(r"\s*\"(.*)\"\s*")
define_re = re.compile(r"\s*(\S+)\s*(.*?)\s*$")
def debug_msg(message):
if debug:
sys.stderr.write(message)
# Parse command line options
def parse_cmdline():
for arg in sys.argv[1:]:
if not arg.startswith("-D"):
continue
name = arg[2:]
if '=' in name:
name, value = name.split('=', 1)
else:
value = True
defines[name] = value
def parse_stream(stream):
result = read_block(stream, False)
if result is not None:
raise Exception("Mismatched #if in '%s'" % stream.name)
def parse_file(filename):
f = io.open(filename, encoding='UTF-8')
try:
parse_stream(f)
finally:
f.close()
# Evaluate an expression using Python's eval() function.
def eval_expr(expr):
expr = expr.replace("||", " or ") \
.replace("&&", " and ") \
.replace("!", "not ")
code = compile(expr, "", "eval")
result = eval(code, {}, defines)
return result
# #include
def cmd_include(arg):
# Extract the filename
match = include_re.match(arg)
if not match:
raise Exception("Invalid 'include' command")
filename = match.group(1)
# Open the file and process it
parse_file(filename)
# #define
def cmd_define(arg):
match = define_re.match(arg)
name = match.group(1)
value = match.group(2)
if value == '':
value = True
defines[name] = value
# #undef
def cmd_undef(arg):
if arg in defines:
del defines[arg]
# #ifdef/#ifndef
def cmd_ifdef(arg, command, stream, ignore):
# Get the define name
debug_msg("%s %s >\n" % (command, arg))
# Should we ignore the contents of this block?
sub_ignore = not eval_expr(arg)
if "n" in command:
sub_ignore = not sub_ignore
# Parse the block
result, newarg = read_block(stream, ignore or sub_ignore)
debug_msg("%s %s < (%s)\n" % (command, arg, result))
# There may be a second "else" block to parse:
if result == "else":
debug_msg("%s %s else >\n" % (command, arg))
result, arg = read_block(stream, ignore or (not sub_ignore))
debug_msg("%s %s else < (%s)\n" % (command, arg, result))
if result == "elif":
debug_msg("%s %s elif %s>\n" % (command, arg, newarg))
cmd_ifdef(newarg, "if", stream, ignore or (not sub_ignore))
result = "endif"
# Should end in an endif:
if result != "endif":
raise Exception("'if' block did not end in an 'endif'")
commands = {
"include" : cmd_include,
"define" : cmd_define,
"undef" : cmd_undef,
"if" : cmd_ifdef,
"ifdef" : cmd_ifdef,
"ifn" : cmd_ifdef,
"ifndef" : cmd_ifdef,
}
# Recursive block reading function
# if 'ignore' argument is 1, contents are ignored
def read_block(stream, ignore):
for line in stream:
# Remove newline
line = line[0:-1]
# Check if this line has a command
match = command_re.match(line)
if match:
command = match.group(1)
arg = match.group(3)
if command in ("else", "elif", "endif"):
return (command, arg)
elif command not in commands:
raise Exception("Unknown command: '%s'" % \
command)
# Get the callback function.
func = commands[command]
# Invoke the callback function. #ifdef commands
# are a special case and need extra arguments.
# Other commands are only executed if we are not
# ignoring this block.
if func == cmd_ifdef:
cmd_ifdef(arg, command=command,
stream=stream,
ignore=ignore)
elif not ignore:
func(arg)
else:
if not ignore:
for key, value in defines.items():
if isinstance(value, str):
line = line.replace(key, value)
print(line)
parse_cmdline()
parse_stream(sys.stdin)

View file

@ -1,91 +0,0 @@
.TH @PROGRAM_SPREFIX@\-strife 6 2018-01-15 "@PACKAGE_NAME@ @VERSION@"
.SH NAME
@PROGRAM_SPREFIX@\-strife \- historically compatible Strife engine
.SH SYNOPSIS
.B @PROGRAM_SPREFIX@\-strife
.RI [ options ]
.SH DESCRIPTION
.PP
@PACKAGE_SHORTNAME@ Strife is an accurate and complete recreation of
Rogue Entertainment's
.IR "Strife: Quest for the Sigil" .
It was created through
more than two years of reverse engineering effort with the blessings
of the original programmers of the game;
see section \(lqHISTORY\(rq below.
@content
.SH IWAD SEARCH PATHS
@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control
@PACKAGE_SHORTNAME@ Strife's behavior.
@include environ.man
.SH FILES
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/strife.cfg
The main configuration file for @PACKAGE_SHORTNAME@ Strife.
See \fBstrife.cfg\fR(5).
.TP
.I $HOME/.local/share/@PROGRAM_SPREFIX@\-doom/@PROGRAM_SPREFIX@\-strife.cfg
Extra configuration values that are specific to @PACKAGE_SHORTNAME@
Strife and not present in Vanilla Strife.
See \fB@PROGRAM_SPREFIX@\-strife.cfg\fR(5).
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-doom\fR(6),
\fB@PROGRAM_SPREFIX@\-server\fR(6),
\fB@PROGRAM_SPREFIX@\-setup\fR(6)
.SH HISTORY
The source code for Strife was lost, which means, unlike the code for
all the other commercial games using the Doom engine, it cannot be
released.
The only access we have to the code is the binary executable file.
Reverse engineering tools were employed to disassemble and decompile the
executables, which were cross-referenced against the Linux Doom and
DOS Heretic sources and painstakingly combed over multiple times,
instruction by instruction, to ensure that the resulting
Chocolate-Doom-based executable is as close as possible to the original.
.SH LEGALITY
Reverse engineering is a protected activity so long as the original code
is not used directly in the product.
Due to the vast amount of information lost through the process of
compilation, and the need to refactor large portions of code in order to
eliminate non-portable idioms or to adapt them properly to Chocolate
Doom's framework, the resulting code behaves the same, but is not the
.I same
code.
.PP
In addition, James Monroe and John Carmack have both stated that they
have no objections to the project.
Because they are the original authors of the code, and neither Rogue nor
their publisher, Velocity, Inc., exist any longer as legal entities,
this is effectively legal permission.
.SH BUGS
@PACKAGE_SHORTNAME@ Strife is almost, but not entirely perfect, in
recreating the behavior of Vanilla Strife.
Help us by reporting any discrepancies you might notice between this
executable and the vanilla DOS program.
.PP
However, do
.I not
report any glitch that you can replicate in the vanilla EXE as a bug.
The point of @PACKAGE_SHORTNAME@ Strife, like Chocolate Doom before it,
is to be as bug-compatible with the original game as possible.
Also be aware that some glitches are impossible to compatibly recreate,
and wherever this is the case, @PACKAGE_SHORTNAME@ Strife has erred on
the side of not crashing the program, for example by initializing
pointers to
.I NULL
rather than using them without setting a value first.
.SH AUTHORS
Chocolate Strife is part of the Chocolate Doom project.
It was reverse engineered from the DOS versions of Strife by James Haley
and Samuel Villarreal.
Chocolate Doom was written and maintained by Simon Howard, and is based
on the LinuxDoom source code released by Id Software.
.SH COPYRIGHT
Copyright \(co id Software Inc.
Copyright \(co 2005-2013 Simon Howard, James Haley, Samuel Villarreal.
.PP
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

View file

@ -1,7 +0,0 @@
# This is a list of wiki pages to automatically link to when generating
# wikitext output.
Dehacked
Doom 1.91
Merging
Multiplayer
Three screen mode

View file

@ -1,7 +0,0 @@
Makefile.in
Makefile
.deps
libopl.a
*.rc
tags
TAGS

View file

@ -1,28 +0,0 @@
add_library(opl STATIC
opl_internal.h
opl.c opl.h
opl_linux.c
opl_obsd.c
opl_queue.c opl_queue.h
opl_sdl.c
opl_timer.c opl_timer.h
opl_win32.c
ioperm_sys.c ioperm_sys.h
opl3.c opl3.h)
target_include_directories(opl
INTERFACE "."
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
if (DEFINED EMSCRIPTEN)
if(ENABLE_SDL2_MIXER)
set_target_properties(opl PROPERTIES COMPILE_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
set_target_properties(opl PROPERTIES LINK_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
else()
set_target_properties(opl PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
set_target_properties(opl PROPERTIES LINK_FLAGS "-s USE_SDL=2")
endif()
else()
target_link_libraries(opl SDL2::SDL2)
if(ENABLE_SDL2_MIXER)
target_link_libraries(opl SDL2_mixer::SDL2_mixer)
endif()
endif()

View file

@ -1,21 +0,0 @@
AM_CFLAGS=@SDLMIXER_CFLAGS@
EXTRA_DIST=CMakeLists.txt
SUBDIRS = . examples
noinst_LIBRARIES=libopl.a
libopl_a_SOURCES = \
opl_internal.h \
opl.c opl.h \
opl_linux.c \
opl_obsd.c \
opl_queue.c opl_queue.h \
opl_sdl.c \
opl_timer.c opl_timer.h \
opl_win32.c \
ioperm_sys.c ioperm_sys.h \
opl3.c opl3.h

View file

@ -1,7 +0,0 @@
Makefile.in
Makefile
.deps
droplay
*.exe
tags
TAGS

View file

@ -1,8 +0,0 @@
AM_CFLAGS = -I$(top_srcdir)/opl
noinst_PROGRAMS=droplay
droplay_LDADD = ../libopl.a @LDFLAGS@ @SDL_LIBS@ @SDLMIXER_LIBS@
droplay_SOURCES = droplay.c

View file

@ -1,210 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// Demonstration program for OPL library to play back DRO
// format files.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#include "opl.h"
#define HEADER_STRING "DBRAWOPL"
#define ADLIB_PORT 0x388
void WriteReg(unsigned int reg, unsigned int val)
{
int i;
// This was recorded from an OPL2, but we are probably playing
// back on an OPL3, so we need to enable the original OPL2
// channels. Doom does this already, but other games don't.
if ((reg & 0xf0) == OPL_REGS_FEEDBACK)
{
val |= 0x30;
}
OPL_WritePort(OPL_REGISTER_PORT, reg);
for (i=0; i<6; ++i)
{
OPL_ReadPort(OPL_REGISTER_PORT);
}
OPL_WritePort(OPL_DATA_PORT, val);
for (i=0; i<35; ++i)
{
OPL_ReadPort(OPL_REGISTER_PORT);
}
}
void ClearAllRegs(void)
{
int i;
for (i=0; i<=0xff; ++i)
{
WriteReg(i, 0x00);
}
}
void Init(void)
{
if (SDL_Init(SDL_INIT_TIMER) < 0)
{
fprintf(stderr, "Unable to initialise SDL timer\n");
exit(-1);
}
if (!OPL_Init(ADLIB_PORT))
{
fprintf(stderr, "Unable to initialise OPL layer\n");
exit(-1);
}
}
void Shutdown(void)
{
OPL_Shutdown();
}
struct timer_data
{
int running;
FILE *fstream;
};
void TimerCallback(void *data)
{
struct timer_data *timer_data = data;
int delay;
if (!timer_data->running)
{
return;
}
// Read data until we must make a delay.
for (;;)
{
int reg, val;
// End of file?
if (feof(timer_data->fstream))
{
timer_data->running = 0;
return;
}
reg = fgetc(timer_data->fstream);
val = fgetc(timer_data->fstream);
// Register value of 0 or 1 indicates a delay.
if (reg == 0x00)
{
delay = val;
break;
}
else if (reg == 0x01)
{
val |= (fgetc(timer_data->fstream) << 8);
delay = val;
break;
}
else
{
WriteReg(reg, val);
}
}
// Schedule the next timer callback.
OPL_SetCallback(delay * OPL_MS, TimerCallback, timer_data);
}
void PlayFile(char *filename)
{
struct timer_data timer_data;
int running;
char buf[8];
timer_data.fstream = fopen(filename, "rb");
if (timer_data.fstream == NULL)
{
fprintf(stderr, "Failed to open %s\n", filename);
exit(-1);
}
if (fread(buf, 1, 8, timer_data.fstream) < 8)
{
fprintf(stderr, "failed to read raw OPL header\n");
exit(-1);
}
if (strncmp(buf, HEADER_STRING, 8) != 0)
{
fprintf(stderr, "Raw OPL header not found\n");
exit(-1);
}
fseek(timer_data.fstream, 28, SEEK_SET);
timer_data.running = 1;
// Start callback loop sequence.
OPL_SetCallback(0, TimerCallback, &timer_data);
// Sleep until the playback finishes.
do
{
OPL_Lock();
running = timer_data.running;
OPL_Unlock();
SDL_Delay(100 * OPL_MS);
} while (running);
fclose(timer_data.fstream);
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Usage: %s <filename>\n", argv[0]);
exit(-1);
}
Init();
PlayFile(argv[1]);
ClearAllRegs();
Shutdown();
return 0;
}

View file

@ -1,355 +0,0 @@
//
// Copyright(C) 2002, 2003 Marcel Telka
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// Interface to the ioperm.sys driver, based on code from the
// Cygwin ioperm library.
//
#ifdef _WIN32
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winioctl.h>
#include <errno.h>
#include "ioperm_sys.h"
#define IOPERM_FILE L"\\\\.\\ioperm"
#define IOCTL_IOPERM \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0xA00, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct ioperm_data
{
unsigned long from;
unsigned long num;
int turn_on;
};
// Function pointers for advapi32.dll. This DLL does not exist on
// Windows 9x, so they are dynamically loaded from the DLL at runtime.
// haleyjd 09/09/10: Moved calling conventions into ()'s
static SC_HANDLE (WINAPI *MyOpenSCManagerW)(wchar_t *lpMachineName,
wchar_t *lpDatabaseName,
DWORD dwDesiredAccess) = NULL;
static SC_HANDLE (WINAPI *MyCreateServiceW)(SC_HANDLE hSCManager,
wchar_t *lpServiceName,
wchar_t *lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
wchar_t *lpBinaryPathName,
wchar_t *lpLoadOrderGroup,
LPDWORD lpdwTagId,
wchar_t *lpDependencies,
wchar_t *lpServiceStartName,
wchar_t *lpPassword);
static SC_HANDLE (WINAPI *MyOpenServiceW)(SC_HANDLE hSCManager,
wchar_t *lpServiceName,
DWORD dwDesiredAccess);
static BOOL (WINAPI *MyStartServiceW)(SC_HANDLE hService,
DWORD dwNumServiceArgs,
wchar_t **lpServiceArgVectors);
static BOOL (WINAPI *MyControlService)(SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus);
static BOOL (WINAPI *MyCloseServiceHandle)(SC_HANDLE hSCObject);
static BOOL (WINAPI *MyDeleteService)(SC_HANDLE hService);
static struct
{
char *name;
void **fn;
} dll_functions[] = {
{ "OpenSCManagerW", (void **) &MyOpenSCManagerW },
{ "CreateServiceW", (void **) &MyCreateServiceW },
{ "OpenServiceW", (void **) &MyOpenServiceW },
{ "StartServiceW", (void **) &MyStartServiceW },
{ "ControlService", (void **) &MyControlService },
{ "CloseServiceHandle", (void **) &MyCloseServiceHandle },
{ "DeleteService", (void **) &MyDeleteService },
};
// Globals
static SC_HANDLE scm = NULL;
static SC_HANDLE svc = NULL;
static int service_was_created = 0;
static int service_was_started = 0;
static int LoadLibraryPointers(void)
{
HMODULE dll;
int i;
// Already loaded?
if (MyOpenSCManagerW != NULL)
{
return 1;
}
dll = LoadLibraryW(L"advapi32.dll");
if (dll == NULL)
{
fprintf(stderr, "LoadLibraryPointers: Failed to open advapi32.dll\n");
return 0;
}
for (i = 0; i < sizeof(dll_functions) / sizeof(*dll_functions); ++i)
{
*dll_functions[i].fn = GetProcAddress(dll, dll_functions[i].name);
if (*dll_functions[i].fn == NULL)
{
fprintf(stderr, "LoadLibraryPointers: Failed to get address "
"for '%s'\n", dll_functions[i].name);
return 0;
}
}
return 1;
}
int IOperm_EnablePortRange(unsigned int from, unsigned int num, int turn_on)
{
HANDLE h;
struct ioperm_data ioperm_data;
DWORD BytesReturned;
BOOL r;
h = CreateFileW(IOPERM_FILE, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
{
errno = ENODEV;
return -1;
}
ioperm_data.from = from;
ioperm_data.num = num;
ioperm_data.turn_on = turn_on;
r = DeviceIoControl(h, IOCTL_IOPERM,
&ioperm_data, sizeof ioperm_data,
NULL, 0,
&BytesReturned, NULL);
if (!r)
{
errno = EPERM;
}
CloseHandle(h);
return r != 0;
}
// Load ioperm.sys driver.
// Returns 1 for success, 0 for failure.
// Remember to call IOperm_UninstallDriver to uninstall the driver later.
int IOperm_InstallDriver(void)
{
wchar_t driver_path[MAX_PATH];
int error;
int result = 1;
if (!LoadLibraryPointers())
{
return 0;
}
scm = MyOpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (scm == NULL)
{
error = GetLastError();
fprintf(stderr, "IOperm_InstallDriver: OpenSCManager failed (%i).\n",
error);
return 0;
}
// Get the full path to the driver file.
GetFullPathNameW(L"ioperm.sys", MAX_PATH, driver_path, NULL);
// Create the service.
svc = MyCreateServiceW(scm,
L"ioperm",
L"ioperm support for Cygwin driver",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
driver_path,
NULL,
NULL,
NULL,
NULL,
NULL);
if (svc == NULL)
{
error = GetLastError();
if (error != ERROR_SERVICE_EXISTS)
{
fprintf(stderr,
"IOperm_InstallDriver: Failed to create service (%i).\n",
error);
}
else
{
svc = MyOpenServiceW(scm, L"ioperm", SERVICE_ALL_ACCESS);
if (svc == NULL)
{
error = GetLastError();
fprintf(stderr,
"IOperm_InstallDriver: Failed to open service (%i).\n",
error);
}
}
if (svc == NULL)
{
MyCloseServiceHandle(scm);
return 0;
}
}
else
{
service_was_created = 1;
}
// Start the service. If the service already existed, it might have
// already been running as well.
if (!MyStartServiceW(svc, 0, NULL))
{
error = GetLastError();
if (error != ERROR_SERVICE_ALREADY_RUNNING)
{
fprintf(stderr, "IOperm_InstallDriver: Failed to start service (%i).\n",
error);
result = 0;
}
else
{
printf("IOperm_InstallDriver: ioperm driver already running.\n");
}
}
else
{
printf("IOperm_InstallDriver: ioperm driver installed.\n");
service_was_started = 1;
}
// If we failed to start the driver running, we need to clean up
// before finishing.
if (result == 0)
{
IOperm_UninstallDriver();
}
return result;
}
int IOperm_UninstallDriver(void)
{
SERVICE_STATUS stat;
int result = 1;
int error;
// If we started the service, stop it.
if (service_was_started)
{
if (!MyControlService(svc, SERVICE_CONTROL_STOP, &stat))
{
error = GetLastError();
if (error == ERROR_SERVICE_NOT_ACTIVE)
{
fprintf(stderr,
"IOperm_UninstallDriver: Service not active? (%i)\n",
error);
}
else
{
fprintf(stderr,
"IOperm_UninstallDriver: Failed to stop service (%i).\n",
error);
result = 0;
}
}
}
// If we created the service, delete it.
if (service_was_created)
{
if (!MyDeleteService(svc))
{
error = GetLastError();
fprintf(stderr,
"IOperm_UninstallDriver: DeleteService failed (%i).\n",
error);
result = 0;
}
else if (service_was_started)
{
printf("IOperm_UnInstallDriver: ioperm driver uninstalled.\n");
}
}
// Close handles.
if (svc != NULL)
{
MyCloseServiceHandle(svc);
svc = NULL;
}
if (scm != NULL)
{
MyCloseServiceHandle(scm);
scm = NULL;
}
service_was_created = 0;
service_was_started = 0;
return result;
}
#endif /* #ifndef _WIN32 */

View file

@ -1,28 +0,0 @@
//
// Copyright(C) 2002, 2003 Marcel Telka
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// Interface to the ioperm.sys driver, based on code from the
// Cygwin ioperm library.
//
#ifndef IOPERM_SYS_H
#define IOPERM_SYS_H
int IOperm_EnablePortRange(unsigned int from, unsigned int num, int turn_on);
int IOperm_InstallDriver(void);
int IOperm_UninstallDriver(void);
#endif /* #ifndef IOPERM_SYS_H */

View file

@ -1,530 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL interface.
//
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#include "opl.h"
#include "opl_internal.h"
//#define OPL_DEBUG_TRACE
#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif
static opl_driver_t *drivers[] =
{
#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IOPERM)
&opl_linux_driver,
#endif
#if defined(HAVE_LIBI386) || defined(HAVE_LIBAMD64)
&opl_openbsd_driver,
#endif
#ifdef _WIN32
&opl_win32_driver,
#endif
#ifndef DISABLE_SDL2MIXER
&opl_sdl_driver,
#endif // DISABLE_SDL2MIXER
NULL
};
static opl_driver_t *driver = NULL;
static int init_stage_reg_writes = 1;
unsigned int opl_sample_rate = 22050;
//
// Init/shutdown code.
//
// Initialize the specified driver and detect an OPL chip. Returns
// true if an OPL is detected.
static opl_init_result_t InitDriver(opl_driver_t *_driver,
unsigned int port_base)
{
opl_init_result_t result1, result2;
// Initialize the driver.
if (!_driver->init_func(port_base))
{
return OPL_INIT_NONE;
}
// The driver was initialized okay, so we now have somewhere
// to write to. It doesn't mean there's an OPL chip there,
// though. Perform the detection sequence to make sure.
// (it's done twice, like how Doom does it).
driver = _driver;
init_stage_reg_writes = 1;
result1 = OPL_Detect();
result2 = OPL_Detect();
if (result1 == OPL_INIT_NONE || result2 == OPL_INIT_NONE)
{
printf("OPL_Init: No OPL detected using '%s' driver.\n", _driver->name);
_driver->shutdown_func();
driver = NULL;
return OPL_INIT_NONE;
}
init_stage_reg_writes = 0;
printf("OPL_Init: Using driver '%s'.\n", driver->name);
return result2;
}
// Find a driver automatically by trying each in the list.
static opl_init_result_t AutoSelectDriver(unsigned int port_base)
{
int i;
opl_init_result_t result;
for (i = 0; drivers[i] != NULL; ++i)
{
result = InitDriver(drivers[i], port_base);
if (result != OPL_INIT_NONE)
{
return result;
}
}
printf("OPL_Init: Failed to find a working driver.\n");
return OPL_INIT_NONE;
}
// Initialize the OPL library. Return value indicates type of OPL chip
// detected, if any.
opl_init_result_t OPL_Init(unsigned int port_base)
{
char *driver_name;
int i;
int result;
driver_name = getenv("OPL_DRIVER");
if (driver_name != NULL)
{
// Search the list until we find the driver with this name.
for (i=0; drivers[i] != NULL; ++i)
{
if (!strcmp(driver_name, drivers[i]->name))
{
result = InitDriver(drivers[i], port_base);
if (result)
{
return result;
}
else
{
printf("OPL_Init: Failed to initialize "
"driver: '%s'.\n", driver_name);
return OPL_INIT_NONE;
}
}
}
printf("OPL_Init: unknown driver: '%s'.\n", driver_name);
return OPL_INIT_NONE;
}
else
{
return AutoSelectDriver(port_base);
}
}
// Shut down the OPL library.
void OPL_Shutdown(void)
{
if (driver != NULL)
{
driver->shutdown_func();
driver = NULL;
}
}
// Set the sample rate used for software OPL emulation.
void OPL_SetSampleRate(unsigned int rate)
{
opl_sample_rate = rate;
}
void OPL_WritePort(opl_port_t port, unsigned int value)
{
if (driver != NULL)
{
#ifdef OPL_DEBUG_TRACE
printf("OPL_write: %i, %x\n", port, value);
fflush(stdout);
#endif
driver->write_port_func(port, value);
}
}
unsigned int OPL_ReadPort(opl_port_t port)
{
if (driver != NULL)
{
unsigned int result;
#ifdef OPL_DEBUG_TRACE
printf("OPL_read: %i...\n", port);
fflush(stdout);
#endif
result = driver->read_port_func(port);
#ifdef OPL_DEBUG_TRACE
printf("OPL_read: %i -> %x\n", port, result);
fflush(stdout);
#endif
return result;
}
else
{
return 0;
}
}
//
// Higher-level functions, based on the lower-level functions above
// (register write, etc).
//
unsigned int OPL_ReadStatus(void)
{
return OPL_ReadPort(OPL_REGISTER_PORT);
}
// Write an OPL register value
void OPL_WriteRegister(int reg, int value)
{
int i;
if (reg & 0x100)
{
OPL_WritePort(OPL_REGISTER_PORT_OPL3, reg);
}
else
{
OPL_WritePort(OPL_REGISTER_PORT, reg);
}
// For timing, read the register port six times after writing the
// register number to cause the appropriate delay
for (i=0; i<6; ++i)
{
// An oddity of the Doom OPL code: at startup initialization,
// the spacing here is performed by reading from the register
// port; after initialization, the data port is read, instead.
if (init_stage_reg_writes)
{
OPL_ReadPort(OPL_REGISTER_PORT);
}
else
{
OPL_ReadPort(OPL_DATA_PORT);
}
}
OPL_WritePort(OPL_DATA_PORT, value);
// Read the register port 24 times after writing the value to
// cause the appropriate delay
for (i=0; i<24; ++i)
{
OPL_ReadStatus();
}
}
// Detect the presence of an OPL chip
opl_init_result_t OPL_Detect(void)
{
int result1, result2;
int i;
// Reset both timers:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x60);
// Enable interrupts:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x80);
// Read status
result1 = OPL_ReadStatus();
// Set timer:
OPL_WriteRegister(OPL_REG_TIMER1, 0xff);
// Start timer 1:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x21);
// Wait for 80 microseconds
// This is how Doom does it:
for (i=0; i<200; ++i)
{
OPL_ReadStatus();
}
OPL_Delay(1 * OPL_MS);
// Read status
result2 = OPL_ReadStatus();
// Reset both timers:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x60);
// Enable interrupts:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x80);
if ((result1 & 0xe0) == 0x00 && (result2 & 0xe0) == 0xc0)
{
result1 = OPL_ReadPort(OPL_REGISTER_PORT);
result2 = OPL_ReadPort(OPL_REGISTER_PORT_OPL3);
if (result1 == 0x00)
{
return OPL_INIT_OPL3;
}
else
{
return OPL_INIT_OPL2;
}
}
else
{
return OPL_INIT_NONE;
}
}
// Initialize registers on startup
void OPL_InitRegisters(int opl3)
{
int r;
// Initialize level registers
for (r=OPL_REGS_LEVEL; r <= OPL_REGS_LEVEL + OPL_NUM_OPERATORS; ++r)
{
OPL_WriteRegister(r, 0x3f);
}
// Initialize other registers
// These two loops write to registers that actually don't exist,
// but this is what Doom does ...
// Similarly, the <= is also intenational.
for (r=OPL_REGS_ATTACK; r <= OPL_REGS_WAVEFORM + OPL_NUM_OPERATORS; ++r)
{
OPL_WriteRegister(r, 0x00);
}
// More registers ...
for (r=1; r < OPL_REGS_LEVEL; ++r)
{
OPL_WriteRegister(r, 0x00);
}
// Re-initialize the low registers:
// Reset both timers and enable interrupts:
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x60);
OPL_WriteRegister(OPL_REG_TIMER_CTRL, 0x80);
// "Allow FM chips to control the waveform of each operator":
OPL_WriteRegister(OPL_REG_WAVEFORM_ENABLE, 0x20);
if (opl3)
{
OPL_WriteRegister(OPL_REG_NEW, 0x01);
// Initialize level registers
for (r=OPL_REGS_LEVEL; r <= OPL_REGS_LEVEL + OPL_NUM_OPERATORS; ++r)
{
OPL_WriteRegister(r | 0x100, 0x3f);
}
// Initialize other registers
// These two loops write to registers that actually don't exist,
// but this is what Doom does ...
// Similarly, the <= is also intenational.
for (r=OPL_REGS_ATTACK; r <= OPL_REGS_WAVEFORM + OPL_NUM_OPERATORS; ++r)
{
OPL_WriteRegister(r | 0x100, 0x00);
}
// More registers ...
for (r=1; r < OPL_REGS_LEVEL; ++r)
{
OPL_WriteRegister(r | 0x100, 0x00);
}
}
// Keyboard split point on (?)
OPL_WriteRegister(OPL_REG_FM_MODE, 0x40);
if (opl3)
{
OPL_WriteRegister(OPL_REG_NEW, 0x01);
}
}
//
// Timer functions.
//
void OPL_SetCallback(uint64_t us, opl_callback_t callback, void *data)
{
if (driver != NULL)
{
driver->set_callback_func(us, callback, data);
}
}
void OPL_ClearCallbacks(void)
{
if (driver != NULL)
{
driver->clear_callbacks_func();
}
}
void OPL_Lock(void)
{
if (driver != NULL)
{
driver->lock_func();
}
}
void OPL_Unlock(void)
{
if (driver != NULL)
{
driver->unlock_func();
}
}
typedef struct
{
int finished;
SDL_mutex *mutex;
SDL_cond *cond;
} delay_data_t;
static void DelayCallback(void *_delay_data)
{
delay_data_t *delay_data = _delay_data;
SDL_LockMutex(delay_data->mutex);
delay_data->finished = 1;
SDL_CondSignal(delay_data->cond);
SDL_UnlockMutex(delay_data->mutex);
}
// Delay for specified number of microseconds after OPL subsystem is initialized
void OPL_Delay(uint64_t us)
{
delay_data_t delay_data;
if (driver == NULL)
{
return;
}
// Create a callback that will signal this thread after the
// specified time.
// Note that this is not just a simple time-based delay, it will ensure
// that the OPL system is initialized and the queue has begun processing
// before releasing the mutex lock
delay_data.finished = 0;
delay_data.mutex = SDL_CreateMutex();
delay_data.cond = SDL_CreateCond();
OPL_SetCallback(us, DelayCallback, &delay_data);
// Wait until the callback is invoked.
SDL_LockMutex(delay_data.mutex);
while (!delay_data.finished)
{
SDL_CondWait(delay_data.cond, delay_data.mutex);
#ifdef EMSCRIPTEN
// Use async sleep to avoid locking browser main thread
emscripten_sleep(us / 1000);
#endif
}
SDL_UnlockMutex(delay_data.mutex);
// Clean up.
SDL_DestroyMutex(delay_data.mutex);
SDL_DestroyCond(delay_data.cond);
}
void OPL_SetPaused(int paused)
{
if (driver != NULL)
{
driver->set_paused_func(paused);
}
}
void OPL_AdjustCallbacks(float value)
{
if (driver != NULL)
{
driver->adjust_callbacks_func(value);
}
}

View file

@ -1,153 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL interface.
//
#ifndef OPL_OPL_H
#define OPL_OPL_H
#include <inttypes.h>
typedef void (*opl_callback_t)(void *data);
// Result from OPL_Init(), indicating what type of OPL chip was detected,
// if any.
typedef enum
{
OPL_INIT_NONE,
OPL_INIT_OPL2,
OPL_INIT_OPL3,
} opl_init_result_t;
typedef enum
{
OPL_REGISTER_PORT = 0,
OPL_DATA_PORT = 1,
OPL_REGISTER_PORT_OPL3 = 2
} opl_port_t;
#define OPL_NUM_OPERATORS 21
#define OPL_NUM_VOICES 9
#define OPL_REG_WAVEFORM_ENABLE 0x01
#define OPL_REG_TIMER1 0x02
#define OPL_REG_TIMER2 0x03
#define OPL_REG_TIMER_CTRL 0x04
#define OPL_REG_FM_MODE 0x08
#define OPL_REG_NEW 0x105
// Operator registers (21 of each):
#define OPL_REGS_TREMOLO 0x20
#define OPL_REGS_LEVEL 0x40
#define OPL_REGS_ATTACK 0x60
#define OPL_REGS_SUSTAIN 0x80
#define OPL_REGS_WAVEFORM 0xE0
// Voice registers (9 of each):
#define OPL_REGS_FREQ_1 0xA0
#define OPL_REGS_FREQ_2 0xB0
#define OPL_REGS_FEEDBACK 0xC0
// Times
#define OPL_SECOND ((uint64_t) 1000 * 1000)
#define OPL_MS ((uint64_t) 1000)
#define OPL_US ((uint64_t) 1)
//
// Low-level functions.
//
// Initialize the OPL subsystem.
opl_init_result_t OPL_Init(unsigned int port_base);
// Shut down the OPL subsystem.
void OPL_Shutdown(void);
// Set the sample rate used for software emulation.
void OPL_SetSampleRate(unsigned int rate);
// Write to one of the OPL I/O ports:
void OPL_WritePort(opl_port_t port, unsigned int value);
// Read from one of the OPL I/O ports:
unsigned int OPL_ReadPort(opl_port_t port);
//
// Higher-level functions.
//
// Read the cuurrent status byte of the OPL chip.
unsigned int OPL_ReadStatus(void);
// Write to an OPL register.
void OPL_WriteRegister(int reg, int value);
// Perform a detection sequence to determine that an
// OPL chip is present.
opl_init_result_t OPL_Detect(void);
// Initialize all registers, performed on startup.
void OPL_InitRegisters(int opl3);
//
// Timer callback functions.
//
// Set a timer callback. After the specified number of microseconds
// have elapsed, the callback will be invoked.
void OPL_SetCallback(uint64_t us, opl_callback_t callback, void *data);
// Adjust callback times by the specified factor. For example, a value of
// 0.5 will halve all remaining times.
void OPL_AdjustCallbacks(float factor);
// Clear all OPL callbacks that have been set.
void OPL_ClearCallbacks(void);
// Begin critical section, during which, OPL callbacks will not be
// invoked.
void OPL_Lock(void);
// End critical section.
void OPL_Unlock(void);
// Block until the specified number of microseconds have elapsed.
void OPL_Delay(uint64_t us);
// Pause the OPL callbacks.
void OPL_SetPaused(int paused);
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,150 +0,0 @@
//
// Copyright (C) 2013-2018 Alexey Khokholov (Nuke.YKT)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// Nuked OPL3 emulator.
// Thanks:
// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh):
// Feedback and Rhythm part calculation information.
// forums.submarine.org.uk(carbon14, opl3):
// Tremolo and phase generator calculation information.
// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
// OPL2 ROMs.
// siliconpr0n.org(John McMaster, digshadow):
// YMF262 and VRC VII decaps and die shots.
//
// version: 1.8
//
#ifndef OPL_OPL3_H
#define OPL_OPL3_H
#include <inttypes.h>
#define OPL_WRITEBUF_SIZE 1024
#define OPL_WRITEBUF_DELAY 2
typedef uintptr_t Bitu;
typedef intptr_t Bits;
typedef uint64_t Bit64u;
typedef int64_t Bit64s;
typedef uint32_t Bit32u;
typedef int32_t Bit32s;
typedef uint16_t Bit16u;
typedef int16_t Bit16s;
typedef uint8_t Bit8u;
typedef int8_t Bit8s;
typedef struct _opl3_slot opl3_slot;
typedef struct _opl3_channel opl3_channel;
typedef struct _opl3_chip opl3_chip;
struct _opl3_slot {
opl3_channel *channel;
opl3_chip *chip;
Bit16s out;
Bit16s fbmod;
Bit16s *mod;
Bit16s prout;
Bit16s eg_rout;
Bit16s eg_out;
Bit8u eg_inc;
Bit8u eg_gen;
Bit8u eg_rate;
Bit8u eg_ksl;
Bit8u *trem;
Bit8u reg_vib;
Bit8u reg_type;
Bit8u reg_ksr;
Bit8u reg_mult;
Bit8u reg_ksl;
Bit8u reg_tl;
Bit8u reg_ar;
Bit8u reg_dr;
Bit8u reg_sl;
Bit8u reg_rr;
Bit8u reg_wf;
Bit8u key;
Bit32u pg_reset;
Bit32u pg_phase;
Bit16u pg_phase_out;
Bit8u slot_num;
};
struct _opl3_channel {
opl3_slot *slots[2];
opl3_channel *pair;
opl3_chip *chip;
Bit16s *out[4];
Bit8u chtype;
Bit16u f_num;
Bit8u block;
Bit8u fb;
Bit8u con;
Bit8u alg;
Bit8u ksv;
Bit16u cha, chb;
Bit8u ch_num;
};
typedef struct _opl3_writebuf {
Bit64u time;
Bit16u reg;
Bit8u data;
} opl3_writebuf;
struct _opl3_chip {
opl3_channel channel[18];
opl3_slot slot[36];
Bit16u timer;
Bit64u eg_timer;
Bit8u eg_timerrem;
Bit8u eg_state;
Bit8u eg_add;
Bit8u newm;
Bit8u nts;
Bit8u rhy;
Bit8u vibpos;
Bit8u vibshift;
Bit8u tremolo;
Bit8u tremolopos;
Bit8u tremoloshift;
Bit32u noise;
Bit16s zeromod;
Bit32s mixbuff[2];
Bit8u rm_hh_bit2;
Bit8u rm_hh_bit3;
Bit8u rm_hh_bit7;
Bit8u rm_hh_bit8;
Bit8u rm_tc_bit3;
Bit8u rm_tc_bit5;
//OPL3L
Bit32s rateratio;
Bit32s samplecnt;
Bit16s oldsamples[2];
Bit16s samples[2];
Bit64u writebuf_samplecnt;
Bit32u writebuf_cur;
Bit32u writebuf_last;
Bit64u writebuf_lasttime;
opl3_writebuf writebuf[OPL_WRITEBUF_SIZE];
};
void OPL3_Generate(opl3_chip *chip, Bit16s *buf);
void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf);
void OPL3_Reset(opl3_chip *chip, Bit32u samplerate);
void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v);
void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v);
void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples);
#endif

View file

@ -1,71 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL internal interface.
//
#ifndef OPL_INTERNAL_H
#define OPL_INTERNAL_H
#include "opl.h"
typedef int (*opl_init_func)(unsigned int port_base);
typedef void (*opl_shutdown_func)(void);
typedef unsigned int (*opl_read_port_func)(opl_port_t port);
typedef void (*opl_write_port_func)(opl_port_t port, unsigned int value);
typedef void (*opl_set_callback_func)(uint64_t us,
opl_callback_t callback,
void *data);
typedef void (*opl_clear_callbacks_func)(void);
typedef void (*opl_lock_func)(void);
typedef void (*opl_unlock_func)(void);
typedef void (*opl_set_paused_func)(int paused);
typedef void (*opl_adjust_callbacks_func)(float value);
typedef struct
{
const char *name;
opl_init_func init_func;
opl_shutdown_func shutdown_func;
opl_read_port_func read_port_func;
opl_write_port_func write_port_func;
opl_set_callback_func set_callback_func;
opl_clear_callbacks_func clear_callbacks_func;
opl_lock_func lock_func;
opl_unlock_func unlock_func;
opl_set_paused_func set_paused_func;
opl_adjust_callbacks_func adjust_callbacks_func;
} opl_driver_t;
// Sample rate to use when doing software emulation.
extern unsigned int opl_sample_rate;
#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IOPERM)
extern opl_driver_t opl_linux_driver;
#endif
#if defined(HAVE_LIBI386) || defined(HAVE_LIBAMD64)
extern opl_driver_t opl_openbsd_driver;
#endif
#ifdef _WIN32
extern opl_driver_t opl_win32_driver;
#endif
extern opl_driver_t opl_sdl_driver;
#endif /* #ifndef OPL_INTERNAL_H */

View file

@ -1,103 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL Linux interface.
//
#include "config.h"
#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IOPERM)
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/io.h>
#include "opl.h"
#include "opl_internal.h"
#include "opl_timer.h"
static unsigned int opl_port_base;
static int OPL_Linux_Init(unsigned int port_base)
{
// Try to get permissions:
if (ioperm(port_base, 3, 1) < 0)
{
fprintf(stderr, "Failed to get I/O port permissions for 0x%x: %s\n",
port_base, strerror(errno));
if (errno == EPERM)
{
fprintf(stderr,
"\tYou may need to run the program as root in order\n"
"\tto acquire I/O port permissions for OPL MIDI playback.\n");
}
return 0;
}
opl_port_base = port_base;
// Start callback thread
if (!OPL_Timer_StartThread())
{
ioperm(port_base, 2, 0);
return 0;
}
return 1;
}
static void OPL_Linux_Shutdown(void)
{
// Stop callback thread
OPL_Timer_StopThread();
// Release permissions
ioperm(opl_port_base, 2, 0);
}
static unsigned int OPL_Linux_PortRead(opl_port_t port)
{
return inb(opl_port_base + port);
}
static void OPL_Linux_PortWrite(opl_port_t port, unsigned int value)
{
outb(value, opl_port_base + port);
}
opl_driver_t opl_linux_driver =
{
"Linux",
OPL_Linux_Init,
OPL_Linux_Shutdown,
OPL_Linux_PortRead,
OPL_Linux_PortWrite,
OPL_Timer_SetCallback,
OPL_Timer_ClearCallbacks,
OPL_Timer_Lock,
OPL_Timer_Unlock,
OPL_Timer_SetPaused,
OPL_Timer_AdjustCallbacks,
};
#endif /* #if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IOPERM) */

View file

@ -1,118 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL OpenBSD interface (also NetBSD)
//
#include "config.h"
// OpenBSD has a i386_iopl on i386 and amd64_iopl on x86_64,
// even though they do the same thing. Take care of this
// here, and map set_iopl to point to the appropriate name.
#if defined(HAVE_LIBI386)
#include <sys/types.h>
#include <machine/sysarch.h>
#include <i386/pio.h>
#define set_iopl i386_iopl
#elif defined(HAVE_LIBAMD64)
#include <sys/types.h>
#include <machine/sysarch.h>
#include <amd64/pio.h>
#define set_iopl amd64_iopl
#else
#define NO_OBSD_DRIVER
#endif
// If the above succeeded, proceed with the rest.
#ifndef NO_OBSD_DRIVER
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "opl.h"
#include "opl_internal.h"
#include "opl_timer.h"
static unsigned int opl_port_base;
static int OPL_OpenBSD_Init(unsigned int port_base)
{
// Try to get permissions:
if (set_iopl(3) < 0)
{
fprintf(stderr, "Failed to get raise I/O privilege level: "
"check that you are running as root.\n");
return 0;
}
opl_port_base = port_base;
// Start callback thread
if (!OPL_Timer_StartThread())
{
set_iopl(0);
return 0;
}
return 1;
}
static void OPL_OpenBSD_Shutdown(void)
{
// Stop callback thread
OPL_Timer_StopThread();
// Release I/O port permissions:
set_iopl(0);
}
static unsigned int OPL_OpenBSD_PortRead(opl_port_t port)
{
return inb(opl_port_base + port);
}
static void OPL_OpenBSD_PortWrite(opl_port_t port, unsigned int value)
{
outb(opl_port_base + port, value);
}
opl_driver_t opl_openbsd_driver =
{
"OpenBSD",
OPL_OpenBSD_Init,
OPL_OpenBSD_Shutdown,
OPL_OpenBSD_PortRead,
OPL_OpenBSD_PortWrite,
OPL_Timer_SetCallback,
OPL_Timer_ClearCallbacks,
OPL_Timer_Lock,
OPL_Timer_Unlock,
OPL_Timer_SetPaused,
OPL_Timer_AdjustCallbacks,
};
#endif /* #ifndef NO_OBSD_DRIVER */

View file

@ -1,285 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// Queue of waiting callbacks, stored in a binary min heap, so that we
// can always get the first callback.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "opl_queue.h"
#define MAX_OPL_QUEUE 64
typedef struct
{
opl_callback_t callback;
void *data;
uint64_t time;
} opl_queue_entry_t;
struct opl_callback_queue_s
{
opl_queue_entry_t entries[MAX_OPL_QUEUE];
unsigned int num_entries;
};
opl_callback_queue_t *OPL_Queue_Create(void)
{
opl_callback_queue_t *queue;
queue = malloc(sizeof(opl_callback_queue_t));
queue->num_entries = 0;
return queue;
}
void OPL_Queue_Destroy(opl_callback_queue_t *queue)
{
free(queue);
}
int OPL_Queue_IsEmpty(opl_callback_queue_t *queue)
{
return queue->num_entries == 0;
}
void OPL_Queue_Clear(opl_callback_queue_t *queue)
{
queue->num_entries = 0;
}
void OPL_Queue_Push(opl_callback_queue_t *queue,
opl_callback_t callback, void *data,
uint64_t time)
{
int entry_id;
int parent_id;
if (queue->num_entries >= MAX_OPL_QUEUE)
{
fprintf(stderr, "OPL_Queue_Push: Exceeded maximum callbacks\n");
return;
}
// Add to last queue entry.
entry_id = queue->num_entries;
++queue->num_entries;
// Shift existing entries down in the heap.
while (entry_id > 0)
{
parent_id = (entry_id - 1) / 2;
// Is the heap condition satisfied?
if (time >= queue->entries[parent_id].time)
{
break;
}
// Move the existing entry down in the heap.
memcpy(&queue->entries[entry_id],
&queue->entries[parent_id],
sizeof(opl_queue_entry_t));
// Advance to the parent.
entry_id = parent_id;
}
// Insert new callback data.
queue->entries[entry_id].callback = callback;
queue->entries[entry_id].data = data;
queue->entries[entry_id].time = time;
}
int OPL_Queue_Pop(opl_callback_queue_t *queue,
opl_callback_t *callback, void **data)
{
opl_queue_entry_t *entry;
int child1, child2;
int i, next_i;
// Empty?
if (queue->num_entries <= 0)
{
return 0;
}
// Store the result:
*callback = queue->entries[0].callback;
*data = queue->entries[0].data;
// Decrease the heap size, and keep pointer to the last entry in
// the heap, which must now be percolated down from the top.
--queue->num_entries;
entry = &queue->entries[queue->num_entries];
// Percolate down.
i = 0;
for (;;)
{
child1 = i * 2 + 1;
child2 = i * 2 + 2;
if (child1 < queue->num_entries
&& queue->entries[child1].time < entry->time)
{
// Left child is less than entry.
// Use the minimum of left and right children.
if (child2 < queue->num_entries
&& queue->entries[child2].time < queue->entries[child1].time)
{
next_i = child2;
}
else
{
next_i = child1;
}
}
else if (child2 < queue->num_entries
&& queue->entries[child2].time < entry->time)
{
// Right child is less than entry. Go down the right side.
next_i = child2;
}
else
{
// Finished percolating.
break;
}
// Percolate the next value up and advance.
memcpy(&queue->entries[i],
&queue->entries[next_i],
sizeof(opl_queue_entry_t));
i = next_i;
}
// Store the old last-entry at its new position.
memcpy(&queue->entries[i], entry, sizeof(opl_queue_entry_t));
return 1;
}
uint64_t OPL_Queue_Peek(opl_callback_queue_t *queue)
{
if (queue->num_entries > 0)
{
return queue->entries[0].time;
}
else
{
return 0;
}
}
void OPL_Queue_AdjustCallbacks(opl_callback_queue_t *queue,
uint64_t time, float factor)
{
int64_t offset;
int i;
for (i = 0; i < queue->num_entries; ++i)
{
offset = queue->entries[i].time - time;
queue->entries[i].time = time + (uint64_t) (offset / factor);
}
}
#ifdef TEST
#include <assert.h>
static void PrintQueueNode(opl_callback_queue_t *queue, int node, int depth)
{
int i;
if (node >= queue->num_entries)
{
return;
}
for (i=0; i<depth * 3; ++i)
{
printf(" ");
}
printf("%i\n", queue->entries[node].time);
PrintQueueNode(queue, node * 2 + 1, depth + 1);
PrintQueueNode(queue, node * 2 + 2, depth + 1);
}
static void PrintQueue(opl_callback_queue_t *queue)
{
PrintQueueNode(queue, 0, 0);
}
int main()
{
opl_callback_queue_t *queue;
int iteration;
queue = OPL_Queue_Create();
for (iteration=0; iteration<5000; ++iteration)
{
opl_callback_t callback;
void *data;
unsigned int time;
unsigned int newtime;
int i;
for (i=0; i<MAX_OPL_QUEUE; ++i)
{
time = rand() % 0x10000;
OPL_Queue_Push(queue, NULL, NULL, time);
}
time = 0;
for (i=0; i<MAX_OPL_QUEUE; ++i)
{
assert(!OPL_Queue_IsEmpty(queue));
newtime = OPL_Queue_Peek(queue);
assert(OPL_Queue_Pop(queue, &callback, &data));
assert(newtime >= time);
time = newtime;
}
assert(OPL_Queue_IsEmpty(queue));
assert(!OPL_Queue_Pop(queue, &callback, &data));
}
}
#endif

View file

@ -1,39 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL callback queue.
//
#ifndef OPL_QUEUE_H
#define OPL_QUEUE_H
#include "opl.h"
typedef struct opl_callback_queue_s opl_callback_queue_t;
opl_callback_queue_t *OPL_Queue_Create(void);
int OPL_Queue_IsEmpty(opl_callback_queue_t *queue);
void OPL_Queue_Clear(opl_callback_queue_t *queue);
void OPL_Queue_Destroy(opl_callback_queue_t *queue);
void OPL_Queue_Push(opl_callback_queue_t *queue,
opl_callback_t callback, void *data,
uint64_t time);
int OPL_Queue_Pop(opl_callback_queue_t *queue,
opl_callback_t *callback, void **data);
uint64_t OPL_Queue_Peek(opl_callback_queue_t *queue);
void OPL_Queue_AdjustCallbacks(opl_callback_queue_t *queue,
uint64_t time, float factor);
#endif /* #ifndef OPL_QUEUE_H */

View file

@ -1,521 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL SDL interface.
//
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "SDL.h"
#ifndef DISABLE_SDL2MIXER
#include "SDL_mixer.h"
#endif // DISABLE_SDL2MIXER
#include "opl3.h"
#include "opl.h"
#include "opl_internal.h"
#include "opl_queue.h"
#ifndef DISABLE_SDL2MIXER
#define MAX_SOUND_SLICE_TIME 100 /* ms */
typedef struct
{
unsigned int rate; // Number of times the timer is advanced per sec.
unsigned int enabled; // Non-zero if timer is enabled.
unsigned int value; // Last value that was set.
uint64_t expire_time; // Calculated time that timer will expire.
} opl_timer_t;
// When the callback mutex is locked using OPL_Lock, callback functions
// are not invoked.
static SDL_mutex *callback_mutex = NULL;
// Queue of callbacks waiting to be invoked.
static opl_callback_queue_t *callback_queue;
// Mutex used to control access to the callback queue.
static SDL_mutex *callback_queue_mutex = NULL;
// Current time, in us since startup:
static uint64_t current_time;
// If non-zero, playback is currently paused.
static int opl_sdl_paused;
// Time offset (in us) due to the fact that callbacks
// were previously paused.
static uint64_t pause_offset;
// OPL software emulator structure.
static opl3_chip opl_chip;
static int opl_opl3mode;
// Temporary mixing buffer used by the mixing callback.
static uint8_t *mix_buffer = NULL;
// Register number that was written.
static int register_num = 0;
// Timers; DBOPL does not do timer stuff itself.
static opl_timer_t timer1 = { 12500, 0, 0, 0 };
static opl_timer_t timer2 = { 3125, 0, 0, 0 };
// SDL parameters.
static int sdl_was_initialized = 0;
static int mixing_freq, mixing_channels;
static Uint16 mixing_format;
static int SDLIsInitialized(void)
{
int freq, channels;
Uint16 format;
return Mix_QuerySpec(&freq, &format, &channels);
}
// Advance time by the specified number of samples, invoking any
// callback functions as appropriate.
static void AdvanceTime(unsigned int nsamples)
{
opl_callback_t callback;
void *callback_data;
uint64_t us;
SDL_LockMutex(callback_queue_mutex);
// Advance time.
us = ((uint64_t) nsamples * OPL_SECOND) / mixing_freq;
current_time += us;
if (opl_sdl_paused)
{
pause_offset += us;
}
// Are there callbacks to invoke now? Keep invoking them
// until there are no more left.
while (!OPL_Queue_IsEmpty(callback_queue)
&& current_time >= OPL_Queue_Peek(callback_queue) + pause_offset)
{
// Pop the callback from the queue to invoke it.
if (!OPL_Queue_Pop(callback_queue, &callback, &callback_data))
{
break;
}
// The mutex stuff here is a bit complicated. We must
// hold callback_mutex when we invoke the callback (so that
// the control thread can use OPL_Lock() to prevent callbacks
// from being invoked), but we must not be holding
// callback_queue_mutex, as the callback must be able to
// call OPL_SetCallback to schedule new callbacks.
SDL_UnlockMutex(callback_queue_mutex);
SDL_LockMutex(callback_mutex);
callback(callback_data);
SDL_UnlockMutex(callback_mutex);
SDL_LockMutex(callback_queue_mutex);
}
SDL_UnlockMutex(callback_queue_mutex);
}
// Call the OPL emulator code to fill the specified buffer.
static void FillBuffer(uint8_t *buffer, unsigned int nsamples)
{
// This seems like a reasonable assumption. mix_buffer is
// 1 second long, which should always be much longer than the
// SDL mix buffer.
assert(nsamples < mixing_freq);
// OPL output is generated into temporary buffer and then mixed
// (to avoid overflows etc.)
OPL3_GenerateStream(&opl_chip, (Bit16s *) mix_buffer, nsamples);
SDL_MixAudioFormat(buffer, mix_buffer, AUDIO_S16SYS, nsamples * 4,
SDL_MIX_MAXVOLUME);
}
// Callback function to fill a new sound buffer:
static void OPL_Mix_Callback(int chan, void *stream, int len, void *udata)
{
unsigned int filled, buffer_samples;
Uint8 *buffer = (Uint8*)stream;
// Repeatedly call the OPL emulator update function until the buffer is
// full.
filled = 0;
buffer_samples = len / 4;
while (filled < buffer_samples)
{
uint64_t next_callback_time;
uint64_t nsamples;
SDL_LockMutex(callback_queue_mutex);
// Work out the time until the next callback waiting in
// the callback queue must be invoked. We can then fill the
// buffer with this many samples.
if (opl_sdl_paused || OPL_Queue_IsEmpty(callback_queue))
{
nsamples = buffer_samples - filled;
}
else
{
next_callback_time = OPL_Queue_Peek(callback_queue) + pause_offset;
nsamples = (next_callback_time - current_time) * mixing_freq;
nsamples = (nsamples + OPL_SECOND - 1) / OPL_SECOND;
if (nsamples > buffer_samples - filled)
{
nsamples = buffer_samples - filled;
}
}
SDL_UnlockMutex(callback_queue_mutex);
// Add emulator output to buffer.
FillBuffer(buffer + filled * 4, nsamples);
filled += nsamples;
// Invoke callbacks for this point in time.
AdvanceTime(nsamples);
}
}
static void OPL_SDL_Shutdown(void)
{
Mix_HookMusic(NULL, NULL);
if (sdl_was_initialized)
{
Mix_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
OPL_Queue_Destroy(callback_queue);
free(mix_buffer);
sdl_was_initialized = 0;
}
/*
if (opl_chip != NULL)
{
OPLDestroy(opl_chip);
opl_chip = NULL;
}
*/
if (callback_mutex != NULL)
{
SDL_DestroyMutex(callback_mutex);
callback_mutex = NULL;
}
if (callback_queue_mutex != NULL)
{
SDL_DestroyMutex(callback_queue_mutex);
callback_queue_mutex = NULL;
}
}
static unsigned int GetSliceSize(void)
{
int limit;
int n;
limit = (opl_sample_rate * MAX_SOUND_SLICE_TIME) / 1000;
// Try all powers of two, not exceeding the limit.
for (n=0;; ++n)
{
// 2^n <= limit < 2^n+1 ?
if ((1 << (n + 1)) > limit)
{
return (1 << n);
}
}
// Should never happen?
return 1024;
}
static int OPL_SDL_Init(unsigned int port_base)
{
// Check if SDL_mixer has been opened already
// If not, we must initialize it now
if (!SDLIsInitialized())
{
if (SDL_Init(SDL_INIT_AUDIO) < 0)
{
fprintf(stderr, "Unable to set up sound.\n");
return 0;
}
if (Mix_OpenAudioDevice(opl_sample_rate, AUDIO_S16SYS, 2, GetSliceSize(), NULL, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) < 0)
{
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
SDL_QuitSubSystem(SDL_INIT_AUDIO);
return 0;
}
SDL_PauseAudio(0);
// When this module shuts down, it has the responsibility to
// shut down SDL.
sdl_was_initialized = 1;
}
else
{
sdl_was_initialized = 0;
}
opl_sdl_paused = 0;
pause_offset = 0;
// Queue structure of callbacks to invoke.
callback_queue = OPL_Queue_Create();
current_time = 0;
// Get the mixer frequency, format and number of channels.
Mix_QuerySpec(&mixing_freq, &mixing_format, &mixing_channels);
// Only supports AUDIO_S16SYS
if (mixing_format != AUDIO_S16SYS || mixing_channels != 2)
{
fprintf(stderr,
"OPL_SDL only supports native signed 16-bit LSB, "
"stereo format!\n");
OPL_SDL_Shutdown();
return 0;
}
// Mix buffer: four bytes per sample (16 bits * 2 channels):
mix_buffer = malloc(mixing_freq * 4);
// Create the emulator structure:
OPL3_Reset(&opl_chip, mixing_freq);
opl_opl3mode = 0;
callback_mutex = SDL_CreateMutex();
callback_queue_mutex = SDL_CreateMutex();
// Set postmix that adds the OPL music. This is deliberately done
// as a postmix and not using Mix_HookMusic() as the latter disables
// normal SDL_mixer music mixing.
Mix_RegisterEffect(MIX_CHANNEL_POST, OPL_Mix_Callback, NULL, NULL);
return 1;
}
static unsigned int OPL_SDL_PortRead(opl_port_t port)
{
unsigned int result = 0;
if (port == OPL_REGISTER_PORT_OPL3)
{
return 0xff;
}
if (timer1.enabled && current_time > timer1.expire_time)
{
result |= 0x80; // Either have expired
result |= 0x40; // Timer 1 has expired
}
if (timer2.enabled && current_time > timer2.expire_time)
{
result |= 0x80; // Either have expired
result |= 0x20; // Timer 2 has expired
}
return result;
}
static void OPLTimer_CalculateEndTime(opl_timer_t *timer)
{
int tics;
// If the timer is enabled, calculate the time when the timer
// will expire.
if (timer->enabled)
{
tics = 0x100 - timer->value;
timer->expire_time = current_time
+ ((uint64_t) tics * OPL_SECOND) / timer->rate;
}
}
static void WriteRegister(unsigned int reg_num, unsigned int value)
{
switch (reg_num)
{
case OPL_REG_TIMER1:
timer1.value = value;
OPLTimer_CalculateEndTime(&timer1);
break;
case OPL_REG_TIMER2:
timer2.value = value;
OPLTimer_CalculateEndTime(&timer2);
break;
case OPL_REG_TIMER_CTRL:
if (value & 0x80)
{
timer1.enabled = 0;
timer2.enabled = 0;
}
else
{
if ((value & 0x40) == 0)
{
timer1.enabled = (value & 0x01) != 0;
OPLTimer_CalculateEndTime(&timer1);
}
if ((value & 0x20) == 0)
{
timer2.enabled = (value & 0x02) != 0;
OPLTimer_CalculateEndTime(&timer2);
}
}
break;
case OPL_REG_NEW:
opl_opl3mode = value & 0x01;
default:
OPL3_WriteRegBuffered(&opl_chip, reg_num, value);
break;
}
}
static void OPL_SDL_PortWrite(opl_port_t port, unsigned int value)
{
if (port == OPL_REGISTER_PORT)
{
register_num = value;
}
else if (port == OPL_REGISTER_PORT_OPL3)
{
register_num = value | 0x100;
}
else if (port == OPL_DATA_PORT)
{
WriteRegister(register_num, value);
}
}
static void OPL_SDL_SetCallback(uint64_t us, opl_callback_t callback,
void *data)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Push(callback_queue, callback, data,
current_time - pause_offset + us);
SDL_UnlockMutex(callback_queue_mutex);
}
static void OPL_SDL_ClearCallbacks(void)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Clear(callback_queue);
SDL_UnlockMutex(callback_queue_mutex);
}
static void OPL_SDL_Lock(void)
{
SDL_LockMutex(callback_mutex);
}
static void OPL_SDL_Unlock(void)
{
SDL_UnlockMutex(callback_mutex);
}
static void OPL_SDL_SetPaused(int paused)
{
opl_sdl_paused = paused;
}
static void OPL_SDL_AdjustCallbacks(float factor)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_AdjustCallbacks(callback_queue, current_time, factor);
SDL_UnlockMutex(callback_queue_mutex);
}
opl_driver_t opl_sdl_driver =
{
"SDL",
OPL_SDL_Init,
OPL_SDL_Shutdown,
OPL_SDL_PortRead,
OPL_SDL_PortWrite,
OPL_SDL_SetCallback,
OPL_SDL_ClearCallbacks,
OPL_SDL_Lock,
OPL_SDL_Unlock,
OPL_SDL_SetPaused,
OPL_SDL_AdjustCallbacks,
};
#endif // DISABLE_SDL2MIXER

View file

@ -1,250 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL timer thread.
// Once started using OPL_Timer_StartThread, the thread sleeps,
// waking up to invoke callbacks set using OPL_Timer_SetCallback.
//
#include "SDL.h"
#include "opl_timer.h"
#include "opl_queue.h"
typedef enum
{
THREAD_STATE_STOPPED,
THREAD_STATE_RUNNING,
THREAD_STATE_STOPPING,
} thread_state_t;
static SDL_Thread *timer_thread = NULL;
static thread_state_t timer_thread_state;
static uint64_t current_time;
// If non-zero, callbacks are currently paused.
static int opl_timer_paused;
// Offset in microseconds to adjust time due to the fact that playback
// was paused.
static uint64_t pause_offset = 0;
// Queue of callbacks waiting to be invoked.
// The callback queue mutex is held while the callback queue structure
// or current_time is being accessed.
static opl_callback_queue_t *callback_queue;
static SDL_mutex *callback_queue_mutex;
// The timer mutex is held while timer callback functions are being
// invoked, so that the calling code can prevent clashes.
static SDL_mutex *timer_mutex;
// Returns true if there is a callback at the head of the queue ready
// to be invoked. Otherwise, next_time is set to the time when the
// timer thread must wake up again to check.
static int CallbackWaiting(uint64_t *next_time)
{
// If paused, just wait in 50ms increments until unpaused.
// Update pause_offset so after we unpause, the callback
// times will be right.
if (opl_timer_paused)
{
*next_time = current_time + 50 * OPL_MS;
pause_offset += 50 * OPL_MS;
return 0;
}
// If there are no queued callbacks, sleep for 50ms at a time
// until a callback is added.
if (OPL_Queue_IsEmpty(callback_queue))
{
*next_time = current_time + 50 * OPL_MS;
return 0;
}
// Read the time of the first callback in the queue.
// If the time for the callback has not yet arrived,
// we must sleep until the callback time.
*next_time = OPL_Queue_Peek(callback_queue) + pause_offset;
return *next_time <= current_time;
}
static uint64_t GetNextTime(void)
{
opl_callback_t callback;
void *callback_data;
uint64_t next_time;
int have_callback;
// Keep running through callbacks until there are none ready to
// run. When we run out of callbacks, next_time will be set.
do
{
SDL_LockMutex(callback_queue_mutex);
// Check if the callback at the head of the list is ready to
// be invoked. If so, pop from the head of the queue.
have_callback = CallbackWaiting(&next_time);
if (have_callback)
{
OPL_Queue_Pop(callback_queue, &callback, &callback_data);
}
SDL_UnlockMutex(callback_queue_mutex);
// Now invoke the callback, if we have one.
// The timer mutex is held while the callback is invoked.
if (have_callback)
{
SDL_LockMutex(timer_mutex);
callback(callback_data);
SDL_UnlockMutex(timer_mutex);
}
} while (have_callback);
return next_time;
}
static int ThreadFunction(void *unused)
{
uint64_t next_time;
uint64_t now;
// Keep running until OPL_Timer_StopThread is called.
while (timer_thread_state == THREAD_STATE_RUNNING)
{
// Get the next time that we must sleep until, and
// wait until that time.
next_time = GetNextTime();
now = SDL_GetTicks() * OPL_MS;
if (next_time > now)
{
SDL_Delay((next_time - now) / OPL_MS);
}
// Update the current time.
SDL_LockMutex(callback_queue_mutex);
current_time = next_time;
SDL_UnlockMutex(callback_queue_mutex);
}
timer_thread_state = THREAD_STATE_STOPPED;
return 0;
}
static void InitResources(void)
{
callback_queue = OPL_Queue_Create();
timer_mutex = SDL_CreateMutex();
callback_queue_mutex = SDL_CreateMutex();
}
static void FreeResources(void)
{
OPL_Queue_Destroy(callback_queue);
SDL_DestroyMutex(callback_queue_mutex);
SDL_DestroyMutex(timer_mutex);
}
int OPL_Timer_StartThread(void)
{
InitResources();
timer_thread_state = THREAD_STATE_RUNNING;
current_time = SDL_GetTicks();
opl_timer_paused = 0;
pause_offset = 0;
timer_thread = SDL_CreateThread(ThreadFunction, "OPL timer thread", NULL);
if (timer_thread == NULL)
{
timer_thread_state = THREAD_STATE_STOPPED;
FreeResources();
return 0;
}
return 1;
}
void OPL_Timer_StopThread(void)
{
timer_thread_state = THREAD_STATE_STOPPING;
while (timer_thread_state != THREAD_STATE_STOPPED)
{
SDL_Delay(1);
}
FreeResources();
}
void OPL_Timer_SetCallback(uint64_t us, opl_callback_t callback, void *data)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Push(callback_queue, callback, data,
current_time + us - pause_offset);
SDL_UnlockMutex(callback_queue_mutex);
}
void OPL_Timer_ClearCallbacks(void)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Clear(callback_queue);
SDL_UnlockMutex(callback_queue_mutex);
}
void OPL_Timer_AdjustCallbacks(float factor)
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_AdjustCallbacks(callback_queue, current_time, factor);
SDL_UnlockMutex(callback_queue_mutex);
}
void OPL_Timer_Lock(void)
{
SDL_LockMutex(timer_mutex);
}
void OPL_Timer_Unlock(void)
{
SDL_UnlockMutex(timer_mutex);
}
void OPL_Timer_SetPaused(int paused)
{
SDL_LockMutex(callback_queue_mutex);
opl_timer_paused = paused;
SDL_UnlockMutex(callback_queue_mutex);
}

View file

@ -1,33 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL timer thread.
//
#ifndef OPL_TIMER_H
#define OPL_TIMER_H
#include "opl.h"
int OPL_Timer_StartThread(void);
void OPL_Timer_StopThread(void);
void OPL_Timer_SetCallback(uint64_t us, opl_callback_t callback, void *data);
void OPL_Timer_ClearCallbacks(void);
void OPL_Timer_Lock(void);
void OPL_Timer_Unlock(void);
void OPL_Timer_SetPaused(int paused);
void OPL_Timer_AdjustCallbacks(float factor);
#endif /* #ifndef OPL_TIMER_H */

View file

@ -1,192 +0,0 @@
//
// Copyright(C) 2005-2014 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// OPL Win32 native interface.
//
#include "config.h"
#ifdef _WIN32
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "opl.h"
#include "opl_internal.h"
#include "opl_timer.h"
#include "ioperm_sys.h"
static unsigned int opl_port_base;
// MingW?
#if defined(__GNUC__) && defined(__i386__)
static unsigned int OPL_Win32_PortRead(opl_port_t port)
{
unsigned char result;
__asm__ volatile (
"movl %1, %%edx\n"
"inb %%dx, %%al\n"
"movb %%al, %0"
: "=m" (result)
: "r" (opl_port_base + port)
: "edx", "al", "memory"
);
return result;
}
static void OPL_Win32_PortWrite(opl_port_t port, unsigned int value)
{
__asm__ volatile (
"movl %0, %%edx\n"
"movb %1, %%al\n"
"outb %%al, %%dx"
:
: "r" (opl_port_base + port), "r" ((unsigned char) value)
: "edx", "al"
);
}
// haleyjd 20110417: MSVC version
#elif defined(_MSC_VER) && defined(_M_IX86)
static unsigned int OPL_Win32_PortRead(opl_port_t port)
{
unsigned char result;
opl_port_t dst_port = opl_port_base + port;
__asm
{
mov edx, dword ptr [dst_port]
in al, dx
mov byte ptr [result], al
}
return result;
}
static void OPL_Win32_PortWrite(opl_port_t port, unsigned int value)
{
opl_port_t dst_port = opl_port_base + port;
__asm
{
mov edx, dword ptr [dst_port]
mov al, byte ptr [value]
out dx, al
}
}
#else
// Not x86, or don't know how to do port R/W on this compiler.
#define NO_PORT_RW
static unsigned int OPL_Win32_PortRead(opl_port_t port)
{
return 0;
}
static void OPL_Win32_PortWrite(opl_port_t port, unsigned int value)
{
}
#endif
static int OPL_Win32_Init(unsigned int port_base)
{
OSVERSIONINFO version_info;
opl_port_base = port_base;
// Check the OS version.
memset(&version_info, 0, sizeof(version_info));
version_info.dwOSVersionInfoSize = sizeof(version_info);
GetVersionEx(&version_info);
#ifndef NO_PORT_RW
// On NT-based systems, we must acquire I/O port permissions
// using the ioperm.sys driver.
if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// Install driver.
if (!IOperm_InstallDriver())
{
return 0;
}
// Open port range.
if (!IOperm_EnablePortRange(opl_port_base, 2, 1))
{
IOperm_UninstallDriver();
return 0;
}
}
// Start callback thread
if (!OPL_Timer_StartThread())
{
IOperm_UninstallDriver();
return 0;
}
return 1;
#endif
return 0;
}
static void OPL_Win32_Shutdown(void)
{
// Stop callback thread
OPL_Timer_StopThread();
// Unload IOperm library.
IOperm_UninstallDriver();
}
opl_driver_t opl_win32_driver =
{
"Win32",
OPL_Win32_Init,
OPL_Win32_Shutdown,
OPL_Win32_PortRead,
OPL_Win32_PortWrite,
OPL_Timer_SetCallback,
OPL_Timer_ClearCallbacks,
OPL_Timer_Lock,
OPL_Timer_Unlock,
OPL_Timer_SetPaused,
OPL_Timer_AdjustCallbacks,
};
#endif /* #ifdef _WIN32 */

View file

@ -1,24 +0,0 @@
add_library(pcsound STATIC
pcsound.c pcsound.h
pcsound_bsd.c
pcsound_sdl.c
pcsound_linux.c
pcsound_win32.c
pcsound_internal.h)
target_include_directories(pcsound
INTERFACE "."
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
if (DEFINED EMSCRIPTEN)
if(ENABLE_SDL2_MIXER)
set_target_properties(pcsound PROPERTIES COMPILE_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
set_target_properties(pcsound PROPERTIES LINK_FLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2")
else()
set_target_properties(pcsound PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
set_target_properties(pcsound PROPERTIES LINK_FLAGS "-s USE_SDL=2")
endif()
else()
target_link_libraries(pcsound SDL2::SDL2)
if(ENABLE_SDL2_MIXER)
target_link_libraries(pcsound SDL2_mixer::SDL2_mixer)
endif()
endif()

Some files were not shown because too many files have changed in this diff Show more