mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-21 02:11:06 +00:00
ZDoom 1.23b25.
This commit is contained in:
parent
320d485ed0
commit
58398fe06f
418 changed files with 21199 additions and 4683 deletions
172
Makefile
Normal file
172
Makefile
Normal file
|
@ -0,0 +1,172 @@
|
|||
####################################################################
|
||||
#
|
||||
# Makefile for ZDoom. This probably requires GNU Make.
|
||||
#
|
||||
####################################################################
|
||||
|
||||
CC = gcc -V3.0
|
||||
CXX = g++ -V3.0
|
||||
AS = nasm
|
||||
RM = rm -f
|
||||
RMTREE = rm -R
|
||||
RMDIR = rmdir
|
||||
CP = cp
|
||||
LD = ld
|
||||
INSTALL = install
|
||||
ECHO = echo
|
||||
TAR = tar
|
||||
GZIP = gzip
|
||||
|
||||
basename = zdoom-1.23
|
||||
|
||||
# the OS type we are building for; should match a directory in src_dir
|
||||
SYSTEM = linux
|
||||
|
||||
# distribution names
|
||||
BINTAR = $(basename)-i586.tar.gz
|
||||
SRCTAR = $(basename).tar.gz
|
||||
|
||||
# options common to all builds
|
||||
prefix = /usr/local
|
||||
lib_dir = $(prefix)/lib
|
||||
bin_dir = $(prefix)/bin
|
||||
doc_dir = $(prefix)/doc/zdoom
|
||||
share_dir = $(prefix)/share
|
||||
zdoomshare_dir = $(share_dir)/zdoom
|
||||
X_libs = /usr/X11R6/lib
|
||||
src_dir = src
|
||||
|
||||
IMPDIR = $(src_dir)/$(SYSTEM)
|
||||
mode = release
|
||||
|
||||
# directory to hold all intermediate files
|
||||
INTDIR = $(IMPDIR)/$(mode)
|
||||
|
||||
SRCDOC = INSTALL README
|
||||
CPPFLAGS_common = -Wall -Winline -I$(src_dir) -I$(src_dir)/fmodsound -I$(IMPDIR) \
|
||||
-I$(src_dir)/g_shared -I$(src_dir)/g_doom -I$(src_dir)/g_raven \
|
||||
-I$(src_dir)/g_heretic -I$(src_dir)/g_hexen -Ifmod/api/inc
|
||||
OUTFILE = zdoom
|
||||
|
||||
zdoom doom release all: $(INTDIR)/$(OUTFILE)
|
||||
|
||||
include $(IMPDIR)/files.mak
|
||||
|
||||
# options specific to the debug build
|
||||
CPPFLAGS_debug = -g -Wp,-DRANGECHECK
|
||||
LDFLAGS_debug =
|
||||
ASFLAGS_debug = -g
|
||||
DEFS_debug = -Wp,-DDEBUG,-DUSEASM # -DNOASM
|
||||
|
||||
# options specific to the release build
|
||||
CPPFLAGS_release = -O2 -march=pentium -fomit-frame-pointer
|
||||
LDFLAGS_release = -s
|
||||
ASFLAGS_release =
|
||||
DEFS_release = -Wp,-DNDEBUG,-DUSEASM
|
||||
|
||||
# select flags for this build
|
||||
CPPFLAGS = $(CPPFLAGS_common) $(CPPFLAGS_$(mode)) \
|
||||
$(DEFS_common) $(DEFS_$(mode))
|
||||
LDFLAGS = $(LDFLAGS_common) $(LDFLAGS_$(mode))
|
||||
ASFLAGS = $(ASFLAGS_common) $(ASFLAGS_$(mode))
|
||||
|
||||
# directory to get dependency files
|
||||
DEPSDIR = deps
|
||||
|
||||
# pull in common object and source files extracted from zdoom.dsp
|
||||
include dspfiles
|
||||
|
||||
# object files
|
||||
OBJS = $(DSPOBJS) $(SYSOBJS)
|
||||
|
||||
# all dependency directories
|
||||
DEPSDIRS = $(DSPDEPSDIRS) $(DEPSDIR)/$(SYSTEM)
|
||||
|
||||
ALLSOURCES = $(DSPSOURCES) $(SOURCES) $(HWSOURCES)
|
||||
|
||||
DSPDEPS = $(patsubst $(src_dir)/%.cpp,$(DEPSDIR)/%.d, \
|
||||
$(filter %.cpp %.c,$(DSPSOURCES)))
|
||||
SYSDEPS = $(patsubst $(src_dir)/%.cpp,$(DEPSDIR)/%.d, \
|
||||
$(filter %.cpp %.c,$(SYSSOURCES)))
|
||||
|
||||
# If the VC++ project file changes, remake our list of source files
|
||||
dspfiles: $(src_dir)/zdoom.dsp util/cvdsp
|
||||
util/cvdsp $(src_dir)/zdoom.dsp > dspfiles
|
||||
|
||||
util/cvdsp: util/cvdsp.c
|
||||
$(CC) util/cvdsp.c -o util/cvdsp -s -O
|
||||
|
||||
debug:
|
||||
$(MAKE) mode=debug
|
||||
|
||||
clean:
|
||||
$(RMTREE) $(IMPDIR)/release
|
||||
$(RMTREE) $(IMPDIR)/debug
|
||||
$(RMTREE) $(DEPSDIR)
|
||||
|
||||
$(INTDIR)/$(OUTFILE): common sysspecific
|
||||
$(CXX) $(LDFLAGS) $(OBJS) -o $@ $(LIBS)
|
||||
|
||||
common: $(DSPINTDIRS) $(DSPDEPS) $(DSPOBJS)
|
||||
|
||||
sysspecific: $(INTDIR)/$(SYSTEM) $(SYSDEPS) $(SYSOBJS)
|
||||
|
||||
# Compile .cpp files
|
||||
$(INTDIR)/%.o: $(src_dir)/%.cpp
|
||||
$(CXX) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
# Assemble .nas files
|
||||
$(INTDIR)/%.o: $(src_dir)/%.nas
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
# Make intermediate directories
|
||||
$(INTDIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(INTDIR)/%:
|
||||
mkdir -p $@
|
||||
|
||||
#$(INTDIR)/%.o: $(IMPDIR)/%.nas
|
||||
# $(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
#$(INTDIR)/%.o: $(IMPDIR)/%.cpp
|
||||
# $(CXX) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
# Create dependency files
|
||||
$(DEPSDIR)/%.d: $(src_dir)/%.cpp
|
||||
mkdir -p $(DEPSDIRS)
|
||||
$(SHELL) -ec '$(CXX) -MM $(CPPFLAGS_common) $(DEFS_common) $< \
|
||||
| sed '\''s/\($(*F)\)\.o[ :]*/$$\(INTDIR\)\/\1.o $(subst /,\/,$(@D))\/$(@F) : /g'\'' > $@; \
|
||||
[ -s $@ ] || rm -f $@'
|
||||
|
||||
include $(DSPDEPS)
|
||||
include $(SYSDEPS)
|
||||
|
||||
# Create a binary tarball
|
||||
bintar: install
|
||||
$(TAR) -cv \
|
||||
$(bin_dir)/$(OUTFILE) \
|
||||
$(lib_dir)/libzdoom-x.so \
|
||||
$(lib_dir)/libzdoom-svgalib.so \
|
||||
$(zdoomshare_dir)/zdoom.wad \
|
||||
$(zdoomshare_dir)/xkeys \
|
||||
$(zdoomshare_dir)/bots.cfg \
|
||||
$(zdoomshare_dir)/railgun.bex \
|
||||
$(doc_dir)/* \
|
||||
| $(GZIP) -9c > $(BINTAR)
|
||||
|
||||
# Create a source tarball
|
||||
srctar: $(ALLSOURCES) Makefile $(SRCDOC) docs/* other/*
|
||||
$(SHELL) -ec 'cd ..; \
|
||||
$(TAR) -cv --no-recursion --exclude=*.d --exclude=*~\
|
||||
$(basename)/Makefile \
|
||||
$(basename)/docs/* \
|
||||
$(basename)/other/* \
|
||||
$(basename)/$(src_dir)/* \
|
||||
$(basename)/$(src_dir)/linux/* \
|
||||
$(basename)/$(src_dir)/win32/* \
|
||||
$(SRCDOC:%=$(basename)/%) \
|
||||
| $(GZIP) -9c > $(basename)/$(SRCTAR)'
|
||||
|
||||
srcbz2: srctar
|
||||
$(GZIP) -cd $(SRCTAR) | bzip2 -9c > $(basename).tar.bz2
|
|
@ -1,98 +0,0 @@
|
|||
#ifndef __C_DISPATCH_H__
|
||||
#define __C_DISPATCH_H__
|
||||
|
||||
#include "dobject.h"
|
||||
|
||||
class FConfigFile;
|
||||
|
||||
#define HASH_SIZE 251 // I think this is prime
|
||||
|
||||
void C_ExecCmdLineParams ();
|
||||
|
||||
// add commands to the console as if they were typed in
|
||||
// for map changing, etc
|
||||
void AddCommandString (char *text);
|
||||
|
||||
// Write out alias commands to a file for all current aliases.
|
||||
void C_ArchiveAliases (FConfigFile *f);
|
||||
|
||||
void C_SetAlias (const char *name, const char *cmd);
|
||||
|
||||
// build a single string out of multiple strings
|
||||
char *BuildString (int argc, char **argv);
|
||||
|
||||
typedef void (*CCmdRun) (int argc, char **argv, const char *args, AActor *instigator);
|
||||
|
||||
class FConsoleCommand
|
||||
{
|
||||
public:
|
||||
FConsoleCommand (const char *name, CCmdRun RunFunc);
|
||||
virtual ~FConsoleCommand ();
|
||||
virtual bool IsAlias ();
|
||||
void PrintCommand () { Printf ("%s\n", m_Name); }
|
||||
|
||||
virtual void Run (int argc, char **argv, const char *args, AActor *instigator);
|
||||
|
||||
FConsoleCommand *m_Next, **m_Prev;
|
||||
char *m_Name;
|
||||
|
||||
protected:
|
||||
FConsoleCommand ();
|
||||
bool AddToHash (FConsoleCommand **table);
|
||||
|
||||
CCmdRun m_RunFunc;
|
||||
|
||||
friend void C_DoCommand (char *cmd);
|
||||
};
|
||||
|
||||
#define CCMD(n) \
|
||||
void Cmd_##n (int, char **, const char *, AActor *); \
|
||||
FConsoleCommand Cmd_##n##_ (#n, Cmd_##n); \
|
||||
void Cmd_##n (int argc, char **argv, const char *args, AActor *m_Instigator)
|
||||
|
||||
class FConsoleAlias : public FConsoleCommand
|
||||
{
|
||||
public:
|
||||
FConsoleAlias (const char *name, const char *command);
|
||||
~FConsoleAlias ();
|
||||
void Run (int argc, char **argv, const char *args, AActor *m_Instigator);
|
||||
bool IsAlias ();
|
||||
void PrintAlias () { Printf ("%s : %s\n", m_Name, m_Command); }
|
||||
void Archive (FConfigFile *f);
|
||||
protected:
|
||||
char *m_Command;
|
||||
};
|
||||
|
||||
// Actions
|
||||
#define ACTION_MLOOK 0
|
||||
#define ACTION_KLOOK 1
|
||||
#define ACTION_USE 2
|
||||
#define ACTION_ATTACK 3
|
||||
#define ACTION_SPEED 4
|
||||
#define ACTION_MOVERIGHT 5
|
||||
#define ACTION_MOVELEFT 6
|
||||
#define ACTION_STRAFE 7
|
||||
#define ACTION_LOOKDOWN 8
|
||||
#define ACTION_LOOKUP 9
|
||||
#define ACTION_BACK 10
|
||||
#define ACTION_FORWARD 11
|
||||
#define ACTION_RIGHT 12
|
||||
#define ACTION_LEFT 13
|
||||
#define ACTION_MOVEDOWN 14
|
||||
#define ACTION_MOVEUP 15
|
||||
#define ACTION_JUMP 16
|
||||
#define ACTION_SHOWSCORES 17
|
||||
#define NUM_ACTIONS 18
|
||||
|
||||
extern byte Actions[NUM_ACTIONS];
|
||||
|
||||
struct ActionBits
|
||||
{
|
||||
unsigned int key;
|
||||
int index;
|
||||
char name[12];
|
||||
};
|
||||
|
||||
extern unsigned int MakeKey (const char *s);
|
||||
|
||||
#endif //__C_DISPATCH_H__
|
|
@ -1,403 +0,0 @@
|
|||
#include "decallib.h"
|
||||
#include "sc_man.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_video.h"
|
||||
#include "v_palette.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
FDecalLib DecalLibrary;
|
||||
|
||||
struct FDecalLib::FTranslation
|
||||
{
|
||||
FTranslation (DWORD start, DWORD end);
|
||||
FTranslation *LocateTranslation (DWORD start, DWORD end);
|
||||
|
||||
DWORD StartColor, EndColor;
|
||||
FTranslation *Next;
|
||||
BYTE PalRemap[256];
|
||||
};
|
||||
|
||||
static const char *DecalKeywords[] =
|
||||
{
|
||||
"x-scale",
|
||||
"y-scale",
|
||||
"pic",
|
||||
"translucency",
|
||||
"flipx",
|
||||
"flipy",
|
||||
"fullbright",
|
||||
"fuzzy",
|
||||
"shade",
|
||||
"colors",
|
||||
NULL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DECAL_XSCALE,
|
||||
DECAL_YSCALE,
|
||||
DECAL_PIC,
|
||||
DECAL_TRANSLUCENCY,
|
||||
DECAL_FLIPX,
|
||||
DECAL_FLIPY,
|
||||
DECAL_FULLBRIGHT,
|
||||
DECAL_FUZZY,
|
||||
DECAL_SHADE,
|
||||
DECAL_COLORS
|
||||
};
|
||||
|
||||
FDecalLib::FDecalLib ()
|
||||
{
|
||||
Root = NULL;
|
||||
Translations = NULL;
|
||||
}
|
||||
|
||||
FDecalLib::~FDecalLib ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
|
||||
void FDecalLib::Clear ()
|
||||
{
|
||||
FTranslation *trans;
|
||||
|
||||
DelTree (Root);
|
||||
Root = NULL;
|
||||
|
||||
trans = Translations;
|
||||
while (trans != NULL)
|
||||
{
|
||||
FTranslation *next = trans->Next;
|
||||
delete trans;
|
||||
trans = next;
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::DelTree (FDecal *root)
|
||||
{
|
||||
if (root != NULL)
|
||||
{
|
||||
DelTree (root->Left);
|
||||
DelTree (root->Right);
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ReadAllDecals ()
|
||||
{
|
||||
int lump, lastlump = 0;
|
||||
|
||||
while ((lump = W_FindLump ("DECALDEF", &lastlump)) != -1)
|
||||
{
|
||||
SC_OpenLumpNum (lump, "DECALDEF");
|
||||
ReadDecals ();
|
||||
SC_Close ();
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ReadDecals ()
|
||||
{
|
||||
char decalName[64];
|
||||
byte decalNum;
|
||||
FDecal newdecal;
|
||||
int code;
|
||||
|
||||
while (SC_GetString ())
|
||||
{
|
||||
if (!SC_Compare ("decal"))
|
||||
{
|
||||
SC_ScriptError (NULL);
|
||||
}
|
||||
SC_MustGetString ();
|
||||
strcpy (decalName, sc_String);
|
||||
SC_MustGetString ();
|
||||
if (!IsNum (sc_String))
|
||||
{
|
||||
SC_UnGet ();
|
||||
decalNum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long num = strtoul (sc_String, NULL, 10);
|
||||
if (num < 1 || num > 255)
|
||||
{
|
||||
SC_ScriptError ("Decal ID must be between 1 and 255");
|
||||
}
|
||||
decalNum = (byte)num;
|
||||
}
|
||||
SC_MustGetStringName ("{");
|
||||
|
||||
memset (&newdecal, 0, sizeof(newdecal));
|
||||
newdecal.PicNum = 0xffff;
|
||||
newdecal.ScaleX = newdecal.ScaleY = 63;
|
||||
newdecal.RenderFlags = RF_WALLSPRITE;
|
||||
newdecal.RenderStyle = STYLE_Translucent;
|
||||
newdecal.Alpha = 0x8000;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SC_GetString ();
|
||||
if (SC_Compare ("}"))
|
||||
{
|
||||
AddDecal (decalName, decalNum, newdecal);
|
||||
break;
|
||||
}
|
||||
switch ((code = SC_MustMatchString (DecalKeywords)))
|
||||
{
|
||||
case DECAL_XSCALE:
|
||||
case DECAL_YSCALE:
|
||||
SC_MustGetNumber ();
|
||||
if (--sc_Number < 0)
|
||||
sc_Number = 0;
|
||||
if (sc_Number > 255)
|
||||
sc_Number = 255;
|
||||
if (code == DECAL_XSCALE)
|
||||
newdecal.ScaleX = sc_Number;
|
||||
else
|
||||
newdecal.ScaleY = sc_Number;
|
||||
break;
|
||||
|
||||
case DECAL_PIC:
|
||||
SC_MustGetString ();
|
||||
newdecal.PicNum = R_CheckTileNumForName (sc_String, TILE_Patch);
|
||||
break;
|
||||
|
||||
case DECAL_TRANSLUCENCY:
|
||||
SC_MustGetFloat ();
|
||||
newdecal.Alpha = (WORD)(32768.f * sc_Float);
|
||||
break;
|
||||
|
||||
case DECAL_FLIPX:
|
||||
newdecal.RenderFlags |= RF_XFLIP;
|
||||
break;
|
||||
|
||||
case DECAL_FLIPY:
|
||||
newdecal.RenderFlags |= RF_YFLIP;
|
||||
break;
|
||||
|
||||
case DECAL_FULLBRIGHT:
|
||||
newdecal.RenderFlags |= RF_FULLBRIGHT;
|
||||
break;
|
||||
|
||||
case DECAL_FUZZY:
|
||||
newdecal.RenderStyle = STYLE_Fuzzy;
|
||||
break;
|
||||
|
||||
case DECAL_SHADE:
|
||||
SC_MustGetString ();
|
||||
newdecal.RenderStyle = STYLE_Shaded;
|
||||
newdecal.ShadeColor = V_GetColor (NULL, sc_String);
|
||||
newdecal.ShadeColor |=
|
||||
ColorMatcher.Pick (RPART(newdecal.ShadeColor),
|
||||
GPART(newdecal.ShadeColor), BPART(newdecal.ShadeColor)) << 24;
|
||||
break;
|
||||
|
||||
case DECAL_COLORS:
|
||||
DWORD startcolor, endcolor;
|
||||
|
||||
SC_MustGetString (); startcolor = V_GetColor (NULL, sc_String);
|
||||
SC_MustGetString (); endcolor = V_GetColor (NULL, sc_String);
|
||||
newdecal.Translation = GenerateTranslation (startcolor, endcolor)->PalRemap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::AddDecal (const char *name, byte num, const FDecal &decal)
|
||||
{
|
||||
FDecal *node = Root, **prev = &Root;
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
int lexx = stricmp (name, node->Name);
|
||||
if (lexx == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (lexx < 0)
|
||||
{
|
||||
prev = &node->Left;
|
||||
node = node->Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &node->Right;
|
||||
node = node->Right;
|
||||
}
|
||||
}
|
||||
if (node == NULL)
|
||||
{
|
||||
node = new FDecal;
|
||||
*node = decal;
|
||||
node->Name = copystring (name);
|
||||
node->SpawnID = num;
|
||||
node->Left = node->Right = NULL;
|
||||
*prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *savename = node->Name;
|
||||
*node = decal;
|
||||
node->Name = savename;
|
||||
node->SpawnID = num;
|
||||
}
|
||||
if (num != 0)
|
||||
{
|
||||
FDecal *spawner = ScanTreeForNum (num, Root);
|
||||
if (spawner != node)
|
||||
{
|
||||
spawner->SpawnID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const FDecal *FDecalLib::GetDecalByNum (byte num) const
|
||||
{
|
||||
if (num == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
FDecal *node = ScanTreeForNum (num, Root);
|
||||
return node;
|
||||
}
|
||||
|
||||
const FDecal *FDecalLib::GetDecalByName (const char *name) const
|
||||
{
|
||||
if (name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
FDecal *node = ScanTreeForName (name, Root);
|
||||
return node;
|
||||
}
|
||||
|
||||
FDecal *FDecalLib::ScanTreeForNum (const BYTE num, FDecal *root)
|
||||
{
|
||||
while (root != NULL)
|
||||
{
|
||||
if (root->SpawnID == num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ScanTreeForNum (num, root->Left);
|
||||
root = root->Right; // Avoid tail-recursion
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
FDecal *FDecalLib::ScanTreeForName (const char *name, FDecal *root)
|
||||
{
|
||||
while (root != NULL)
|
||||
{
|
||||
int lexx = stricmp (name, root->Name);
|
||||
if (lexx == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (lexx < 0)
|
||||
{
|
||||
root = root->Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = root->Right;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation *FDecalLib::GenerateTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
FTranslation *trans;
|
||||
|
||||
if (Translations != NULL)
|
||||
{
|
||||
trans = Translations->LocateTranslation (start, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans = NULL;
|
||||
}
|
||||
if (trans == NULL)
|
||||
{
|
||||
trans = new FTranslation (start, end);
|
||||
trans->Next = Translations;
|
||||
Translations = trans;
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
|
||||
FDecal::FDecal ()
|
||||
{
|
||||
Name = NULL;
|
||||
Translation = NULL;
|
||||
}
|
||||
|
||||
FDecal::~FDecal ()
|
||||
{
|
||||
if (Name != NULL)
|
||||
delete[] Name;
|
||||
}
|
||||
|
||||
void FDecal::ApplyToActor (AActor *actor) const
|
||||
{
|
||||
if (RenderStyle == STYLE_Shaded)
|
||||
{
|
||||
actor->SetShade (ShadeColor);
|
||||
}
|
||||
actor->translation = Translation;
|
||||
actor->xscale = ScaleX;
|
||||
actor->yscale = ScaleY;
|
||||
actor->picnum = PicNum;
|
||||
actor->renderflags = RenderFlags |
|
||||
(actor->renderflags & (RF_RELMASK|RF_CLIPMASK|RF_INVISIBLE|RF_ONESIDED));
|
||||
actor->alpha = Alpha << 1;
|
||||
actor->RenderStyle = RenderStyle;
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation::FTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
DWORD ri, gi, bi, rs, gs, bs;
|
||||
PalEntry *first, *last;
|
||||
int i;
|
||||
|
||||
StartColor = start;
|
||||
EndColor = end;
|
||||
Next = NULL;
|
||||
|
||||
first = (PalEntry *)&StartColor;
|
||||
last = (PalEntry *)&EndColor;
|
||||
|
||||
ri = first->r << 24;
|
||||
gi = first->g << 24;
|
||||
bi = first->b << 24;
|
||||
rs = last->r << 24;
|
||||
gs = last->g << 24;
|
||||
bs = last->b << 24;
|
||||
|
||||
rs = (rs - ri) / 255;
|
||||
gs = (gs - ri) / 255;
|
||||
bs = (bs - bi) / 255;
|
||||
|
||||
for (i = 1; i < 256; i++, ri += rs, gi += gs, bi += bs)
|
||||
{
|
||||
PalRemap[i] = ColorMatcher.Pick (ri >> 24, gi >> 24, bi >> 24);
|
||||
}
|
||||
PalRemap[0] = PalRemap[1];
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation *FDecalLib::FTranslation::LocateTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
FTranslation *trans = this;
|
||||
|
||||
do
|
||||
{
|
||||
if (start == trans->StartColor && end == trans->EndColor)
|
||||
{
|
||||
return trans;
|
||||
}
|
||||
trans = trans->Next;
|
||||
} while (trans != NULL);
|
||||
return trans;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef __V_TEXT_H__
|
||||
#define __V_TEXT_H__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "v_font.h"
|
||||
|
||||
struct brokenlines_s {
|
||||
short width;
|
||||
byte nlterminated;
|
||||
byte pad;
|
||||
char *string;
|
||||
};
|
||||
typedef struct brokenlines_s brokenlines_t;
|
||||
|
||||
#define TEXTCOLOR_ESCAPE '\x81'
|
||||
|
||||
#define TEXTCOLOR_BRICK "\x81""A"
|
||||
#define TEXTCOLOR_TAN "\x81""B"
|
||||
#define TEXTCOLOR_GRAY "\x81""C"
|
||||
#define TEXTCOLOR_GREY "\x81""C"
|
||||
#define TEXTCOLOR_GREEN "\x81""D"
|
||||
#define TEXTCOLOR_BROWN "\x81""E"
|
||||
#define TEXTCOLOR_GOLD "\x81""F"
|
||||
#define TEXTCOLOR_RED "\x81""G"
|
||||
#define TEXTCOLOR_BLUE "\x81""H"
|
||||
#define TEXTCOLOR_ORANGE "\x81""I"
|
||||
#define TEXTCOLOR_WHITE "\x81""J"
|
||||
#define TEXTCOLOR_YELLOW "\x81""k"
|
||||
|
||||
#define TEXTCOLOR_NORMAL "\x81-"
|
||||
#define TEXTCOLOR_BOLD "\x81+"
|
||||
|
||||
brokenlines_t *V_BreakLines (int maxwidth, const byte *str, bool keepspace=false);
|
||||
void V_FreeBrokenLines (brokenlines_t *lines);
|
||||
inline brokenlines_t *V_BreakLines (int maxwidth, const char *str, bool keepspace=false)
|
||||
{ return V_BreakLines (maxwidth, (const byte *)str, keepspace); }
|
||||
|
||||
#endif //__V_TEXT_H__
|
File diff suppressed because it is too large
Load diff
|
@ -1,45 +0,0 @@
|
|||
#ifndef __MUS2STRM_H__
|
||||
#define __MUS2STRM_H__
|
||||
|
||||
#include "mid2strm.h"
|
||||
|
||||
#define MUS_RELEASE 0
|
||||
#define MUS_PLAY 1
|
||||
#define MUS_PITCHBEND 2
|
||||
#define MUS_SYSEVENT 3
|
||||
#define MUS_CTRLCHANGE 4
|
||||
#define MUS_UNKNOWN1 5
|
||||
#define MUS_END 6
|
||||
#define MUS_UNKNOWN2 7
|
||||
|
||||
#define MUSMAGIC "MUS\032"
|
||||
|
||||
typedef unsigned short int2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char ID[4]; /* identifier "MUS" 0x1A */
|
||||
int2 ScoreLength;
|
||||
int2 ScoreStart;
|
||||
int2 channels; /* count of primary channels */
|
||||
int2 SecChannels; /* count of secondary channels (?) */
|
||||
int2 InstrCnt;
|
||||
} MUSheader;
|
||||
|
||||
struct Track
|
||||
{
|
||||
unsigned long current;
|
||||
char vel;
|
||||
long DeltaTime;
|
||||
unsigned char LastEvent;
|
||||
char *data; /* Primary data */
|
||||
};
|
||||
|
||||
extern OUTSTREAMSTATE ots;
|
||||
|
||||
|
||||
PSTREAMBUF mus2strmConvert (BYTE *inFile, DWORD inSize);
|
||||
void mus2strmCleanup (void);
|
||||
|
||||
|
||||
#endif //__MUS2STRM_H__
|
|
@ -1,8 +1,3 @@
|
|||
This file is sorely outdated in regards to DObject usage. You can still use
|
||||
it as a baseline, but see the source for actual implementation details, since
|
||||
many of them have changed.
|
||||
|
||||
|
||||
ZDoom 1.19 offers a partial conversion of the Doom code to C++. As such, some
|
||||
functions and classes have been encapsulated in classes. This document tries
|
||||
to give an overview of those classes and how to use them.
|
756
docs/colors.txt
Normal file
756
docs/colors.txt
Normal file
|
@ -0,0 +1,756 @@
|
|||
! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $
|
||||
|
||||
255 250 250 snow
|
||||
248 248 255 ghost white
|
||||
248 248 255 GhostWhite
|
||||
245 245 245 white smoke
|
||||
245 245 245 WhiteSmoke
|
||||
220 220 220 gainsboro
|
||||
255 250 240 floral white
|
||||
255 250 240 FloralWhite
|
||||
253 245 230 old lace
|
||||
253 245 230 OldLace
|
||||
250 240 230 linen
|
||||
250 235 215 antique white
|
||||
250 235 215 AntiqueWhite
|
||||
255 239 213 papaya whip
|
||||
255 239 213 PapayaWhip
|
||||
255 235 205 blanched almond
|
||||
255 235 205 BlanchedAlmond
|
||||
255 228 196 bisque
|
||||
255 218 185 peach puff
|
||||
255 218 185 PeachPuff
|
||||
255 222 173 navajo white
|
||||
255 222 173 NavajoWhite
|
||||
255 228 181 moccasin
|
||||
255 248 220 cornsilk
|
||||
255 255 240 ivory
|
||||
255 250 205 lemon chiffon
|
||||
255 250 205 LemonChiffon
|
||||
255 245 238 seashell
|
||||
240 255 240 honeydew
|
||||
245 255 250 mint cream
|
||||
245 255 250 MintCream
|
||||
240 255 255 azure
|
||||
240 248 255 alice blue
|
||||
240 248 255 AliceBlue
|
||||
230 230 250 lavender
|
||||
255 240 245 lavender blush
|
||||
255 240 245 LavenderBlush
|
||||
255 228 225 misty rose
|
||||
255 228 225 MistyRose
|
||||
255 255 255 white
|
||||
0 0 0 black
|
||||
47 79 79 dark slate gray
|
||||
47 79 79 DarkSlateGray
|
||||
47 79 79 dark slate grey
|
||||
47 79 79 DarkSlateGrey
|
||||
105 105 105 dim gray
|
||||
105 105 105 DimGray
|
||||
105 105 105 dim grey
|
||||
105 105 105 DimGrey
|
||||
112 128 144 slate gray
|
||||
112 128 144 SlateGray
|
||||
112 128 144 slate grey
|
||||
112 128 144 SlateGrey
|
||||
119 136 153 light slate gray
|
||||
119 136 153 LightSlateGray
|
||||
119 136 153 light slate grey
|
||||
119 136 153 LightSlateGrey
|
||||
190 190 190 gray
|
||||
190 190 190 grey
|
||||
211 211 211 light grey
|
||||
211 211 211 LightGrey
|
||||
211 211 211 light gray
|
||||
211 211 211 LightGray
|
||||
25 25 112 midnight blue
|
||||
25 25 112 MidnightBlue
|
||||
0 0 128 navy
|
||||
0 0 128 navy blue
|
||||
0 0 128 NavyBlue
|
||||
100 149 237 cornflower blue
|
||||
100 149 237 CornflowerBlue
|
||||
72 61 139 dark slate blue
|
||||
72 61 139 DarkSlateBlue
|
||||
106 90 205 slate blue
|
||||
106 90 205 SlateBlue
|
||||
123 104 238 medium slate blue
|
||||
123 104 238 MediumSlateBlue
|
||||
132 112 255 light slate blue
|
||||
132 112 255 LightSlateBlue
|
||||
0 0 205 medium blue
|
||||
0 0 205 MediumBlue
|
||||
65 105 225 royal blue
|
||||
65 105 225 RoyalBlue
|
||||
0 0 255 blue
|
||||
30 144 255 dodger blue
|
||||
30 144 255 DodgerBlue
|
||||
0 191 255 deep sky blue
|
||||
0 191 255 DeepSkyBlue
|
||||
135 206 235 sky blue
|
||||
135 206 235 SkyBlue
|
||||
135 206 250 light sky blue
|
||||
135 206 250 LightSkyBlue
|
||||
70 130 180 steel blue
|
||||
70 130 180 SteelBlue
|
||||
176 196 222 light steel blue
|
||||
176 196 222 LightSteelBlue
|
||||
173 216 230 light blue
|
||||
173 216 230 LightBlue
|
||||
176 224 230 powder blue
|
||||
176 224 230 PowderBlue
|
||||
175 238 238 pale turquoise
|
||||
175 238 238 PaleTurquoise
|
||||
0 206 209 dark turquoise
|
||||
0 206 209 DarkTurquoise
|
||||
72 209 204 medium turquoise
|
||||
72 209 204 MediumTurquoise
|
||||
64 224 208 turquoise
|
||||
0 255 255 cyan
|
||||
224 255 255 light cyan
|
||||
224 255 255 LightCyan
|
||||
95 158 160 cadet blue
|
||||
95 158 160 CadetBlue
|
||||
102 205 170 medium aquamarine
|
||||
102 205 170 MediumAquamarine
|
||||
127 255 212 aquamarine
|
||||
0 100 0 dark green
|
||||
0 100 0 DarkGreen
|
||||
85 107 47 dark olive green
|
||||
85 107 47 DarkOliveGreen
|
||||
143 188 143 dark sea green
|
||||
143 188 143 DarkSeaGreen
|
||||
46 139 87 sea green
|
||||
46 139 87 SeaGreen
|
||||
60 179 113 medium sea green
|
||||
60 179 113 MediumSeaGreen
|
||||
32 178 170 light sea green
|
||||
32 178 170 LightSeaGreen
|
||||
152 251 152 pale green
|
||||
152 251 152 PaleGreen
|
||||
0 255 127 spring green
|
||||
0 255 127 SpringGreen
|
||||
124 252 0 lawn green
|
||||
124 252 0 LawnGreen
|
||||
0 255 0 green
|
||||
127 255 0 chartreuse
|
||||
0 250 154 medium spring green
|
||||
0 250 154 MediumSpringGreen
|
||||
173 255 47 green yellow
|
||||
173 255 47 GreenYellow
|
||||
50 205 50 lime green
|
||||
50 205 50 LimeGreen
|
||||
154 205 50 yellow green
|
||||
154 205 50 YellowGreen
|
||||
34 139 34 forest green
|
||||
34 139 34 ForestGreen
|
||||
107 142 35 olive drab
|
||||
107 142 35 OliveDrab
|
||||
189 183 107 dark khaki
|
||||
189 183 107 DarkKhaki
|
||||
240 230 140 khaki
|
||||
238 232 170 pale goldenrod
|
||||
238 232 170 PaleGoldenrod
|
||||
250 250 210 light goldenrod yellow
|
||||
250 250 210 LightGoldenrodYellow
|
||||
255 255 224 light yellow
|
||||
255 255 224 LightYellow
|
||||
255 255 0 yellow
|
||||
255 215 0 gold
|
||||
238 221 130 light goldenrod
|
||||
238 221 130 LightGoldenrod
|
||||
218 165 32 goldenrod
|
||||
184 134 11 dark goldenrod
|
||||
184 134 11 DarkGoldenrod
|
||||
188 143 143 rosy brown
|
||||
188 143 143 RosyBrown
|
||||
205 92 92 indian red
|
||||
205 92 92 IndianRed
|
||||
139 69 19 saddle brown
|
||||
139 69 19 SaddleBrown
|
||||
160 82 45 sienna
|
||||
205 133 63 peru
|
||||
222 184 135 burlywood
|
||||
245 245 220 beige
|
||||
245 222 179 wheat
|
||||
244 164 96 sandy brown
|
||||
244 164 96 SandyBrown
|
||||
210 180 140 tan
|
||||
210 105 30 chocolate
|
||||
178 34 34 firebrick
|
||||
165 42 42 brown
|
||||
233 150 122 dark salmon
|
||||
233 150 122 DarkSalmon
|
||||
250 128 114 salmon
|
||||
255 160 122 light salmon
|
||||
255 160 122 LightSalmon
|
||||
255 165 0 orange
|
||||
255 140 0 dark orange
|
||||
255 140 0 DarkOrange
|
||||
255 127 80 coral
|
||||
240 128 128 light coral
|
||||
240 128 128 LightCoral
|
||||
255 99 71 tomato
|
||||
255 69 0 orange red
|
||||
255 69 0 OrangeRed
|
||||
255 0 0 red
|
||||
255 105 180 hot pink
|
||||
255 105 180 HotPink
|
||||
255 20 147 deep pink
|
||||
255 20 147 DeepPink
|
||||
255 192 203 pink
|
||||
255 182 193 light pink
|
||||
255 182 193 LightPink
|
||||
219 112 147 pale violet red
|
||||
219 112 147 PaleVioletRed
|
||||
176 48 96 maroon
|
||||
199 21 133 medium violet red
|
||||
199 21 133 MediumVioletRed
|
||||
208 32 144 violet red
|
||||
208 32 144 VioletRed
|
||||
255 0 255 magenta
|
||||
238 130 238 violet
|
||||
221 160 221 plum
|
||||
218 112 214 orchid
|
||||
186 85 211 medium orchid
|
||||
186 85 211 MediumOrchid
|
||||
153 50 204 dark orchid
|
||||
153 50 204 DarkOrchid
|
||||
148 0 211 dark violet
|
||||
148 0 211 DarkViolet
|
||||
138 43 226 blue violet
|
||||
138 43 226 BlueViolet
|
||||
160 32 240 purple
|
||||
147 112 219 medium purple
|
||||
147 112 219 MediumPurple
|
||||
216 191 216 thistle
|
||||
255 250 250 snow1
|
||||
238 233 233 snow2
|
||||
205 201 201 snow3
|
||||
139 137 137 snow4
|
||||
255 245 238 seashell1
|
||||
238 229 222 seashell2
|
||||
205 197 191 seashell3
|
||||
139 134 130 seashell4
|
||||
255 239 219 AntiqueWhite1
|
||||
238 223 204 AntiqueWhite2
|
||||
205 192 176 AntiqueWhite3
|
||||
139 131 120 AntiqueWhite4
|
||||
255 228 196 bisque1
|
||||
238 213 183 bisque2
|
||||
205 183 158 bisque3
|
||||
139 125 107 bisque4
|
||||
255 218 185 PeachPuff1
|
||||
238 203 173 PeachPuff2
|
||||
205 175 149 PeachPuff3
|
||||
139 119 101 PeachPuff4
|
||||
255 222 173 NavajoWhite1
|
||||
238 207 161 NavajoWhite2
|
||||
205 179 139 NavajoWhite3
|
||||
139 121 94 NavajoWhite4
|
||||
255 250 205 LemonChiffon1
|
||||
238 233 191 LemonChiffon2
|
||||
205 201 165 LemonChiffon3
|
||||
139 137 112 LemonChiffon4
|
||||
255 248 220 cornsilk1
|
||||
238 232 205 cornsilk2
|
||||
205 200 177 cornsilk3
|
||||
139 136 120 cornsilk4
|
||||
255 255 240 ivory1
|
||||
238 238 224 ivory2
|
||||
205 205 193 ivory3
|
||||
139 139 131 ivory4
|
||||
240 255 240 honeydew1
|
||||
224 238 224 honeydew2
|
||||
193 205 193 honeydew3
|
||||
131 139 131 honeydew4
|
||||
255 240 245 LavenderBlush1
|
||||
238 224 229 LavenderBlush2
|
||||
205 193 197 LavenderBlush3
|
||||
139 131 134 LavenderBlush4
|
||||
255 228 225 MistyRose1
|
||||
238 213 210 MistyRose2
|
||||
205 183 181 MistyRose3
|
||||
139 125 123 MistyRose4
|
||||
240 255 255 azure1
|
||||
224 238 238 azure2
|
||||
193 205 205 azure3
|
||||
131 139 139 azure4
|
||||
131 111 255 SlateBlue1
|
||||
122 103 238 SlateBlue2
|
||||
105 89 205 SlateBlue3
|
||||
71 60 139 SlateBlue4
|
||||
72 118 255 RoyalBlue1
|
||||
67 110 238 RoyalBlue2
|
||||
58 95 205 RoyalBlue3
|
||||
39 64 139 RoyalBlue4
|
||||
0 0 255 blue1
|
||||
0 0 238 blue2
|
||||
0 0 205 blue3
|
||||
0 0 139 blue4
|
||||
30 144 255 DodgerBlue1
|
||||
28 134 238 DodgerBlue2
|
||||
24 116 205 DodgerBlue3
|
||||
16 78 139 DodgerBlue4
|
||||
99 184 255 SteelBlue1
|
||||
92 172 238 SteelBlue2
|
||||
79 148 205 SteelBlue3
|
||||
54 100 139 SteelBlue4
|
||||
0 191 255 DeepSkyBlue1
|
||||
0 178 238 DeepSkyBlue2
|
||||
0 154 205 DeepSkyBlue3
|
||||
0 104 139 DeepSkyBlue4
|
||||
135 206 255 SkyBlue1
|
||||
126 192 238 SkyBlue2
|
||||
108 166 205 SkyBlue3
|
||||
74 112 139 SkyBlue4
|
||||
176 226 255 LightSkyBlue1
|
||||
164 211 238 LightSkyBlue2
|
||||
141 182 205 LightSkyBlue3
|
||||
96 123 139 LightSkyBlue4
|
||||
198 226 255 SlateGray1
|
||||
185 211 238 SlateGray2
|
||||
159 182 205 SlateGray3
|
||||
108 123 139 SlateGray4
|
||||
202 225 255 LightSteelBlue1
|
||||
188 210 238 LightSteelBlue2
|
||||
162 181 205 LightSteelBlue3
|
||||
110 123 139 LightSteelBlue4
|
||||
191 239 255 LightBlue1
|
||||
178 223 238 LightBlue2
|
||||
154 192 205 LightBlue3
|
||||
104 131 139 LightBlue4
|
||||
224 255 255 LightCyan1
|
||||
209 238 238 LightCyan2
|
||||
180 205 205 LightCyan3
|
||||
122 139 139 LightCyan4
|
||||
187 255 255 PaleTurquoise1
|
||||
174 238 238 PaleTurquoise2
|
||||
150 205 205 PaleTurquoise3
|
||||
102 139 139 PaleTurquoise4
|
||||
152 245 255 CadetBlue1
|
||||
142 229 238 CadetBlue2
|
||||
122 197 205 CadetBlue3
|
||||
83 134 139 CadetBlue4
|
||||
0 245 255 turquoise1
|
||||
0 229 238 turquoise2
|
||||
0 197 205 turquoise3
|
||||
0 134 139 turquoise4
|
||||
0 255 255 cyan1
|
||||
0 238 238 cyan2
|
||||
0 205 205 cyan3
|
||||
0 139 139 cyan4
|
||||
151 255 255 DarkSlateGray1
|
||||
141 238 238 DarkSlateGray2
|
||||
121 205 205 DarkSlateGray3
|
||||
82 139 139 DarkSlateGray4
|
||||
127 255 212 aquamarine1
|
||||
118 238 198 aquamarine2
|
||||
102 205 170 aquamarine3
|
||||
69 139 116 aquamarine4
|
||||
193 255 193 DarkSeaGreen1
|
||||
180 238 180 DarkSeaGreen2
|
||||
155 205 155 DarkSeaGreen3
|
||||
105 139 105 DarkSeaGreen4
|
||||
84 255 159 SeaGreen1
|
||||
78 238 148 SeaGreen2
|
||||
67 205 128 SeaGreen3
|
||||
46 139 87 SeaGreen4
|
||||
154 255 154 PaleGreen1
|
||||
144 238 144 PaleGreen2
|
||||
124 205 124 PaleGreen3
|
||||
84 139 84 PaleGreen4
|
||||
0 255 127 SpringGreen1
|
||||
0 238 118 SpringGreen2
|
||||
0 205 102 SpringGreen3
|
||||
0 139 69 SpringGreen4
|
||||
0 255 0 green1
|
||||
0 238 0 green2
|
||||
0 205 0 green3
|
||||
0 139 0 green4
|
||||
127 255 0 chartreuse1
|
||||
118 238 0 chartreuse2
|
||||
102 205 0 chartreuse3
|
||||
69 139 0 chartreuse4
|
||||
192 255 62 OliveDrab1
|
||||
179 238 58 OliveDrab2
|
||||
154 205 50 OliveDrab3
|
||||
105 139 34 OliveDrab4
|
||||
202 255 112 DarkOliveGreen1
|
||||
188 238 104 DarkOliveGreen2
|
||||
162 205 90 DarkOliveGreen3
|
||||
110 139 61 DarkOliveGreen4
|
||||
255 246 143 khaki1
|
||||
238 230 133 khaki2
|
||||
205 198 115 khaki3
|
||||
139 134 78 khaki4
|
||||
255 236 139 LightGoldenrod1
|
||||
238 220 130 LightGoldenrod2
|
||||
205 190 112 LightGoldenrod3
|
||||
139 129 76 LightGoldenrod4
|
||||
255 255 224 LightYellow1
|
||||
238 238 209 LightYellow2
|
||||
205 205 180 LightYellow3
|
||||
139 139 122 LightYellow4
|
||||
255 255 0 yellow1
|
||||
238 238 0 yellow2
|
||||
205 205 0 yellow3
|
||||
139 139 0 yellow4
|
||||
255 215 0 gold1
|
||||
238 201 0 gold2
|
||||
205 173 0 gold3
|
||||
139 117 0 gold4
|
||||
255 193 37 goldenrod1
|
||||
238 180 34 goldenrod2
|
||||
205 155 29 goldenrod3
|
||||
139 105 20 goldenrod4
|
||||
255 185 15 DarkGoldenrod1
|
||||
238 173 14 DarkGoldenrod2
|
||||
205 149 12 DarkGoldenrod3
|
||||
139 101 8 DarkGoldenrod4
|
||||
255 193 193 RosyBrown1
|
||||
238 180 180 RosyBrown2
|
||||
205 155 155 RosyBrown3
|
||||
139 105 105 RosyBrown4
|
||||
255 106 106 IndianRed1
|
||||
238 99 99 IndianRed2
|
||||
205 85 85 IndianRed3
|
||||
139 58 58 IndianRed4
|
||||
255 130 71 sienna1
|
||||
238 121 66 sienna2
|
||||
205 104 57 sienna3
|
||||
139 71 38 sienna4
|
||||
255 211 155 burlywood1
|
||||
238 197 145 burlywood2
|
||||
205 170 125 burlywood3
|
||||
139 115 85 burlywood4
|
||||
255 231 186 wheat1
|
||||
238 216 174 wheat2
|
||||
205 186 150 wheat3
|
||||
139 126 102 wheat4
|
||||
255 165 79 tan1
|
||||
238 154 73 tan2
|
||||
205 133 63 tan3
|
||||
139 90 43 tan4
|
||||
255 127 36 chocolate1
|
||||
238 118 33 chocolate2
|
||||
205 102 29 chocolate3
|
||||
139 69 19 chocolate4
|
||||
255 48 48 firebrick1
|
||||
238 44 44 firebrick2
|
||||
205 38 38 firebrick3
|
||||
139 26 26 firebrick4
|
||||
255 64 64 brown1
|
||||
238 59 59 brown2
|
||||
205 51 51 brown3
|
||||
139 35 35 brown4
|
||||
255 140 105 salmon1
|
||||
238 130 98 salmon2
|
||||
205 112 84 salmon3
|
||||
139 76 57 salmon4
|
||||
255 160 122 LightSalmon1
|
||||
238 149 114 LightSalmon2
|
||||
205 129 98 LightSalmon3
|
||||
139 87 66 LightSalmon4
|
||||
255 165 0 orange1
|
||||
238 154 0 orange2
|
||||
205 133 0 orange3
|
||||
139 90 0 orange4
|
||||
255 127 0 DarkOrange1
|
||||
238 118 0 DarkOrange2
|
||||
205 102 0 DarkOrange3
|
||||
139 69 0 DarkOrange4
|
||||
255 114 86 coral1
|
||||
238 106 80 coral2
|
||||
205 91 69 coral3
|
||||
139 62 47 coral4
|
||||
255 99 71 tomato1
|
||||
238 92 66 tomato2
|
||||
205 79 57 tomato3
|
||||
139 54 38 tomato4
|
||||
255 69 0 OrangeRed1
|
||||
238 64 0 OrangeRed2
|
||||
205 55 0 OrangeRed3
|
||||
139 37 0 OrangeRed4
|
||||
255 0 0 red1
|
||||
238 0 0 red2
|
||||
205 0 0 red3
|
||||
139 0 0 red4
|
||||
255 20 147 DeepPink1
|
||||
238 18 137 DeepPink2
|
||||
205 16 118 DeepPink3
|
||||
139 10 80 DeepPink4
|
||||
255 110 180 HotPink1
|
||||
238 106 167 HotPink2
|
||||
205 96 144 HotPink3
|
||||
139 58 98 HotPink4
|
||||
255 181 197 pink1
|
||||
238 169 184 pink2
|
||||
205 145 158 pink3
|
||||
139 99 108 pink4
|
||||
255 174 185 LightPink1
|
||||
238 162 173 LightPink2
|
||||
205 140 149 LightPink3
|
||||
139 95 101 LightPink4
|
||||
255 130 171 PaleVioletRed1
|
||||
238 121 159 PaleVioletRed2
|
||||
205 104 137 PaleVioletRed3
|
||||
139 71 93 PaleVioletRed4
|
||||
255 52 179 maroon1
|
||||
238 48 167 maroon2
|
||||
205 41 144 maroon3
|
||||
139 28 98 maroon4
|
||||
255 62 150 VioletRed1
|
||||
238 58 140 VioletRed2
|
||||
205 50 120 VioletRed3
|
||||
139 34 82 VioletRed4
|
||||
255 0 255 magenta1
|
||||
238 0 238 magenta2
|
||||
205 0 205 magenta3
|
||||
139 0 139 magenta4
|
||||
255 131 250 orchid1
|
||||
238 122 233 orchid2
|
||||
205 105 201 orchid3
|
||||
139 71 137 orchid4
|
||||
255 187 255 plum1
|
||||
238 174 238 plum2
|
||||
205 150 205 plum3
|
||||
139 102 139 plum4
|
||||
224 102 255 MediumOrchid1
|
||||
209 95 238 MediumOrchid2
|
||||
180 82 205 MediumOrchid3
|
||||
122 55 139 MediumOrchid4
|
||||
191 62 255 DarkOrchid1
|
||||
178 58 238 DarkOrchid2
|
||||
154 50 205 DarkOrchid3
|
||||
104 34 139 DarkOrchid4
|
||||
155 48 255 purple1
|
||||
145 44 238 purple2
|
||||
125 38 205 purple3
|
||||
85 26 139 purple4
|
||||
171 130 255 MediumPurple1
|
||||
159 121 238 MediumPurple2
|
||||
137 104 205 MediumPurple3
|
||||
93 71 139 MediumPurple4
|
||||
255 225 255 thistle1
|
||||
238 210 238 thistle2
|
||||
205 181 205 thistle3
|
||||
139 123 139 thistle4
|
||||
0 0 0 gray0
|
||||
0 0 0 grey0
|
||||
3 3 3 gray1
|
||||
3 3 3 grey1
|
||||
5 5 5 gray2
|
||||
5 5 5 grey2
|
||||
8 8 8 gray3
|
||||
8 8 8 grey3
|
||||
10 10 10 gray4
|
||||
10 10 10 grey4
|
||||
13 13 13 gray5
|
||||
13 13 13 grey5
|
||||
15 15 15 gray6
|
||||
15 15 15 grey6
|
||||
18 18 18 gray7
|
||||
18 18 18 grey7
|
||||
20 20 20 gray8
|
||||
20 20 20 grey8
|
||||
23 23 23 gray9
|
||||
23 23 23 grey9
|
||||
26 26 26 gray10
|
||||
26 26 26 grey10
|
||||
28 28 28 gray11
|
||||
28 28 28 grey11
|
||||
31 31 31 gray12
|
||||
31 31 31 grey12
|
||||
33 33 33 gray13
|
||||
33 33 33 grey13
|
||||
36 36 36 gray14
|
||||
36 36 36 grey14
|
||||
38 38 38 gray15
|
||||
38 38 38 grey15
|
||||
41 41 41 gray16
|
||||
41 41 41 grey16
|
||||
43 43 43 gray17
|
||||
43 43 43 grey17
|
||||
46 46 46 gray18
|
||||
46 46 46 grey18
|
||||
48 48 48 gray19
|
||||
48 48 48 grey19
|
||||
51 51 51 gray20
|
||||
51 51 51 grey20
|
||||
54 54 54 gray21
|
||||
54 54 54 grey21
|
||||
56 56 56 gray22
|
||||
56 56 56 grey22
|
||||
59 59 59 gray23
|
||||
59 59 59 grey23
|
||||
61 61 61 gray24
|
||||
61 61 61 grey24
|
||||
64 64 64 gray25
|
||||
64 64 64 grey25
|
||||
66 66 66 gray26
|
||||
66 66 66 grey26
|
||||
69 69 69 gray27
|
||||
69 69 69 grey27
|
||||
71 71 71 gray28
|
||||
71 71 71 grey28
|
||||
74 74 74 gray29
|
||||
74 74 74 grey29
|
||||
77 77 77 gray30
|
||||
77 77 77 grey30
|
||||
79 79 79 gray31
|
||||
79 79 79 grey31
|
||||
82 82 82 gray32
|
||||
82 82 82 grey32
|
||||
84 84 84 gray33
|
||||
84 84 84 grey33
|
||||
87 87 87 gray34
|
||||
87 87 87 grey34
|
||||
89 89 89 gray35
|
||||
89 89 89 grey35
|
||||
92 92 92 gray36
|
||||
92 92 92 grey36
|
||||
94 94 94 gray37
|
||||
94 94 94 grey37
|
||||
97 97 97 gray38
|
||||
97 97 97 grey38
|
||||
99 99 99 gray39
|
||||
99 99 99 grey39
|
||||
102 102 102 gray40
|
||||
102 102 102 grey40
|
||||
105 105 105 gray41
|
||||
105 105 105 grey41
|
||||
107 107 107 gray42
|
||||
107 107 107 grey42
|
||||
110 110 110 gray43
|
||||
110 110 110 grey43
|
||||
112 112 112 gray44
|
||||
112 112 112 grey44
|
||||
115 115 115 gray45
|
||||
115 115 115 grey45
|
||||
117 117 117 gray46
|
||||
117 117 117 grey46
|
||||
120 120 120 gray47
|
||||
120 120 120 grey47
|
||||
122 122 122 gray48
|
||||
122 122 122 grey48
|
||||
125 125 125 gray49
|
||||
125 125 125 grey49
|
||||
127 127 127 gray50
|
||||
127 127 127 grey50
|
||||
130 130 130 gray51
|
||||
130 130 130 grey51
|
||||
133 133 133 gray52
|
||||
133 133 133 grey52
|
||||
135 135 135 gray53
|
||||
135 135 135 grey53
|
||||
138 138 138 gray54
|
||||
138 138 138 grey54
|
||||
140 140 140 gray55
|
||||
140 140 140 grey55
|
||||
143 143 143 gray56
|
||||
143 143 143 grey56
|
||||
145 145 145 gray57
|
||||
145 145 145 grey57
|
||||
148 148 148 gray58
|
||||
148 148 148 grey58
|
||||
150 150 150 gray59
|
||||
150 150 150 grey59
|
||||
153 153 153 gray60
|
||||
153 153 153 grey60
|
||||
156 156 156 gray61
|
||||
156 156 156 grey61
|
||||
158 158 158 gray62
|
||||
158 158 158 grey62
|
||||
161 161 161 gray63
|
||||
161 161 161 grey63
|
||||
163 163 163 gray64
|
||||
163 163 163 grey64
|
||||
166 166 166 gray65
|
||||
166 166 166 grey65
|
||||
168 168 168 gray66
|
||||
168 168 168 grey66
|
||||
171 171 171 gray67
|
||||
171 171 171 grey67
|
||||
173 173 173 gray68
|
||||
173 173 173 grey68
|
||||
176 176 176 gray69
|
||||
176 176 176 grey69
|
||||
179 179 179 gray70
|
||||
179 179 179 grey70
|
||||
181 181 181 gray71
|
||||
181 181 181 grey71
|
||||
184 184 184 gray72
|
||||
184 184 184 grey72
|
||||
186 186 186 gray73
|
||||
186 186 186 grey73
|
||||
189 189 189 gray74
|
||||
189 189 189 grey74
|
||||
191 191 191 gray75
|
||||
191 191 191 grey75
|
||||
194 194 194 gray76
|
||||
194 194 194 grey76
|
||||
196 196 196 gray77
|
||||
196 196 196 grey77
|
||||
199 199 199 gray78
|
||||
199 199 199 grey78
|
||||
201 201 201 gray79
|
||||
201 201 201 grey79
|
||||
204 204 204 gray80
|
||||
204 204 204 grey80
|
||||
207 207 207 gray81
|
||||
207 207 207 grey81
|
||||
209 209 209 gray82
|
||||
209 209 209 grey82
|
||||
212 212 212 gray83
|
||||
212 212 212 grey83
|
||||
214 214 214 gray84
|
||||
214 214 214 grey84
|
||||
217 217 217 gray85
|
||||
217 217 217 grey85
|
||||
219 219 219 gray86
|
||||
219 219 219 grey86
|
||||
222 222 222 gray87
|
||||
222 222 222 grey87
|
||||
224 224 224 gray88
|
||||
224 224 224 grey88
|
||||
227 227 227 gray89
|
||||
227 227 227 grey89
|
||||
229 229 229 gray90
|
||||
229 229 229 grey90
|
||||
232 232 232 gray91
|
||||
232 232 232 grey91
|
||||
235 235 235 gray92
|
||||
235 235 235 grey92
|
||||
237 237 237 gray93
|
||||
237 237 237 grey93
|
||||
240 240 240 gray94
|
||||
240 240 240 grey94
|
||||
242 242 242 gray95
|
||||
242 242 242 grey95
|
||||
245 245 245 gray96
|
||||
245 245 245 grey96
|
||||
247 247 247 gray97
|
||||
247 247 247 grey97
|
||||
250 250 250 gray98
|
||||
250 250 250 grey98
|
||||
252 252 252 gray99
|
||||
252 252 252 grey99
|
||||
255 255 255 gray100
|
||||
255 255 255 grey100
|
||||
169 169 169 dark grey
|
||||
169 169 169 DarkGrey
|
||||
169 169 169 dark gray
|
||||
169 169 169 DarkGray
|
||||
0 0 139 dark blue
|
||||
0 0 139 DarkBlue
|
||||
0 139 139 dark cyan
|
||||
0 139 139 DarkCyan
|
||||
139 0 139 dark magenta
|
||||
139 0 139 DarkMagenta
|
||||
139 0 0 dark red
|
||||
139 0 0 DarkRed
|
||||
144 238 144 light green
|
||||
144 238 144 LightGreen
|
||||
|
||||
|
1742
docs/commands.txt
Normal file
1742
docs/commands.txt
Normal file
File diff suppressed because it is too large
Load diff
534
docs/history.txt
Normal file
534
docs/history.txt
Normal file
|
@ -0,0 +1,534 @@
|
|||
ZDoom Release History
|
||||
|
||||
More detailed info can be found in the file docs/rh-log.txt included with
|
||||
the source code.
|
||||
|
||||
|
||||
1.22 (12 December 1999)
|
||||
=======================
|
||||
* Scroll_Texture_Both and TranslucentLine specials can now be used from ACS.
|
||||
* Fixed compiler-dependent cvar ordering during netgame arbitration.
|
||||
* Fixed certain polyobject movement combinations that would not stop even
|
||||
though they were supposed to.
|
||||
* Did some cleanup for Alpha processors.
|
||||
|
||||
|
||||
1.21 (26 November 1999)
|
||||
=======================
|
||||
* Fixed problems with thinkers removing themselves and causing other thinkers
|
||||
to not get a chance to think.
|
||||
* Added hud_scale cvar.
|
||||
|
||||
|
||||
1.20 (25 November 1999)
|
||||
=======================
|
||||
* Fixed saving, reloading, and then resaving games when travelling between
|
||||
levels in a hub.
|
||||
* Fixed saving of ACS scripts scheduled to occur on a future level.
|
||||
|
||||
|
||||
1.19 (24 November 1999)
|
||||
=======================
|
||||
* DeHackEd patches that set an actor's death sound to 0 without removing
|
||||
the A_Scream call no longer crash.
|
||||
* Fixed sync problems when playing with bullet puffs as particles vs as
|
||||
sprites.
|
||||
* Fixed friction when walking on the bottom of swimmable water.
|
||||
* Added Jeffrey Cuenco's fixes to get -host and -join to work properly.
|
||||
* Fixed BOOM generalized locked doors so that the open/close type will
|
||||
actually close.
|
||||
* Added pointer tracking and cleanup. This should fix the occasional
|
||||
crashes when saving games and various other anomalies.
|
||||
|
||||
|
||||
1.18b (15 September 1999)
|
||||
=========================
|
||||
* Fixed crash when saving games with more than 1024 objects.
|
||||
* Fixed crash when loading a game without starting a new one first.
|
||||
* Reduced the size and frequency of pregame network packets, under the
|
||||
assumption that problems people were having using 1.18 on the Internet
|
||||
are a result of limited modem bandwidth.
|
||||
|
||||
|
||||
1.18a (12 September 1999)
|
||||
=========================
|
||||
* Fixed liquid warping temporarily stopping when changing levels.
|
||||
* +/-mlook commands do not generate unknown command messages.
|
||||
* Fixed support for maps with >10 deathmatch starts. Thanks to Roman
|
||||
Hatsiev.
|
||||
* Fixed support for the special "maps" EndGame? in MAPINFO lumps.
|
||||
* Teleport destination (no gravity) now works as intended.
|
||||
* Hopefully fixed savegame problems.
|
||||
* Bots are restored from savegames.
|
||||
* Fixed keyboard turning speed when -dup is used.
|
||||
* Network commands get executed only once when -dup is used.
|
||||
* In sectors with damaging floors and swimmable deep water, the damage
|
||||
will also be applied while the player is swimming and not just when
|
||||
the player is on the ground.
|
||||
|
||||
|
||||
1.18 (5 September 1999)
|
||||
=======================
|
||||
* Replaced the older Cajun 0.71 with Cajun 0.97.
|
||||
* Fixed handling of status bar faces with skins that provide them.
|
||||
* Added swimmable water.
|
||||
* Messages printed to the middle of the screen also print to the console.
|
||||
* Skill and other server cvars get saved in savegames again.
|
||||
* Added liquid texture warping.
|
||||
* Bad MAPINFO lumps generate error messages instead of hanging.
|
||||
* Realized that it's impossible to guarantee that all object pointers will
|
||||
be valid without some effort, so FArchive saves DObject objects as NULL
|
||||
objects now instead of aborting with an error.
|
||||
* Added the ACS built-in functions localambientsound, activatorsound, and
|
||||
setlinemonsterblocking.
|
||||
* Added a thing that does nothing but count toward the number of secrets.
|
||||
* Added a fly mode.
|
||||
* Finally implemented the +moveup and +movedown commands.
|
||||
|
||||
|
||||
118test10-source only (14 August 1999)
|
||||
======================================
|
||||
* Reimplemented hub travel.
|
||||
* Optimized R_MapPlane slightly.
|
||||
* Added fov command.
|
||||
* Added vertical sub-pixel accuracy to the renderer.
|
||||
* Added searches for an IWAD in the current directory, $DOOMWADDIR, and
|
||||
$HOME.
|
||||
|
||||
|
||||
118test9 (9 August 1999)
|
||||
========================
|
||||
* Fixed the "wild" bot spinning problem.
|
||||
* Commands like changemap that could make network games go out of sync
|
||||
should work properly now. The reason they would do that is closely related
|
||||
to the reason that the bots would start spinning.
|
||||
* Finished the serializer. Now savegames work. Hubs don't, because I haven't
|
||||
written the player travelling code yet.
|
||||
* Various other code cleanup.
|
||||
|
||||
|
||||
118test8 (20 July 1999)
|
||||
=======================
|
||||
* Fixed a crash problem with the "burn" screen wipe.
|
||||
* Fixed a crash problem with playing non-assigned sound sequences.
|
||||
* Fixed a crash problem related to trying to shutdown the music subsystem
|
||||
twice.
|
||||
* If you try to add more coop bots than there are coop starts, the extra
|
||||
bot leaves quietly instead of ending the game.
|
||||
* Weapondrop is now a "server" cvar, which it should have been in the
|
||||
first place.
|
||||
* Changed the nodetable file format to be more compact.
|
||||
* Bots can now be recorded in demos.
|
||||
* Bots work in multiplayer games. Still buggy. Spawning bots can cause
|
||||
consistancy failures, and they can start spinning wildly.
|
||||
|
||||
|
||||
118test7 (12 July 1999)
|
||||
=======================
|
||||
* Fixed handling of maps with scrolling walls.
|
||||
* Single player works again. In test6, all games were considered either coop
|
||||
or deathmatch.
|
||||
* Disabled the bot thinking code in single player games, so you don't suffer
|
||||
a performance hitwhen not using bots.
|
||||
* Added some performance counters accessible through the stat command.
|
||||
|
||||
|
||||
118test6 (10 July 1999)
|
||||
=======================
|
||||
* Rewrote the wu line drawer to look better (especially in overlay mode).
|
||||
* Stretched skies now get stretched horizontally as well as vertically.
|
||||
* Did an initial integration of the Cajun Bot 0.71 code.
|
||||
|
||||
|
||||
118test5 (6 July 1999)
|
||||
======================
|
||||
* Fixed a potential infinite loop that was introduced in 118test1.
|
||||
* Delayed the initial execution of cvar callbacks.
|
||||
* Added Heretic's anti-aliased Wu line drawer to the automap.
|
||||
|
||||
|
||||
118test4 (3 July 1999)
|
||||
======================
|
||||
* Fixed the "Bad DCanvas::CopyRect" problem introduced in test3.
|
||||
* Fixed sound sequences that should not be cut off when stopped (such as
|
||||
the standard doors).
|
||||
|
||||
|
||||
118test3 (2 July 1999)
|
||||
======================
|
||||
* Removed unnecessary display mode switches.
|
||||
* Created a DCanvas class to encapsulate most 2D rendering.
|
||||
|
||||
|
||||
118test2 (1 July 1999)
|
||||
======================
|
||||
* Fixed vertical aim clipping (BFG works again).
|
||||
* Fixed monster wandering.
|
||||
* Maps with mapthings of type 0 no longer generate warning messages.
|
||||
* Crushers that do no damage no longer act as if they inflict pain to
|
||||
actors.
|
||||
* The alias command lists aliases again.
|
||||
* Aliases are saved to the config file again.
|
||||
|
||||
|
||||
118test1 (30 June 1999)
|
||||
=======================
|
||||
* Tweaked the optimized renderer for fifth-generation processors.
|
||||
* Added the following specials:
|
||||
- Line_AlignFloor
|
||||
- Line_AlignCeiling
|
||||
- Sector_SetRotation
|
||||
- Sector_SetCeilingPanning
|
||||
- Sector_SetFloorPanning
|
||||
- Secter_SetCeilingScale
|
||||
- Sector_SetFloorScale
|
||||
* Added an additional parameter to the Transfer_Heights special.
|
||||
* Switched to the OpenPTC library for display.
|
||||
* Converted lots of code to an object-oriented C++ architecture.
|
||||
|
||||
|
||||
1.17c (5 May 1999)
|
||||
==================
|
||||
* Fixed game saving crashes on maps with wind/current effects.
|
||||
* In deep water sectors, the underwater light and fog colors can now be
|
||||
set independently of the area above water.
|
||||
* Added nojump, allowjump, nofreelook, and allowfreelook keywords for
|
||||
use in MAPINFO lumps.
|
||||
* The random number seed now changes each time you run the program.
|
||||
|
||||
|
||||
1.17b (15 March 1999)
|
||||
=====================
|
||||
1.17b contains some minor bug fixes over 1.17 and 1.17a. It also loads
|
||||
faster because the sprite dimensions are not cached until they are
|
||||
actually needed. There are also some other internal changes in
|
||||
preparation for supporting Heretic and Hexen, but those don't affect
|
||||
the user yet.
|
||||
|
||||
|
||||
1.17a (21 February 1999)
|
||||
========================
|
||||
1.17a is mostly minor bug fixes and was released because Herian 2 needed
|
||||
some of those fixes. There are a few new features, however:
|
||||
|
||||
* If you have a skins directory in the same directory as zdoom.exe,
|
||||
every wad file in it will be automatically loaded when the game starts.
|
||||
This way, you don't have to load your skins by hand to use them.
|
||||
* New formatting options for text printed using ACS.
|
||||
* A code pointer to make monsters fire a railgun.
|
||||
|
||||
|
||||
1.17 (17 February 1999)
|
||||
=======================
|
||||
* I'm releasing both DOS and Win32 versions simultaneously. (The DOS version
|
||||
does not support MIDI/MUS music or a joystick.)
|
||||
|
||||
Bug fixes:
|
||||
* Multiplayer games with monsters do not crash.
|
||||
* Player corpses do not levitate and then fall down when a player respawns
|
||||
in multiplayer games.
|
||||
* Using togglemap outside of a game will not crash.
|
||||
* Monsters stop attacking their target once it's dead.
|
||||
* EV_StopPlat() does not get stuck in an infinite loop if there are moving
|
||||
platforms.
|
||||
* Partially invisible players are drawn the proper colors (instead of
|
||||
green) if r_drawfuzz is 0.
|
||||
* If you are invisible, so are your muzzle flashes.
|
||||
* Trying to execute a non-existant script will not crash.
|
||||
* Using a ChangeCamera special from an open script will not crash.
|
||||
* The FloorAndCeiling_RaiseByValue and FloorAndCeiling_LowerByValues now
|
||||
behave like Hexen's.
|
||||
* Using -loadgame from the command line works.
|
||||
* Fixed a memory leak during generation of the translucency tables.
|
||||
* In high resolutions, weapon sprites meet the bottom of the screen.
|
||||
* Sounds will not cut out mysteriously when there is no reason for them to
|
||||
do so.
|
||||
* Sounds will also not be stopped immediately when a thing is removed, so
|
||||
explosion sounds will play to their full length.
|
||||
* Things can make more than one sound at once.
|
||||
* The deathmatch scoreboard is aligned properly at high resolutions.
|
||||
* Spynext and spyprev work properly instead of leaving the status bar
|
||||
"lagging behind" the player being viewed.
|
||||
* The light-amp does not disable colored lighting.
|
||||
* The sky gets inverted when using the invulnerability powerup.
|
||||
* Implemented better z-checking code (from Heretic/Hexen).
|
||||
* Pain elementals will spawn one lost soul at a time instead of two inside
|
||||
of each other.
|
||||
* Bex patches that use thing mnemonics really do work now, and unknown bit
|
||||
messages aren't generated for regular DeHackEd patches.
|
||||
* Linedef type 134 for regular DOOM/BOOM maps requires a red key for
|
||||
activation (it was being improperly translated to require a blue one).
|
||||
* Monsters can activate secret lines when they cross them. (See DOOM2/MAP08).
|
||||
* The player extreme death sound is used.
|
||||
* When a player leaves a network game, their body is removed instead of
|
||||
being left empty.
|
||||
* 0-length sounds are treated as empty sounds instead of sounds 4 gigs long.
|
||||
* Skins that replaced player sounds with sounds in the IWAD work.
|
||||
* Muzzle flashes do not light up foggy areas, and fullbright sprites stay
|
||||
shrouded in fog.
|
||||
* Alphanumeric keys no longer automatically repeat on the console.
|
||||
* Wads such as gothicdm2 that used new flats in addition to the ones in the
|
||||
IWAD with the regular doom.exe work.
|
||||
|
||||
New features:
|
||||
* Significant speed improvements on modern processors.
|
||||
* Armor and keys are shown on the fullscreen HUD.
|
||||
* Colored text.
|
||||
* A playdemo console command.
|
||||
* A chasecam.
|
||||
* A particle sytsem.
|
||||
* An optional railgun to show off the particle system. (Start the game with
|
||||
-deh railgun.bex if you want to use it.)
|
||||
|
||||
New features interesting for wad authors:
|
||||
* Polyobjects.
|
||||
* Sound sequences.
|
||||
* WAVE files can be used as sound lumps without converting them to DMX's
|
||||
format first.
|
||||
* A sky can be specified to not be stretched even if it is shorter than 200
|
||||
pixels.
|
||||
* Sparks.
|
||||
* Particle fountains.
|
||||
* Parallax skies.
|
||||
* Some new DeHackEd thing flags from Hexen (bobbing, reflective, etc.).
|
||||
|
||||
|
||||
1.16 (22 December 1998)
|
||||
=======================
|
||||
Bug fixes:
|
||||
* No more limit on size of savegames or demos.
|
||||
* Screen resolutions above 320x200 are now the proper brightness (they were
|
||||
too bright before.)
|
||||
* Improved the brightness of the console font.
|
||||
* Bullet puffs can show up on the floor and ceiling and not just walls.
|
||||
* Missile weapons can trigger gun activation lines.
|
||||
* Barrels now bounce around as much as they did in original DOOM. (They were
|
||||
too "inert" in 1.14.)
|
||||
* If a demo is being recorded, quitting the game normally will save the demo
|
||||
to disk. (Previously, you had to use the stop command to do this.)
|
||||
|
||||
New features for players:
|
||||
* Proper support for BOOM maps.
|
||||
* Mouse wheel support and weapnext/weapprev commands.
|
||||
* Doublebindings.
|
||||
* Better analog joystick support.
|
||||
* 180 degree turn command for keyboarders.
|
||||
* Damage done by a rocket to its shooter is configurable and defaults to the
|
||||
original Doom behavior.
|
||||
* User-configurable gender. (Even though I don't have any new player sounds,
|
||||
at least the obituaries are gender-aware. :-)
|
||||
* Teamplay mode.
|
||||
* New cvar to disable manual aiming of the BFG to prevent someone from
|
||||
shooting it at the floor and quickly triggering tracer damage before.
|
||||
* Maps no longer need to have as many deathmatch starts as there are players
|
||||
in a deathmatch game.
|
||||
* Support for Doom Legacy skins.
|
||||
* Rewrote the MIDI/MUS code so that it has a working volume control.
|
||||
* Many more console commands and cvars.
|
||||
|
||||
New features for editors:
|
||||
* Proper support for BOOM maps.
|
||||
* Obituaries are configurable with a .bex patch.
|
||||
* Moster paths
|
||||
* Colored lighting
|
||||
* Fog can be applied to only part of a level instead of all of it.
|
||||
* Per-sector gravity settings.
|
||||
* Support for up to 256 ambient sounds (as opposed to the limit of 64 in
|
||||
earlier versions).
|
||||
* Sector damage adjustable from between 0-255 points of damage.
|
||||
* Changable camera views.
|
||||
* The following editing features that were introduced in Hexen are also
|
||||
available in ZDoom:
|
||||
- Most line specials take arguments that modify their behavior.
|
||||
- ACS scripting.
|
||||
- Hubs.
|
||||
- Earthquakes.
|
||||
- Dormant monsters.
|
||||
- Trigger events to happen on monster deaths.
|
||||
- "Waggling" floors.
|
||||
- Pillar builders.
|
||||
- Push activation lines (walking into a wall can trigger an event).
|
||||
- Thing spawning (e.g. for traps/gifts).
|
||||
|
||||
|
||||
1.14a (27 July 1998)
|
||||
====================
|
||||
Bugs fixed are:
|
||||
|
||||
* No more crashing about freeing a pointer without ZONEID when changing
|
||||
levels.
|
||||
* Skies wider than 256 pixels are drawn correctly.
|
||||
* Monsters' heights are once again the same as they were in id's original
|
||||
DOOM, so certain areas work properly again.
|
||||
* Monsters shouldn't teleport into each other anymore.
|
||||
* Improved support for international keyboards.
|
||||
* The skill level chosen for a new game is no longer ignored if the new
|
||||
game is started while a demo is playing.
|
||||
|
||||
Cosmetic changes:
|
||||
|
||||
* No more "sv_gravity changed to...", "skill changed to...", etc. messages
|
||||
in single player games.
|
||||
* Activating the player setup menu automatically stops any playing demos,
|
||||
since it doesn't work properly while they play.
|
||||
* Barrels don't go flying away when exploding anymore.
|
||||
* Added def_patch cvar to automatically load a DeHackEd patch each time the
|
||||
game is started.
|
||||
* ZDoom save games now use the name zdoomsv?.dsg instead of doomsav?.dsg.
|
||||
|
||||
This version also includes some preliminary BOOM support as I started
|
||||
integrating some of the BOOM source code with ZDoom:
|
||||
|
||||
* Medusa fix.
|
||||
* Openings limit removed.
|
||||
* Removed limit on switches and animations.
|
||||
* Added support for BOOM-like ANIMATED and SWITCHES lumps in PWADs.
|
||||
* Added support for BOOM-style scrollers (including conveyors).
|
||||
* Added partial deep-water support.
|
||||
|
||||
|
||||
1.14 (14 July 1998)
|
||||
===================
|
||||
Bugs fixed:
|
||||
* The bunny scroller at the end of E3M8 no longer crashes the game.
|
||||
* The IDKFA cheat gives the proper amount of armor again.
|
||||
* Demo recording works again.
|
||||
* Telefragging works again.
|
||||
* Picking up the invulnerability sphere displays the correct colors now.
|
||||
* DeHackEd patches containing text replacements no longer crash the game.
|
||||
* Printing a string containing "%s" to the console and then changing the
|
||||
video mode will no longer crash the game.
|
||||
* Chat mode finally works again.
|
||||
* If MIDAS can't initialize, you can still play the game but without sound.
|
||||
* Pistol and chaingun sounds no longer cut out when there are lots of
|
||||
zombie men shooting their pistols at you.
|
||||
* Mouse input should no longer be so jerky under Windows NT.
|
||||
* The crosshair is finally accurate for aiming.
|
||||
* Autoaim is properly remembered each time you start ZDoom.
|
||||
* Switches in the Ultimate Doom that aren't also in the shareware Doom
|
||||
properly change their appearance when switched.
|
||||
|
||||
New features:
|
||||
* Players can choose their own colors and names.
|
||||
(Player setup menu is included).
|
||||
* 8-player support (untested but should work).
|
||||
* Miscellaneous internal code changes have been borrowed from the BOOM
|
||||
source. (This does *not* mean that ZDoom supports BOOM levels yet.)
|
||||
* Cheats, chat messages, and gamestate changes are now recorded in demos.
|
||||
* Single-player demos recorded with ZDoom are generally smaller than
|
||||
before.
|
||||
* Quake 2-style deathmatch flags.
|
||||
* Cheats (optionally) work in multiplayer games.
|
||||
* Mode X is now supported under Win95, so all the machines that couldn't
|
||||
run ZDoom in 320x200 before should be able to now.
|
||||
* Fewer conditions result in error messages that quit the game. (If you
|
||||
have Heretic, try this: Start ZDoom with -file heretic and go to the
|
||||
console and type "MAP E1M1".)
|
||||
* Keys can repeat in the console.
|
||||
* The console and chat mode now use the localized keymap set with the
|
||||
Keyboard control panel.
|
||||
* Messages at the top of the screen now break along between words instead
|
||||
of in the middle of them.
|
||||
* Added -config command line parameter.
|
||||
* Added -fastdemo command line parameter.
|
||||
* Added new screen shot command. (bound to "Print Screen" key by default)
|
||||
* Added Quake-like +showscores command. (bound to "\" key by default)
|
||||
* Aliases are now saved in the config file.
|
||||
* Added support for multiple pitched sounds like in very old version of
|
||||
Doom. (Use the snd_pitched cvar to turn it on and off.)
|
||||
|
||||
|
||||
1.13 (26 May 1998)
|
||||
==================
|
||||
* Fixed some major bugs (that crashed the game) and other lesser bugs that were
|
||||
just annoying.
|
||||
* 3-D collisions for walking under and standing on other things.
|
||||
* The status bar can be scaled to the full width of the screen.
|
||||
* The screen mode can be selected from a menu inside the game.
|
||||
* ZDoom can run in a window on the desktop.
|
||||
* Better DeHackEd support. Only a few text replacements are not supported.
|
||||
Everything else works (including monster infighting which I haven't seen
|
||||
in any other port).
|
||||
* New features for level designers (see editing.txt for details):
|
||||
Specification of next and secret maps on a per-map basis.
|
||||
Specify sky texture on a per-map basis.
|
||||
Use any lump in a wad as music for a map.
|
||||
Give maps a custom name without using a DeHackEd patch.
|
||||
Maps can be named anything (not just E?M? or MAP??).
|
||||
Place any messages of any length between any two maps.
|
||||
Hexen-style fog (of any color).
|
||||
Ambient sounds--either point like Quake or global like Heretic and Hexen.
|
||||
Automatic use of DeHackEd patches in PWADs.
|
||||
No more tutti-frutti for short textures of certain heights.
|
||||
zdoom.wcf file for use with WadAuthor.
|
||||
* Rocket jumping. (One very important note about this: You need to be *in the
|
||||
air* when your rocket explodes for rocket jumping to work. This is different
|
||||
from Quake, and I will probably rewrite it for the next release.)
|
||||
* Dynamic palette flashes.
|
||||
* Supports stretching skies for freelook.
|
||||
* Larger freelook range.
|
||||
* Added tab-completion to the console.
|
||||
* zdoom.cfg is now the name of the default configuration file since Doom
|
||||
Legacy decided to start using config.cfg.
|
||||
* French language support. (Set language cvar to "french".)
|
||||
* Player obituaries.
|
||||
* Unlimited ammo cheat (use g_unlimitedammo cvar).
|
||||
|
||||
|
||||
1.12 (7 April 1998)
|
||||
===================
|
||||
* Some visual enhancements were made such as centering the menus and
|
||||
drawing borders around the status bar in higher resolutions.
|
||||
* Console commands can now be specified on the command line.
|
||||
* Removed some of DOOM's limits such as VisPlanes, VisSprites, and 2S
|
||||
HOM.
|
||||
* Rewrote some of the inner loops in assembly. (There was some assembly
|
||||
in 1.11, but it never got used.)
|
||||
* New cvars relating to mouse movement. (invertmouse, m_pitch, m_yaw,
|
||||
etc.)
|
||||
* Mouse movement doesn't get sluggish in high resolutions.
|
||||
* Automap colors are customizable.
|
||||
* Automap overlay and rotation are available.
|
||||
* Eight crosshairs.
|
||||
* Shoot up/down.
|
||||
* Alt-Tab and Pause work properly on all machines now.
|
||||
* The +jump command now works.
|
||||
* 25% and 75% translucency levels in addition to 50%. The translucency
|
||||
tables now get saved to disk, too, so they only need to be calculated
|
||||
once instead of every time the game is run.
|
||||
* The console font is now editable.
|
||||
* Near complete support for DeHackEd patches. (Only monster infighting
|
||||
and changing a few minor text strings are not supported.)
|
||||
* Sky height and position is now fixed for high resolutions. (It still
|
||||
wraps if you look up, but at least now if you look straight ahead, it
|
||||
never will.)
|
||||
* Weapon sprite is always drawn at the correct location. (It was being
|
||||
drawn too low in some resolutions like 400x300.)
|
||||
* New options menu, which includes a key configuration screen.
|
||||
* "Stealth" monsters.
|
||||
* New full-screen HUD.
|
||||
* And a few other things not worth mentioning separately.
|
||||
|
||||
|
||||
1.11 (6 March 1998) Initial Release
|
||||
===================================
|
||||
* Works under both Windows 95 and NT 4.0, although it works best under
|
||||
Win95.
|
||||
* Limited support for the Pause key. It works with some keyboards on
|
||||
some machines.
|
||||
* Supports any resolution compatible with your DirectDraw drivers.
|
||||
* Look up/down ala Heretic.
|
||||
* Translucency for selected objects.
|
||||
* Has a console with most of the functionality of Quake's. The only
|
||||
significant missing feature is Tab-completion.
|
||||
* Notarget cheat.
|
||||
* Command to kill all monsters in a level or yourself.
|
||||
* Can play MUS, MIDI, and MOD music.
|
||||
* Selected sounds are played in surround sound.
|
||||
* Doors that need keys to open are highlighted on the automap.
|
||||
* Automap now shows various statistics in addition to the level name.
|
||||
* True keybindings. Bind any key to any command or sequence of
|
||||
commands.
|
||||
* Intermission screen can now display your stats using absolute values
|
||||
rather than percentages.
|
||||
* A new more general demo format.
|
|
@ -1,3 +1,313 @@
|
|||
August 15, 2001
|
||||
- Fixed: Wind in Hexen played wrong because it used S_GetSoundPlayingInfo(),
|
||||
which has no way of following sound links. And now that I have random
|
||||
sounds, I can't think of an easy way to make it work with those. Fixed it
|
||||
by adding S_IsActorPlayingSomething() and using that instead. Changed a
|
||||
few other places that called S_GetSoundPlayingInfo() to match.
|
||||
- Fixed: Animating flats with an ANIMDEFS lump was broken.
|
||||
- Fixed: The values returned by MakeKey() changed with each rebuild because
|
||||
I was using the address of get_crc_table() as the CRC table instead of
|
||||
actually calling the function to get the CRC table's location.
|
||||
- Changed falling damage so that it can't kill you if you have god mode on.
|
||||
- Added the filterstarts mapinfo flag to enable filtering out player starts
|
||||
based on skill/gametype.
|
||||
- Fixed: Redefining sounds with a random list (whether it had one before or
|
||||
not) would cause problems because I was still sorting the S_rnd array--a
|
||||
remnant from the time when random lists were found by using binary search
|
||||
on S_rnd instead of by following the sound's link field.
|
||||
- Added the sv_ihatesounds cvar for people who think they should be able
|
||||
to shut up the BFG by landing on the ground. It forces all sounds to
|
||||
use channel 1 instead of their preferred channel.
|
||||
- Changed crushing ceilings to not restart their sound sequences each time
|
||||
they reach the top or bottom of their path.
|
||||
- Added a tag argument to S_StopSoundID() so that it only stops sounds in
|
||||
a certain group. For my purposes, a group is currently defined as "any
|
||||
sectors with the same tag." Actors do not utilise sound groups.
|
||||
- Removed S_CheckSound().
|
||||
- Added entries to DOOMX and HERETICX to make mirrors and slopes possible
|
||||
without using the Hexen map format. Also added some of EDGE's default
|
||||
linetypes for scrolling, translucency, and 2-unit floor raising.
|
||||
|
||||
August 12, 2001
|
||||
- Changed the algorithm in W_LumpNameHash() and MakeKey() to a CRC32
|
||||
algorithm because it hashes better. The only problem was that using a CRC,
|
||||
klook and mlook both have the same CRC value, so I had to twiddle MakeKey
|
||||
a little to give them unique keys.
|
||||
|
||||
August 11, 2001
|
||||
- Added support for sprite frames with 16 rotations ala EDGE. The assignment
|
||||
of rotations is the same as for EDGE: 1,9,2,A,3,B,4,C,5,D,6,E,7,F,8,G.
|
||||
- Changed the music streamers to use FSOUND_Stream_Play3DAttrib because of a
|
||||
report that they were actually being positioned with snd_3d true. I can't
|
||||
use snd_3d under NT, where I do most of my development, so I don't know if
|
||||
it made a difference or not.
|
||||
- Fixed music recognition so that wave files can be played as music.
|
||||
- Fudged about with slope handling in AActor::RunThink and P_CheckSlopeWalk
|
||||
in an effort to let the player walk on some steep slopes that are not very
|
||||
far off the surrounding ground. It is a big hack. I do not like it.
|
||||
|
||||
August 10, 2001
|
||||
- Fixed drawing of rotated, scaled, and sloped flats.
|
||||
- Fixed: PCD_PRINTNUMBER did not update the stack pointer.
|
||||
|
||||
August 8, 2001
|
||||
- Fixed drawing of scaled and sloped flats.
|
||||
- Restored the default radius and height for AInvisibleBridge, since it can no
|
||||
longer inherit them from ABridge (which sets them at game start time).
|
||||
|
||||
August 4, 2001
|
||||
- The alwaysfake modification for R_FakeFlat() did not work as intended, so I
|
||||
removed it. The changes Lee Killough made for MBF seem to be good enough.
|
||||
- Added new Thing_Destroy semantics: a tid of 0 will kill all monsters in the
|
||||
level, just like the massacre cheat.
|
||||
- Changed the friendly fire check in P_DamageMobj from (target != source) to
|
||||
(target->player != source->player). This is just so that voodoo doll damage
|
||||
cannot be reduced by turning on teamplay and changing teamdamage.
|
||||
|
||||
August 2, 2001
|
||||
- Fixed: Items were respawning at the location where they were picked up when
|
||||
they should have respawned where the level author placed them on the map.
|
||||
- Changed the criteria for executing thing death specials from MF_COUNTKILL to
|
||||
!MF_SPECIAL. Now you can give a barrel a special, and it will be executed when
|
||||
the barrel is destroyed.
|
||||
- Added the print command to print a string from the string table.
|
||||
- Added the contributed Italian translation.
|
||||
- Fixed: OB_UNDEAD said "revevant" instead of "revenant".
|
||||
- Added names for all the new keys I found when looking at the dinput.h from
|
||||
the DX8 SDK.
|
||||
- Fixed: Bindings for kp= would not save in the ini file properly.
|
||||
- Added rebind command to change the binding of the key that activated it.
|
||||
This is intended to allow the creation of generic sequential aliases. (That
|
||||
is, a series of aliases that do something, then bind a key to the next alias
|
||||
in the sequence.) Like this:
|
||||
alias dumb1 "echo one; rebind dumb2"
|
||||
alias dumb2 "echo two; rebind dumb1"
|
||||
|
||||
July 26, 2001
|
||||
- Fixed the TMulScale<x> definitions for GCC.
|
||||
|
||||
July 25, 2001
|
||||
- In I_InitSound(), A3D is no longer the default if snd_3d is true.
|
||||
- Moved s_sfxvolume, s_midivolume, and s_musicvolume into their appropriate
|
||||
i_* files and integrated them with the functions they called. Also made
|
||||
their ranges uniform at [0.0,1.0].
|
||||
|
||||
July 23, 2001
|
||||
- Added some more checks to p_setup.cpp to catch bad maps. In this
|
||||
case, the checks were added for ma_sincity.wad, which has two one-
|
||||
sided linedefs that have -1 as their front sector and will crash if
|
||||
you look at them.
|
||||
|
||||
June 8, 2001
|
||||
- Fixed: Single files added with -file were recorded with their lump
|
||||
names instead of the file names so if they got closed, they could
|
||||
not be reopened.
|
||||
|
||||
June 3, 2001
|
||||
- Finished TiMidity++ support for the Win32 version. It has two modes
|
||||
of operations: 1) Just play as normal. This only works if the sound
|
||||
card can play multiple wave streams at a time. 2) The default, have
|
||||
TiMidity output wave data through a pipe and use that to fill an
|
||||
FMOD stream. This will work with all sound cards and offers a little
|
||||
more control over the output. The only problem I could not figure out
|
||||
how to solve was how to make TiMidity quit (safely) when ZDoom wants
|
||||
it to without modifying TiMidity. The solution I ended up using was to
|
||||
have TiMidity start a thread that waits on a special named event and
|
||||
calls exit when the event becomes signalled.
|
||||
Ironically, the whole purpose of being able to use TiMidity for music
|
||||
was that it could provide better music support under Linux, yet the
|
||||
Linux side of things has not even been done yet. When I do write it, it
|
||||
should work fine with an unmodified TiMidity.
|
||||
|
||||
June 1, 2001
|
||||
- Put back the "<type> operator *()" members of the different cvar
|
||||
classes because VC++ always uses a bitwise copy when passing a class
|
||||
to a varargs function EVEN IF THE COPY CONSTRUCTOR IS DEFINED. This
|
||||
means that something like printf ("%d", dmflags); will actually copy
|
||||
dmflags to the stack instead of just dmflag's value. To make it work
|
||||
as expected, you need to use printf ("%d", (int)dmflags);. Since
|
||||
printf ("%d", *dmflags); is more compact, I decided operator * is
|
||||
useful after all.
|
||||
I just hope the timidity cvars are the only ones I used with printf
|
||||
style functions. I did not see any others when I scanned the source,
|
||||
but that doesn't mean I didn't miss any. :-(
|
||||
- Changed the name of the variable passed to cvar callbacks from "var"
|
||||
to "self" to make its use more obvious.
|
||||
- Changed the "<type> operator *()" of the different cvar types to
|
||||
"operator <type> ()" so that fetching a cvar's value looks just like
|
||||
fetching any other variable's value.
|
||||
|
||||
May 30, 2001
|
||||
- Added snd_midiprecache cvar so that people without GUSes can turn off
|
||||
the precaching.
|
||||
- Fixed: snd_surround was ignored.
|
||||
- Fixed: snd_reset turned off MIDI.
|
||||
- Added assembly routines for the different r_detail settings.
|
||||
|
||||
May 28, 2001
|
||||
- Fixed: LEVEL_SPECOPENDOOR opened the door at a speed of 8*TICRATE instead
|
||||
of 8*FRACUNIT, about 1872 times slower than it should have been.
|
||||
|
||||
May 26, 2001
|
||||
- Fixed the positioning of y-doubled view windows and changed the x-doubling
|
||||
so that it works with the optimized column drawer and does not need the
|
||||
columnofs table.
|
||||
- Fixed: M_FindResponseFile had a poor parser that considered lots of things
|
||||
to be white space that weren't and did not treat quotes specially. Now it
|
||||
uses essentially the same parser as the console.
|
||||
- Fixed Heretic/Hexen wind specials so that they can apply even when an
|
||||
actor's current velocity is 0.
|
||||
- Added MF3_NOBLOCKMONST flag to indicate which things can cross
|
||||
ML_BLOCKMONSTERS lines (because this is a better way than writing a
|
||||
special case for Heretic's APod).
|
||||
- Removed MaxSpecialCross, since it isn't needed anymore.
|
||||
|
||||
May 25, 2001
|
||||
- Fixed: ATreeDestructible's default list was missing the mass property.
|
||||
- Added Hexen's falling damage code and made the two types of falling damage
|
||||
(ZDoom or Hexen) selectable from the level and dmflags. The dmflags falling
|
||||
damage selector can now be used to enable falling damage but not to disable
|
||||
it to avoid cheating in levels meant to be played with falling damage.
|
||||
- Added a new dmflag (sv_nopassover) to make thing z-checking work as it
|
||||
did in Doom (that is, not at all, except for missiles).
|
||||
- Fixed: Chat macros did not work because Windows sends WM_SYSCHAR instead of
|
||||
WM_CHAR when ALT is held down.
|
||||
|
||||
May 14, 2001
|
||||
- Added decal groups and generators to DECALDEF.
|
||||
- Fixed potential crash when defining decals with SpawnIDs.
|
||||
|
||||
May 3, 2001
|
||||
- Added lightning scripts, which get executed whenever lightning strikes in
|
||||
a level.
|
||||
- Added the OutdoorLightning sector special (197) so that skyboxes can
|
||||
flash outdoor (as opposed to indoor) lightning without fancy scripts.
|
||||
|
||||
May 2, 2001
|
||||
- Fixed: When teleporting in a non-hub environment, the level's snapshot
|
||||
would stay around if the player had saved while in it. This was especially
|
||||
obvious if the player was moving to the same map he just left.
|
||||
- Enabled key repeating in the menus.
|
||||
- Added Hexen's lightning and fixed a bug in Hexen's code: It is not safe
|
||||
to assume that the number of sectors that lightning can apply to will
|
||||
remain constant through the level (thanks to ACS).
|
||||
|
||||
May 1, 20001
|
||||
- Fixed: The SkyBox member of sector_t was not serialized.
|
||||
|
||||
April 26, 2001
|
||||
- Fixed: When loading savegames, bobbing actors would have semi-random
|
||||
heights because they get loaded in a different memory address than they
|
||||
were saved at. The actor's address is used to determine its phase shift
|
||||
compared to other bobbing actors, so when the actor was restored there
|
||||
was no way to restore the original cycle. The solution is to take out the
|
||||
bob offset before saving and add it back in when restoring.
|
||||
- Added some DrawChar functions to DCanvas.
|
||||
- Fixed DCanvas::StringWidth() for high ASCII characters.
|
||||
- Changed the arrangement of codes in ESpecialGUIKeys to document the
|
||||
standard ASCII codes in the range [1,31].
|
||||
- Changed text color escape character from 0x81 to 0x1c, because 0x81 is a
|
||||
printable character (though most Windows fonts seem to leave it undefined).
|
||||
- Added support for WM_CHAR messages (they get fired off as EV_GUI_Char), so
|
||||
now you can do all the standard Windows text manipulation stuff when typing
|
||||
text at the console or elsewhere.
|
||||
- Fixed: Decals were being saved to savegames but were not restored properly.
|
||||
I think this was also causing crash problems after loading savegames.
|
||||
- Changed mouse pointer hiding to change the cursor to an invisible cursor
|
||||
instead of changing its visibility. This is to ensure that it works
|
||||
correctly all the time instead of just most of the time.
|
||||
- Removed testing for WM_ACTIVATE in the window procedure. Looking for
|
||||
input focus is what we really want to do where the window's active status
|
||||
was being checked.
|
||||
- Got rid of I_Pause/ResumeMouse() and let the code in i_input.cpp decide
|
||||
whether or not the pointer should be visible.
|
||||
|
||||
April 25, 2001
|
||||
- Changed action command handling so that multiple keys bound to the same
|
||||
action can coexist peacefully. That is, if you are pressing two keys bound
|
||||
to the same action and release one of them, the action will still persist
|
||||
until the second key is also released. This is like Quake.
|
||||
- Added a check for key bindings to check if a binding contains the substring
|
||||
"bind". Only if it does is the binding copied before being executed.
|
||||
Previously, the command was always copied, even if it was unneccessary.
|
||||
- Changed C_DoCommand()'s argument to a const char *.
|
||||
|
||||
April 24, 2001
|
||||
- Changed command line handling for console commands so that argv and argc
|
||||
are not calculated until the first time they are needed.
|
||||
|
||||
April 23, 2001
|
||||
- Added shuffle parameter to playlist command.
|
||||
|
||||
April 22, 2001
|
||||
- Added playlistprev and playlistnext commands.
|
||||
- Pressing F1 at the save/load menu replaces the comment with the actual
|
||||
file name of the savegame.
|
||||
- Added GK_ entries for the function keys.
|
||||
- Fixed: Quicksaving without saving/loading first crashed.
|
||||
- Added reverse tab-completion to the console, when pressing Shift-Tab.
|
||||
|
||||
April 21, 2001
|
||||
- Fixed: P_GiveAmmo() did not check userinfo.neverswitch before setting the
|
||||
pendingweapon.
|
||||
- Got rid of P_GiveWeapon() and moved its functionality into AWeapon::
|
||||
TryPickup() and added some more AWeapon member functions just so that
|
||||
picking up a weapon with sv_weaponstay true will produce all the standard
|
||||
pickup feedback. This breaks the "give weapons" cheat, but you can still
|
||||
summon them, so how bad is that really?
|
||||
- Changed P_GroupLines() to warn about lines that lack frontsectors instead of
|
||||
crashing.
|
||||
|
||||
April 20, 2001
|
||||
- Fixed: In Heretic and Hexen, things are supposed to gib at negative half
|
||||
their original health.
|
||||
|
||||
April 17, 2001
|
||||
- Fixed: It was possible to stand at the very edge of a steep slope and not
|
||||
fall off of it. It is still possible to "balance" by running away from the
|
||||
edge, but I think that will take more time to fix than it's work (especially
|
||||
if I really do go ahead and rewrite the level geometry collision detection.)
|
||||
- Added in-air friction that depends on aircontrol: The greater aircontrol is,
|
||||
the more friction affects things. Only affects players.
|
||||
- Made level gravity and aircontrol accessible through MAPINFO as well as ACS.
|
||||
- Disabled migration of zdoom.cfg. Perhaps it is better to make a clean break
|
||||
from the old format than to try and import it if zdoom.ini is not found.
|
||||
- Fixed: When the status bar face graphic changed and the status bar was
|
||||
scaled, only the area enclosing the new graphic was updated to the screen.
|
||||
It should update the entire face box.
|
||||
- Fixed: When a dehacked/bex patch changed a level's name, the change was not
|
||||
reflected in the level infos, so it did not actually become visible.
|
||||
|
||||
April 14, 2001
|
||||
- Modified S_LookupPlayerSound() to detect player sounds which were defined
|
||||
but did not have any valid lumps and automatically try again using male.
|
||||
- Added storesavepic cvar.
|
||||
- Added sorting to the savegame menus.
|
||||
- Finally tested the savegame menus to make sure that they work with more
|
||||
save games than are visible and discovered that they didn't, so I fixed
|
||||
them so they do work.
|
||||
- DCanvas::StringWidth() now knows about '\n' characters and returns the
|
||||
length of the longest line.
|
||||
- Changed the savegame menus to display games saved with an incompatible
|
||||
ZDoom version so that the user has a more convenient means of deleting them
|
||||
than by opening the savegames in a hex editor to find out which version each
|
||||
one was saved with.
|
||||
- Added "name" support to archives. Basically, names are just managed strings
|
||||
that allow duplicates to be stored by index instead of duplicating the
|
||||
string.
|
||||
|
||||
April 13, 2001
|
||||
- Fixed: Particles were rendered as if they were being drawn to the main
|
||||
frame buffer, even when they weren't.
|
||||
- Fixed: After deleting the last save game, the menu would think you still
|
||||
had a game selected and crashed if you tried to delete again.
|
||||
- Discovered the problem with some of Tei Tenga's cameras: They have invalid
|
||||
heights that put them above/below the sector. Copied the viewz clamping
|
||||
from P_CalcHeight() into R_SetupFrame() to compensate. I don't know why
|
||||
they worked in earlier versions.
|
||||
- Moved zvox.wad loading to happen after loading the IWAD. There are certain
|
||||
places where the IWAD is assumed to be the second wad loaded.
|
||||
|
||||
April 12, 2001
|
||||
- Added a new game menu for Hexen that explains you cannot start Hexen from
|
||||
a menu yet.
|
1134
docs/zdoom.txt
Normal file
1134
docs/zdoom.txt
Normal file
File diff suppressed because it is too large
Load diff
35
install
Normal file
35
install
Normal file
|
@ -0,0 +1,35 @@
|
|||
This applies to the Linux version. Ignore it if you aren't using Linux.
|
||||
|
||||
INSTALLING ZDOOM
|
||||
----------------
|
||||
You need SDL installed. Go get it from http://www.libsdl.org/ if you don't
|
||||
have it already.
|
||||
|
||||
You also need FMOD. Get it from http://www.fmod.org/
|
||||
|
||||
INSTALLING FROM SOURCE
|
||||
----------------------
|
||||
Get and install nasm from http://www.web-sites.co.uk/nasm/
|
||||
|
||||
Edit the makefile as needed. Then run make. Make install probably
|
||||
doesn't work right now, so you can find the executable in
|
||||
src/linux/release.
|
||||
|
||||
INSTALLING PRECOMPILED BINARIES
|
||||
-------------------------------
|
||||
I don't have any yet.
|
||||
|
||||
INSTALLING IWADS
|
||||
----------------
|
||||
Copy your DOOM IWAD files to /usr/share/zdoom. Alternatively, you can
|
||||
keep the IWADs somewhere else and create symbolic links to them in
|
||||
/usr/local/share/zdoom.
|
||||
|
||||
ZDoom will also look for IWADs in the current directory, ~/.zdoom, and
|
||||
$DOOMWADDIR.
|
||||
|
||||
COMPILING UNDER OSF/1
|
||||
---------------------
|
||||
OSF/1 is no longer supported. (Not that it ever really was, but now I
|
||||
have no access to OSF/1 machines, so I can't even test a minimal build.)
|
||||
|
|
@ -223,6 +223,7 @@ enum
|
|||
MF3_CANBLAST = 0x00020000, // Actor is not a monster but can be blasted
|
||||
MF3_NOTARGET = 0x00040000, // This actor not targetted when it hurts something else
|
||||
MF3_DONTGIB = 0x00080000, // Don't gib this corpse
|
||||
MF3_NOBLOCKMONST = 0x00100000, // Can cross ML_BLOCKMONSTERS lines
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
@ -285,6 +286,7 @@ enum ERenderStyle
|
|||
#define HX_ALTSHADOW (0x6800)
|
||||
|
||||
class FPlayerSkin;
|
||||
class FDecalBase;
|
||||
|
||||
inline AActor *GetDefaultByName (const char *name)
|
||||
{
|
||||
|
@ -437,7 +439,8 @@ public:
|
|||
// no matter what (even if shot)
|
||||
player_s *player; // only valid if type of APlayerPawn
|
||||
int lastlook; // player number last looked for
|
||||
mapthing2_t spawnpoint; // For nightmare respawn
|
||||
WORD SpawnPoint[3]; // For nightmare respawn
|
||||
WORD SpawnAngle;
|
||||
AActor *tracer; // Thing being chased/attacked for tracers
|
||||
fixed_t floorclip; // value to use for floor clipping
|
||||
WORD tid; // thing identifier
|
||||
|
@ -448,6 +451,7 @@ public:
|
|||
AActor *goal; // Monster's goal if not chasing anything
|
||||
FPlayerSkin *skin; // Sprite override
|
||||
byte waterlevel; // 0=none, 1=feet, 2=waist, 3=eyes
|
||||
BYTE SpawnFlags;
|
||||
SWORD gear; // killough 11/98: used in torque simulation
|
||||
|
||||
// a linked list of sectors where this object appears
|
||||
|
@ -480,6 +484,9 @@ public:
|
|||
FState *IDeathState;
|
||||
FState *RaiseState;
|
||||
|
||||
// [RH] Decal(s) this weapon/projectile generates on impact.
|
||||
FDecalBase *DecalGenerator;
|
||||
|
||||
// Public functions
|
||||
bool IsTeammate (AActor *other);
|
||||
|
|
@ -529,7 +529,7 @@ static void AM_initColors (BOOL overlayed)
|
|||
NotSeenColor = TSWallColor = am_ovunseencolor.GetIndex ();
|
||||
IntraTeleportColor = InterTeleportColor = am_ovtelecolor.GetIndex ();
|
||||
}
|
||||
else if (*am_usecustomcolors)
|
||||
else if (am_usecustomcolors)
|
||||
{
|
||||
/* Use the custom colors in the am_* cvars */
|
||||
Background = am_backcolor.GetIndex ();
|
||||
|
@ -546,7 +546,7 @@ static void AM_initColors (BOOL overlayed)
|
|||
InterTeleportColor = am_interlevelcolor.GetIndex ();
|
||||
IntraTeleportColor = am_intralevelcolor.GetIndex ();
|
||||
|
||||
DWORD ba = *am_backcolor;
|
||||
DWORD ba = am_backcolor;
|
||||
|
||||
int r = RPART(ba) - 16;
|
||||
int g = GPART(ba) - 16;
|
||||
|
@ -733,11 +733,11 @@ CCMD (togglemap)
|
|||
if (!automapactive)
|
||||
{
|
||||
AM_Start ();
|
||||
viewactive = (*am_overlay != 0.f);
|
||||
viewactive = (am_overlay != 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*am_overlay && viewactive)
|
||||
if (am_overlay && viewactive)
|
||||
{
|
||||
viewactive = false;
|
||||
SB_state = screen->GetPageCount ();
|
||||
|
@ -1561,7 +1561,7 @@ void AM_drawGrid (int color)
|
|||
{
|
||||
ml.a.x = x;
|
||||
ml.b.x = x;
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint (&ml.a.x, &ml.a.y);
|
||||
AM_rotatePoint (&ml.b.x, &ml.b.y);
|
||||
|
@ -1583,7 +1583,7 @@ void AM_drawGrid (int color)
|
|||
{
|
||||
ml.a.y = y;
|
||||
ml.b.y = y;
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint (&ml.a.x, &ml.a.y);
|
||||
AM_rotatePoint (&ml.b.x, &ml.b.y);
|
||||
|
@ -1608,7 +1608,7 @@ void AM_drawWalls ()
|
|||
l.b.x = lines[i].v2->x;
|
||||
l.b.y = lines[i].v2->y;
|
||||
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint (&l.a.x, &l.a.y);
|
||||
AM_rotatePoint (&l.b.x, &l.b.y);
|
||||
|
@ -1756,7 +1756,7 @@ void AM_drawPlayers ()
|
|||
|
||||
if (!multiplayer)
|
||||
{
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
angle = ANG90;
|
||||
else
|
||||
angle = players[consoleplayer].camera->angle;
|
||||
|
@ -1779,7 +1779,7 @@ void AM_drawPlayers ()
|
|||
mpoint_t pt;
|
||||
|
||||
if (!playeringame[i] ||
|
||||
(*deathmatch && !demoplayback) && p != players[consoleplayer].camera->player)
|
||||
(deathmatch && !demoplayback) && p != players[consoleplayer].camera->player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1794,7 +1794,7 @@ void AM_drawPlayers ()
|
|||
pt.y = p->mo->y;
|
||||
angle = p->mo->angle;
|
||||
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint (&pt.x, &pt.y);
|
||||
angle -= players[consoleplayer].camera->angle - ANG90;
|
||||
|
@ -1822,7 +1822,7 @@ void AM_drawThings (int color)
|
|||
p.y = t->y;
|
||||
angle = t->angle;
|
||||
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint (&p.x, &p.y);
|
||||
angle += ANG90 - players[consoleplayer].camera->angle;
|
||||
|
@ -1853,7 +1853,7 @@ void AM_drawMarks ()
|
|||
pt.x = markpoints[i].x;
|
||||
pt.y = markpoints[i].y;
|
||||
|
||||
if (*am_rotate)
|
||||
if (am_rotate)
|
||||
AM_rotatePoint (&pt.x, &pt.y);
|
||||
|
||||
fx = CXMTOF(pt.x);
|
||||
|
@ -1897,7 +1897,7 @@ void AM_Drawer ()
|
|||
f_w = realviewwidth;
|
||||
f_h = realviewheight;
|
||||
f_p = screen->GetPitch ();
|
||||
WeightingScale = (int)(*am_ovtrans * 256.f);
|
||||
WeightingScale = (int)(am_ovtrans * 256.f);
|
||||
if (WeightingScale < 0 || WeightingScale >= 256)
|
||||
{
|
||||
WeightingScale = 0;
|
|
@ -31,7 +31,7 @@ CCMD (addbot)
|
|||
return;
|
||||
}
|
||||
|
||||
if (argc > 2)
|
||||
if (argv.argc() > 2)
|
||||
{
|
||||
Printf ("addbot [botname] : add a bot to the game\n");
|
||||
return;
|
||||
|
@ -44,7 +44,7 @@ CCMD (addbot)
|
|||
if (color>10) color=10;
|
||||
}
|
||||
*/
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
bglobal.SpawnBot (argv[1]);
|
||||
else
|
||||
bglobal.SpawnBot (NULL);
|
|
@ -311,7 +311,7 @@ AActor *DCajunMaster::Choose_Mate (AActor *bot)
|
|||
|
||||
target = NULL;
|
||||
closest_dist = FIXED_MAX;
|
||||
if (*bot_observer)
|
||||
if (bot_observer)
|
||||
observer = players[consoleplayer].mo;
|
||||
else
|
||||
observer = NULL;
|
||||
|
@ -324,10 +324,10 @@ AActor *DCajunMaster::Choose_Mate (AActor *bot)
|
|||
if (playeringame[count]
|
||||
&& client->mo
|
||||
&& bot != client->mo
|
||||
&& (bot->IsTeammate (client->mo) || !*deathmatch)
|
||||
&& (bot->IsTeammate (client->mo) || !deathmatch)
|
||||
&& client->mo->health > 0
|
||||
&& client->mo != observer
|
||||
&& ((bot->health/2) <= client->mo->health || !*deathmatch)
|
||||
&& ((bot->health/2) <= client->mo->health || !deathmatch)
|
||||
&& !p_leader[count]) //taken?
|
||||
{
|
||||
|
||||
|
@ -374,7 +374,7 @@ AActor *DCajunMaster::Find_enemy (AActor *bot)
|
|||
AActor *observer;
|
||||
|
||||
//Allow monster killing. keep monster enemy.
|
||||
if (!*deathmatch)
|
||||
if (!deathmatch)
|
||||
return NULL;
|
||||
|
||||
//Note: It's hard to ambush a bot who is not alone
|
||||
|
@ -386,7 +386,7 @@ AActor *DCajunMaster::Find_enemy (AActor *bot)
|
|||
|
||||
target = NULL;
|
||||
closest_dist = FIXED_MAX;
|
||||
if (*bot_observer)
|
||||
if (bot_observer)
|
||||
observer = players[consoleplayer].mo;
|
||||
else
|
||||
observer = NULL;
|
|
@ -129,7 +129,7 @@ void DCajunMaster::Main (int buf)
|
|||
}
|
||||
|
||||
//Check if player should go observer. Or un observe
|
||||
if (*bot_observer && !observer)
|
||||
if (bot_observer && !observer)
|
||||
{
|
||||
Printf ("%s is now observer\n", players[consoleplayer].userinfo.netname);
|
||||
observer = true;
|
||||
|
@ -138,7 +138,7 @@ void DCajunMaster::Main (int buf)
|
|||
players[consoleplayer].mo->flags2 |= MF2_FLY;
|
||||
players[consoleplayer].mo->LinkToWorld ();
|
||||
}
|
||||
else if (!*bot_observer && observer) //Go back
|
||||
else if (!bot_observer && observer) //Go back
|
||||
{
|
||||
Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.netname);
|
||||
observer = false;
|
||||
|
@ -182,13 +182,13 @@ void DCajunMaster::Init ()
|
|||
}
|
||||
}
|
||||
|
||||
if (ctf && *teamplay == false)
|
||||
if (ctf && teamplay == false)
|
||||
teamplay = true; //Need teamplay for ctf. (which is not done yet)
|
||||
|
||||
t_join = (wanted_botnum + 1) * SPAWN_DELAY; //The + is to let player get away before the bots come in.
|
||||
|
||||
//Determine Combat distance for each weapon.
|
||||
if (*deathmatch)
|
||||
if (deathmatch)
|
||||
{
|
||||
combatdst[wp_fist] = 1 ;
|
||||
combatdst[wp_pistol] = 25000000;
|
||||
|
@ -253,8 +253,10 @@ void DCajunMaster::End ()
|
|||
|
||||
bool DCajunMaster::SpawnBot (const char *name, int color)
|
||||
{
|
||||
#if 0
|
||||
int num=0;
|
||||
static bool red; //ctf, spawning helper, spawn first blue then a red ...
|
||||
#endif
|
||||
int i;
|
||||
|
||||
//COLORS
|
||||
|
@ -334,11 +336,11 @@ bool DCajunMaster::SpawnBot (const char *name, int color)
|
|||
Net_WriteByte (playernumber);
|
||||
{
|
||||
//Set color.
|
||||
if (color == NOCOLOR && *bot_next_color < NOCOLOR && *bot_next_color >= 0)
|
||||
if (color == NOCOLOR && bot_next_color < NOCOLOR && bot_next_color >= 0)
|
||||
{
|
||||
char concat[256];
|
||||
strcpy (concat, thebot->info);
|
||||
strcat (concat, colors[*bot_next_color]);
|
||||
strcat (concat, colors[bot_next_color]);
|
||||
Net_WriteString (concat);
|
||||
}
|
||||
else
|
||||
|
@ -378,7 +380,7 @@ bool DCajunMaster::SpawnBot (const char *name, int color)
|
|||
void DCajunMaster::DoAddBot (int bnum, char *info)
|
||||
{
|
||||
D_ReadUserInfoStrings (bnum, (byte **)&info, false);
|
||||
if (!*deathmatch && playerstarts[bnum].type == 0)
|
||||
if (!deathmatch && playerstarts[bnum].type == 0)
|
||||
{
|
||||
Printf ("%s tried to join, but there was no player %d start\n",
|
||||
players[bnum].userinfo.netname, bnum+1);
|
||||
|
@ -507,7 +509,7 @@ void DCajunMaster::ForgetBots ()
|
|||
bool DCajunMaster::LoadBots ()
|
||||
{
|
||||
bglobal.ForgetBots ();
|
||||
#ifndef UNIX
|
||||
#ifndef unix
|
||||
if (!FileExists ("zcajun/" BOTFILENAME))
|
||||
{
|
||||
DPrintf ("No " BOTFILENAME ", so no bots\n");
|
|
@ -29,7 +29,7 @@ void DCajunMaster::Think (AActor *actor, ticcmd_t *cmd)
|
|||
|
||||
if (actor->health > 0) //Still alive
|
||||
{
|
||||
if (*teamplay || !*deathmatch)
|
||||
if (teamplay || !deathmatch)
|
||||
actor->player->mate = Choose_Mate (actor);
|
||||
|
||||
angle_t oldyaw = actor->angle;
|
||||
|
@ -285,13 +285,13 @@ void DCajunMaster::WhatToGet (AActor *actor, AActor *item)
|
|||
return;
|
||||
else if ((typeis (AMegasphere) || typeis (ASoulsphere) || typeis (AHealthBonus)) && actor->health >= deh.MaxSoulsphere)
|
||||
return;
|
||||
else if (((typeis (ASuperShotgun) || typeis (AShotgun) || typeis (AShell) || typeis (AShellBox)) && b->ammo[am_shell] == b->maxammo[am_shell]) || (*deathmatch != 2 && ((typeis (AShotgun) && b->weaponowned[wp_shotgun]) || (typeis (ASuperShotgun) && b->weaponowned[wp_supershotgun]))))
|
||||
else if (((typeis (ASuperShotgun) || typeis (AShotgun) || typeis (AShell) || typeis (AShellBox)) && b->ammo[am_shell] == b->maxammo[am_shell]) || (deathmatch != 2 && ((typeis (AShotgun) && b->weaponowned[wp_shotgun]) || (typeis (ASuperShotgun) && b->weaponowned[wp_supershotgun]))))
|
||||
return;
|
||||
else if (((typeis (AChaingun) || typeis (AClip) || typeis (AClipBox)) && b->ammo[am_clip] == b->maxammo[am_clip]) || (*deathmatch != 2 && (typeis (AChaingun) && b->weaponowned[wp_chaingun])))
|
||||
else if (((typeis (AChaingun) || typeis (AClip) || typeis (AClipBox)) && b->ammo[am_clip] == b->maxammo[am_clip]) || (deathmatch != 2 && (typeis (AChaingun) && b->weaponowned[wp_chaingun])))
|
||||
return;
|
||||
else if (((typeis (APlasmaRifle) || typeis (ABigFreakingGun) || typeis (ACell) || typeis (ACellPack)) && b->ammo[am_cell] == b->maxammo[am_cell]) || (*deathmatch != 2 && ((typeis (ABigFreakingGun) && b->weaponowned[wp_bfg]) || (typeis (APlasmaRifle) && b->weaponowned[wp_plasma]))))
|
||||
else if (((typeis (APlasmaRifle) || typeis (ABigFreakingGun) || typeis (ACell) || typeis (ACellPack)) && b->ammo[am_cell] == b->maxammo[am_cell]) || (deathmatch != 2 && ((typeis (ABigFreakingGun) && b->weaponowned[wp_bfg]) || (typeis (APlasmaRifle) && b->weaponowned[wp_plasma]))))
|
||||
return;
|
||||
else if (((typeis (ARocketLauncher) || typeis (ARocketAmmo) || typeis (ARocketBox)) && b->ammo[am_misl] == b->maxammo[am_misl]) || (*deathmatch != 2 && (typeis (ARocketLauncher) && b->weaponowned[wp_missile])))
|
||||
else if (((typeis (ARocketLauncher) || typeis (ARocketAmmo) || typeis (ARocketBox)) && b->ammo[am_misl] == b->maxammo[am_misl]) || (deathmatch != 2 && (typeis (ARocketLauncher) && b->weaponowned[wp_missile])))
|
||||
return;
|
||||
else if (typeis (AChainsaw) && b->weaponowned[wp_chainsaw])
|
||||
return;
|
|
@ -75,7 +75,7 @@ static const FBinding DefBindings[] =
|
|||
{ "f12", "spynext" },
|
||||
{ "mwheeldown", "weapnext" },
|
||||
{ "mwheelup", "weapprev" },
|
||||
NULL
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const FBinding DefRavenBindings[] =
|
||||
|
@ -86,7 +86,7 @@ static const FBinding DefRavenBindings[] =
|
|||
{ "pgdn", "+lookup" },
|
||||
{ "del", "+lookdown" },
|
||||
{ "end", "centerview" },
|
||||
NULL
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const FBinding DefHexenBindings[] =
|
||||
|
@ -100,52 +100,53 @@ static const FBinding DefHexenBindings[] =
|
|||
// 7 arti_teleportother
|
||||
// 6 arti_egg
|
||||
// 5 arti_invulnerability
|
||||
NULL
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
const char *KeyNames[NUM_KEYS] = {
|
||||
const char *KeyNames[NUM_KEYS] =
|
||||
{
|
||||
// This array is dependant on the particular keyboard input
|
||||
// codes generated in i_input.c. If they change there, they
|
||||
// also need to change here. In this case, we use the
|
||||
// DirectInput codes and assume a qwerty keyboard layout.
|
||||
// See <dinput.h> for the DIK_* codes
|
||||
|
||||
NULL, "escape","1", "2", "3", "4", "5", "6", //00
|
||||
"7", "8", "9", "0", "-", "=", "backspace","tab", //08
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", //10
|
||||
"o", "p", "[", "]", "enter","ctrl", "a", "s", //18
|
||||
"d", "f", "g", "h", "j", "k", "l", ";", //20
|
||||
"'", "`", "shift","\\", "z", "x", "c", "v", //28
|
||||
"b", "n", "m", ",", ".", "/", NULL, "kp*", //30
|
||||
"alt", "space","capslock","f1","f2", "f3", "f4", "f5", //38
|
||||
"f6", "f7", "f8", "f9", "f10", "numlock","scroll", "kp7", //40
|
||||
"kp8", "kp9", "kp-", "kp4", "kp5", "kp6", "kp+", "kp1", //48
|
||||
"kp2", "kp3", "kp0", "kp.", NULL, NULL, NULL, "f11", //50
|
||||
"f12", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //58
|
||||
NULL, NULL, NULL, NULL, "f13", "f14", "f15", NULL, //60
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //68
|
||||
"kana", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //70
|
||||
NULL, "convert",NULL, "noconvert",NULL,"yen", NULL, NULL, //78
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //80
|
||||
NULL, NULL, NULL, NULL, NULL, "kp=", NULL, NULL, //88
|
||||
"circumflex","@",":", "_", "kanji","stop", "ax", "unlabeled",//90
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //98
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //A0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //A8
|
||||
NULL, NULL, NULL, "kp,", NULL, "kp/", NULL, "sysrq", //B0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //B8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "home", //C0
|
||||
"uparrow","pgup",NULL, "leftarrow",NULL,"rightarrow",NULL, "end", //C8
|
||||
"downarrow","pgdn","ins","del", NULL, NULL, NULL, NULL, //D0
|
||||
NULL, NULL, NULL, "lwin", "rwin", "apps", NULL, NULL, //D8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //E0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //E8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "pause", //F8
|
||||
NULL, "escape", "1", "2", "3", "4", "5", "6", //00
|
||||
"7", "8", "9", "0", "-", "=", "backspace","tab", //08
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", //10
|
||||
"o", "p", "[", "]", "enter", "ctrl", "a", "s", //18
|
||||
"d", "f", "g", "h", "j", "k", "l", ";", //20
|
||||
"'", "`", "shift", "\\", "z", "x", "c", "v", //28
|
||||
"b", "n", "m", ",", ".", "/", NULL, "kp*", //30
|
||||
"alt", "space", "capslock", "f1", "f2", "f3", "f4", "f5", //38
|
||||
"f6", "f7", "f8", "f9", "f10", "numlock", "scroll", "kp7", //40
|
||||
"kp8", "kp9", "kp-", "kp4", "kp5", "kp6", "kp+", "kp1", //48
|
||||
"kp2", "kp3", "kp0", "kp.", NULL, NULL, "oem102", "f11", //50
|
||||
"f12", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //58
|
||||
NULL, NULL, NULL, NULL, "f13", "f14", "f15", NULL, //60
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //68
|
||||
"kana", NULL, NULL, "abnt_c1", NULL, NULL, NULL, NULL, //70
|
||||
NULL, "convert", NULL, "noconvert",NULL, "yen", "abnt_c2", NULL, //78
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //80
|
||||
NULL, NULL, NULL, NULL, NULL, "kp=", NULL, NULL, //88
|
||||
"circumflex","@", ":", "_", "kanji", "stop", "ax", "unlabeled",//90
|
||||
NULL, "prevtrack",NULL, NULL, NULL, NULL, NULL, NULL, //98
|
||||
"mute", "calculator","play", NULL, "stop", NULL, NULL, NULL, //A0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, "voldown", NULL, //A8
|
||||
"volup", NULL, "webhome", "kp,", NULL, "kp/", NULL, "sysrq", //B0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //B8
|
||||
NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0
|
||||
"uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8
|
||||
"downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0
|
||||
NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8
|
||||
NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0
|
||||
"webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F8
|
||||
|
||||
// non-keyboard buttons that can be bound
|
||||
"mouse1", "mouse2", "mouse3", "mouse4", // 4 mouse buttons
|
||||
"mwheelup", "mwheeldown",NULL, NULL, // the wheel and some extra space
|
||||
"mouse1", "mouse2", "mouse3", "mouse4", // 6 mouse buttons
|
||||
"mouse5", "mouse6", "mwheelup", "mwheeldown", // and the wheel
|
||||
"joy1", "joy2", "joy3", "joy4", // 32 joystick buttons
|
||||
"joy5", "joy6", "joy7", "joy8",
|
||||
"joy9", "joy10", "joy11", "joy12",
|
||||
|
@ -157,6 +158,7 @@ const char *KeyNames[NUM_KEYS] = {
|
|||
};
|
||||
|
||||
static char *Bindings[NUM_KEYS];
|
||||
|
||||
static char *DoubleBindings[NUM_KEYS];
|
||||
static int DClickTime[NUM_KEYS];
|
||||
static byte DClicked[(NUM_KEYS+7)/8];
|
||||
|
@ -166,12 +168,14 @@ static int GetKeyFromName (const char *name)
|
|||
int i;
|
||||
|
||||
// Names of the form #xxx are translated to key xxx automatically
|
||||
if (name[0] == '#' && name[1] != 0) {
|
||||
if (name[0] == '#' && name[1] != 0)
|
||||
{
|
||||
return atoi (name + 1);
|
||||
}
|
||||
|
||||
// Otherwise, we scan the KeyNames[] array for a matching name
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (KeyNames[i] && !stricmp (KeyNames[i], name))
|
||||
return i;
|
||||
}
|
||||
|
@ -189,30 +193,33 @@ static const char *KeyName (int key)
|
|||
return name;
|
||||
}
|
||||
|
||||
CCMD (unbindall)
|
||||
void C_UnbindAll ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
for (int i = 0; i < NUM_KEYS; ++i)
|
||||
{
|
||||
if (Bindings[i])
|
||||
{
|
||||
free (Bindings[i]);
|
||||
Bindings[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
if (DoubleBindings[i])
|
||||
{
|
||||
free (DoubleBindings[i]);
|
||||
DoubleBindings[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (unbindall)
|
||||
{
|
||||
C_UnbindAll ();
|
||||
}
|
||||
|
||||
CCMD (unbind)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if ( (i = GetKeyFromName (argv[1])) )
|
||||
{
|
||||
|
@ -235,21 +242,29 @@ CCMD (bind)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1) {
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i) {
|
||||
if (!i)
|
||||
{
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argc == 2) {
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], (Bindings[i] ? Bindings[i] : ""));
|
||||
} else {
|
||||
ReplaceString (&Bindings[i], argv[2]);
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
ReplaceString (&Bindings[i], argv.AllButFirstArg (2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Current key bindings:\n");
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (Bindings[i])
|
||||
Printf ("%s \"%s\"\n", KeyName (i), Bindings[i]);
|
||||
}
|
||||
|
@ -260,7 +275,7 @@ CCMD (undoublebind)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if ( (i = GetKeyFromName (argv[1])) )
|
||||
{
|
||||
|
@ -283,7 +298,7 @@ CCMD (doublebind)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i)
|
||||
|
@ -291,13 +306,13 @@ CCMD (doublebind)
|
|||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argc == 2)
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], (DoubleBindings[i] ? DoubleBindings[i] : ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceString (&DoubleBindings[i], argv[2]);
|
||||
ReplaceString (&DoubleBindings[i], argv.AllButFirstArg (2));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -312,6 +327,32 @@ CCMD (doublebind)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD (rebind)
|
||||
{
|
||||
char **bindings;
|
||||
|
||||
if (key == 0)
|
||||
{
|
||||
Printf ("Rebind cannot be used from the console\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (key & KEY_DBLCLICKED)
|
||||
{
|
||||
bindings = DoubleBindings;
|
||||
key &= KEY_DBLCLICKED-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindings = Bindings;
|
||||
}
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
ReplaceString (&bindings[key], argv.AllButFirstArg (1));
|
||||
}
|
||||
}
|
||||
|
||||
static void SetBinds (const FBinding *array)
|
||||
{
|
||||
while (array->Key)
|
||||
|
@ -321,7 +362,7 @@ static void SetBinds (const FBinding *array)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD(binddefaults)
|
||||
void C_BindDefaults ()
|
||||
{
|
||||
SetBinds (DefBindings);
|
||||
|
||||
|
@ -336,9 +377,21 @@ CCMD(binddefaults)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD(binddefaults)
|
||||
{
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
void C_SetDefaultBindings ()
|
||||
{
|
||||
C_UnbindAll ();
|
||||
C_BindDefaults ();
|
||||
}
|
||||
|
||||
BOOL C_DoKey (event_t *ev)
|
||||
{
|
||||
char *binding = NULL;
|
||||
bool dclick;
|
||||
int dclickspot;
|
||||
byte dclickmask;
|
||||
|
||||
|
@ -347,61 +400,61 @@ BOOL C_DoKey (event_t *ev)
|
|||
|
||||
dclickspot = ev->data1 >> 3;
|
||||
dclickmask = 1 << (ev->data1 & 7);
|
||||
dclick = false;
|
||||
|
||||
if (DClickTime[ev->data1] > level.time && ev->type == EV_KeyDown)
|
||||
{
|
||||
// Key pressed for a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] |= dclickmask;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
// Key pressed for a normal press
|
||||
{ // Key pressed for a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
DClickTime[ev->data1] = level.time + 20;
|
||||
}
|
||||
else if (DClicked[dclickspot] & dclickmask)
|
||||
{
|
||||
// Key released from a double click
|
||||
{ // Key released from a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] &= ~dclickmask;
|
||||
DClickTime[ev->data1] = 0;
|
||||
dclick = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key released from a normal press
|
||||
{ // Key released from a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!binding)
|
||||
binding = Bindings[ev->data1];
|
||||
|
||||
if (binding && (chatmodeon == 0 || ev->data1 < 256))
|
||||
if (binding == NULL)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
char copy[1024];
|
||||
// Copy the command in case the binding rebinds the key
|
||||
strcpy (copy, binding);
|
||||
AddCommandString (copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *achar;
|
||||
|
||||
achar = strchr (binding, '+');
|
||||
if (!achar)
|
||||
return false;
|
||||
binding = Bindings[ev->data1];
|
||||
dclick = false;
|
||||
}
|
||||
|
||||
if ((achar == binding) || (*(achar - 1) <= ' '))
|
||||
if (binding != NULL && (chatmodeon == 0 || ev->data1 < 256))
|
||||
{
|
||||
if (ev->type == EV_KeyUp)
|
||||
{
|
||||
if (binding[0] != '+')
|
||||
{
|
||||
*achar = '-';
|
||||
AddCommandString (binding);
|
||||
*achar = '+';
|
||||
return false;
|
||||
}
|
||||
binding[0] = '-';
|
||||
}
|
||||
|
||||
// Copy the command in case it rebinds the key
|
||||
char copy[1024];
|
||||
strncpy (copy, binding, 1023);
|
||||
copy[1023] = 0;
|
||||
AddCommandString (copy, dclick ? ev->data1 | KEY_DBLCLICKED : ev->data1);
|
||||
|
||||
if (ev->type == EV_KeyUp)
|
||||
{
|
||||
binding[0] = '+';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -429,6 +482,8 @@ void C_ArchiveBindings (FConfigFile *f, bool dodouble)
|
|||
name = "RightBracket";
|
||||
else if (name[0] == '=')
|
||||
name = "Equals";
|
||||
else if (strcmp (name, "kp=") == 0)
|
||||
name = "KP-Equals";
|
||||
}
|
||||
f->SetValueForKey (name, bindings[i]);
|
||||
}
|
||||
|
@ -452,6 +507,10 @@ void C_DoBind (const char *key, const char *bind, bool dodouble)
|
|||
{
|
||||
keynum = GetKeyFromName ("=");
|
||||
}
|
||||
else if (stricmp (key, "KP-Equals") == 0)
|
||||
{
|
||||
keynum = GetKeyFromName ("kp=");
|
||||
}
|
||||
}
|
||||
if (keynum != 0)
|
||||
{
|
||||
|
@ -465,8 +524,10 @@ int C_GetKeysForCommand (char *cmd, int *first, int *second)
|
|||
|
||||
*first = *second = c = i = 0;
|
||||
|
||||
while (i < NUM_KEYS && c < 2) {
|
||||
if (Bindings[i] && !stricmp (cmd, Bindings[i])) {
|
||||
while (i < NUM_KEYS && c < 2)
|
||||
{
|
||||
if (Bindings[i] && stricmp (cmd, Bindings[i]) == 0)
|
||||
{
|
||||
if (c++ == 0)
|
||||
*first = i;
|
||||
else
|
||||
|
@ -482,14 +543,16 @@ void C_NameKeys (char *str, int first, int second)
|
|||
int c = 0;
|
||||
|
||||
*str = 0;
|
||||
if (first) {
|
||||
if (first)
|
||||
{
|
||||
c++;
|
||||
strcpy (str, KeyName (first));
|
||||
if (second)
|
||||
strcat (str, " or ");
|
||||
}
|
||||
|
||||
if (second) {
|
||||
if (second)
|
||||
{
|
||||
c++;
|
||||
strcat (str, KeyName (second));
|
||||
}
|
||||
|
@ -502,8 +565,10 @@ void C_UnbindACommand (char *str)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
if (Bindings[i] && !stricmp (str, Bindings[i])) {
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
if (Bindings[i] && !stricmp (str, Bindings[i]))
|
||||
{
|
||||
delete[] Bindings[i];
|
||||
Bindings[i] = NULL;
|
||||
}
|
|
@ -16,8 +16,10 @@ void C_NameKeys (char *str, int first, int second);
|
|||
void C_UnbindACommand (char *str);
|
||||
void C_ChangeBinding (const char *str, int newone);
|
||||
void C_DoBind (const char *key, const char *bind, bool doublebind);
|
||||
void C_SetDefaultBindings ();
|
||||
void C_UnbindAll ();
|
||||
|
||||
// Returns string bound to given key (NULL if none)
|
||||
char *C_GetBinding (int key);
|
||||
|
||||
#endif //__C_BINDINGS_H__
|
||||
#endif //__C_BINDINGS_H__
|
|
@ -40,7 +40,7 @@ CCMD (toggleconsole)
|
|||
|
||||
BOOL CheckCheatmode ()
|
||||
{
|
||||
if (((*gameskill == sk_nightmare) || netgame || *deathmatch) && (*sv_cheats == 0.0))
|
||||
if (((gameskill == sk_nightmare) || netgame || deathmatch) && (sv_cheats == 0.0))
|
||||
{
|
||||
Printf ("You must run the server with '+set sv_cheats 1' to enable this command.\n");
|
||||
return true;
|
||||
|
@ -152,7 +152,7 @@ CCMD (chase)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (*chasedemo)
|
||||
if (chasedemo)
|
||||
{
|
||||
chasedemo = false;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -167,7 +167,7 @@ CCMD (chase)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (*deathmatch && CheckCheatmode ())
|
||||
if (deathmatch && CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
|
@ -180,7 +180,7 @@ CCMD (idclev)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
if ((argc > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1])
|
||||
if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1])
|
||||
{
|
||||
int epsd, map;
|
||||
char buf[2];
|
||||
|
@ -225,7 +225,7 @@ CCMD (changemap)
|
|||
return;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if (W_CheckNumForName (argv[1]) == -1)
|
||||
{
|
||||
|
@ -241,20 +241,11 @@ CCMD (changemap)
|
|||
|
||||
CCMD (give)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (CheckCheatmode ())
|
||||
if (CheckCheatmode () || argv.argc() < 2)
|
||||
return;
|
||||
|
||||
if (argc < 2)
|
||||
return;
|
||||
|
||||
if ( (name = BuildString (argc - 1, argv + 1)) )
|
||||
{
|
||||
Net_WriteByte (DEM_GIVECHEAT);
|
||||
Net_WriteString (name);
|
||||
delete[] name;
|
||||
}
|
||||
Net_WriteByte (DEM_GIVECHEAT);
|
||||
Net_WriteString (argv.AllButFirstArg ());
|
||||
}
|
||||
|
||||
CCMD (gameversion)
|
||||
|
@ -262,12 +253,32 @@ CCMD (gameversion)
|
|||
Printf ("%d.%d : " __DATE__ "\n", VERSION / 100, VERSION % 100);
|
||||
}
|
||||
|
||||
CCMD (print)
|
||||
{
|
||||
if (argv.argc() != 2)
|
||||
{
|
||||
Printf ("print <name>: Print a string from the string table\n");
|
||||
return;
|
||||
}
|
||||
GStrings.LoadNames ();
|
||||
int strnum = GStrings.FindString (argv[1]);
|
||||
if (strnum < 0)
|
||||
{
|
||||
Printf ("%s unknown\n", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("%s\n", GStrings(strnum));
|
||||
}
|
||||
GStrings.FlushNames ();
|
||||
}
|
||||
|
||||
CCMD (exec)
|
||||
{
|
||||
FILE *f;
|
||||
char cmd[4096];
|
||||
|
||||
if (argc < 2)
|
||||
if (argv.argc() < 2)
|
||||
return;
|
||||
|
||||
if ( (f = fopen (argv[1], "r")) )
|
||||
|
@ -300,9 +311,11 @@ CCMD (dumpheap)
|
|||
{
|
||||
int lo = PU_STATIC, hi = PU_CACHE;
|
||||
|
||||
if (argc >= 2) {
|
||||
if (argv.argc() >= 2)
|
||||
{
|
||||
lo = atoi (argv[1]);
|
||||
if (argc >= 3) {
|
||||
if (argv.argc() >= 3)
|
||||
{
|
||||
hi = atoi (argv[2]);
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +338,7 @@ CCMD (logfile)
|
|||
Logfile = NULL;
|
||||
}
|
||||
|
||||
if (argc >= 2)
|
||||
if (argv.argc() >= 2)
|
||||
{
|
||||
if ( (Logfile = fopen (argv[1], "w")) )
|
||||
{
|
||||
|
@ -343,17 +356,25 @@ bool P_StartScript (AActor *who, line_t *where, int script, char *map, int lineS
|
|||
|
||||
CCMD (puke)
|
||||
{
|
||||
if (argc < 2 || argc > 5) {
|
||||
int argc = argv.argc();
|
||||
|
||||
if (argc < 2 || argc > 5)
|
||||
{
|
||||
Printf (" puke <script> [arg1] [arg2] [arg3]\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int script = atoi (argv[1]);
|
||||
int arg0=0, arg1=0, arg2=0;
|
||||
|
||||
if (argc > 2) {
|
||||
if (argc > 2)
|
||||
{
|
||||
arg0 = atoi (argv[2]);
|
||||
if (argc > 3) {
|
||||
if (argc > 3)
|
||||
{
|
||||
arg1 = atoi (argv[3]);
|
||||
if (argc > 4) {
|
||||
if (argc > 4)
|
||||
{
|
||||
arg2 = atoi (argv[4]);
|
||||
}
|
||||
}
|
||||
|
@ -364,9 +385,7 @@ CCMD (puke)
|
|||
|
||||
CCMD (error)
|
||||
{
|
||||
char *text = BuildString (argc - 1, argv + 1);
|
||||
char *textcopy = copystring (text);
|
||||
delete[] text;
|
||||
char *textcopy = copystring (argv.AllButFirstArg ());
|
||||
I_Error (textcopy);
|
||||
}
|
||||
|
||||
|
@ -383,9 +402,9 @@ CCMD (dir)
|
|||
return;
|
||||
}
|
||||
|
||||
if (argc == 1 || chdir (argv[1]))
|
||||
if (argv.argc() == 1 || chdir (argv[1]))
|
||||
{
|
||||
match = argc == 1 ? (char *)"./*" : argv[1];
|
||||
match = argv.argc() == 1 ? (char *)"./*" : argv[1];
|
||||
|
||||
ExtractFilePath (match, dir);
|
||||
if (dir[0])
|
||||
|
@ -438,7 +457,7 @@ CCMD (fov)
|
|||
player_t *player = m_Instigator ? m_Instigator->player
|
||||
: &players[consoleplayer];
|
||||
|
||||
if (argc != 2)
|
||||
if (argv.argc() != 2)
|
||||
Printf ("fov is %g\n", player->DesiredFOV);
|
||||
else
|
||||
player->DesiredFOV = atof (argv[1]);
|
|
@ -38,7 +38,7 @@
|
|||
#define RIGHTMARGIN 8
|
||||
#define BOTTOMARGIN 12
|
||||
|
||||
static void C_TabComplete ();
|
||||
static void C_TabComplete (bool goForward);
|
||||
static BOOL TabbedLast; // Last key pressed was tab
|
||||
|
||||
|
||||
|
@ -118,32 +118,32 @@ FIntCVar msglevel ("msg", 0, CVAR_ARCHIVE);
|
|||
|
||||
CUSTOM_CVAR (Int, msg0color, 6, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (0, *var);
|
||||
setmsgcolor (0, self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, msg1color, 5, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (1, *var);
|
||||
setmsgcolor (1, self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, msg2color, 2, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (2, *var);
|
||||
setmsgcolor (2, self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, msg3color, 3, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (3, *var);
|
||||
setmsgcolor (3, self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, msg4color, 3, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (4, *var);
|
||||
setmsgcolor (4, self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, msgmidcolor, 5, CVAR_ARCHIVE)
|
||||
{
|
||||
setmsgcolor (PRINTLEVELS, *var);
|
||||
setmsgcolor (PRINTLEVELS, self);
|
||||
}
|
||||
|
||||
static void maybedrawnow ()
|
||||
|
@ -200,7 +200,7 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
|
||||
if (stylize)
|
||||
{
|
||||
byte *fadetable = (byte *)W_CacheLumpName ("COLORMAP", PU_CACHE), f, *v, *i;
|
||||
byte *fadetable = (byte *)W_CacheLumpName ("COLORMAP", PU_CACHE), f, *i;
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < conback->GetHeight(); y++)
|
||||
|
@ -212,7 +212,7 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
f = y;
|
||||
else
|
||||
f = 199 - y;
|
||||
v = fadetable + (30 - f) * 256;
|
||||
byte *v = fadetable + (30 - f) * 256;
|
||||
for (x = 0; x < conback->GetWidth(); x++)
|
||||
{
|
||||
*i = v[*i];
|
||||
|
@ -224,11 +224,12 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
for (x = 0; x < conback->GetWidth(); x++)
|
||||
{
|
||||
if (x <= 8)
|
||||
v = fadetable + (30 - x) * 256;
|
||||
*i = *(fadetable + (30 - x) * 256 + *i);
|
||||
else if (x > 312)
|
||||
v = fadetable + (x - 289) * 256;
|
||||
*i = v[*i];
|
||||
i++;
|
||||
*i = *(fadetable + (x - 289) * 256 + *i);
|
||||
else
|
||||
*i = *(fadetable + 22*256 + *i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +254,7 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
|
||||
char *fmtBuff = (char *)malloc (CONSOLESIZE);
|
||||
char **fmtLines = (char **)malloc (CONSOLELINES*sizeof(char*)*4);
|
||||
int out;
|
||||
int out = 0;
|
||||
|
||||
if (fmtBuff && fmtLines)
|
||||
{
|
||||
|
@ -264,7 +265,7 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
fmtpos = fmtBuff;
|
||||
memset (fmtBuff, 0, CONSOLESIZE);
|
||||
|
||||
for (in = TopLine, out = 0; in != InsertLine; in = (in + 1) & LINEMASK)
|
||||
for (in = TopLine; in != InsertLine; in = (in + 1) & LINEMASK)
|
||||
{
|
||||
int len = strlen (Lines[in]);
|
||||
|
||||
|
@ -348,12 +349,12 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
brokenlines_t *lines;
|
||||
int i, len, width;
|
||||
|
||||
if ((printlevel != 128 && !*show_messages) ||
|
||||
if ((printlevel != 128 && !show_messages) ||
|
||||
!(len = strlen (source)) ||
|
||||
gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
width = *con_scaletext ? DisplayWidth / CleanXfac : DisplayWidth;
|
||||
width = con_scaletext ? DisplayWidth / CleanXfac : DisplayWidth;
|
||||
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel
|
||||
&& (work = (char *)malloc (strlen ((char *)NotifyStrings[NUMNOTIFIES-1].text)
|
||||
|
@ -377,7 +378,7 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
if (addtype == NEWLINE)
|
||||
memmove (&NotifyStrings[0], &NotifyStrings[1], sizeof(struct NotifyText) * (NUMNOTIFIES-1));
|
||||
strcpy ((char *)NotifyStrings[NUMNOTIFIES-1].text, lines[i].string);
|
||||
NotifyStrings[NUMNOTIFIES-1].timeout = gametic + (int)(*con_notifytime * TICRATE);
|
||||
NotifyStrings[NUMNOTIFIES-1].timeout = gametic + (int)(con_notifytime * TICRATE);
|
||||
NotifyStrings[NUMNOTIFIES-1].printlevel = printlevel;
|
||||
addtype = NEWLINE;
|
||||
}
|
||||
|
@ -486,6 +487,7 @@ static void AddToConsole (int printlevel, const char *text)
|
|||
{
|
||||
strcpy (work, Lines[InsertLine]);
|
||||
strcat (work, text);
|
||||
cc = CR_TAN;
|
||||
}
|
||||
else if (printlevel >= 0)
|
||||
{
|
||||
|
@ -583,7 +585,7 @@ static void AddToConsole (int printlevel, const char *text)
|
|||
/* Adds a string to the console and also to the notify buffer */
|
||||
int PrintString (int printlevel, const char *outline)
|
||||
{
|
||||
if (printlevel < *msglevel || *outline == '\0')
|
||||
if (printlevel < msglevel || *outline == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -659,7 +661,7 @@ int STACK_ARGS DPrintf (const char *format, ...)
|
|||
va_list argptr;
|
||||
int count;
|
||||
|
||||
if (*developer)
|
||||
if (developer)
|
||||
{
|
||||
va_start (argptr, format);
|
||||
count = VPrintf (PRINT_HIGH, format, argptr);
|
||||
|
@ -735,7 +737,7 @@ void C_Ticker ()
|
|||
|
||||
static void C_DrawNotifyText ()
|
||||
{
|
||||
bool center = (*con_centernotify != 0.f);
|
||||
bool center = (con_centernotify != 0.f);
|
||||
int i, line, color;
|
||||
|
||||
if (gamestate != GS_LEVEL || menuactive)
|
||||
|
@ -749,7 +751,7 @@ static void C_DrawNotifyText ()
|
|||
{
|
||||
if (NotifyStrings[i].timeout > gametic)
|
||||
{
|
||||
if (!*show_messages && NotifyStrings[i].printlevel != 128)
|
||||
if (!show_messages && NotifyStrings[i].printlevel != 128)
|
||||
continue;
|
||||
|
||||
if (NotifyStrings[i].printlevel >= PRINTLEVELS)
|
||||
|
@ -757,7 +759,7 @@ static void C_DrawNotifyText ()
|
|||
else
|
||||
color = PrintColors[NotifyStrings[i].printlevel];
|
||||
|
||||
if (*con_scaletext)
|
||||
if (con_scaletext)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawTextClean (color, 0, line, NotifyStrings[i].text);
|
||||
|
@ -917,14 +919,14 @@ void C_DrawConsole ()
|
|||
else
|
||||
{
|
||||
CmdLine[2+CmdLine[0]] = 0;
|
||||
screen->DrawText (CR_ORANGE, left, bottomline, "\x1c");
|
||||
screen->DrawChar (CR_ORANGE, left, bottomline, '\x1c');
|
||||
screen->DrawText (CR_ORANGE, left + 8, bottomline,
|
||||
(char *)&CmdLine[2+CmdLine[259]]);
|
||||
}
|
||||
if (cursoron)
|
||||
{
|
||||
screen->DrawText (CR_YELLOW, left + 8 + (CmdLine[1] - CmdLine[259])* 8,
|
||||
bottomline, "\xb");
|
||||
screen->DrawChar (CR_YELLOW, left + 8 + (CmdLine[1] - CmdLine[259])* 8,
|
||||
bottomline, '\xb');
|
||||
}
|
||||
if (RowAdjust && ConBottom >= 28)
|
||||
{
|
||||
|
@ -957,7 +959,6 @@ void C_FullConsole ()
|
|||
S_Start ();
|
||||
SN_StopAllSequences ();
|
||||
V_SetBlend (0,0,0,0);
|
||||
I_PauseMouse ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -976,13 +977,11 @@ void C_ToggleConsole ()
|
|||
ConsoleState = c_falling;
|
||||
HistPos = NULL;
|
||||
TabbedLast = false;
|
||||
I_PauseMouse ();
|
||||
}
|
||||
else if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP)
|
||||
{
|
||||
ConsoleState = c_rising;
|
||||
C_FlushDisplay ();
|
||||
I_ResumeMouse ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -995,10 +994,6 @@ void C_HideConsole ()
|
|||
ConsoleState = c_up;
|
||||
ConBottom = 0;
|
||||
HistPos = NULL;
|
||||
if (!menuactive)
|
||||
{
|
||||
I_ResumeMouse ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1030,316 +1025,314 @@ static void makestartposgood ()
|
|||
|
||||
static BOOL C_HandleKey (event_t *ev, byte *buffer, int len)
|
||||
{
|
||||
switch (ev->data1)
|
||||
{
|
||||
case '\t':
|
||||
// Try to do tab-completion
|
||||
C_TabComplete ();
|
||||
break;
|
||||
|
||||
case GK_PGUP:
|
||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||
{ // Scroll console buffer up one page
|
||||
RowAdjust += (SCREENHEIGHT-4) /
|
||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? 8 : 16) - 3;
|
||||
}
|
||||
else if (RowAdjust < CONSOLELINES)
|
||||
{ // Scroll console buffer up
|
||||
RowAdjust++;
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_PGDN:
|
||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||
{ // Scroll console buffer down one page
|
||||
const int scrollamt = (SCREENHEIGHT-4) /
|
||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? 8 : 16) - 3;
|
||||
if (RowAdjust < scrollamt)
|
||||
if (ev->subtype == EV_GUI_Char)
|
||||
{ // Add keypress to command line
|
||||
if (buffer[0] < len)
|
||||
{
|
||||
if (buffer[1] == buffer[0])
|
||||
{
|
||||
RowAdjust = 0;
|
||||
buffer[buffer[0] + 2] = ev->data1;
|
||||
}
|
||||
else
|
||||
{
|
||||
RowAdjust -= scrollamt;
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 1];
|
||||
c = (char *)&buffer[buffer[1] + 2];
|
||||
|
||||
for (; e >= c; e--)
|
||||
*(e + 1) = *e;
|
||||
|
||||
*c = ev->data1;
|
||||
}
|
||||
}
|
||||
else if (RowAdjust > 0)
|
||||
{ // Scroll console buffer down
|
||||
RowAdjust--;
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_HOME:
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{ // Move to top of console buffer
|
||||
RowAdjust = CONSOLELINES;
|
||||
}
|
||||
else
|
||||
{ // Move cursor to start of line
|
||||
buffer[1] = buffer[len+4] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_END:
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{ // Move to bottom of console buffer
|
||||
RowAdjust = 0;
|
||||
}
|
||||
else
|
||||
{ // Move cursor to end of line
|
||||
buffer[1] = buffer[0];
|
||||
makestartposgood ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_LEFT:
|
||||
// Move cursor left one character
|
||||
if (buffer[1])
|
||||
{
|
||||
buffer[1]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_RIGHT:
|
||||
// Move cursor right one character
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
buffer[0]++;
|
||||
buffer[1]++;
|
||||
makestartposgood ();
|
||||
}
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
// Erase character to left of cursor
|
||||
if (buffer[0] && buffer[1])
|
||||
{
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 2];
|
||||
c = (char *)&buffer[buffer[1] + 2];
|
||||
|
||||
for (; c < e; c++)
|
||||
*(c - 1) = *c;
|
||||
|
||||
buffer[0]--;
|
||||
buffer[1]--;
|
||||
if (buffer[len+4])
|
||||
buffer[len+4]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_DEL:
|
||||
// Erase charater under cursor
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 2];
|
||||
c = (char *)&buffer[buffer[1] + 3];
|
||||
|
||||
for (; c < e; c++)
|
||||
*(c - 1) = *c;
|
||||
|
||||
buffer[0]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_UP:
|
||||
// Move to previous entry in the command history
|
||||
if (HistPos == NULL)
|
||||
{
|
||||
HistPos = HistHead;
|
||||
}
|
||||
else if (HistPos->Older)
|
||||
{
|
||||
HistPos = HistPos->Older;
|
||||
}
|
||||
|
||||
if (HistPos)
|
||||
{
|
||||
strcpy ((char *)&buffer[2], HistPos->String);
|
||||
buffer[0] = buffer[1] = strlen ((char *)&buffer[2]);
|
||||
buffer[len+4] = 0;
|
||||
makestartposgood();
|
||||
}
|
||||
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_DOWN:
|
||||
// Move to next entry in the command history
|
||||
if (HistPos && HistPos->Newer)
|
||||
{
|
||||
HistPos = HistPos->Newer;
|
||||
|
||||
strcpy ((char *)&buffer[2], HistPos->String);
|
||||
buffer[0] = buffer[1] = strlen ((char *)&buffer[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
HistPos = NULL;
|
||||
buffer[0] = buffer[1] = 0;
|
||||
}
|
||||
buffer[len+4] = 0;
|
||||
makestartposgood();
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
// Execute command line (ENTER)
|
||||
|
||||
buffer[2 + buffer[0]] = 0;
|
||||
|
||||
if (HistHead && stricmp (HistHead->String, (char *)&buffer[2]) == 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ev->data1)
|
||||
{
|
||||
// Command line was the same as the previous one,
|
||||
// so leave the history list alone
|
||||
}
|
||||
else
|
||||
{
|
||||
// Command line is different from last command line,
|
||||
// or there is nothing in the history list,
|
||||
// so add it to the history list.
|
||||
case '\t':
|
||||
// Try to do tab-completion
|
||||
C_TabComplete ((ev->data3 & GKM_SHIFT) ? false : true);
|
||||
break;
|
||||
|
||||
History *temp = (History *)Malloc (sizeof(struct History) + buffer[0]);
|
||||
|
||||
strcpy (temp->String, (char *)&buffer[2]);
|
||||
temp->Older = HistHead;
|
||||
if (HistHead)
|
||||
{
|
||||
HistHead->Newer = temp;
|
||||
case GK_PGUP:
|
||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||
{ // Scroll console buffer up one page
|
||||
RowAdjust += (SCREENHEIGHT-4) /
|
||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? 8 : 16) - 3;
|
||||
}
|
||||
temp->Newer = NULL;
|
||||
HistHead = temp;
|
||||
|
||||
if (!HistTail)
|
||||
{
|
||||
HistTail = temp;
|
||||
else if (RowAdjust < CONSOLELINES)
|
||||
{ // Scroll console buffer up
|
||||
RowAdjust++;
|
||||
}
|
||||
break;
|
||||
|
||||
if (HistSize == MAXHISTSIZE)
|
||||
{
|
||||
HistTail = HistTail->Newer;
|
||||
free (HistTail->Older);
|
||||
HistTail->Older = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HistSize++;
|
||||
}
|
||||
}
|
||||
HistPos = NULL;
|
||||
Printf (127, "]%s\n", &buffer[2]);
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
AddCommandString ((char *)&buffer[2]);
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case '`':
|
||||
case GK_ESCAPE:
|
||||
// Close console and clear command line. But if we're in the
|
||||
// fullscreen console mode, there's nothing to fall back on
|
||||
// if it's closed, so open the main menu instead.
|
||||
if (gamestate == GS_STARTUP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (gamestate == GS_FULLCONSOLE)
|
||||
{
|
||||
AddCommandString ("menu_main");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
HistPos = NULL;
|
||||
C_ToggleConsole ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'V':
|
||||
TabbedLast = false;
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
if (ev->data1 == 'C')
|
||||
{ // copy to clipboard
|
||||
if (buffer[0] > 0)
|
||||
case GK_PGDN:
|
||||
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
|
||||
{ // Scroll console buffer down one page
|
||||
const int scrollamt = (SCREENHEIGHT-4) /
|
||||
((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? 8 : 16) - 3;
|
||||
if (RowAdjust < scrollamt)
|
||||
{
|
||||
buffer[2 + buffer[0]] = 0;
|
||||
I_PutInClipboard ((char *)&buffer[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // paste from clipboard
|
||||
char *clip = I_GetFromClipboard ();
|
||||
if (clip != NULL)
|
||||
{
|
||||
strtok (clip, "\r\n\b");
|
||||
int cliplen = strlen (clip);
|
||||
|
||||
cliplen = MIN(len, cliplen);
|
||||
if (buffer[0] + cliplen > len)
|
||||
{
|
||||
cliplen = len - buffer[0];
|
||||
}
|
||||
|
||||
if (cliplen > 0)
|
||||
{
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
memmove (&buffer[2 + buffer[1] + cliplen],
|
||||
&buffer[2 + buffer[1]], buffer[0] - buffer[1]);
|
||||
}
|
||||
memcpy (&buffer[2 + buffer[1]], clip, cliplen);
|
||||
buffer[0] += cliplen;
|
||||
buffer[1] += cliplen;
|
||||
makestartposgood ();
|
||||
HistPos = NULL;
|
||||
}
|
||||
delete[] clip;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// intentional fall-through
|
||||
default:
|
||||
if (ev->data2 >= ' ')
|
||||
{ // Add keypress to command line
|
||||
|
||||
if (buffer[0] < len)
|
||||
{
|
||||
char data = ev->data2;
|
||||
|
||||
if (buffer[1] == buffer[0])
|
||||
{
|
||||
buffer[buffer[0] + 2] = data;
|
||||
RowAdjust = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 1];
|
||||
c = (char *)&buffer[buffer[1] + 2];
|
||||
|
||||
for (; e >= c; e--)
|
||||
*(e + 1) = *e;
|
||||
|
||||
*c = data;
|
||||
RowAdjust -= scrollamt;
|
||||
}
|
||||
buffer[0]++;
|
||||
}
|
||||
else if (RowAdjust > 0)
|
||||
{ // Scroll console buffer down
|
||||
RowAdjust--;
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_HOME:
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{ // Move to top of console buffer
|
||||
RowAdjust = CONSOLELINES;
|
||||
}
|
||||
else
|
||||
{ // Move cursor to start of line
|
||||
buffer[1] = buffer[len+4] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_END:
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{ // Move to bottom of console buffer
|
||||
RowAdjust = 0;
|
||||
}
|
||||
else
|
||||
{ // Move cursor to end of line
|
||||
buffer[1] = buffer[0];
|
||||
makestartposgood ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_LEFT:
|
||||
// Move cursor left one character
|
||||
if (buffer[1])
|
||||
{
|
||||
buffer[1]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GK_RIGHT:
|
||||
// Move cursor right one character
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
buffer[1]++;
|
||||
makestartposgood ();
|
||||
HistPos = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
// Erase character to left of cursor
|
||||
if (buffer[0] && buffer[1])
|
||||
{
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 2];
|
||||
c = (char *)&buffer[buffer[1] + 2];
|
||||
|
||||
for (; c < e; c++)
|
||||
*(c - 1) = *c;
|
||||
|
||||
buffer[0]--;
|
||||
buffer[1]--;
|
||||
if (buffer[len+4])
|
||||
buffer[len+4]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_DEL:
|
||||
// Erase charater under cursor
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
char *c, *e;
|
||||
|
||||
e = (char *)&buffer[buffer[0] + 2];
|
||||
c = (char *)&buffer[buffer[1] + 3];
|
||||
|
||||
for (; c < e; c++)
|
||||
*(c - 1) = *c;
|
||||
|
||||
buffer[0]--;
|
||||
makestartposgood ();
|
||||
}
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_UP:
|
||||
// Move to previous entry in the command history
|
||||
if (HistPos == NULL)
|
||||
{
|
||||
HistPos = HistHead;
|
||||
}
|
||||
else if (HistPos->Older)
|
||||
{
|
||||
HistPos = HistPos->Older;
|
||||
}
|
||||
|
||||
if (HistPos)
|
||||
{
|
||||
strcpy ((char *)&buffer[2], HistPos->String);
|
||||
buffer[0] = buffer[1] = strlen ((char *)&buffer[2]);
|
||||
buffer[len+4] = 0;
|
||||
makestartposgood();
|
||||
}
|
||||
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case GK_DOWN:
|
||||
// Move to next entry in the command history
|
||||
if (HistPos && HistPos->Newer)
|
||||
{
|
||||
HistPos = HistPos->Newer;
|
||||
|
||||
strcpy ((char *)&buffer[2], HistPos->String);
|
||||
buffer[0] = buffer[1] = strlen ((char *)&buffer[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
HistPos = NULL;
|
||||
buffer[0] = buffer[1] = 0;
|
||||
}
|
||||
buffer[len+4] = 0;
|
||||
makestartposgood();
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
// Execute command line (ENTER)
|
||||
|
||||
buffer[2 + buffer[0]] = 0;
|
||||
|
||||
if (HistHead && stricmp (HistHead->String, (char *)&buffer[2]) == 0)
|
||||
{
|
||||
// Command line was the same as the previous one,
|
||||
// so leave the history list alone
|
||||
}
|
||||
else
|
||||
{
|
||||
// Command line is different from last command line,
|
||||
// or there is nothing in the history list,
|
||||
// so add it to the history list.
|
||||
|
||||
History *temp = (History *)Malloc (sizeof(struct History) + buffer[0]);
|
||||
|
||||
strcpy (temp->String, (char *)&buffer[2]);
|
||||
temp->Older = HistHead;
|
||||
if (HistHead)
|
||||
{
|
||||
HistHead->Newer = temp;
|
||||
}
|
||||
temp->Newer = NULL;
|
||||
HistHead = temp;
|
||||
|
||||
if (!HistTail)
|
||||
{
|
||||
HistTail = temp;
|
||||
}
|
||||
|
||||
if (HistSize == MAXHISTSIZE)
|
||||
{
|
||||
HistTail = HistTail->Newer;
|
||||
free (HistTail->Older);
|
||||
HistTail->Older = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HistSize++;
|
||||
}
|
||||
}
|
||||
HistPos = NULL;
|
||||
Printf (127, "]%s\n", &buffer[2]);
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
AddCommandString ((char *)&buffer[2]);
|
||||
TabbedLast = false;
|
||||
break;
|
||||
|
||||
case '`':
|
||||
case GK_ESCAPE:
|
||||
// Close console and clear command line. But if we're in the
|
||||
// fullscreen console mode, there's nothing to fall back on
|
||||
// if it's closed, so open the main menu instead.
|
||||
if (gamestate == GS_STARTUP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (gamestate == GS_FULLCONSOLE)
|
||||
{
|
||||
C_DoCommand ("menu_main");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
HistPos = NULL;
|
||||
C_ToggleConsole ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'V':
|
||||
TabbedLast = false;
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
if (ev->data1 == 'C')
|
||||
{ // copy to clipboard
|
||||
if (buffer[0] > 0)
|
||||
{
|
||||
buffer[2 + buffer[0]] = 0;
|
||||
I_PutInClipboard ((char *)&buffer[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // paste from clipboard
|
||||
char *clip = I_GetFromClipboard ();
|
||||
if (clip != NULL)
|
||||
{
|
||||
strtok (clip, "\r\n\b");
|
||||
int cliplen = strlen (clip);
|
||||
|
||||
cliplen = MIN(len, cliplen);
|
||||
if (buffer[0] + cliplen > len)
|
||||
{
|
||||
cliplen = len - buffer[0];
|
||||
}
|
||||
|
||||
if (cliplen > 0)
|
||||
{
|
||||
if (buffer[1] < buffer[0])
|
||||
{
|
||||
memmove (&buffer[2 + buffer[1] + cliplen],
|
||||
&buffer[2 + buffer[1]], buffer[0] - buffer[1]);
|
||||
}
|
||||
memcpy (&buffer[2 + buffer[1]], clip, cliplen);
|
||||
buffer[0] += cliplen;
|
||||
buffer[1] += cliplen;
|
||||
makestartposgood ();
|
||||
HistPos = NULL;
|
||||
}
|
||||
delete[] clip;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CursorTicker = C_BLINKRATE;
|
||||
cursoron = 1;
|
||||
|
@ -1356,7 +1349,9 @@ BOOL C_Responder (event_t *ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat)
|
||||
if (ev->subtype == EV_GUI_KeyDown ||
|
||||
ev->subtype == EV_GUI_KeyRepeat ||
|
||||
ev->subtype == EV_GUI_Char)
|
||||
{
|
||||
return C_HandleKey (ev, CmdLine, 255);
|
||||
}
|
||||
|
@ -1383,12 +1378,7 @@ CCMD (clear)
|
|||
|
||||
CCMD (echo)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
char *str = BuildString (argc - 1, argv + 1);
|
||||
Printf ("%s\n", str);
|
||||
delete[] str;
|
||||
}
|
||||
Printf ("%s\n", argv.AllButFirstArg());
|
||||
}
|
||||
|
||||
/* Printing in the middle of the screen */
|
||||
|
@ -1411,7 +1401,7 @@ void C_MidPrint (const char *msg)
|
|||
AddToConsole (-1, buff);
|
||||
|
||||
StatusBar->AttachMessage (new FHUDMessage (msg, 1.5f, 0.375f,
|
||||
(EColorRange)PrintColors[PRINTLEVELS], *con_midtime), 'CNTR');
|
||||
(EColorRange)PrintColors[PRINTLEVELS], con_midtime), 'CNTR');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1495,7 +1485,7 @@ static int FindDiffPoint (const char *str1, const char *str2)
|
|||
return i;
|
||||
}
|
||||
|
||||
static void C_TabComplete ()
|
||||
static void C_TabComplete (bool goForward)
|
||||
{
|
||||
int i;
|
||||
int diffpoint;
|
||||
|
@ -1524,11 +1514,26 @@ static void C_TabComplete ()
|
|||
if (!FindTabCommand ((char *)(CmdLine + TabStart), &TabPos, TabSize))
|
||||
return; // No initial matches
|
||||
|
||||
TabPos--;
|
||||
if (goForward)
|
||||
{ // Position just before the list of completions so that when TabPos
|
||||
// gets advanced below, it will be at the first one.
|
||||
--TabPos;
|
||||
}
|
||||
else
|
||||
{ // Find the last matching tab, then go one past it.
|
||||
while (++TabPos < NumTabCommands)
|
||||
{
|
||||
if (FindDiffPoint (TabCommands[TabPos].Name, (char *)(CmdLine + TabStart)) < TabSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
TabbedLast = true;
|
||||
}
|
||||
|
||||
if (++TabPos == NumTabCommands)
|
||||
if ((goForward && ++TabPos == NumTabCommands) ||
|
||||
(!goForward && --TabPos < 0))
|
||||
{
|
||||
TabbedLast = false;
|
||||
CmdLine[0] = CmdLine[1] = TabSize;
|
|
@ -24,8 +24,8 @@ void C_NewModeAdjust (void);
|
|||
void C_Ticker (void);
|
||||
|
||||
int PrintString (int printlevel, const char *string);
|
||||
int VPrintf (int printlevel, const char *format, va_list parms);
|
||||
int STACK_ARGS Printf_Bold (const char *format, ...);
|
||||
int VPrintf (int printlevel, const char *format, va_list parms) GCCFORMAT(2);
|
||||
int STACK_ARGS Printf_Bold (const char *format, ...) GCCPRINTF(1,2);
|
||||
|
||||
void C_DrawConsole (void);
|
||||
void C_ToggleConsole (void);
|
|
@ -401,7 +401,9 @@ void FBaseCVar::EnableCallbacks ()
|
|||
while (cvar)
|
||||
{
|
||||
if (!(cvar->Flags & CVAR_NOINITCALL))
|
||||
{
|
||||
cvar->Callback ();
|
||||
}
|
||||
cvar = cvar->m_Next;
|
||||
}
|
||||
}
|
||||
|
@ -676,8 +678,6 @@ void FColorCVar::SetGenericRepDefault (UCVarValue value, ECVarType type)
|
|||
|
||||
void FColorCVar::DoSet (UCVarValue value, ECVarType type)
|
||||
{
|
||||
if (strcmp (Name, "dimcolor") == 0)
|
||||
value = value;
|
||||
Value = ToInt2 (value, type);
|
||||
if (screen)
|
||||
Index = ColorMatcher.Pick (RPART(Value), GPART(Value), BPART(Value));
|
||||
|
@ -777,14 +777,14 @@ ECVarType FFlagCVar::GetRealType () const
|
|||
|
||||
UCVarValue FFlagCVar::GetGenericRep (ECVarType type) const
|
||||
{
|
||||
return FromBool ((*ValueVar & BitVal) != 0, type);
|
||||
return FromBool ((ValueVar & BitVal) != 0, type);
|
||||
}
|
||||
|
||||
UCVarValue FFlagCVar::GetFavoriteRep (ECVarType *type) const
|
||||
{
|
||||
UCVarValue ret;
|
||||
*type = CVAR_Bool;
|
||||
ret.Bool = (*ValueVar & BitVal) != 0;
|
||||
ret.Bool = (ValueVar & BitVal) != 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1022,6 +1022,28 @@ FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev)
|
|||
return var;
|
||||
}
|
||||
|
||||
FBaseCVar *FindCVarSub (const char *var_name, int namelen)
|
||||
{
|
||||
FBaseCVar *var;
|
||||
|
||||
if (var_name == NULL)
|
||||
return NULL;
|
||||
|
||||
var = CVars;
|
||||
while (var)
|
||||
{
|
||||
const char *probename = var->GetName ();
|
||||
|
||||
if (strnicmp (probename, var_name, namelen) == 0 &&
|
||||
probename[namelen] == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
var = var->m_Next;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
void UnlatchCVars (void)
|
||||
{
|
||||
FLatchedValue var;
|
||||
|
@ -1088,34 +1110,41 @@ void C_ArchiveCVars (FConfigFile *f, int type)
|
|||
}
|
||||
}
|
||||
|
||||
void FBaseCVar::CmdSet (const char *newval)
|
||||
{
|
||||
UCVarValue val;
|
||||
|
||||
// Casting away the const is safe in this case.
|
||||
val.String = const_cast<char *>(newval);
|
||||
SetGenericRep (val, CVAR_String);
|
||||
|
||||
if (GetFlags() & CVAR_NOSET)
|
||||
Printf ("%s is write protected.\n", GetName());
|
||||
else if (GetFlags() & CVAR_LATCH)
|
||||
Printf ("%s will be changed for next game.\n", GetName());
|
||||
}
|
||||
|
||||
CCMD (set)
|
||||
{
|
||||
if (argc != 3)
|
||||
if (argv.argc() != 3)
|
||||
{
|
||||
Printf ("usage: set <variable> <value>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
FBaseCVar *var, *prev;
|
||||
UCVarValue val;
|
||||
FBaseCVar *var;
|
||||
|
||||
var = FindCVar (argv[1], &prev);
|
||||
if (!var)
|
||||
var = FindCVar (argv[1], NULL);
|
||||
if (var == NULL)
|
||||
var = new FStringCVar (argv[1], NULL, CVAR_AUTO | CVAR_UNSETTABLE | cvar_defflags);
|
||||
|
||||
val.String = argv[2];
|
||||
var->SetGenericRep (val, CVAR_String);
|
||||
|
||||
if (var->GetFlags() & CVAR_NOSET)
|
||||
Printf ("%s is write protected.\n", argv[1]);
|
||||
else if (var->GetFlags() & CVAR_LATCH)
|
||||
Printf ("%s will be changed for next game.\n", argv[1]);
|
||||
var->CmdSet (argv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (unset)
|
||||
{
|
||||
if (argc != 2)
|
||||
if (argv.argc() != 2)
|
||||
{
|
||||
Printf ("usage: unset <variable>\n");
|
||||
}
|
||||
|
@ -1140,7 +1169,7 @@ CCMD (get)
|
|||
{
|
||||
FBaseCVar *var, *prev;
|
||||
|
||||
if (argc >= 2)
|
||||
if (argv.argc() >= 2)
|
||||
{
|
||||
if ( (var = FindCVar (argv[1], &prev)) )
|
||||
{
|
||||
|
@ -1164,7 +1193,7 @@ CCMD (toggle)
|
|||
FBaseCVar *var, *prev;
|
||||
UCVarValue val;
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
if ( (var = FindCVar (argv[1], &prev)) )
|
||||
{
|
||||
|
@ -1177,7 +1206,7 @@ CCMD (toggle)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD (cvarlist)
|
||||
void FBaseCVar::ListVars (const char *filter)
|
||||
{
|
||||
FBaseCVar *var = CVars;
|
||||
int count = 0;
|
||||
|
@ -1197,8 +1226,20 @@ CCMD (cvarlist)
|
|||
flags & CVAR_LATCH ? 'L' :
|
||||
flags & CVAR_UNSETTABLE ? '*' : ' ',
|
||||
var->GetName(),
|
||||
val.String);
|
||||
var->GetGenericRep (CVAR_String).String);
|
||||
var = var->m_Next;
|
||||
}
|
||||
Printf ("%d cvars\n", count);
|
||||
}
|
||||
|
||||
CCMD (cvarlist)
|
||||
{
|
||||
if (argv.argc() == 1)
|
||||
{
|
||||
FBaseCVar::ListVars (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FBaseCVar::ListVars (argv[1]);
|
||||
}
|
||||
}
|
|
@ -21,11 +21,12 @@ enum
|
|||
// but can be set from the command line
|
||||
CVAR_LATCH = 16, // save changes until server restart
|
||||
CVAR_UNSETTABLE = 32, // can unset this var from console
|
||||
CVAR_DEMOSAVE = 64, // save the value of this FBaseCVar in a demo
|
||||
CVAR_DEMOSAVE = 64, // save the value of this cvar in a demo
|
||||
CVAR_ISDEFAULT = 128, // is cvar unchanged since creation?
|
||||
CVAR_AUTO = 256, // allocated; needs to be freed when destroyed
|
||||
CVAR_NOINITCALL = 512, // don't call callback at game start
|
||||
CVAR_GLOBALCONFIG = 1024, // cvar is saved to global config section
|
||||
CVAR_VIDEOCONFIG = 2048, // cvar is saved to video config section
|
||||
};
|
||||
|
||||
union UCVarValue
|
||||
|
@ -60,6 +61,7 @@ public:
|
|||
inline const char *GetName () const { return Name; }
|
||||
inline DWORD GetFlags () const { return Flags; }
|
||||
|
||||
void CmdSet (const char *newval);
|
||||
void ForceSet (UCVarValue value, ECVarType type);
|
||||
void SetGenericRep (UCVarValue value, ECVarType type);
|
||||
void ResetToDefault ();
|
||||
|
@ -80,7 +82,10 @@ public:
|
|||
static void EnableCallbacks ();
|
||||
static void ResetColors (); // recalc color cvars' indices after screen change
|
||||
|
||||
static void ListVars (const char *filter);
|
||||
|
||||
protected:
|
||||
FBaseCVar () {}
|
||||
virtual void DoSet (UCVarValue value, ECVarType type) = 0;
|
||||
|
||||
static bool ToBool (UCVarValue value, ECVarType type);
|
||||
|
@ -96,8 +101,8 @@ protected:
|
|||
DWORD Flags;
|
||||
|
||||
private:
|
||||
FBaseCVar (const char *name, DWORD flags);
|
||||
FBaseCVar (const FBaseCVar &var);
|
||||
FBaseCVar (const char *name, DWORD flags);
|
||||
|
||||
void (*m_Callback)(FBaseCVar &);
|
||||
FBaseCVar *m_Next;
|
||||
|
@ -105,8 +110,6 @@ private:
|
|||
static bool m_UseCallback;
|
||||
static bool m_DoNoSet;
|
||||
|
||||
friend void Cmd_cvarlist (int, char **, const char *, AActor *);
|
||||
|
||||
// Writes all cvars that could effect demo sync to *demo_p. These are
|
||||
// cvars that have either CVAR_SERVERINFO or CVAR_DEMOSAVE set.
|
||||
friend void C_WriteCVars (byte **demo_p, DWORD filter, bool compact=false);
|
||||
|
@ -120,6 +123,7 @@ private:
|
|||
|
||||
// Finds a named cvar
|
||||
friend FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
|
||||
friend FBaseCVar *FindCVarSub (const char *var_name, int namelen);
|
||||
|
||||
// Called from G_InitNew()
|
||||
friend void UnlatchCVars (void);
|
||||
|
@ -148,7 +152,8 @@ public:
|
|||
|
||||
inline bool operator= (bool boolval)
|
||||
{ UCVarValue val; val.Bool = boolval; SetGenericRep (val, CVAR_Bool); return boolval; }
|
||||
inline bool operator* () { return Value; }
|
||||
inline operator bool () const { return Value; }
|
||||
inline bool operator *() const { return Value; }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -172,7 +177,8 @@ public:
|
|||
|
||||
int operator= (int intval)
|
||||
{ UCVarValue val; val.Int = intval; SetGenericRep (val, CVAR_Int); return intval; }
|
||||
inline int operator* () { return Value; }
|
||||
inline operator int () const { return Value; }
|
||||
inline int operator *() const { return Value; }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -198,7 +204,8 @@ public:
|
|||
|
||||
float operator= (float floatval)
|
||||
{ UCVarValue val; val.Float = floatval; SetGenericRep (val, CVAR_Float); return floatval; }
|
||||
inline float operator* () { return Value; }
|
||||
inline operator float () const { return Value; }
|
||||
inline float operator *() const { return Value; }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -222,7 +229,8 @@ public:
|
|||
|
||||
char *operator= (char *stringrep)
|
||||
{ UCVarValue val; val.String = stringrep; SetGenericRep (val, CVAR_String); return stringrep; }
|
||||
inline const char *operator* () { return Value; }
|
||||
inline operator const char * () const { return Value; }
|
||||
inline const char *operator *() const { return Value; }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -242,8 +250,9 @@ public:
|
|||
virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
|
||||
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
|
||||
|
||||
inline int operator* () { return Value; }
|
||||
inline int GetIndex () { return Index; }
|
||||
inline operator DWORD () const { return Value; }
|
||||
inline DWORD operator *() const { return Value; }
|
||||
inline int GetIndex () const { return Index; }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -269,7 +278,8 @@ public:
|
|||
|
||||
bool operator= (bool boolval)
|
||||
{ UCVarValue val; val.Bool = boolval; SetGenericRep (val, CVAR_Bool); return boolval; }
|
||||
inline int operator* () { return (*ValueVar & BitVal); }
|
||||
inline operator int () const { return (ValueVar & BitVal); }
|
||||
inline int operator *() const { return (ValueVar & BitVal); }
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
@ -300,7 +310,7 @@ void C_RestoreCVars (void);
|
|||
#define CUSTOM_CVAR(type,name,def,flags) \
|
||||
static void cvarfunc_##name(F##type##CVar &); \
|
||||
F##type##CVar name (#name, def, flags, cvarfunc_##name); \
|
||||
static void cvarfunc_##name(F##type##CVar &var)
|
||||
static void cvarfunc_##name(F##type##CVar &self)
|
||||
|
||||
#define CVAR(type,name,def,flags) \
|
||||
F##type##CVar name (#name, def, flags);
|
|
@ -13,6 +13,9 @@
|
|||
#include "m_alloc.h"
|
||||
#include "d_player.h"
|
||||
#include "configfile.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_crc32.h"
|
||||
|
||||
|
||||
static long ParseCommandLine (const char *args, int *argc, char **argv);
|
||||
|
||||
|
@ -38,45 +41,65 @@ class DStoredCommand : public DThinker
|
|||
{
|
||||
DECLARE_CLASS (DStoredCommand, DThinker)
|
||||
public:
|
||||
DStoredCommand (int argc, char **argv, const char *args);
|
||||
DStoredCommand (FConsoleCommand *com, const char *cmd);
|
||||
~DStoredCommand ();
|
||||
void RunThink ();
|
||||
|
||||
private:
|
||||
DStoredCommand ();
|
||||
|
||||
int ArgC;
|
||||
char **ArgV;
|
||||
char *ArgS;
|
||||
FConsoleCommand *Command;
|
||||
char *Text;
|
||||
};
|
||||
|
||||
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name);
|
||||
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, FConsoleCommand **prev);
|
||||
struct FActionMap
|
||||
{
|
||||
unsigned int Key; // value from passing Name to MakeKey()
|
||||
FButtonStatus *Button;
|
||||
char Name[12];
|
||||
};
|
||||
|
||||
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name, int namelen);
|
||||
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, int namelen, FConsoleCommand **prev);
|
||||
|
||||
FConsoleCommand *Commands[HASH_SIZE];
|
||||
|
||||
struct ActionBits actionbits[NUM_ACTIONS] =
|
||||
FButtonStatus Button_Mlook, Button_Klook, Button_Use,
|
||||
Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft,
|
||||
Button_Strafe, Button_LookDown, Button_LookUp, Button_Back,
|
||||
Button_Forward, Button_Right, Button_Left, Button_MoveDown,
|
||||
Button_MoveUp, Button_Jump, Button_ShowScores;
|
||||
|
||||
// To add new actions, go to the console and type "key <action name>".
|
||||
// This will give you the key value to use in the first column. Then
|
||||
// insert your new action into this list so that the keys remain sorted
|
||||
// in ascending order. No two keys can be identical. If yours matches
|
||||
// an existing key, either modify MakeKey(), or (preferably) change the
|
||||
// name of your action.
|
||||
|
||||
FActionMap ActionMaps[] =
|
||||
{
|
||||
{ 0x00409, ACTION_USE, "use" },
|
||||
{ 0x0074d, ACTION_BACK, "back" },
|
||||
{ 0x007e4, ACTION_LEFT, "left" },
|
||||
{ 0x00816, ACTION_JUMP, "jump" },
|
||||
{ 0x0106d, ACTION_KLOOK, "klook" },
|
||||
{ 0x0109d, ACTION_MLOOK, "mlook" },
|
||||
{ 0x010d8, ACTION_RIGHT, "right" },
|
||||
{ 0x0110a, ACTION_SPEED, "speed" },
|
||||
{ 0x01fc5, ACTION_ATTACK, "attack" },
|
||||
{ 0x021ae, ACTION_LOOKUP, "lookup" },
|
||||
{ 0x021fe, ACTION_MOVEUP, "moveup" },
|
||||
{ 0x02315, ACTION_STRAFE, "strafe" },
|
||||
{ 0x041c4, ACTION_FORWARD, "forward" },
|
||||
{ 0x08788, ACTION_LOOKDOWN, "lookdown" },
|
||||
{ 0x088c4, ACTION_MOVELEFT, "moveleft" },
|
||||
{ 0x088c8, ACTION_MOVEDOWN, "movedown" },
|
||||
{ 0x11268, ACTION_MOVERIGHT, "moveright" },
|
||||
{ 0x2314d, ACTION_SHOWSCORES, "showscores" }
|
||||
{ 0x0f26fef6, &Button_Speed, "speed" },
|
||||
{ 0x1ccf57bf, &Button_MoveUp, "moveup" },
|
||||
{ 0x22beba5f, &Button_Klook, "klook" },
|
||||
{ 0x47c02d3b, &Button_Attack, "attack" },
|
||||
{ 0x6dcec137, &Button_Back, "back" },
|
||||
{ 0x7a67e768, &Button_Left, "left" },
|
||||
{ 0x84b8789a, &Button_MoveLeft, "moveleft" },
|
||||
{ 0x8fd9bf1e, &Button_ShowScores, "showscores" },
|
||||
{ 0x94b1cc4b, &Button_Use, "use" },
|
||||
{ 0xa7b30616, &Button_Jump, "jump" },
|
||||
{ 0xadfe4fff, &Button_Mlook, "mlook" },
|
||||
{ 0xb4ca7514, &Button_Right, "right" },
|
||||
{ 0xb563e265, &Button_LookDown, "lookdown" },
|
||||
{ 0xb67a0835, &Button_Strafe, "strafe" },
|
||||
{ 0xe2200fc9, &Button_MoveDown, "movedown" },
|
||||
{ 0xe78739bb, &Button_MoveRight, "moveright" },
|
||||
{ 0xe7912f86, &Button_Forward, "forward" },
|
||||
{ 0xf01cb105, &Button_LookUp, "lookup" },
|
||||
};
|
||||
byte Actions[NUM_ACTIONS];
|
||||
|
||||
#define NUM_ACTIONS (sizeof(ActionMaps)/sizeof(FActionMap))
|
||||
|
||||
IMPLEMENT_CLASS (DWaitingCommand)
|
||||
|
||||
|
@ -119,195 +142,294 @@ IMPLEMENT_CLASS (DStoredCommand)
|
|||
|
||||
DStoredCommand::DStoredCommand ()
|
||||
{
|
||||
Text = NULL;
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
DStoredCommand::DStoredCommand (int argc, char **argv, const char *args)
|
||||
DStoredCommand::DStoredCommand (FConsoleCommand *command, const char *args)
|
||||
{
|
||||
ArgC = argc;
|
||||
if (argc != 0)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
|
||||
for (i = len = 0; i < argc; i++)
|
||||
{
|
||||
len += strlen (argv[i]) + 1;
|
||||
}
|
||||
ArgV = new char *[argc];
|
||||
ArgV[0] = new char[len];
|
||||
ArgV[0][0] = 0;
|
||||
for (i = len = 0; i < argc; i++)
|
||||
{
|
||||
ArgV[i] = ArgV[0] + len;
|
||||
strcpy (ArgV[0] + len, argv[i]);
|
||||
len += strlen (argv[i]) + 1;
|
||||
}
|
||||
ArgS = new char[strlen (args) + 1];
|
||||
strcpy (ArgS, args);
|
||||
}
|
||||
Command = command;
|
||||
Text = copystring (args);
|
||||
}
|
||||
|
||||
DStoredCommand::~DStoredCommand ()
|
||||
{
|
||||
if (ArgC != 0)
|
||||
if (Text != NULL)
|
||||
{
|
||||
delete[] ArgV[0];
|
||||
delete[] ArgV;
|
||||
delete[] ArgS;
|
||||
delete[] Text;
|
||||
}
|
||||
}
|
||||
|
||||
void DStoredCommand::RunThink ()
|
||||
{
|
||||
if (ArgC != 0)
|
||||
if (Text != NULL && Command != NULL)
|
||||
{
|
||||
FConsoleCommand *com = FindNameInHashTable (Commands, ArgV[0]);
|
||||
if (com != NULL)
|
||||
{
|
||||
com->Run (ArgC, ArgV, ArgS, players[consoleplayer].mo);
|
||||
}
|
||||
FCommandLine args (Text);
|
||||
Command->Run (args, players[consoleplayer].mo, 0);
|
||||
}
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
static int ListActionCommands (void)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_ACTIONS; i++)
|
||||
for (i = 0; i < NUM_ACTIONS; ++i)
|
||||
{
|
||||
Printf ("+%s\n", actionbits[i].name);
|
||||
Printf ("-%s\n", actionbits[i].name);
|
||||
Printf ("+%s\n", ActionMaps[i].Name);
|
||||
Printf ("-%s\n", ActionMaps[i].Name);
|
||||
}
|
||||
return NUM_ACTIONS * 2;
|
||||
}
|
||||
|
||||
unsigned int MakeKey (const char *s)
|
||||
{
|
||||
register unsigned int v = 0;
|
||||
DWORD key = 0xffffffff;
|
||||
const DWORD *table = GetCRCTable ();
|
||||
|
||||
if (*s)
|
||||
v = tolower(*s++);
|
||||
if (*s)
|
||||
v = (v*3) + tolower(*s++);
|
||||
while (*s)
|
||||
v = (v << 1) + tolower(*s++);
|
||||
|
||||
return v;
|
||||
{
|
||||
key = CRC1 (key, tolower (*s++), table);
|
||||
}
|
||||
return key ^ 0xffffffff;
|
||||
}
|
||||
|
||||
// GetActionBit scans through the actionbits[] array
|
||||
unsigned int MakeKey (const char *s, int len)
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
DWORD key = 0xffffffff;
|
||||
const DWORD *table = GetCRCTable ();
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
key = CRC1 (key, tolower(*s++), table);
|
||||
--len;
|
||||
}
|
||||
return key ^ 0xffffffff;
|
||||
}
|
||||
|
||||
// FindButton scans through the actionbits[] array
|
||||
// for a matching key and returns an index or -1 if
|
||||
// the key could not be found. This uses binary search,
|
||||
// so actionbits[] must be sorted in ascending order.
|
||||
|
||||
int GetActionBit (unsigned int key)
|
||||
FButtonStatus *FindButton (unsigned int key)
|
||||
{
|
||||
const ActionBits *bit;
|
||||
const FActionMap *bit;
|
||||
|
||||
bit = BinarySearch (actionbits, NUM_ACTIONS, &ActionBits::key, key);
|
||||
return bit ? bit->index : -1;
|
||||
bit = BinarySearch<FActionMap, unsigned int>
|
||||
(ActionMaps, NUM_ACTIONS, &FActionMap::Key, key);
|
||||
return bit ? bit->Button : NULL;
|
||||
}
|
||||
|
||||
void C_DoCommand (char *cmd)
|
||||
void FButtonStatus::PressKey (int keynum)
|
||||
{
|
||||
int argc;
|
||||
long argsize;
|
||||
char **argv;
|
||||
FConsoleCommand *com;
|
||||
int i, open;
|
||||
|
||||
keynum &= KEY_DBLCLICKED-1;
|
||||
|
||||
if (keynum == 0)
|
||||
{ // Issued from console instead of a key, so force on
|
||||
Keys[0] = 0xffff;
|
||||
for (i = MAX_KEYS-1; i > 0; --i)
|
||||
{
|
||||
Keys[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = MAX_KEYS-1, open = -1; i >= 0; --i)
|
||||
{
|
||||
if (Keys[i] == 0)
|
||||
{
|
||||
open = i;
|
||||
}
|
||||
else if (Keys[i] == keynum)
|
||||
{ // Key is already down; do nothing
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (open < 0)
|
||||
{ // No free key slots, so do nothing
|
||||
Printf ("More than %u keys pressed for a single action!\n", MAX_KEYS);
|
||||
return;
|
||||
}
|
||||
Keys[open] = keynum;
|
||||
}
|
||||
bDown = bWentDown = true;
|
||||
}
|
||||
|
||||
void FButtonStatus::ReleaseKey (int keynum)
|
||||
{
|
||||
int i, numdown, match;
|
||||
|
||||
keynum &= KEY_DBLCLICKED-1;
|
||||
|
||||
if (keynum == 0)
|
||||
{ // Issued from console instead of a key, so force off
|
||||
for (i = MAX_KEYS-1; i >= 0; --i)
|
||||
{
|
||||
Keys[i] = 0;
|
||||
}
|
||||
bWentUp = true;
|
||||
bDown = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = MAX_KEYS-1, numdown = 0, match = -1; i >= 0; --i)
|
||||
{
|
||||
if (Keys[i] != 0)
|
||||
{
|
||||
++numdown;
|
||||
if (Keys[i] == keynum)
|
||||
{
|
||||
match = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match < 0)
|
||||
{ // Key was not down; do nothing
|
||||
return;
|
||||
}
|
||||
Keys[match] = 0;
|
||||
bWentUp = true;
|
||||
if (--numdown == 0)
|
||||
{
|
||||
bDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResetButtonTriggers ()
|
||||
{
|
||||
for (int i = NUM_ACTIONS-1; i >= 0; --i)
|
||||
{
|
||||
ActionMaps[i].Button->ResetTriggers ();
|
||||
}
|
||||
}
|
||||
|
||||
void ResetButtonStates ()
|
||||
{
|
||||
for (int i = NUM_ACTIONS-1; i >= 0; --i)
|
||||
{
|
||||
FButtonStatus *button = ActionMaps[i].Button;
|
||||
|
||||
if (button != &Button_Mlook && button != &Button_Klook)
|
||||
{
|
||||
button->ReleaseKey (0);
|
||||
}
|
||||
button->ResetTriggers ();
|
||||
}
|
||||
}
|
||||
|
||||
void C_DoCommand (const char *cmd, int keynum)
|
||||
{
|
||||
FConsoleCommand *com;
|
||||
const char *end;
|
||||
const char *beg;
|
||||
|
||||
// Skip any beginning whitespace
|
||||
while (*cmd && *cmd <= ' ')
|
||||
cmd++;
|
||||
|
||||
// Check if this is an action
|
||||
if (*cmd == '+' || *cmd == '-')
|
||||
// Find end of the command name
|
||||
if (*cmd == '\"')
|
||||
{
|
||||
int action;
|
||||
char *end = cmd+1;
|
||||
char brk;
|
||||
for (end = beg = cmd+1; *end && *end != '\"'; ++end)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
beg = cmd;
|
||||
for (end = cmd+1; *end > ' '; ++end)
|
||||
;
|
||||
}
|
||||
|
||||
while (*end && *end > ' ')
|
||||
end++;
|
||||
brk = *end;
|
||||
*end = 0;
|
||||
action = GetActionBit (MakeKey (cmd + 1));
|
||||
*end = brk;
|
||||
if (action >= 0)
|
||||
// Check if this is an action
|
||||
if (*beg == '+' || *beg == '-')
|
||||
{
|
||||
FButtonStatus *button;
|
||||
|
||||
button = FindButton (MakeKey (beg + 1, end - beg - 1));
|
||||
if (button != NULL)
|
||||
{
|
||||
if (*cmd == '+')
|
||||
if (*beg == '+')
|
||||
{
|
||||
//if (Actions[check] < 255)
|
||||
// Actions[check]++;
|
||||
Actions[action] = 1;
|
||||
button->PressKey (keynum);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (Actions[check])
|
||||
// Actions[check]--;
|
||||
Actions[action] = 0;
|
||||
if (action == ACTION_MLOOK && *lookspring)
|
||||
button->ReleaseKey (keynum);
|
||||
if (button == &Button_Mlook && lookspring)
|
||||
{
|
||||
AddCommandString ("centerview");
|
||||
C_DoCommand ("centerview");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse it as a normal command
|
||||
argsize = ParseCommandLine (cmd, &argc, NULL);
|
||||
argv = (char **)Malloc (argc*sizeof(char *) + argsize);
|
||||
argv[0] = (char *)argv + argc*sizeof(char *);
|
||||
ParseCommandLine (cmd, NULL, argv);
|
||||
const int len = end - beg;
|
||||
|
||||
// Parse it as a normal command
|
||||
// Checking for matching commands follows this search order:
|
||||
// 1. Check the Commands[] hash table
|
||||
// 2. Check the CVars list
|
||||
|
||||
if ( (com = FindNameInHashTable (Commands, argv[0])) )
|
||||
if ( (com = FindNameInHashTable (Commands, beg, len)) )
|
||||
{
|
||||
if (gamestate != GS_STARTUP ||
|
||||
stricmp (argv[0], "set") == 0 ||
|
||||
stricmp (argv[0], "logfile") == 0 ||
|
||||
stricmp (argv[0], "unbindall") == 0 ||
|
||||
stricmp (argv[0], "exec") == 0)
|
||||
(len == 3 && strnicmp (beg, "set", 3) == 0) ||
|
||||
(len == 7 && strnicmp (beg, "logfile", 7) == 0) ||
|
||||
(len == 9 && strnicmp (beg, "unbindall", 9) == 0) ||
|
||||
(len == 4 && strnicmp (beg, "bind", 4) == 0) ||
|
||||
(len == 4 && strnicmp (beg, "exec", 4) == 0) ||
|
||||
(len ==10 && strnicmp (beg, "doublebind", 10) == 0)
|
||||
)
|
||||
{
|
||||
com->Run (argc, argv, cmd, players[consoleplayer].mo);
|
||||
FCommandLine args (beg);
|
||||
com->Run (args, players[consoleplayer].mo, keynum);
|
||||
}
|
||||
else
|
||||
{
|
||||
new DStoredCommand (argc, argv, cmd);
|
||||
new DStoredCommand (com, beg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for any console vars that match the command
|
||||
FBaseCVar *var;
|
||||
{ // Check for any console vars that match the command
|
||||
FBaseCVar *var = FindCVarSub (beg, len);
|
||||
|
||||
if ( (var = FindCVar (argv[0], NULL)) )
|
||||
if (var != NULL)
|
||||
{
|
||||
if (argc >= 2)
|
||||
{ // Hack
|
||||
com = FindNameInHashTable (Commands, "set");
|
||||
com->Run (argc + 1, argv - 1, cmd, players[consoleplayer].mo);
|
||||
FCommandLine args (beg);
|
||||
|
||||
if (args.argc() >= 2)
|
||||
{ // Set the variable
|
||||
var->CmdSet (args.AllButFirstArg (1));
|
||||
}
|
||||
else
|
||||
{
|
||||
{ // Get the variable's value
|
||||
UCVarValue val = var->GetGenericRep (CVAR_String);
|
||||
Printf ("\"%s\" is \"%s\"\n", var->GetName(), val.String);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't know how to handle this command
|
||||
Printf ("Unknown command \"%s\"\n", argv[0]);
|
||||
{ // We don't know how to handle this command
|
||||
char cmdname[64];
|
||||
int minlen = MIN (len, 63);
|
||||
|
||||
memcpy (cmdname, beg, minlen);
|
||||
cmdname[len] = 0;
|
||||
Printf ("Unknown command \"%s\"\n", cmdname);
|
||||
}
|
||||
}
|
||||
free (argv);
|
||||
}
|
||||
|
||||
void AddCommandString (char *cmd)
|
||||
void AddCommandString (char *cmd, int keynum)
|
||||
{
|
||||
char *brkpt;
|
||||
int more;
|
||||
|
@ -336,12 +458,13 @@ void AddCommandString (char *cmd)
|
|||
{
|
||||
more = 0;
|
||||
}
|
||||
// Intercept wait commands here
|
||||
// Intercept wait commands here. Note: wait must be lowercase
|
||||
while (*cmd && *cmd <= ' ')
|
||||
cmd++;
|
||||
if (*cmd)
|
||||
{
|
||||
if (strnicmp (cmd, "wait", 4) == 0 && (cmd[4] == 0 || cmd[4] == ' '))
|
||||
if (cmd[0] == 'w' && cmd[1] == 'a' && cmd[2] == 'i' && cmd[3] == 't' &&
|
||||
(cmd[4] == 0 || cmd[4] == ' '))
|
||||
{
|
||||
int tics;
|
||||
|
||||
|
@ -357,6 +480,8 @@ void AddCommandString (char *cmd)
|
|||
{
|
||||
if (more)
|
||||
{ // The remainder of the command will be executed later
|
||||
// Note that deferred commands lose track of which key
|
||||
// (if any) they were pressed from.
|
||||
*brkpt = ';';
|
||||
new DWaitingCommand (brkpt + 1, tics);
|
||||
}
|
||||
|
@ -365,7 +490,7 @@ void AddCommandString (char *cmd)
|
|||
}
|
||||
else
|
||||
{
|
||||
C_DoCommand (cmd);
|
||||
C_DoCommand (cmd, keynum);
|
||||
}
|
||||
}
|
||||
if (more)
|
||||
|
@ -476,17 +601,86 @@ static long ParseCommandLine (const char *args, int *argc, char **argv)
|
|||
return (long)buffplace;
|
||||
}
|
||||
|
||||
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, FConsoleCommand **prev)
|
||||
FCommandLine::FCommandLine (const char *commandline)
|
||||
{
|
||||
cmd = commandline;
|
||||
_argc = -1;
|
||||
_argv = NULL;
|
||||
}
|
||||
|
||||
FCommandLine::~FCommandLine ()
|
||||
{
|
||||
if (_argv != NULL)
|
||||
{
|
||||
Z_Free (_argv);
|
||||
}
|
||||
}
|
||||
|
||||
int FCommandLine::argc ()
|
||||
{
|
||||
if (_argc == -1)
|
||||
{
|
||||
argsize = ParseCommandLine (cmd, &_argc, NULL);
|
||||
}
|
||||
return _argc;
|
||||
}
|
||||
|
||||
char *FCommandLine::operator[] (int i)
|
||||
{
|
||||
if (_argv == NULL)
|
||||
{
|
||||
int count = argc();
|
||||
_argv = (char **)Z_Malloc (count*sizeof(char *) + argsize, PU_STATIC, 0);
|
||||
_argv[0] = (char *)_argv + count*sizeof(char *);
|
||||
ParseCommandLine (cmd, NULL, _argv);
|
||||
}
|
||||
return _argv[i];
|
||||
}
|
||||
|
||||
const char *FCommandLine::AllButFirstArg (int numToSkip)
|
||||
{
|
||||
const char *start = cmd;
|
||||
|
||||
if (argc() != numToSkip + 1)
|
||||
{
|
||||
while (--numToSkip >= 0 && *start)
|
||||
{
|
||||
// Skip non-white space (the arg itself)
|
||||
while (*start > ' ')
|
||||
{
|
||||
if (*start == '\"')
|
||||
{ // skip to end of quoted string
|
||||
while (*start && *start != '\"')
|
||||
++start;
|
||||
if (*start == 0)
|
||||
return start;
|
||||
}
|
||||
++start;
|
||||
}
|
||||
|
||||
// Skip white space after arg
|
||||
while (*start && *start <= ' ')
|
||||
++start;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
else
|
||||
{
|
||||
return operator[] (numToSkip);
|
||||
}
|
||||
}
|
||||
|
||||
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, int namelen, FConsoleCommand **prev)
|
||||
{
|
||||
int comp;
|
||||
|
||||
*prev = NULL;
|
||||
while (start)
|
||||
{
|
||||
comp = stricmp (start->m_Name, name);
|
||||
comp = strnicmp (start->m_Name, name, namelen);
|
||||
if (comp > 0)
|
||||
return NULL;
|
||||
else if (comp == 0)
|
||||
else if (comp == 0 && start->m_Name[namelen] == 0)
|
||||
return start;
|
||||
|
||||
*prev = start;
|
||||
|
@ -495,11 +689,11 @@ static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *na
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name)
|
||||
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name, int namelen)
|
||||
{
|
||||
FConsoleCommand *dummy;
|
||||
|
||||
return ScanChainForName (table[MakeKey (name) % HASH_SIZE], name, &dummy);
|
||||
return ScanChainForName (table[MakeKey (name, namelen) % HASH_SIZE], name, namelen, &dummy);
|
||||
}
|
||||
|
||||
bool FConsoleCommand::AddToHash (FConsoleCommand **table)
|
||||
|
@ -513,7 +707,7 @@ bool FConsoleCommand::AddToHash (FConsoleCommand **table)
|
|||
key = MakeKey (m_Name);
|
||||
bucket = &table[key % HASH_SIZE];
|
||||
|
||||
if (ScanChainForName (*bucket, m_Name, &insert))
|
||||
if (ScanChainForName (*bucket, m_Name, strlen (m_Name), &insert))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -547,14 +741,14 @@ FConsoleCommand::FConsoleCommand (const char *name, CCmdRun runFunc)
|
|||
if (firstTime)
|
||||
{
|
||||
char tname[16];
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
firstTime = false;
|
||||
|
||||
// Add all the action commands for tab completion
|
||||
for (i = 0; i < NUM_ACTIONS; i++)
|
||||
{
|
||||
strcpy (&tname[1], actionbits[i].name);
|
||||
strcpy (&tname[1], ActionMaps[i].Name);
|
||||
tname[0] = '+';
|
||||
C_AddTabCommand (tname);
|
||||
tname[0] = '-';
|
||||
|
@ -582,9 +776,9 @@ FConsoleCommand::~FConsoleCommand ()
|
|||
delete[] m_Name;
|
||||
}
|
||||
|
||||
void FConsoleCommand::Run (int argc, char **argv, const char *args, AActor *instigator)
|
||||
void FConsoleCommand::Run (FCommandLine &argv, AActor *instigator, int key)
|
||||
{
|
||||
m_RunFunc (argc, argv, args, instigator);
|
||||
m_RunFunc (argv, instigator, key);
|
||||
}
|
||||
|
||||
FConsoleAlias::FConsoleAlias (const char *name, const char *command)
|
||||
|
@ -682,7 +876,7 @@ void C_SetAlias (const char *name, const char *cmd)
|
|||
FConsoleCommand *prev, *alias, **chain;
|
||||
|
||||
chain = &Commands[MakeKey (name) % HASH_SIZE];
|
||||
alias = ScanChainForName (*chain, name, &prev);
|
||||
alias = ScanChainForName (*chain, name, strlen (name), &prev);
|
||||
if (alias != NULL)
|
||||
{
|
||||
delete alias;
|
||||
|
@ -694,7 +888,7 @@ CCMD (alias)
|
|||
{
|
||||
FConsoleCommand *prev, *alias, **chain;
|
||||
|
||||
if (argc == 1)
|
||||
if (argv.argc() == 1)
|
||||
{
|
||||
Printf ("Current alias commands:\n");
|
||||
DumpHash (Commands, true);
|
||||
|
@ -703,25 +897,23 @@ CCMD (alias)
|
|||
{
|
||||
chain = &Commands[MakeKey (argv[1]) % HASH_SIZE];
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
// Remove the alias
|
||||
if (argv.argc() == 2)
|
||||
{ // Remove the alias
|
||||
|
||||
if ( (alias = ScanChainForName (*chain, argv[1], &prev)) )
|
||||
if ( (alias = ScanChainForName (*chain, argv[1], strlen (argv[1]), &prev)) )
|
||||
{
|
||||
delete alias;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add/Change the alias
|
||||
{ // Add/change the alias
|
||||
|
||||
alias = ScanChainForName (*chain, argv[1], &prev);
|
||||
alias = ScanChainForName (*chain, argv[1], strlen (argv[1]), &prev);
|
||||
if (alias)
|
||||
delete alias;
|
||||
|
||||
if (argc > 3)
|
||||
new FConsoleAlias (argv[1], BuildString (argc - 2, &argv[2]));
|
||||
if (argv.argc() > 3)
|
||||
new FConsoleAlias (argv[1], copystring (argv.AllButFirstArg(2)));
|
||||
else
|
||||
new FConsoleAlias (argv[1], copystring (argv[2]));
|
||||
}
|
||||
|
@ -739,15 +931,15 @@ CCMD (cmdlist)
|
|||
|
||||
CCMD (key)
|
||||
{
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
while (argc > 1)
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argv.argc(); ++i)
|
||||
{
|
||||
Printf (" %08x", MakeKey (argv[1]));
|
||||
argc--;
|
||||
argv++;
|
||||
unsigned int key = MakeKey (argv[i]);
|
||||
Printf (" 0x%08x\n", key, key);
|
||||
}
|
||||
Printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -792,7 +984,7 @@ bool FConsoleAlias::IsAlias ()
|
|||
return true;
|
||||
}
|
||||
|
||||
void FConsoleAlias::Run (int argc, char **argv, const char *args, AActor *m_Instigator)
|
||||
void FConsoleAlias::Run (FCommandLine &args, AActor *m_Instigator, int key)
|
||||
{
|
||||
AddCommandString (m_Command);
|
||||
AddCommandString (m_Command, key);
|
||||
}
|
117
src/c_dispatch.h
Normal file
117
src/c_dispatch.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
#ifndef __C_DISPATCH_H__
|
||||
#define __C_DISPATCH_H__
|
||||
|
||||
#include "dobject.h"
|
||||
|
||||
class FConfigFile;
|
||||
|
||||
#define HASH_SIZE 251 // I think this is prime
|
||||
|
||||
void C_ExecCmdLineParams ();
|
||||
|
||||
// Add commands to the console as if they were typed in. Can handle wait
|
||||
// and semicolon-separated commands. This function may modify the source
|
||||
// string, but the string will be restored to its original state before
|
||||
// returning. Therefore, commands passed must not be in read-only memory.
|
||||
void AddCommandString (char *text, int keynum=0);
|
||||
|
||||
// Process a single console command. Does not handle wait.
|
||||
void C_DoCommand (const char *cmd, int keynum=0);
|
||||
|
||||
// Write out alias commands to a file for all current aliases.
|
||||
void C_ArchiveAliases (FConfigFile *f);
|
||||
|
||||
void C_SetAlias (const char *name, const char *cmd);
|
||||
|
||||
// build a single string out of multiple strings
|
||||
char *BuildString (int argc, char **argv);
|
||||
|
||||
// Class that can parse command lines
|
||||
class FCommandLine
|
||||
{
|
||||
public:
|
||||
FCommandLine (const char *commandline);
|
||||
~FCommandLine ();
|
||||
int argc ();
|
||||
char *operator[] (int i);
|
||||
const char *args () { return cmd; }
|
||||
const char *AllButFirstArg (int numToSkip=1); // like args(), but can skip first n args
|
||||
|
||||
private:
|
||||
const char *cmd;
|
||||
int _argc;
|
||||
char **_argv;
|
||||
long argsize;
|
||||
};
|
||||
|
||||
typedef void (*CCmdRun) (FCommandLine &argv, AActor *instigator, int key);
|
||||
|
||||
class FConsoleCommand
|
||||
{
|
||||
public:
|
||||
FConsoleCommand (const char *name, CCmdRun RunFunc);
|
||||
virtual ~FConsoleCommand ();
|
||||
virtual bool IsAlias ();
|
||||
void PrintCommand () { Printf ("%s\n", m_Name); }
|
||||
|
||||
virtual void Run (FCommandLine &args, AActor *instigator, int key);
|
||||
|
||||
FConsoleCommand *m_Next, **m_Prev;
|
||||
char *m_Name;
|
||||
|
||||
protected:
|
||||
FConsoleCommand ();
|
||||
bool AddToHash (FConsoleCommand **table);
|
||||
|
||||
CCmdRun m_RunFunc;
|
||||
|
||||
};
|
||||
|
||||
#define CCMD(n) \
|
||||
void Cmd_##n (FCommandLine &, AActor *, int key); \
|
||||
FConsoleCommand Cmd_##n##_ (#n, Cmd_##n); \
|
||||
void Cmd_##n (FCommandLine &argv, AActor *m_Instigator, int key)
|
||||
|
||||
const int KEY_DBLCLICKED = 0x8000;
|
||||
|
||||
class FConsoleAlias : public FConsoleCommand
|
||||
{
|
||||
public:
|
||||
FConsoleAlias (const char *name, const char *command);
|
||||
~FConsoleAlias ();
|
||||
void Run (FCommandLine &args, AActor *Instigator, int key);
|
||||
bool IsAlias ();
|
||||
void PrintAlias () { Printf ("%s : %s\n", m_Name, m_Command); }
|
||||
void Archive (FConfigFile *f);
|
||||
protected:
|
||||
char *m_Command;
|
||||
};
|
||||
|
||||
// Actions
|
||||
struct FButtonStatus
|
||||
{
|
||||
enum { MAX_KEYS = 6 }; // Maximum number of keys that can press this button
|
||||
|
||||
WORD Keys[MAX_KEYS];
|
||||
BYTE bDown; // Button is down right now
|
||||
BYTE bWentDown; // Button went down this tic
|
||||
BYTE bWentUp; // Button went up this tic
|
||||
BYTE padTo16Bytes;
|
||||
|
||||
void PressKey (int keynum);
|
||||
void ReleaseKey (int keynum);
|
||||
void ResetTriggers () { bWentDown = bWentUp = false; }
|
||||
};
|
||||
|
||||
extern FButtonStatus Button_Mlook, Button_Klook, Button_Use,
|
||||
Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft,
|
||||
Button_Strafe, Button_LookDown, Button_LookUp, Button_Back,
|
||||
Button_Forward, Button_Right, Button_Left, Button_MoveDown,
|
||||
Button_MoveUp, Button_Jump, Button_ShowScores;
|
||||
|
||||
void ResetButtonTriggers (); // Call ResetTriggers for all buttons
|
||||
void ResetButtonStates (); // Same as above, but also clear bDown
|
||||
|
||||
extern unsigned int MakeKey (const char *s);
|
||||
|
||||
#endif //__C_DISPATCH_H__
|
|
@ -60,7 +60,7 @@ void FColorMatcher::SetPalette (const DWORD *palette)
|
|||
|
||||
#ifdef BEFAST
|
||||
Seed seeds[255];
|
||||
byte seedspread[HISIZE+1][HISIZE+1][HISIZE+1];
|
||||
byte seedspread[CHISIZE+1][CHISIZE+1][CHISIZE+1];
|
||||
int numseeds;
|
||||
int i, radius;
|
||||
|
||||
|
@ -70,9 +70,9 @@ void FColorMatcher::SetPalette (const DWORD *palette)
|
|||
// Plant each color from the palette as seeds in the color cube
|
||||
for (i = 1; i < 256; i++)
|
||||
{
|
||||
int r = (Pal[i].r + LOSIZE/2) >> LOBITS;
|
||||
int g = (Pal[i].g + LOSIZE/2) >> LOBITS;
|
||||
int b = (Pal[i].b + LOSIZE/2) >> LOBITS;
|
||||
int r = (Pal[i].r + CLOSIZE/2) >> CLOBITS;
|
||||
int g = (Pal[i].g + CLOSIZE/2) >> CLOBITS;
|
||||
int b = (Pal[i].b + CLOSIZE/2) >> CLOBITS;
|
||||
|
||||
if (FirstColor[r][g][b] == 0)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ void FColorMatcher::SetPalette (const DWORD *palette)
|
|||
|
||||
// Grow each seed outward as a cube until no seed can
|
||||
// grow any further.
|
||||
for (radius = 1; radius < HISIZE; radius++)
|
||||
for (radius = 1; radius < CHISIZE; radius++)
|
||||
{
|
||||
int seedsused = 0;
|
||||
for (i = numseeds - 1; i >= 0; i--)
|
||||
|
@ -120,11 +120,11 @@ void FColorMatcher::SetPalette (const DWORD *palette)
|
|||
// Check to see which planes are acceptable
|
||||
byte bad = 0;
|
||||
if (r1 < 0) bad |= 1, r1 = 0;
|
||||
if (r2 > HISIZE) bad |= 2, r2 = HISIZE;
|
||||
if (r2 > CHISIZE) bad |= 2, r2 = CHISIZE;
|
||||
if (g1 < 0) bad |= 4, g1 = 0;
|
||||
if (g2 > HISIZE) bad |= 8, g2 = HISIZE;
|
||||
if (g2 > CHISIZE) bad |= 8, g2 = CHISIZE;
|
||||
if (b1 < 0) bad |= 16, b1 = 0;
|
||||
if (b2 > HISIZE) bad |= 32, b2 = HISIZE;
|
||||
if (b2 > CHISIZE) bad |= 32, b2 = CHISIZE;
|
||||
|
||||
bad |= seeds[i].bad;
|
||||
|
||||
|
@ -187,7 +187,7 @@ void FColorMatcher::SetPalette (const DWORD *palette)
|
|||
}
|
||||
|
||||
int FColorMatcher::FillPlane (int r1, int r2, int g1, int g2, int b1, int b2,
|
||||
byte seedspread[HISIZE+1][HISIZE+1][HISIZE+1],
|
||||
byte seedspread[CHISIZE+1][CHISIZE+1][CHISIZE+1],
|
||||
Seed *seeds, int thisseed)
|
||||
{
|
||||
const Seed *secnd = seeds + thisseed;
|
||||
|
@ -239,7 +239,7 @@ byte FColorMatcher::Pick (int r, int g, int b)
|
|||
byte bestcolor;
|
||||
int bestdist;
|
||||
|
||||
byte color = FirstColor[(r+LOSIZE/2)>>LOBITS][(g+LOSIZE/2)>>LOBITS][(b+LOSIZE/2)>>LOBITS];
|
||||
byte color = FirstColor[(r+CLOSIZE/2)>>CLOBITS][(g+CLOSIZE/2)>>CLOBITS][(b+CLOSIZE/2)>>CLOBITS];
|
||||
if (NextColor[color] == 0)
|
||||
return color;
|
||||
|
|
@ -31,17 +31,17 @@ public:
|
|||
FColorMatcher &operator= (const FColorMatcher &other);
|
||||
|
||||
private:
|
||||
enum { HIBITS=4, LOBITS=8-HIBITS, HISIZE=1<<HIBITS, LOSIZE=1<<LOBITS};
|
||||
enum { CHIBITS=4, CLOBITS=8-CHIBITS, CHISIZE=1<<CHIBITS, CLOSIZE=1<<CLOBITS};
|
||||
struct Seed;
|
||||
struct PalEntry;
|
||||
|
||||
const PalEntry *Pal;
|
||||
byte FirstColor[HISIZE+1][HISIZE+1][HISIZE+1];
|
||||
byte FirstColor[CHISIZE+1][CHISIZE+1][CHISIZE+1];
|
||||
byte NextColor[256];
|
||||
|
||||
int FillPlane (int r1, int r2, int g1, int g2, int b1, int b2,
|
||||
byte seedspread[HISIZE+1][HISIZE+1][HISIZE+1],
|
||||
byte seedspread[CHISIZE+1][CHISIZE+1][CHISIZE+1],
|
||||
Seed *seeds, int thisseed);
|
||||
};
|
||||
|
||||
#endif //__COLORMATCHER_H__
|
||||
#endif //__COLORMATCHER_H__
|
|
@ -65,4 +65,4 @@ private:
|
|||
FConfigEntry *NewConfigEntry (FConfigSection *section, const char *key, const char *value);
|
||||
};
|
||||
|
||||
#endif //__CONFIGFILE_H__
|
||||
#endif //__CONFIGFILE_H__
|
|
@ -114,53 +114,58 @@ void CT_Stop ()
|
|||
|
||||
BOOL CT_Responder (event_t *ev)
|
||||
{
|
||||
if (chatmodeon && ev->type == EV_GUI_Event &&
|
||||
(ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat))
|
||||
if (chatmodeon && ev->type == EV_GUI_Event)
|
||||
{
|
||||
// send a macro
|
||||
if ((ev->data3 & GKM_ALT) && (ev->data1 >= '0' && ev->data1 <= '9'))
|
||||
if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat)
|
||||
{
|
||||
ShoveChatStr (**chat_macros[ev->data1 - '0'], chatmodeon - 1);
|
||||
CT_Stop ();
|
||||
return true;
|
||||
}
|
||||
if (ev->data1 == '\r')
|
||||
{
|
||||
ShoveChatStr ((char *)ChatQueue, chatmodeon - 1);
|
||||
CT_Stop ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == GK_ESCAPE)
|
||||
{
|
||||
CT_Stop ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == '\b')
|
||||
{
|
||||
CT_BackSpace ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
||||
{
|
||||
I_PutInClipboard ((char *)ChatQueue);
|
||||
}
|
||||
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
|
||||
{
|
||||
char *clip = I_GetFromClipboard ();
|
||||
if (clip != NULL)
|
||||
if (ev->data1 == '\r')
|
||||
{
|
||||
char *clip_p = clip;
|
||||
strtok (clip, "\n\r\b");
|
||||
while (*clip_p)
|
||||
ShoveChatStr ((char *)ChatQueue, chatmodeon - 1);
|
||||
CT_Stop ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == GK_ESCAPE)
|
||||
{
|
||||
CT_Stop ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == '\b')
|
||||
{
|
||||
CT_BackSpace ();
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
||||
{
|
||||
I_PutInClipboard ((char *)ChatQueue);
|
||||
return true;
|
||||
}
|
||||
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
|
||||
{
|
||||
char *clip = I_GetFromClipboard ();
|
||||
if (clip != NULL)
|
||||
{
|
||||
CT_AddChar (*clip_p++);
|
||||
char *clip_p = clip;
|
||||
strtok (clip, "\n\r\b");
|
||||
while (*clip_p)
|
||||
{
|
||||
CT_AddChar (*clip_p++);
|
||||
}
|
||||
delete[] clip;
|
||||
}
|
||||
delete[] clip;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (ev->subtype == EV_GUI_Char)
|
||||
{
|
||||
CT_AddChar (ev->data2);
|
||||
// send a macro
|
||||
if (ev->data2 && (ev->data1 >= '0' && ev->data1 <= '9'))
|
||||
{
|
||||
ShoveChatStr (*chat_macros[ev->data1 - '0'], chatmodeon - 1);
|
||||
CT_Stop ();
|
||||
}
|
||||
else
|
||||
{
|
||||
CT_AddChar (ev->data1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +186,7 @@ void CT_Drawer (void)
|
|||
static const char *prompt = "Say: ";
|
||||
int i, x, scalex, y, promptwidth;
|
||||
|
||||
if (*con_scaletext)
|
||||
if (con_scaletext)
|
||||
{
|
||||
scalex = CleanXfac;
|
||||
y = (!viewactive ? -30 : -10) * CleanYfac;
|
||||
|
@ -216,7 +221,7 @@ void CT_Drawer (void)
|
|||
// draw the prompt, text, and cursor
|
||||
ChatQueue[len] = gameinfo.gametype == GAME_Doom ? '_' : '[';
|
||||
ChatQueue[len+1] = '\0';
|
||||
if (*con_scaletext)
|
||||
if (con_scaletext)
|
||||
{
|
||||
screen->DrawTextClean (CR_GREEN, 0, y, prompt);
|
||||
screen->DrawTextClean (CR_GREY, promptwidth, y, ChatQueue + i);
|
||||
|
@ -231,8 +236,8 @@ void CT_Drawer (void)
|
|||
BorderTopRefresh = screen->GetPageCount ();
|
||||
}
|
||||
|
||||
if (*deathmatch &&
|
||||
((Actions[ACTION_SHOWSCORES]) ||
|
||||
if (deathmatch &&
|
||||
(Button_ShowScores.bDown ||
|
||||
players[consoleplayer].camera->health <= 0))
|
||||
{
|
||||
HU_DrawScores (&players[consoleplayer]);
|
||||
|
@ -301,12 +306,7 @@ CCMD (messagemode)
|
|||
|
||||
CCMD (say)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
char *chat = BuildString (argc - 1, argv + 1);
|
||||
ShoveChatStr (chat, 0);
|
||||
delete[] chat;
|
||||
}
|
||||
ShoveChatStr (argv.AllButFirstArg(), 0);
|
||||
}
|
||||
|
||||
CCMD (messagemode2)
|
||||
|
@ -321,12 +321,7 @@ CCMD (messagemode2)
|
|||
|
||||
CCMD (say_team)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
char *chat = BuildString (argc - 1, argv + 1);
|
||||
ShoveChatStr (chat, 1);
|
||||
delete[] chat;
|
||||
}
|
||||
ShoveChatStr (argv.AllButFirstArg(), 1);
|
||||
}
|
||||
|
||||
static int STACK_ARGS compare (const void *arg1, const void *arg2)
|
||||
|
@ -361,7 +356,7 @@ void HU_DrawScores (player_t *player)
|
|||
if (playeringame[i])
|
||||
{
|
||||
int width = screen->StringWidth (players[i].userinfo.netname);
|
||||
if (*teamplay)
|
||||
if (teamplay)
|
||||
width += screen->StringWidth (
|
||||
players[i].userinfo.team == TEAM_None ? "None"
|
||||
: TeamNames[players[i].userinfo.team]) + 24;
|
||||
|
@ -376,9 +371,9 @@ void HU_DrawScores (player_t *player)
|
|||
y = (ST_Y >> 1) - (MAXPLAYERS * 6);
|
||||
if (y < 48) y = 48;
|
||||
|
||||
if (*deathmatch && *timelimit && gamestate == GS_LEVEL)
|
||||
if (deathmatch && timelimit && gamestate == GS_LEVEL)
|
||||
{
|
||||
int timeleft = (int)(*timelimit * TICRATE * 60) - level.time;
|
||||
int timeleft = (int)(timelimit * TICRATE * 60) - level.time;
|
||||
int hours, minutes, seconds;
|
||||
|
||||
if (timeleft < 0)
|
||||
|
@ -414,7 +409,7 @@ void HU_DrawScores (player_t *player)
|
|||
screen->DrawTextClean (sortedplayers[i] == player ? CR_GREEN : CR_BRICK,
|
||||
margin, y, str);
|
||||
|
||||
if (*teamplay && sortedplayers[i]->userinfo.team != TEAM_None)
|
||||
if (teamplay && sortedplayers[i]->userinfo.team != TEAM_None)
|
||||
sprintf (str, "%s (%s)", sortedplayers[i]->userinfo.netname,
|
||||
TeamNames[sortedplayers[i]->userinfo.team]);
|
||||
else
|
|
@ -123,89 +123,89 @@ static CodePtrMap *CodePtrNames;
|
|||
static int NumCodePtrs;
|
||||
static const actionf_t CodePtrs[] =
|
||||
{
|
||||
{(actionf_p1)NULL},
|
||||
{(actionf_p1)A_MonsterRail},
|
||||
{(actionf_p1)A_FireRailgun},
|
||||
{(actionf_p1)A_FireRailgunLeft},
|
||||
{(actionf_p1)A_FireRailgunRight},
|
||||
{(actionf_p1)A_RailWait},
|
||||
{(actionf_p1)A_Light0},
|
||||
{(actionf_p1)A_WeaponReady},
|
||||
{(actionf_p1)A_Lower},
|
||||
{(actionf_p1)A_Raise},
|
||||
{(actionf_p1)A_Punch},
|
||||
{(actionf_p1)A_ReFire},
|
||||
{(actionf_p1)A_FirePistol},
|
||||
{(actionf_p1)A_Light1},
|
||||
{(actionf_p1)A_FireShotgun},
|
||||
{(actionf_p1)A_Light2},
|
||||
{(actionf_p1)A_FireShotgun2},
|
||||
{(actionf_p1)A_CheckReload},
|
||||
{(actionf_p1)A_OpenShotgun2},
|
||||
{(actionf_p1)A_LoadShotgun2},
|
||||
{(actionf_p1)A_CloseShotgun2},
|
||||
{(actionf_p1)A_FireCGun},
|
||||
{(actionf_p1)A_GunFlash},
|
||||
{(actionf_p1)A_FireMissile},
|
||||
{(actionf_p1)A_Saw},
|
||||
{(actionf_p1)A_FirePlasma},
|
||||
{(actionf_p1)A_BFGsound},
|
||||
{(actionf_p1)A_FireBFG},
|
||||
{(actionf_p1)A_BFGSpray},
|
||||
{(actionf_p1)A_Explode},
|
||||
{(actionf_p1)A_Pain},
|
||||
{(actionf_p1)A_PlayerScream},
|
||||
{(actionf_p1)A_NoBlocking},
|
||||
{(actionf_p1)A_XScream},
|
||||
{(actionf_p1)A_Look},
|
||||
{(actionf_p1)A_Chase},
|
||||
{(actionf_p1)A_FaceTarget},
|
||||
{(actionf_p1)A_PosAttack},
|
||||
{(actionf_p1)A_Scream},
|
||||
{(actionf_p1)A_SPosAttack},
|
||||
{(actionf_p1)A_VileChase},
|
||||
{(actionf_p1)A_VileStart},
|
||||
{(actionf_p1)A_VileTarget},
|
||||
{(actionf_p1)A_VileAttack},
|
||||
{(actionf_p1)A_StartFire},
|
||||
{(actionf_p1)A_Fire},
|
||||
{(actionf_p1)A_FireCrackle},
|
||||
{(actionf_p1)A_Tracer},
|
||||
{(actionf_p1)A_SkelWhoosh},
|
||||
{(actionf_p1)A_SkelFist},
|
||||
{(actionf_p1)A_SkelMissile},
|
||||
{(actionf_p1)A_FatRaise},
|
||||
{(actionf_p1)A_FatAttack1},
|
||||
{(actionf_p1)A_FatAttack2},
|
||||
{(actionf_p1)A_FatAttack3},
|
||||
{(actionf_p1)A_BossDeath},
|
||||
{(actionf_p1)A_CPosAttack},
|
||||
{(actionf_p1)A_CPosRefire},
|
||||
{(actionf_p1)A_TroopAttack},
|
||||
{(actionf_p1)A_SargAttack},
|
||||
{(actionf_p1)A_HeadAttack},
|
||||
{(actionf_p1)A_BruisAttack},
|
||||
{(actionf_p1)A_SkullAttack},
|
||||
{(actionf_p1)A_Metal},
|
||||
{(actionf_p1)A_SpidRefire},
|
||||
{(actionf_p1)A_BabyMetal},
|
||||
{(actionf_p1)A_BspiAttack},
|
||||
{(actionf_p1)A_Hoof},
|
||||
{(actionf_p1)A_CyberAttack},
|
||||
{(actionf_p1)A_PainAttack},
|
||||
{(actionf_p1)A_PainDie},
|
||||
{(actionf_p1)A_KeenDie},
|
||||
{(actionf_p1)A_BrainPain},
|
||||
{(actionf_p1)A_BrainScream},
|
||||
{(actionf_p1)A_BrainDie},
|
||||
{(actionf_p1)A_BrainAwake},
|
||||
{(actionf_p1)A_BrainSpit},
|
||||
{(actionf_p1)A_SpawnSound},
|
||||
{(actionf_p1)A_SpawnFly},
|
||||
{(actionf_p1)A_BrainExplode},
|
||||
{(actionf_p1)A_Die},
|
||||
{(actionf_p1)A_Detonate},
|
||||
{(actionf_p1)A_Mushroom},
|
||||
{(void *)NULL},
|
||||
{(void *)A_MonsterRail},
|
||||
{(void *)A_FireRailgun},
|
||||
{(void *)A_FireRailgunLeft},
|
||||
{(void *)A_FireRailgunRight},
|
||||
{(void *)A_RailWait},
|
||||
{(void *)A_Light0},
|
||||
{(void *)A_WeaponReady},
|
||||
{(void *)A_Lower},
|
||||
{(void *)A_Raise},
|
||||
{(void *)A_Punch},
|
||||
{(void *)A_ReFire},
|
||||
{(void *)A_FirePistol},
|
||||
{(void *)A_Light1},
|
||||
{(void *)A_FireShotgun},
|
||||
{(void *)A_Light2},
|
||||
{(void *)A_FireShotgun2},
|
||||
{(void *)A_CheckReload},
|
||||
{(void *)A_OpenShotgun2},
|
||||
{(void *)A_LoadShotgun2},
|
||||
{(void *)A_CloseShotgun2},
|
||||
{(void *)A_FireCGun},
|
||||
{(void *)A_GunFlash},
|
||||
{(void *)A_FireMissile},
|
||||
{(void *)A_Saw},
|
||||
{(void *)A_FirePlasma},
|
||||
{(void *)A_BFGsound},
|
||||
{(void *)A_FireBFG},
|
||||
{(void *)A_BFGSpray},
|
||||
{(void *)A_Explode},
|
||||
{(void *)A_Pain},
|
||||
{(void *)A_PlayerScream},
|
||||
{(void *)A_NoBlocking},
|
||||
{(void *)A_XScream},
|
||||
{(void *)A_Look},
|
||||
{(void *)A_Chase},
|
||||
{(void *)A_FaceTarget},
|
||||
{(void *)A_PosAttack},
|
||||
{(void *)A_Scream},
|
||||
{(void *)A_SPosAttack},
|
||||
{(void *)A_VileChase},
|
||||
{(void *)A_VileStart},
|
||||
{(void *)A_VileTarget},
|
||||
{(void *)A_VileAttack},
|
||||
{(void *)A_StartFire},
|
||||
{(void *)A_Fire},
|
||||
{(void *)A_FireCrackle},
|
||||
{(void *)A_Tracer},
|
||||
{(void *)A_SkelWhoosh},
|
||||
{(void *)A_SkelFist},
|
||||
{(void *)A_SkelMissile},
|
||||
{(void *)A_FatRaise},
|
||||
{(void *)A_FatAttack1},
|
||||
{(void *)A_FatAttack2},
|
||||
{(void *)A_FatAttack3},
|
||||
{(void *)A_BossDeath},
|
||||
{(void *)A_CPosAttack},
|
||||
{(void *)A_CPosRefire},
|
||||
{(void *)A_TroopAttack},
|
||||
{(void *)A_SargAttack},
|
||||
{(void *)A_HeadAttack},
|
||||
{(void *)A_BruisAttack},
|
||||
{(void *)A_SkullAttack},
|
||||
{(void *)A_Metal},
|
||||
{(void *)A_SpidRefire},
|
||||
{(void *)A_BabyMetal},
|
||||
{(void *)A_BspiAttack},
|
||||
{(void *)A_Hoof},
|
||||
{(void *)A_CyberAttack},
|
||||
{(void *)A_PainAttack},
|
||||
{(void *)A_PainDie},
|
||||
{(void *)A_KeenDie},
|
||||
{(void *)A_BrainPain},
|
||||
{(void *)A_BrainScream},
|
||||
{(void *)A_BrainDie},
|
||||
{(void *)A_BrainAwake},
|
||||
{(void *)A_BrainSpit},
|
||||
{(void *)A_SpawnSound},
|
||||
{(void *)A_SpawnFly},
|
||||
{(void *)A_BrainExplode},
|
||||
{(void *)A_Die},
|
||||
{(void *)A_Detonate},
|
||||
{(void *)A_Mushroom},
|
||||
};
|
||||
|
||||
// Miscellaneous info that used to be constant
|
||||
|
@ -679,6 +679,7 @@ static int PatchThing (int thingy)
|
|||
if (thingy > NumInfos || thingy <= 0)
|
||||
{
|
||||
info = &dummy;
|
||||
ednum = &dummyed;
|
||||
Printf ("Thing %d out of range.\n", thingy);
|
||||
}
|
||||
else
|
||||
|
@ -1015,6 +1016,7 @@ static int PatchFrame (int frameNum)
|
|||
else
|
||||
{
|
||||
info = &dummy;
|
||||
tics = misc1 = frame = 0;
|
||||
Printf ("Frame %d out of range\n", frameNum);
|
||||
}
|
||||
|
||||
|
@ -1937,6 +1939,7 @@ static void UnloadDehSupp ()
|
|||
Z_FreeTags (PU_DEHACKED, PU_DEHACKED);
|
||||
GStrings.FlushNames ();
|
||||
GStrings.Compact ();
|
||||
G_SetLevelStrings ();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
void DoDehPatch (const char *patchfile, BOOL autoloading);
|
||||
|
||||
#endif //__D_DEHACK_H__
|
||||
#endif //__D_DEHACK_H__
|
|
@ -8,6 +8,7 @@ enum EGUIEvent
|
|||
EV_GUI_KeyDown, // data1: unshifted ASCII, data2: shifted ASCII, data3: modifiers
|
||||
EV_GUI_KeyRepeat, // same
|
||||
EV_GUI_KeyUp, // same
|
||||
EV_GUI_Char, // data1: translated character (for user text input), data2: alt down?
|
||||
EV_GUI_MouseMove,
|
||||
EV_GUI_LButtonDown,
|
||||
EV_GUI_LButtonUp,
|
||||
|
@ -29,7 +30,7 @@ enum GUIKeyModifiers
|
|||
GKM_ALT = 4
|
||||
};
|
||||
|
||||
// Special "ASCII" codes for some GUI keys
|
||||
// Special codes for some GUI keys, including a few real ASCII codes.
|
||||
enum ESpecialGUIKeys
|
||||
{
|
||||
GK_PGUP = 1,
|
||||
|
@ -38,10 +39,33 @@ enum ESpecialGUIKeys
|
|||
GK_END = 4,
|
||||
GK_LEFT = 5,
|
||||
GK_RIGHT = 6,
|
||||
GK_UP = 11,
|
||||
GK_ALERT = 7, // ASCII bell
|
||||
GK_BACKSPACE= 8, // ASCII
|
||||
GK_TAB = 9, // ASCII
|
||||
GK_LINEFEED = 10, // ASCII
|
||||
GK_DOWN = 10,
|
||||
GK_DEL = 14,
|
||||
GK_ESCAPE = 27
|
||||
GK_VTAB = 11, // ASCII
|
||||
GK_UP = 11,
|
||||
GK_FORMFEED = 12, // ASCII
|
||||
GK_RETURN = 13, // ASCII
|
||||
GK_F1 = 14,
|
||||
GK_F2 = 15,
|
||||
GK_F3 = 16,
|
||||
GK_F4 = 17,
|
||||
GK_F5 = 18,
|
||||
GK_F6 = 19,
|
||||
GK_F7 = 20,
|
||||
GK_F8 = 21,
|
||||
GK_F9 = 22,
|
||||
GK_F10 = 23,
|
||||
GK_F11 = 24,
|
||||
GK_F12 = 25,
|
||||
GK_DEL = 26,
|
||||
GK_ESCAPE = 27, // ASCII
|
||||
GK_FREE1 = 28,
|
||||
GK_FREE2 = 29,
|
||||
GK_FREE3 = 30,
|
||||
GK_CESCAPE = 31 // color escape
|
||||
};
|
||||
|
||||
#endif //__D_GUI_H__
|
||||
#endif //__D_GUI_H__
|
|
@ -389,4 +389,4 @@ gitem_t itemlist[] = {
|
|||
void InitItems (void)
|
||||
{
|
||||
num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
|
||||
}
|
||||
}
|
|
@ -68,4 +68,4 @@ gitem_t *FindItem (const char *pickup_name);
|
|||
|
||||
#define ITEM_INDEX(i) ((i)-itemlist)
|
||||
|
||||
#endif //__D_ITEMS_H__
|
||||
#endif //__D_ITEMS_H__
|
|
@ -33,7 +33,7 @@
|
|||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
#ifdef unix
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -254,14 +254,17 @@ CUSTOM_CVAR (Int, dmflags, 0, CVAR_SERVERINFO)
|
|||
if (textureheight)
|
||||
R_InitSkyMap ();
|
||||
|
||||
if (*var & DF_NO_FREELOOK)
|
||||
AddCommandString ("centerview");
|
||||
if (self & DF_NO_FREELOOK)
|
||||
{
|
||||
C_DoCommand ("centerview");
|
||||
}
|
||||
}
|
||||
|
||||
CVAR (Flag, sv_nohealth, dmflags, DF_NO_HEALTH);
|
||||
CVAR (Flag, sv_noitems, dmflags, DF_NO_ITEMS);
|
||||
CVAR (Flag, sv_weaponstay, dmflags, DF_WEAPONS_STAY);
|
||||
CVAR (Flag, sv_falldamage, dmflags, DF_YES_FALLING);
|
||||
CVAR (Flag, sv_falldamage, dmflags, DF_FORCE_FALLINGHX);
|
||||
CVAR (Flag, sv_oldfalldamage, dmflags, DF_FORCE_FALLINGZD);
|
||||
CVAR (Flag, sv_samelevel, dmflags, DF_SAME_LEVEL);
|
||||
CVAR (Flag, sv_spawnfarthest, dmflags, DF_SPAWN_FARTHEST);
|
||||
CVAR (Flag, sv_forcerespawn, dmflags, DF_FORCE_RESPAWN);
|
||||
|
@ -275,13 +278,14 @@ CVAR (Flag, sv_fastmonsters, dmflags, DF_FAST_MONSTERS);
|
|||
CVAR (Flag, sv_nojump, dmflags, DF_NO_JUMP);
|
||||
CVAR (Flag, sv_nofreelook, dmflags, DF_NO_FREELOOK);
|
||||
CVAR (Flag, sv_respawnsuper, dmflags, DF_RESPAWN_SUPER);
|
||||
CVAR (Flag, sv_nopassover, dmflags, DF_NO_PASSMOBJ);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CVAR dmflags2
|
||||
//
|
||||
// [RH] From Skull Tag. Some of these were already done as separate cvars
|
||||
// (such as bfgaiming), but I collected them here like Skull Tag did.
|
||||
// (such as bfgaiming), but I collected them here like Skull Tag does.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -349,7 +353,7 @@ void D_Display (bool screenshot)
|
|||
// Refresh the console.
|
||||
C_NewModeAdjust ();
|
||||
// Reload crosshair if transitioned to a different size
|
||||
crosshair = *crosshair;
|
||||
crosshair.Callback ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,7 +366,7 @@ void D_Display (bool screenshot)
|
|||
setmodeneeded = false;
|
||||
}
|
||||
|
||||
if (screen->Lock (TransArea >= *vid_bufferarea || screenshot))
|
||||
if (screen->Lock (TransArea >= vid_bufferarea || screenshot))
|
||||
{
|
||||
SB_state = screen->GetPageCount ();
|
||||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
|
@ -595,10 +599,8 @@ void D_DoomLoop ()
|
|||
{
|
||||
TryRunTics (); // will run at least one tic
|
||||
}
|
||||
|
||||
// [RH] Use the consoleplayer's camera to update sounds
|
||||
S_UpdateSounds (players[consoleplayer].camera); // move positional sounds
|
||||
|
||||
// Update display, next frame, with current state.
|
||||
D_Display (false);
|
||||
}
|
||||
|
@ -1183,12 +1185,13 @@ static EIWADType IdentifyVersion (void)
|
|||
CheckIWADinEnvDir (value + 1, wads);
|
||||
}
|
||||
}
|
||||
#ifdef UNIX
|
||||
#ifdef unix
|
||||
else if (*value == '~' && (*(value + 1) == 0 || *(value + 1) == '/'))
|
||||
{
|
||||
homepath = GetUserFile (*(value + 1) ? value + 2 : value + 1);
|
||||
CheckIWAD (homepath, wads);
|
||||
delete[] homepath;
|
||||
homepath = NULL;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
@ -1223,7 +1226,7 @@ static EIWADType IdentifyVersion (void)
|
|||
|
||||
pickwad = 0;
|
||||
|
||||
if (!iwadparmfound && numwads > 1 && *queryiwad)
|
||||
if (!iwadparmfound && numwads > 1 && queryiwad)
|
||||
{
|
||||
pickwad = I_PickIWad (wads, numwads);
|
||||
}
|
||||
|
@ -1256,7 +1259,7 @@ static const char *BaseFileSearch (const char *file, const char *ext)
|
|||
|
||||
if (!FileExists (file))
|
||||
{
|
||||
#ifndef UNIX
|
||||
#ifndef unix
|
||||
sprintf (wad, "%s%s", progdir, file);
|
||||
if (!FileExists (wad))
|
||||
{
|
||||
|
@ -1386,6 +1389,11 @@ void D_DoomMain (void)
|
|||
else
|
||||
I_FatalError ("Cannot find zdoom.wad");
|
||||
|
||||
M_LoadDefaults (); // load before initing other systems
|
||||
I_SetTitleString (IWADTypeNames[IdentifyVersion ()]);
|
||||
GameConfig->DoGameSetup (GameNames[gameinfo.gametype]);
|
||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||
|
||||
// [RH] zvox.wad - A wad I had intended to be automatically generate
|
||||
// from Q2's pak0.pak so the female and cyborg player could have
|
||||
// voices. I never got around to writing the utility to do it, though.
|
||||
|
@ -1393,13 +1401,8 @@ void D_DoomMain (void)
|
|||
if (wad)
|
||||
D_AddFile (wad);
|
||||
|
||||
M_LoadDefaults (); // load before initing other systems
|
||||
I_SetTitleString (IWADTypeNames[IdentifyVersion ()]);
|
||||
GameConfig->DoGameSetup (GameNames[gameinfo.gametype]);
|
||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||
|
||||
// [RH] Add any .wad files in the skins directory
|
||||
#ifdef UNIX
|
||||
#ifdef unix
|
||||
sprintf (file, "%sskins", SHARE_DIR);
|
||||
#else
|
||||
sprintf (file, "%sskins", progdir);
|
||||
|
@ -1436,7 +1439,7 @@ void D_DoomMain (void)
|
|||
}
|
||||
}
|
||||
delete files;
|
||||
|
||||
|
||||
W_InitMultipleFiles (&wadfiles);
|
||||
|
||||
// [RH] Initialize localizable strings.
|
||||
|
@ -1513,7 +1516,7 @@ void D_DoomMain (void)
|
|||
bglobal.wanted_botnum = bglobal.getspawned->NumArgs();
|
||||
}
|
||||
|
||||
flags = *dmflags;
|
||||
flags = dmflags;
|
||||
|
||||
if (Args.CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS;
|
||||
if (Args.CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN;
|
||||
|
@ -1581,7 +1584,7 @@ void D_DoomMain (void)
|
|||
if (devparm)
|
||||
Printf (GStrings(D_DEVSTR));
|
||||
|
||||
#ifndef UNIX
|
||||
#ifndef unix
|
||||
if (Args.CheckParm("-cdrom"))
|
||||
{
|
||||
Printf (GStrings(D_CDROM));
|
||||
|
@ -1620,7 +1623,7 @@ void D_DoomMain (void)
|
|||
// Check for -file in shareware
|
||||
if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
|
||||
I_FatalError ("You cannot -file with the shareware version. Register!");
|
||||
|
||||
|
||||
Printf ("Init miscellaneous info.\n");
|
||||
M_Init ();
|
||||
|
||||
|
@ -1631,7 +1634,7 @@ void D_DoomMain (void)
|
|||
P_Init ();
|
||||
|
||||
Printf ("Setting up sound.\n");
|
||||
S_Init ((int)*snd_sfxvolume /* *8 */, (int)*snd_musicvolume /* *8*/ );
|
||||
S_Init ();
|
||||
|
||||
I_FinishClockCalibration ();
|
||||
|
|
@ -295,11 +295,7 @@ unsigned NetbufferChecksum (int len)
|
|||
|
||||
c = 0x1234567;
|
||||
|
||||
// FIXME -endianess?
|
||||
//#ifdef NORMALUNIX
|
||||
// return 0; // byte order problems
|
||||
//#endif
|
||||
|
||||
// FIXME -endianess? [RH] Is endian-ness still a problem?
|
||||
l = (len - myoffsetof(doomdata_t, retransmitfrom))/4;
|
||||
for (i=0 ; i<l ; i++)
|
||||
c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
|
||||
|
@ -481,7 +477,7 @@ void GetPackets (void)
|
|||
nodeingame[netnode] = false;
|
||||
playeringame[netconsole] = false;
|
||||
|
||||
if (*deathmatch)
|
||||
if (deathmatch)
|
||||
{
|
||||
Printf ("%s left the game with %d frags\n",
|
||||
players[netconsole].userinfo.netname,
|
||||
|
@ -1331,7 +1327,7 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
{
|
||||
byte which = ReadByte (stream);
|
||||
FWeaponInfo **infos = (players[player].powers[pw_weaponlevel2]
|
||||
&& *deathmatch) ? wpnlev2info : wpnlev1info;
|
||||
&& deathmatch) ? wpnlev2info : wpnlev1info;
|
||||
|
||||
if (which < NUMWEAPONS
|
||||
&& which != players[player].readyweapon
|
||||
|
@ -1400,13 +1396,11 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
{
|
||||
paused = 0;
|
||||
S_ResumeSound ();
|
||||
I_ResumeMouse ();
|
||||
}
|
||||
else
|
||||
{
|
||||
paused = player + 1;
|
||||
S_PauseSound ();
|
||||
I_PauseMouse ();
|
||||
}
|
||||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
break;
|
|
@ -51,4 +51,4 @@ void D_DoServerInfoChange (byte **stream);
|
|||
void D_WriteUserInfoStrings (int player, byte **stream, bool compact=false);
|
||||
void D_ReadUserInfoStrings (int player, byte **stream, bool update);
|
||||
|
||||
#endif //__D_CLIENTINFO_H__
|
||||
#endif //__D_CLIENTINFO_H__
|
|
@ -75,17 +75,17 @@ void D_SetupUserInfo (void)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
memset (&players[i].userinfo, 0, sizeof(userinfo_t));
|
||||
|
||||
strncpy (coninfo->netname, *name, MAXPLAYERNAME);
|
||||
coninfo->team = *team;
|
||||
coninfo->aimdist = abs ((int)(*autoaim * (float)ANGLE_1));
|
||||
strncpy (coninfo->netname, name, MAXPLAYERNAME);
|
||||
coninfo->team = team;
|
||||
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
||||
if (coninfo->aimdist > ANGLE_1*32)
|
||||
{
|
||||
coninfo->aimdist = ANGLE_1*32;
|
||||
}
|
||||
coninfo->color = *color;
|
||||
coninfo->skin = R_FindSkin (*skin);
|
||||
coninfo->gender = D_GenderToInt (*gender);
|
||||
coninfo->neverswitch = *neverswitchonpickup;
|
||||
coninfo->color = color;
|
||||
coninfo->skin = R_FindSkin (skin);
|
||||
coninfo->gender = D_GenderToInt (gender);
|
||||
coninfo->neverswitch = neverswitchonpickup;
|
||||
R_BuildPlayerTranslation (consoleplayer, coninfo->color);
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,12 @@ void D_UserInfoChanged (FBaseCVar *cvar)
|
|||
|
||||
if (cvar == &autoaim)
|
||||
{
|
||||
if (*autoaim < 0.0f)
|
||||
if (autoaim < 0.0f)
|
||||
{
|
||||
autoaim = 0.0f;
|
||||
return;
|
||||
}
|
||||
else if (*autoaim > 5000.0f)
|
||||
else if (autoaim > 5000.0f)
|
||||
{
|
||||
autoaim = 5000.f;
|
||||
return;
|
||||
|
@ -403,7 +403,7 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info)
|
|||
|
||||
CCMD (playerinfo)
|
||||
{
|
||||
if (argc < 2)
|
||||
if (argv.argc() < 2)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -185,7 +185,6 @@ public:
|
|||
int jumpTics; // delay the next jump for a moment
|
||||
|
||||
int respawn_time; // [RH] delay respawning until this tic
|
||||
fixed_t oldvelocity[3]; // [RH] Used for falling damage
|
||||
AActor *camera; // [RH] Whose eyes this player sees through
|
||||
|
||||
int air_finished; // [RH] Time when you start drowning
|
|
@ -322,4 +322,4 @@ void SkipChunk (byte **stream)
|
|||
|
||||
len = ReadLong (stream);
|
||||
stream += len + (len & 1);
|
||||
}
|
||||
}
|
|
@ -145,4 +145,4 @@ void WriteLong (int val, byte **stream);
|
|||
void WriteFloat (float val, byte **stream);
|
||||
void WriteString (const char *string, byte **stream);
|
||||
|
||||
#endif //__D_PROTOCOL_H__
|
||||
#endif //__D_PROTOCOL_H__
|
587
src/decallib.cpp
Normal file
587
src/decallib.cpp
Normal file
|
@ -0,0 +1,587 @@
|
|||
#include "decallib.h"
|
||||
#include "sc_man.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_video.h"
|
||||
#include "v_palette.h"
|
||||
#include "cmdlib.h"
|
||||
#include "m_random.h"
|
||||
#include "weightedlist.h"
|
||||
|
||||
FDecalLib DecalLibrary;
|
||||
|
||||
// A decal group holds multiple decals and returns one randomly
|
||||
// when GetDecal() is called.
|
||||
|
||||
class FDecalGroup : public FDecalBase
|
||||
{
|
||||
friend class FDecalLib;
|
||||
|
||||
public:
|
||||
FDecalGroup () : Choices (pr_decalchoice) {}
|
||||
FDecal *GetDecal ();
|
||||
void AddDecal (FDecalBase *decal, WORD weight)
|
||||
{
|
||||
Choices.AddEntry (decal, weight);
|
||||
}
|
||||
|
||||
private:
|
||||
TWeightedList<FDecalBase *> Choices;
|
||||
};
|
||||
|
||||
struct FDecalLib::FTranslation
|
||||
{
|
||||
FTranslation (DWORD start, DWORD end);
|
||||
FTranslation *LocateTranslation (DWORD start, DWORD end);
|
||||
|
||||
DWORD StartColor, EndColor;
|
||||
FTranslation *Next;
|
||||
BYTE PalRemap[256];
|
||||
};
|
||||
|
||||
static const char *DecalKeywords[] =
|
||||
{
|
||||
"x-scale",
|
||||
"y-scale",
|
||||
"pic",
|
||||
"solid",
|
||||
"add",
|
||||
"translucent",
|
||||
"flipx",
|
||||
"flipy",
|
||||
"randomflipx",
|
||||
"randomflipy",
|
||||
"fullbright",
|
||||
"fuzzy",
|
||||
"shade",
|
||||
"colors",
|
||||
NULL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DECAL_XSCALE,
|
||||
DECAL_YSCALE,
|
||||
DECAL_PIC,
|
||||
DECAL_SOLID,
|
||||
DECAL_ADD,
|
||||
DECAL_TRANSLUCENT,
|
||||
DECAL_FLIPX,
|
||||
DECAL_FLIPY,
|
||||
DECAL_RANDOMFLIPX,
|
||||
DECAL_RANDOMFLIPY,
|
||||
DECAL_FULLBRIGHT,
|
||||
DECAL_FUZZY,
|
||||
DECAL_SHADE,
|
||||
DECAL_COLORS
|
||||
};
|
||||
|
||||
FDecal *FDecalBase::GetDecal ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FDecalLib::FDecalLib ()
|
||||
{
|
||||
Root = NULL;
|
||||
Translations = NULL;
|
||||
}
|
||||
|
||||
FDecalLib::~FDecalLib ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
|
||||
void FDecalLib::Clear ()
|
||||
{
|
||||
FTranslation *trans;
|
||||
|
||||
DelTree (Root);
|
||||
Root = NULL;
|
||||
|
||||
trans = Translations;
|
||||
while (trans != NULL)
|
||||
{
|
||||
FTranslation *next = trans->Next;
|
||||
delete trans;
|
||||
trans = next;
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::DelTree (FDecalBase *root)
|
||||
{
|
||||
if (root != NULL)
|
||||
{
|
||||
DelTree (root->Left);
|
||||
DelTree (root->Right);
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ReadAllDecals ()
|
||||
{
|
||||
int lump, lastlump = 0;
|
||||
|
||||
while ((lump = W_FindLump ("DECALDEF", &lastlump)) != -1)
|
||||
{
|
||||
SC_OpenLumpNum (lump, "DECALDEF");
|
||||
ReadDecals ();
|
||||
SC_Close ();
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ReadDecals ()
|
||||
{
|
||||
while (SC_GetString ())
|
||||
{
|
||||
if (SC_Compare ("decal"))
|
||||
{
|
||||
ParseDecal ();
|
||||
}
|
||||
else if (SC_Compare ("decalgroup"))
|
||||
{
|
||||
ParseDecalGroup ();
|
||||
}
|
||||
else if (SC_Compare ("generator"))
|
||||
{
|
||||
ParseGenerator ();
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BYTE FDecalLib::GetDecalID ()
|
||||
{
|
||||
SC_MustGetString ();
|
||||
if (!IsNum (sc_String))
|
||||
{
|
||||
SC_UnGet ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long num = strtoul (sc_String, NULL, 10);
|
||||
if (num < 1 || num > 255)
|
||||
{
|
||||
SC_ScriptError ("Decal ID must be between 1 and 255");
|
||||
}
|
||||
return (BYTE)num;
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ParseDecal ()
|
||||
{
|
||||
char decalName[64];
|
||||
byte decalNum;
|
||||
FDecal newdecal;
|
||||
int code;
|
||||
|
||||
SC_MustGetString ();
|
||||
strcpy (decalName, sc_String);
|
||||
decalNum = GetDecalID ();
|
||||
SC_MustGetStringName ("{");
|
||||
|
||||
memset (&newdecal, 0, sizeof(newdecal));
|
||||
newdecal.PicNum = 0xffff;
|
||||
newdecal.ScaleX = newdecal.ScaleY = 63;
|
||||
newdecal.RenderFlags = RF_WALLSPRITE;
|
||||
newdecal.RenderStyle = STYLE_Normal;
|
||||
newdecal.Alpha = 0x8000;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SC_GetString ();
|
||||
if (SC_Compare ("}"))
|
||||
{
|
||||
AddDecal (decalName, decalNum, newdecal);
|
||||
break;
|
||||
}
|
||||
switch ((code = SC_MustMatchString (DecalKeywords)))
|
||||
{
|
||||
case DECAL_XSCALE:
|
||||
case DECAL_YSCALE:
|
||||
SC_MustGetNumber ();
|
||||
if (--sc_Number < 0)
|
||||
sc_Number = 0;
|
||||
if (sc_Number > 255)
|
||||
sc_Number = 255;
|
||||
if (code == DECAL_XSCALE)
|
||||
newdecal.ScaleX = sc_Number;
|
||||
else
|
||||
newdecal.ScaleY = sc_Number;
|
||||
break;
|
||||
|
||||
case DECAL_PIC:
|
||||
SC_MustGetString ();
|
||||
newdecal.PicNum = R_CheckTileNumForName (sc_String, TILE_Patch);
|
||||
break;
|
||||
|
||||
case DECAL_SOLID:
|
||||
newdecal.RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
|
||||
case DECAL_ADD:
|
||||
SC_MustGetFloat ();
|
||||
newdecal.Alpha = (WORD)(32768.f * sc_Float);
|
||||
newdecal.RenderStyle = STYLE_Add;
|
||||
break;
|
||||
|
||||
case DECAL_TRANSLUCENT:
|
||||
SC_MustGetFloat ();
|
||||
newdecal.Alpha = (WORD)(32768.f * sc_Float);
|
||||
newdecal.RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
|
||||
case DECAL_FLIPX:
|
||||
newdecal.RenderFlags |= RF_XFLIP;
|
||||
break;
|
||||
|
||||
case DECAL_FLIPY:
|
||||
newdecal.RenderFlags |= RF_YFLIP;
|
||||
break;
|
||||
|
||||
case DECAL_RANDOMFLIPX:
|
||||
newdecal.RenderFlags |= FDecal::DECAL_RandomFlipX;
|
||||
break;
|
||||
|
||||
case DECAL_RANDOMFLIPY:
|
||||
newdecal.RenderFlags |= FDecal::DECAL_RandomFlipY;
|
||||
break;
|
||||
|
||||
case DECAL_FULLBRIGHT:
|
||||
newdecal.RenderFlags |= RF_FULLBRIGHT;
|
||||
break;
|
||||
|
||||
case DECAL_FUZZY:
|
||||
newdecal.RenderStyle = STYLE_Fuzzy;
|
||||
break;
|
||||
|
||||
case DECAL_SHADE:
|
||||
SC_MustGetString ();
|
||||
newdecal.RenderStyle = STYLE_Shaded;
|
||||
newdecal.ShadeColor = V_GetColor (NULL, sc_String);
|
||||
newdecal.ShadeColor |=
|
||||
ColorMatcher.Pick (RPART(newdecal.ShadeColor),
|
||||
GPART(newdecal.ShadeColor), BPART(newdecal.ShadeColor)) << 24;
|
||||
break;
|
||||
|
||||
case DECAL_COLORS:
|
||||
DWORD startcolor, endcolor;
|
||||
|
||||
SC_MustGetString (); startcolor = V_GetColor (NULL, sc_String);
|
||||
SC_MustGetString (); endcolor = V_GetColor (NULL, sc_String);
|
||||
newdecal.Translation = GenerateTranslation (startcolor, endcolor)->PalRemap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ParseDecalGroup ()
|
||||
{
|
||||
char groupName[64];
|
||||
BYTE decalNum;
|
||||
FDecalBase *targetDecal;
|
||||
FDecalGroup *group;
|
||||
|
||||
SC_MustGetString ();
|
||||
strcpy (groupName, sc_String);
|
||||
decalNum = GetDecalID ();
|
||||
SC_MustGetStringName ("{");
|
||||
|
||||
group = new FDecalGroup;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SC_GetString ();
|
||||
if (SC_Compare ("}"))
|
||||
{
|
||||
group->Name = copystring (groupName);
|
||||
AddDecal (group);
|
||||
break;
|
||||
}
|
||||
|
||||
targetDecal = ScanTreeForName (sc_String, Root);
|
||||
if (targetDecal == NULL)
|
||||
{
|
||||
const char *arg = sc_String;
|
||||
SC_ScriptError ("%s has not been defined", &arg);
|
||||
}
|
||||
SC_MustGetNumber ();
|
||||
|
||||
group->AddDecal (targetDecal, sc_Number);
|
||||
}
|
||||
}
|
||||
|
||||
void FDecalLib::ParseGenerator ()
|
||||
{
|
||||
const TypeInfo *type;
|
||||
FDecalBase *decal;
|
||||
AActor *actor;
|
||||
|
||||
// Get name of generator (actor)
|
||||
SC_MustGetString ();
|
||||
type = TypeInfo::FindType (sc_String);
|
||||
if (type == NULL || type->ActorInfo == NULL)
|
||||
{
|
||||
const char *eekMsg = "%s is not an actor.";
|
||||
const char *args[2];
|
||||
|
||||
args[0] = sc_String;
|
||||
if (type == NULL)
|
||||
{
|
||||
type = TypeInfo::IFindType (sc_String);
|
||||
if (type != NULL)
|
||||
{
|
||||
args[1] = type->Name + 1;
|
||||
eekMsg = "%s is not an actor.\nDid you mean %s?";
|
||||
}
|
||||
}
|
||||
SC_ScriptError (eekMsg, args);
|
||||
}
|
||||
actor = (AActor *)type->ActorInfo->Defaults;
|
||||
|
||||
// Get name of generated decal
|
||||
SC_MustGetString ();
|
||||
decal = ScanTreeForName (sc_String, Root);
|
||||
if (decal == NULL)
|
||||
{
|
||||
const char *arg = sc_String;
|
||||
SC_ScriptError ("%s has not been defined.", &arg);
|
||||
}
|
||||
|
||||
actor->DecalGenerator = decal;
|
||||
}
|
||||
|
||||
void FDecalLib::AddDecal (const char *name, byte num, const FDecal &decal)
|
||||
{
|
||||
FDecal *newDecal = new FDecal;
|
||||
|
||||
*newDecal = decal;
|
||||
newDecal->Name = copystring (name);
|
||||
newDecal->SpawnID = num;
|
||||
AddDecal (newDecal);
|
||||
}
|
||||
|
||||
void FDecalLib::AddDecal (FDecalBase *decal)
|
||||
{
|
||||
FDecalBase *node = Root, **prev = &Root;
|
||||
int num = decal->SpawnID;
|
||||
|
||||
decal->SpawnID = 0;
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
int lexx = stricmp (decal->Name, node->Name);
|
||||
if (lexx == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (lexx < 0)
|
||||
{
|
||||
prev = &node->Left;
|
||||
node = node->Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &node->Right;
|
||||
node = node->Right;
|
||||
}
|
||||
}
|
||||
if (node == NULL)
|
||||
{
|
||||
decal->SpawnID = 0;
|
||||
*prev = decal;
|
||||
decal->Left = NULL;
|
||||
decal->Right = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
decal->Left = node->Left;
|
||||
decal->Right = node->Right;
|
||||
*prev = decal;
|
||||
delete node;
|
||||
}
|
||||
if (num != 0)
|
||||
{
|
||||
FDecalBase *spawner = ScanTreeForNum (num, Root);
|
||||
if (spawner != NULL)
|
||||
{
|
||||
spawner->SpawnID = 0;
|
||||
}
|
||||
decal->SpawnID = num;
|
||||
}
|
||||
}
|
||||
|
||||
const FDecal *FDecalLib::GetDecalByNum (byte num) const
|
||||
{
|
||||
if (num == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ScanTreeForNum (num, Root)->GetDecal ();
|
||||
}
|
||||
|
||||
const FDecal *FDecalLib::GetDecalByName (const char *name) const
|
||||
{
|
||||
if (name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ScanTreeForName (name, Root)->GetDecal ();
|
||||
}
|
||||
|
||||
FDecalBase *FDecalLib::ScanTreeForNum (const BYTE num, FDecalBase *root)
|
||||
{
|
||||
while (root != NULL)
|
||||
{
|
||||
if (root->SpawnID == num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ScanTreeForNum (num, root->Left);
|
||||
root = root->Right; // Avoid tail-recursion
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
FDecalBase *FDecalLib::ScanTreeForName (const char *name, FDecalBase *root)
|
||||
{
|
||||
while (root != NULL)
|
||||
{
|
||||
int lexx = stricmp (name, root->Name);
|
||||
if (lexx == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (lexx < 0)
|
||||
{
|
||||
root = root->Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = root->Right;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation *FDecalLib::GenerateTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
FTranslation *trans;
|
||||
|
||||
if (Translations != NULL)
|
||||
{
|
||||
trans = Translations->LocateTranslation (start, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans = NULL;
|
||||
}
|
||||
if (trans == NULL)
|
||||
{
|
||||
trans = new FTranslation (start, end);
|
||||
trans->Next = Translations;
|
||||
Translations = trans;
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
|
||||
FDecalBase::FDecalBase ()
|
||||
{
|
||||
Name = NULL;
|
||||
}
|
||||
|
||||
FDecalBase::~FDecalBase ()
|
||||
{
|
||||
if (Name != NULL)
|
||||
delete[] Name;
|
||||
}
|
||||
|
||||
void FDecal::ApplyToActor (AActor *actor) const
|
||||
{
|
||||
if (RenderStyle == STYLE_Shaded)
|
||||
{
|
||||
actor->SetShade (ShadeColor);
|
||||
}
|
||||
actor->translation = Translation;
|
||||
actor->xscale = ScaleX;
|
||||
actor->yscale = ScaleY;
|
||||
actor->picnum = PicNum;
|
||||
actor->alpha = Alpha << 1;
|
||||
actor->RenderStyle = RenderStyle;
|
||||
actor->renderflags = (RenderFlags & ~(DECAL_RandomFlipX|DECAL_RandomFlipY)) |
|
||||
(actor->renderflags & (RF_RELMASK|RF_CLIPMASK|RF_INVISIBLE|RF_ONESIDED));
|
||||
if (RenderFlags & (DECAL_RandomFlipX|DECAL_RandomFlipY))
|
||||
{
|
||||
actor->renderflags ^= P_Random (pr_decal) &
|
||||
((RenderFlags & (DECAL_RandomFlipX|DECAL_RandomFlipY)) >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
FDecal *FDecal::GetDecal ()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation::FTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
DWORD ri, gi, bi, rs, gs, bs;
|
||||
PalEntry *first, *last;
|
||||
int i;
|
||||
|
||||
StartColor = start;
|
||||
EndColor = end;
|
||||
Next = NULL;
|
||||
|
||||
first = (PalEntry *)&StartColor;
|
||||
last = (PalEntry *)&EndColor;
|
||||
|
||||
ri = first->r << 24;
|
||||
gi = first->g << 24;
|
||||
bi = first->b << 24;
|
||||
rs = last->r << 24;
|
||||
gs = last->g << 24;
|
||||
bs = last->b << 24;
|
||||
|
||||
rs = (rs - ri) / 255;
|
||||
gs = (gs - ri) / 255;
|
||||
bs = (bs - bi) / 255;
|
||||
|
||||
for (i = 1; i < 256; i++, ri += rs, gi += gs, bi += bs)
|
||||
{
|
||||
PalRemap[i] = ColorMatcher.Pick (ri >> 24, gi >> 24, bi >> 24);
|
||||
}
|
||||
PalRemap[0] = PalRemap[1];
|
||||
}
|
||||
|
||||
FDecalLib::FTranslation *FDecalLib::FTranslation::LocateTranslation (DWORD start, DWORD end)
|
||||
{
|
||||
FTranslation *trans = this;
|
||||
|
||||
do
|
||||
{
|
||||
if (start == trans->StartColor && end == trans->EndColor)
|
||||
{
|
||||
return trans;
|
||||
}
|
||||
trans = trans->Next;
|
||||
} while (trans != NULL);
|
||||
return trans;
|
||||
}
|
||||
|
||||
FDecal *FDecalGroup::GetDecal ()
|
||||
{
|
||||
FDecalBase *decal = Choices.PickEntry ();
|
||||
FDecalBase *remember;
|
||||
|
||||
// Repeatedly GetDecal() until the result is the same, since
|
||||
// the choice might be another FDecalGroup.
|
||||
do
|
||||
{
|
||||
remember = decal;
|
||||
decal = decal->GetDecal ();
|
||||
} while (decal != remember);
|
||||
return static_cast<FDecal *>(decal);
|
||||
}
|
|
@ -6,28 +6,41 @@
|
|||
#include "doomtype.h"
|
||||
|
||||
class AActor;
|
||||
class FDecal;
|
||||
|
||||
class FDecal
|
||||
class FDecalBase
|
||||
{
|
||||
friend class FDecalLib;
|
||||
|
||||
private:
|
||||
FDecal ();
|
||||
~FDecal ();
|
||||
|
||||
FDecal *Left, *Right;
|
||||
|
||||
public:
|
||||
virtual FDecal *GetDecal ();
|
||||
|
||||
protected:
|
||||
FDecalBase ();
|
||||
virtual ~FDecalBase ();
|
||||
|
||||
FDecalBase *Left, *Right;
|
||||
char *Name;
|
||||
BYTE SpawnID;
|
||||
};
|
||||
|
||||
class FDecal : public FDecalBase
|
||||
{
|
||||
friend class FDecalLib;
|
||||
public:
|
||||
FDecal () : Translation (NULL) {}
|
||||
|
||||
void ApplyToActor (AActor *actor) const;
|
||||
FDecal *GetDecal ();
|
||||
|
||||
DWORD ShadeColor;
|
||||
BYTE *Translation;
|
||||
char *Name;
|
||||
BYTE ScaleX, ScaleY;
|
||||
BYTE SpawnID, RenderStyle;
|
||||
BYTE RenderStyle;
|
||||
WORD PicNum;
|
||||
WORD RenderFlags;
|
||||
WORD Alpha; // same as (actor->alpha >> 1)
|
||||
|
||||
enum { DECAL_RandomFlipX = 0x100, DECAL_RandomFlipY = 0x200 };
|
||||
};
|
||||
|
||||
class FDecalLib
|
||||
|
@ -42,20 +55,26 @@ public:
|
|||
|
||||
const FDecal *GetDecalByNum (byte num) const;
|
||||
const FDecal *GetDecalByName (const char *name) const;
|
||||
void AddDecal (const char *name, byte num, const FDecal &decal);
|
||||
|
||||
private:
|
||||
struct FTranslation;
|
||||
|
||||
static void DelTree (FDecal *root);
|
||||
static FDecal *ScanTreeForNum (const BYTE num, FDecal *root);
|
||||
static FDecal *ScanTreeForName (const char *name, FDecal *root);
|
||||
static void DelTree (FDecalBase *root);
|
||||
static FDecalBase *ScanTreeForNum (const BYTE num, FDecalBase *root);
|
||||
static FDecalBase *ScanTreeForName (const char *name, FDecalBase *root);
|
||||
FTranslation *GenerateTranslation (DWORD start, DWORD end);
|
||||
void AddDecal (const char *name, byte num, const FDecal &decal);
|
||||
void AddDecal (FDecalBase *decal);
|
||||
|
||||
FDecal *Root;
|
||||
BYTE GetDecalID ();
|
||||
void ParseDecal ();
|
||||
void ParseDecalGroup ();
|
||||
void ParseGenerator ();
|
||||
|
||||
FDecalBase *Root;
|
||||
FTranslation *Translations;
|
||||
};
|
||||
|
||||
extern FDecalLib DecalLibrary;
|
||||
|
||||
#endif //__DECALLIB_H__
|
||||
#endif //__DECALLIB_H__
|
|
@ -121,7 +121,7 @@ CCMD (dumpclasses)
|
|||
int shown, omitted;
|
||||
bool showall = true;
|
||||
|
||||
if (argc > 1)
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
root = TypeInfo::IFindType (argv[1]);
|
||||
if (root == NULL)
|
||||
|
@ -131,7 +131,7 @@ CCMD (dumpclasses)
|
|||
}
|
||||
if (stricmp (argv[1], "Actor") == 0)
|
||||
{
|
||||
if (argc < 3 || stricmp (argv[2], "all") != 0)
|
||||
if (argv.argc() < 3 || stricmp (argv[2], "all") != 0)
|
||||
{
|
||||
showall = false;
|
||||
}
|
|
@ -116,9 +116,8 @@ enum ESkillLevels
|
|||
#define TELEFOGHEIGHT (gameinfo.telefogheight)
|
||||
|
||||
//
|
||||
// DOOM keyboard definition.
|
||||
// This is the stuff configured by Setup.Exe.
|
||||
// Most key data are simple ascii (uppercased).
|
||||
// DOOM keyboard definition. Everything below 0x100 matches
|
||||
// a DirectInput key code.
|
||||
//
|
||||
#define KEY_RIGHTARROW 0xcd // DIK_RIGHT
|
||||
#define KEY_LEFTARROW 0xcb // DIK_LEFT
|
||||
|
@ -142,7 +141,7 @@ enum ESkillLevels
|
|||
#define KEY_F12 0x58 // DIK_F12
|
||||
|
||||
#define KEY_BACKSPACE 0x0e // DIK_BACK
|
||||
#define KEY_PAUSE 0xff
|
||||
#define KEY_PAUSE 0xc5 // DIK_PAUSE
|
||||
|
||||
#define KEY_EQUALS 0x0d // DIK_EQUALS
|
||||
#define KEY_MINUS 0x0c // DIK_MINUS
|
||||
|
@ -166,8 +165,10 @@ enum ESkillLevels
|
|||
#define KEY_MOUSE2 0x101
|
||||
#define KEY_MOUSE3 0x102
|
||||
#define KEY_MOUSE4 0x103
|
||||
#define KEY_MWHEELUP 0x104
|
||||
#define KEY_MWHEELDOWN 0x105
|
||||
#define KEY_MOUSE5 0x104
|
||||
#define KEY_MOUSE6 0x105
|
||||
#define KEY_MWHEELUP 0x106
|
||||
#define KEY_MWHEELDOWN 0x107
|
||||
|
||||
#define KEY_JOY1 0x108
|
||||
#define KEY_JOY2 0x109
|
||||
|
@ -208,7 +209,8 @@ enum ESkillLevels
|
|||
#define DF_NO_HEALTH 1 // Do not spawn health items (DM)
|
||||
#define DF_NO_ITEMS 2 // Do not spawn powerups (DM)
|
||||
#define DF_WEAPONS_STAY 4 // Leave weapons around after pickup (DM)
|
||||
#define DF_YES_FALLING 8 // Falling too far hurts
|
||||
#define DF_FORCE_FALLINGZD 8 // Falling too far hurts (old ZDoom style)
|
||||
#define DF_FORCE_FALLINGHX 16 // Falling too far hurts (Hexen style)
|
||||
//#define DF_INVENTORY_ITEMS 32 // Wait for player to use powerups when picked up
|
||||
#define DF_SAME_LEVEL 64 // Stay on the same map when someone exits (DM)
|
||||
#define DF_SPAWN_FARTHEST 128 // Spawn players as far as possible from other players (DM)
|
||||
|
@ -223,6 +225,7 @@ enum ESkillLevels
|
|||
#define DF_NO_JUMP 65536 // Don't allow jumping
|
||||
#define DF_NO_FREELOOK 131072 // Don't allow freelook
|
||||
#define DF_RESPAWN_SUPER 262144 // Respawn invulnerability and invisibility
|
||||
#define DF_NO_PASSMOBJ 524288 // Pretend every actor is infinitely tall
|
||||
|
||||
// [BC] More dmflags. w00p!
|
||||
//#define DF2_YES_IMPALING 1 // Player gets implaed on MF2_IMPALE items
|
|
@ -65,4 +65,4 @@ CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
|
|||
}
|
||||
|
||||
// [RH] Network arbitrator
|
||||
int Net_Arbitrator = 0;
|
||||
int Net_Arbitrator = 0;
|
|
@ -98,17 +98,9 @@ EXTERN_CVAR (Float, teamdamage)
|
|||
|
||||
// -------------------------
|
||||
// Internal parameters for sound rendering.
|
||||
// These have been taken from the DOS version,
|
||||
// but are not (yet) supported with Linux
|
||||
// (e.g. no sound volume adjustment with menu.
|
||||
|
||||
// These are not used, but should be (menu).
|
||||
// From m_menu.c:
|
||||
// Sound FX volume has default, 0 - 15
|
||||
// Music volume has default, 0 - 15
|
||||
// These are multiplied by 8.
|
||||
EXTERN_CVAR (Int, snd_sfxvolume) // maximum volume for sound
|
||||
EXTERN_CVAR (Int, snd_musicvolume) // maximum volume for music
|
||||
EXTERN_CVAR (Float, snd_sfxvolume) // maximum volume for sound
|
||||
EXTERN_CVAR (Float, snd_musicvolume) // maximum volume for music
|
||||
|
||||
|
||||
// -------------------------
|
|
@ -26,6 +26,14 @@
|
|||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
// VC++ does not define PATH_MAX, but the Windows headers do define MAX_PATH.
|
||||
// However, we want to avoid including the Windows headers in most of the
|
||||
// source files, so we can't use it. So define PATH_MAX to be what MAX_PATH
|
||||
// currently is:
|
||||
#define PATH_MAX 260
|
||||
#endif
|
||||
|
||||
#ifndef __BYTEBOOL__
|
||||
#define __BYTEBOOL__
|
||||
// [RH] Some windows includes already define this
|
||||
|
@ -35,13 +43,6 @@ typedef int BOOL;
|
|||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi)))
|
||||
#else
|
||||
#define GCCPRINTF(a,b)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define STACK_ARGS __cdecl
|
||||
#else
|
||||
|
@ -90,8 +91,8 @@ typedef DWORD BITFIELD;
|
|||
typedef SDWORD fixed_t;
|
||||
typedef DWORD dsfixed_t; // fixedpt used by span drawer
|
||||
|
||||
#define FIXED_MAX 0x7fffffff
|
||||
#define FIXED_MIN 0x80000000
|
||||
#define FIXED_MAX (signed)(0x7fffffff)
|
||||
#define FIXED_MIN (signed)(0x80000000)
|
||||
|
||||
#ifndef NOASM
|
||||
#ifndef USEASM
|
||||
|
@ -103,6 +104,18 @@ typedef DWORD dsfixed_t; // fixedpt used by span drawer
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi)))
|
||||
#define GCCFORMAT(stri) __attribute__((format(printf,stri,0)))
|
||||
#define GCCNOWARN __attribute__((unused))
|
||||
#else
|
||||
#define GCCPRINTF(a,b)
|
||||
#define GCCFORMAT(a)
|
||||
#define GCCNOWARN
|
||||
#endif
|
||||
|
||||
|
||||
// [RH] This gets used all over; define it here:
|
||||
int STACK_ARGS Printf (int printlevel, const char *, ...) GCCPRINTF(2,3);
|
||||
int STACK_ARGS Printf (const char *, ...) GCCPRINTF(1,2);
|
|
@ -65,4 +65,4 @@ protected:
|
|||
DMovingCeiling ();
|
||||
};
|
||||
|
||||
#endif //__DSECTOREFFECT_H__
|
||||
#endif //__DSECTOREFFECT_H__
|
|
@ -130,7 +130,7 @@ void DThinker::ChangeStatNum (int statnum)
|
|||
statnum = MAX_STATNUM;
|
||||
}
|
||||
Remove ();
|
||||
if (ObjectFlags & OF_JustSpawned)
|
||||
if ((ObjectFlags & OF_JustSpawned) && statnum >= STAT_FIRST_THINKING)
|
||||
{
|
||||
FreshThinkers[statnum].AddTail (this);
|
||||
}
|
||||
|
@ -334,4 +334,4 @@ DThinker *it;
|
|||
void mine ()
|
||||
{
|
||||
it = new DThinker;
|
||||
}
|
||||
}
|
|
@ -112,4 +112,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#endif //__DTHINKER_H__
|
||||
#endif //__DTHINKER_H__
|
|
@ -43,4 +43,4 @@ public:
|
|||
CFatalError(const char *message) : CDoomError(message) {}
|
||||
};
|
||||
|
||||
#endif //__ERRORS_H__
|
||||
#endif //__ERRORS_H__
|
|
@ -601,7 +601,7 @@ void F_CastDrawer (void)
|
|||
sprdef = &sprites[castsprite];
|
||||
sprframe = &sprdef->spriteframes[caststate->GetFrame()];
|
||||
lump = sprframe->lump[0];
|
||||
flip = (BOOL)sprframe->flip[0];
|
||||
flip = (BOOL)sprframe->flip & 1;
|
||||
|
||||
patch = (patch_t *)W_CacheLumpNum (lump, PU_CACHE);
|
||||
if (flip)
|
|
@ -376,7 +376,7 @@ int wipe_exitFade (int ticks)
|
|||
|
||||
int wipe_StartScreen (void)
|
||||
{
|
||||
CurrentWipeType = *wipetype;
|
||||
CurrentWipeType = wipetype;
|
||||
if (CurrentWipeType < 0)
|
||||
CurrentWipeType = 0;
|
||||
else if (CurrentWipeType >= wipe_NUMWIPES)
|
|
@ -9,9 +9,20 @@
|
|||
#include "cmdlib.h"
|
||||
#include "i_system.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "d_player.h"
|
||||
#include "dobject.h"
|
||||
|
||||
#define NEW_OBJ ((BYTE)1)
|
||||
#define NEW_CLS_OBJ ((BYTE)2)
|
||||
#define OLD_OBJ ((BYTE)3)
|
||||
#define NULL_OBJ ((BYTE)4)
|
||||
#define NEW_PLYR_OBJ ((BYTE)5)
|
||||
#define NEW_PLYR_CLS_OBJ ((BYTE)6)
|
||||
#define NEW_NAME ((BYTE)27)
|
||||
#define OLD_NAME ((BYTE)28)
|
||||
#define NIL_NAME ((BYTE)33)
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define SWAP_WORD(x)
|
||||
#define SWAP_DWORD(x)
|
||||
|
@ -231,7 +242,7 @@ void FCompressedFile::Implode ()
|
|||
byte *oldbuf = m_Buffer;
|
||||
int r;
|
||||
|
||||
if (!*nofilecompression && !m_NoCompress)
|
||||
if (!nofilecompression && !m_NoCompress)
|
||||
{
|
||||
outlen = OUT_LEN(len);
|
||||
do
|
||||
|
@ -248,12 +259,12 @@ void FCompressedFile::Implode ()
|
|||
// If the data could not be compressed, store it as-is.
|
||||
if (r != Z_OK || outlen >= len)
|
||||
{
|
||||
DPrintf ("cfile could not be deflated\n");
|
||||
DPrintf ("cfile could not be compress\n");
|
||||
outlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPrintf ("cfile shrank from %u to %u bytes\n", len, outlen);
|
||||
DPrintf ("cfile shrank from %lu to %lu bytes\n", len, outlen);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -407,7 +418,7 @@ void FCompressedMemFile::Serialize (FArchive &arc)
|
|||
{
|
||||
if (m_ImplodedBuffer == NULL)
|
||||
{
|
||||
I_Error ("FCompressedMemFile must be deflated before storing");
|
||||
I_Error ("FCompressedMemFile must be compressed before storing");
|
||||
}
|
||||
arc.Write (ZSig, 4);
|
||||
|
||||
|
@ -485,7 +496,10 @@ FArchive::FArchive (FFile &file)
|
|||
}
|
||||
m_ClassCount = 0;
|
||||
for (i = 0; i < EObjectHashSize; i++)
|
||||
{
|
||||
m_ObjectHash[i] = ~0;
|
||||
m_NameHash[i] = NameMap::NO_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
FArchive::~FArchive ()
|
||||
|
@ -513,7 +527,7 @@ void FArchive::Close ()
|
|||
{
|
||||
m_File->Close ();
|
||||
m_File = NULL;
|
||||
DPrintf ("Processed %d objects\n", m_ObjectCount);
|
||||
DPrintf ("Processed %ld objects\n", m_ObjectCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,6 +562,72 @@ DWORD FArchive::ReadCount ()
|
|||
return count;
|
||||
}
|
||||
|
||||
void FArchive::WriteName (const char *name)
|
||||
{
|
||||
BYTE id;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
id = NIL_NAME;
|
||||
Write (&id, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD index = FindName (name);
|
||||
if (index != NameMap::NO_INDEX)
|
||||
{
|
||||
id = OLD_NAME;
|
||||
Write (&id, 1);
|
||||
WriteCount (index);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddName (name);
|
||||
id = NEW_NAME;
|
||||
Write (&id, 1);
|
||||
WriteString (name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *FArchive::ReadName ()
|
||||
{
|
||||
BYTE id;
|
||||
|
||||
operator<< (id);
|
||||
if (id == NIL_NAME)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (id == OLD_NAME)
|
||||
{
|
||||
DWORD index = ReadCount ();
|
||||
if (index >= m_Names.Size())
|
||||
{
|
||||
I_Error ("Name %lu has not been read yet\n", index);
|
||||
}
|
||||
return &m_NameStorage[m_Names[index].StringStart];
|
||||
}
|
||||
else if (id == NEW_NAME)
|
||||
{
|
||||
DWORD index;
|
||||
DWORD size = ReadCount ();
|
||||
char *str;
|
||||
|
||||
index = m_NameStorage.Reserve (size);
|
||||
str = &m_NameStorage[index];
|
||||
Read (str, size-1);
|
||||
str[size-1] = 0;
|
||||
AddName (index);
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error ("Expected a name but got something else\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FArchive::WriteString (const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
|
@ -717,13 +797,6 @@ FArchive &FArchive::SerializeObject (DObject *&object, TypeInfo *type)
|
|||
return ReadObject (object, type);
|
||||
}
|
||||
|
||||
#define NEW_OBJ ((BYTE)1)
|
||||
#define NEW_CLS_OBJ ((BYTE)2)
|
||||
#define OLD_OBJ ((BYTE)3)
|
||||
#define NULL_OBJ ((BYTE)4)
|
||||
#define NEW_PLYR_OBJ ((BYTE)5)
|
||||
#define NEW_PLYR_CLS_OBJ ((BYTE)6)
|
||||
|
||||
FArchive &FArchive::WriteObject (DObject *obj)
|
||||
{
|
||||
player_t *player;
|
||||
|
@ -828,7 +901,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, TypeInfo *wanttype)
|
|||
index = ReadCount ();
|
||||
if (index >= m_ObjectCount)
|
||||
{
|
||||
I_Error ("Object reference too high (%u; max is %u)\n", index, m_ObjectCount);
|
||||
I_Error ("Object reference too high (%lu; max is %lu)\n", index, m_ObjectCount);
|
||||
}
|
||||
obj = (DObject *)m_ObjectMap[index].object;
|
||||
break;
|
||||
|
@ -888,6 +961,52 @@ FArchive &FArchive::ReadObject (DObject* &obj, TypeInfo *wanttype)
|
|||
return *this;
|
||||
}
|
||||
|
||||
DWORD FArchive::AddName (const char *name)
|
||||
{
|
||||
DWORD index;
|
||||
size_t hash = MakeKey (name) % EObjectHashSize;
|
||||
|
||||
index = FindName (name, hash);
|
||||
if (index == NameMap::NO_INDEX)
|
||||
{
|
||||
size_t namelen = strlen (name) + 1;
|
||||
size_t strpos = m_NameStorage.Reserve (namelen);
|
||||
NameMap mapper = { strpos, m_NameHash[hash] };
|
||||
|
||||
memcpy (&m_NameStorage[strpos], name, namelen);
|
||||
m_NameHash[hash] = index = m_Names.Push (mapper);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
DWORD FArchive::AddName (size_t start)
|
||||
{
|
||||
size_t hash = MakeKey (&m_NameStorage[start]) % EObjectHashSize;
|
||||
NameMap mapper = { start, m_NameHash[hash] };
|
||||
return (m_NameHash[hash] = m_Names.Push (mapper));
|
||||
}
|
||||
|
||||
DWORD FArchive::FindName (const char *name) const
|
||||
{
|
||||
return FindName (name, MakeKey (name) % EObjectHashSize);
|
||||
}
|
||||
|
||||
DWORD FArchive::FindName (const char *name, size_t bucket) const
|
||||
{
|
||||
size_t map = m_NameHash[bucket];
|
||||
|
||||
while (map != NameMap::NO_INDEX)
|
||||
{
|
||||
const NameMap *mapping = &m_Names[map];
|
||||
if (strcmp (name, &m_NameStorage[mapping->StringStart]) == 0)
|
||||
{
|
||||
return map;
|
||||
}
|
||||
map = mapping->HashNext;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
DWORD FArchive::WriteClass (const TypeInfo *info)
|
||||
{
|
||||
if (m_ClassCount >= TypeInfo::m_NumTypes)
|
||||
|
@ -930,7 +1049,7 @@ const TypeInfo *FArchive::ReadClass ()
|
|||
return TypeInfo::m_Types[i];
|
||||
}
|
||||
}
|
||||
I_Error ("Unknown class '%s'\n", typeName);
|
||||
I_Error ("Unknown class '%s'\n", typeName.val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -951,7 +1070,7 @@ const TypeInfo *FArchive::ReadStoredClass (const TypeInfo *wanttype)
|
|||
DWORD index = ReadCount ();
|
||||
if (index >= m_ClassCount)
|
||||
{
|
||||
I_Error ("Class reference too high (%u; max is %u)\n", index, m_ClassCount);
|
||||
I_Error ("Class reference too high (%lu; max is %lu)\n", index, m_ClassCount);
|
||||
}
|
||||
const TypeInfo *type = m_TypeMap[index].toCurrent;
|
||||
if (!type->IsDescendantOf (wanttype))
|
||||
|
@ -990,7 +1109,7 @@ DWORD FArchive::MapObject (const DObject *obj)
|
|||
|
||||
DWORD FArchive::HashObject (const DObject *obj) const
|
||||
{
|
||||
return (DWORD)((ptrdiff_t)obj % EObjectHashSize);
|
||||
return (DWORD)((size_t)obj % EObjectHashSize);
|
||||
}
|
||||
|
||||
DWORD FArchive::FindObjectIndex (const DObject *obj) const
|
||||
|
@ -1046,4 +1165,4 @@ void FArchive::UserReadClass (const TypeInfo *&type)
|
|||
type = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include "doomtype.h"
|
||||
#include "dobject.h"
|
||||
#include "tarray.h"
|
||||
|
||||
class DObject;
|
||||
|
||||
|
@ -137,6 +138,9 @@ virtual void Read (void *mem, unsigned int len);
|
|||
FArchive& WriteObject (DObject *obj);
|
||||
FArchive& ReadObject (DObject *&obj, TypeInfo *wanttype);
|
||||
|
||||
void WriteName (const char *name);
|
||||
const char *ReadName (); // The returned name disappears with the archive, unlike strings
|
||||
|
||||
inline FArchive& operator<< (char &c) { return operator<< ((BYTE &)c); }
|
||||
inline FArchive& operator<< (SBYTE &c) { return operator<< ((BYTE &)c); }
|
||||
inline FArchive& operator<< (SWORD &s) { return operator<< ((WORD &)s); }
|
||||
|
@ -159,6 +163,10 @@ protected:
|
|||
const TypeInfo *ReadClass (const TypeInfo *wanttype);
|
||||
const TypeInfo *ReadStoredClass (const TypeInfo *wanttype);
|
||||
DWORD HashObject (const DObject *obj) const;
|
||||
DWORD AddName (const char *name);
|
||||
DWORD AddName (size_t start); // Name has already been added to storage
|
||||
DWORD FindName (const char *name) const;
|
||||
DWORD FindName (const char *name, size_t bucket) const;
|
||||
|
||||
bool m_Persistent; // meant for persistent storage (disk)?
|
||||
bool m_Loading; // extracting objects?
|
||||
|
@ -168,13 +176,15 @@ protected:
|
|||
DWORD m_ObjectCount; // # of objects currently serialized
|
||||
DWORD m_MaxObjectCount;
|
||||
DWORD m_ClassCount; // # of unique classes currently serialized
|
||||
|
||||
struct TypeMap
|
||||
{
|
||||
const TypeInfo *toCurrent; // maps archive type index to execution type index
|
||||
DWORD toArchive; // maps execution type index to archive type index
|
||||
|
||||
enum { NO_INDEX = 0xffffffff};
|
||||
enum { NO_INDEX = 0xffffffff };
|
||||
} *m_TypeMap;
|
||||
|
||||
struct ObjectMap
|
||||
{
|
||||
const DObject *object;
|
||||
|
@ -182,6 +192,16 @@ protected:
|
|||
} *m_ObjectMap;
|
||||
size_t m_ObjectHash[EObjectHashSize];
|
||||
|
||||
struct NameMap
|
||||
{
|
||||
DWORD StringStart; // index into m_NameStorage
|
||||
DWORD HashNext; // next in hash bucket
|
||||
enum { NO_INDEX = 0xffffffff };
|
||||
};
|
||||
TArray<NameMap> m_Names;
|
||||
TArray<char> m_NameStorage;
|
||||
size_t m_NameHash[EObjectHashSize];
|
||||
|
||||
private:
|
||||
FArchive (const FArchive &src) {}
|
||||
void operator= (const FArchive &src) {}
|
1912
src/fmodsound/i_music.cpp
Normal file
1912
src/fmodsound/i_music.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -40,4 +40,4 @@ bool I_SetSongPosition (long handle, int order);
|
|||
// Is the song still playing?
|
||||
bool I_QrySongPlaying (long handle);
|
||||
|
||||
#endif //__I_MUSIC_H__
|
||||
#endif //__I_MUSIC_H__
|
|
@ -1,12 +1,17 @@
|
|||
/* i_sound.cpp: System interface for sound, uses fmod.dll
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "resource.h"
|
||||
extern HWND Window;
|
||||
extern HINSTANCE hInstance;
|
||||
#else
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -46,7 +51,10 @@ static const char *OutputNames[] =
|
|||
"No sound",
|
||||
"Windows Multimedia",
|
||||
"DirectSound",
|
||||
"A3D"
|
||||
"A3D",
|
||||
"OSS (Open Sound System)",
|
||||
"ESD (Enlightenment Sound Daemon)",
|
||||
"ALSA (Advanced Linux Sound Architecture)"
|
||||
};
|
||||
static const char *MixerNames[] =
|
||||
{
|
||||
|
@ -60,7 +68,7 @@ static const char *MixerNames[] =
|
|||
"Quality PPro MMX"
|
||||
};
|
||||
|
||||
EXTERN_CVAR (Int, snd_sfxvolume)
|
||||
EXTERN_CVAR (Float, snd_sfxvolume)
|
||||
CVAR (Int, snd_samplerate, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Int, snd_buffersize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Int, snd_driver, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
@ -69,7 +77,7 @@ CVAR (Bool, snd_3d, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
// killough 2/21/98: optionally use varying pitched sounds
|
||||
CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE)
|
||||
#define PITCH(f,x) (*snd_pitched ? ((f)*(x))/128 : (f))
|
||||
#define PITCH(f,x) (snd_pitched ? ((f)*(x))/128 : (f))
|
||||
|
||||
// Maps sfx channels onto FMOD channels
|
||||
static struct ChanMap
|
||||
|
@ -484,26 +492,32 @@ void UncheckSound (sfxinfo_t *sfx, BOOL looped)
|
|||
//
|
||||
// SFX API
|
||||
//
|
||||
|
||||
void I_SetSfxVolume (int volume)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CVAR snd_sfxvolume
|
||||
//
|
||||
// Maximum volume of a sound effect.
|
||||
//==========================================================================
|
||||
|
||||
CUSTOM_CVAR (Float, snd_sfxvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
{
|
||||
// volume range is 0-15, but FMOD wants 0-255
|
||||
FSOUND_SetSFXMasterVolume ((volume << 4) | volume);
|
||||
// FMOD apparently resets absolute volume channels when setting master vol
|
||||
snd_musicvolume.Callback ();
|
||||
if (self < 0.f)
|
||||
self = 0.f;
|
||||
else if (self > 1.f)
|
||||
self = 1.f;
|
||||
else
|
||||
{
|
||||
FSOUND_SetSFXMasterVolume ((int)(self * 255.f));
|
||||
// FMOD apparently resets absolute volume channels when setting master vol
|
||||
snd_musicvolume.Callback ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Starting a sound means adding it
|
||||
// to the current list of active sounds
|
||||
// in the internal channels.
|
||||
// As the SFX info struct contains
|
||||
// e.g. a pointer to the raw data,
|
||||
// it is ignored.
|
||||
//
|
||||
// vol range is 0-255
|
||||
// sep range is 0-255, -1 for surround, -2 for full vol middle
|
||||
//
|
||||
long I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel, BOOL looping)
|
||||
{
|
||||
if (_nosound)
|
||||
|
@ -739,6 +753,7 @@ void I_LoadSound (sfxinfo_t *sfx)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// [RH] Dialog procedure for the error dialog that appears if FMOD
|
||||
// could not be initialized for some reason.
|
||||
BOOL CALLBACK InitBoxCallback (HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -757,6 +772,7 @@ BOOL CALLBACK InitBoxCallback (HWND hwndDlg, UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char FModLog (char success)
|
||||
{
|
||||
|
@ -773,8 +789,16 @@ static char FModLog (char success)
|
|||
|
||||
void I_InitSound ()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static const FSOUND_OUTPUTTYPES outtypes[2] =
|
||||
{ FSOUND_OUTPUT_DSOUND, FSOUND_OUTPUT_WINMM };
|
||||
const int maxtrynum = 2;
|
||||
#else
|
||||
static const FSOUND_OUTPUTTYPES outtypes[3] =
|
||||
{ FSOUND_OUTPUT_DSOUND, FSOUND_OUTPUT_WINMM, FSOUND_OUTPUT_DSOUND };
|
||||
{ FSOUND_OUTPUT_ALSA, FSOUND_OUTPUT_OSS, FSOUND_OUTPUT_ESD };
|
||||
const int maxtrynum = 3;
|
||||
#endif
|
||||
bool trya3d = false;
|
||||
|
||||
/* Get command line options: */
|
||||
_nosound = !!Args.CheckParm ("-nosfx") || !!Args.CheckParm ("-nosound");
|
||||
|
@ -786,35 +810,52 @@ void I_InitSound ()
|
|||
|
||||
int outindex;
|
||||
int trynum;
|
||||
bool trya3d = false;
|
||||
|
||||
if (stricmp (*snd_output, "dsound") == 0)
|
||||
#ifdef _WIN32
|
||||
if (stricmp (snd_output, "dsound") == 0)
|
||||
{
|
||||
outindex = 0;
|
||||
}
|
||||
else if (stricmp (*snd_output, "winmm") == 0)
|
||||
else if (stricmp (snd_output, "winmm") == 0)
|
||||
{
|
||||
outindex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
outindex = (OSPlatform == os_WinNT) ? 1 : 0;
|
||||
if (*snd_3d || stricmp (*snd_output, "a3d") == 0)
|
||||
if (stricmp (snd_output, "a3d") == 0)
|
||||
{
|
||||
trya3d = true;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
if (stricmp (snd_output, "oss") == 0)
|
||||
{
|
||||
outindex = 2;
|
||||
}
|
||||
else if (stricmp (snd_output, "esd") == 0 ||
|
||||
stricmp (snd_output, "esound") == 0)
|
||||
{
|
||||
outindex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
outindex = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
Printf ("I_InitSound: Initializing FMOD\n");
|
||||
#ifdef _WIN32
|
||||
FSOUND_SetHWND (Window);
|
||||
#endif
|
||||
|
||||
while (!_nosound)
|
||||
{
|
||||
trynum = 0;
|
||||
while (trynum < 2)
|
||||
while (trynum < maxtrynum)
|
||||
{
|
||||
long outtype = trya3d ? FSOUND_OUTPUT_A3D
|
||||
: outtypes[outindex+trynum];
|
||||
: outtypes[(outindex+trynum) % maxtrynum];
|
||||
|
||||
Printf (" Setting %s output", OutputNames[outtype]);
|
||||
FModLog (FSOUND_SetOutput (outtype));
|
||||
|
@ -828,12 +869,12 @@ void I_InitSound ()
|
|||
}
|
||||
else
|
||||
{
|
||||
trynum++;
|
||||
++trynum;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Printf (" Setting driver %d", *snd_driver);
|
||||
FModLog (FSOUND_SetDriver (*snd_driver));
|
||||
FModLog (FSOUND_SetDriver (snd_driver));
|
||||
if (FSOUND_GetOutput() != outtype)
|
||||
{
|
||||
Printf (" Output changed to %s\n Trying driver 0",
|
||||
|
@ -842,14 +883,15 @@ void I_InitSound ()
|
|||
FModLog (FSOUND_SetDriver (0));
|
||||
}
|
||||
// FSOUND_GetDriverCaps (FSOUND_GetDriver(), &DriverCaps);
|
||||
if (*snd_buffersize)
|
||||
if (snd_buffersize)
|
||||
{
|
||||
Printf (" Setting buffer size %d", *snd_buffersize);
|
||||
FModLog (FSOUND_SetBufferSize (*snd_buffersize));
|
||||
FModLog (FSOUND_SetBufferSize (snd_buffersize));
|
||||
}
|
||||
//FSOUND_SetMinHardwareChannels (32);
|
||||
Printf (" Initialization");
|
||||
if (!FModLog (FSOUND_Init (*snd_samplerate, 64, 0)))
|
||||
if (!FModLog (FSOUND_Init (snd_samplerate, 64,
|
||||
FSOUND_INIT_USEDEFAULTMIDISYNTH)))
|
||||
{
|
||||
if (trya3d)
|
||||
{
|
||||
|
@ -869,6 +911,7 @@ void I_InitSound ()
|
|||
{ // Initialized successfully
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
// If sound cannot be initialized, give the user some options.
|
||||
switch (DialogBox (hInstance,
|
||||
MAKEINTRESOURCE(IDD_FMODINITFAILED),
|
||||
|
@ -883,13 +926,17 @@ void I_InitSound ()
|
|||
exit (0);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
Printf ("Sound init failed. Using nosound.\n");
|
||||
_nosound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!_nosound)
|
||||
{
|
||||
Enable_FSOUND_IO_Loader ();
|
||||
OutputType = FSOUND_GetOutput ();
|
||||
if (*snd_3d)
|
||||
if (snd_3d)
|
||||
{
|
||||
Sound3D = true;
|
||||
//FSOUND_Reverb_SetEnvironment (FSOUND_PRESET_GENERIC);
|
||||
|
@ -904,6 +951,7 @@ void I_InitSound ()
|
|||
{
|
||||
Sound3D = false;
|
||||
}
|
||||
snd_sfxvolume.Callback ();
|
||||
|
||||
static bool didthis = false;
|
||||
if (!didthis)
|
|
@ -23,7 +23,11 @@
|
|||
#ifndef __I_SOUND__
|
||||
#define __I_SOUND__
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
|
|
@ -239,7 +239,7 @@ void A_BrainExplode (AActor *self)
|
|||
void A_BrainDie (AActor *self)
|
||||
{
|
||||
// [RH] If noexit, then don't end the level.
|
||||
if ((*deathmatch || *alwaysapplydmflags) && (*dmflags & DF_NO_EXIT))
|
||||
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
|
||||
return;
|
||||
|
||||
G_ExitLevel (0);
|
||||
|
@ -337,7 +337,7 @@ ABossTarget *DBrainState::GetTarget ()
|
|||
{
|
||||
Easy = !Easy;
|
||||
|
||||
if (*gameskill <= sk_easy && !Easy)
|
||||
if (gameskill <= sk_easy && !Easy)
|
||||
return NULL;
|
||||
|
||||
ABossTarget *target;
|
|
@ -49,7 +49,7 @@ const char *AInvulnerabilitySphere::PickupMessage ()
|
|||
|
||||
bool AInvulnerabilitySphere::ShouldRespawn ()
|
||||
{
|
||||
return Super::ShouldRespawn () && (*dmflags & DF_RESPAWN_SUPER);
|
||||
return Super::ShouldRespawn () && (dmflags & DF_RESPAWN_SUPER);
|
||||
}
|
||||
|
||||
// Soulsphere --------------------------------------------------------------
|
||||
|
@ -172,7 +172,7 @@ public:
|
|||
}
|
||||
virtual bool ShouldRespawn ()
|
||||
{
|
||||
return Super::ShouldRespawn () && (*dmflags & DF_RESPAWN_SUPER);
|
||||
return Super::ShouldRespawn () && (dmflags & DF_RESPAWN_SUPER);
|
||||
}
|
||||
protected:
|
||||
virtual bool TryPickup (AActor *toucher)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue