diff --git a/programs/games/doom/trunk/d_main.c b/programs/games/doom/trunk/d_main.c index a7f3d109d3..2d712e99ff 100644 --- a/programs/games/doom/trunk/d_main.c +++ b/programs/games/doom/trunk/d_main.c @@ -436,7 +436,7 @@ void D_DoomLoop (void) S_UpdateSounds (players[consoleplayer].mo);// move positional sounds D_Display (); -// I_UpdateSound(); + // I_UpdateSound(); XXX(105); } } @@ -1120,8 +1120,8 @@ void D_DoomMain (void) printf ("D_CheckNetGame: Checking network game status.\n\r"); D_CheckNetGame (); -// printf ("S_Init: Setting up sound.\n\r"); -// S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); + printf ("S_Init: Setting up sound.\n\r"); + S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); printf ("HU_Init: Setting up heads up display.\n\r"); HU_Init (); diff --git a/programs/games/doom/trunk/h/doomdata.h b/programs/games/doom/trunk/h/doomdata.h index bab5e00604..968532bc53 100644 --- a/programs/games/doom/trunk/h/doomdata.h +++ b/programs/games/doom/trunk/h/doomdata.h @@ -42,25 +42,25 @@ // to provide a complete scene geometry description. enum { - ML_LABEL, // A separator, name, ExMx or MAPxx - ML_THINGS, // Monsters, items.. - ML_LINEDEFS, // LineDefs, from editing - ML_SIDEDEFS, // SideDefs, from editing - ML_VERTEXES, // Vertices, edited and BSP splits generated - ML_SEGS, // LineSegs, from LineDefs split by BSP - ML_SSECTORS, // SubSectors, list of LineSegs - ML_NODES, // BSP nodes - ML_SECTORS, // Sectors, from editing - ML_REJECT, // LUT, sector-sector visibility - ML_BLOCKMAP // LUT, motion clipping, walls/grid element + ML_LABEL, // A separator, name, ExMx or MAPxx + ML_THINGS, // Monsters, items.. + ML_LINEDEFS, // LineDefs, from editing + ML_SIDEDEFS, // SideDefs, from editing + ML_VERTEXES, // Vertices, edited and BSP splits generated + ML_SEGS, // LineSegs, from LineDefs split by BSP + ML_SSECTORS, // SubSectors, list of LineSegs + ML_NODES, // BSP nodes + ML_SECTORS, // Sectors, from editing + ML_REJECT, // LUT, sector-sector visibility + ML_BLOCKMAP // LUT, motion clipping, walls/grid element }; // A single Vertex. typedef struct { - short x; - short y; + short x; + short y; } mapvertex_t; @@ -68,13 +68,13 @@ typedef struct // by setting textures and offsets. typedef struct { - short textureoffset; - short rowoffset; - char toptexture[8]; - char bottomtexture[8]; - char midtexture[8]; + short textureoffset; + short rowoffset; + char toptexture[8]; + char bottomtexture[8]; + char midtexture[8]; // Front sector, towards viewer. - short sector; + short sector; } mapsidedef_t; @@ -83,13 +83,13 @@ typedef struct // to the BSP builder. typedef struct { - short v1; - short v2; - short flags; - short special; - short tag; + short v1; + short v2; + short flags; + short special; + short tag; // sidenum[1] will be -1 if one sided - short sidenum[2]; + short sidenum[2]; } maplinedef_t; @@ -98,14 +98,14 @@ typedef struct // // Solid, is an obstacle. -#define ML_BLOCKING 1 +#define ML_BLOCKING 1 // Blocks monsters only. -#define ML_BLOCKMONSTERS 2 +#define ML_BLOCKMONSTERS 2 // Backside will not be present at all // if not two sided. -#define ML_TWOSIDED 4 +#define ML_TWOSIDED 4 // If a texture is pegged, the texture will have // the end exposed to air held constant at the @@ -117,44 +117,44 @@ typedef struct // top and bottom textures (use next to windows). // upper texture unpegged -#define ML_DONTPEGTOP 8 +#define ML_DONTPEGTOP 8 // lower texture unpegged -#define ML_DONTPEGBOTTOM 16 +#define ML_DONTPEGBOTTOM 16 // In AutoMap: don't map as two sided: IT'S A SECRET! -#define ML_SECRET 32 +#define ML_SECRET 32 // Sound rendering: don't let sound cross two of these. -#define ML_SOUNDBLOCK 64 +#define ML_SOUNDBLOCK 64 // Don't draw on the automap at all. -#define ML_DONTDRAW 128 +#define ML_DONTDRAW 128 // Set if already seen, thus drawn in automap. -#define ML_MAPPED 256 +#define ML_MAPPED 256 // Sector definition, from editing. -typedef struct +typedef struct { - short floorheight; - short ceilingheight; - char floorpic[8]; - char ceilingpic[8]; - short lightlevel; - short special; - short tag; + short floorheight; + short ceilingheight; + char floorpic[8]; + char ceilingpic[8]; + short lightlevel; + short special; + short tag; } mapsector_t; // SubSector, as generated by BSP. typedef struct { - short numsegs; + short numsegs; // Index of first one, segs are stored sequentially. - short firstseg; + short firstseg; } mapsubsector_t; @@ -162,12 +162,12 @@ typedef struct // using partition lines selected by BSP builder. typedef struct { - short v1; - short v2; - short angle; - short linedef; - short side; - short offset; + short v1; + short v2; + short angle; + short linedef; + short side; + short offset; } mapseg_t; @@ -175,23 +175,23 @@ typedef struct // BSP node structure. // Indicate a leaf. -#define NF_SUBSECTOR 0x8000 +#define NF_SUBSECTOR 0x8000 typedef struct { // Partition line from (x,y) to x+dx,y+dy) - short x; - short y; - short dx; - short dy; + short x; + short y; + short dx; + short dy; // Bounding box for each child, // clip against view frustum. - short bbox[2][4]; + short bbox[2][4]; // If NF_SUBSECTOR its a subsector, // else it's a node of another subtree. - unsigned short children[2]; + unsigned short children[2]; } mapnode_t; @@ -202,18 +202,18 @@ typedef struct // plus skill/visibility flags and attributes. typedef struct { - short x; - short y; - short angle; - short type; - short options; + short x; + short y; + short angle; + short type; + short options; } mapthing_t; -#endif // __DOOMDATA__ +#endif // __DOOMDATA__ //----------------------------------------------------------------------------- // // $Log:$ diff --git a/programs/games/doom/trunk/h/r_defs.h b/programs/games/doom/trunk/h/r_defs.h index eee14c11d9..a023840c80 100644 --- a/programs/games/doom/trunk/h/r_defs.h +++ b/programs/games/doom/trunk/h/r_defs.h @@ -23,7 +23,7 @@ #ifndef __R_DEFS__ #define __R_DEFS__ - +#include "doomtype.h" // Screenwidth. #include "doomdef.h" diff --git a/programs/games/doom/trunk/i_sound.c b/programs/games/doom/trunk/i_sound.c index bf4c58561b..32388f0f6e 100644 --- a/programs/games/doom/trunk/i_sound.c +++ b/programs/games/doom/trunk/i_sound.c @@ -1,671 +1,685 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// $Log:$ -// -// DESCRIPTION: -// System interface for sound. -// -//----------------------------------------------------------------------------- - -static const char -rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $"; - -#include -#include -#include - -#include - -#include - -#include - -// Timer stuff. Experimental. -#include -#include - -#include "z_zone.h" - -#include "i_system.h" -#include "i_sound.h" -#include "m_argv.h" -#include "m_misc.h" -#include "w_wad.h" - -#include "doomdef.h" - -// The number of internal mixing channels, -// the samples calculated for each mixing step, -// the size of the 16bit, 2 hardware channel (stereo) -// mixing buffer, and the samplerate of the raw data. - - -// Needed for calling the actual sound output. -#define SAMPLECOUNT 512 -#define NUM_CHANNELS 16 -// It is 2 for 16bit, and 2 for two channels. -#define BUFMUL 4 -#define MIXBUFFERSIZE (SAMPLECOUNT*BUFMUL) - -#define SAMPLERATE 11025 // Hz -#define SAMPLESIZE 2 // 16bit - -// The actual lengths of all sound effects. -int lengths[NUMSFX]; - -// The actual output device. -int audio_fd; - -// The global mixing buffer. -// Basically, samples from all active internal channels -// are modifed and added, and stored in the buffer -// that is submitted to the audio device. -signed short mixbuffer[MIXBUFFERSIZE]; - - -// The channel step amount... -unsigned int channelstep[NUM_CHANNELS]; -// ... and a 0.16 bit remainder of last step. -unsigned int channelstepremainder[NUM_CHANNELS]; - - -// The channel data pointers, start and end. -unsigned char* channels[NUM_CHANNELS]; -unsigned char* channelsend[NUM_CHANNELS]; - - -// Time/gametic that the channel started playing, -// used to determine oldest, which automatically -// has lowest priority. -// In case number of active sounds exceeds -// available channels. -int channelstart[NUM_CHANNELS]; - -// The sound in channel handles, -// determined on registration, -// might be used to unregister/stop/modify, -// currently unused. -int channelhandles[NUM_CHANNELS]; - -// SFX id of the playing sound effect. -// Used to catch duplicates (like chainsaw). -int channelids[NUM_CHANNELS]; - -// Pitch to stepping lookup, unused. -int steptable[256]; - -// Volume lookups. -int vol_lookup[128*256]; - -// Hardware left and right channel volume lookup. -int* channelleftvol_lookup[NUM_CHANNELS]; -int* channelrightvol_lookup[NUM_CHANNELS]; - - -// -// This function loads the sound data from the WAD lump, -// for single sound. -// -void* getsfx (char* sfxname, int* len) -{ - unsigned char* sfx; - unsigned char* paddedsfx; - int i; - int size; - int paddedsize; - char name[20]; - int sfxlump; - - - // Get the sound data from the WAD, allocate lump - // in zone memory. - sprintf(name, "ds%s", sfxname); - - // Now, there is a severe problem with the - // sound handling, in it is not (yet/anymore) - // gamemode aware. That means, sounds from - // DOOM II will be requested even with DOOM - // shareware. - // The sound list is wired into sounds.c, - // which sets the external variable. - // I do not do runtime patches to that - // variable. Instead, we will use a - // default sound for replacement. - if ( W_CheckNumForName(name) == -1 ) - sfxlump = W_GetNumForName("dspistol"); - else - sfxlump = W_GetNumForName(name); - - size = W_LumpLength( sfxlump ); - - // Debug. - // fprintf( stderr, "." ); - //fprintf( stderr, " -loading %s (lump %d, %d bytes)\n", - // sfxname, sfxlump, size ); - //fflush( stderr ); - - sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC ); - - // Pads the sound effect out to the mixing buffer size. - // The original realloc would interfere with zone memory. - paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT; - - // Allocate from zone memory. - paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 ); - // ddt: (unsigned char *) realloc(sfx, paddedsize+8); - // This should interfere with zone memory handling, - // which does not kick in in the soundserver. - - // Now copy and pad. - memcpy( paddedsfx, sfx, size ); - for (i=size ; i> 16); ///(256*256); - seperation = seperation - 257; - rightvol = - volume - ((volume*seperation*seperation) >> 16); - - // Sanity check, clamp volume. - if (rightvol < 0 || rightvol > 127) - I_Error("rightvol out of bounds"); - - if (leftvol < 0 || leftvol > 127) - I_Error("leftvol out of bounds"); - - // Get the proper lookup table piece - // for this volume level??? - channelleftvol_lookup[slot] = &vol_lookup[leftvol*256]; - channelrightvol_lookup[slot] = &vol_lookup[rightvol*256]; - - // Preserve sound SFX id, - // e.g. for avoiding duplicates of chainsaw. - channelids[slot] = sfxid; - - // You tell me. - return rc; -} - -// -// SFX API -// Note: this was called by S_Init. -// However, whatever they did in the -// old DPMS based DOS version, this -// were simply dummies in the Linux -// version. -// See soundserver initdata(). -// -void I_SetChannels() -{ - // Init internal lookups (raw data, mixing buffer, channels). - // This function sets up internal lookups used during - // the mixing process. - int i; - int j; - - int* steptablemid = steptable + 128; - - // Okay, reset internal mixing channels to zero. - for (i=0; iname); - return W_GetNumForName(namebuf); -} - -// -// 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. -// As our sound handling does not handle -// priority, it is ignored. -// Pitching (that is, increased speed of playback) -// -int I_StartSound(int id, int vol, int sep, - int pitch, int priority ) -{ - // Returns a handle (not used). - id = addsfx( id, vol, steptable[pitch], sep ); - return id; -} - -void I_StopSound (int handle) -{ - // You need the handle returned by StartSound. - // Would be looping all channels, - // tracking down the handle, - // an setting the channel to zero. - - // UNUSED. - handle = 0; -} - - -int I_SoundIsPlaying(int handle) -{ - // Ouch. - return gametic < handle; -} - -// -// This function loops all active (internal) sound -// channels, retrieves a given number of samples -// from the raw sound data, modifies it according -// to the current (internal) channel parameters, -// mixes the per channel samples into the global -// mixbuffer, clamping it to the allowed range, -// and sets up everything for transferring the -// contents of the mixbuffer to the (two) -// hardware channels (left and right, that is). -// -// This function currently supports only 16bit. -// -void I_UpdateSound( void ) -{ - - // Mix current sound data. - // Data, from raw sound, for right and left. - register unsigned int sample; - register int dl; - register int dr; - - // Pointers in global mixbuffer, left, right, end. - signed short* leftout; - signed short* rightout; - signed short* leftend; - // Step in mixbuffer, left and right, thus two. - int step; - - // Mixing channel index. - int chan; - - // Left and right channel - // are in global mixbuffer, alternating. - leftout = mixbuffer; - rightout = mixbuffer+1; - step = 2; - - // Determine end, for left channel only - // (right channel is implicit). - leftend = mixbuffer + SAMPLECOUNT*step; - - // Mix sounds into the mixing buffer. - // Loop over step*SAMPLECOUNT, - // that is 512 values for two channels. - while (leftout != leftend) - { - // Reset left/right value. - dl = 0; - dr = 0; - - // Love thy L2 chache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for ( chan = 0; chan < NUM_CHANNELS; chan++ ) - { - // Check channel, if active. - if (channels[ chan ]) - { - // Get the raw data from the channel. - sample = *channels[ chan ]; - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - dl += channelleftvol_lookup[ chan ][sample]; - dr += channelrightvol_lookup[ chan ][sample]; - - channelstepremainder[ chan ] += channelstep[ chan ]; - - channels[ chan ] += channelstepremainder[ chan ] >> 16; - - channelstepremainder[ chan ] &= 65536-1; - - // Check whether we are done. - if (channels[ chan ] >= channelsend[ chan ]) - channels[ chan ] = 0; - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - // if (dl > 127) *leftout = 127; - // else if (dl < -128) *leftout = -128; - // else *leftout = dl; - - if (dl > 0x7fff) - *leftout = 0x7fff; - else if (dl < -0x8000) - *leftout = -0x8000; - else - *leftout = dl; - - // Same for right hardware channel. - if (dr > 0x7fff) - *rightout = 0x7fff; - else if (dr < -0x8000) - *rightout = -0x8000; - else - *rightout = dr; - - // Increment current pointers in mixbuffer. - leftout += step; - rightout += step; - } - // I_SubmitSound(mixbuffer); -} - - -// -// This would be used to write out the mixbuffer -// during each game loop update. -// Updates sound buffer and audio device at runtime. -// It is called during Timer interrupt with SNDINTR. -// Mixing now done synchronous, and -// only output be done asynchronous? -// -//void I_SubmitSound(void) -//{ - // Write it to DSP device. -// write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL); -//} - - -void I_UpdateSoundParams(int handle, int vol, int sep, int pitch) -{ - // I fail too see that this is used. - // Would be using the handle to identify - // on which channel the sound might be active, - // and resetting the channel parameters. - - // UNUSED. - handle = vol = sep = pitch = 0; -} - -void I_ShutdownSound(void) -{ - // Wait till all pending sounds are finished. - int done = 0; - int i; - - // FIXME (below). - printf( "I_ShutdownSound: NOT finishing pending sounds\n"); - - while ( !done ) - { - for( i=0 ; i<8 && !channels[i] ; i++); - - // FIXME. No proper channel output. - //if (i==8) - done=1; - } - return; -} - -void I_InitSound() -{ int i; - - printf("I_InitSound: "); - - for (i=1 ; idata; - lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; - } - } - - printf( " pre-cached all sound data\n"); - - // Now initialize mixbuffer with zero. - for ( i = 0; i< MIXBUFFERSIZE; i++ ) - mixbuffer[i] = 0; - - // Finished initialization. - printf("I_InitSound: sound module ready\n"); - -} - - -// -// MUSIC API. -// Still no music done. -// Remains. Dummies. -// -void I_InitMusic(void) { } -void I_ShutdownMusic(void) { } - -static int looping=0; -static int musicdies=-1; - -void I_PlaySong(int handle, int looping) -{ - // UNUSED. - handle = looping = 0; - musicdies = gametic + TICRATE*30; -} - -void I_PauseSong (int handle) -{ - // UNUSED. - handle = 0; -} - -void I_ResumeSong (int handle) -{ - // UNUSED. - handle = 0; -} - -void I_StopSong(int handle) -{ - // UNUSED. - handle = 0; - - looping = 0; - musicdies = 0; -} - -void I_UnRegisterSong(int handle) -{ - // UNUSED. - handle = 0; -} - -int I_RegisterSong(void* data) -{ - // UNUSED. - data = NULL; - - return 1; -} - -// Is the song playing? -int I_QrySongPlaying(int handle) -{ - // UNUSED. - handle = 0; - return looping || musicdies > gametic; -} - - -// Interrupt handler. -void I_HandleSoundTimer( int ignore ) -{ - - // UNUSED, but required. - ignore = 0; - return; -} - +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// System interface for sound. +// +//----------------------------------------------------------------------------- + +static const char +rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $"; + +#include +#include +#include + +#include + +#include + +#include + +// Timer stuff. Experimental. +#include +#include + +#include "z_zone.h" + +#include "i_system.h" +#include "i_sound.h" +#include "m_argv.h" +#include "m_misc.h" +#include "w_wad.h" + +#include "doomdef.h" + +#include "kolibri.h" + +// The number of internal mixing channels, +// the samples calculated for each mixing step, +// the size of the 16bit, 2 hardware channel (stereo) +// mixing buffer, and the samplerate of the raw data. + + +// Needed for calling the actual sound output. +#define SAMPLECOUNT 8192 +#define NUM_CHANNELS 16 +// It is 2 for 16bit, and 2 for two channels. +#define BUFMUL 4 +#define MIXBUFFERSIZE (SAMPLECOUNT*BUFMUL) + +#define SAMPLERATE 11025 // Hz +#define SAMPLESIZE 2 // 16bit + +// The actual lengths of all sound effects. +int lengths[NUMSFX]; + +// The actual output device. +int audio_fd; + +// The global mixing buffer. +// Basically, samples from all active internal channels +// are modifed and added, and stored in the buffer +// that is submitted to the audio device. +signed short mixbuffer[MIXBUFFERSIZE]; + + +// The channel step amount... +unsigned int channelstep[NUM_CHANNELS]; +// ... and a 0.16 bit remainder of last step. +unsigned int channelstepremainder[NUM_CHANNELS]; + + +// The channel data pointers, start and end. +unsigned char* channels[NUM_CHANNELS]; +unsigned char* channelsend[NUM_CHANNELS]; + + +// Time/gametic that the channel started playing, +// used to determine oldest, which automatically +// has lowest priority. +// In case number of active sounds exceeds +// available channels. +int channelstart[NUM_CHANNELS]; + +// The sound in channel handles, +// determined on registration, +// might be used to unregister/stop/modify, +// currently unused. +int channelhandles[NUM_CHANNELS]; + +// SFX id of the playing sound effect. +// Used to catch duplicates (like chainsaw). +int channelids[NUM_CHANNELS]; + +// Pitch to stepping lookup, unused. +int steptable[256]; + +// Volume lookups. +int vol_lookup[128*256]; + +// Hardware left and right channel volume lookup. +int* channelleftvol_lookup[NUM_CHANNELS]; +int* channelrightvol_lookup[NUM_CHANNELS]; + + +// +// This function loads the sound data from the WAD lump, +// for single sound. +// +void* getsfx (char* sfxname, int* len) +{ + unsigned char* sfx; + unsigned char* paddedsfx; + int i; + int size; + int paddedsize; + char name[20]; + int sfxlump; + + + // Get the sound data from the WAD, allocate lump + // in zone memory. + sprintf(name, "ds%s", sfxname); + + // Now, there is a severe problem with the + // sound handling, in it is not (yet/anymore) + // gamemode aware. That means, sounds from + // DOOM II will be requested even with DOOM + // shareware. + // The sound list is wired into sounds.c, + // which sets the external variable. + // I do not do runtime patches to that + // variable. Instead, we will use a + // default sound for replacement. + if ( W_CheckNumForName(name) == -1 ) + sfxlump = W_GetNumForName("dspistol"); + else + sfxlump = W_GetNumForName(name); + + size = W_LumpLength( sfxlump ); + + // Debug. + // fprintf( stderr, "." ); + //fprintf( stderr, " -loading %s (lump %d, %d bytes)\n", + // sfxname, sfxlump, size ); + //fflush( stderr ); + + sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC ); + + // Pads the sound effect out to the mixing buffer size. + // The original realloc would interfere with zone memory. + paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT; + + // Allocate from zone memory. + paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 ); + // ddt: (unsigned char *) realloc(sfx, paddedsize+8); + // This should interfere with zone memory handling, + // which does not kick in in the soundserver. + + // Now copy and pad. + memcpy( paddedsfx, sfx, size ); + for (i=size ; i> 16); ///(256*256); + seperation = seperation - 257; + rightvol = + volume - ((volume*seperation*seperation) >> 16); + + // Sanity check, clamp volume. + if (rightvol < 0 || rightvol > 127) + I_Error("rightvol out of bounds"); + + if (leftvol < 0 || leftvol > 127) + I_Error("leftvol out of bounds"); + + // Get the proper lookup table piece + // for this volume level??? + channelleftvol_lookup[slot] = &vol_lookup[leftvol*256]; + channelrightvol_lookup[slot] = &vol_lookup[rightvol*256]; + + // Preserve sound SFX id, + // e.g. for avoiding duplicates of chainsaw. + channelids[slot] = sfxid; + + // You tell me. + return rc; +} + +// +// SFX API +// Note: this was called by S_Init. +// However, whatever they did in the +// old DPMS based DOS version, this +// were simply dummies in the Linux +// version. +// See soundserver initdata(). +// +void I_SetChannels() +{ + // Init internal lookups (raw data, mixing buffer, channels). + // This function sets up internal lookups used during + // the mixing process. + int i; + int j; + + int* steptablemid = steptable + 128; + + // Okay, reset internal mixing channels to zero. + for (i=0; iname); + return W_GetNumForName(namebuf); +} + +// +// 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. +// As our sound handling does not handle +// priority, it is ignored. +// Pitching (that is, increased speed of playback) +// +int I_StartSound(int id, int vol, int sep, + int pitch, int priority ) +{ + // Returns a handle (not used). + id = addsfx( id, vol, steptable[pitch], sep ); + return id; +} + +void I_StopSound (int handle) +{ + // You need the handle returned by StartSound. + // Would be looping all channels, + // tracking down the handle, + // an setting the channel to zero. + + // UNUSED. + handle = 0; +} + + +int I_SoundIsPlaying(int handle) +{ + // Ouch. + return gametic < handle; +} + +// +// This function loops all active (internal) sound +// channels, retrieves a given number of samples +// from the raw sound data, modifies it according +// to the current (internal) channel parameters, +// mixes the per channel samples into the global +// mixbuffer, clamping it to the allowed range, +// and sets up everything for transferring the +// contents of the mixbuffer to the (two) +// hardware channels (left and right, that is). +// +// This function currently supports only 16bit. +// + +extern DWORD hMixBuff[4]; +extern int mix_ptr; + +void I_UpdateSound( void ) +{ + + // Mix current sound data. + // Data, from raw sound, for right and left. + register unsigned int sample; + register int dl; + register int dr; + + // Pointers in global mixbuffer, left, right, end. + signed short* leftout; + signed short* rightout; + signed short* leftend; + // Step in mixbuffer, left and right, thus two. + int step; + + // Mixing channel index. + int chan; + int i; + int flags; + flags = 0; + + // Left and right channel + // are in global mixbuffer, alternating. + leftout = mixbuffer; + rightout = mixbuffer+1; + step = 2; + + // Determine end, for left channel only + // (right channel is implicit). + leftend = mixbuffer + SAMPLECOUNT*step; + + // Mix sounds into the mixing buffer. + // Loop over step*SAMPLECOUNT, + // that is 512 values for two channels. + for (i=0; i < 8192; i++) + { + // Reset left/right value. + dl = 0; + dr = 0; + + // Love thy L2 chache - made this a loop. + // Now more channels could be set at compile time + // as well. Thus loop those channels. + for ( chan = 0; chan < NUM_CHANNELS; chan++ ) + { + // Check channel, if active. + if (channels[ chan ]) + { + flags=1; + + // Get the raw data from the channel. + sample = *channels[ chan ]; + // Add left and right part + // for this channel (sound) + // to the current data. + // Adjust volume accordingly. + dl += channelleftvol_lookup[ chan ][sample]; + dr += channelrightvol_lookup[ chan ][sample]; + + channelstepremainder[ chan ] += channelstep[ chan ]; + + channels[ chan ] += channelstepremainder[ chan ] >> 16; + + channelstepremainder[ chan ] &= 65536-1; + + // Check whether we are done. + if (channels[ chan ] >= channelsend[ chan ]) + channels[ chan ] = 0; + } + } + + // Clamp to range. Left hardware channel. + // Has been char instead of short. + // if (dl > 127) *leftout = 127; + // else if (dl < -128) *leftout = -128; + // else *leftout = dl; + + if (dl > 0x7fff) + *leftout = 0x7fff; + else if (dl < -0x8000) + *leftout = -0x8000; + else + *leftout = dl; + + // Same for right hardware channel. + if (dr > 0x7fff) + *rightout = 0x7fff; + else if (dr < -0x8000) + *rightout = -0x8000; + else + *rightout = dr; + + // Increment current pointers in mixbuffer. + leftout += step; + rightout += step; + } + if(flags) + { WaveOut(hMixBuff[mix_ptr],(char*)&mixbuffer[0],32768); + mix_ptr= (mix_ptr+1)&3; + }; +} + + +// +// This would be used to write out the mixbuffer +// during each game loop update. +// Updates sound buffer and audio device at runtime. +// It is called during Timer interrupt with SNDINTR. +// Mixing now done synchronous, and +// only output be done asynchronous? +// +//void I_SubmitSound(void) +//{ + // Write it to DSP device. +// write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL); +//} + + +void I_UpdateSoundParams(int handle, int vol, int sep, int pitch) +{ + // I fail too see that this is used. + // Would be using the handle to identify + // on which channel the sound might be active, + // and resetting the channel parameters. + + // UNUSED. + handle = vol = sep = pitch = 0; +} + +void I_ShutdownSound(void) +{ + // Wait till all pending sounds are finished. + int done = 0; + int i; + + // FIXME (below). + printf( "I_ShutdownSound: NOT finishing pending sounds\n"); + + while ( !done ) + { + for( i=0 ; i<8 && !channels[i] ; i++); + + // FIXME. No proper channel output. + //if (i==8) + done=1; + } + return; +} + +void I_InitSound() +{ int i; + + printf("I_InitSound: "); + + for (i=1 ; idata; + lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; + } + } + + printf( " pre-cached all sound data\n"); + + // Now initialize mixbuffer with zero. + for ( i = 0; i< MIXBUFFERSIZE; i++ ) + mixbuffer[i] = 0; + + // Finished initialization. + printf("I_InitSound: sound module ready\n"); + +} + + +// +// MUSIC API. +// Still no music done. +// Remains. Dummies. +// +void I_InitMusic(void) { } +void I_ShutdownMusic(void) { } + +static int looping=0; +static int musicdies=-1; + +void I_PlaySong(int handle, int looping) +{ + // UNUSED. + handle = looping = 0; + musicdies = gametic + TICRATE*30; +} + +void I_PauseSong (int handle) +{ + // UNUSED. + handle = 0; +} + +void I_ResumeSong (int handle) +{ + // UNUSED. + handle = 0; +} + +void I_StopSong(int handle) +{ + // UNUSED. + handle = 0; + + looping = 0; + musicdies = 0; +} + +void I_UnRegisterSong(int handle) +{ + // UNUSED. + handle = 0; +} + +int I_RegisterSong(void* data) +{ + // UNUSED. + data = NULL; + + return 1; +} + +// Is the song playing? +int I_QrySongPlaying(int handle) +{ + // UNUSED. + handle = 0; + return looping || musicdies > gametic; +} + + +// Interrupt handler. +void I_HandleSoundTimer( int ignore ) +{ + + // UNUSED, but required. + ignore = 0; + return; +} + diff --git a/programs/games/doom/trunk/i_system.c b/programs/games/doom/trunk/i_system.c index 9f58c66a6f..86454ed103 100644 --- a/programs/games/doom/trunk/i_system.c +++ b/programs/games/doom/trunk/i_system.c @@ -99,7 +99,7 @@ int I_GetTime (void) void I_Init (void) { I_InitGraphics(); - // I_InitSound(); + I_InitSound(); } // diff --git a/programs/games/doom/trunk/m_fixed.c b/programs/games/doom/trunk/m_fixed.c index 4e0792d603..2f120f5ca0 100644 --- a/programs/games/doom/trunk/m_fixed.c +++ b/programs/games/doom/trunk/m_fixed.c @@ -17,7 +17,7 @@ // $Log:$ // // DESCRIPTION: -// Fixed point implementation. +// Fixed point implementation. // //----------------------------------------------------------------------------- @@ -42,8 +42,8 @@ rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $"; fixed_t FixedMul -( fixed_t a, - fixed_t b ) +( fixed_t a, + fixed_t b ) { return ((long long) a * (long long) b) >> FRACBITS; } @@ -56,11 +56,11 @@ FixedMul fixed_t FixedDiv -( fixed_t a, - fixed_t b ) +( fixed_t a, + fixed_t b ) { if ( (abs(a)>>14) >= abs(b)) - return (a^b)<0 ? MININT : MAXINT; + return (a^b)<0 ? MININT : MAXINT; return FixedDiv2 (a,b); } @@ -68,8 +68,8 @@ FixedDiv fixed_t FixedDiv2 -( fixed_t a, - fixed_t b ) +( fixed_t a, + fixed_t b ) { #if 0 long long c; @@ -82,6 +82,6 @@ FixedDiv2 c = ((double)a) / ((double)b) * FRACUNIT; if (c >= 2147483648.0 || c < -2147483648.0) - I_Error("FixedDiv: divide by zero"); + I_Error("FixedDiv: divide by zero"); return (fixed_t) c; } diff --git a/programs/games/doom/trunk/p_map.c b/programs/games/doom/trunk/p_map.c index aba15d8084..c521739edc 100644 --- a/programs/games/doom/trunk/p_map.c +++ b/programs/games/doom/trunk/p_map.c @@ -17,8 +17,8 @@ // $Log:$ // // DESCRIPTION: -// Movement, collision handling. -// Shooting and aiming. +// Movement, collision handling. +// Shooting and aiming. // //----------------------------------------------------------------------------- @@ -27,6 +27,7 @@ rcsid[] = "$Id: p_map.c,v 1.5 1997/02/03 22:45:11 b1 Exp $"; #include +#include "doomtype.h" #include "m_bbox.h" #include "m_random.h" #include "i_system.h" @@ -43,31 +44,31 @@ rcsid[] = "$Id: p_map.c,v 1.5 1997/02/03 22:45:11 b1 Exp $"; #include "sounds.h" -fixed_t tmbbox[4]; -mobj_t* tmthing; -int tmflags; -fixed_t tmx; -fixed_t tmy; +fixed_t tmbbox[4]; +mobj_t* tmthing; +int tmflags; +fixed_t tmx; +fixed_t tmy; // If "floatok" true, move would be ok // if within "tmfloorz - tmceilingz". -boolean floatok; +boolean floatok; -fixed_t tmfloorz; -fixed_t tmceilingz; -fixed_t tmdropoffz; +fixed_t tmfloorz; +fixed_t tmceilingz; +fixed_t tmdropoffz; // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls -line_t* ceilingline; +line_t* ceilingline; // keep track of special lines as they are hit, // but don't process them until the move is proven valid -#define MAXSPECIALCROSS 8 +#define MAXSPECIALCROSS 8 -line_t* spechit[MAXSPECIALCROSS]; -int numspechit; +line_t* spechit[MAXSPECIALCROSS]; +int numspechit; @@ -80,30 +81,30 @@ int numspechit; // boolean PIT_StompThing (mobj_t* thing) { - fixed_t blockdist; - + fixed_t blockdist; + if (!(thing->flags & MF_SHOOTABLE) ) - return true; - + return true; + blockdist = thing->radius + tmthing->radius; if ( abs(thing->x - tmx) >= blockdist - || abs(thing->y - tmy) >= blockdist ) + || abs(thing->y - tmy) >= blockdist ) { - // didn't hit it - return true; + // didn't hit it + return true; } // don't clip against self if (thing == tmthing) - return true; + return true; // monsters don't stomp things except on boss level if ( !tmthing->player && gamemap != 30) - return false; - + return false; + P_DamageMobj (thing, tmthing, tmthing, 10000); - + return true; } @@ -113,26 +114,26 @@ boolean PIT_StompThing (mobj_t* thing) // boolean P_TeleportMove -( mobj_t* thing, - fixed_t x, - fixed_t y ) +( mobj_t* thing, + fixed_t x, + fixed_t y ) { - int xl; - int xh; - int yl; - int yh; - int bx; - int by; + int xl; + int xh; + int yl; + int yh; + int bx; + int by; - subsector_t* newsubsec; + subsector_t* newsubsec; // kill anything occupying the position tmthing = thing; tmflags = thing->flags; - + tmx = x; tmy = y; - + tmbbox[BOXTOP] = y + tmthing->radius; tmbbox[BOXBOTTOM] = y - tmthing->radius; tmbbox[BOXRIGHT] = x + tmthing->radius; @@ -147,7 +148,7 @@ P_TeleportMove // will adjust them. tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmceilingz = newsubsec->sector->ceilingheight; - + validcount++; numspechit = 0; @@ -158,21 +159,21 @@ P_TeleportMove yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; for (bx=xl ; bx<=xh ; bx++) - for (by=yl ; by<=yh ; by++) - if (!P_BlockThingsIterator(bx,by,PIT_StompThing)) - return false; + for (by=yl ; by<=yh ; by++) + if (!P_BlockThingsIterator(bx,by,PIT_StompThing)) + return false; // the move is ok, // so link the thing into its new position P_UnsetThingPosition (thing); thing->floorz = tmfloorz; - thing->ceilingz = tmceilingz; + thing->ceilingz = tmceilingz; thing->x = x; thing->y = y; P_SetThingPosition (thing); - + return true; } @@ -189,14 +190,14 @@ P_TeleportMove boolean PIT_CheckLine (line_t* ld) { if (tmbbox[BOXRIGHT] <= ld->bbox[BOXLEFT] - || tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] - || tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] - || tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP] ) - return true; + || tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] + || tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP] ) + return true; if (P_BoxOnLineSide (tmbbox, ld) != -1) - return true; - + return true; + // A line has been hit // The moving thing's destination position will cross @@ -209,38 +210,38 @@ boolean PIT_CheckLine (line_t* ld) // could be crossed in either order. if (!ld->backsector) - return false; // one sided line - + return false; // one sided line + if (!(tmthing->flags & MF_MISSILE) ) { - if ( ld->flags & ML_BLOCKING ) - return false; // explicitly blocking everything + if ( ld->flags & ML_BLOCKING ) + return false; // explicitly blocking everything - if ( !tmthing->player && ld->flags & ML_BLOCKMONSTERS ) - return false; // block monsters only + if ( !tmthing->player && ld->flags & ML_BLOCKMONSTERS ) + return false; // block monsters only } // set openrange, opentop, openbottom - P_LineOpening (ld); - + P_LineOpening (ld); + // adjust floor / ceiling heights if (opentop < tmceilingz) { - tmceilingz = opentop; - ceilingline = ld; + tmceilingz = opentop; + ceilingline = ld; } if (openbottom > tmfloorz) - tmfloorz = openbottom; + tmfloorz = openbottom; if (lowfloor < tmdropoffz) - tmdropoffz = lowfloor; - + tmdropoffz = lowfloor; + // if contacted a special line, add it to the list if (ld->special) { - spechit[numspechit] = ld; - numspechit++; + spechit[numspechit] = ld; + numspechit++; } return true; @@ -251,94 +252,94 @@ boolean PIT_CheckLine (line_t* ld) // boolean PIT_CheckThing (mobj_t* thing) { - fixed_t blockdist; - boolean solid; - int damage; - + fixed_t blockdist; + boolean solid; + int damage; + if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) )) - return true; + return true; blockdist = thing->radius + tmthing->radius; if ( abs(thing->x - tmx) >= blockdist - || abs(thing->y - tmy) >= blockdist ) + || abs(thing->y - tmy) >= blockdist ) { - // didn't hit it - return true; + // didn't hit it + return true; } // don't clip against self if (thing == tmthing) - return true; + return true; // check for skulls slamming into things if (tmthing->flags & MF_SKULLFLY) { - damage = ((P_Random()%8)+1)*tmthing->info->damage; - - P_DamageMobj (thing, tmthing, tmthing, damage); - - tmthing->flags &= ~MF_SKULLFLY; - tmthing->momx = tmthing->momy = tmthing->momz = 0; - - P_SetMobjState (tmthing, tmthing->info->spawnstate); - - return false; // stop moving + damage = ((P_Random()%8)+1)*tmthing->info->damage; + + P_DamageMobj (thing, tmthing, tmthing, damage); + + tmthing->flags &= ~MF_SKULLFLY; + tmthing->momx = tmthing->momy = tmthing->momz = 0; + + P_SetMobjState (tmthing, tmthing->info->spawnstate); + + return false; // stop moving } // missiles can hit other things if (tmthing->flags & MF_MISSILE) { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z+tmthing->height < thing->z) - return true; // underneath - - if (tmthing->target && ( - tmthing->target->type == thing->type || - (tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)|| - (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) ) - { - // Don't hit same species as originator. - if (thing == tmthing->target) - return true; + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z+tmthing->height < thing->z) + return true; // underneath + + if (tmthing->target && ( + tmthing->target->type == thing->type || + (tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)|| + (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) ) + { + // Don't hit same species as originator. + if (thing == tmthing->target) + return true; - if (thing->type != MT_PLAYER) - { - // Explode, but do no damage. - // Let players missile other players. - return false; - } - } - - if (! (thing->flags & MF_SHOOTABLE) ) - { - // didn't do any damage - return !(thing->flags & MF_SOLID); - } - - // damage / explode - damage = ((P_Random()%8)+1)*tmthing->info->damage; - P_DamageMobj (thing, tmthing, tmthing->target, damage); + if (thing->type != MT_PLAYER) + { + // Explode, but do no damage. + // Let players missile other players. + return false; + } + } + + if (! (thing->flags & MF_SHOOTABLE) ) + { + // didn't do any damage + return !(thing->flags & MF_SOLID); + } + + // damage / explode + damage = ((P_Random()%8)+1)*tmthing->info->damage; + P_DamageMobj (thing, tmthing, tmthing->target, damage); - // don't traverse any more - return false; + // don't traverse any more + return false; } // check for special pickup if (thing->flags & MF_SPECIAL) { - solid = thing->flags&MF_SOLID; - if (tmflags&MF_PICKUP) - { - // can remove thing - P_TouchSpecialThing (thing, tmthing); - } - return !solid; + solid = thing->flags&MF_SOLID; + if (tmflags&MF_PICKUP) + { + // can remove thing + P_TouchSpecialThing (thing, tmthing); + } + return !solid; } - + return !(thing->flags & MF_SOLID); } @@ -373,24 +374,24 @@ boolean PIT_CheckThing (mobj_t* thing) // boolean P_CheckPosition -( mobj_t* thing, - fixed_t x, - fixed_t y ) +( mobj_t* thing, + fixed_t x, + fixed_t y ) { - int xl; - int xh; - int yl; - int yh; - int bx; - int by; - subsector_t* newsubsec; + int xl; + int xh; + int yl; + int yh; + int bx; + int by; + subsector_t* newsubsec; tmthing = thing; tmflags = thing->flags; - + tmx = x; tmy = y; - + tmbbox[BOXTOP] = y + tmthing->radius; tmbbox[BOXBOTTOM] = y - tmthing->radius; tmbbox[BOXRIGHT] = x + tmthing->radius; @@ -405,12 +406,12 @@ P_CheckPosition // will adjust them. tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmceilingz = newsubsec->sector->ceilingheight; - + validcount++; numspechit = 0; if ( tmflags & MF_NOCLIP ) - return true; + return true; // Check things first, possibly picking things up. // The bounding box is extended by MAXRADIUS @@ -423,9 +424,9 @@ P_CheckPosition yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; for (bx=xl ; bx<=xh ; bx++) - for (by=yl ; by<=yh ; by++) - if (!P_BlockThingsIterator(bx,by,PIT_CheckThing)) - return false; + for (by=yl ; by<=yh ; by++) + if (!P_BlockThingsIterator(bx,by,PIT_CheckThing)) + return false; // check lines xl = (tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT; @@ -434,9 +435,9 @@ P_CheckPosition yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; for (bx=xl ; bx<=xh ; bx++) - for (by=yl ; by<=yh ; by++) - if (!P_BlockLinesIterator (bx,by,PIT_CheckLine)) - return false; + for (by=yl ; by<=yh ; by++) + if (!P_BlockLinesIterator (bx,by,PIT_CheckLine)) + return false; return true; } @@ -449,38 +450,38 @@ P_CheckPosition // boolean P_TryMove -( mobj_t* thing, - fixed_t x, - fixed_t y ) +( mobj_t* thing, + fixed_t x, + fixed_t y ) { - fixed_t oldx; - fixed_t oldy; - int side; - int oldside; - line_t* ld; + fixed_t oldx; + fixed_t oldy; + int side; + int oldside; + line_t* ld; floatok = false; if (!P_CheckPosition (thing, x, y)) - return false; // solid wall or thing + return false; // solid wall or thing if ( !(thing->flags & MF_NOCLIP) ) { - if (tmceilingz - tmfloorz < thing->height) - return false; // doesn't fit + if (tmceilingz - tmfloorz < thing->height) + return false; // doesn't fit - floatok = true; - - if ( !(thing->flags&MF_TELEPORT) - &&tmceilingz - thing->z < thing->height) - return false; // mobj must lower itself to fit + floatok = true; + + if ( !(thing->flags&MF_TELEPORT) + &&tmceilingz - thing->z < thing->height) + return false; // mobj must lower itself to fit - if ( !(thing->flags&MF_TELEPORT) - && tmfloorz - thing->z > 24*FRACUNIT ) - return false; // too big a step up + if ( !(thing->flags&MF_TELEPORT) + && tmfloorz - thing->z > 24*FRACUNIT ) + return false; // too big a step up - if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT)) - && tmfloorz - tmdropoffz > 24*FRACUNIT ) - return false; // don't stand over a dropoff + if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT)) + && tmfloorz - tmdropoffz > 24*FRACUNIT ) + return false; // don't stand over a dropoff } // the move is ok, @@ -490,7 +491,7 @@ P_TryMove oldx = thing->x; oldy = thing->y; thing->floorz = tmfloorz; - thing->ceilingz = tmceilingz; + thing->ceilingz = tmceilingz; thing->x = x; thing->y = y; @@ -499,18 +500,18 @@ P_TryMove // if any special lines were hit, do the effect if (! (thing->flags&(MF_TELEPORT|MF_NOCLIP)) ) { - while (numspechit--) - { - // see if the line was crossed - ld = spechit[numspechit]; - side = P_PointOnLineSide (thing->x, thing->y, ld); - oldside = P_PointOnLineSide (oldx, oldy, ld); - if (side != oldside) - { - if (ld->special) - P_CrossSpecialLine (ld-lines, oldside, thing); - } - } + while (numspechit--) + { + // see if the line was crossed + ld = spechit[numspechit]; + side = P_PointOnLineSide (thing->x, thing->y, ld); + oldside = P_PointOnLineSide (oldx, oldy, ld); + if (side != oldside) + { + if (ld->special) + P_CrossSpecialLine (ld-lines, oldside, thing); + } + } } return true; @@ -529,31 +530,31 @@ P_TryMove // boolean P_ThingHeightClip (mobj_t* thing) { - boolean onfloor; - + boolean onfloor; + onfloor = (thing->z == thing->floorz); - - P_CheckPosition (thing, thing->x, thing->y); + + P_CheckPosition (thing, thing->x, thing->y); // what about stranding a monster partially off an edge? - + thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; - + if (onfloor) { - // walking monsters rise and fall with the floor - thing->z = thing->floorz; + // walking monsters rise and fall with the floor + thing->z = thing->floorz; } else { - // don't adjust a floating monster unless forced to - if (thing->z+thing->height > thing->ceilingz) - thing->z = thing->ceilingz - thing->height; + // don't adjust a floating monster unless forced to + if (thing->z+thing->height > thing->ceilingz) + thing->z = thing->ceilingz - thing->height; } - + if (thing->ceilingz - thing->floorz < thing->height) - return false; - + return false; + return true; } @@ -563,16 +564,16 @@ boolean P_ThingHeightClip (mobj_t* thing) // SLIDE MOVE // Allows the player to slide along any angled walls. // -fixed_t bestslidefrac; -fixed_t secondslidefrac; +fixed_t bestslidefrac; +fixed_t secondslidefrac; -line_t* bestslideline; -line_t* secondslideline; +line_t* bestslideline; +line_t* secondslideline; -mobj_t* slidemo; +mobj_t* slidemo; -fixed_t tmxmove; -fixed_t tmymove; +fixed_t tmxmove; +fixed_t tmymove; @@ -583,50 +584,50 @@ fixed_t tmymove; // void P_HitSlideLine (line_t* ld) { - int side; + int side; - angle_t lineangle; - angle_t moveangle; - angle_t deltaangle; + angle_t lineangle; + angle_t moveangle; + angle_t deltaangle; - fixed_t movelen; - fixed_t newlen; - - + fixed_t movelen; + fixed_t newlen; + + if (ld->slopetype == ST_HORIZONTAL) { - tmymove = 0; - return; + tmymove = 0; + return; } if (ld->slopetype == ST_VERTICAL) { - tmxmove = 0; - return; + tmxmove = 0; + return; } - + side = P_PointOnLineSide (slidemo->x, slidemo->y, ld); - + lineangle = R_PointToAngle2 (0,0, ld->dx, ld->dy); if (side == 1) - lineangle += ANG180; + lineangle += ANG180; moveangle = R_PointToAngle2 (0,0, tmxmove, tmymove); deltaangle = moveangle-lineangle; if (deltaangle > ANG180) - deltaangle += ANG180; - // I_Error ("SlideLine: ang>ANG180"); + deltaangle += ANG180; + // I_Error ("SlideLine: ang>ANG180"); lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - + movelen = P_AproxDistance (tmxmove, tmymove); newlen = FixedMul (movelen, finecosine[deltaangle]); - tmxmove = FixedMul (newlen, finecosine[lineangle]); - tmymove = FixedMul (newlen, finesine[lineangle]); + tmxmove = FixedMul (newlen, finecosine[lineangle]); + tmymove = FixedMul (newlen, finesine[lineangle]); } @@ -635,50 +636,50 @@ void P_HitSlideLine (line_t* ld) // boolean PTR_SlideTraverse (intercept_t* in) { - line_t* li; - + line_t* li; + if (!in->isaline) - I_Error ("PTR_SlideTraverse: not a line?"); - + I_Error ("PTR_SlideTraverse: not a line?"); + li = in->d.line; if ( ! (li->flags & ML_TWOSIDED) ) { - if (P_PointOnLineSide (slidemo->x, slidemo->y, li)) - { - // don't hit the back side - return true; - } - goto isblocking; + if (P_PointOnLineSide (slidemo->x, slidemo->y, li)) + { + // don't hit the back side + return true; + } + goto isblocking; } // set openrange, opentop, openbottom P_LineOpening (li); if (openrange < slidemo->height) - goto isblocking; // doesn't fit - + goto isblocking; // doesn't fit + if (opentop - slidemo->z < slidemo->height) - goto isblocking; // mobj is too high + goto isblocking; // mobj is too high if (openbottom - slidemo->z > 24*FRACUNIT ) - goto isblocking; // too big a step up + goto isblocking; // too big a step up // this line doesn't block movement - return true; - + return true; + // the line does block movement, // see if it is closer than best so far - isblocking: + isblocking: if (in->frac < bestslidefrac) { - secondslidefrac = bestslidefrac; - secondslideline = bestslideline; - bestslidefrac = in->frac; - bestslideline = li; + secondslidefrac = bestslidefrac; + secondslideline = bestslideline; + bestslidefrac = in->frac; + bestslideline = li; } - - return false; // stop + + return false; // stop } @@ -694,73 +695,73 @@ boolean PTR_SlideTraverse (intercept_t* in) // void P_SlideMove (mobj_t* mo) { - fixed_t leadx; - fixed_t leady; - fixed_t trailx; - fixed_t traily; - fixed_t newx; - fixed_t newy; - int hitcount; - + fixed_t leadx; + fixed_t leady; + fixed_t trailx; + fixed_t traily; + fixed_t newx; + fixed_t newy; + int hitcount; + slidemo = mo; hitcount = 0; retry: if (++hitcount == 3) - goto stairstep; // don't loop forever + goto stairstep; // don't loop forever // trace along the three leading corners if (mo->momx > 0) { - leadx = mo->x + mo->radius; - trailx = mo->x - mo->radius; + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; } else { - leadx = mo->x - mo->radius; - trailx = mo->x + mo->radius; + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; } - + if (mo->momy > 0) { - leady = mo->y + mo->radius; - traily = mo->y - mo->radius; + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; } else { - leady = mo->y - mo->radius; - traily = mo->y + mo->radius; + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; } - + bestslidefrac = FRACUNIT+1; - + P_PathTraverse ( leadx, leady, leadx+mo->momx, leady+mo->momy, - PT_ADDLINES, PTR_SlideTraverse ); + PT_ADDLINES, PTR_SlideTraverse ); P_PathTraverse ( trailx, leady, trailx+mo->momx, leady+mo->momy, - PT_ADDLINES, PTR_SlideTraverse ); + PT_ADDLINES, PTR_SlideTraverse ); P_PathTraverse ( leadx, traily, leadx+mo->momx, traily+mo->momy, - PT_ADDLINES, PTR_SlideTraverse ); + PT_ADDLINES, PTR_SlideTraverse ); // move up to the wall if (bestslidefrac == FRACUNIT+1) { - // the move most have hit the middle, so stairstep + // the move most have hit the middle, so stairstep stairstep: - if (!P_TryMove (mo, mo->x, mo->y + mo->momy)) - P_TryMove (mo, mo->x + mo->momx, mo->y); - return; + if (!P_TryMove (mo, mo->x, mo->y + mo->momy)) + P_TryMove (mo, mo->x + mo->momx, mo->y); + return; } // fudge a bit to make sure it doesn't hit - bestslidefrac -= 0x800; + bestslidefrac -= 0x800; if (bestslidefrac > 0) { - newx = FixedMul (mo->momx, bestslidefrac); - newy = FixedMul (mo->momy, bestslidefrac); - - if (!P_TryMove (mo, mo->x+newx, mo->y+newy)) - goto stairstep; + newx = FixedMul (mo->momx, bestslidefrac); + newy = FixedMul (mo->momy, bestslidefrac); + + if (!P_TryMove (mo, mo->x+newx, mo->y+newy)) + goto stairstep; } // Now continue along the wall. @@ -768,22 +769,22 @@ void P_SlideMove (mobj_t* mo) bestslidefrac = FRACUNIT-(bestslidefrac+0x800); if (bestslidefrac > FRACUNIT) - bestslidefrac = FRACUNIT; + bestslidefrac = FRACUNIT; if (bestslidefrac <= 0) - return; + return; tmxmove = FixedMul (mo->momx, bestslidefrac); tmymove = FixedMul (mo->momy, bestslidefrac); - P_HitSlideLine (bestslideline); // clip the moves + P_HitSlideLine (bestslideline); // clip the moves mo->momx = tmxmove; mo->momy = tmymove; - + if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove)) { - goto retry; + goto retry; } } @@ -791,21 +792,21 @@ void P_SlideMove (mobj_t* mo) // // P_LineAttack // -mobj_t* linetarget; // who got hit (or NULL) -mobj_t* shootthing; +mobj_t* linetarget; // who got hit (or NULL) +mobj_t* shootthing; // Height if not aiming up or down // ???: use slope for monsters? -fixed_t shootz; +fixed_t shootz; -int la_damage; -fixed_t attackrange; +int la_damage; +fixed_t attackrange; -fixed_t aimslope; +fixed_t aimslope; // slopes to top and bottom of target -extern fixed_t topslope; -extern fixed_t bottomslope; +extern fixed_t topslope; +extern fixed_t bottomslope; // @@ -815,81 +816,81 @@ extern fixed_t bottomslope; boolean PTR_AimTraverse (intercept_t* in) { - line_t* li; - mobj_t* th; - fixed_t slope; - fixed_t thingtopslope; - fixed_t thingbottomslope; - fixed_t dist; - + line_t* li; + mobj_t* th; + fixed_t slope; + fixed_t thingtopslope; + fixed_t thingbottomslope; + fixed_t dist; + if (in->isaline) { - li = in->d.line; - - if ( !(li->flags & ML_TWOSIDED) ) - return false; // stop - - // Crosses a two sided line. - // A two sided line will restrict - // the possible target ranges. - P_LineOpening (li); - - if (openbottom >= opentop) - return false; // stop - - dist = FixedMul (attackrange, in->frac); + li = in->d.line; + + if ( !(li->flags & ML_TWOSIDED) ) + return false; // stop + + // Crosses a two sided line. + // A two sided line will restrict + // the possible target ranges. + P_LineOpening (li); + + if (openbottom >= opentop) + return false; // stop + + dist = FixedMul (attackrange, in->frac); - if (li->frontsector->floorheight != li->backsector->floorheight) - { - slope = FixedDiv (openbottom - shootz , dist); - if (slope > bottomslope) - bottomslope = slope; - } - - if (li->frontsector->ceilingheight != li->backsector->ceilingheight) - { - slope = FixedDiv (opentop - shootz , dist); - if (slope < topslope) - topslope = slope; - } - - if (topslope <= bottomslope) - return false; // stop - - return true; // shot continues + if (li->frontsector->floorheight != li->backsector->floorheight) + { + slope = FixedDiv (openbottom - shootz , dist); + if (slope > bottomslope) + bottomslope = slope; + } + + if (li->frontsector->ceilingheight != li->backsector->ceilingheight) + { + slope = FixedDiv (opentop - shootz , dist); + if (slope < topslope) + topslope = slope; + } + + if (topslope <= bottomslope) + return false; // stop + + return true; // shot continues } // shoot a thing th = in->d.thing; if (th == shootthing) - return true; // can't shoot self + return true; // can't shoot self if (!(th->flags&MF_SHOOTABLE)) - return true; // corpse or something + return true; // corpse or something // check angles to see if the thing can be aimed at dist = FixedMul (attackrange, in->frac); thingtopslope = FixedDiv (th->z+th->height - shootz , dist); if (thingtopslope < bottomslope) - return true; // shot over the thing + return true; // shot over the thing thingbottomslope = FixedDiv (th->z - shootz, dist); if (thingbottomslope > topslope) - return true; // shot under the thing + return true; // shot under the thing // this thing can be hit! if (thingtopslope > topslope) - thingtopslope = topslope; + thingtopslope = topslope; if (thingbottomslope < bottomslope) - thingbottomslope = bottomslope; + thingbottomslope = bottomslope; aimslope = (thingtopslope+thingbottomslope)/2; linetarget = th; - return false; // don't go any farther + return false; // don't go any farther } @@ -898,98 +899,98 @@ PTR_AimTraverse (intercept_t* in) // boolean PTR_ShootTraverse (intercept_t* in) { - fixed_t x; - fixed_t y; - fixed_t z; - fixed_t frac; + fixed_t x; + fixed_t y; + fixed_t z; + fixed_t frac; - line_t* li; + line_t* li; - mobj_t* th; + mobj_t* th; - fixed_t slope; - fixed_t dist; - fixed_t thingtopslope; - fixed_t thingbottomslope; - + fixed_t slope; + fixed_t dist; + fixed_t thingtopslope; + fixed_t thingbottomslope; + if (in->isaline) { - li = in->d.line; - - if (li->special) - P_ShootSpecialLine (shootthing, li); + li = in->d.line; + + if (li->special) + P_ShootSpecialLine (shootthing, li); - if ( !(li->flags & ML_TWOSIDED) ) - goto hitline; - - // crosses a two sided line - P_LineOpening (li); - - dist = FixedMul (attackrange, in->frac); + if ( !(li->flags & ML_TWOSIDED) ) + goto hitline; + + // crosses a two sided line + P_LineOpening (li); + + dist = FixedMul (attackrange, in->frac); - if (li->frontsector->floorheight != li->backsector->floorheight) - { - slope = FixedDiv (openbottom - shootz , dist); - if (slope > aimslope) - goto hitline; - } - - if (li->frontsector->ceilingheight != li->backsector->ceilingheight) - { - slope = FixedDiv (opentop - shootz , dist); - if (slope < aimslope) - goto hitline; - } + if (li->frontsector->floorheight != li->backsector->floorheight) + { + slope = FixedDiv (openbottom - shootz , dist); + if (slope > aimslope) + goto hitline; + } + + if (li->frontsector->ceilingheight != li->backsector->ceilingheight) + { + slope = FixedDiv (opentop - shootz , dist); + if (slope < aimslope) + goto hitline; + } - // shot continues - return true; - - - // hit line + // shot continues + return true; + + + // hit line hitline: - // position a bit closer - frac = in->frac - FixedDiv (4*FRACUNIT,attackrange); - x = trace.x + FixedMul (trace.dx, frac); - y = trace.y + FixedMul (trace.dy, frac); - z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange)); + // position a bit closer + frac = in->frac - FixedDiv (4*FRACUNIT,attackrange); + x = trace.x + FixedMul (trace.dx, frac); + y = trace.y + FixedMul (trace.dy, frac); + z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange)); - if (li->frontsector->ceilingpic == skyflatnum) - { - // don't shoot the sky! - if (z > li->frontsector->ceilingheight) - return false; - - // it's a sky hack wall - if (li->backsector && li->backsector->ceilingpic == skyflatnum) - return false; - } + if (li->frontsector->ceilingpic == skyflatnum) + { + // don't shoot the sky! + if (z > li->frontsector->ceilingheight) + return false; + + // it's a sky hack wall + if (li->backsector && li->backsector->ceilingpic == skyflatnum) + return false; + } - // Spawn bullet puffs. - P_SpawnPuff (x,y,z); - - // don't go any farther - return false; + // Spawn bullet puffs. + P_SpawnPuff (x,y,z); + + // don't go any farther + return false; } // shoot a thing th = in->d.thing; if (th == shootthing) - return true; // can't shoot self + return true; // can't shoot self if (!(th->flags&MF_SHOOTABLE)) - return true; // corpse or something - + return true; // corpse or something + // check angles to see if the thing can be aimed at dist = FixedMul (attackrange, in->frac); thingtopslope = FixedDiv (th->z+th->height - shootz , dist); if (thingtopslope < aimslope) - return true; // shot over the thing + return true; // shot over the thing thingbottomslope = FixedDiv (th->z - shootz, dist); if (thingbottomslope > aimslope) - return true; // shot under the thing + return true; // shot under the thing // hit thing @@ -1003,16 +1004,16 @@ boolean PTR_ShootTraverse (intercept_t* in) // Spawn bullet puffs or blod spots, // depending on target type. if (in->d.thing->flags & MF_NOBLOOD) - P_SpawnPuff (x,y,z); + P_SpawnPuff (x,y,z); else - P_SpawnBlood (x,y,z, la_damage); + P_SpawnBlood (x,y,z, la_damage); if (la_damage) - P_DamageMobj (th, shootthing, shootthing, la_damage); + P_DamageMobj (th, shootthing, shootthing, la_damage); // don't go any farther return false; - + } @@ -1021,13 +1022,13 @@ boolean PTR_ShootTraverse (intercept_t* in) // fixed_t P_AimLineAttack -( mobj_t* t1, - angle_t angle, - fixed_t distance ) +( mobj_t* t1, + angle_t angle, + fixed_t distance ) { - fixed_t x2; - fixed_t y2; - + fixed_t x2; + fixed_t y2; + angle >>= ANGLETOFINESHIFT; shootthing = t1; @@ -1036,19 +1037,19 @@ P_AimLineAttack shootz = t1->z + (t1->height>>1) + 8*FRACUNIT; // can't shoot outside view angles - topslope = 100*FRACUNIT/160; + topslope = 100*FRACUNIT/160; bottomslope = -100*FRACUNIT/160; attackrange = distance; linetarget = NULL; - + P_PathTraverse ( t1->x, t1->y, - x2, y2, - PT_ADDLINES|PT_ADDTHINGS, - PTR_AimTraverse ); - + x2, y2, + PT_ADDLINES|PT_ADDTHINGS, + PTR_AimTraverse ); + if (linetarget) - return aimslope; + return aimslope; return 0; } @@ -1061,15 +1062,15 @@ P_AimLineAttack // void P_LineAttack -( mobj_t* t1, - angle_t angle, - fixed_t distance, - fixed_t slope, - int damage ) +( mobj_t* t1, + angle_t angle, + fixed_t distance, + fixed_t slope, + int damage ) { - fixed_t x2; - fixed_t y2; - + fixed_t x2; + fixed_t y2; + angle >>= ANGLETOFINESHIFT; shootthing = t1; la_damage = damage; @@ -1078,11 +1079,11 @@ P_LineAttack shootz = t1->z + (t1->height>>1) + 8*FRACUNIT; attackrange = distance; aimslope = slope; - + P_PathTraverse ( t1->x, t1->y, - x2, y2, - PT_ADDLINES|PT_ADDTHINGS, - PTR_ShootTraverse ); + x2, y2, + PT_ADDLINES|PT_ADDTHINGS, + PTR_ShootTraverse ); } @@ -1090,32 +1091,32 @@ P_LineAttack // // USE LINES // -mobj_t* usething; +mobj_t* usething; -boolean PTR_UseTraverse (intercept_t* in) +boolean PTR_UseTraverse (intercept_t* in) { - int side; - + int side; + if (!in->d.line->special) { - P_LineOpening (in->d.line); - if (openrange <= 0) - { - S_StartSound (usething, sfx_noway); - - // can't use through a wall - return false; - } - // not a special line, but keep checking - return true ; + P_LineOpening (in->d.line); + if (openrange <= 0) + { + S_StartSound (usething, sfx_noway); + + // can't use through a wall + return false; + } + // not a special line, but keep checking + return true ; } - + side = 0; if (P_PointOnLineSide (usething->x, usething->y, in->d.line) == 1) - side = 1; + side = 1; - // return false; // don't use back side - + // return false; // don't use back side + P_UseSpecialLine (usething, in->d.line, side); // can't use for than one special line in a row @@ -1127,23 +1128,23 @@ boolean PTR_UseTraverse (intercept_t* in) // P_UseLines // Looks for special lines in front of the player to activate. // -void P_UseLines (player_t* player) +void P_UseLines (player_t* player) { - int angle; - fixed_t x1; - fixed_t y1; - fixed_t x2; - fixed_t y2; - + int angle; + fixed_t x1; + fixed_t y1; + fixed_t x2; + fixed_t y2; + usething = player->mo; - + angle = player->mo->angle >> ANGLETOFINESHIFT; x1 = player->mo->x; y1 = player->mo->y; x2 = x1 + (USERANGE>>FRACBITS)*finecosine[angle]; y2 = y1 + (USERANGE>>FRACBITS)*finesine[angle]; - + P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse ); } @@ -1151,9 +1152,9 @@ void P_UseLines (player_t* player) // // RADIUS ATTACK // -mobj_t* bombsource; -mobj_t* bombspot; -int bombdamage; +mobj_t* bombsource; +mobj_t* bombspot; +int bombdamage; // @@ -1163,19 +1164,19 @@ int bombdamage; // boolean PIT_RadiusAttack (mobj_t* thing) { - fixed_t dx; - fixed_t dy; - fixed_t dist; - + fixed_t dx; + fixed_t dy; + fixed_t dist; + if (!(thing->flags & MF_SHOOTABLE) ) - return true; + return true; // Boss spider and cyborg // take no damage from concussion. if (thing->type == MT_CYBORG - || thing->type == MT_SPIDER) - return true; - + || thing->type == MT_SPIDER) + return true; + dx = abs(thing->x - bombspot->x); dy = abs(thing->y - bombspot->y); @@ -1183,15 +1184,15 @@ boolean PIT_RadiusAttack (mobj_t* thing) dist = (dist - thing->radius) >> FRACBITS; if (dist < 0) - dist = 0; + dist = 0; if (dist >= bombdamage) - return true; // out of range + return true; // out of range if ( P_CheckSight (thing, bombspot) ) { - // must be in direct path - P_DamageMobj (thing, bombspot, bombsource, bombdamage - dist); + // must be in direct path + P_DamageMobj (thing, bombspot, bombsource, bombdamage - dist); } return true; @@ -1204,20 +1205,20 @@ boolean PIT_RadiusAttack (mobj_t* thing) // void P_RadiusAttack -( mobj_t* spot, - mobj_t* source, - int damage ) +( mobj_t* spot, + mobj_t* source, + int damage ) { - int x; - int y; + int x; + int y; - int xl; - int xh; - int yl; - int yh; + int xl; + int xh; + int yl; + int yh; - fixed_t dist; - + fixed_t dist; + dist = (damage+MAXRADIUS)<y + dist - bmaporgy)>>MAPBLOCKSHIFT; yl = (spot->y - dist - bmaporgy)>>MAPBLOCKSHIFT; @@ -1226,10 +1227,10 @@ P_RadiusAttack bombspot = spot; bombsource = source; bombdamage = damage; - + for (y=yl ; y<=yh ; y++) - for (x=xl ; x<=xh ; x++) - P_BlockThingsIterator (x, y, PIT_RadiusAttack ); + for (x=xl ; x<=xh ; x++) + P_BlockThingsIterator (x, y, PIT_RadiusAttack ); } @@ -1247,69 +1248,69 @@ P_RadiusAttack // the way it was and call P_ChangeSector again // to undo the changes. // -boolean crushchange; -boolean nofit; +boolean crushchange; +boolean nofit; // // PIT_ChangeSector // -boolean PIT_ChangeSector (mobj_t* thing) +boolean PIT_ChangeSector (mobj_t* thing) { - mobj_t* mo; - + mobj_t* mo; + if (P_ThingHeightClip (thing)) { - // keep checking - return true; + // keep checking + return true; } // crunch bodies to giblets if (thing->health <= 0) { - P_SetMobjState (thing, S_GIBS); + P_SetMobjState (thing, S_GIBS); - thing->flags &= ~MF_SOLID; - thing->height = 0; - thing->radius = 0; + thing->flags &= ~MF_SOLID; + thing->height = 0; + thing->radius = 0; - // keep checking - return true; + // keep checking + return true; } // crunch dropped items if (thing->flags & MF_DROPPED) { - P_RemoveMobj (thing); - - // keep checking - return true; + P_RemoveMobj (thing); + + // keep checking + return true; } if (! (thing->flags & MF_SHOOTABLE) ) { - // assume it is bloody gibs or something - return true; + // assume it is bloody gibs or something + return true; } nofit = true; if (crushchange && !(leveltime&3) ) { - P_DamageMobj(thing,NULL,NULL,10); + P_DamageMobj(thing,NULL,NULL,10); - // spray blood in a random direction - mo = P_SpawnMobj (thing->x, - thing->y, - thing->z + thing->height/2, MT_BLOOD); - - mo->momx = (P_Random() - P_Random ())<<12; - mo->momy = (P_Random() - P_Random ())<<12; + // spray blood in a random direction + mo = P_SpawnMobj (thing->x, + thing->y, + thing->z + thing->height/2, MT_BLOOD); + + mo->momx = (P_Random() - P_Random ())<<12; + mo->momy = (P_Random() - P_Random ())<<12; } - // keep checking (crush other things) - return true; + // keep checking (crush other things) + return true; } @@ -1319,21 +1320,21 @@ boolean PIT_ChangeSector (mobj_t* thing) // boolean P_ChangeSector -( sector_t* sector, - boolean crunch ) +( sector_t* sector, + boolean crunch ) { - int x; - int y; - + int x; + int y; + nofit = false; crushchange = crunch; - + // re-check heights for all things near the moving sector for (x=sector->blockbox[BOXLEFT] ; x<= sector->blockbox[BOXRIGHT] ; x++) - for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++) - P_BlockThingsIterator (x, y, PIT_ChangeSector); - - + for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++) + P_BlockThingsIterator (x, y, PIT_ChangeSector); + + return nofit; } diff --git a/programs/games/doom/trunk/p_telept.c b/programs/games/doom/trunk/p_telept.c index 56ba3d7109..469368a287 100644 --- a/programs/games/doom/trunk/p_telept.c +++ b/programs/games/doom/trunk/p_telept.c @@ -17,7 +17,7 @@ // $Log:$ // // DESCRIPTION: -// Teleportation. +// Teleportation. // //----------------------------------------------------------------------------- @@ -25,7 +25,7 @@ static const char rcsid[] = "$Id: p_telept.c,v 1.3 1997/01/28 22:08:29 b1 Exp $"; - +#include "doomtype.h" #include "doomdef.h" #include "s_sound.h" @@ -46,86 +46,86 @@ rcsid[] = "$Id: p_telept.c,v 1.3 1997/01/28 22:08:29 b1 Exp $"; // int EV_Teleport -( line_t* line, - int side, - mobj_t* thing ) +( line_t* line, + int side, + mobj_t* thing ) { - int i; - int tag; - mobj_t* m; - mobj_t* fog; - unsigned an; - thinker_t* thinker; - sector_t* sector; - fixed_t oldx; - fixed_t oldy; - fixed_t oldz; + int i; + int tag; + mobj_t* m; + mobj_t* fog; + unsigned an; + thinker_t* thinker; + sector_t* sector; + fixed_t oldx; + fixed_t oldy; + fixed_t oldz; // don't teleport missiles if (thing->flags & MF_MISSILE) - return 0; + return 0; // Don't teleport if hit back of line, // so you can get out of teleporter. - if (side == 1) - return 0; + if (side == 1) + return 0; tag = line->tag; for (i = 0; i < numsectors; i++) { - if (sectors[ i ].tag == tag ) - { - thinker = thinkercap.next; - for (thinker = thinkercap.next; - thinker != &thinkercap; - thinker = thinker->next) - { - // not a mobj - if (thinker->function.acp1 != (actionf_p1)P_MobjThinker) - continue; + if (sectors[ i ].tag == tag ) + { + thinker = thinkercap.next; + for (thinker = thinkercap.next; + thinker != &thinkercap; + thinker = thinker->next) + { + // not a mobj + if (thinker->function.acp1 != (actionf_p1)P_MobjThinker) + continue; - m = (mobj_t *)thinker; - - // not a teleportman - if (m->type != MT_TELEPORTMAN ) - continue; + m = (mobj_t *)thinker; + + // not a teleportman + if (m->type != MT_TELEPORTMAN ) + continue; - sector = m->subsector->sector; - // wrong sector - if (sector-sectors != i ) - continue; + sector = m->subsector->sector; + // wrong sector + if (sector-sectors != i ) + continue; - oldx = thing->x; - oldy = thing->y; - oldz = thing->z; - - if (!P_TeleportMove (thing, m->x, m->y)) - return 0; - - thing->z = thing->floorz; //fixme: not needed? - if (thing->player) - thing->player->viewz = thing->z+thing->player->viewheight; - - // spawn teleport fog at source and destination - fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG); - S_StartSound (fog, sfx_telept); - an = m->angle >> ANGLETOFINESHIFT; - fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an] - , thing->z, MT_TFOG); + oldx = thing->x; + oldy = thing->y; + oldz = thing->z; + + if (!P_TeleportMove (thing, m->x, m->y)) + return 0; + + thing->z = thing->floorz; //fixme: not needed? + if (thing->player) + thing->player->viewz = thing->z+thing->player->viewheight; + + // spawn teleport fog at source and destination + fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG); + S_StartSound (fog, sfx_telept); + an = m->angle >> ANGLETOFINESHIFT; + fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an] + , thing->z, MT_TFOG); - // emit sound, where? - S_StartSound (fog, sfx_telept); - - // don't move for a bit - if (thing->player) - thing->reactiontime = 18; + // emit sound, where? + S_StartSound (fog, sfx_telept); + + // don't move for a bit + if (thing->player) + thing->reactiontime = 18; - thing->angle = m->angle; - thing->momx = thing->momy = thing->momz = 0; - return 1; - } - } + thing->angle = m->angle; + thing->momx = thing->momy = thing->momz = 0; + return 1; + } + } } return 0; } diff --git a/programs/games/doom/trunk/r_draw.c b/programs/games/doom/trunk/r_draw.c index 0145044962..770821aa5e 100644 --- a/programs/games/doom/trunk/r_draw.c +++ b/programs/games/doom/trunk/r_draw.c @@ -17,9 +17,9 @@ // $Log:$ // // DESCRIPTION: -// The actual span/column drawing functions. -// Here find the main potential for optimization, -// e.g. inline assembly, different algorithms. +// The actual span/column drawing functions. +// Here find the main potential for optimization, +// e.g. inline assembly, different algorithms. // //----------------------------------------------------------------------------- @@ -27,7 +27,7 @@ static const char rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; - +#include "doomtype.h" #include "doomdef.h" #include "i_system.h" @@ -44,11 +44,11 @@ rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; // ? -#define MAXWIDTH 1120 -#define MAXHEIGHT 832 +#define MAXWIDTH 1120 +#define MAXHEIGHT 832 // status bar height at bottom of screen -#define SBARHEIGHT 32 +#define SBARHEIGHT 32 // // All drawing to the view buffer is accomplished in this file. @@ -60,20 +60,20 @@ rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; // -byte* viewimage; -int viewwidth; -int scaledviewwidth; -int viewheight; -int viewwindowx; -int viewwindowy; -byte* ylookup[MAXHEIGHT]; -int columnofs[MAXWIDTH]; +byte* viewimage; +int viewwidth; +int scaledviewwidth; +int viewheight; +int viewwindowx; +int viewwindowy; +byte* ylookup[MAXHEIGHT]; +int columnofs[MAXWIDTH]; // Color tables for different players, // translate a limited part to another // (color ramps used for suit colors). // -byte translations[3][256]; +byte translations[3][256]; @@ -82,18 +82,18 @@ byte translations[3][256]; // R_DrawColumn // Source is the top of the column to scale. // -lighttable_t* dc_colormap; -int dc_x; -int dc_yl; -int dc_yh; -fixed_t dc_iscale; -fixed_t dc_texturemid; +lighttable_t* dc_colormap; +int dc_x; +int dc_yl; +int dc_yh; +fixed_t dc_iscale; +fixed_t dc_texturemid; // first pixel in a column (possibly virtual) -byte* dc_source; +byte* dc_source; // just for profiling -int dccount; +int dccount; // // A column is a vertical slice/span from a wall texture that, @@ -104,22 +104,22 @@ int dccount; // void R_DrawColumn (void) { - int count; - byte* dest; - fixed_t frac; - fixed_t fracstep; + int count; + byte* dest; + fixed_t frac; + fixed_t fracstep; count = dc_yh - dc_yl; // Zero length, column does not exceed a pixel. if (count < 0) - return; - + return; + #ifdef RANGECHECK if ((unsigned)dc_x >= SCREENWIDTH - || dc_yl < 0 - || dc_yh >= SCREENHEIGHT) - I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); + || dc_yl < 0 + || dc_yh >= SCREENHEIGHT) + I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); #endif // Framebuffer destination address. @@ -137,13 +137,13 @@ void R_DrawColumn (void) // This is as fast as it gets. do { - // Re-map color indices from wall texture column - // using a lighting/special effects LUT. - *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; - - dest += SCREENWIDTH; - frac += fracstep; - + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; + + dest += SCREENWIDTH; + frac += fracstep; + } while (count--); } @@ -154,55 +154,55 @@ void R_DrawColumn (void) #if 0 void R_DrawColumn (void) { - int count; - byte* source; - byte* dest; - byte* colormap; + int count; + byte* source; + byte* dest; + byte* colormap; - unsigned frac; - unsigned fracstep; - unsigned fracstep2; - unsigned fracstep3; - unsigned fracstep4; + unsigned frac; + unsigned fracstep; + unsigned fracstep2; + unsigned fracstep3; + unsigned fracstep4; count = dc_yh - dc_yl + 1; source = dc_source; - colormap = dc_colormap; + colormap = dc_colormap; dest = ylookup[dc_yl] + columnofs[dc_x]; - + fracstep = dc_iscale<<9; frac = (dc_texturemid + (dc_yl-centery)*dc_iscale)<<9; fracstep2 = fracstep+fracstep; fracstep3 = fracstep2+fracstep; fracstep4 = fracstep3+fracstep; - + while (count >= 8) { - dest[0] = colormap[source[frac>>25]]; - dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; - dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; - dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]]; - - frac += fracstep4; + dest[0] = colormap[source[frac>>25]]; + dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; + dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; + dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]]; + + frac += fracstep4; - dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; - dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; - dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; - dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]]; + dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; + dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; + dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; + dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]]; - frac += fracstep4; - dest += SCREENWIDTH*8; - count -= 8; + frac += fracstep4; + dest += SCREENWIDTH*8; + count -= 8; } - + while (count > 0) { - *dest = colormap[source[frac>>25]]; - dest += SCREENWIDTH; - frac += fracstep; - count--; + *dest = colormap[source[frac>>25]]; + dest += SCREENWIDTH; + frac += fracstep; + count--; } } #endif @@ -210,27 +210,27 @@ void R_DrawColumn (void) void R_DrawColumnLow (void) { - int count; - byte* dest; - byte* dest2; - fixed_t frac; - fixed_t fracstep; + int count; + byte* dest; + byte* dest2; + fixed_t frac; + fixed_t fracstep; count = dc_yh - dc_yl; // Zero length. if (count < 0) - return; - + return; + #ifdef RANGECHECK if ((unsigned)dc_x >= SCREENWIDTH - || dc_yl < 0 - || dc_yh >= SCREENHEIGHT) + || dc_yl < 0 + || dc_yh >= SCREENHEIGHT) { - - I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); + + I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); } - // dccount++; + // dccount++; #endif // Blocky mode, need to multiply by 2. dc_x <<= 1; @@ -243,11 +243,11 @@ void R_DrawColumnLow (void) do { - // Hack. Does not work corretly. - *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; - dest += SCREENWIDTH; - dest2 += SCREENWIDTH; - frac += fracstep; + // Hack. Does not work corretly. + *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; + dest += SCREENWIDTH; + dest2 += SCREENWIDTH; + frac += fracstep; } while (count--); } @@ -256,11 +256,11 @@ void R_DrawColumnLow (void) // // Spectre/Invisibility. // -#define FUZZTABLE 50 -#define FUZZOFF (SCREENWIDTH) +#define FUZZTABLE 50 +#define FUZZOFF (SCREENWIDTH) -int fuzzoffset[FUZZTABLE] = +int fuzzoffset[FUZZTABLE] = { FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, @@ -271,7 +271,7 @@ int fuzzoffset[FUZZTABLE] = FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF }; -int fuzzpos = 0; +int fuzzpos = 0; // @@ -284,32 +284,32 @@ int fuzzpos = 0; // void R_DrawFuzzColumn (void) { - int count; - byte* dest; - fixed_t frac; - fixed_t fracstep; + int count; + byte* dest; + fixed_t frac; + fixed_t fracstep; // Adjust borders. Low... if (!dc_yl) - dc_yl = 1; + dc_yl = 1; // .. and high. if (dc_yh == viewheight-1) - dc_yh = viewheight - 2; - + dc_yh = viewheight - 2; + count = dc_yh - dc_yl; // Zero length. if (count < 0) - return; + return; #ifdef RANGECHECK if ((unsigned)dc_x >= SCREENWIDTH - || dc_yl < 0 || dc_yh >= SCREENHEIGHT) + || dc_yl < 0 || dc_yh >= SCREENHEIGHT) { - I_Error ("R_DrawFuzzColumn: %i to %i at %i", - dc_yl, dc_yh, dc_x); + I_Error ("R_DrawFuzzColumn: %i to %i at %i", + dc_yl, dc_yh, dc_x); } #endif @@ -319,23 +319,23 @@ void R_DrawFuzzColumn (void) /* WATCOM code if (detailshift) { - if (dc_x & 1) - { - outpw (GC_INDEX,GC_READMAP+(2<<8) ); - outp (SC_INDEX+1,12); - } - else - { - outpw (GC_INDEX,GC_READMAP); - outp (SC_INDEX+1,3); - } - dest = destview + dc_yl*80 + (dc_x>>1); + if (dc_x & 1) + { + outpw (GC_INDEX,GC_READMAP+(2<<8) ); + outp (SC_INDEX+1,12); + } + else + { + outpw (GC_INDEX,GC_READMAP); + outp (SC_INDEX+1,3); + } + dest = destview + dc_yl*80 + (dc_x>>1); } else { - outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); - outp (SC_INDEX+1,1<<(dc_x&3)); - dest = destview + dc_yl*80 + (dc_x>>2); + outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); + outp (SC_INDEX+1,1<<(dc_x&3)); + dest = destview + dc_yl*80 + (dc_x>>2); }*/ @@ -351,19 +351,19 @@ void R_DrawFuzzColumn (void) // brighter than average). do { - // Lookup framebuffer, and retrieve - // a pixel that is either one column - // left or right of the current one. - // Add index from colormap to index. - *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; + // Lookup framebuffer, and retrieve + // a pixel that is either one column + // left or right of the current one. + // Add index from colormap to index. + *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; - // Clamp table lookup index. - if (++fuzzpos == FUZZTABLE) - fuzzpos = 0; - - dest += SCREENWIDTH; + // Clamp table lookup index. + if (++fuzzpos == FUZZTABLE) + fuzzpos = 0; + + dest += SCREENWIDTH; - frac += fracstep; + frac += fracstep; } while (count--); } @@ -379,27 +379,27 @@ void R_DrawFuzzColumn (void) // of the BaronOfHell, the HellKnight, uses // identical sprites, kinda brightened up. // -byte* dc_translation; -byte* translationtables; +byte* dc_translation; +byte* translationtables; void R_DrawTranslatedColumn (void) { - int count; - byte* dest; - fixed_t frac; - fixed_t fracstep; + int count; + byte* dest; + fixed_t frac; + fixed_t fracstep; count = dc_yh - dc_yl; if (count < 0) - return; - + return; + #ifdef RANGECHECK if ((unsigned)dc_x >= SCREENWIDTH - || dc_yl < 0 - || dc_yh >= SCREENHEIGHT) + || dc_yl < 0 + || dc_yh >= SCREENHEIGHT) { - I_Error ( "R_DrawColumn: %i to %i at %i", - dc_yl, dc_yh, dc_x); + I_Error ( "R_DrawColumn: %i to %i at %i", + dc_yl, dc_yh, dc_x); } #endif @@ -409,18 +409,18 @@ void R_DrawTranslatedColumn (void) /* Keep for fixing. if (detailshift) { - if (dc_x & 1) - outp (SC_INDEX+1,12); - else - outp (SC_INDEX+1,3); - - dest = destview + dc_yl*80 + (dc_x>>1); + if (dc_x & 1) + outp (SC_INDEX+1,12); + else + outp (SC_INDEX+1,3); + + dest = destview + dc_yl*80 + (dc_x>>1); } else { - outp (SC_INDEX+1,1<<(dc_x&3)); + outp (SC_INDEX+1,1<<(dc_x&3)); - dest = destview + dc_yl*80 + (dc_x>>2); + dest = destview + dc_yl*80 + (dc_x>>2); }*/ @@ -434,15 +434,15 @@ void R_DrawTranslatedColumn (void) // Here we do an additional index re-mapping. do { - // Translation tables are used - // to map certain colorramps to other ones, - // used with PLAY sprites. - // Thus the "green" ramp of the player 0 sprite - // is mapped to gray, red, black/indigo. - *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; - dest += SCREENWIDTH; - - frac += fracstep; + // Translation tables are used + // to map certain colorramps to other ones, + // used with PLAY sprites. + // Thus the "green" ramp of the player 0 sprite + // is mapped to gray, red, black/indigo. + *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; + dest += SCREENWIDTH; + + frac += fracstep; } while (count--); } @@ -458,27 +458,27 @@ void R_DrawTranslatedColumn (void) // void R_InitTranslationTables (void) { - int i; - + int i; + translationtables = Z_Malloc (256*3+255, PU_STATIC, 0); translationtables = (byte *)(( (int)translationtables + 255 )& ~255); // translate just the 16 green colors for (i=0 ; i<256 ; i++) { - if (i >= 0x70 && i<= 0x7f) - { - // map green ramp to gray, brown, red - translationtables[i] = 0x60 + (i&0xf); - translationtables [i+256] = 0x40 + (i&0xf); - translationtables [i+512] = 0x20 + (i&0xf); - } - else - { - // Keep all other colors as is. - translationtables[i] = translationtables[i+256] - = translationtables[i+512] = i; - } + if (i >= 0x70 && i<= 0x7f) + { + // map green ramp to gray, brown, red + translationtables[i] = 0x60 + (i&0xf); + translationtables [i+256] = 0x40 + (i&0xf); + translationtables [i+512] = 0x20 + (i&0xf); + } + else + { + // Keep all other colors as is. + translationtables[i] = translationtables[i+256] + = translationtables[i+512] = i; + } } } @@ -497,50 +497,50 @@ void R_InitTranslationTables (void) // In consequence, flats are not stored by column (like walls), // and the inner loop has to step in texture space u and v. // -int ds_y; -int ds_x1; -int ds_x2; +int ds_y; +int ds_x1; +int ds_x2; -lighttable_t* ds_colormap; +lighttable_t* ds_colormap; -fixed_t ds_xfrac; -fixed_t ds_yfrac; -fixed_t ds_xstep; -fixed_t ds_ystep; +fixed_t ds_xfrac; +fixed_t ds_yfrac; +fixed_t ds_xstep; +fixed_t ds_ystep; // start of a 64*64 tile image -byte* ds_source; +byte* ds_source; // just for profiling -int dscount; +int dscount; // // Draws the actual span. void R_DrawSpan (void) { - fixed_t xfrac; - fixed_t yfrac; - byte* dest; - int count; - int spot; - + fixed_t xfrac; + fixed_t yfrac; + byte* dest; + int count; + int spot; + #ifdef RANGECHECK if (ds_x2 < ds_x1 - || ds_x1<0 - || ds_x2>=SCREENWIDTH - || (unsigned)ds_y>SCREENHEIGHT) + || ds_x1<0 + || ds_x2>=SCREENWIDTH + || (unsigned)ds_y>SCREENHEIGHT) { - I_Error( "R_DrawSpan: %i to %i at %i", - ds_x1,ds_x2,ds_y); + I_Error( "R_DrawSpan: %i to %i at %i", + ds_x1,ds_x2,ds_y); } -// dscount++; +// dscount++; #endif xfrac = ds_xfrac; yfrac = ds_yfrac; - + dest = ylookup[ds_y] + columnofs[ds_x1]; // We do not check for zero spans here? @@ -548,17 +548,17 @@ void R_DrawSpan (void) do { - // Current texture index in u,v. - spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); + // Current texture index in u,v. + spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); - // Lookup pixel from flat texture tile, - // re-index using light/colormap. - *dest++ = ds_colormap[ds_source[spot]]; + // Lookup pixel from flat texture tile, + // re-index using light/colormap. + *dest++ = ds_colormap[ds_source[spot]]; - // Next step in u,v. - xfrac += ds_xstep; - yfrac += ds_ystep; - + // Next step in u,v. + xfrac += ds_xstep; + yfrac += ds_ystep; + } while (count--); } @@ -569,69 +569,69 @@ void R_DrawSpan (void) #if 0 void R_DrawSpan (void) { - unsigned position, step; + unsigned position, step; - byte* source; - byte* colormap; - byte* dest; + byte* source; + byte* colormap; + byte* dest; - unsigned count; - usingned spot; - unsigned value; - unsigned temp; - unsigned xtemp; - unsigned ytemp; - + unsigned count; + usingned spot; + unsigned value; + unsigned temp; + unsigned xtemp; + unsigned ytemp; + position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff); step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff); - + source = ds_source; colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + dest = ylookup[ds_y] + columnofs[ds_x1]; count = ds_x2 - ds_x1 + 1; - + while (count >= 4) { - ytemp = position>>4; - ytemp = ytemp & 4032; - xtemp = position>>26; - spot = xtemp | ytemp; - position += step; - dest[0] = colormap[source[spot]]; + ytemp = position>>4; + ytemp = ytemp & 4032; + xtemp = position>>26; + spot = xtemp | ytemp; + position += step; + dest[0] = colormap[source[spot]]; - ytemp = position>>4; - ytemp = ytemp & 4032; - xtemp = position>>26; - spot = xtemp | ytemp; - position += step; - dest[1] = colormap[source[spot]]; - - ytemp = position>>4; - ytemp = ytemp & 4032; - xtemp = position>>26; - spot = xtemp | ytemp; - position += step; - dest[2] = colormap[source[spot]]; - - ytemp = position>>4; - ytemp = ytemp & 4032; - xtemp = position>>26; - spot = xtemp | ytemp; - position += step; - dest[3] = colormap[source[spot]]; - - count -= 4; - dest += 4; + ytemp = position>>4; + ytemp = ytemp & 4032; + xtemp = position>>26; + spot = xtemp | ytemp; + position += step; + dest[1] = colormap[source[spot]]; + + ytemp = position>>4; + ytemp = ytemp & 4032; + xtemp = position>>26; + spot = xtemp | ytemp; + position += step; + dest[2] = colormap[source[spot]]; + + ytemp = position>>4; + ytemp = ytemp & 4032; + xtemp = position>>26; + spot = xtemp | ytemp; + position += step; + dest[3] = colormap[source[spot]]; + + count -= 4; + dest += 4; } while (count > 0) { - ytemp = position>>4; - ytemp = ytemp & 4032; - xtemp = position>>26; - spot = xtemp | ytemp; - position += step; - *dest++ = colormap[source[spot]]; - count--; + ytemp = position>>4; + ytemp = ytemp & 4032; + xtemp = position>>26; + spot = xtemp | ytemp; + position += step; + *dest++ = colormap[source[spot]]; + count--; } } #endif @@ -642,24 +642,24 @@ void R_DrawSpan (void) // void R_DrawSpanLow (void) { - fixed_t xfrac; - fixed_t yfrac; - byte* dest; - int count; - int spot; - + fixed_t xfrac; + fixed_t yfrac; + byte* dest; + int count; + int spot; + #ifdef RANGECHECK if (ds_x2 < ds_x1 - || ds_x1<0 - || ds_x2>=SCREENWIDTH - || (unsigned)ds_y>SCREENHEIGHT) + || ds_x1<0 + || ds_x2>=SCREENWIDTH + || (unsigned)ds_y>SCREENHEIGHT) { - I_Error( "R_DrawSpan: %i to %i at %i", - ds_x1,ds_x2,ds_y); + I_Error( "R_DrawSpan: %i to %i at %i", + ds_x1,ds_x2,ds_y); } -// dscount++; +// dscount++; #endif - + xfrac = ds_xfrac; yfrac = ds_yfrac; @@ -673,14 +673,14 @@ void R_DrawSpanLow (void) count = ds_x2 - ds_x1; do { - spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); - // Lowres/blocky mode does it twice, - // while scale is adjusted appropriately. - *dest++ = ds_colormap[ds_source[spot]]; - *dest++ = ds_colormap[ds_source[spot]]; - - xfrac += ds_xstep; - yfrac += ds_ystep; + spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); + // Lowres/blocky mode does it twice, + // while scale is adjusted appropriately. + *dest++ = ds_colormap[ds_source[spot]]; + *dest++ = ds_colormap[ds_source[spot]]; + + xfrac += ds_xstep; + yfrac += ds_ystep; } while (count--); } @@ -694,10 +694,10 @@ void R_DrawSpanLow (void) // void R_InitBuffer -( int width, - int height ) +( int width, + int height ) { - int i; + int i; // Handle resize, // e.g. smaller view windows @@ -706,17 +706,17 @@ R_InitBuffer // Column offset. For windows. for (i=0 ; i> 1; + viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; // Preclaculate all row offsets. for (i=0 ; i -#include - - -#include "doomdef.h" -#include "m_swap.h" - -#include "i_system.h" -#include "z_zone.h" -#include "w_wad.h" - -#include "r_local.h" - -#include "doomstat.h" - - - -#define MINZ (FRACUNIT*4) -#define BASEYCENTER 100 - -//void R_DrawColumn (void); -//void R_DrawFuzzColumn (void); - - - -typedef struct -{ - int x1; - int x2; - - int column; - int topclip; - int bottomclip; - -} maskdraw_t; - - - -// -// Sprite rotation 0 is facing the viewer, -// rotation 1 is one angle turn CLOCKWISE around the axis. -// This is not the same as the angle, -// which increases counter clockwise (protractor). -// There was a lot of stuff grabbed wrong, so I changed it... -// -fixed_t pspritescale; -fixed_t pspriteiscale; - -lighttable_t** spritelights; - -// constant arrays -// used for psprite clipping and initializing clipping -short negonearray[SCREENWIDTH]; -short screenheightarray[SCREENWIDTH]; - - -// -// INITIALIZATION FUNCTIONS -// - -// variables used to look up -// and range check thing_t sprites patches -spritedef_t* sprites; -int numsprites; - -spriteframe_t sprtemp[29]; -int maxframe; -char* spritename; - - - - -// -// R_InstallSpriteLump -// Local function for R_InitSprites. -// -void -R_InstallSpriteLump -( int lump, - unsigned frame, - unsigned rotation, - boolean flipped ) -{ - int r; - - if (frame >= 29 || rotation > 8) - I_Error("R_InstallSpriteLump: " - "Bad frame characters in lump %i", lump); - - if ((int)frame > maxframe) - maxframe = frame; - - if (rotation == 0) - { - // the lump should be used for all rotations - if (sprtemp[frame].rotate == false) - I_Error ("R_InitSprites: Sprite %s frame %c has " - "multip rot=0 lump", spritename, 'A'+frame); - - if (sprtemp[frame].rotate == true) - I_Error ("R_InitSprites: Sprite %s frame %c has rotations " - "and a rot=0 lump", spritename, 'A'+frame); - - sprtemp[frame].rotate = false; - for (r=0 ; r<8 ; r++) - { - sprtemp[frame].lump[r] = lump - firstspritelump; - sprtemp[frame].flip[r] = (byte)flipped; - } - return; - } - - // the lump is only used for one rotation - if (sprtemp[frame].rotate == false) - I_Error ("R_InitSprites: Sprite %s frame %c has rotations " - "and a rot=0 lump", spritename, 'A'+frame); - - sprtemp[frame].rotate = true; - - // make 0 based - rotation--; - if (sprtemp[frame].lump[rotation] != -1) - I_Error ("R_InitSprites: Sprite %s : %c : %c " - "has two lumps mapped to it", - spritename, 'A'+frame, '1'+rotation); - - sprtemp[frame].lump[rotation] = lump - firstspritelump; - sprtemp[frame].flip[rotation] = (byte)flipped; -} - - - - -// -// R_InitSpriteDefs -// Pass a null terminated list of sprite names -// (4 chars exactly) to be used. -// Builds the sprite rotation matrixes to account -// for horizontally flipped sprites. -// Will report an error if the lumps are inconsistant. -// Only called at startup. -// -// Sprite lump names are 4 characters for the actor, -// a letter for the frame, and a number for the rotation. -// A sprite that is flippable will have an additional -// letter/number appended. -// The rotation character can be 0 to signify no rotations. -// -void R_InitSpriteDefs (char** namelist) -{ - char** check; - int i; - int l; - int intname; - int frame; - int rotation; - int start; - int end; - int patched; - - // count the number of sprite names - check = namelist; - while (*check != NULL) - check++; - - numsprites = check-namelist; - - if (!numsprites) - return; - - sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL); - - start = firstspritelump-1; - end = lastspritelump+1; - - // scan all the lump names for each of the names, - // noting the highest frame letter. - // Just compare 4 characters as ints - for (i=0 ; itopdelta != 0xff ; ) - { - // calculate unclipped screen coordinates - // for post - topscreen = sprtopscreen + spryscale*column->topdelta; - bottomscreen = topscreen + spryscale*column->length; - - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x]-1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x]+1; - - if (dc_yl <= dc_yh) - { - dc_source = (byte *)column + 3; - dc_texturemid = basetexturemid - (column->topdelta<topdelta; - - // Drawn by either R_DrawColumn - // or (SHADOW) R_DrawFuzzColumn. - colfunc (); - } - column = (column_t *)( (byte *)column + column->length + 4); - } - - dc_texturemid = basetexturemid; -} - - - -// -// R_DrawVisSprite -// mfloorclip and mceilingclip should also be set. -// -void -R_DrawVisSprite -( vissprite_t* vis, - int x1, - int x2 ) -{ - column_t* column; - int texturecolumn; - fixed_t frac; - patch_t* patch; - - - patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE); - - dc_colormap = vis->colormap; - - if (!dc_colormap) - { - // NULL colormap = shadow draw - colfunc = fuzzcolfunc; - } - else if (vis->mobjflags & MF_TRANSLATION) - { - colfunc = R_DrawTranslatedColumn; - dc_translation = translationtables - 256 + - ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) ); - } - - dc_iscale = abs(vis->xiscale)>>detailshift; - dc_texturemid = vis->texturemid; - frac = vis->startfrac; - spryscale = vis->scale; - sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale); - - for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale) - { - texturecolumn = frac>>FRACBITS; -#ifdef RANGECHECK - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error ("R_DrawSpriteRange: bad texturecolumn"); -#endif - column = (column_t *) ((byte *)patch + - LONG(patch->columnofs[texturecolumn])); - R_DrawMaskedColumn (column); - } - - colfunc = basecolfunc; -} - - - -// -// R_ProjectSprite -// Generates a vissprite for a thing -// if it might be visible. -// -void R_ProjectSprite (mobj_t* thing) -{ - fixed_t tr_x; - fixed_t tr_y; - - fixed_t gxt; - fixed_t gyt; - - fixed_t tx; - fixed_t tz; - - fixed_t xscale; - - int x1; - int x2; - - spritedef_t* sprdef; - spriteframe_t* sprframe; - int lump; - - unsigned rot; - boolean flip; - - int index; - - vissprite_t* vis; - - angle_t ang; - fixed_t iscale; - - // transform the origin point - tr_x = thing->x - viewx; - tr_y = thing->y - viewy; - - gxt = FixedMul(tr_x,viewcos); - gyt = -FixedMul(tr_y,viewsin); - - tz = gxt-gyt; - - // thing is behind view plane? - if (tz < MINZ) - return; - - xscale = FixedDiv(projection, tz); - - gxt = -FixedMul(tr_x,viewsin); - gyt = FixedMul(tr_y,viewcos); - tx = -(gyt+gxt); - - // too far off the side? - if (abs(tx)>(tz<<2)) - return; - - // decide which patch to use for sprite relative to player -#ifdef RANGECHECK - if ((unsigned)thing->sprite >= numsprites) - I_Error ("R_ProjectSprite: invalid sprite number %i ", - thing->sprite); -#endif - sprdef = &sprites[thing->sprite]; -#ifdef RANGECHECK - if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes ) - I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ", - thing->sprite, thing->frame); -#endif - sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK]; - - if (sprframe->rotate) - { - // choose a different rotation based on player view - ang = R_PointToAngle (thing->x, thing->y); - rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29; - lump = sprframe->lump[rot]; - flip = (boolean)sprframe->flip[rot]; - } - else - { - // use single rotation for all views - lump = sprframe->lump[0]; - flip = (boolean)sprframe->flip[0]; - } - - // calculate edges of the shape - tx -= spriteoffset[lump]; - x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS; - - // off the right side? - if (x1 > viewwidth) - return; - - tx += spritewidth[lump]; - x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1; - - // off the left side - if (x2 < 0) - return; - - // store information in a vissprite - vis = R_NewVisSprite (); - vis->mobjflags = thing->flags; - vis->scale = xscale<gx = thing->x; - vis->gy = thing->y; - vis->gz = thing->z; - vis->gzt = thing->z + spritetopoffset[lump]; - vis->texturemid = vis->gzt - viewz; - vis->x1 = x1 < 0 ? 0 : x1; - vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; - iscale = FixedDiv (FRACUNIT, xscale); - - if (flip) - { - vis->startfrac = spritewidth[lump]-1; - vis->xiscale = -iscale; - } - else - { - vis->startfrac = 0; - vis->xiscale = iscale; - } - - if (vis->x1 > x1) - vis->startfrac += vis->xiscale*(vis->x1-x1); - vis->patch = lump; - - // get light level - if (thing->flags & MF_SHADOW) - { - // shadow draw - vis->colormap = NULL; - } - else if (fixedcolormap) - { - // fixed map - vis->colormap = fixedcolormap; - } - else if (thing->frame & FF_FULLBRIGHT) - { - // full bright - vis->colormap = colormaps; - } - - else - { - // diminished light - index = xscale>>(LIGHTSCALESHIFT-detailshift); - - if (index >= MAXLIGHTSCALE) - index = MAXLIGHTSCALE-1; - - vis->colormap = spritelights[index]; - } -} - - - - -// -// R_AddSprites -// During BSP traversal, this adds sprites by sector. -// -void R_AddSprites (sector_t* sec) -{ - mobj_t* thing; - int lightnum; - - // BSP is traversed by subsector. - // A sector might have been split into several - // subsectors during BSP building. - // Thus we check whether its already added. - if (sec->validcount == validcount) - return; - - // Well, now it will be done. - sec->validcount = validcount; - - lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight; - - if (lightnum < 0) - spritelights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; - else - spritelights = scalelight[lightnum]; - - // Handle all things in sector. - for (thing = sec->thinglist ; thing ; thing = thing->snext) - R_ProjectSprite (thing); -} - - -// -// R_DrawPSprite -// -void R_DrawPSprite (pspdef_t* psp) -{ - fixed_t tx; - int x1; - int x2; - spritedef_t* sprdef; - spriteframe_t* sprframe; - int lump; - boolean flip; - vissprite_t* vis; - vissprite_t avis; - - // decide which patch to use -#ifdef RANGECHECK - if ( (unsigned)psp->state->sprite >= numsprites) - I_Error ("R_ProjectSprite: invalid sprite number %i ", - psp->state->sprite); -#endif - sprdef = &sprites[psp->state->sprite]; -#ifdef RANGECHECK - if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) - I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ", - psp->state->sprite, psp->state->frame); -#endif - sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ]; - - lump = sprframe->lump[0]; - flip = (boolean)sprframe->flip[0]; - - // calculate edges of the shape - tx = psp->sx-160*FRACUNIT; - - tx -= spriteoffset[lump]; - x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS; - - // off the right side - if (x1 > viewwidth) - return; - - tx += spritewidth[lump]; - x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1; - - // off the left side - if (x2 < 0) - return; - - // store information in a vissprite - vis = &avis; - vis->mobjflags = 0; - vis->texturemid = (BASEYCENTER<sy-spritetopoffset[lump]); - vis->x1 = x1 < 0 ? 0 : x1; - vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; - vis->scale = pspritescale<xiscale = -pspriteiscale; - vis->startfrac = spritewidth[lump]-1; - } - else - { - vis->xiscale = pspriteiscale; - vis->startfrac = 0; - } - - if (vis->x1 > x1) - vis->startfrac += vis->xiscale*(vis->x1-x1); - - vis->patch = lump; - - if (viewplayer->powers[pw_invisibility] > 4*32 - || viewplayer->powers[pw_invisibility] & 8) - { - // shadow draw - vis->colormap = NULL; - } - else if (fixedcolormap) - { - // fixed color - vis->colormap = fixedcolormap; - } - else if (psp->state->frame & FF_FULLBRIGHT) - { - // full bright - vis->colormap = colormaps; - } - else - { - // local light - vis->colormap = spritelights[MAXLIGHTSCALE-1]; - } - - R_DrawVisSprite (vis, vis->x1, vis->x2); -} - - - -// -// R_DrawPlayerSprites -// -void R_DrawPlayerSprites (void) -{ - int i; - int lightnum; - pspdef_t* psp; - - // get light level - lightnum = - (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) - +extralight; - - if (lightnum < 0) - spritelights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; - else - spritelights = scalelight[lightnum]; - - // clip to screen bounds - mfloorclip = screenheightarray; - mceilingclip = negonearray; - - // add all active psprites - for (i=0, psp=viewplayer->psprites; - istate) - R_DrawPSprite (psp); - } -} - - - - -// -// R_SortVisSprites -// -vissprite_t vsprsortedhead; - - -void R_SortVisSprites (void) -{ - int i; - int count; - vissprite_t* ds; - vissprite_t* best; - vissprite_t unsorted; - fixed_t bestscale; - - count = vissprite_p - vissprites; - - unsorted.next = unsorted.prev = &unsorted; - - if (!count) - return; - - for (ds=vissprites ; dsnext = ds+1; - ds->prev = ds-1; - } - - vissprites[0].prev = &unsorted; - unsorted.next = &vissprites[0]; - (vissprite_p-1)->next = &unsorted; - unsorted.prev = vissprite_p-1; - - // pull the vissprites out by scale - //best = 0; // shut up the compiler warning - vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; - for (i=0 ; inext) - { - if (ds->scale < bestscale) - { - bestscale = ds->scale; - best = ds; - } - } - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = &vsprsortedhead; - best->prev = vsprsortedhead.prev; - vsprsortedhead.prev->next = best; - vsprsortedhead.prev = best; - } -} - - - -// -// R_DrawSprite -// -void R_DrawSprite (vissprite_t* spr) -{ - drawseg_t* ds; - short clipbot[SCREENWIDTH]; - short cliptop[SCREENWIDTH]; - int x; - int r1; - int r2; - fixed_t scale; - fixed_t lowscale; - int silhouette; - - for (x = spr->x1 ; x<=spr->x2 ; x++) - clipbot[x] = cliptop[x] = -2; - - // Scan drawsegs from end to start for obscuring segs. - // The first drawseg that has a greater scale - // is the clip seg. - for (ds=ds_p-1 ; ds >= drawsegs ; ds--) - { - // determine if the drawseg obscures the sprite - if (ds->x1 > spr->x2 - || ds->x2 < spr->x1 - || (!ds->silhouette - && !ds->maskedtexturecol) ) - { - // does not cover sprite - continue; - } - - r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; - r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; - - if (ds->scale1 > ds->scale2) - { - lowscale = ds->scale2; - scale = ds->scale1; - } - else - { - lowscale = ds->scale1; - scale = ds->scale2; - } - - if (scale < spr->scale - || ( lowscale < spr->scale - && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) ) - { - // masked mid texture? - if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, r1, r2); - // seg is behind sprite - continue; - } - - - // clip this piece of the sprite - silhouette = ds->silhouette; - - if (spr->gz >= ds->bsilheight) - silhouette &= ~SIL_BOTTOM; - - if (spr->gzt <= ds->tsilheight) - silhouette &= ~SIL_TOP; - - if (silhouette == 1) - { - // bottom sil - for (x=r1 ; x<=r2 ; x++) - if (clipbot[x] == -2) - clipbot[x] = ds->sprbottomclip[x]; - } - else if (silhouette == 2) - { - // top sil - for (x=r1 ; x<=r2 ; x++) - if (cliptop[x] == -2) - cliptop[x] = ds->sprtopclip[x]; - } - else if (silhouette == 3) - { - // both - for (x=r1 ; x<=r2 ; x++) - { - if (clipbot[x] == -2) - clipbot[x] = ds->sprbottomclip[x]; - if (cliptop[x] == -2) - cliptop[x] = ds->sprtopclip[x]; - } - } - - } - - // all clipping has been performed, so draw the sprite - - // check for unclipped columns - for (x = spr->x1 ; x<=spr->x2 ; x++) - { - if (clipbot[x] == -2) - clipbot[x] = viewheight; - - if (cliptop[x] == -2) - cliptop[x] = -1; - } - - mfloorclip = clipbot; - mceilingclip = cliptop; - R_DrawVisSprite (spr, spr->x1, spr->x2); -} - - - - -// -// R_DrawMasked -// -void R_DrawMasked (void) -{ - vissprite_t* spr; - drawseg_t* ds; - - R_SortVisSprites (); - - if (vissprite_p > vissprites) - { - // draw all vissprites back to front - for (spr = vsprsortedhead.next ; - spr != &vsprsortedhead ; - spr=spr->next) - { - - R_DrawSprite (spr); - } - } - - // render any remaining masked mid textures - for (ds=ds_p-1 ; ds >= drawsegs ; ds--) - if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, ds->x1, ds->x2); - - // draw the psprites on top of everything - // but does not draw on side views - if (!viewangleoffset) - R_DrawPlayerSprites (); -} - - - +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// Refresh of things, i.e. objects represented by sprites. +// +//----------------------------------------------------------------------------- + + +static const char +rcsid[] = "$Id: r_things.c,v 1.5 1997/02/03 16:47:56 b1 Exp $"; + + +#include +#include + +#include "doomtype.h" + +#include "doomdef.h" +#include "m_swap.h" + +#include "i_system.h" +#include "z_zone.h" +#include "w_wad.h" + +#include "r_local.h" + +#include "doomstat.h" + + + +#define MINZ (FRACUNIT*4) +#define BASEYCENTER 100 + +//void R_DrawColumn (void); +//void R_DrawFuzzColumn (void); + + + +typedef struct +{ + int x1; + int x2; + + int column; + int topclip; + int bottomclip; + +} maskdraw_t; + + + +// +// Sprite rotation 0 is facing the viewer, +// rotation 1 is one angle turn CLOCKWISE around the axis. +// This is not the same as the angle, +// which increases counter clockwise (protractor). +// There was a lot of stuff grabbed wrong, so I changed it... +// +fixed_t pspritescale; +fixed_t pspriteiscale; + +lighttable_t** spritelights; + +// constant arrays +// used for psprite clipping and initializing clipping +short negonearray[SCREENWIDTH]; +short screenheightarray[SCREENWIDTH]; + + +// +// INITIALIZATION FUNCTIONS +// + +// variables used to look up +// and range check thing_t sprites patches +spritedef_t* sprites; +int numsprites; + +spriteframe_t sprtemp[29]; +int maxframe; +char* spritename; + + + + +// +// R_InstallSpriteLump +// Local function for R_InitSprites. +// +void +R_InstallSpriteLump +( int lump, + unsigned frame, + unsigned rotation, + boolean flipped ) +{ + int r; + + if (frame >= 29 || rotation > 8) + I_Error("R_InstallSpriteLump: " + "Bad frame characters in lump %i", lump); + + if ((int)frame > maxframe) + maxframe = frame; + + if (rotation == 0) + { + // the lump should be used for all rotations + if (sprtemp[frame].rotate == false) + I_Error ("R_InitSprites: Sprite %s frame %c has " + "multip rot=0 lump", spritename, 'A'+frame); + + if (sprtemp[frame].rotate == true) + I_Error ("R_InitSprites: Sprite %s frame %c has rotations " + "and a rot=0 lump", spritename, 'A'+frame); + + sprtemp[frame].rotate = false; + for (r=0 ; r<8 ; r++) + { + sprtemp[frame].lump[r] = lump - firstspritelump; + sprtemp[frame].flip[r] = (byte)flipped; + } + return; + } + + // the lump is only used for one rotation + if (sprtemp[frame].rotate == false) + I_Error ("R_InitSprites: Sprite %s frame %c has rotations " + "and a rot=0 lump", spritename, 'A'+frame); + + sprtemp[frame].rotate = true; + + // make 0 based + rotation--; + if (sprtemp[frame].lump[rotation] != -1) + I_Error ("R_InitSprites: Sprite %s : %c : %c " + "has two lumps mapped to it", + spritename, 'A'+frame, '1'+rotation); + + sprtemp[frame].lump[rotation] = lump - firstspritelump; + sprtemp[frame].flip[rotation] = (byte)flipped; +} + + + + +// +// R_InitSpriteDefs +// Pass a null terminated list of sprite names +// (4 chars exactly) to be used. +// Builds the sprite rotation matrixes to account +// for horizontally flipped sprites. +// Will report an error if the lumps are inconsistant. +// Only called at startup. +// +// Sprite lump names are 4 characters for the actor, +// a letter for the frame, and a number for the rotation. +// A sprite that is flippable will have an additional +// letter/number appended. +// The rotation character can be 0 to signify no rotations. +// +void R_InitSpriteDefs (char** namelist) +{ + char** check; + int i; + int l; + int intname; + int frame; + int rotation; + int start; + int end; + int patched; + + // count the number of sprite names + check = namelist; + while (*check != NULL) + check++; + + numsprites = check-namelist; + + if (!numsprites) + return; + + sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL); + + start = firstspritelump-1; + end = lastspritelump+1; + + // scan all the lump names for each of the names, + // noting the highest frame letter. + // Just compare 4 characters as ints + for (i=0 ; itopdelta != 0xff ; ) + { + // calculate unclipped screen coordinates + // for post + topscreen = sprtopscreen + spryscale*column->topdelta; + bottomscreen = topscreen + spryscale*column->length; + + dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (dc_yh >= mfloorclip[dc_x]) + dc_yh = mfloorclip[dc_x]-1; + if (dc_yl <= mceilingclip[dc_x]) + dc_yl = mceilingclip[dc_x]+1; + + if (dc_yl <= dc_yh) + { + dc_source = (byte *)column + 3; + dc_texturemid = basetexturemid - (column->topdelta<topdelta; + + // Drawn by either R_DrawColumn + // or (SHADOW) R_DrawFuzzColumn. + colfunc (); + } + column = (column_t *)( (byte *)column + column->length + 4); + } + + dc_texturemid = basetexturemid; +} + + + +// +// R_DrawVisSprite +// mfloorclip and mceilingclip should also be set. +// +void +R_DrawVisSprite +( vissprite_t* vis, + int x1, + int x2 ) +{ + column_t* column; + int texturecolumn; + fixed_t frac; + patch_t* patch; + + + patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE); + + dc_colormap = vis->colormap; + + if (!dc_colormap) + { + // NULL colormap = shadow draw + colfunc = fuzzcolfunc; + } + else if (vis->mobjflags & MF_TRANSLATION) + { + colfunc = R_DrawTranslatedColumn; + dc_translation = translationtables - 256 + + ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) ); + } + + dc_iscale = abs(vis->xiscale)>>detailshift; + dc_texturemid = vis->texturemid; + frac = vis->startfrac; + spryscale = vis->scale; + sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale); + + for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale) + { + texturecolumn = frac>>FRACBITS; +#ifdef RANGECHECK + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + { + // I_Error ("R_DrawSpriteRange: bad texturecolumn"); + printf( "texturecolumn= %d, width= %d\n\r", + texturecolumn,patch->width); + texturecolumn=patch->width-1; + } +#endif + column = (column_t *) ((byte *)patch + + LONG(patch->columnofs[texturecolumn])); + R_DrawMaskedColumn (column); + } + + colfunc = basecolfunc; +} + + + +// +// R_ProjectSprite +// Generates a vissprite for a thing +// if it might be visible. +// +void R_ProjectSprite (mobj_t* thing) +{ + fixed_t tr_x; + fixed_t tr_y; + + fixed_t gxt; + fixed_t gyt; + + fixed_t tx; + fixed_t tz; + + fixed_t xscale; + + int x1; + int x2; + + spritedef_t* sprdef; + spriteframe_t* sprframe; + int lump; + + unsigned rot; + boolean flip; + + int index; + + vissprite_t* vis; + + angle_t ang; + fixed_t iscale; + + // transform the origin point + tr_x = thing->x - viewx; + tr_y = thing->y - viewy; + + gxt = FixedMul(tr_x,viewcos); + gyt = -FixedMul(tr_y,viewsin); + + tz = gxt-gyt; + + // thing is behind view plane? + if (tz < MINZ) + return; + + xscale = FixedDiv(projection, tz); + + gxt = -FixedMul(tr_x,viewsin); + gyt = FixedMul(tr_y,viewcos); + tx = -(gyt+gxt); + + // too far off the side? + if (abs(tx)>(tz<<2)) + return; + + // decide which patch to use for sprite relative to player +#ifdef RANGECHECK + if ((unsigned)thing->sprite >= numsprites) + I_Error ("R_ProjectSprite: invalid sprite number %i ", + thing->sprite); +#endif + sprdef = &sprites[thing->sprite]; +#ifdef RANGECHECK + if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes ) + I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ", + thing->sprite, thing->frame); +#endif + sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK]; + + if (sprframe->rotate) + { + // choose a different rotation based on player view + ang = R_PointToAngle (thing->x, thing->y); + rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29; + lump = sprframe->lump[rot]; + flip = (boolean)sprframe->flip[rot]; + } + else + { + // use single rotation for all views + lump = sprframe->lump[0]; + flip = (boolean)sprframe->flip[0]; + } + + // calculate edges of the shape + tx -= spriteoffset[lump]; + x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS; + + // off the right side? + if (x1 > viewwidth) + return; + + tx += spritewidth[lump]; + x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1; + + // off the left side + if (x2 < 0) + return; + + // store information in a vissprite + vis = R_NewVisSprite (); + vis->mobjflags = thing->flags; + vis->scale = xscale<gx = thing->x; + vis->gy = thing->y; + vis->gz = thing->z; + vis->gzt = thing->z + spritetopoffset[lump]; + vis->texturemid = vis->gzt - viewz; + vis->x1 = x1 < 0 ? 0 : x1; + vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + iscale = FixedDiv (FRACUNIT, xscale); + + if (flip) + { + vis->startfrac = spritewidth[lump]-1; + vis->xiscale = -iscale; + } + else + { + vis->startfrac = 0; + vis->xiscale = iscale; + } + + if (vis->x1 > x1) + vis->startfrac += vis->xiscale*(vis->x1-x1); + vis->patch = lump; + + // get light level + if (thing->flags & MF_SHADOW) + { + // shadow draw + vis->colormap = NULL; + } + else if (fixedcolormap) + { + // fixed map + vis->colormap = fixedcolormap; + } + else if (thing->frame & FF_FULLBRIGHT) + { + // full bright + vis->colormap = colormaps; + } + + else + { + // diminished light + index = xscale>>(LIGHTSCALESHIFT-detailshift); + + if (index >= MAXLIGHTSCALE) + index = MAXLIGHTSCALE-1; + + vis->colormap = spritelights[index]; + } +} + + + + +// +// R_AddSprites +// During BSP traversal, this adds sprites by sector. +// +void R_AddSprites (sector_t* sec) +{ + mobj_t* thing; + int lightnum; + + // BSP is traversed by subsector. + // A sector might have been split into several + // subsectors during BSP building. + // Thus we check whether its already added. + if (sec->validcount == validcount) + return; + + // Well, now it will be done. + sec->validcount = validcount; + + lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight; + + if (lightnum < 0) + spritelights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + spritelights = scalelight[LIGHTLEVELS-1]; + else + spritelights = scalelight[lightnum]; + + // Handle all things in sector. + for (thing = sec->thinglist ; thing ; thing = thing->snext) + R_ProjectSprite (thing); +} + + +// +// R_DrawPSprite +// +void R_DrawPSprite (pspdef_t* psp) +{ + fixed_t tx; + int x1; + int x2; + spritedef_t* sprdef; + spriteframe_t* sprframe; + int lump; + boolean flip; + vissprite_t* vis; + vissprite_t avis; + + // decide which patch to use +#ifdef RANGECHECK + if ( (unsigned)psp->state->sprite >= numsprites) + I_Error ("R_ProjectSprite: invalid sprite number %i ", + psp->state->sprite); +#endif + sprdef = &sprites[psp->state->sprite]; +#ifdef RANGECHECK + if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) + I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ", + psp->state->sprite, psp->state->frame); +#endif + sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ]; + + lump = sprframe->lump[0]; + flip = (boolean)sprframe->flip[0]; + + // calculate edges of the shape + tx = psp->sx-160*FRACUNIT; + + tx -= spriteoffset[lump]; + x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS; + + // off the right side + if (x1 > viewwidth) + return; + + tx += spritewidth[lump]; + x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1; + + // off the left side + if (x2 < 0) + return; + + // store information in a vissprite + vis = &avis; + vis->mobjflags = 0; + vis->texturemid = (BASEYCENTER<sy-spritetopoffset[lump]); + vis->x1 = x1 < 0 ? 0 : x1; + vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + vis->scale = pspritescale<xiscale = -pspriteiscale; + vis->startfrac = spritewidth[lump]-1; + } + else + { + vis->xiscale = pspriteiscale; + vis->startfrac = 0; + } + + if (vis->x1 > x1) + vis->startfrac += vis->xiscale*(vis->x1-x1); + + vis->patch = lump; + + if (viewplayer->powers[pw_invisibility] > 4*32 + || viewplayer->powers[pw_invisibility] & 8) + { + // shadow draw + vis->colormap = NULL; + } + else if (fixedcolormap) + { + // fixed color + vis->colormap = fixedcolormap; + } + else if (psp->state->frame & FF_FULLBRIGHT) + { + // full bright + vis->colormap = colormaps; + } + else + { + // local light + vis->colormap = spritelights[MAXLIGHTSCALE-1]; + } + + R_DrawVisSprite (vis, vis->x1, vis->x2); +} + + + +// +// R_DrawPlayerSprites +// +void R_DrawPlayerSprites (void) +{ + int i; + int lightnum; + pspdef_t* psp; + + // get light level + lightnum = + (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) + +extralight; + + if (lightnum < 0) + spritelights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + spritelights = scalelight[LIGHTLEVELS-1]; + else + spritelights = scalelight[lightnum]; + + // clip to screen bounds + mfloorclip = screenheightarray; + mceilingclip = negonearray; + + // add all active psprites + for (i=0, psp=viewplayer->psprites; + istate) + R_DrawPSprite (psp); + } +} + + + + +// +// R_SortVisSprites +// +vissprite_t vsprsortedhead; + + +void R_SortVisSprites (void) +{ + int i; + int count; + vissprite_t* ds; + vissprite_t* best; + vissprite_t unsorted; + fixed_t bestscale; + + count = vissprite_p - vissprites; + + unsorted.next = unsorted.prev = &unsorted; + + if (!count) + return; + + for (ds=vissprites ; dsnext = ds+1; + ds->prev = ds-1; + } + + vissprites[0].prev = &unsorted; + unsorted.next = &vissprites[0]; + (vissprite_p-1)->next = &unsorted; + unsorted.prev = vissprite_p-1; + + // pull the vissprites out by scale + //best = 0; // shut up the compiler warning + vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; + for (i=0 ; inext) + { + if (ds->scale < bestscale) + { + bestscale = ds->scale; + best = ds; + } + } + best->next->prev = best->prev; + best->prev->next = best->next; + best->next = &vsprsortedhead; + best->prev = vsprsortedhead.prev; + vsprsortedhead.prev->next = best; + vsprsortedhead.prev = best; + } +} + + + +// +// R_DrawSprite +// +void R_DrawSprite (vissprite_t* spr) +{ + drawseg_t* ds; + short clipbot[SCREENWIDTH]; + short cliptop[SCREENWIDTH]; + int x; + int r1; + int r2; + fixed_t scale; + fixed_t lowscale; + int silhouette; + + for (x = spr->x1 ; x<=spr->x2 ; x++) + clipbot[x] = cliptop[x] = -2; + + // Scan drawsegs from end to start for obscuring segs. + // The first drawseg that has a greater scale + // is the clip seg. + for (ds=ds_p-1 ; ds >= drawsegs ; ds--) + { + // determine if the drawseg obscures the sprite + if (ds->x1 > spr->x2 + || ds->x2 < spr->x1 + || (!ds->silhouette + && !ds->maskedtexturecol) ) + { + // does not cover sprite + continue; + } + + r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; + r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; + + if (ds->scale1 > ds->scale2) + { + lowscale = ds->scale2; + scale = ds->scale1; + } + else + { + lowscale = ds->scale1; + scale = ds->scale2; + } + + if (scale < spr->scale + || ( lowscale < spr->scale + && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) ) + { + // masked mid texture? + if (ds->maskedtexturecol) + R_RenderMaskedSegRange (ds, r1, r2); + // seg is behind sprite + continue; + } + + + // clip this piece of the sprite + silhouette = ds->silhouette; + + if (spr->gz >= ds->bsilheight) + silhouette &= ~SIL_BOTTOM; + + if (spr->gzt <= ds->tsilheight) + silhouette &= ~SIL_TOP; + + if (silhouette == 1) + { + // bottom sil + for (x=r1 ; x<=r2 ; x++) + if (clipbot[x] == -2) + clipbot[x] = ds->sprbottomclip[x]; + } + else if (silhouette == 2) + { + // top sil + for (x=r1 ; x<=r2 ; x++) + if (cliptop[x] == -2) + cliptop[x] = ds->sprtopclip[x]; + } + else if (silhouette == 3) + { + // both + for (x=r1 ; x<=r2 ; x++) + { + if (clipbot[x] == -2) + clipbot[x] = ds->sprbottomclip[x]; + if (cliptop[x] == -2) + cliptop[x] = ds->sprtopclip[x]; + } + } + + } + + // all clipping has been performed, so draw the sprite + + // check for unclipped columns + for (x = spr->x1 ; x<=spr->x2 ; x++) + { + if (clipbot[x] == -2) + clipbot[x] = viewheight; + + if (cliptop[x] == -2) + cliptop[x] = -1; + } + + mfloorclip = clipbot; + mceilingclip = cliptop; + R_DrawVisSprite (spr, spr->x1, spr->x2); +} + + + + +// +// R_DrawMasked +// +void R_DrawMasked (void) +{ + vissprite_t* spr; + drawseg_t* ds; + + R_SortVisSprites (); + + if (vissprite_p > vissprites) + { + // draw all vissprites back to front + for (spr = vsprsortedhead.next ; + spr != &vsprsortedhead ; + spr=spr->next) + { + + R_DrawSprite (spr); + } + } + + // render any remaining masked mid textures + for (ds=ds_p-1 ; ds >= drawsegs ; ds--) + if (ds->maskedtexturecol) + R_RenderMaskedSegRange (ds, ds->x1, ds->x2); + + // draw the psprites on top of everything + // but does not draw on side views + if (!viewangleoffset) + R_DrawPlayerSprites (); +} + + + diff --git a/programs/games/doom/trunk/s_sound.c b/programs/games/doom/trunk/s_sound.c index cb76037aa2..1c1381392b 100644 --- a/programs/games/doom/trunk/s_sound.c +++ b/programs/games/doom/trunk/s_sound.c @@ -45,6 +45,9 @@ rcsid[] = "$Id: s_sound.c,v 1.6 1997/02/03 22:45:12 b1 Exp $"; //#include "qmus2mid.h" + +#include "kolibri.h" + void WriteDebug(char *); // Purpose? @@ -112,10 +115,10 @@ static channel_t* channels; // These are not used, but should be (menu). // Maximum volume of a sound effect. // Internal default is max out of 0-15. -int snd_SfxVolume = 80; +int snd_SfxVolume = 15; // Maximum volume of music. Useless so far. -int snd_MusicVolume = 80; +int snd_MusicVolume = 15; @@ -161,6 +164,10 @@ void S_StopChannel(int cnum); // Sets channels, SFX and music volume, // allocates channel buffer, sets S_sfx lookup. // + +DWORD hMixBuff[4]; +int mix_ptr; + void S_Init ( int sfxVolume, int musicVolume ) @@ -169,7 +176,13 @@ void S_Init printf("S_Init: default sfx volume %d\n", sfxVolume); - //I_CreateSound(); + InitSound(); + + hMixBuff[0]= CreateBuffer(15); + hMixBuff[1]= CreateBuffer(15); + hMixBuff[2]= CreateBuffer(15); + hMixBuff[3]= CreateBuffer(15); + numChannels = NUM_CHANNELS; // Whatever these did with DMX, these are rather dummies now. diff --git a/programs/games/doom/trunk/w_wad.c b/programs/games/doom/trunk/w_wad.c index 3f49ea0291..24f7830ce0 100644 --- a/programs/games/doom/trunk/w_wad.c +++ b/programs/games/doom/trunk/w_wad.c @@ -151,6 +151,8 @@ void W_AddFile (char *filename) reloadname = filename; reloadlump = numlumps; } + + printf("open file %s\n\r",filename); if ( (handle = fopen (filename,"rb")) == NULL) {