Merge remote-tracking branch 'origin/master' into sdl2-branch
This commit is contained in:
commit
c139624650
31 changed files with 4012 additions and 4159 deletions
6
.github/CONTRIBUTING.md
vendored
6
.github/CONTRIBUTING.md
vendored
|
|
@ -11,7 +11,7 @@ terms. To report violations, please send an email to fraggle@gmail.com.
|
|||
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) file for a list of common issues which aren't
|
||||
[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.
|
||||
|
|
@ -39,7 +39,7 @@ Please try to give as much information as possible:
|
|||
|
||||
Chocolate Doom is always open to new feature requests; however, please
|
||||
be aware that the project is designed around a deliberately limited
|
||||
[philosophy](../PHILOSOPHY), and many features common in other source
|
||||
[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:
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ following guidelines before opening a pull request:
|
|||
to license it under the GPL.
|
||||
|
||||
* Please follow the coding style guidelines described in the
|
||||
[HACKING](../HACKING) file.
|
||||
[HACKING](../HACKING.md) file.
|
||||
|
||||
* The guidelines given above in the "feature requests" section also
|
||||
apply here. New features which aren't in line with the project
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ addons:
|
|||
- libsdl-net1.2-dev
|
||||
- libpng-dev
|
||||
|
||||
script: ./autogen.sh && make
|
||||
script: ./autogen.sh && make && make install DESTDIR=/tmp/whatever && make dist
|
||||
|
||||
branches:
|
||||
only:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
Coding style guidelines
|
||||
=======================
|
||||
# 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
|
||||
|
|
@ -9,52 +7,57 @@ 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
|
||||
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
|
||||
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
|
||||
`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
|
||||
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
|
||||
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 don't care that this isn't standard ANSI C.
|
||||
Use C++-style comments, ie. `//` comments, not `/* ... */` comments.
|
||||
I don’t care that this isn’t standard ANSI C.
|
||||
|
||||
Variables should be named like this: 'my_variable_name', not like this:
|
||||
'MyVariableName'. In pointer variable declarations, place the '*' next
|
||||
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 using an if, do, while, or for statement, always use the { } braces
|
||||
even when they are not necessary. For example, do this:
|
||||
|
||||
if (condition)
|
||||
{
|
||||
body;
|
||||
}
|
||||
```c
|
||||
if (condition)
|
||||
{
|
||||
body;
|
||||
}
|
||||
```
|
||||
|
||||
Not this:
|
||||
|
||||
if (condition) // NO
|
||||
body;
|
||||
```c
|
||||
if (condition) // NO
|
||||
body;
|
||||
```
|
||||
|
||||
Write code like this:
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
int member1;
|
||||
|
|
@ -117,81 +120,82 @@ void FunctionName(int argument, int arg2, int arg3, int arg4, int arg5,
|
|||
|
||||
} while (condition);
|
||||
}
|
||||
```
|
||||
|
||||
Security
|
||||
========
|
||||
## 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()
|
||||
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()`
|
||||
|
||||
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:
|
||||
|
||||
printf(DEH_String("foo %s"), s);
|
||||
sprintf(mybuf, DEH_String("bar %s"), t);
|
||||
```c
|
||||
printf(DEH_String("foo %s"), s);
|
||||
sprintf(mybuf, DEH_String("bar %s"), t);
|
||||
```
|
||||
|
||||
Instead do this:
|
||||
|
||||
DEH_printf("foo %s", s);
|
||||
DEH_snprintf(mybuf, sizeof(mybuf), "bar %s", t);
|
||||
```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
|
||||
===========
|
||||
## 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).
|
||||
Do not use the `long` type (its size differs across platforms; use
|
||||
`int` or `int64_t` depending on which you want).
|
||||
|
||||
Use Doom's 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.
|
||||
Use Doom’s 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 MacOS X. Others
|
||||
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
|
||||
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 shouldn't assume that (i >> n) is the same as
|
||||
(i / (1 << n)). However, most processors handle bitshifts of signed
|
||||
integers properly, so it's not a huge problem.
|
||||
For signed integers, you shouldn’t assume that `(i >> n)` is the same as
|
||||
`(i / (1 << n))`. However, most processors handle bitshifts of signed
|
||||
integers properly, so it’s not a huge problem.
|
||||
|
||||
## GNU GPL and licensing
|
||||
|
||||
GNU GPL and licensing
|
||||
=====================
|
||||
|
||||
All code submitted to the project must be licensed under the GNU GPL or a
|
||||
compatible license. If you use code that you haven't 100% written
|
||||
All code submitted to the project must be licensed under the GNU GPLv2 or a
|
||||
compatible license. If you use code that you haven’t 100% written
|
||||
yourself, say so. Add a copyright header to the start of every file. Use
|
||||
this template:
|
||||
|
||||
```
|
||||
//
|
||||
// Copyright(C) YEAR Author's name
|
||||
//
|
||||
|
|
@ -208,6 +212,4 @@ this template:
|
|||
//
|
||||
// *File description goes here*
|
||||
//
|
||||
|
||||
# vim: tw=70
|
||||
|
||||
```
|
||||
20
Makefile.am
20
Makefile.am
|
|
@ -38,10 +38,10 @@ CODEBLOCKS_FILES= \
|
|||
codeblocks/setup-res.rc
|
||||
|
||||
DOC_FILES= \
|
||||
README \
|
||||
README.Music \
|
||||
NEWS \
|
||||
PHILOSOPHY \
|
||||
README.md \
|
||||
README.Music.md \
|
||||
NEWS.md \
|
||||
PHILOSOPHY.md \
|
||||
ChangeLog
|
||||
|
||||
EXTRA_DIST= \
|
||||
|
|
@ -49,15 +49,15 @@ EXTRA_DIST= \
|
|||
$(MSVC_FILES) \
|
||||
$(CODEBLOCKS_FILES) \
|
||||
$(DOC_FILES) \
|
||||
NOT-BUGS \
|
||||
README.Strife \
|
||||
NOT-BUGS.md \
|
||||
README.Strife.md \
|
||||
.lvimrc \
|
||||
HACKING \
|
||||
TODO \
|
||||
HACKING.md \
|
||||
TODO.md \
|
||||
rpm.spec
|
||||
|
||||
doomdocsdir = ${docdir}/../${PROGRAM_PREFIX}doom
|
||||
doomdocs_DATA = $(DOC_FILES) NOT-BUGS
|
||||
doomdocs_DATA = $(DOC_FILES) NOT-BUGS.md
|
||||
|
||||
hereticdocsdir = ${docdir}/../${PROGRAM_PREFIX}heretic
|
||||
hereticdocs_DATA = $(DOC_FILES)
|
||||
|
|
@ -66,7 +66,7 @@ hexendocsdir = ${docdir}/../${PROGRAM_PREFIX}hexen
|
|||
hexendocs_DATA = $(DOC_FILES)
|
||||
|
||||
strifedocsdir = ${docdir}/../${PROGRAM_PREFIX}strife
|
||||
strifedocs_DATA = $(DOC_FILES) README.Strife
|
||||
strifedocs_DATA = $(DOC_FILES) README.Strife.md
|
||||
|
||||
MAINTAINERCLEANFILES = $(AUX_DIST_GEN)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +1,32 @@
|
|||
|
||||
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
|
||||
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.
|
||||
For more information, consult the “engine bugs” page of the Doom Wiki.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
== Game exits after title screen with message about game version ==
|
||||
## 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 106, should be 109)
|
||||
(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.6/v1.666.
|
||||
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 the v1.9 IWAD file.
|
||||
Chocolate Doom only supports versions 1.666 through 1.9.
|
||||
|
||||
To fix the problem, you must upgrade to the v1.9 IWAD file. The URL
|
||||
in the message has downloadable upgrade patches that you can use to
|
||||
upgrade.
|
||||
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 ==
|
||||
## 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
|
||||
|
|
@ -53,11 +48,9 @@ the alternate version, run with:
|
|||
|
||||
chocolate-doom -gameversion final2
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
## Game exits when accessing the options menu
|
||||
|
||||
== Game exits when accessing the options menu ==
|
||||
|
||||
The game may exit with the message "Bad V_DrawPatch" when accessing
|
||||
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
|
||||
|
|
@ -73,37 +66,35 @@ 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 Doom's key bindings anyway:
|
||||
controlled through Doom’s key bindings anyway:
|
||||
|
||||
End game: F7
|
||||
Messages on/off: F8
|
||||
Graphic detail high/low: F5
|
||||
Screen size smaller/larger: -/+
|
||||
Sound volume menu: F4
|
||||
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 ==
|
||||
## 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".
|
||||
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.
|
||||
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
|
||||
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 ==
|
||||
## 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
|
||||
|
|
@ -113,33 +104,27 @@ 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.
|
||||
the “Vanilla demo limit” option.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
== Game exits with a message about "visplanes" ==
|
||||
## 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
|
||||
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):
|
||||
More information can be found here (archived link): https://archive.is/s6h7V
|
||||
|
||||
https://archive.is/s6h7V
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
== IDMUS## cheat doesn't work with shareware/registered Doom IWADs ==
|
||||
## IDMUS## cheat doesn’t 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 didn't work properly when playing with
|
||||
the original v1.9 this cheat didn’t work properly when playing with
|
||||
the Doom 1 (shareware and registered) IWADs. This bug was fixed in
|
||||
the Ultimate Doom and Final Doom executables.
|
||||
|
||||
|
|
@ -149,9 +134,7 @@ 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 ==
|
||||
## 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
|
||||
|
|
@ -161,9 +144,6 @@ 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, it's best to get a
|
||||
allow the game to run, but for the best experience, it’s best to get a
|
||||
copy of the classic versions of the IWADs. These are still available
|
||||
to buy from Steam or Id's online store.
|
||||
|
||||
# vim: tw=70
|
||||
|
||||
to buy from Steam or GOG.com.
|
||||
|
|
@ -1,39 +1,38 @@
|
|||
|
||||
Chocolate Doom has been designed around a careful and deliberate
|
||||
philosophy that attempts to recreate the original ("Vanilla") DOS
|
||||
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 ==
|
||||
# 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"
|
||||
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 aren't part of the central
|
||||
gameplay experience can be extended as long as there's a good
|
||||
* The surrounding aspects of the game that aren’t part of the central
|
||||
gameplay experience can be extended as long as there’s 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:
|
||||
“Vanilla” is defined as:
|
||||
|
||||
* DOS Doom 1.9 (although there are actually multiple "1.9"s).
|
||||
* DOS Doom 1.9 (although there are actually multiple “1.9”s).
|
||||
* DOS Heretic 1.3.
|
||||
* DOS Hexen 1.1.
|
||||
* DOS Strife 1.31.
|
||||
|
||||
"Vanilla" does not include ports (either official or unofficial), such
|
||||
“Vanilla” does not include ports (either official or unofficial), such
|
||||
as console ports, Doom 95 or Doom 3: BFG Edition.
|
||||
|
||||
== Compatibility ==
|
||||
# Compatibility
|
||||
|
||||
Chocolate Doom aims to be compatible with Vanilla Doom in several
|
||||
different ways. Examples are:
|
||||
|
|
@ -41,12 +40,12 @@ 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
|
||||
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
|
||||
‘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
|
||||
|
|
@ -60,9 +59,9 @@ different ways. Examples are:
|
|||
file format as Vanilla, such that it should be possible to import
|
||||
and use existing savegame files.
|
||||
|
||||
== DOS tools ==
|
||||
# DOS tools
|
||||
|
||||
Chocolate Doom includes some features that aren't part of Vanilla Doom
|
||||
Chocolate Doom includes some features that aren’t 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:
|
||||
|
|
@ -73,7 +72,7 @@ treated as such. Some examples are:
|
|||
does under DOS. Chocolate Doom imposes the same limitations that
|
||||
Vanilla Dehacked does.
|
||||
|
||||
== Exceptions ==
|
||||
# Exceptions
|
||||
|
||||
Chocolate Doom differs from Vanilla Doom in a number of ways. In most
|
||||
cases these are subtle, minor differences. Nonetheless they deserve
|
||||
|
|
@ -81,25 +80,25 @@ 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
|
||||
player's computer, or is just outright misleading. For example:
|
||||
player’s 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 doesn't run under DOS, reproducing
|
||||
CONFIG.SYS. As Chocolate Doom doesn’t run under DOS, reproducing
|
||||
this message would not be helpful.
|
||||
|
||||
2. Subtly extending behavior is okay where it's not clear what the
|
||||
2. Subtly extending behavior is okay where it’s not clear what the
|
||||
Vanilla behavior is anyway. For example:
|
||||
|
||||
- Opening the menu releases mouse grab in Chocolate Doom.
|
||||
- Chocolate Hexen's graphical startup screen runs in a window.
|
||||
- Chocolate Hexen’s graphical startup screen runs in a window.
|
||||
|
||||
3. Supporting obsolete technology is not a goal: it's considered
|
||||
3. Supporting obsolete technology is not a goal: it’s 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 technology that
|
||||
isn't supported are:
|
||||
isn’t supported are:
|
||||
|
||||
- No support for IPX networks, but TCP/IP is supported instead.
|
||||
- No support for dial-up/serial connections; modern operating
|
||||
|
|
@ -109,35 +108,39 @@ situations where changes are considered acceptable:
|
|||
4. Changes are acceptable that allow the player to be able play the
|
||||
game. For example:
|
||||
|
||||
- There are new key bindings for actions that can't be rebound with
|
||||
Vanilla Doom, because it's useful for portability to machines
|
||||
that don't have a full keyboard.
|
||||
- There are new key bindings for actions that can’t be rebound with
|
||||
Vanilla Doom, because it’s useful for portability to machines
|
||||
that don’t have a full keyboard.
|
||||
- There are additional mouse and joystick key 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 it's not Vanilla behavior.
|
||||
play is better than nothing, even if it’s 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 game’s 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 doesn't change gameplay and
|
||||
there's a good reason for it. For example:
|
||||
as the defaults match Vanilla, it doesn’t change gameplay and
|
||||
there’s 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 there's a
|
||||
6. Changing configuration file defaults is acceptable where there’s 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; there's no need to configure hardware IRQ settings
|
||||
support these; there’s no need to configure hardware IRQ settings
|
||||
to get sound working.
|
||||
|
||||
7. Things can be changed if they're really just inconsequential. For
|
||||
7. Things can be changed if they’re really just inconsequential. For
|
||||
example:
|
||||
|
||||
- The startup messages in Chocolate Doom are not identical to
|
||||
|
|
@ -146,22 +149,22 @@ situations where changes are considered acceptable:
|
|||
-regdev used by id internally for development; these have been
|
||||
removed.
|
||||
|
||||
A good litmus test of when it's acceptable to break from Vanilla
|
||||
behavior is to ask the question: "Although this is Vanilla behavior,
|
||||
is there anyone who would want this?".
|
||||
A good litmus test of when it’s 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 ==
|
||||
# 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 Boom's complicated maze
|
||||
the inspiration for Chocolate Doom came from Boom’s complicated maze
|
||||
of options menus (and a desire to avoid them). Too many preferences
|
||||
lead to a bad user interface; see Havoc Pennington's essay on Free
|
||||
lead to a bad user interface; see Havoc Pennington’s essay on Free
|
||||
Software UI:
|
||||
|
||||
http://ometer.com/free-software-ui.html
|
||||
|
|
@ -173,21 +176,21 @@ 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 Havoc's Metacity window
|
||||
Also inspirational was the README file from Havoc’s 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.
|
||||
> Boring window manager for the adult in you. Many window managers
|
||||
> are like Marshmallow Froot Loops; Metacity is like Cheerios.
|
||||
|
||||
I'd like to think that Chocolate Doom's philosophy towards features is
|
||||
I’d like to think that Chocolate Doom’s 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
|
||||
“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 Gritti's Epiphany web browser and Evince PDF viewer.
|
||||
are Marco Pesenti Gritti’s Epiphany web browser and Evince PDF viewer.
|
||||
|
||||
== Other philosophical aspects ==
|
||||
# Other philosophical aspects
|
||||
|
||||
Chocolate Doom aims for maximal portability. That includes running on
|
||||
many different CPUs, different operating systems and different devices
|
||||
|
|
@ -195,6 +198,3 @@ many different CPUs, different operating systems and different devices
|
|||
|
||||
Chocolate Doom is and will always remain Free Software. It will never
|
||||
include code that is not compatible with the GNU GPL.
|
||||
|
||||
# vim: tw=70
|
||||
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
|
||||
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 ==
|
||||
## 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
|
||||
example). To use this, choose “Native MIDI” in the sound configuration
|
||||
dialog in the setup tool.
|
||||
|
||||
== Timidity ==
|
||||
## 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
|
||||
|
|
@ -20,17 +19,17 @@ 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
|
||||
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) ==
|
||||
## Gravis Ultrasound (GUS)
|
||||
|
||||
The Gravis Ultrasound (GUS) was a PC sound card popular in the '90s,
|
||||
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
|
||||
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
|
||||
|
|
@ -41,37 +40,37 @@ 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"
|
||||
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.
|
||||
|
||||
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) ==
|
||||
## OPL (Soundblaster / Adlib)
|
||||
|
||||
Most people playing Doom in the '90s had Soundblaster-compatible sound
|
||||
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)".
|
||||
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, here's how
|
||||
cards do have real hardware OPL. If you have such a card, here’s how
|
||||
to configure Chocolate Doom to use it.
|
||||
|
||||
=== Sound cards with OPL chips ===
|
||||
# Sound cards with OPL chips
|
||||
|
||||
If you have an ISA sound card, it almost certainly includes an OPL
|
||||
chip. Modern computers don't have slots for ISA cards though, so you
|
||||
chip. Modern computers don’t have slots for ISA cards though, so you
|
||||
must be running a pretty old machine.
|
||||
|
||||
If you have a PCI sound card, you probably don't have an OPL chip.
|
||||
If you have a PCI sound card, you probably don’t have an OPL chip.
|
||||
However, there are some exceptions to this. The following cards are
|
||||
known to include "legacy" OPL support:
|
||||
known to include “legacy” OPL support:
|
||||
|
||||
* C-Media CMI8738 (*)
|
||||
* Forte Media FM801
|
||||
|
|
@ -93,31 +92,31 @@ 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.
|
||||
|
||||
If your machine is not a PC, you don't have an OPL chip, and you will
|
||||
If your machine is not a PC, you don’t have an OPL chip, and you will
|
||||
have to use the software OPL.
|
||||
|
||||
=== Operating System support ===
|
||||
# Operating System support
|
||||
|
||||
If you're certain that you have a sound card with hardware OPL, you
|
||||
If you’re 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).
|
||||
|
||||
=== Windows 9x ===
|
||||
## Windows 9x
|
||||
|
||||
If you're running Windows 95, 98 or Me, there is no need to configure
|
||||
If you’re running Windows 95, 98 or Me, there is no need to configure
|
||||
anything. Windows allows direct access to the OPL chip. You can
|
||||
confirm that hardware OPL is working by checking for this message in
|
||||
stdout.txt:
|
||||
|
||||
OPL_Init: Using driver 'Win32'.
|
||||
OPL_Init: Using driver 'Win32'.
|
||||
|
||||
=== Windows NT (including 2000, XP and later) ===
|
||||
## Windows NT (including 2000, XP and later)
|
||||
|
||||
If you're running an NT-based system, it is not possible to directly
|
||||
If you’re running an NT-based system, 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:
|
||||
it is possible to use the “ioperm.sys” driver developed for Cygwin:
|
||||
|
||||
http://openwince.sourceforge.net/ioperm/
|
||||
|
||||
|
|
@ -128,44 +127,41 @@ 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'.
|
||||
OPL_Init: Using driver 'Win32'.
|
||||
|
||||
=== Linux ===
|
||||
## 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'.
|
||||
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
|
||||
options snd-ymfpci fm_port=0x388
|
||||
options snd-cmipci fm_port=0x388
|
||||
|
||||
=== OpenBSD/NetBSD ===
|
||||
## 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'.
|
||||
OPL_Init: Using driver 'OpenBSD'.
|
||||
|
||||
There is no native OPL backend for FreeBSD yet. Sorry!
|
||||
|
||||
== Other options ==
|
||||
# Other options
|
||||
|
||||
If you have some other favorite MIDI playback option that isn't
|
||||
If you have some other favorite MIDI playback option that isn’t
|
||||
listed above, you can set a hook to invoke an external command for
|
||||
MIDI playback using the 'snd_musiccmd' configuration file option. For
|
||||
MIDI playback using the ‘snd_musiccmd’ configuration file option. For
|
||||
example, set:
|
||||
|
||||
snd_musiccmd "aplaymidi -p 128:0"
|
||||
snd_musiccmd "aplaymidi -p 128:0"
|
||||
|
||||
in your chocolate-doom.cfg file.
|
||||
|
||||
# vim: set tw=70:
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
===============================================================================
|
||||
````````````````````````````````````````````````````````````````````````
|
||||
|
||||
Samuel 'Kaiser' Villarreal and James 'Quasar' Haley Present
|
||||
Samuel ‘Kaiser’ Villarreal and James ‘Quasar’ Haley Present
|
||||
|
||||
C H O C O L A T E
|
||||
______________________________._________________________
|
||||
|
|
@ -10,17 +10,17 @@
|
|||
/_______ / |____| |____|_ /___|\___ / /_______ /
|
||||
\/ \/ \/ \/
|
||||
|
||||
===============================================================================
|
||||
````````````````````````````````````````````````````````````````````````
|
||||
|
||||
* What is it? *
|
||||
## What is it?
|
||||
|
||||
Chocolate Strife is the most accurate and complete recreation of Rogue
|
||||
Entertainment's "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.
|
||||
Entertainment’s “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? *
|
||||
## 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
|
||||
|
|
@ -32,7 +32,7 @@ resulting Chocolate Doom-based executable is as close as possible to the
|
|||
original.
|
||||
|
||||
|
||||
* Is it Legal? *
|
||||
## Is it Legal?
|
||||
|
||||
Chocolate Strife was originally reverse-engineered from the DOS Strife
|
||||
binaries. Although reverse engineering is legally a protected activity, this
|
||||
|
|
@ -45,9 +45,9 @@ 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? *
|
||||
## Is it Perfect?
|
||||
|
||||
Almost, but not entirely! That's where you come in. Help us by reporting any
|
||||
Almost, but not entirely! That’s where you come in. Help us by reporting any
|
||||
discrepancies you may notice between this executable and the vanilla DOS
|
||||
program!
|
||||
|
||||
|
|
@ -60,16 +60,20 @@ for example by initializing pointers to NULL rather than using them without
|
|||
setting a value first.
|
||||
|
||||
|
||||
* What are some known problems? *
|
||||
## 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 a much earlier beta version of Rogue's
|
||||
codebase). You should use a commercial Strife IWAD file, preferably of
|
||||
version 1.2 or later.
|
||||
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 Rogue’s
|
||||
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? *
|
||||
## 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
|
||||
|
|
@ -82,27 +86,27 @@ redundant and unnecessary.
|
|||
|
||||
Some new command-line parameters in Chocolate Strife include the following:
|
||||
|
||||
-nograph
|
||||
Disables the graphical introduction sequence. -devparm implies this.
|
||||
- -nograph
|
||||
- Disables the graphical introduction sequence. -devparm implies this.
|
||||
|
||||
-novoice
|
||||
Disables voices even if voices.wad can be found.
|
||||
- -novoice
|
||||
- Disables voices even if voices.wad can be found.
|
||||
|
||||
-work
|
||||
Enables Rogue's playtesting mode. Automatic godmode, and pressing the
|
||||
inventory drop key will toggle noclipping.
|
||||
- -work
|
||||
- Enables Rogue’s 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 engine's behavior).
|
||||
- -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 engine’s behavior).
|
||||
|
||||
-random
|
||||
Randomizes the timing and location of item respawns in deathmatch, when
|
||||
item respawning is enabled.
|
||||
- -random
|
||||
- Randomizes the timing and location of item respawns in deathmatch, when
|
||||
item respawning is enabled.
|
||||
|
||||
|
||||
* Copyright *
|
||||
## 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
|
||||
|
|
@ -113,9 +117,8 @@ 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
|
||||
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.
|
||||
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
# 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
|
||||
|
|
@ -6,35 +7,35 @@ 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 Doom's aims are:
|
||||
Chocolate Doom’s 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
|
||||
* 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 ==
|
||||
## Setting up gameplay
|
||||
|
||||
For instructions on how to set up Chocolate Doom for play, see the
|
||||
INSTALL file.
|
||||
|
||||
== Configuration File ==
|
||||
## Configuration File
|
||||
|
||||
Chocolate Doom is compatible with the DOS Doom configuration file
|
||||
(normally named 'default.cfg'). Existing configuration files for DOS
|
||||
(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'.
|
||||
separate file named `chocolate-doom.cfg`.
|
||||
|
||||
The configuration can be edited using the chocolate-setup tool.
|
||||
|
||||
== Command line options ==
|
||||
## 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
|
||||
|
|
@ -42,30 +43,34 @@ binary distributions, see the CMDLINE file included with your
|
|||
download; more information is also available on the Chocolate Doom
|
||||
website.
|
||||
|
||||
== Playing TCs ==
|
||||
## Playing TCs
|
||||
|
||||
With Vanilla Doom there is no way to include sprites in PWAD files.
|
||||
Chocolate Doom's '-file' command line option behaves exactly the same
|
||||
Chocolate Doom’s ‘-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.
|
||||
‘-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
|
||||
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
|
||||
```
|
||||
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)
|
||||
```
|
||||
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 ==
|
||||
## Other information
|
||||
|
||||
* Chocolate Doom includes a number of different options for music
|
||||
playback. See the README.Music file for more details.
|
||||
|
|
@ -97,6 +102,3 @@ Here are some examples:
|
|||
|
||||
* Please send any feedback, questions or suggestions to
|
||||
fraggle@gmail.com. Thanks!
|
||||
|
||||
# vim: tw=70
|
||||
|
||||
56
TODO
56
TODO
|
|
@ -1,56 +0,0 @@
|
|||
To do:
|
||||
|
||||
* Multiplayer:
|
||||
- Use UPnP to automatically configure port forwarding for NATted
|
||||
networks.
|
||||
- Multiplayer options and configuration file (server name, etc)
|
||||
* Improve multiplayer startup:
|
||||
- Select an IWAD automatically from the server's 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)
|
||||
- Don't make structure packing assumptions when loading levels.
|
||||
- Port to every OS and architecture under the sun
|
||||
|
||||
Heretic/Hexen:
|
||||
* Frequency shifted sounds.
|
||||
* Check for endianness assumptions - mostly done now
|
||||
* Structure packing macros for structures read from disk
|
||||
* Merge r_draw.c to common version and delete duplicate
|
||||
* Heretic v1.2 emulation (if possible)
|
||||
* Hexen v1.0 emulation (if possible/necessary)
|
||||
* 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.
|
||||
* Video capture mode?
|
||||
|
||||
== OPL TODO list ==
|
||||
|
||||
Needs research:
|
||||
|
||||
* Strategy when no more voices are available is still wrong
|
||||
* Scale levels don't exactly match Vanilla (off-by-one?)
|
||||
|
||||
Bad MIDIs:
|
||||
|
||||
* doom2.wad MAP01
|
||||
* gothicdm MAP05
|
||||
* tnt.wad MAP30
|
||||
* Alien Vendetta (title screen, MAP01, etc)
|
||||
|
||||
Other tasks:
|
||||
|
||||
* Get a better software OPL emulator
|
||||
* DMXOPTIONS opl3/phase option support.
|
||||
|
||||
# vim: tw=70
|
||||
|
||||
36
TODO.md
Normal file
36
TODO.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
This is Chocolate Doom’s “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 server’s 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)
|
||||
- Don’t 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.
|
||||
47
opl/opl3.c
47
opl/opl3.c
|
|
@ -21,37 +21,7 @@
|
|||
// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
// OPL2 ROMs.
|
||||
//
|
||||
// version: 1.7
|
||||
//
|
||||
// Changelog:
|
||||
//
|
||||
// v1.1:
|
||||
// Vibrato's sign fix.
|
||||
// v1.2:
|
||||
// Operator key fix.
|
||||
// Corrected 4-operator mode.
|
||||
// Corrected rhythm mode.
|
||||
// Some small fixes.
|
||||
// v1.2.1:
|
||||
// Small envelope generator fix.
|
||||
// Removed EX_Get function(not used)
|
||||
// v1.3:
|
||||
// Complete rewrite.
|
||||
// v1.4:
|
||||
// New envelope and waveform generator.
|
||||
// Some small fixes.
|
||||
// v1.4.1:
|
||||
// Envelope generator rate calculation fix.
|
||||
// v1.4.2:
|
||||
// Version for ZDoom.
|
||||
// v1.5:
|
||||
// Optimizations.
|
||||
// v1.6:
|
||||
// Improved emulation output.
|
||||
// v1.6.1:
|
||||
// Simple YMF289(OPL3-L) emulation.
|
||||
// v1.7:
|
||||
// Version for Chocolate Doom.
|
||||
// version: 1.7.2
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -537,16 +507,13 @@ static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type)
|
|||
if (!slot->key)
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_attack;
|
||||
if ((slot->eg_rate >> 2) != 0x0f)
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_attack;
|
||||
}
|
||||
else
|
||||
OPL3_EnvelopeUpdateRate(slot);
|
||||
if ((slot->eg_rate >> 2) == 0x0f)
|
||||
{
|
||||
slot->eg_gen = envelope_gen_num_decay;
|
||||
OPL3_EnvelopeUpdateRate(slot);
|
||||
slot->eg_rout = 0x00;
|
||||
}
|
||||
OPL3_EnvelopeUpdateRate(slot);
|
||||
slot->pg_phase = 0x00;
|
||||
}
|
||||
slot->key |= type;
|
||||
|
|
@ -683,7 +650,7 @@ static void OPL3_SlotGenerate(opl3_slot *slot)
|
|||
|
||||
static void OPL3_SlotGenerateZM(opl3_slot *slot)
|
||||
{
|
||||
OPL3_SlotGeneratePhase(slot, 0);
|
||||
OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9));
|
||||
}
|
||||
|
||||
static void OPL3_SlotCalcFB(opl3_slot *slot)
|
||||
|
|
@ -789,6 +756,8 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
|
|||
{
|
||||
chip->channel[chnum].chtype = ch_2op;
|
||||
OPL3_ChannelSetupAlg(&chip->channel[chnum]);
|
||||
OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1084,7 +1053,7 @@ static void OPL3_GenerateRhythm1(opl3_chip *chip)
|
|||
| (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00;
|
||||
//hh
|
||||
phase = (phasebit << 9)
|
||||
| (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1)));
|
||||
| (0x34 << ((phasebit ^ (chip->noise & 0x01)) << 1));
|
||||
OPL3_SlotGeneratePhase(channel7->slots[0], phase);
|
||||
//tt
|
||||
OPL3_SlotGenerateZM(channel8->slots[0]);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
// OPL2 ROMs.
|
||||
//
|
||||
// version: 1.7
|
||||
// version: 1.7.2
|
||||
//
|
||||
|
||||
#ifndef OPL_OPL3_H
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
|
|||
|
||||
# Documentation files to distribute with packages.
|
||||
|
||||
DOC_FILES = README \
|
||||
README.Music \
|
||||
COPYING \
|
||||
ChangeLog \
|
||||
NEWS
|
||||
DOC_FILES = README.md \
|
||||
README.Music.md \
|
||||
COPYING \
|
||||
NEWS.md
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
include ../config.make
|
||||
|
||||
DOC_FILES += README.Strife NOT-BUGS
|
||||
DOC_FILES += README.Strife.md NOT-BUGS.md
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.7
|
||||
|
||||
|
|
@ -71,6 +71,7 @@ $(STAGING_DIR): launcher $(TOPLEVEL_DOCS)
|
|||
mkdir -p "$(APP_DOC_DIR)"
|
||||
cp $(TOPLEVEL_DOCS) "$(APP_DOC_DIR)"
|
||||
|
||||
mv "$(APP_DOC_DIR)/README.md" "$(APP_DOC_DIR)/README"
|
||||
ln -s "$(APP_DOC_RELDIR)/COPYING" "$(STAGING_DIR)/Software License"
|
||||
ln -s "$(APP_DOC_RELDIR)/README" "$(STAGING_DIR)/README"
|
||||
ln -s /Applications "$(STAGING_DIR)"
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ $(STRIFE_ZIP): staging-strife hook-strife
|
|||
# Special hooks to custom modify files for particular games.
|
||||
|
||||
hook-doom: staging-doom
|
||||
cp $(TOPLEVEL)/NOT-BUGS $</NOT-BUGS.txt
|
||||
cp $(TOPLEVEL)/NOT-BUGS.md $</NOT-BUGS.txt
|
||||
|
||||
# Chocolate Strife has its own custom README file:
|
||||
|
||||
hook-strife: staging-strife
|
||||
cp $(TOPLEVEL)/README.Strife $</README.txt
|
||||
cp $(TOPLEVEL)/README.Strife.md $</README.txt
|
||||
|
||||
# Build up a staging dir for a particular game.
|
||||
|
||||
|
|
@ -45,8 +45,8 @@ staging-%:
|
|||
$@/$(PROGRAM_PREFIX)$*-setup.exe
|
||||
$(STRIP) $@/*.exe
|
||||
|
||||
for f in $(DOC_FILES); do \
|
||||
cp $(TOPLEVEL)/$$f $@/$$f.txt; \
|
||||
for f in $(DOC_FILES); do \
|
||||
cp $(TOPLEVEL)/$$f $@/$$(basename $$f .md).txt; \
|
||||
done
|
||||
cp $(TOPLEVEL)/man/CMDLINE.$* $@/CMDLINE.txt
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ make
|
|||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%description
|
||||
%(sed -n "/==/ q; p " < README)
|
||||
%(sed -n "/##/ q; p " < README.md)
|
||||
|
||||
See @PACKAGE_URL@ for more information.
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0
|
|||
/usr/share/applications/*
|
||||
|
||||
%description -n @PROGRAM_PREFIX@heretic
|
||||
%(sed -n "/==/ q; p " < README)
|
||||
%(sed -n "/##/ q; p " < README.md)
|
||||
|
||||
These are the Heretic binaries.
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ Group: Amusements/Games
|
|||
Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0
|
||||
|
||||
%description -n @PROGRAM_PREFIX@hexen
|
||||
%(sed -n "/==/ q; p " < README)
|
||||
%(sed -n "/##/ q; p " < README.md)
|
||||
|
||||
These are the Hexen binaries.
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ Group: Amusements/Games
|
|||
Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0
|
||||
|
||||
%description -n @PROGRAM_PREFIX@strife
|
||||
%(sed -n "/==/ q; p " < README)
|
||||
%(sed -n "/##/ q; p " < README.md)
|
||||
|
||||
These are the Strife binaries.
|
||||
|
||||
|
|
|
|||
|
|
@ -697,11 +697,12 @@ AM_Responder
|
|||
rc = false;
|
||||
}
|
||||
|
||||
if (!deathmatch && cht_CheckCheat(&cheat_amap, ev->data2))
|
||||
{
|
||||
rc = false;
|
||||
cheating = (cheating+1) % 3;
|
||||
}
|
||||
if ((!deathmatch || gameversion <= exe_doom_1_8)
|
||||
&& cht_CheckCheat(&cheat_amap, ev->data2))
|
||||
{
|
||||
rc = false;
|
||||
cheating = (cheating + 1) % 3;
|
||||
}
|
||||
}
|
||||
else if (ev->type == ev_keyup)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ void D_DoAdvanceDemo (void)
|
|||
{
|
||||
pagetic = 200;
|
||||
|
||||
if ( gamemode == retail )
|
||||
if (gameversion >= exe_ultimate)
|
||||
pagename = DEH_String("CREDIT");
|
||||
else
|
||||
pagename = DEH_String("HELP2");
|
||||
|
|
|
|||
|
|
@ -671,7 +671,7 @@ static void F_ArtScreenDrawer(void)
|
|||
switch (gameepisode)
|
||||
{
|
||||
case 1:
|
||||
if (gamemode == retail)
|
||||
if (gameversion >= exe_ultimate)
|
||||
{
|
||||
lumpname = "CREDIT";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -750,74 +750,9 @@ void M_QuickLoad(void)
|
|||
//
|
||||
void M_DrawReadThis1(void)
|
||||
{
|
||||
char *lumpname = "CREDIT";
|
||||
int skullx = 330, skully = 175;
|
||||
|
||||
inhelpscreens = true;
|
||||
|
||||
// Different versions of Doom 1.9 work differently
|
||||
|
||||
switch (gameversion)
|
||||
{
|
||||
case exe_doom_1_666:
|
||||
case exe_doom_1_7:
|
||||
case exe_doom_1_8:
|
||||
case exe_doom_1_9:
|
||||
case exe_hacx:
|
||||
|
||||
if (gamemode == commercial)
|
||||
{
|
||||
// Doom 2
|
||||
|
||||
lumpname = "HELP";
|
||||
|
||||
skullx = 330;
|
||||
skully = 165;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Doom 1
|
||||
// HELP2 is the first screen shown in Doom 1
|
||||
|
||||
lumpname = "HELP2";
|
||||
|
||||
skullx = 280;
|
||||
skully = 185;
|
||||
}
|
||||
break;
|
||||
|
||||
case exe_ultimate:
|
||||
case exe_chex:
|
||||
|
||||
// Ultimate Doom always displays "HELP1".
|
||||
|
||||
// Chex Quest version also uses "HELP1", even though it is based
|
||||
// on Final Doom.
|
||||
|
||||
lumpname = "HELP1";
|
||||
|
||||
break;
|
||||
|
||||
case exe_final:
|
||||
case exe_final2:
|
||||
|
||||
// Final Doom always displays "HELP".
|
||||
|
||||
lumpname = "HELP";
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
I_Error("Unhandled game version");
|
||||
break;
|
||||
}
|
||||
|
||||
lumpname = DEH_String(lumpname);
|
||||
|
||||
V_DrawPatchDirect (0, 0, W_CacheLumpName(lumpname, PU_CACHE));
|
||||
|
||||
ReadDef1.x = skullx;
|
||||
ReadDef1.y = skully;
|
||||
V_DrawPatchDirect(0, 0, W_CacheLumpName(DEH_String("HELP2"), PU_CACHE));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -835,6 +770,13 @@ void M_DrawReadThis2(void)
|
|||
V_DrawPatchDirect(0, 0, W_CacheLumpName(DEH_String("HELP1"), PU_CACHE));
|
||||
}
|
||||
|
||||
void M_DrawReadThisCommercial(void)
|
||||
{
|
||||
inhelpscreens = true;
|
||||
|
||||
V_DrawPatchDirect(0, 0, W_CacheLumpName(DEH_String("HELP"), PU_CACHE));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Change Sfx & Music volumes
|
||||
|
|
@ -971,15 +913,6 @@ void M_Episode(int choice)
|
|||
return;
|
||||
}
|
||||
|
||||
// Yet another hack...
|
||||
if ( (gamemode == registered)
|
||||
&& (choice > 2))
|
||||
{
|
||||
fprintf( stderr,
|
||||
"M_Episode: 4th episode requires UltimateDOOM\n");
|
||||
choice = 0;
|
||||
}
|
||||
|
||||
epi = choice;
|
||||
M_SetupNextMenu(&NewDef);
|
||||
}
|
||||
|
|
@ -1082,20 +1015,8 @@ void M_ReadThis(int choice)
|
|||
|
||||
void M_ReadThis2(int choice)
|
||||
{
|
||||
// Doom 1.9 had two menus when playing Doom 1
|
||||
// All others had only one
|
||||
|
||||
if (gameversion <= exe_doom_1_9 && gamemode != commercial)
|
||||
{
|
||||
choice = 0;
|
||||
M_SetupNextMenu(&ReadDef2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Close the menu
|
||||
|
||||
M_FinishReadThis(0);
|
||||
}
|
||||
choice = 0;
|
||||
M_SetupNextMenu(&ReadDef2);
|
||||
}
|
||||
|
||||
void M_FinishReadThis(int choice)
|
||||
|
|
@ -1692,7 +1613,7 @@ boolean M_Responder (event_t* ev)
|
|||
{
|
||||
M_StartControlPanel ();
|
||||
|
||||
if ( gamemode == retail )
|
||||
if (gameversion >= exe_ultimate)
|
||||
currentMenu = &ReadDef2;
|
||||
else
|
||||
currentMenu = &ReadDef1;
|
||||
|
|
@ -2107,25 +2028,29 @@ void M_Init (void)
|
|||
// Here we could catch other version dependencies,
|
||||
// like HELP1/2, and four episodes.
|
||||
|
||||
|
||||
switch ( gamemode )
|
||||
// The same hacks were used in the original Doom EXEs.
|
||||
|
||||
if (gameversion >= exe_ultimate)
|
||||
{
|
||||
case commercial:
|
||||
// Commercial has no "read this" entry.
|
||||
MainMenu[readthis] = MainMenu[quitdoom];
|
||||
MainDef.numitems--;
|
||||
MainDef.y += 8;
|
||||
NewDef.prevMenu = &MainDef;
|
||||
break;
|
||||
case shareware:
|
||||
// Episode 2 and 3 are handled,
|
||||
// branching to an ad screen.
|
||||
case registered:
|
||||
break;
|
||||
case retail:
|
||||
// We are fine.
|
||||
default:
|
||||
break;
|
||||
MainMenu[readthis].routine = M_ReadThis2;
|
||||
ReadDef2.prevMenu = NULL;
|
||||
}
|
||||
|
||||
if (gameversion >= exe_final && gameversion <= exe_final2)
|
||||
{
|
||||
ReadDef2.routine = M_DrawReadThisCommercial;
|
||||
}
|
||||
|
||||
if (gamemode == commercial)
|
||||
{
|
||||
MainMenu[readthis] = MainMenu[quitdoom];
|
||||
MainDef.numitems--;
|
||||
MainDef.y += 8;
|
||||
NewDef.prevMenu = &MainDef;
|
||||
ReadDef1.routine = M_DrawReadThisCommercial;
|
||||
ReadDef1.x = 330;
|
||||
ReadDef1.y = 165;
|
||||
ReadMenu1[rdthsempty1].routine = M_FinishReadThis;
|
||||
}
|
||||
|
||||
// Versions of doom.exe before the Ultimate Doom release only had
|
||||
|
|
@ -2134,7 +2059,12 @@ void M_Init (void)
|
|||
// (should crash if missing).
|
||||
if (gameversion < exe_ultimate)
|
||||
{
|
||||
EpiDef.numitems--;
|
||||
EpiDef.numitems--;
|
||||
}
|
||||
// chex.exe shows only one episode.
|
||||
else if (gameversion == exe_chex)
|
||||
{
|
||||
EpiDef.numitems = 1;
|
||||
}
|
||||
|
||||
opldev = M_CheckParm("-opldev") > 0;
|
||||
|
|
|
|||
|
|
@ -1,356 +1,356 @@
|
|||
/*
|
||||
|
||||
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.
|
||||
|
||||
--
|
||||
|
||||
Functions for presenting the information captured from the statistics
|
||||
buffer to a file.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "d_player.h"
|
||||
#include "d_mode.h"
|
||||
#include "m_argv.h"
|
||||
|
||||
#include "statdump.h"
|
||||
|
||||
/* Par times for E1M1-E1M9. */
|
||||
static const int doom1_par_times[] =
|
||||
{
|
||||
30, 75, 120, 90, 165, 180, 180, 30, 165,
|
||||
};
|
||||
|
||||
/* Par times for MAP01-MAP09. */
|
||||
static const int doom2_par_times[] =
|
||||
{
|
||||
30, 90, 120, 120, 90, 150, 120, 120, 270,
|
||||
};
|
||||
|
||||
/* Player colors. */
|
||||
static const char *player_colors[] =
|
||||
{
|
||||
"Green", "Indigo", "Brown", "Red"
|
||||
};
|
||||
|
||||
// Array of end-of-level statistics that have been captured.
|
||||
|
||||
#define MAX_CAPTURES 32
|
||||
static wbstartstruct_t captured_stats[MAX_CAPTURES];
|
||||
static int num_captured_stats = 0;
|
||||
|
||||
static GameMission_t discovered_gamemission = none;
|
||||
|
||||
/* Try to work out whether this is a Doom 1 or Doom 2 game, by looking
|
||||
* at the episode and map, and the par times. This is used to decide
|
||||
* how to format the level name. Unfortunately, in some cases it is
|
||||
* impossible to determine whether this is Doom 1 or Doom 2. */
|
||||
|
||||
static void DiscoverGamemode(wbstartstruct_t *stats, int num_stats)
|
||||
{
|
||||
int partime;
|
||||
int level;
|
||||
int i;
|
||||
|
||||
if (discovered_gamemission != none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<num_stats; ++i)
|
||||
{
|
||||
level = stats[i].last;
|
||||
|
||||
/* If episode 2, 3 or 4, this is Doom 1. */
|
||||
|
||||
if (stats[i].epsd > 0)
|
||||
{
|
||||
discovered_gamemission = doom;
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is episode 1. If this is level 10 or higher,
|
||||
it must be Doom 2. */
|
||||
|
||||
if (level >= 9)
|
||||
{
|
||||
discovered_gamemission = doom2;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try to work out if this is Doom 1 or Doom 2 by looking
|
||||
at the par time. */
|
||||
|
||||
partime = stats[i].partime;
|
||||
|
||||
if (partime == doom1_par_times[level] * TICRATE
|
||||
&& partime != doom2_par_times[level] * TICRATE)
|
||||
{
|
||||
discovered_gamemission = doom;
|
||||
return;
|
||||
}
|
||||
|
||||
if (partime != doom1_par_times[level] * TICRATE
|
||||
&& partime == doom2_par_times[level] * TICRATE)
|
||||
{
|
||||
discovered_gamemission = doom2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the number of players active in the given stats buffer. */
|
||||
|
||||
static int GetNumPlayers(wbstartstruct_t *stats)
|
||||
{
|
||||
int i;
|
||||
int num_players = 0;
|
||||
|
||||
for (i=0; i<MAXPLAYERS; ++i)
|
||||
{
|
||||
if (stats->plyr[i].in)
|
||||
{
|
||||
++num_players;
|
||||
}
|
||||
}
|
||||
|
||||
return num_players;
|
||||
}
|
||||
|
||||
static void PrintBanner(FILE *stream)
|
||||
{
|
||||
fprintf(stream, "===========================================\n");
|
||||
}
|
||||
|
||||
static void PrintPercentage(FILE *stream, int amount, int total)
|
||||
{
|
||||
if (total == 0)
|
||||
{
|
||||
fprintf(stream, "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "%i / %i", amount, total);
|
||||
|
||||
// statdump.exe is a 16-bit program, so very occasionally an
|
||||
// integer overflow can occur when doing this calculation with
|
||||
// a large value. Therefore, cast to short to give the same
|
||||
// output.
|
||||
|
||||
fprintf(stream, " (%i%%)", (short) (amount * 100) / total);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display statistics for a single player. */
|
||||
|
||||
static void PrintPlayerStats(FILE *stream, wbstartstruct_t *stats,
|
||||
int player_num)
|
||||
{
|
||||
wbplayerstruct_t *player = &stats->plyr[player_num];
|
||||
|
||||
fprintf(stream, "Player %i (%s):\n", player_num + 1,
|
||||
player_colors[player_num]);
|
||||
|
||||
/* Kills percentage */
|
||||
|
||||
fprintf(stream, "\tKills: ");
|
||||
PrintPercentage(stream, player->skills, stats->maxkills);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
/* Items percentage */
|
||||
|
||||
fprintf(stream, "\tItems: ");
|
||||
PrintPercentage(stream, player->sitems, stats->maxitems);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
/* Secrets percentage */
|
||||
|
||||
fprintf(stream, "\tSecrets: ");
|
||||
PrintPercentage(stream, player->ssecret, stats->maxsecret);
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
/* Frags table for multiplayer games. */
|
||||
|
||||
static void PrintFragsTable(FILE *stream, wbstartstruct_t *stats)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
fprintf(stream, "Frags:\n");
|
||||
|
||||
/* Print header */
|
||||
|
||||
fprintf(stream, "\t\t");
|
||||
|
||||
for (x=0; x<MAXPLAYERS; ++x)
|
||||
{
|
||||
|
||||
if (!stats->plyr[x].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "%s\t", player_colors[x]);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
|
||||
fprintf(stream, "\t\t-------------------------------- VICTIMS\n");
|
||||
|
||||
/* Print table */
|
||||
|
||||
for (y=0; y<MAXPLAYERS; ++y)
|
||||
{
|
||||
if (!stats->plyr[y].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "\t%s\t|", player_colors[y]);
|
||||
|
||||
for (x=0; x<MAXPLAYERS; ++x)
|
||||
{
|
||||
if (!stats->plyr[x].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "%i\t", stats->plyr[y].frags[x]);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
fprintf(stream, "\t\t|\n");
|
||||
fprintf(stream, "\t KILLERS\n");
|
||||
}
|
||||
|
||||
/* Displays the level name: MAPxy or ExMy, depending on game mode. */
|
||||
|
||||
static void PrintLevelName(FILE *stream, int episode, int level)
|
||||
{
|
||||
PrintBanner(stream);
|
||||
|
||||
switch (discovered_gamemission)
|
||||
{
|
||||
|
||||
case doom:
|
||||
fprintf(stream, "E%iM%i\n", episode + 1, level + 1);
|
||||
break;
|
||||
case doom2:
|
||||
fprintf(stream, "MAP%02i\n", level + 1);
|
||||
break;
|
||||
default:
|
||||
case none:
|
||||
fprintf(stream, "E%iM%i / MAP%02i\n",
|
||||
episode + 1, level + 1, level + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
PrintBanner(stream);
|
||||
}
|
||||
|
||||
/* Print details of a statistics buffer to the given file. */
|
||||
|
||||
static void PrintStats(FILE *stream, wbstartstruct_t *stats)
|
||||
{
|
||||
int leveltime, partime;
|
||||
int i;
|
||||
|
||||
PrintLevelName(stream, stats->epsd, stats->last);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
leveltime = stats->plyr[0].stime / TICRATE;
|
||||
partime = stats->partime / TICRATE;
|
||||
fprintf(stream, "Time: %i:%02i", leveltime / 60, leveltime % 60);
|
||||
fprintf(stream, " (par: %i:%02i)\n", partime / 60, partime % 60);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
for (i=0; i<MAXPLAYERS; ++i)
|
||||
{
|
||||
if (stats->plyr[i].in)
|
||||
{
|
||||
PrintPlayerStats(stream, stats, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetNumPlayers(stats) >= 2)
|
||||
{
|
||||
PrintFragsTable(stream, stats);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
void StatCopy(wbstartstruct_t *stats)
|
||||
{
|
||||
if (M_ParmExists("-statdump") && num_captured_stats < MAX_CAPTURES)
|
||||
{
|
||||
memcpy(&captured_stats[num_captured_stats], stats,
|
||||
sizeof(wbstartstruct_t));
|
||||
++num_captured_stats;
|
||||
}
|
||||
}
|
||||
|
||||
void StatDump(void)
|
||||
{
|
||||
FILE *dumpfile;
|
||||
int i;
|
||||
|
||||
//!
|
||||
// @category compat
|
||||
// @arg <filename>
|
||||
//
|
||||
// Dump statistics information to the specified file on the levels
|
||||
// that were played. The output from this option matches the output
|
||||
// from statdump.exe (see ctrlapi.zip in the /idgames archive).
|
||||
//
|
||||
|
||||
i = M_CheckParmWithArgs("-statdump", 1);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
printf("Statistics captured for %i level(s)\n", num_captured_stats);
|
||||
|
||||
// We actually know what the real gamemission is, but this has
|
||||
// to match the output from statdump.exe.
|
||||
|
||||
DiscoverGamemode(captured_stats, num_captured_stats);
|
||||
|
||||
// Allow "-" as output file, for stdout.
|
||||
|
||||
if (strcmp(myargv[i + 1], "-") != 0)
|
||||
{
|
||||
dumpfile = fopen(myargv[i + 1], "w");
|
||||
}
|
||||
else
|
||||
{
|
||||
dumpfile = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_captured_stats; ++i)
|
||||
{
|
||||
PrintStats(dumpfile, &captured_stats[i]);
|
||||
}
|
||||
|
||||
if (dumpfile != NULL)
|
||||
{
|
||||
fclose(dumpfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
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.
|
||||
|
||||
--
|
||||
|
||||
Functions for presenting the information captured from the statistics
|
||||
buffer to a file.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "d_player.h"
|
||||
#include "d_mode.h"
|
||||
#include "m_argv.h"
|
||||
|
||||
#include "statdump.h"
|
||||
|
||||
/* Par times for E1M1-E1M9. */
|
||||
static const int doom1_par_times[] =
|
||||
{
|
||||
30, 75, 120, 90, 165, 180, 180, 30, 165,
|
||||
};
|
||||
|
||||
/* Par times for MAP01-MAP09. */
|
||||
static const int doom2_par_times[] =
|
||||
{
|
||||
30, 90, 120, 120, 90, 150, 120, 120, 270,
|
||||
};
|
||||
|
||||
/* Player colors. */
|
||||
static const char *player_colors[] =
|
||||
{
|
||||
"Green", "Indigo", "Brown", "Red"
|
||||
};
|
||||
|
||||
// Array of end-of-level statistics that have been captured.
|
||||
|
||||
#define MAX_CAPTURES 32
|
||||
static wbstartstruct_t captured_stats[MAX_CAPTURES];
|
||||
static int num_captured_stats = 0;
|
||||
|
||||
static GameMission_t discovered_gamemission = none;
|
||||
|
||||
/* Try to work out whether this is a Doom 1 or Doom 2 game, by looking
|
||||
* at the episode and map, and the par times. This is used to decide
|
||||
* how to format the level name. Unfortunately, in some cases it is
|
||||
* impossible to determine whether this is Doom 1 or Doom 2. */
|
||||
|
||||
static void DiscoverGamemode(wbstartstruct_t *stats, int num_stats)
|
||||
{
|
||||
int partime;
|
||||
int level;
|
||||
int i;
|
||||
|
||||
if (discovered_gamemission != none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<num_stats; ++i)
|
||||
{
|
||||
level = stats[i].last;
|
||||
|
||||
/* If episode 2, 3 or 4, this is Doom 1. */
|
||||
|
||||
if (stats[i].epsd > 0)
|
||||
{
|
||||
discovered_gamemission = doom;
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is episode 1. If this is level 10 or higher,
|
||||
it must be Doom 2. */
|
||||
|
||||
if (level >= 9)
|
||||
{
|
||||
discovered_gamemission = doom2;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try to work out if this is Doom 1 or Doom 2 by looking
|
||||
at the par time. */
|
||||
|
||||
partime = stats[i].partime;
|
||||
|
||||
if (partime == doom1_par_times[level] * TICRATE
|
||||
&& partime != doom2_par_times[level] * TICRATE)
|
||||
{
|
||||
discovered_gamemission = doom;
|
||||
return;
|
||||
}
|
||||
|
||||
if (partime != doom1_par_times[level] * TICRATE
|
||||
&& partime == doom2_par_times[level] * TICRATE)
|
||||
{
|
||||
discovered_gamemission = doom2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the number of players active in the given stats buffer. */
|
||||
|
||||
static int GetNumPlayers(wbstartstruct_t *stats)
|
||||
{
|
||||
int i;
|
||||
int num_players = 0;
|
||||
|
||||
for (i=0; i<MAXPLAYERS; ++i)
|
||||
{
|
||||
if (stats->plyr[i].in)
|
||||
{
|
||||
++num_players;
|
||||
}
|
||||
}
|
||||
|
||||
return num_players;
|
||||
}
|
||||
|
||||
static void PrintBanner(FILE *stream)
|
||||
{
|
||||
fprintf(stream, "===========================================\n");
|
||||
}
|
||||
|
||||
static void PrintPercentage(FILE *stream, int amount, int total)
|
||||
{
|
||||
if (total == 0)
|
||||
{
|
||||
fprintf(stream, "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "%i / %i", amount, total);
|
||||
|
||||
// statdump.exe is a 16-bit program, so very occasionally an
|
||||
// integer overflow can occur when doing this calculation with
|
||||
// a large value. Therefore, cast to short to give the same
|
||||
// output.
|
||||
|
||||
fprintf(stream, " (%i%%)", (short) (amount * 100) / total);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display statistics for a single player. */
|
||||
|
||||
static void PrintPlayerStats(FILE *stream, wbstartstruct_t *stats,
|
||||
int player_num)
|
||||
{
|
||||
wbplayerstruct_t *player = &stats->plyr[player_num];
|
||||
|
||||
fprintf(stream, "Player %i (%s):\n", player_num + 1,
|
||||
player_colors[player_num]);
|
||||
|
||||
/* Kills percentage */
|
||||
|
||||
fprintf(stream, "\tKills: ");
|
||||
PrintPercentage(stream, player->skills, stats->maxkills);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
/* Items percentage */
|
||||
|
||||
fprintf(stream, "\tItems: ");
|
||||
PrintPercentage(stream, player->sitems, stats->maxitems);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
/* Secrets percentage */
|
||||
|
||||
fprintf(stream, "\tSecrets: ");
|
||||
PrintPercentage(stream, player->ssecret, stats->maxsecret);
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
/* Frags table for multiplayer games. */
|
||||
|
||||
static void PrintFragsTable(FILE *stream, wbstartstruct_t *stats)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
fprintf(stream, "Frags:\n");
|
||||
|
||||
/* Print header */
|
||||
|
||||
fprintf(stream, "\t\t");
|
||||
|
||||
for (x=0; x<MAXPLAYERS; ++x)
|
||||
{
|
||||
|
||||
if (!stats->plyr[x].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "%s\t", player_colors[x]);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
|
||||
fprintf(stream, "\t\t-------------------------------- VICTIMS\n");
|
||||
|
||||
/* Print table */
|
||||
|
||||
for (y=0; y<MAXPLAYERS; ++y)
|
||||
{
|
||||
if (!stats->plyr[y].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "\t%s\t|", player_colors[y]);
|
||||
|
||||
for (x=0; x<MAXPLAYERS; ++x)
|
||||
{
|
||||
if (!stats->plyr[x].in)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stream, "%i\t", stats->plyr[y].frags[x]);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
fprintf(stream, "\t\t|\n");
|
||||
fprintf(stream, "\t KILLERS\n");
|
||||
}
|
||||
|
||||
/* Displays the level name: MAPxy or ExMy, depending on game mode. */
|
||||
|
||||
static void PrintLevelName(FILE *stream, int episode, int level)
|
||||
{
|
||||
PrintBanner(stream);
|
||||
|
||||
switch (discovered_gamemission)
|
||||
{
|
||||
|
||||
case doom:
|
||||
fprintf(stream, "E%iM%i\n", episode + 1, level + 1);
|
||||
break;
|
||||
case doom2:
|
||||
fprintf(stream, "MAP%02i\n", level + 1);
|
||||
break;
|
||||
default:
|
||||
case none:
|
||||
fprintf(stream, "E%iM%i / MAP%02i\n",
|
||||
episode + 1, level + 1, level + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
PrintBanner(stream);
|
||||
}
|
||||
|
||||
/* Print details of a statistics buffer to the given file. */
|
||||
|
||||
static void PrintStats(FILE *stream, wbstartstruct_t *stats)
|
||||
{
|
||||
int leveltime, partime;
|
||||
int i;
|
||||
|
||||
PrintLevelName(stream, stats->epsd, stats->last);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
leveltime = stats->plyr[0].stime / TICRATE;
|
||||
partime = stats->partime / TICRATE;
|
||||
fprintf(stream, "Time: %i:%02i", leveltime / 60, leveltime % 60);
|
||||
fprintf(stream, " (par: %i:%02i)\n", partime / 60, partime % 60);
|
||||
fprintf(stream, "\n");
|
||||
|
||||
for (i=0; i<MAXPLAYERS; ++i)
|
||||
{
|
||||
if (stats->plyr[i].in)
|
||||
{
|
||||
PrintPlayerStats(stream, stats, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetNumPlayers(stats) >= 2)
|
||||
{
|
||||
PrintFragsTable(stream, stats);
|
||||
}
|
||||
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
void StatCopy(wbstartstruct_t *stats)
|
||||
{
|
||||
if (M_ParmExists("-statdump") && num_captured_stats < MAX_CAPTURES)
|
||||
{
|
||||
memcpy(&captured_stats[num_captured_stats], stats,
|
||||
sizeof(wbstartstruct_t));
|
||||
++num_captured_stats;
|
||||
}
|
||||
}
|
||||
|
||||
void StatDump(void)
|
||||
{
|
||||
FILE *dumpfile;
|
||||
int i;
|
||||
|
||||
//!
|
||||
// @category compat
|
||||
// @arg <filename>
|
||||
//
|
||||
// Dump statistics information to the specified file on the levels
|
||||
// that were played. The output from this option matches the output
|
||||
// from statdump.exe (see ctrlapi.zip in the /idgames archive).
|
||||
//
|
||||
|
||||
i = M_CheckParmWithArgs("-statdump", 1);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
printf("Statistics captured for %i level(s)\n", num_captured_stats);
|
||||
|
||||
// We actually know what the real gamemission is, but this has
|
||||
// to match the output from statdump.exe.
|
||||
|
||||
DiscoverGamemode(captured_stats, num_captured_stats);
|
||||
|
||||
// Allow "-" as output file, for stdout.
|
||||
|
||||
if (strcmp(myargv[i + 1], "-") != 0)
|
||||
{
|
||||
dumpfile = fopen(myargv[i + 1], "w");
|
||||
}
|
||||
else
|
||||
{
|
||||
dumpfile = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_captured_stats; ++i)
|
||||
{
|
||||
PrintStats(dumpfile, &captured_stats[i]);
|
||||
}
|
||||
|
||||
if (dumpfile != NULL)
|
||||
{
|
||||
fclose(dumpfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
/*
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DOOM_STATDUMP_H
|
||||
#define DOOM_STATDUMP_H
|
||||
|
||||
void StatCopy(wbstartstruct_t *stats);
|
||||
void StatDump(void);
|
||||
|
||||
#endif /* #ifndef DOOM_STATDUMP_H */
|
||||
/*
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DOOM_STATDUMP_H
|
||||
#define DOOM_STATDUMP_H
|
||||
|
||||
void StatCopy(wbstartstruct_t *stats);
|
||||
void StatDump(void);
|
||||
|
||||
#endif /* #ifndef DOOM_STATDUMP_H */
|
||||
|
|
|
|||
|
|
@ -1687,7 +1687,7 @@ static void WI_loadUnloadData(load_callback_t callback)
|
|||
{
|
||||
M_StringCopy(name, DEH_String("INTERPIC"), sizeof(name));
|
||||
}
|
||||
else if (gamemode == retail && wbs->epsd == 3)
|
||||
else if (gameversion >= exe_ultimate && wbs->epsd == 3)
|
||||
{
|
||||
M_StringCopy(name, DEH_String("INTERPIC"), sizeof(name));
|
||||
}
|
||||
|
|
@ -1781,7 +1781,7 @@ void WI_initVariables(wbstartstruct_t* wbstartstruct)
|
|||
#ifdef RANGECHECKING
|
||||
if (gamemode != commercial)
|
||||
{
|
||||
if ( gamemode == retail )
|
||||
if (gameversion >= exe_ultimate)
|
||||
RNGCHECK(wbs->epsd, 0, 3);
|
||||
else
|
||||
RNGCHECK(wbs->epsd, 0, 2);
|
||||
|
|
|
|||
1056
src/strife/m_saves.c
1056
src/strife/m_saves.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,56 +1,56 @@
|
|||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 2010 James Haley, Samuel Villareal
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// [STRIFE] New Module
|
||||
//
|
||||
// Strife Hub Saving Code
|
||||
//
|
||||
|
||||
#ifndef M_SAVES_H__
|
||||
#define M_SAVES_H__
|
||||
|
||||
#define CHARACTER_NAME_LEN 32
|
||||
|
||||
extern char *savepath;
|
||||
extern char *savepathtemp;
|
||||
extern char *loadpath;
|
||||
extern char character_name[CHARACTER_NAME_LEN];
|
||||
|
||||
// Strife Savegame Functions
|
||||
void ClearTmp(void);
|
||||
void ClearSlot(void);
|
||||
void FromCurr(void);
|
||||
void ToCurr(void);
|
||||
void M_SaveMoveMapToHere(void);
|
||||
void M_SaveMoveHereToMap(void);
|
||||
|
||||
boolean M_SaveMisObj(const char *path);
|
||||
void M_ReadMisObj(void);
|
||||
|
||||
// Custom Utilities for Filepath Handling
|
||||
void *M_Calloc(size_t n1, size_t n2);
|
||||
void M_NormalizeSlashes(char *str);
|
||||
int M_StringAlloc(char **str, int numstrs, size_t extra, const char *str1, ...);
|
||||
char *M_SafeFilePath(const char *basepath, const char *newcomponent);
|
||||
char M_GetFilePath(const char *fn, char *dest, size_t len);
|
||||
char *M_MakeStrifeSaveDir(int slotnum, const char *extra);
|
||||
void M_CreateSaveDirs(const char *savedir);
|
||||
|
||||
#endif
|
||||
|
||||
// EOF
|
||||
|
||||
|
||||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 2010 James Haley, Samuel Villareal
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// [STRIFE] New Module
|
||||
//
|
||||
// Strife Hub Saving Code
|
||||
//
|
||||
|
||||
#ifndef M_SAVES_H__
|
||||
#define M_SAVES_H__
|
||||
|
||||
#define CHARACTER_NAME_LEN 32
|
||||
|
||||
extern char *savepath;
|
||||
extern char *savepathtemp;
|
||||
extern char *loadpath;
|
||||
extern char character_name[CHARACTER_NAME_LEN];
|
||||
|
||||
// Strife Savegame Functions
|
||||
void ClearTmp(void);
|
||||
void ClearSlot(void);
|
||||
void FromCurr(void);
|
||||
void ToCurr(void);
|
||||
void M_SaveMoveMapToHere(void);
|
||||
void M_SaveMoveHereToMap(void);
|
||||
|
||||
boolean M_SaveMisObj(const char *path);
|
||||
void M_ReadMisObj(void);
|
||||
|
||||
// Custom Utilities for Filepath Handling
|
||||
void *M_Calloc(size_t n1, size_t n2);
|
||||
void M_NormalizeSlashes(char *str);
|
||||
int M_StringAlloc(char **str, int numstrs, size_t extra, const char *str1, ...);
|
||||
char *M_SafeFilePath(const char *basepath, const char *newcomponent);
|
||||
char M_GetFilePath(const char *fn, char *dest, size_t len);
|
||||
char *M_MakeStrifeSaveDir(int slotnum, const char *extra);
|
||||
void M_CreateSaveDirs(const char *savedir);
|
||||
|
||||
#endif
|
||||
|
||||
// EOF
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,102 +1,102 @@
|
|||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 1996 Rogue Entertainment / Velocity, Inc.
|
||||
// Copyright(C) 2010 James Haley, Samuel Villareal
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// [STRIFE] New Module
|
||||
//
|
||||
// Dialog Engine for Strife
|
||||
//
|
||||
|
||||
#ifndef P_DIALOG_H__
|
||||
#define P_DIALOG_H__
|
||||
|
||||
#define OBJECTIVE_LEN 300
|
||||
|
||||
#define MAXINVENTORYSLOTS 30
|
||||
|
||||
#define MDLG_CHOICELEN 32
|
||||
#define MDLG_MSGLEN 80
|
||||
#define MDLG_NAMELEN 16
|
||||
#define MDLG_LUMPLEN 8
|
||||
#define MDLG_TEXTLEN 320
|
||||
#define MDLG_MAXCHOICES 5
|
||||
#define MDLG_MAXITEMS 3
|
||||
|
||||
extern char mission_objective[OBJECTIVE_LEN];
|
||||
|
||||
extern int dialogshowtext;
|
||||
|
||||
// villsa - convenient macro for giving objective logs to player
|
||||
#define GiveObjective(x, minlumpnum) \
|
||||
do { \
|
||||
int obj_ln = W_CheckNumForName(DEH_String(x)); \
|
||||
if(obj_ln > minlumpnum) \
|
||||
M_StringCopy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), \
|
||||
OBJECTIVE_LEN);\
|
||||
} while(0)
|
||||
|
||||
// haleyjd - voice and objective in one
|
||||
#define GiveVoiceObjective(voice, log, minlumpnum) \
|
||||
do { \
|
||||
int obj_ln = W_CheckNumForName(DEH_String(log)); \
|
||||
I_StartVoice(DEH_String(voice)); \
|
||||
if(obj_ln > minlumpnum) \
|
||||
M_StringCopy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), \
|
||||
OBJECTIVE_LEN);\
|
||||
} while(0)
|
||||
|
||||
typedef struct mapdlgchoice_s
|
||||
{
|
||||
int giveitem; // item given when successful
|
||||
int needitems[MDLG_MAXITEMS]; // item needed for success
|
||||
int needamounts[MDLG_MAXITEMS]; // amount of items needed
|
||||
char text[MDLG_CHOICELEN]; // normal text
|
||||
char textok[MDLG_MSGLEN]; // message given on success
|
||||
int next; // next dialog?
|
||||
int objective; // ???
|
||||
char textno[MDLG_MSGLEN]; // message given on failure
|
||||
} mapdlgchoice_t;
|
||||
|
||||
typedef struct mapdialog_s
|
||||
{
|
||||
int speakerid; // script ID# for mobjtype that will use this dialog
|
||||
int dropitem; // item to drop if that thingtype is killed
|
||||
int checkitem[MDLG_MAXITEMS]; // item(s) needed to see this dialog
|
||||
int jumptoconv; // conversation to jump to when... ?
|
||||
char name[MDLG_NAMELEN]; // name of speaker
|
||||
char voice[MDLG_LUMPLEN]; // voice file to play
|
||||
char backpic[MDLG_LUMPLEN]; // backdrop pic for character, if any
|
||||
char text[MDLG_TEXTLEN]; // main message text
|
||||
|
||||
// options that this dialog gives the player
|
||||
mapdlgchoice_t choices[MDLG_MAXCHOICES];
|
||||
} mapdialog_t;
|
||||
|
||||
void P_DialogLoad(void);
|
||||
void P_DialogStart(player_t *player);
|
||||
void P_DialogDoChoice(int choice);
|
||||
boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type);
|
||||
boolean P_GiveInventoryItem(player_t *player, int sprnum, mobjtype_t type);
|
||||
boolean P_UseInventoryItem(player_t* player, int item);
|
||||
void P_DialogStartP1(void);
|
||||
mapdialog_t* P_DialogFind(mobjtype_t type, int jumptoconv);
|
||||
int P_PlayerHasItem(player_t *player, mobjtype_t type);
|
||||
|
||||
#endif
|
||||
|
||||
// EOF
|
||||
|
||||
|
||||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 1996 Rogue Entertainment / Velocity, Inc.
|
||||
// Copyright(C) 2010 James Haley, Samuel Villareal
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// [STRIFE] New Module
|
||||
//
|
||||
// Dialog Engine for Strife
|
||||
//
|
||||
|
||||
#ifndef P_DIALOG_H__
|
||||
#define P_DIALOG_H__
|
||||
|
||||
#define OBJECTIVE_LEN 300
|
||||
|
||||
#define MAXINVENTORYSLOTS 30
|
||||
|
||||
#define MDLG_CHOICELEN 32
|
||||
#define MDLG_MSGLEN 80
|
||||
#define MDLG_NAMELEN 16
|
||||
#define MDLG_LUMPLEN 8
|
||||
#define MDLG_TEXTLEN 320
|
||||
#define MDLG_MAXCHOICES 5
|
||||
#define MDLG_MAXITEMS 3
|
||||
|
||||
extern char mission_objective[OBJECTIVE_LEN];
|
||||
|
||||
extern int dialogshowtext;
|
||||
|
||||
// villsa - convenient macro for giving objective logs to player
|
||||
#define GiveObjective(x, minlumpnum) \
|
||||
do { \
|
||||
int obj_ln = W_CheckNumForName(DEH_String(x)); \
|
||||
if(obj_ln > minlumpnum) \
|
||||
M_StringCopy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), \
|
||||
OBJECTIVE_LEN);\
|
||||
} while(0)
|
||||
|
||||
// haleyjd - voice and objective in one
|
||||
#define GiveVoiceObjective(voice, log, minlumpnum) \
|
||||
do { \
|
||||
int obj_ln = W_CheckNumForName(DEH_String(log)); \
|
||||
I_StartVoice(DEH_String(voice)); \
|
||||
if(obj_ln > minlumpnum) \
|
||||
M_StringCopy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), \
|
||||
OBJECTIVE_LEN);\
|
||||
} while(0)
|
||||
|
||||
typedef struct mapdlgchoice_s
|
||||
{
|
||||
int giveitem; // item given when successful
|
||||
int needitems[MDLG_MAXITEMS]; // item needed for success
|
||||
int needamounts[MDLG_MAXITEMS]; // amount of items needed
|
||||
char text[MDLG_CHOICELEN]; // normal text
|
||||
char textok[MDLG_MSGLEN]; // message given on success
|
||||
int next; // next dialog?
|
||||
int objective; // ???
|
||||
char textno[MDLG_MSGLEN]; // message given on failure
|
||||
} mapdlgchoice_t;
|
||||
|
||||
typedef struct mapdialog_s
|
||||
{
|
||||
int speakerid; // script ID# for mobjtype that will use this dialog
|
||||
int dropitem; // item to drop if that thingtype is killed
|
||||
int checkitem[MDLG_MAXITEMS]; // item(s) needed to see this dialog
|
||||
int jumptoconv; // conversation to jump to when... ?
|
||||
char name[MDLG_NAMELEN]; // name of speaker
|
||||
char voice[MDLG_LUMPLEN]; // voice file to play
|
||||
char backpic[MDLG_LUMPLEN]; // backdrop pic for character, if any
|
||||
char text[MDLG_TEXTLEN]; // main message text
|
||||
|
||||
// options that this dialog gives the player
|
||||
mapdlgchoice_t choices[MDLG_MAXCHOICES];
|
||||
} mapdialog_t;
|
||||
|
||||
void P_DialogLoad(void);
|
||||
void P_DialogStart(player_t *player);
|
||||
void P_DialogDoChoice(int choice);
|
||||
boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type);
|
||||
boolean P_GiveInventoryItem(player_t *player, int sprnum, mobjtype_t type);
|
||||
boolean P_UseInventoryItem(player_t* player, int item);
|
||||
void P_DialogStartP1(void);
|
||||
mapdialog_t* P_DialogFind(mobjtype_t type, int jumptoconv);
|
||||
int P_PlayerHasItem(player_t *player, mobjtype_t type);
|
||||
|
||||
#endif
|
||||
|
||||
// EOF
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -325,13 +325,15 @@ void P_AddActivePlat(plat_t* plat)
|
|||
int i;
|
||||
|
||||
for(i = 0; i < MAXPLATS; i++)
|
||||
{
|
||||
if (activeplats[i] == NULL)
|
||||
{
|
||||
activeplats[i] = plat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
I_Error("P_AddActivePlat: no more plats!");
|
||||
I_Error("P_AddActivePlat: no more plats!");
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -341,6 +343,7 @@ void P_RemoveActivePlat(plat_t* plat)
|
|||
{
|
||||
int i;
|
||||
for(i = 0; i < MAXPLATS; i++)
|
||||
{
|
||||
if(plat == activeplats[i])
|
||||
{
|
||||
(activeplats[i])->sector->specialdata = NULL;
|
||||
|
|
@ -349,6 +352,7 @@ void P_RemoveActivePlat(plat_t* plat)
|
|||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
I_Error("P_RemoveActivePlat: can't find plat!");
|
||||
I_Error("P_RemoveActivePlat: can't find plat!");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue