ZDoom 1.17b.

This commit is contained in:
Randy Heit 1999-03-15 00:00:00 +00:00
parent 02bae52a82
commit 274c693a70
93 changed files with 17288 additions and 2684 deletions

View file

@ -558,14 +558,18 @@ void AM_unloadPics(void)
int i;
for (i = 0; i < 10; i++)
Z_ChangeTag (marknums[i], PU_CACHE);
if (marknums[i])
{
Z_ChangeTag (marknums[i], PU_CACHE);
marknums[i] = NULL;
}
}
void AM_clearMarks(void)
{
int i;
for (i=0;i<AM_NUMMARKPOINTS;i++)
for (i = AM_NUMMARKPOINTS-1; i >= 0; i--)
markpoints[i].x = -1; // means empty
markpointnum = 0;
}

View file

@ -25,6 +25,7 @@
#include "z_zone.h"
#include "w_wad.h"
#include "g_level.h"
#include "gi.h"
extern FILE *Logfile;
@ -229,11 +230,12 @@ void Cmd_idclev (player_t *plyr, int argc, char **argv)
if ((argc > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1]) {
int epsd, map;
char *buf = argv[1];
char *mapname;
buf[0] -= '0';
buf[1] -= '0';
if (gamemode == commercial) {
if (gameinfo.flags & GI_MAPxx) {
epsd = 1;
map = buf[0]*10 + buf[1];
} else {
@ -242,28 +244,13 @@ void Cmd_idclev (player_t *plyr, int argc, char **argv)
}
// Catch invalid maps.
if (epsd < 1)
return;
if (map < 1)
return;
if ((gamemode == retail) && ((epsd > 4) || (map > 9)))
return;
if ((gamemode == registered) && ((epsd > 3) || (map > 9)))
return;
if ((gamemode == shareware) && ((epsd > 1) || (map > 9)))
return;
if ((gamemode == commercial) && (( epsd > 1) || (map > 34)))
mapname = CalcMapName (epsd, map);
if (W_CheckNumForName (mapname) == -1)
return;
// So be it.
Printf (PRINT_HIGH, "%s\n", STSTR_CLEV);
G_DeferedInitNew (CalcMapName (epsd, map));
G_DeferedInitNew (mapname);
}
}
@ -290,21 +277,28 @@ void Cmd_idmus (player_t *plyr, int argc, char **argv)
char *map;
int l;
if (argc > 1) {
if (gamemode == commercial) {
if (argc > 1)
{
if (gameinfo.flags & GI_MAPxx)
{
l = atoi (argv[1]);
if (l <= 99)
map = CalcMapName (0, l);
else {
else
{
Printf (PRINT_HIGH, "%s\n", STSTR_NOMUS);
return;
}
} else {
}
else
{
map = CalcMapName (argv[1][0] - '0', argv[1][1] - '0');
}
if ( (info = FindLevelInfo (map)) ) {
if (info->music[0]) {
if ( (info = FindLevelInfo (map)) )
{
if (info->music[0])
{
S_ChangeMusic (info->music, 1);
Printf (PRINT_HIGH, "%s\n", STSTR_MUS);
}

View file

@ -754,6 +754,7 @@ static int PatchThing (int thingNum)
{ "Mass", myoffsetof(mobjinfo_t,mass) },
{ "Missile damage", myoffsetof(mobjinfo_t,damage) },
{ "Respawn frame", myoffsetof(mobjinfo_t,raisestate) },
{ "Translucency", myoffsetof(mobjinfo_t,translucency) },
{ NULL, }
};
@ -849,11 +850,6 @@ static int PatchThing (int thingNum)
Printf (PRINT_HIGH, "Thing %d out of range.\n", thingNum + 1);
}
// Turn off transparency for the mobj, since original DOOM
// didn't have any. If some is wanted, let the patch specify it.
// Uncomment this if you want to make it so.
//info->flags &= ~MF_TRANSLUCBITS;
while ((result = GetLine ()) == 1) {
int sndmap = atoi (Line2);
@ -916,7 +912,13 @@ static int PatchThing (int thingNum)
}
}
if (vchanged)
{
info->flags = value;
// Bit flags are no longer used to specify translucency.
// This is just a temporary hack.
if (info->flags & 0x60000000)
info->translucency = (info->flags & 0x60000000) >> 15;
}
if (v2changed)
info->flags2 = value2;
DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags, info->flags2,
@ -1174,7 +1176,7 @@ static int PatchMisc (int dummy)
{ "Max Armor", myoffsetof(struct DehInfo,MaxArmor) },
{ "Green Armor Class", myoffsetof(struct DehInfo,GreenAC) },
{ "Blue Armor Class", myoffsetof(struct DehInfo,BlueAC) },
{ "Max Soulsphere", myoffsetof(struct DehInfo,BlueAC) },
{ "Max Soulsphere", myoffsetof(struct DehInfo,MaxSoulsphere) },
{ "Soulsphere Health", myoffsetof(struct DehInfo,SoulsphereHealth) },
{ "Megasphere Health", myoffsetof(struct DehInfo,MegasphereHealth) },
{ "God Mode Health", myoffsetof(struct DehInfo,GodHealth) },

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,8 @@
#include "p_effect.h"
#include "p_local.h"
#include "gi.h"
#define NCMD_EXIT 0x80000000
#define NCMD_RETRANSMIT 0x40000000
#define NCMD_SETUP 0x20000000
@ -501,24 +503,21 @@ void NetUpdate (void)
//
// CheckAbort
//
void CheckAbort (void)
BOOL CheckAbort (void)
{
event_t *ev;
int stoptic;
Printf (PRINT_HIGH, ""); // [RH] Give the console a chance to redraw itself
stoptic = I_GetTime () + 2;
while (I_GetTime() < stoptic)
I_StartTic ();
I_WaitForTic (I_GetTime () + TICRATE*2/35);
I_StartTic ();
for ( ; eventtail != eventhead
; eventtail = (++eventtail)&(MAXEVENTS-1) )
{
ev = &events[eventtail];
if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
I_Error ("Network game synchronization aborted.");
}
return true;
}
return false;
}
@ -548,7 +547,8 @@ void D_ArbitrateNetStart (void)
Printf (PRINT_HIGH, "Waiting for %d more player%s...\n",
doomcom->numnodes - 1, (doomcom->numnodes == 2) ? "" : "s");
do {
CheckAbort ();
if (CheckAbort ())
I_FatalError ("Network game synchronization aborted.");
for (i = 10; i > 0; i--) {
if (HGetPacket ()) {
@ -736,7 +736,7 @@ void TryRunTics (void)
int numplaying;
// get real tics
entertic = I_GetTime ()/ticdup;
entertic = I_WaitForTic (oldentertics * ticdup) / ticdup;
realtics = entertic - oldentertics;
oldentertics = entertic;
@ -945,22 +945,12 @@ void Net_DoCommand (int type, byte **stream, int player)
if ((who == 0) || players[player].userinfo.team[0] == 0) {
// Said to everyone
Printf (PRINT_CHAT, "%s: %s\n", players[player].userinfo.netname, s);
if (gamemode == commercial) {
S_Sound (NULL, CHAN_VOICE, "misc/chat", 1, ATTN_NONE);
} else {
S_Sound (NULL, CHAN_VOICE, "misc/chat2", 1, ATTN_NONE);
}
S_Sound (NULL, CHAN_VOICE, gameinfo.chatSound, 1, ATTN_NONE);
} else if (!stricmp (players[player].userinfo.team,
players[consoleplayer].userinfo.team)) {
// Said only to members of the player's team
Printf (PRINT_TEAMCHAT, "(%s): %s\n", players[player].userinfo.netname, s);
if (gamemode == commercial) {
S_Sound (NULL, CHAN_VOICE, "misc/chat", 1, ATTN_NONE);
} else {
S_Sound (NULL, CHAN_VOICE, "misc/chat2", 1, ATTN_NONE);
}
S_Sound (NULL, CHAN_VOICE, gameinfo.chatSound, 1, ATTN_NONE);
}
}
break;
@ -1018,7 +1008,7 @@ void Net_DoCommand (int type, byte **stream, int player)
free (s);
}
// [RH] List ping times
// [RH] List "ping" times
void Cmd_Pings (void *plyr, int argc, char **argv)
{
int i;

View file

@ -126,7 +126,8 @@ typedef struct player_s
int attackdown, usedown; // true if button down last tic
int cheats; // bit flags
int refire; // refired shots are less accurate
short refire; // refired shots are less accurate
short inconsistant;
int killcount, itemcount, secretcount; // for intermission
int damagecount, bonuscount;// for screen flashing
mobj_t *attacker; // who did damage (NULL for floors

View file

@ -314,6 +314,7 @@ typedef enum
#define DF_FAST_MONSTERS 32768 // Monsters are fast (replaces -fast parm)
#define DF_NO_JUMP 65536 // Don't allow jumping
#define DF_NO_FREELOOK 131072 // Don't allow freelook
#define DF_RESPAWN_SUPER 262144 // Respawn invulnerability and invisibility
// phares 3/20/98:
//

View file

@ -46,6 +46,4 @@ cvar_t *boom_friction, *boom_pushers;
// [RH] Deathmatch flags
cvar_t *dmflagsvar;
int dmflags; // Copy of dmflagsvar->value, but as an integer.
// [RH] Information about the current game
gameinfo_t gameinfo;
cvar_t *fakedmatch;

View file

@ -85,6 +85,9 @@ extern BOOL netgame;
// Flag: true only if started as net deathmatch.
extern cvar_t *deathmatch;
// [RH] Pretend as deathmatch for purposes of dmflags
extern cvar_t *fakedmatch;
// [RH] Teamplay mode
extern cvar_t *teamplay;
@ -317,27 +320,6 @@ extern struct DehInfo deh;
extern cvar_t *dmflagsvar;
extern int dmflags;
// [RH] Generic information about the current game
struct gameinfo_s
{
char *gameTitle;
BOOL pagesArePatches;
char *titlePage;
char *demoPage1;
char *demoPage2;
char *advisory;
float titleTime;
float demoPage1Time;
float demoPage2Time;
float advisoryTime;
char *titleSong;
char *skyFlatName;
};
typedef struct gameinfo_s gameinfo_t;
extern gameinfo_t gameinfo;
#endif
//-----------------------------------------------------------------------------
//

View file

@ -38,6 +38,8 @@
#include "r_state.h"
#include "hu_stuff.h"
#include "gi.h"
// Stage of animation:
// 0 = text, 1 = art screen, 2 = character cast
unsigned int finalestage;
@ -73,20 +75,15 @@ void F_StartFinale (char *music, char *flat, char *text)
// determined in G_WorldDone() based on data in
// a level_info_t and a cluster_info_t.
if (*music == 0) {
if (gamemode == commercial)
S_ChangeMusic ("D_READ_M", true);
else
S_ChangeMusic ("D_VICTOR", true);
} else
S_ChangeMusic (music, true);
if (*music == 0)
S_ChangeMusic (gameinfo.finaleMusic,
!(gameinfo.flags & GI_NOLOOPFINALEMUSIC));
else
S_ChangeMusic (music, !(gameinfo.flags & GI_NOLOOPFINALEMUSIC));
if (*flat == 0) {
if (gamemode == commercial)
finaleflat = "SLIME16";
else
finaleflat = "FLOOR4_8";
} else
if (*flat == 0)
finaleflat = gameinfo.finaleFlat;
else
finaleflat = flat;
if (text)
@ -676,7 +673,8 @@ void F_BunnyScroll (void)
//
void F_Drawer (void)
{
switch (finalestage) {
switch (finalestage)
{
case 0:
F_TextWrite ();
break;
@ -684,24 +682,22 @@ void F_Drawer (void)
case 1:
switch (level.nextmap[7])
{
case '1':
if (gamemode == retail)
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("CREDIT",PU_CACHE));
else
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE));
break;
case '2':
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("VICTORY2",PU_CACHE));
break;
case '3':
F_BunnyScroll ();
break;
case '4':
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("ENDPIC",PU_CACHE));
break;
default:
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE));
break;
default:
case '1':
V_DrawPatchIndirect (0, 0, &screen,
W_CacheLumpName (gameinfo.finalePage1, PU_CACHE));
break;
case '2':
V_DrawPatchIndirect (0, 0, &screen,
W_CacheLumpName (gameinfo.finalePage2, PU_CACHE));
break;
case '3':
F_BunnyScroll ();
break;
case '4':
V_DrawPatchIndirect (0, 0, &screen,
W_CacheLumpName (gameinfo.finalePage3, PU_CACHE));
break;
}
break;

View file

@ -21,127 +21,83 @@
//
//-----------------------------------------------------------------------------
#include "z_zone.h"
#include "i_video.h"
#include "v_video.h"
#include "m_random.h"
#include "m_alloc.h"
#include "doomdef.h"
#include "f_wipe.h"
#include "c_cvars.h"
//
// SCREEN WIPE PACKAGE
//
// when zero, stop the wipe
static BOOL go = 0;
short *wipe_scr_start;
short *wipe_scr_end;
screen_t *wipe_scr;
void wipe_shittyColMajorXform (short *array, int width, int height)
enum
{
int x;
int y;
short* dest;
dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
for(y=0;y<height;y++)
for(x=0;x<width;x++)
dest[x*height+y] = array[y*width+x];
memcpy(array, dest, width*height*2);
Z_Free(dest);
}
int wipe_initColorXForm (int width, int height, int ticks)
{
V_DrawBlock (0, 0, wipe_scr, width, height, (byte *)wipe_scr_start);
return 0;
}
int wipe_doColorXForm (int width, int height, int ticks)
{
BOOL changed;
byte* w;
byte* wend;
byte* e;
int newval;
int y;
changed = false;
e = (byte *)wipe_scr_end;
for (y = 0; y < height; y++) {
w = wipe_scr->buffer + wipe_scr->pitch * y;
wend = w + width;
while (w!=wend)
{
if (*w != *e)
{
if (*w > *e)
{
newval = *w - ticks;
if (newval < *e)
*w = *e;
else
*w = (byte)newval;
changed = true;
}
else if (*w < *e)
{
newval = *w + ticks;
if (newval > *e)
*w = *e;
else
*w = (byte)newval;
changed = true;
}
}
w++;
e++;
}
}
return !changed;
}
int wipe_exitColorXForm (int width, int height, int ticks)
{
return 0;
}
wipe_None, // don't bother
wipe_Melt, // weird screen melt
wipe_Burn, // fade in shape of fire
wipe_Fade, // crossfade from old to new
wipe_NUMWIPES
};
cvar_t *wipetype;
static int CurrentWipeType;
static short *wipe_scr_start;
static short *wipe_scr_end;
static int *y;
int wipe_initMelt (int width, int height, int ticks)
// [RH] Fire Wipe
#define FIREWIDTH 64
#define FIREHEIGHT 64
static byte *burnarray;
static int density;
static int burntime;
// [RH] Crossfade
static int fade;
// Melt -------------------------------------------------------------
void wipe_shittyColMajorXform (short *array)
{
int x, y;
short *dest;
int width = screen.width / 2;
dest = (short*) Malloc (width*screen.height*2);
for(y = 0; y < screen.height; y++)
for(x = 0; x < width; x++)
dest[x*screen.height+y] = array[y*width+x];
memcpy(array, dest, screen.width*screen.height);
free (dest);
}
int wipe_initMelt (int ticks)
{
int i, r;
// copy start screen to main screen
V_DrawBlock (0, 0, wipe_scr, width, height, (byte *)wipe_scr_start);
V_DrawBlock (0, 0, &screen, screen.width, screen.height, (byte *)wipe_scr_start);
// makes this wipe faster (in theory)
// to have stuff in column-major format
wipe_shittyColMajorXform (wipe_scr_start, width/2, height);
wipe_shittyColMajorXform (wipe_scr_end, width/2, height);
wipe_shittyColMajorXform (wipe_scr_start);
wipe_shittyColMajorXform (wipe_scr_end);
// setup initial column positions
// (y<0 => not ready to scroll yet)
y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
y = (int *) Z_Malloc (screen.width*sizeof(int), PU_STATIC, 0);
y[0] = -(M_Random()&0xf);
for (i=1;i<width;i++)
for (i = 1; i < screen.width; i++)
{
r = (M_Random()%3) - 1;
y[i] = y[i-1] + r;
@ -152,7 +108,7 @@ int wipe_initMelt (int width, int height, int ticks)
return 0;
}
int wipe_doMelt (int width, int height, int ticks)
int wipe_doMelt (int ticks)
{
int i;
int j;
@ -163,37 +119,38 @@ int wipe_doMelt (int width, int height, int ticks)
short* d;
BOOL done = true;
width/=2;
int width = screen.width / 2;
while (ticks--)
{
for (i=0;i<width;i++)
for (i = 0; i < width; i++)
{
if (y[i]<0)
{
y[i]++; done = false;
}
else if (y[i] < height)
else if (y[i] < screen.height)
{
dy = (y[i] < 16) ? y[i]+1 : 8;
dy = (dy * screen.height) / 200;
if (y[i]+dy >= height) dy = height - y[i];
s = &wipe_scr_end[i*height+y[i]];
d = &((short *)wipe_scr->buffer)[y[i]*(wipe_scr->pitch/2)+i];
if (y[i]+dy >= screen.height)
dy = screen.height - y[i];
s = &wipe_scr_end[i*screen.height+y[i]];
d = &((short *)screen.buffer)[y[i]*(screen.pitch/2)+i];
idx = 0;
for (j=dy;j;j--)
{
d[idx] = *(s++);
idx += wipe_scr->pitch/2;
idx += screen.pitch/2;
}
y[i] += dy;
s = &wipe_scr_start[i*height];
d = &((short *)wipe_scr->buffer)[y[i]*(wipe_scr->pitch/2)+i];
s = &wipe_scr_start[i*screen.height];
d = &((short *)screen.buffer)[y[i]*(screen.pitch/2)+i];
idx = 0;
for (j=height-y[i];j;j--)
for (j=screen.height-y[i];j;j--)
{
d[idx] = *(s++);
idx += wipe_scr->pitch/2;
idx += screen.pitch/2;
}
done = false;
}
@ -204,72 +161,287 @@ int wipe_doMelt (int width, int height, int ticks)
}
int wipe_exitMelt (int width, int height, int ticks)
int wipe_exitMelt (int ticks)
{
free (wipe_scr_start);
free (wipe_scr_end);
Z_Free(y);
Z_Free (y);
return 0;
}
int wipe_StartScreen (int x, int y, int width, int height)
// Burn -------------------------------------------------------------
int wipe_initBurn (int ticks)
{
wipe_scr = &screen;
if (wipe_scr->is8bit)
wipe_scr_start = (short *)Malloc (width * height);
else
wipe_scr_start = (short *)Malloc (width * height * 4);
V_GetBlock (0, 0, wipe_scr, width, height, (byte *)wipe_scr_start);
burnarray = Z_Malloc (FIREWIDTH * (FIREHEIGHT+4), PU_STATIC, 0);
memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+4));
density = 4;
burntime = 0;
return 0;
}
int wipe_EndScreen (int x, int y, int width, int height)
int wipe_doBurn (int ticks)
{
if (wipe_scr->is8bit)
wipe_scr_end = (short *)Malloc (width * height);
else
wipe_scr_end = (short *)Malloc (width * height * 4);
static int voop;
BOOL done;
V_GetBlock (0, 0, wipe_scr, width, height, (byte *)wipe_scr_end);
V_DrawBlock (0, 0, wipe_scr, width, height, (byte *)wipe_scr_start); // restore start scr.
// This is a modified version of the fire from the player
// setup menu.
burntime += ticks;
ticks *= 2;
return 0;
}
int wipe_ScreenWipe (int wipeno, int x, int y, int width, int height, int ticks)
{
int rc;
static int (*wipes[])(int, int, int) =
// Make the fire burn
while (ticks--)
{
wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
wipe_initMelt, wipe_doMelt, wipe_exitMelt
};
int a, b;
byte *from;
void V_MarkRect(int, int, int, int);
// generator
from = burnarray + FIREHEIGHT * FIREWIDTH;
b = voop;
voop += density / 3;
for (a = 0; a < density/8; a++)
{
unsigned int offs = (a+b) % FIREWIDTH;
unsigned int v = M_Random();
v = from[offs] + 4 + (v & 15) + (v >> 3) + (M_Random() & 31);
if (v > 255)
v = 255;
from[offs] = from[FIREWIDTH*2 + (offs + FIREWIDTH*3/2)%FIREWIDTH] = v;
}
density += 10;
if (density > FIREWIDTH*7)
density = FIREWIDTH*7;
from = burnarray;
for (b = 0; b <= FIREHEIGHT; b += 2)
{
byte *pixel = from;
// special case: first pixel on line
byte *p = pixel + (FIREWIDTH << 1);
unsigned int top = *p + *(p + FIREWIDTH - 1) + *(p + 1);
unsigned int bottom = *(pixel + (FIREWIDTH << 2));
unsigned int c1 = (top + bottom) >> 2;
if (c1 > 1) c1--;
*pixel = c1;
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1;
pixel++;
// main line loop
for (a = 1; a < FIREWIDTH-1; a++)
{
// sum top pixels
p = pixel + (FIREWIDTH << 1);
top = *p + *(p - 1) + *(p + 1);
// bottom pixel
bottom = *(pixel + (FIREWIDTH << 2));
// combine pixels
c1 = (top + bottom) >> 2;
if (c1 > 1) c1--;
// store pixels
*pixel = c1;
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1; // interpolate
// next pixel
pixel++;
}
// special case: last pixel on line
p = pixel + (FIREWIDTH << 1);
top = *p + *(p - 1) + *(p - FIREWIDTH + 1);
bottom = *(pixel + (FIREWIDTH << 2));
c1 = (top + bottom) >> 2;
if (c1 > 1) c1--;
*pixel = c1;
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1;
// next line
from += FIREWIDTH << 1;
}
}
// Draw the screen
{
fixed_t xstep, ystep, firex, firey;
int x, y;
byte *to, *fromold, *fromnew;
xstep = (FIREWIDTH * FRACUNIT) / screen.width;
ystep = (FIREHEIGHT * FRACUNIT) / screen.height;
to = screen.buffer;
fromold = (byte *)wipe_scr_start;
fromnew = (byte *)wipe_scr_end;
done = true;
for (y = 0, firey = 0; y < screen.height; y++, firey += ystep)
{
for (x = 0, firex = 0; x < screen.width; x++, firex += xstep)
{
int fglevel;
fglevel = burnarray[(firex>>FRACBITS)+(firey>>FRACBITS)*FIREWIDTH] / 2;
if (fglevel >= 63)
{
to[x] = fromnew[x];
}
else if (fglevel == 0)
{
to[x] = fromold[x];
done = false;
}
else
{
int bglevel = 64-fglevel;
unsigned int *fg2rgb = Col2RGB8[fglevel];
unsigned int *bg2rgb = Col2RGB8[bglevel];
unsigned int fg = fg2rgb[fromnew[x]];
unsigned int bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0xf07c3e1f;
to[x] = RGB8k[0][0][(fg>>5) & (fg>>19)];
done = false;
}
}
fromold += screen.width;
fromnew += screen.width;
to += screen.pitch;
}
}
return done || (burntime > 40);
}
int wipe_exitBurn (int ticks)
{
free (wipe_scr_start);
free (wipe_scr_end);
Z_Free (burnarray);
return 0;
}
// Crossfade --------------------------------------------------------
int wipe_initFade (int ticks)
{
fade = 0;
return 0;
}
int wipe_doFade (int ticks)
{
fade += ticks;
if (fade > 64)
{
V_DrawBlock (0, 0, &screen, screen.width, screen.height, (byte *)wipe_scr_end);
return 1;
}
else
{
int x, y;
fixed_t bglevel = 64 - fade;
unsigned int *fg2rgb = Col2RGB8[fade];
unsigned int *bg2rgb = Col2RGB8[bglevel];
byte *fromnew = (byte *)wipe_scr_end;
byte *fromold = (byte *)wipe_scr_start;
byte *to = screen.buffer;
for (y = 0; y < screen.height; y++)
{
for (x = 0; x < screen.width; x++)
{
unsigned int fg = fg2rgb[fromnew[x]];
unsigned int bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0xf07c3e1f;
to[x] = RGB8k[0][0][(fg>>5) & (fg>>19)];
}
fromnew += screen.width;
fromold += screen.width;
to += screen.pitch;
}
}
fade++;
return 0;
}
int wipe_exitFade (int ticks)
{
return 0;
}
// General Wipe Functions -------------------------------------------
int wipe_StartScreen (void)
{
CurrentWipeType = (int)wipetype->value;
if (CurrentWipeType < 0)
CurrentWipeType = 0;
else if (CurrentWipeType >= wipe_NUMWIPES)
CurrentWipeType = wipe_NUMWIPES-1;
if (CurrentWipeType)
{
if (screen.is8bit)
wipe_scr_start = (short *)Malloc (screen.width * screen.height);
else
wipe_scr_start = (short *)Malloc (screen.width * screen.height * 4);
V_GetBlock (0, 0, &screen, screen.width, screen.height, (byte *)wipe_scr_start);
}
return 0;
}
int wipe_EndScreen (void)
{
if (CurrentWipeType)
{
if (screen.is8bit)
wipe_scr_end = (short *)Malloc (screen.width * screen.height);
else
wipe_scr_end = (short *)Malloc (screen.width * screen.height * 4);
V_GetBlock (0, 0, &screen, screen.width, screen.height, (byte *)wipe_scr_end);
V_DrawBlock (0, 0, &screen, screen.width, screen.height, (byte *)wipe_scr_start); // restore start scr.
}
return 0;
}
int wipe_ScreenWipe (int ticks)
{
static BOOL go = 0; // when zero, stop the wipe
static int (*wipes[])(int) =
{
wipe_initMelt, wipe_doMelt, wipe_exitMelt,
wipe_initBurn, wipe_doBurn, wipe_exitBurn,
wipe_initFade, wipe_doFade, wipe_exitFade
};
int rc;
if (CurrentWipeType == wipe_None)
return true;
// initial stuff
if (!go)
{
go = 1;
// wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
wipe_scr = &screen;
(*wipes[wipeno*3])(width, height, ticks);
(*wipes[(CurrentWipeType-1)*3])(ticks);
}
// do a piece of wipe-in
V_MarkRect(0, 0, width, height);
rc = (*wipes[wipeno*3+1])(width, height, ticks);
// V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
V_MarkRect(0, 0, screen.width, screen.height);
rc = (*wipes[(CurrentWipeType-1)*3+1])(ticks);
// final stuff
if (rc)
{
go = 0;
(*wipes[wipeno*3+2])(width, height, ticks);
(*wipes[(CurrentWipeType-1)*3+2])(ticks);
}
return !go;
}

View file

@ -557,6 +557,7 @@ BOOL G_Responder (event_t *ev)
stricmp (cmd, "+showscores") &&
stricmp (cmd, "bumpgamma") &&
stricmp (cmd, "screenshot"))) {
S_Sound (NULL, CHAN_VOICE, "switches/normbutn", 1, ATTN_NONE);
M_StartControlPanel ();
return true;
} else {
@ -629,11 +630,14 @@ BOOL G_Responder (event_t *ev)
// G_Ticker
// Make ticcmd_ts for the players.
//
extern screen_t page;
void G_Ticker (void)
{
int i;
int buf;
ticcmd_t* cmd;
gamestate_t oldgamestate;
// do player reborns if needed
for (i=0 ; i<MAXPLAYERS ; i++)
@ -641,6 +645,7 @@ void G_Ticker (void)
G_DoReborn (i);
// do things to change the game state
oldgamestate = gamestate;
while (gameaction != ga_nothing)
{
switch (gameaction)
@ -688,6 +693,9 @@ void G_Ticker (void)
C_AdjustBottom ();
}
if (oldgamestate == GS_DEMOSCREEN && oldgamestate != gamestate && page.impdata)
V_FreeScreen (&page);
// get commands, check consistancy,
// and build new consistancy check
buf = (gametic/ticdup)%BACKUPTICS;
@ -717,8 +725,7 @@ void G_Ticker (void)
if (gametic > BACKUPTICS
&& consistancy[i][buf] != cmd->consistancy)
{
Printf_Bold ("Consistency failure! %d: %i (!%i)\n",
i, cmd->consistancy, consistancy[i][buf]);
players[i].inconsistant = 1;
}
if (players[i].mo)
consistancy[i][buf] = players[i].mo->x;
@ -1113,6 +1120,7 @@ void G_LoadGame (char* name)
void G_DoLoadGame (void)
{
extern BOOL ZDoom117aSave;
int length;
int i;
char mapname[9];
@ -1122,8 +1130,18 @@ void G_DoLoadGame (void)
length = M_ReadFile (savename, &savebuffer);
save_p = savebuffer + SAVESTRINGSIZE; // skip the description field
if (strncmp (save_p, SAVESIG, 16)) // Bad version
I_Error ("Savegame is from a different version\n");
if (strncmp (save_p, SAVESIG, 16))
{ // Bad version
// This is a quick hack to support ZDoom 1.17 and 1.17a savegames
// with 1.17b. 1.17b mobjs have a translucency field. Earlier
// versions used flags bits to specify it.
if (strncmp (save_p, "ZDOOMSAVE117 ", 16))
I_Error ("Savegame is from a different version\n");
else
ZDoom117aSave = true;
}
else
ZDoom117aSave = false;
save_p += 16;
@ -1663,7 +1681,7 @@ BOOL G_CheckDemoStatus (void)
int endtime;
if (timingdemo)
endtime = I_GetTimeReally () - starttime;
endtime = I_GetTimePolled () - starttime;
C_RestoreCVars (); // [RH] Restore cvars demo might have changed

View file

@ -28,6 +28,7 @@
#include "v_text.h"
#include "s_sndseq.h"
#include "gi.h"
#include "minilzo.h"
// [RH] Output buffer size for LZO compression.
@ -585,7 +586,6 @@ void G_InitNew (char *mapname)
//
BOOL secretexit;
static int startpos; // [RH] Support for multiple starts per level
extern char* pagename;
extern BOOL NoWipe; // [RH] Don't wipe when travelling in hubs
// [RH] The position parameter to these next two functions should
@ -818,7 +818,7 @@ void G_DoLoadLevel (int position)
static BOOL firstTime = true;
if (firstTime) {
starttime = I_GetTimeReally ();
starttime = I_GetTimePolled ();
firstTime = false;
}
}
@ -948,9 +948,12 @@ char *CalcMapName (int episode, int level)
{
static char lumpname[9];
if (gamemode == commercial) {
if (gameinfo.flags & GI_MAPxx)
{
sprintf (lumpname, "MAP%02d", level);
} else {
}
else
{
lumpname[0] = 'E';
lumpname[1] = '0' + episode;
lumpname[2] = 'M';
@ -1095,7 +1098,7 @@ void G_SnapshotLevel (void)
save_p = savebuffer = Malloc (savegamesize);
if (level.info->snapshot)
Z_Free (level.info->snapshot);
free (level.info->snapshot);
WriteLong (level.flags, &save_p);
WriteLong (level.fadeto, &save_p);
@ -1134,7 +1137,7 @@ void G_SnapshotLevel (void)
DPrintf ("Snapshot: %d .. %d bytes\n", len, outlen);
}
level.info->snapshot = Z_Malloc (((outlen == 0) ? len : outlen) + sizeof(int)*2, PU_STATIC, 0);
level.info->snapshot = Malloc (((outlen == 0) ? len : outlen) + sizeof(int)*2);
((int *)(level.info->snapshot))[0] = outlen;
((int *)(level.info->snapshot))[1] = len;
if (outlen == 0)
@ -1163,7 +1166,7 @@ void G_UnSnapshotLevel (BOOL keepPlayers)
if (cprlen) {
int r, newlen;
expand = Z_Malloc (expandsize, PU_STATIC, 0);
expand = Malloc (expandsize);
r = lzo1x_decompress (level.info->snapshot + sizeof(int)*2, cprlen, expand, &newlen, NULL);
if (r != LZO_E_OK || newlen != expandsize) {
Printf (PRINT_HIGH, "Could not decompress snapshot");
@ -1192,10 +1195,10 @@ void G_UnSnapshotLevel (BOOL keepPlayers)
P_UnArchiveSounds ();
if (expand)
Z_Free (expand);
free (expand);
// No reason to keep the snapshot around once the level's been entered.
Z_Free (level.info->snapshot);
free (level.info->snapshot);
level.info->snapshot = NULL;
save_p = NULL;
@ -1207,13 +1210,13 @@ void G_ClearSnapshots (void)
for (i = 0; i < numwadlevelinfos; i++)
if (wadlevelinfos[i].snapshot) {
Z_Free (wadlevelinfos[i].snapshot);
free (wadlevelinfos[i].snapshot);
wadlevelinfos[i].snapshot = NULL;
}
for (i = 0; LevelInfos[i].level_name; i++)
if (LevelInfos[i].snapshot) {
Z_Free (LevelInfos[i].snapshot);
free (LevelInfos[i].snapshot);
LevelInfos[i].snapshot = NULL;
}
}
@ -1266,7 +1269,7 @@ void G_UnArchiveSnapshots (void)
fullsize = ((int *)save_p)[1];
savesize = (shortsize ? shortsize : fullsize) + sizeof(int)*2;
if (i) {
i->snapshot = Z_Malloc (savesize, PU_STATIC, 0);
i->snapshot = Malloc (savesize);
memcpy (i->snapshot, save_p, savesize);
}
save_p += savesize;

File diff suppressed because it is too large Load diff

View file

@ -1353,7 +1353,7 @@ typedef enum {
// [RH] Miscellaneous things
MT_UNKNOWNTHING,
MT_MAPSPOT,
MT_MAPSPOTGRAV,
MT_MAPSPOTGRAVITY,
MT_BRIDGE,
MT_PUSH, // Boom's push thing
MT_PULL, // Boom's pull thing
@ -1393,6 +1393,7 @@ typedef struct
int flags;
int flags2;
int raisestate;
int translucency;
} mobjinfo_t;

View file

@ -35,42 +35,30 @@
#include <sys/stat.h>
#endif
#include "doomdef.h"
#include "dstrings.h"
#include "c_consol.h"
#include "c_dispch.h"
#include "d_main.h"
#include "i_system.h"
#include "i_input.h"
#include "i_video.h"
#include "z_zone.h"
#include "v_video.h"
#include "w_wad.h"
#include "r_local.h"
#include "hu_stuff.h"
#include "g_game.h"
#include "m_argv.h"
#include "m_swap.h"
#include "m_random.h"
#include "s_sound.h"
#include "doomstat.h"
#include "m_menu.h"
#include "v_text.h"
#include "st_stuff.h"
#include "gi.h"
extern patch_t* hu_font[HU_FONTSIZE];
@ -106,7 +94,6 @@ int saveCharIndex; // which char we're editing
// old save description before edit
char saveOldString[SAVESTRINGSIZE];
BOOL inhelpscreens;
BOOL menuactive;
#define SKULLXOFF -32
@ -255,7 +242,7 @@ oldmenuitem_t EpisodeMenu[]=
oldmenu_t EpiDef =
{
ep_end, // # of menu items
ep4, // # of menu items
EpisodeMenu, // oldmenuitem_t ->
M_DrawEpisode, // drawing routine ->
48,63, // x,y
@ -799,21 +786,8 @@ void M_QuickLoad(void)
//
void M_DrawReadThis1(void)
{
inhelpscreens = true;
switch ( gamemode )
{
case commercial:
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP",PU_CACHE));
break;
case shareware:
case registered:
case retail:
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP1",PU_CACHE));
break;
default:
break;
}
return;
V_DrawPatchIndirect (0, 0, &screen,
W_CacheLumpName (gameinfo.info.infoPage[0], PU_CACHE));
}
@ -823,22 +797,8 @@ void M_DrawReadThis1(void)
//
void M_DrawReadThis2(void)
{
inhelpscreens = true;
switch ( gamemode )
{
case retail:
case commercial:
// This hack keeps us from having to change menus.
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("CREDIT",PU_CACHE));
break;
case shareware:
case registered:
V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE));
break;
default:
break;
}
return;
V_DrawPatchIndirect (0, 0, &screen,
W_CacheLumpName (gameinfo.info.infoPage[1], PU_CACHE));
}
@ -870,7 +830,7 @@ void M_NewGame(int choice)
return;
}
if (gamemode == commercial)
if (gameinfo.flags & GI_MAPxx)
M_SetupNextMenu(&NewDef);
else
M_SetupNextMenu(&EpiDef);
@ -915,20 +875,13 @@ void M_ChooseSkill(int choice)
void M_Episode (int choice)
{
if ((gamemode == shareware) && choice)
if ((gameinfo.flags & GI_SHAREWARE) && choice)
{
M_StartMessage(SWSTRING,NULL,false);
M_SetupNextMenu(&ReadDef1);
return;
}
// Yet another hack...
if ((gamemode != retail) && (choice > 2))
{
Printf (PRINT_HIGH, "M_Episode: 4th episode requires Ultimate DOOM\n");
choice = 0;
}
epi = choice;
M_SetupNextMenu(&NewDef);
}
@ -1011,37 +964,9 @@ void M_FinishReadThis(int choice)
M_SetupNextMenu(&MainDef);
}
//
// M_QuitDOOM
//
char *quitsounds[8] =
{
"player/male/death1",
"demon/pain",
"grunt/pain",
"misc/gibbed",
"misc/teleport",
"grunt/sight1",
"grunt/sight3",
"demon/melee"
};
char *quitsounds2[8] =
{
"vile/active",
"misc/p_pkup",
"brain/cube",
"misc/gibbed",
"skeleton/swing",
"knight/death",
"baby/active",
"demon/melee"
};
void M_QuitResponse(int ch)
{
@ -1049,19 +974,16 @@ void M_QuitResponse(int ch)
return;
if (!netgame)
{
if (gamemode == commercial) {
S_Sound (NULL, CHAN_VOICE, quitsounds2[(gametic>>2)&7], 1, ATTN_SURROUND);
} else {
S_Sound (NULL, CHAN_VOICE, quitsounds[(gametic>>2)&7], 1, ATTN_SURROUND);
if (gameinfo.quitSounds)
{
S_Sound (NULL, CHAN_VOICE, gameinfo.quitSounds[(gametic>>2)&7],
1, ATTN_SURROUND);
I_WaitVBL (105);
}
I_WaitVBL(105);
}
exit (0);
}
void M_QuitDOOM (int choice)
{
// We pick index 0 which is language sensitive,
@ -1787,6 +1709,8 @@ void M_StartControlPanel (void)
drawSkull = true;
MenuStackDepth = 0;
menuactive = 1;
currentMenu = &MainDef;
itemOn = currentMenu->lastOn;
C_HideConsole (); // [RH] Make sure console goes bye bye.
OptionsActive = false; // [RH] Make sure none of the options menus appear.
I_PauseMouse (); // [RH] Give the mouse back in windowed modes.
@ -1807,8 +1731,6 @@ void M_Drawer (void)
char string[80];
int start;
inhelpscreens = false;
// Horiz. & Vertically center string and print it.
if (messageToPrint)
{
@ -1978,31 +1900,30 @@ void M_Init (void)
// Here we could catch other version dependencies,
// like HELP1/2, and four episodes.
switch ( gamemode )
switch (gameinfo.flags & GI_MENUHACK)
{
case commercial:
// This is used because DOOM 2 had only one HELP
// page. I use CREDIT as second page now, but
// kept this hack for educational purposes.
MainMenu[readthis] = MainMenu[quitdoom];
MainDef.numitems--;
MainDef.y += 8;
ReadDef1.routine = M_DrawReadThis1;
ReadDef1.x = 330;
ReadDef1.y = 165;
ReadMenu1[0].routine = M_FinishReadThis;
break;
case shareware:
// Episode 2 and 3 are handled,
// branching to an ad screen.
case registered:
// We need to remove the fourth episode.
EpiDef.numitems--;
break;
case retail:
// We are fine.
default:
break;
case GI_MENUHACK_COMMERCIAL:
// This is used because DOOM 2 had only one HELP
// page. I use CREDIT as second page now, but
// kept this hack for educational purposes.
MainMenu[readthis] = MainMenu[quitdoom];
MainDef.numitems--;
MainDef.y += 8;
ReadDef1.routine = M_DrawReadThis1;
ReadDef1.x = 330;
ReadDef1.y = 165;
ReadMenu1[0].routine = M_FinishReadThis;
break;
case GI_MENUHACK_RETAIL:
// add the fourth episode.
EpiDef.numitems++;
break;
case GI_MENUHACK_EXTENDED:
// EpisodeMenu.itemCount = 5;
// EpisodeMenu.y -= ITEM_HEIGHT;
break;
default:
break;
}
M_OptInit ();

View file

@ -127,6 +127,83 @@ int M_ReadFile (char const *name, byte **buffer)
return length;
}
//---------------------------------------------------------------------------
//
// PROC M_FindResponseFile
//
//---------------------------------------------------------------------------
#define MAXARGVS 100
void M_FindResponseFile (void)
{
int i;
for (i = 1; i < myargc; i++)
{
if (myargv[i][0] == '@')
{
FILE * handle;
int size;
int k;
int index;
int indexinfile;
char *infile;
char *file;
char *moreargs[20];
char *firstargv;
// READ THE RESPONSE FILE INTO MEMORY
handle = fopen (&myargv[i][1],"rb");
if (!handle)
I_FatalError ("\nNo such response file!");
Printf (PRINT_HIGH, "Found response file %s!\n", &myargv[i][1]);
fseek (handle,0,SEEK_END);
size = ftell(handle);
fseek (handle,0,SEEK_SET);
file = Malloc (size);
fread (file,size,1,handle);
fclose (handle);
// KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
for (index = 0,k = i+1; k < myargc; k++)
moreargs[index++] = myargv[k];
firstargv = myargv[0];
myargv = Malloc(sizeof(char *)*MAXARGVS);
memset(myargv,0,sizeof(char *)*MAXARGVS);
myargv[0] = firstargv;
infile = file;
indexinfile = k = 0;
indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
do
{
myargv[indexinfile++] = infile+k;
while(k < size &&
((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
k++;
*(infile+k) = 0;
while(k < size &&
((*(infile+k)<= ' ') || (*(infile+k)>'z')))
k++;
} while(k < size);
for (k = 0;k < index;k++)
myargv[indexinfile++] = moreargs[k];
myargc = indexinfile;
// DISPLAY ARGS
Printf (PRINT_HIGH, "%d command-line args:\n",myargc);
for (k = 1; k < myargc; k++)
Printf (PRINT_HIGH, "%s\n",myargv[k]);
break;
}
}
}
//
// DEFAULTS
@ -194,7 +271,8 @@ void M_SaveDefaults (void)
configfile = GetConfigPath ();
// Make sure the user hasn't changed configver
cvar_set ("configver", VERSIONSTR);
//cvar_set ("configver", VERSIONSTR);
cvar_set ("configver", "117.2");
if ( (f = fopen (configfile, "w")) ) {
fprintf (f, "// Generated by ZDOOM - don't hurt anything\n");
@ -219,6 +297,7 @@ void M_SaveDefaults (void)
//
extern byte scantokey[128];
extern int cvar_defflags;
extern cvar_t *dimamount;
void M_LoadDefaults (void)
{
@ -234,7 +313,8 @@ void M_LoadDefaults (void)
// Used to identify the version of the game that saved
// a config file to compensate for new features that get
// put into newer configfiles.
configver = cvar ("configver", VERSIONSTR, CVAR_ARCHIVE);
// configver = cvar ("configver", VERSIONSTR, CVAR_ARCHIVE);
configver = cvar ("configver", "117.2", CVAR_ARCHIVE);
configfile = GetConfigPath ();
execcommand = Malloc (strlen (configfile) + 8);
@ -251,10 +331,16 @@ void M_LoadDefaults (void)
AddCommandString (execcommand);
free (execcommand);
if (configver->value <= 113.0f) {
AddCommandString ("bind t messagemode; bind \\ +showscores; bind f12 spynext; bind sysrq screenshot");
if (C_GetBinding (KEY_F5) && !stricmp (C_GetBinding (KEY_F5), "menu_video"))
AddCommandString ("bind f5 menu_display");
if (configver->value < 117.2f)
{
SetCVarFloat (dimamount, dimamount->value / 4);
if (configver->value <= 113.0f)
{
AddCommandString ("bind t messagemode; bind \\ +showscores;"
"bind f12 spynext; bind sysrq screenshot");
if (C_GetBinding (KEY_F5) && !stricmp (C_GetBinding (KEY_F5), "menu_video"))
AddCommandString ("bind f5 menu_display");
}
}
DefaultsLoaded = true;

View file

@ -25,15 +25,10 @@
#include "doomtype.h"
//
// MISC
//
BOOL M_WriteFile (char const *name, void *source, int length);
int M_ReadFile (char const *name, byte **buffer);
void M_FindResponseFile (void);
// [RH] M_ScreenShot now accepts a filename parameter.
// Pass a NULL to get the original behavior.

View file

@ -8,22 +8,21 @@
####################################################################
CC = gcc
# sorry, but the DOS version of nasm runs out of memory
AS = d:/nasm/nasmw
RM = del
CP = copy
# options common to all builds
IMPDIR = djgpp
CFLAGS_common = -Wall -Winline -I. -I$(IMPDIR) -idirafter ../ptc/source
CFLAGS_common = -Wall -Winline -DUSEASM -I. -I$(IMPDIR) -idirafter ../ptc/source
OUTFILE = zdoomdos.exe
# options specific to the debug build
CFLAGS_debug = -g -O2 -DNOASM
CFLAGS_debug = -g -O2 -DRANGECHECK
LFLAGS_debug =
# options specific to the release build
CFLAGS_release = -O3 -ffast-math -fomit-frame-pointer -m486 -DUSEASM
CFLAGS_release = -O3 -ffast-math -fomit-frame-pointer -m486
LFLAGS_release = -s
# libraries to link with
@ -65,6 +64,7 @@ OBJS = \
$(INTDIR)/f_wipe.o \
$(INTDIR)/g_game.o \
$(INTDIR)/g_level.o \
$(INTDIR)/gi.o \
$(INTDIR)/i_input.o \
$(INTDIR)/i_main.o \
$(INTDIR)/i_music.o \
@ -142,7 +142,6 @@ OBJS = \
zdoom doom release all: $(INTDIR)/$(OUTFILE)
$(CP) $(IMPDIR)\$(mode)\$(OUTFILE) .
# why doesn't this work?
debug:
$(MAKE) mode=debug
@ -171,7 +170,7 @@ $(INTDIR)/%.o: $(IMPDIR)/%.cpp
# Changing the makefile rebuilds everything else
$(OBJS): Makefile.dj
# Dependencies for each file (this is why I automatically
# Dependencies for each file (which is why I automatically
# generated this file instead of writing it all by hand).
$(INTDIR)/am_map.o: am_map.c \
@ -251,6 +250,7 @@ $(INTDIR)/c_cmds.o: c_cmds.c \
dstrings.h \
g_game.h \
g_level.h \
gi.h \
info.h \
m_fixed.h \
p_inter.h \
@ -283,6 +283,7 @@ $(INTDIR)/c_consol.o: c_consol.c \
dstrings.h \
g_game.h \
g_level.h \
gi.h \
hu_stuff.h \
info.h \
m_alloc.h \
@ -491,6 +492,7 @@ $(INTDIR)/d_main.o: d_main.c \
f_wipe.h \
g_game.h \
g_level.h \
gi.h \
hu_stuff.h \
info.h \
lzoconf.h \
@ -519,6 +521,7 @@ $(INTDIR)/d_main.o: d_main.c \
st_stuff.h \
tables.h \
v_palett.h \
v_text.h \
v_video.h \
w_wad.h \
wi_stuff.h \
@ -545,6 +548,7 @@ $(INTDIR)/d_net.o: d_net.c \
doomtype.h \
g_game.h \
g_level.h \
gi.h \
info.h \
m_alloc.h \
m_cheat.h \
@ -693,6 +697,7 @@ $(INTDIR)/f_finale.o: f_finale.c \
doomtype.h \
dstrings.h \
g_level.h \
gi.h \
hu_stuff.h \
info.h \
m_fixed.h \
@ -824,6 +829,7 @@ $(INTDIR)/g_level.o: g_level.c \
f_finale.h \
g_game.h \
g_level.h \
gi.h \
hu_stuff.h \
info.h \
lzoconf.h \
@ -861,6 +867,12 @@ $(INTDIR)/g_level.o: g_level.c \
$(IMPDIR)/i_system.h \
z_zone.h
$(INTDIR)/gi.o: gi.c \
d_think.h \
doomtype.h \
gi.h \
info.h
$(INTDIR)/info.o: info.c \
d_think.h \
doomdata.h \
@ -954,6 +966,7 @@ $(INTDIR)/m_menu.o: m_menu.c \
dstrings.h \
g_game.h \
g_level.h \
gi.h \
hu_stuff.h \
info.h \
m_argv.h \
@ -1277,6 +1290,7 @@ $(INTDIR)/p_enemy.o: p_enemy.c \
doomtype.h \
g_game.h \
g_level.h \
gi.h \
info.h \
m_fixed.h \
m_random.h \
@ -1750,7 +1764,9 @@ $(INTDIR)/p_saveg.o: p_saveg.c \
z_zone.h
$(INTDIR)/p_setup.o: p_setup.c \
c_consol.h \
c_cvars.h \
cmdlib.h \
d_event.h \
d_items.h \
d_net.h \
@ -1891,6 +1907,7 @@ $(INTDIR)/p_switch.o: p_switch.c \
doomtype.h \
g_game.h \
g_level.h \
gi.h \
info.h \
m_fixed.h \
p_lnspec.h \
@ -2211,6 +2228,7 @@ $(INTDIR)/r_draw.o: r_draw.c \
doomstat.h \
doomtype.h \
g_level.h \
gi.h \
info.h \
m_alloc.h \
m_fixed.h \
@ -2255,7 +2273,9 @@ $(INTDIR)/r_drawt.o: r_drawt.c \
r_main.h \
r_state.h \
r_things.h \
tables.h
tables.h \
v_palett.h \
v_video.h
$(INTDIR)/r_main.o: r_main.c \
c_cvars.h \

View file

@ -204,7 +204,7 @@ BOOL EV_DoCeiling (ceiling_e type, line_t *line,
sec = &sectors[secnum];
manual_ceiling:
// if ceiling already moving, don't start a second function on it
if (P_SectorActive (ceiling_special, sec)) //jff 2/22/98
if (sec->ceilingdata)
continue;
// new door thinker
@ -406,8 +406,9 @@ manual_ceiling:
//
void P_AddActiveCeiling (ceiling_t *c)
{
c->next = activeceilings;
c->prev = NULL;
if ( (c->next = activeceilings) )
c->next->prev = &c->next;
c->prev = &activeceilings;
activeceilings = c;
}
@ -424,14 +425,9 @@ void P_RemoveActiveCeiling (ceiling_t *c)
while (scan) {
if (scan == c) {
c->sector->ceilingdata = NULL;
if (c == activeceilings) {
activeceilings = c->next;
} else {
if (c->prev)
c->prev->next = c->next;
if (c->next)
c->next->prev = c->prev;
}
if ( (*(c->prev) = c->next) )
c->next->prev = c->prev;
P_RemoveThinker (&c->thinker);
break;
}

View file

@ -294,7 +294,7 @@ BOOL EV_DoDoor (vldoor_e type, line_t *line, mobj_t *thing,
{
sec = &sectors[secnum];
// if the ceiling already moving, don't start the door action
if (P_SectorActive (ceiling_special,sec)) //jff 2/22/98
if (sec->ceilingdata)
continue;
rtn |= SpawnDoor (sec, type, speed, delay);

View file

@ -28,22 +28,18 @@
#include "m_random.h"
#include "i_system.h"
#include "doomdef.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "p_effect.h"
#include "s_sound.h"
#include "g_game.h"
// State.
#include "doomstat.h"
#include "r_state.h"
#include "c_cvars.h"
#include "gi.h"
cvar_t *testgibs;
@ -279,9 +275,9 @@ BOOL P_Move (mobj_t *actor)
fixed_t tryx, tryy, deltax, deltay, origx, origy;
BOOL try_ok;
int good;
int speed;
int movefactor = ORIG_FRICTION_FACTOR;
int friction = ORIG_FRICTION;
int speed;
if (actor->movedir == DI_NODIR)
return false;
@ -289,15 +285,17 @@ BOOL P_Move (mobj_t *actor)
if ((unsigned)actor->movedir >= 8)
I_Error ("Weird actor->movedir!");
speed = actor->info->speed;
#if 0 // [RH] I'm not so sure this is such a good idea
// killough 10/98: make monsters get affected by ice and sludge too:
movefactor = P_GetMoveFactor (actor, &friction);
speed = actor->info->speed;
if (friction < ORIG_FRICTION && // sludge
!(speed = ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2)
* speed) / ORIG_FRICTION_FACTOR))
speed = 1; // always give the monster a little bit of speed
#endif
tryx = (origx = actor->x) + (deltax = speed * xspeed[actor->movedir]);
tryy = (origy = actor->y) + (deltay = speed * yspeed[actor->movedir]);
@ -682,7 +680,7 @@ void A_Look (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_IncreaseVisibility(actor);
actor->visdir = 1;
}
if (targ && (targ->flags & MF_SHOOTABLE) )
@ -745,7 +743,7 @@ void A_Chase (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_DecreaseVisibility(actor);
actor->visdir = -1;
}
if (actor->reactiontime)
@ -875,7 +873,7 @@ void A_FaceTarget (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_IncreaseVisibility(actor);
actor->visdir = 1;
}
actor->flags &= ~MF_AMBUSH;
@ -905,7 +903,7 @@ void A_MonsterRail (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_IncreaseVisibility(actor);
actor->visdir = 1;
}
actor->flags &= ~MF_AMBUSH;
@ -915,7 +913,9 @@ void A_MonsterRail (mobj_t *actor)
actor->target->x,
actor->target->y);
actor->pitch = FixedDiv (P_AimLineAttack (actor, actor->angle, MISSILERANGE), -40960);
// The -2000 makes the monster aim a bit higher (at your chest instead
// of your butt).
actor->pitch = FixedDiv (P_AimLineAttack (actor, actor->angle, MISSILERANGE), -40960) - 2000;
// Let the aim trail behind the player
actor->angle = R_PointToAngle2 (actor->x,
@ -929,7 +929,7 @@ void A_MonsterRail (mobj_t *actor)
actor->angle += (t-P_Random(pr_facetarget))<<21;
}
P_RailAttack (actor, actor->damage, 0);
P_RailAttack (actor, actor->info->damage, 0);
}
//
@ -993,7 +993,7 @@ void A_CPosAttack (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_IncreaseVisibility(actor);
actor->visdir = 1;
}
S_Sound (actor, CHAN_WEAPON, "chainguy/attack", 1, ATTN_NORM);
@ -1048,7 +1048,7 @@ void A_BspiAttack (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_IncreaseVisibility(actor);
actor->visdir = 1;
}
A_FaceTarget (actor);
@ -1373,7 +1373,10 @@ void A_VileChase (mobj_t *actor)
P_SetMobjState (corpsehit,info->raisestate);
corpsehit->height = info->height; // [RH] Use real mobj height
corpsehit->radius = info->radius; // [RH] Use real radius
corpsehit->flags = (info->flags & ~MF_TRANSLUCBITS) | MF_TRANSLUC50;
if (corpsehit->translucency > TRANSLUC50)
corpsehit->translucency /= 2;
corpsehit->flags = info->flags;
corpsehit->flags2 = info->flags2;
corpsehit->health = info->spawnhealth;
corpsehit->target = NULL;
@ -1761,7 +1764,8 @@ void A_Fall (mobj_t *actor)
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
P_BecomeVisible(actor);
actor->translucency = FRACUNIT;
actor->visdir = 0;
}
// actor is on ground, it can be walked over
@ -1937,7 +1941,7 @@ void A_BossDeath (mobj_t *mo)
}
// [RH] If noexit, then don't end the level.
if (deathmatch->value && (dmflags & DF_NO_EXIT))
if ((deathmatch->value || fakedmatch->value) && (dmflags & DF_NO_EXIT))
return;
G_ExitLevel (0);
@ -2078,7 +2082,7 @@ void A_BrainExplode (mobj_t *mo)
void A_BrainDie (mobj_t *mo)
{
// [RH] If noexit, then don't end the level.
if (deathmatch->value && (dmflags & DF_NO_EXIT))
if ((deathmatch->value || fakedmatch->value) && (dmflags & DF_NO_EXIT))
return;
G_ExitLevel (0);
@ -2184,8 +2188,8 @@ void A_PlayerScream (mobj_t *mo)
{
char nametemp[128];
char *sound;
if ((gamemode == commercial) && (mo->health < -50))
if (!(gameinfo.flags & GI_NOCRAZYDEATH) && (mo->health < -50))
{
// IF THE PLAYER DIES LESS THAN -50% WITHOUT GIBBING
sound = "*xdeath1";
@ -2197,52 +2201,3 @@ void A_PlayerScream (mobj_t *mo)
S_Sound (mo, CHAN_VOICE, sound, 1, ATTN_NORM);
}
/***** Start of new functions for Andy Baker's stealth monsters ******/
void P_BecomeVisible (mobj_t *actor)
{
actor->flags2 &= ~MF2_DONTDRAW;
actor->flags &= ~MF_TRANSLUCBITS;
};
void P_IncreaseVisibility (mobj_t *actor)
{
if (actor->flags2 & MF2_DONTDRAW) {
actor->flags2 &= ~MF2_DONTDRAW;
actor->flags |= MF_TRANSLUC25;
} else switch (actor->flags & MF_TRANSLUCBITS) {
case MF_TRANSLUC25:
actor->flags ^= MF_TRANSLUCBITS;
break;
case MF_TRANSLUC50:
actor->flags |= MF_TRANSLUC25;
break;
case MF_TRANSLUC75:
actor->flags &= ~MF_TRANSLUCBITS;
break;
}
}
void P_DecreaseVisibility (mobj_t *actor)
{
if (actor->flags2 & MF2_DONTDRAW)
return; // already invisible
switch (actor->flags & MF_TRANSLUCBITS) {
case 0:
actor->flags |= MF_TRANSLUC75;
break;
case MF_TRANSLUC75:
actor->flags &= ~MF_TRANSLUC25;
break;
case MF_TRANSLUC50:
actor->flags ^= MF_TRANSLUCBITS;
break;
case MF_TRANSLUC25:
actor->flags &= ~MF_TRANSLUCBITS;
actor->flags2 |= MF2_DONTDRAW;
}
}
/***** End of new functions for Andy Baker's stealth monsters ******/

View file

@ -432,7 +432,7 @@ BOOL EV_DoFloor (floor_e floortype, line_t *line, int tag,
manual_floor:
// ALREADY MOVING? IF SO, KEEP GOING...
if (P_SectorActive (floor_special, sec)) //jff 2/33/98
if (sec->floordata)
continue;
// new floor thinker
@ -764,7 +764,7 @@ manual_stair:
// ALREADY MOVING? IF SO, KEEP GOING...
//jff 2/26/98 add special lockout condition to wait for entire
//staircase to build before retriggering
if (P_SectorActive (floor_special, sec) || sec->stairlock) {
if (sec->floordata || sec->stairlock) {
if (!manual)
continue;
else
@ -815,7 +815,7 @@ manual_stair:
// if sector's floor already moving, look for another
//jff 2/26/98 special lockout condition for retriggering
if (P_SectorActive (floor_special,tsec) || tsec->stairlock) {
if (tsec->floordata || tsec->stairlock) {
prev = sec;
sec = tsec;
continue;
@ -845,7 +845,7 @@ manual_stair:
// if sector's floor already moving, look for another
//jff 2/26/98 special lockout condition for retriggering
if (P_SectorActive (floor_special,tsec) || tsec->stairlock)
if (tsec->floordata || tsec->stairlock)
continue;
ok = true;
@ -922,7 +922,7 @@ int EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed)
s1 = &sectors[secnum]; // s1 is pillar's sector
// ALREADY MOVING? IF SO, KEEP GOING...
if (P_SectorActive (floor_special, s1)) //jff 2/22/98
if (s1->floordata)
continue;
rtn = 1;

View file

@ -183,13 +183,13 @@ BOOL P_GiveWeapon (player_t *player, weapontype_t weapon, BOOL dropped)
if ((state->frame & FF_FRAMEMASK) >= sprites[state->sprite].numframes)
return false;
if (netgame && (!deathmatch->value || dmflags & DF_WEAPONS_STAY) && !dropped)
if (netgame && ((!deathmatch->value && !fakedmatch->value) || dmflags & DF_WEAPONS_STAY) && !dropped)
{
// leave placed weapons forever on net games
if (player->weaponowned[weapon])
return false;
player->bonuscount += BONUSADD;
player->bonuscount = BONUSADD;
player->weaponowned[weapon] = true;
if (deathmatch->value)
@ -256,7 +256,7 @@ BOOL P_GiveBody (player_t *player, int num)
//
BOOL P_GiveArmor (player_t *player, int armortype)
{
int hits;
int hits;
hits = armortype*100;
if (player->armorpoints >= hits)
@ -399,8 +399,6 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
break;
case SPR_MEGA:
if (gamemode != commercial)
return;
player->health = deh.MegasphereHealth;
player->mo->health = player->health;
P_GiveArmor (player,deh.BlueAC);
@ -662,7 +660,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
level.found_items++;
}
P_RemoveMobj (special);
player->bonuscount += BONUSADD;
player->bonuscount = BONUSADD;
{
mobj_t *ent;
@ -1170,7 +1168,8 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
// [RH] Andy Baker's Stealth monsters
if (target->flags & MF_STEALTH)
{
P_BecomeVisible(target);
target->translucency = FRACUNIT;
target->visdir = -1;
}
if ( target->flags & MF_SKULLFLY )

View file

@ -263,7 +263,7 @@ void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics)
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
{
sector_t *sec = &sectors[secnum];
if (P_SectorActive (lighting_special, sec)) //jff 2/22/98
if (sec->lightingdata)
continue;
P_SpawnStrobeFlash (sec, upper, lower, utics, ltics, 0);
@ -453,7 +453,7 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics)
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
{
sector_t *sec = &sectors[secnum];
if (P_SectorActive (lighting_special, sec))
if (sec->lightingdata)
continue;
P_SpawnGlowingLight2 (sec, upper, lower, tics, false);
@ -468,7 +468,7 @@ void EV_StartLightFading (int tag, int value, int tics)
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
{
sector_t *sec = &sectors[secnum];
if (P_SectorActive (lighting_special, sec))
if (sec->lightingdata)
continue;
// No need to fade if lightlevel is already at desired value.

View file

@ -667,7 +667,7 @@ FUNC(LS_Teleport_EndGame)
// Teleport_EndGame ()
{
if (!TeleportSide) {
if (gamemode == commercial && CheckIfExitIsGood (it)) {
if (CheckIfExitIsGood (it)) {
strncpy (level.nextmap, "EndGameC", 8);
G_ExitLevel (0);
return true;

View file

@ -219,8 +219,8 @@ typedef enum {
Init_Gravity = 0,
Init_Color = 1,
Init_Damage = 2,
NUM_STATIC_INITS
NUM_STATIC_INITS,
Init_TransferSky = 255
} staticinit_t;
typedef enum {

View file

@ -160,11 +160,6 @@ extern struct brain_s { // killough 3/26/98: global state of boss brain
int easy, targeton;
} brain;
// [RH] Andy Baker's stealth monsters
void P_BecomeVisible (mobj_t *actor);
void P_IncreaseVisibility (mobj_t *actor);
void P_DecreaseVisibility (mobj_t *actor);
//
// P_MAPUTL

View file

@ -223,10 +223,6 @@ int P_GetFriction (const mobj_t *mo, int *frictionfactor)
const msecnode_t *m;
const sector_t *sec;
// Assign the friction value to objects on the floor, non-floating,
// and clipped. Normally the object's friction value is kept at
// ORIG_FRICTION and this thinker changes it for icy or muddy floors.
//
// When the object is straddling sectors with the same
// floorheight that have different frictions, use the lowest
// friction value (muddy has precedence over icy).

View file

@ -281,15 +281,15 @@ void P_UnsetThingPosition (mobj_t *thing)
{
if (!(thing->flags & MF_NOSECTOR))
{
// inert things don't need to be in sector list
// invisible things don't need to be in sector list
// unlink from subsector
if (thing->snext)
thing->snext->sprev = thing->sprev;
if (thing->sprev)
thing->sprev->snext = thing->snext;
else
thing->subsector->sector->thinglist = thing->snext;
// killough 8/11/98: simpler scheme using pointers-to-pointers for prev
// pointers, allows head node pointers to be treated like everything else
mobj_t **sprev = thing->sprev;
mobj_t *snext = thing->snext;
if ((*sprev = snext)) // unlink from sector list
snext->sprev = sprev;
// phares 3/14/98
//
@ -308,61 +308,48 @@ void P_UnsetThingPosition (mobj_t *thing)
thing->touching_sectorlist = NULL; //to be restored by P_SetThingPosition
}
if ( ! (thing->flags & MF_NOBLOCKMAP) )
if ( !(thing->flags & MF_NOBLOCKMAP) )
{
// inert things don't need to be in blockmap
// unlink from block map
if (thing->bnext)
thing->bnext->bprev = thing->bprev;
if (thing->bprev)
thing->bprev->bnext = thing->bnext;
else
{
int blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
int blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
// killough 8/11/98: simpler scheme using pointers-to-pointers for prev
// pointers, allows head node pointers to be treated like everything else
//
// Also more robust, since it doesn't depend on current position for
// unlinking. Old method required computing head node based on position
// at time of unlinking, assuming it was the same position as during
// linking.
if (blockx>=0 && blockx < bmapwidth
&& blocky>=0 && blocky <bmapheight)
{
blocklinks[blocky*bmapwidth+blockx] = thing->bnext;
}
}
mobj_t *bnext, **bprev = thing->bprev;
if (bprev && (*bprev = bnext = thing->bnext)) // unlink from block map
bnext->bprev = bprev;
}
}
//
// P_SetThingPosition
// Links a thing into both a block and a subsector
// based on it's x y.
// Links a thing into both a block and a subsector based on it's x y.
// Sets thing->subsector properly
//
void P_SetThingPosition (mobj_t *thing)
{
subsector_t* ss;
sector_t* sec;
int blockx;
int blocky;
mobj_t** link;
// link into subsector
subsector_t *ss;
ss = R_PointInSubsector (thing->x,thing->y);
thing->subsector = ss;
if ( ! (thing->flags & MF_NOSECTOR) )
if ( !(thing->flags & MF_NOSECTOR) )
{
// invisible things don't go into the sector links
sec = ss->sector;
thing->sprev = NULL;
thing->snext = sec->thinglist;
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
// pointers, allows head nodes to be treated like everything else
if (sec->thinglist)
sec->thinglist->sprev = thing;
sec->thinglist = thing;
mobj_t **link = &ss->sector->thinglist;
mobj_t *snext = *link;
if ((thing->snext = snext))
snext->sprev = &thing->snext;
thing->sprev = link;
*link = thing;
// phares 3/16/98
//
@ -384,30 +371,27 @@ void P_SetThingPosition (mobj_t *thing)
// link into blockmap
if ( ! (thing->flags & MF_NOBLOCKMAP) )
if ( !(thing->flags & MF_NOBLOCKMAP) )
{
// inert things don't need to be in blockmap
blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
// inert things don't need to be in blockmap
int blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
int blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
if (blockx>=0
&& blockx < bmapwidth
&& blocky>=0
&& blocky < bmapheight)
{
link = &blocklinks[blocky*bmapwidth+blockx];
thing->bprev = NULL;
thing->bnext = *link;
if (*link)
(*link)->bprev = thing;
if (blockx>=0 && blockx < bmapwidth && blocky>=0 && blocky < bmapheight)
{
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
// pointers, allows head nodes to be treated like everything else
mobj_t **link = &blocklinks[blocky*bmapwidth+blockx];
mobj_t *bnext = *link;
if ((thing->bnext = bnext))
bnext->bprev = &thing->bnext;
thing->bprev = link;
*link = thing;
}
else
{
// thing is off the map
thing->bnext = thing->bprev = NULL;
}
else // thing is off the map
thing->bnext = NULL, thing->bprev = NULL;
}
}
@ -503,7 +487,7 @@ BOOL P_BlockThingsIterator (int x, int y, BOOL(*func)(mobj_t*))
mobj ;
mobj = mobj->bnext)
{
if (!func( mobj ))
if (!func (mobj))
return false;
}
}

View file

@ -21,6 +21,7 @@
//
//-----------------------------------------------------------------------------
// HEADER FILES ------------------------------------------------------------
#include "m_alloc.h"
#include "i_system.h"
@ -37,12 +38,15 @@
#include "v_video.h"
#include "c_cvars.h"
cvar_t *sv_gravity;
cvar_t *sv_friction;
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void G_PlayerReborn (int player);
// PUBLIC DATA DEFINITIONS -------------------------------------------------
cvar_t *sv_gravity;
cvar_t *sv_friction;
fixed_t FloatBobOffsets[64] =
{
0, 51389, 102283, 152192,
@ -63,11 +67,16 @@ fixed_t FloatBobOffsets[64] =
-200637, -152193, -102284, -51389
};
// CODE --------------------------------------------------------------------
//==========================================================================
//
// P_SetMobjState
//
// Returns true if the mobj is still present.
//
//==========================================================================
BOOL P_SetMobjState (mobj_t *mobj, statenum_t state)
{
state_t *st;
@ -122,19 +131,21 @@ BOOL P_SetMobjState (mobj_t *mobj, statenum_t state)
return ret;
}
//----------------------------------------------------------------------------
//
// PROC P_ExplodeMissile
//
//----------------------------------------------------------------------------
//
// P_ExplodeMissile
//
void P_ExplodeMissile (mobj_t* mo)
{
mo->momx = mo->momy = mo->momz = 0;
P_SetMobjState (mo, mobjinfo[mo->type].deathstate);
// [RH] If the object isn't translucent, don't change it.
// Otherwise, make it 75% translucent.
if (TransTable && !(mo->flags & MF_TRANSLUCBITS))
mo->flags |= MF_TRANSLUC75;
// [RH] If the object is already translucent, don't change it.
// Otherwise, make it 66% translucent.
if (mo->translucency == FRACUNIT)
mo->translucency = TRANSLUC66;
mo->tics -= P_Random (pr_explodemissile) & 3;
@ -646,24 +657,20 @@ static void PlayerLandedOnThing(mobj_t *mo, mobj_t *onmobj)
//
void P_NightmareRespawn (mobj_t *mobj)
{
fixed_t x;
fixed_t y;
subsector_t* ss;
mobj_t* mo;
mapthing2_t* mthing;
fixed_t x, y, z;
subsector_t *ss;
mobj_t *mo;
mapthing2_t *mthing;
x = mobj->spawnpoint.x << FRACBITS;
y = mobj->spawnpoint.y << FRACBITS;
// something is occupying it's position?
if (!P_CheckPosition (mobj, x, y))
return; // no respawn
// spawn a teleport fog at old spot
// because of removal of the body?
mo = P_SpawnMobj (mobj->x,
mobj->y,
ONFLOORZ, MT_TFOG);
mo = P_SpawnMobj (mobj->x, mobj->y, ONFLOORZ, MT_TFOG);
// initiate teleport sound
S_Sound (mo, CHAN_VOICE, "misc/teleport", 1, ATTN_NORM);
@ -677,12 +684,33 @@ void P_NightmareRespawn (mobj_t *mobj)
// spawn the new monster
mthing = &mobj->spawnpoint;
if (mobj->info->flags & MF_SPAWNCEILING)
z = ONCEILINGZ;
else if (mobj->info->flags2 & MF2_SPAWNFLOAT)
z = FLOATRANDZ;
else if (mobj->info->flags2 & MF2_FLOATBOB)
z = mthing->z << FRACBITS;
else
z = ONFLOORZ;
// spawn it
// inherit attributes from deceased one
mo = P_SpawnMobj (x, y, ONFLOORZ, mobj->type);
mo->spawnpoint = mobj->spawnpoint;
mo->angle = ANG45 * (mthing->angle/45);
if (z == ONFLOORZ)
mobj->z += mthing->z << FRACBITS;
else if (z == ONCEILINGZ)
mobj->z -= mthing->z << FRACBITS;
mobj->spawnpoint = *mthing;
if (mobj->flags2 & MF2_FLOATBOB)
{ // Seed random starting index for bobbing motion
mobj->health = M_Random();
mobj->special1 = mthing->z << FRACBITS;
}
if (mthing->flags & MTF_AMBUSH)
mo->flags |= MF_AMBUSH;
@ -818,6 +846,49 @@ void P_MobjThinker (mobj_t *mobj)
if (mobj->targettic)
mobj->targettic--;
// [RH] Pulse in and out of visibility
if (mobj->effects & FX_VISIBILITYPULSE)
{
if (mobj->special2 > 0)
{
mobj->translucency += 0x800;
if (mobj->translucency >= FRACUNIT)
{
mobj->translucency = FRACUNIT;
mobj->special2 = -1;
}
}
else
{
mobj->translucency -= 0x800;
if (mobj->translucency <= TRANSLUC25)
{
mobj->translucency = TRANSLUC25;
mobj->special2 = 1;
}
}
}
// [RH] Fade a stealth monster in and out of visibility
if (mobj->visdir > 0)
{
mobj->translucency += 2*FRACUNIT/TICRATE;
if (mobj->translucency > FRACUNIT)
{
mobj->translucency = FRACUNIT;
mobj->visdir = 0;
}
}
else if (mobj->visdir < 0)
{
mobj->translucency -= 3*FRACUNIT/TICRATE/2;
if (mobj->translucency < 0)
{
mobj->translucency = 0;
mobj->visdir = 0;
}
}
// Handle X and Y momemtums
BlockingMobj = NULL;
if (mobj->momx || mobj->momy || (mobj->flags & MF_SKULLFLY))
@ -898,8 +969,7 @@ void P_MobjThinker (mobj_t *mobj)
else
{
// check for nightmare respawn
if (!(mobj->flags & MF_COUNTKILL) ||
!respawnmonsters)
if (!(mobj->flags & MF_COUNTKILL) || !respawnmonsters)
return;
mobj->movecount++;
@ -907,7 +977,7 @@ void P_MobjThinker (mobj_t *mobj)
if (mobj->movecount < 12*TICRATE)
return;
if ( level.time&31 )
if (level.time & 31)
return;
if (P_Random (pr_mobjthinker) > 4)
@ -917,19 +987,18 @@ void P_MobjThinker (mobj_t *mobj)
}
}
//==========================================================================
//
// P_SpawnMobj
// [RH] Since MapThings can now be stored with their own z-position,
// we now use a separate parameter to indicate if it should be
// spawned relative to the floor or ceiling.
//
//==========================================================================
mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{
mobj_t* mobj;
state_t* st;
mobjinfo_t* info;
fixed_t space;
mobj_t *mobj;
state_t *st;
mobjinfo_t *info;
fixed_t space;
mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
memset (mobj, 0, sizeof (*mobj));
@ -943,16 +1012,23 @@ mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->height = info->height;
mobj->flags = info->flags;
mobj->flags2 = info->flags2;
mobj->damage = info->damage;
mobj->health = info->spawnhealth;
if (mobj->flags & MF_STEALTH) // [RH] Stealth monsters start out invisible
mobj->flags2 |= MF2_DONTDRAW;
mobj->translucency = info->translucency;
if (type == MT_INS)
{
mobj->effects = FX_VISIBILITYPULSE;
mobj->special2 = -1;
}
if (gameskill->value != sk_nightmare)
mobj->reactiontime = info->reactiontime;
mobj->lastlook = P_Random (pr_spawnmobj) % MAXPLAYERS;
// do not set the state with P_SetMobjState,
// because action routines can not be called yet
// Set the state, but do not use P_SetMobjState, because action
// routines can't be called yet. If the spawnstate has an action
// routine, it will not be called.
st = &states[info->spawnstate];
mobj->state = st;
mobj->tics = st->tics;
@ -962,7 +1038,6 @@ mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// set subsector and/or block links
P_SetThingPosition (mobj);
mobj->floorz = mobj->subsector->sector->floorheight;
mobj->ceilingz = mobj->subsector->sector->ceilingheight;
@ -1012,16 +1087,17 @@ int iquehead;
int iquetail;
void P_RemoveMobj (mobj_t* mobj)
void P_RemoveMobj (mobj_t *mobj)
{
if ((mobj->flags & MF_SPECIAL)
&& !(mobj->flags & MF_DROPPED)
&& (mobj->type != MT_INV)
&& (mobj->type != MT_INS))
if ((mobj->flags & MF_SPECIAL) && !(mobj->flags & MF_DROPPED))
{
itemrespawnque[iquehead] = mobj->spawnpoint;
itemrespawntime[iquehead] = level.time;
iquehead = (iquehead+1)&(ITEMQUESIZE-1);
if ((mobj->type != MT_INV && mobj->type != MT_INS)
|| (dmflags & DF_RESPAWN_SUPER))
{
itemrespawnque[iquehead] = mobj->spawnpoint;
itemrespawntime[iquehead] = level.time;
iquehead = (iquehead+1)&(ITEMQUESIZE-1);
}
// lose one off the end?
if (iquehead == iquetail)
@ -1035,10 +1111,9 @@ void P_RemoveMobj (mobj_t* mobj)
P_RemoveMobjFromHash (mobj);
// Delete all nodes on the current sector_list phares 3/16/98
if (sector_list)
{
P_DelSeclist(sector_list);
P_DelSeclist (sector_list);
sector_list = NULL;
}
@ -1068,7 +1143,7 @@ void P_RespawnSpecials (void)
int i;
// only respawn items in deathmatch
if (!deathmatch->value || !(dmflags & DF_ITEMS_RESPAWN))
if ((!deathmatch->value && !fakedmatch->value) || !(dmflags & DF_ITEMS_RESPAWN))
return;
// nothing left to respawn?
@ -1121,8 +1196,10 @@ void P_RespawnSpecials (void)
}
// [RH] Set the thing's special
mo->special = mthing->special;
memcpy (mo->args, mthing->args, sizeof(mo->args));
// On second thought, don't.
mo->special = 0;
//mo->special = mthing->special;
//memcpy (mo->args, mthing->args, sizeof(mo->args));
// pull it from the que
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
@ -1182,6 +1259,7 @@ void P_SpawnPlayer (mapthing2_t *mthing)
p->extralight = 0;
p->fixedcolormap = 0;
p->viewheight = VIEWHEIGHT;
p->inconsistant = 0;
p->momx = p->momy = 0; // killough 10/98: initialize bobbing to 0.
@ -1418,7 +1496,7 @@ void P_SpawnMapThing (mapthing2_t *mthing, int position)
}
// [RH] Other things that shouldn't be spawned depending on dmflags
if (deathmatch->value) {
if (deathmatch->value || fakedmatch->value) {
spritenum_t sprite = states[mobjinfo[i].spawnstate].sprite;
if (dmflags & DF_NO_HEALTH) {

View file

@ -107,133 +107,85 @@
// Any questions?
//
//
// Misc. mobj flags
//
typedef enum
{
// Call P_SpecialThing when touched.
MF_SPECIAL = 0x00000001,
// Blocks.
MF_SOLID = 0x00000002,
// Can be hit.
MF_SHOOTABLE = 0x00000004,
// Don't use the sector links (invisible but touchable).
MF_NOSECTOR = 0x00000008,
// Don't use the blocklinks (inert but displayable)
MF_NOBLOCKMAP = 0x00000010,
// --- mobj.flags ---
// Not to be activated by sound, deaf monster.
MF_AMBUSH = 0x00000020,
// Will try to attack right back.
MF_JUSTHIT = 0x00000040,
// Will take at least one step before attacking.
MF_JUSTATTACKED = 0x00000080,
// On level spawning (initial position),
// hang from ceiling instead of stand on floor.
MF_SPAWNCEILING = 0x00000100,
// Don't apply gravity (every tic),
// that is, object will float, keeping current height
// or changing it actively.
MF_NOGRAVITY = 0x00000200,
#define MF_SPECIAL 1 // call P_SpecialThing when touched
#define MF_SOLID 2
#define MF_SHOOTABLE 4
#define MF_NOSECTOR 8 // don't use the sector links
// (invisible but touchable)
#define MF_NOBLOCKMAP 16 // don't use the blocklinks
// (inert but displayable)
#define MF_AMBUSH 32 // not activated by sound; deaf monster
#define MF_JUSTHIT 64 // try to attack right back
#define MF_JUSTATTACKED 128 // take at least one step before attacking
#define MF_SPAWNCEILING 256 // hang from ceiling instead of floor
#define MF_NOGRAVITY 512 // don't apply gravity every tic
// Movement flags.
// This allows jumps from high places.
MF_DROPOFF = 0x00000400,
// For players, will pick up items.
MF_PICKUP = 0x00000800,
// Player cheat. ???
MF_NOCLIP = 0x00001000,
// Player: keep info about sliding along walls.
MF_SLIDE = 0x00002000,
// Allow moves to any height, no gravity.
// For active floaters, e.g. cacodemons, pain elementals.
MF_FLOAT = 0x00004000,
// Don't cross lines
// ??? or look at heights on teleport.
MF_TELEPORT = 0x00008000,
// Don't hit same species, explode on block.
// Player missiles as well as fireballs of various kinds.
MF_MISSILE = 0x00010000,
// Dropped by a demon, not level spawned.
// E.g. ammo clips dropped by dying former humans.
MF_DROPPED = 0x00020000,
// Use fuzzy draw (shadow demons or spectres),
// temporary player invisibility powerup.
MF_SHADOW = 0x00040000,
// Flag: don't bleed when shot (use puff),
// barrels and shootable furniture shall not bleed.
MF_NOBLOOD = 0x00080000,
// Don't stop moving halfway off a step,
// that is, have dead bodies slide down all the way.
MF_CORPSE = 0x00100000,
// Floating to a height for a move, ???
// don't auto float to target's height.
MF_INFLOAT = 0x00200000,
// movement flags
#define MF_DROPOFF 0x00000400 // allow jumps from high places
#define MF_PICKUP 0x00000800 // for players to pick up items
#define MF_NOCLIP 0x00001000 // player cheat
#define MF_SLIDE 0x00002000 // keep info about sliding along walls
#define MF_FLOAT 0x00004000 // allow moves to any height, no gravity
#define MF_TELEPORT 0x00008000 // don't cross lines or look at heights
#define MF_MISSILE 0x00010000 // don't hit same species, explode on block
// On kill, count this enemy object
// towards intermission kill total.
// Happy gathering.
MF_COUNTKILL = 0x00400000,
// On picking up, count this item object
// towards intermission item total.
MF_COUNTITEM = 0x00800000,
#define MF_DROPPED 0x00020000 // dropped by a demon, not level spawned
#define MF_SHADOW 0x00040000 // use fuzzy draw (shadow demons / spectres)
#define MF_NOBLOOD 0x00080000 // don't bleed when shot (use puff)
#define MF_CORPSE 0x00100000 // don't stop moving halfway off a step
#define MF_INFLOAT 0x00200000 // floating to a height for a move, don't
// auto float to target's height
// Special handling: skull in flight.
// Neither a cacodemon nor a missile.
MF_SKULLFLY = 0x01000000,
#define MF_COUNTKILL 0x00400000 // count towards intermission kill total
#define MF_COUNTITEM 0x00800000 // count towards intermission item total
// Don't spawn this object
// in death match mode (e.g. key cards).
MF_NOTDMATCH = 0x02000000,
#define MF_SKULLFLY 0x01000000 // skull in flight
#define MF_NOTDMATCH 0x02000000 // don't spawn in death match (key cards)
// Player sprites in multiplayer modes are modified
// using an internal color lookup table for re-indexing.
// If 0x4 0x8 or 0xc,
// use a translation table for player colormaps
MF_TRANSLATION = 0x0c000000,
// Hmm ???.
MF_TRANSSHIFT = 26,
#define MF_TRANSLATION 0x0c000000 // if 0x4 0x8 or 0xc, use a translation
#define MF_TRANSSHIFT 26 // tablefor player colormaps
// [RH] Andy Baker's stealth monsters
//Stealth Mode - Creatures that dissappear and reappear.
MF_STEALTH = 0x10000000,
#define MF_STEALTH 0x40000000 // [RH] Andy Baker's stealth monsters
#define MF_ICECORPSE 0x80000000 // a frozen corpse (for blasting) [RH] was 0x800000
// [RH] 3 (4 counting opaque) levels of translucency
MF_TRANSLUCSHIFT = 29,
MF_TRANSLUCBITS = 0x60000000,
MF_TRANSLUC25 = 0x20000000,
MF_TRANSLUC50 = 0x40000000,
MF_TRANSLUC75 = 0x60000000,
} mobjflag_t;
// [RH] These are all from Hexen. Very few are used.
// --- mobj.flags2 ---
#define MF2_LOGRAV 0x00000001 // alternate gravity setting
#define MF2_WINDTHRUST 0x00000002 // gets pushed around by the wind specials
#define MF2_WINDTHRUST 0x00000002 // gets pushed around by the wind
// specials
#define MF2_FLOORBOUNCE 0x00000004 // bounces off the floor
#define MF2_BLASTED 0x00000008 // missile will pass through ghosts
#define MF2_FLY 0x00000010 // fly mode is active
#define MF2_FLOORCLIP 0x00000020 // if feet are allowed to be clipped
#define MF2_SPAWNFLOAT 0x00000040 // spawn random float z
#define MF2_NOTELEPORT 0x00000080 // does not teleport
#define MF2_RIP 0x00000100 // missile rips through solid targets
#define MF2_PUSHABLE 0x00000200 // can be pushed by other moving mobjs
#define MF2_RIP 0x00000100 // missile rips through solid
// targets
#define MF2_PUSHABLE 0x00000200 // can be pushed by other moving
// mobjs
#define MF2_SLIDE 0x00000400 // slides against walls
#define MF2_ONMOBJ 0x00000800 // mobj is resting on top of another mobj
#define MF2_ONMOBJ 0x00000800 // mobj is resting on top of another
// mobj
#define MF2_PASSMOBJ 0x00001000 // Enable z block checking. If on,
// this flag will allow the mobj to
// pass over/under other mobjs.
#define MF2_CANNOTPUSH 0x00002000 // cannot push other pushable mobjs
#define MF2_DROPPED 0x00004000 // dropped by a demon
//#define MF2_DROPPED 0x00004000 // dropped by a demon [RH] use MF_DROPPED instead
#define MF2_THRUGHOST 0x00004000 // missile will pass through ghosts [RH] was 8
#define MF2_BOSS 0x00008000 // mobj is a major boss
#define MF2_FIREDAMAGE 0x00010000 // does fire damage
#define MF2_NODMGTHRUST 0x00020000 // does not thrust target when damaging
#define MF2_NODMGTHRUST 0x00020000 // does not thrust target when
// damaging
#define MF2_TELESTOMP 0x00040000 // mobj can stomp another
#define MF2_FLOATBOB 0x00080000 // use float bobbing z movement
#define MF2_DONTDRAW 0x00100000 // don't generate a vissprite
#define MF2_IMPACT 0x00200000 // an MF_MISSILE mobj can activate SPAC_IMPACT
#define MF2_IMPACT 0x00200000 // an MF_MISSILE mobj can activate
// SPAC_IMPACT
#define MF2_PUSHWALL 0x00400000 // mobj can push walls
#define MF2_MCROSS 0x00800000 // can activate monster cross lines
#define MF2_PCROSS 0x01000000 // can activate projectile cross lines
@ -247,6 +199,12 @@ typedef enum
#define MF2_REFLECTIVE 0x80000000 // reflects missiles
#define TRANSLUC25 (FRACUNIT/4)
#define TRANSLUC33 (FRACUNIT/3)
#define TRANSLUC50 (FRACUNIT/2)
#define TRANSLUC66 ((FRACUNIT*2)/3)
#define TRANSLUC75 ((FRACUNIT*3)/4)
// Map Object definition.
typedef struct mobj_s
{
@ -254,7 +212,7 @@ typedef struct mobj_s
// info for drawing
fixed_t x,y,z;
struct mobj_s *snext, *sprev; // links in sector (if needed)
struct mobj_s *snext, **sprev; // links in sector (if needed)
angle_t angle;
spritenum_t sprite; // used to find patch_t and flip value
int frame; // might be ord with FF_FULLBRIGHT
@ -262,7 +220,7 @@ typedef struct mobj_s
// interaction info
fixed_t pitch, roll;
struct mobj_s *bnext, *bprev; // links in blocks (if needed)
struct mobj_s *bnext, **bprev; // links in blocks (if needed)
struct subsector_s *subsector;
fixed_t floorz, ceilingz; // closest together of contacted secs
// fixed_t floorpic; // contacted sec floorpic
@ -279,7 +237,9 @@ typedef struct mobj_s
int special1; // Special info
int special2; // Special info
int health;
int movedir; // 0-7
byte movedir; // 0-7
char visdir;
short pad; // hack for 1.17a saves. to be removed
int movecount; // when 0, select a new dir
struct mobj_s *target; // thing being chased/attacked (or NULL)
// also the originator for missiles
@ -303,6 +263,7 @@ typedef struct mobj_s
struct mobj_s *goal; // Monster's goal if not chasing anything
unsigned targettic; // Avoid missiles blowing up in your face
byte *translation; // Translation table (or NULL)
fixed_t translucency; // 65536=fully opaque, 0=fully invisible
// a linked list of sectors where this object appears
struct msecnode_s *touching_sectorlist; // phares 3/14/98

View file

@ -201,7 +201,7 @@ BOOL EV_DoPlat (int tag, line_t *line, plattype_e type, int height,
sec = &sectors[secnum];
manual_plat:
if (P_SectorActive (floor_special, sec)) //jff 2/23/98 multiple thinkers
if (sec->floordata)
continue;
// Find lowest & highest floors around sector
@ -361,10 +361,9 @@ void EV_StopPlat (int tag)
// [RH] Rewritten to use list
void P_AddActivePlat (plat_t *plat)
{
if (activeplats)
activeplats->prev = plat;
plat->next = activeplats;
plat->prev = NULL;
if ( (plat->next = activeplats) )
plat->next->prev = &plat->next;
plat->prev = &activeplats;
activeplats = plat;
}
@ -376,14 +375,8 @@ void P_RemoveActivePlat (plat_t *plat)
while (scan) {
if (scan == plat) {
scan->sector->floordata = NULL;
if (scan == activeplats) {
activeplats = scan->next;
} else {
if (scan->prev)
scan->prev->next = scan->next;
if (scan->next)
scan->next->prev = scan->prev;
}
if ( (*(scan->prev) = scan->next) )
scan->next->prev = scan->prev;
P_RemoveThinker (&scan->thinker);
break;
}

View file

@ -173,14 +173,12 @@ BOOL P_CheckAmmo (player_t *player)
do
{
if (player->weaponowned[wp_plasma]
&& player->ammo[am_cell]
&& (gamemode != shareware) )
&& player->ammo[am_cell])
{
player->pendingweapon = wp_plasma;
}
else if (player->weaponowned[wp_supershotgun]
&& player->ammo[am_shell]>2
&& (gamemode == commercial) )
&& player->ammo[am_shell]>2)
{
player->pendingweapon = wp_supershotgun;
}
@ -208,8 +206,7 @@ BOOL P_CheckAmmo (player_t *player)
player->pendingweapon = wp_missile;
}
else if (player->weaponowned[wp_bfg]
&& player->ammo[am_cell]>40
&& (gamemode != shareware) )
&& player->ammo[am_cell]>40)
{
player->pendingweapon = wp_bfg;
}

View file

@ -36,10 +36,12 @@
#include "v_palett.h"
extern button_t *buttonlist;
extern byte *translationtables;
byte *save_p;
BOOL ZDoom117aSave;
//
// P_ArchivePlayers
@ -349,6 +351,11 @@ void P_ArchiveThinkers (void)
// killough 2/14/98: end changes
if (mobj->translation)
mobj->translation = (byte *)(mobj->translation - translationtables);
else
mobj->translation = (byte *)-1;
if (mobj->player)
mobj->player = (player_t *)((mobj->player-players) + 1);
}
@ -413,7 +420,10 @@ void P_UnArchiveThinkers (BOOL keepPlayers)
for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98
{ // skip all entries, adding up count
PADSAVEP();
save_p += sizeof(mobj_t);
if (ZDoom117aSave) // Quick hack. To be removed.
save_p += sizeof(mobj_t)-sizeof(fixed_t);
else
save_p += sizeof(mobj_t);
}
if (*--save_p != tc_end)
@ -433,8 +443,32 @@ void P_UnArchiveThinkers (BOOL keepPlayers)
mobj_p[size] = mobj;
PADSAVEP();
memcpy (mobj, save_p, sizeof(mobj_t));
save_p += sizeof(mobj_t);
if (ZDoom117aSave)
{ // Quick hack. To be removed.
memcpy (mobj, save_p, sizeof(mobj_t)-sizeof(fixed_t));
mobj->translucency = (mobj->flags & 0x60000000) >> 15;
mobj->flags &= ~0x60000000;
if (mobj->translucency == 0)
{
if (mobj->flags2 & MF2_DONTDRAW)
{
mobj->flags2 &= ~MF2_DONTDRAW;
}
else
{
mobj->translucency = FRACUNIT;
}
}
if (mobj->type == MT_INS)
mobj->effects |= 0x40; // FX_VISIBILITYPULSE
mobj->visdir = 0;
save_p += sizeof(mobj_t)-sizeof(fixed_t);
}
else
{
memcpy (mobj, save_p, sizeof(mobj_t));
save_p += sizeof(mobj_t);
}
mobj->state = states + (int) mobj->state;
if (mobj->player) {
@ -452,6 +486,7 @@ void P_UnArchiveThinkers (BOOL keepPlayers)
mobj->player->camera = mobj; // [RH] Reset the camera to the player's viewpoint
}
mobj->touching_sectorlist = NULL;
P_SetThingPosition (mobj);
mobj->info = &mobjinfo[mobj->type];
@ -487,12 +522,17 @@ void P_UnArchiveThinkers (BOOL keepPlayers)
((mobj_t *) th)->goal = // [RH] restore goal
mobj_p[(size_t)((mobj_t *)th)->goal];
if (ZDoom117aSave) // Quick hack. To be removed.
((mobj_t *)th)->translation = NULL;
else
((mobj_t *) th)->translation = ((ptrdiff_t)((mobj_t *) th)->translation != -1) ?
translationtables + (ptrdiff_t)((mobj_t *) th)->translation : NULL;
}
}
// killough 3/26/98: Spawn icon landings:
if (gamemode == commercial)
P_SpawnBrainTargets();
P_SpawnBrainTargets();
}
@ -934,7 +974,7 @@ void P_UnArchiveSpecials (void)
ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
P_AddThinker (&ceiling->thinker);
P_AddActiveCeiling(ceiling);
P_AddActiveCeiling (ceiling);
break;
case tc_door:

View file

@ -40,6 +40,7 @@
#include "doomstat.h"
#include "p_lnspec.h"
#include "v_palett.h"
#include "c_consol.h"
extern void P_SpawnMapThing (mapthing2_t *mthing, int position);
@ -367,6 +368,8 @@ void P_LoadSectors (int lump)
else
ss->colormap = GetSpecialLights (255,255,255,
RPART(level.fadeto),GPART(level.fadeto),BPART(level.fadeto));
ss->sky = 0;
}
Z_Free (data);
@ -1271,11 +1274,13 @@ void P_SetupLevel (char *lumpname, int position)
level.killed_monsters = level.found_items = level.found_secrets =
wminfo.maxfrags = 0;
wminfo.partime = 180;
for (i=0 ; i<MAXPLAYERS ; i++)
{
players[i].killcount = players[i].secretcount
= players[i].itemcount = 0;
}
if (!savegamerestore)
for (i=0 ; i<MAXPLAYERS ; i++)
{
players[i].killcount = players[i].secretcount
= players[i].itemcount = 0;
}
// Initial height of PointOfView will be set by player think.
players[consoleplayer].viewz = 1;
@ -1286,6 +1291,9 @@ void P_SetupLevel (char *lumpname, int position)
// [RH] Clear all ThingID hash chains.
P_ClearTidHashes ();
// [RH] clear out the mid-screen message
C_MidPrint (NULL);
PolyBlockMap = NULL;
#if 0 // UNUSED
@ -1390,8 +1398,7 @@ void P_SetupLevel (char *lumpname, int position)
}
// killough 3/26/98: Spawn icon landings:
if (gamemode == commercial)
P_SpawnBrainTargets();
P_SpawnBrainTargets();
// clear special respawning que
iquehead = iquetail = 0;

View file

@ -404,7 +404,7 @@ sightcounts[0]++;
//
// [RH] Andy Baker's stealth monsters:
// Cannot see an invisible object
if (!ignoreInvisibility && (t2->flags2 & MF2_DONTDRAW)
if (!ignoreInvisibility && (t2->translucency == 0)
&& P_Random (pr_checksight) > 50) // <- small chance of an attack being made anyway
return false;

View file

@ -317,7 +317,8 @@ BOOL CheckIfExitIsGood (mobj_t *self)
if (self == NULL)
return false;
if (deathmatch->value && dmflags & DF_NO_EXIT && self) {
if ((deathmatch->value || fakedmatch->value) && dmflags & DF_NO_EXIT && self)
{
while (self->health > 0)
P_DamageMobj (self, self, self, 10000, MOD_EXIT);
return false;
@ -416,32 +417,6 @@ sector_t *P_NextSpecialSector (sector_t *sec, int type, sector_t *nogood)
return NULL;
}
//
// P_SectorActive()
//
// Passed a linedef special class (floor, ceiling, lighting) and a sector
// returns whether the sector is already busy with a linedef special of the
// same class. If old demo compatibility true, all linedef special classes
// are the same.
//
// jff 2/23/98 added to prevent old demos from
// succeeding in starting multiple specials on one sector
//
int P_SectorActive(special_e t,sector_t *sec)
{
switch (t) // return whether thinker of same type is active
{
case floor_special:
return (int)sec->floordata;
case ceiling_special:
return (int)sec->ceilingdata;
case lighting_special:
return (int)sec->lightingdata;
}
return 1; // don't know which special, must be active, shouldn't be here
}
//
// P_FindLowestFloorSurrounding()
// FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS
@ -1403,6 +1378,10 @@ void P_SpawnSpecials (void)
P_SpawnLightPhased (sector);
break;
case Sky2:
sector->sky = PL_SKYFLAT;
break;
default:
// [RH] Try for normal Hexen scroller
if ((sector->special & 0xff) >= Scroll_North_Slow &&
@ -1434,7 +1413,6 @@ void P_SpawnSpecials (void)
break;
}
}
// Init other misc stuff
@ -1443,9 +1421,7 @@ void P_SpawnSpecials (void)
activeceilings = NULL;
activeplats = NULL;
buttonlist = NULL; // [RH] And buttonlist is also a singly-linked list.
ActiveQuakes = NULL; // [RH] Clear out any earthquakes.
// P_InitTagLists() must be called before P_FindSectorFromTag()
@ -1508,6 +1484,20 @@ void P_SpawnSpecials (void)
}
}
break;
// killough 10/98:
//
// Support for sky textures being transferred from sidedefs.
// Allows scrolling and other effects (but if scrolling is
// used, then the same sector tag needs to be used for the
// sky sector, the sky-transfer linedef, and the scroll-effect
// linedef). Still requires user to use F_SKY1 for the floor
// or ceiling texture, to distinguish floor and ceiling sky.
case Init_TransferSky:
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
sectors[s].sky = (i+1) | PL_SKYFLAT;
break;
}
break;
}
@ -1866,7 +1856,8 @@ static void P_SpawnFriction(void)
{
if (l->special == Sector_SetFriction)
{
int length, friction, movefactor, s;
int length, s;
fixed_t friction, movefactor;
if (l->args[1])
{ // [RH] Allow setting friction amount from parameter
@ -1878,20 +1869,25 @@ static void P_SpawnFriction(void)
}
friction = (0x1EB8*length)/0x80 + 0xD000;
// The following check might seem odd. At the time of movement,
// the move distance is multiplied by 'friction/0x10000', so a
// higher friction value actually means 'less friction'.
if (friction > ORIG_FRICTION) // ice
movefactor = ((0x10092 - friction)*(0x70))/0x158;
else
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
// killough 8/28/98: prevent odd situations
if (friction > FRACUNIT)
friction = FRACUNIT;
if (friction < 0)
friction = 0;
// The following check might seem odd. At the time of movement,
// the move distance is multiplied by 'friction/0x10000', so a
// higher friction value actually means 'less friction'.
// [RH] Twiddled these values so that momentum on ice (with
// friction 0xf900) is the same as in Heretic/Hexen.
if (friction > ORIG_FRICTION) // ice
// movefactor = ((0x10092 - friction)*(0x70))/0x158;
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
else
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
// killough 8/28/98: prevent odd situations
if (movefactor < 32)
movefactor = 32;

View file

@ -349,7 +349,7 @@ typedef struct plat_s
thinker_t thinker;
// [RH] Added next and prev links
struct plat_s *next, *prev;
struct plat_s *next, **prev;
sector_t* sector;
fixed_t speed;
@ -496,7 +496,7 @@ typedef struct ceiling_s
thinker_t thinker;
// [RH] Added next and prev links
struct ceiling_s *next, *prev;
struct ceiling_s *next, **prev;
ceiling_e type;
sector_t* sector;
@ -685,9 +685,6 @@ BOOL EV_SilentLineTeleport (line_t *line, int side, mobj_t *thing, int id,
BOOL reverse);
int P_SectorActive (special_e t, sector_t *s); // [RH] from BOOM
//
// [RH] ACS (see also p_acs.h)
//

View file

@ -26,18 +26,15 @@
#include "doomdef.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "g_game.h"
#include "s_sound.h"
// State.
#include "doomstat.h"
#include "r_state.h"
#include "z_zone.h"
#include "w_wad.h"
#include "gi.h"
//
// CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE
//
@ -57,29 +54,25 @@ void P_InitSwitchList(void)
{
byte *alphSwitchList = W_CacheLumpName ("SWITCHES", PU_STATIC);
byte *list_p;
int i;
int episode;
for (i = 0, list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20, i++)
;
if (i == 0) {
if (i == 0)
{
switchlist = Z_Malloc (sizeof(*switchlist), PU_STATIC, 0);
*switchlist = -1;
numswitches = 0;
} else {
}
else
{
switchlist = Z_Malloc (sizeof(*switchlist)*(i*2+1), PU_STATIC, 0);
if (gamemode == registered || gamemode == retail)
episode = 2;
else if ( gamemode == commercial )
episode = 3;
else
episode = 1;
for (i = 0, list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20) {
if (episode >= (list_p[18] | (list_p[19] << 8)))
for (i = 0, list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20)
{
if (((gameinfo.maxSwitch & 15) >= (list_p[18] & 15)) &&
((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)))
{
// [RH] Skip this switch if it can't be found.
if (R_CheckTextureNumForName (list_p /* .name1 */) < 0)

View file

@ -333,7 +333,7 @@ void P_DeathThink (player_t *player)
// [RH] Delay rebirth slightly
if (level.time >= player->respawn_time) {
if (player->cmd.ucmd.buttons & BT_USE ||
(deathmatch->value && dmflags & DF_FORCE_RESPAWN))
((deathmatch->value || fakedmatch->value) && dmflags & DF_FORCE_RESPAWN))
player->playerstate = PST_REBORN;
}
}

View file

@ -372,9 +372,12 @@ static const xlat_t SpecialTranslation[] = {
/* 266 */ { MONWALK, Teleport_Line, { TAG, TAG, 0 } },
/* 267 */ { MONWALK|REP, Teleport_Line, { TAG, TAG, 0 } },
/* 268 */ { MONWALK, Teleport_NoFog, { TAG } },
/* 269 */ { MONWALK|REP, Teleport_NoFog, { TAG } }
/* 269 */ { MONWALK|REP, Teleport_NoFog, { TAG } },
/* 270 */ { 0, 0, { 0 } },
/* 271 */ { 0, Static_Init, { TAG, Init_TransferSky, 0 } },
/* 272 */ { 0, Static_Init, { TAG, Init_TransferSky, 1 } }
};
#define NUM_SPECIALS 269
#define NUM_SPECIALS 272
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
{

View file

@ -684,12 +684,14 @@ void R_Subsector (int num)
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
// killough 3/16/98: add floorlightlevel
// killough 10/98: add support for skies transferred from sidedefs
floorplane = frontsector->floorheight < viewz || // killough 3/7/98
(frontsector->heightsec != -1 &&
sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
R_FindPlane(frontsector->floorheight,
frontsector->floorpic,
frontsector->floorpic == skyflatnum && // kilough 10/98
frontsector->sky & PL_SKYFLAT ? frontsector->sky :
frontsector->floorpic,
floorlightlevel, // killough 3/16/98
frontsector->floor_xoffs, // killough 3/7/98
frontsector->floor_yoffs
@ -700,7 +702,9 @@ void R_Subsector (int num)
(frontsector->heightsec != -1 &&
sectors[frontsector->heightsec].floorpic == skyflatnum) ?
R_FindPlane(frontsector->ceilingheight, // killough 3/8/98
frontsector->ceilingpic,
frontsector->ceilingpic == skyflatnum && // kilough 10/98
frontsector->sky & PL_SKYFLAT ? frontsector->sky :
frontsector->ceilingpic,
ceilinglightlevel, // killough 4/11/98
frontsector->ceiling_xoffs, // killough 3/7/98
frontsector->ceiling_yoffs

View file

@ -869,18 +869,8 @@ void R_PrecacheLevel (void)
for (i = numsprites - 1; i >= 0; i--)
{
if (hitlist[i]) {
int j;
for (j = sprites[i].numframes - 1; j >= 0; j--)
{
short *sflumps = sprites[i].spriteframes[j].lump;
int k;
for (k = 7; k >= 0; k--)
W_CacheLumpNum(sflumps[k], PU_CACHE);
}
}
if (hitlist[i])
R_CacheSprite (sprites + i);
}
Z_Free (hitlist);

View file

@ -115,6 +115,8 @@ struct sector_s
mobj_t* thinglist; // list of mobjs in sector
int seqType; // this sector's sound sequence
int sky;
// killough 8/28/98: friction is a sector property, not an mobj property.
// these fields used to be in mobj_t, but presented performance problems
// when processed as mobj properties. Fix is to make them sector properties.
@ -385,6 +387,7 @@ struct vissprite_s
int mobjflags; // for shadow draw
byte *translation; // [RH] for translation;
int heightsec; // killough 3/27/98: height sector for underwater/fake ceiling
fixed_t translucency;
};
typedef struct vissprite_s vissprite_t;

View file

@ -24,23 +24,17 @@
//-----------------------------------------------------------------------------
#include "m_alloc.h"
#include "doomdef.h"
#include "i_system.h"
#include "z_zone.h"
#include "w_wad.h"
#include "r_local.h"
// Needs access to LFB (guess what).
#include "v_video.h"
// State.
#include "doomstat.h"
#include "st_stuff.h"
#include "gi.h"
#undef RANGECHECK
// status bar height at bottom of screen
@ -379,15 +373,51 @@ void R_DrawFuzzColumnP_C (void)
//
// R_DrawTranlucentColumn
//
byte *dc_transmap;
fixed_t dc_translevel;
/*
[RH] This note is from DOSDoom 0.65:
New translucency algorithm, by Erik Sandberg:
Basically, we compute the red, green and blue values for each pixel, and
then use a RGB table to check which one of the palette colours that best
represents those RGB values. The RGB table is 8k big, with 4 R-bits,
5 G-bits and 4 B-bits. A 4k table gives a bit too bad precision, and a 32k
table takes up more memory and results in more cache misses, so an 8k
table seemed to be quite ultimate.
The computation of the RGB for each pixel is accelerated by using two
1k tables for each translucency level.
The xth element of one of these tables contains the r, g and b values for
the colour x, weighted for the current translucency level (for example,
the weighted rgb values for background colour at 75% translucency are 1/4
of the original rgb values). The rgb values are stored as three
low-precision fixed point values, packed into one long per colour:
Bit 0-4: Frac part of blue (5 bits)
Bit 5-8: Int part of blue (4 bits)
Bit 9-13: Frac part of red (5 bits)
Bit 14-17: Int part of red (4 bits)
Bit 18-22: Frac part of green (5 bits)
Bit 23-27: Int part of green (5 bits)
Bit 28-31: All zeros (4 bits)
The point of this format is that the two colours now can be added, and
then be converted to a RGB table index very easily: First, we just set
all the frac bits and the four upper zero bits to 1. It's now possible
to get the RGB table index by anding the current value >> 5 with the
current value >> 19. When asm-optimised, this should be the fastest
algorithm that uses RGB tables.
*/
#ifndef USEASM
void R_DrawTranslucentColumnP_C (void)
{
int count;
byte* dest;
fixed_t frac;
fixed_t fracstep;
int count;
byte *dest;
fixed_t frac;
fixed_t fracstep;
unsigned int *fg2rgb, *bg2rgb;
count = dc_yh - dc_yl;
if (count < 0)
@ -402,16 +432,23 @@ void R_DrawTranslucentColumnP_C (void)
I_Error ( "R_DrawTranslucentColumnP_C: %i to %i at %i",
dc_yl, dc_yh, dc_x);
}
#endif
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
dest = ylookup[dc_yl] + columnofs[dc_x];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
{
byte *transmap = dc_transmap;
byte *colormap = dc_colormap;
byte *source = dc_source;
int mask = dc_mask;
@ -419,14 +456,18 @@ void R_DrawTranslucentColumnP_C (void)
do
{
*dest = transmap[colormap[source[(frac>>FRACBITS)&mask]] | ((*dest)<<8)];
dest += pitch;
unsigned int fg = colormap[source[(frac>>FRACBITS)&mask]];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
frac += fracstep;
} while (--count);
}
}
#endif // USEASM
//
// R_DrawTranslatedColumn
@ -465,11 +506,9 @@ void R_DrawTranslatedColumnP_C (void)
dest = ylookup[dc_yl] + columnofs[dc_x];
// Looks familiar.
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
// Here we do an additional index re-mapping.
{
// [RH] Local copies of global vars to improve compiler optimizations
byte *colormap = dc_colormap;
@ -480,11 +519,6 @@ void R_DrawTranslatedColumnP_C (void)
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 = colormap[translation[source[(frac>>FRACBITS) & mask]]];
dest += pitch;
@ -493,13 +527,14 @@ void R_DrawTranslatedColumnP_C (void)
}
}
// [RH] Draw a column that is both translated and translucent
// Draw a column that is both translated and translucent
void R_DrawTlatedLucentColumnP_C (void)
{
int count;
byte* dest;
fixed_t frac;
fixed_t fracstep;
int count;
byte *dest;
fixed_t frac;
fixed_t fracstep;
unsigned int *fg2rgb, *bg2rgb;
count = dc_yh - dc_yl;
if (count < 0)
@ -517,6 +552,15 @@ void R_DrawTlatedLucentColumnP_C (void)
#endif
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
dest = ylookup[dc_yl] + columnofs[dc_x];
fracstep = dc_iscale;
@ -524,7 +568,6 @@ void R_DrawTlatedLucentColumnP_C (void)
{
byte *translation = dc_translation;
byte *transmap = dc_transmap;
byte *colormap = dc_colormap;
byte *source = dc_source;
int mask = dc_mask;
@ -532,9 +575,14 @@ void R_DrawTlatedLucentColumnP_C (void)
do
{
*dest = transmap[colormap[translation[source[(frac>>FRACBITS)&mask]]] | ((*dest)<<8)];
dest += pitch;
unsigned int fg = colormap[translation[source[(frac>>FRACBITS)&mask]]];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
frac += fracstep;
} while (--count);
}
@ -1071,7 +1119,7 @@ void R_DrawBorder (int x1, int y1, int x2, int y2)
{
int lump;
lump = R_FlatNumForName ((gamemode == commercial) ? "GRNROCK" : "FLOOR7_2");
lump = R_FlatNumForName (gameinfo.borderFlat);
V_FlatFill (x1 & ~63, y1, x2, y2, &screen,
W_CacheLumpNum (lump + firstflat, PU_CACHE));
@ -1094,6 +1142,8 @@ void V_MarkRect (int x, int y, int width, int height);
void R_DrawViewBorder (void)
{
int x, y;
int offset, size;
gameborder_t *border;
// [RH] Redraw the status bar if SCREENWIDTH > status bar width.
// Will draw borders around itself, too.
@ -1106,43 +1156,47 @@ void R_DrawViewBorder (void)
return;
}
border = gameinfo.border;
offset = border->offset;
size = border->size;
R_DrawBorder (0, 0, screen.width, viewwindowy);
R_DrawBorder (0, viewwindowy, viewwindowx, realviewheight + viewwindowy);
R_DrawBorder (viewwindowx + realviewwidth, viewwindowy, screen.width, realviewheight + viewwindowy);
R_DrawBorder (0, viewwindowy + realviewheight, screen.width, ST_Y);
for (x = viewwindowx; x < viewwindowx + realviewwidth; x += 8)
for (x = viewwindowx; x < viewwindowx + realviewwidth; x += size)
{
V_DrawPatch (x, viewwindowy - 8, &screen, W_CacheLumpName ("brdr_t", PU_CACHE));
V_DrawPatch (x, viewwindowy + realviewheight, &screen, W_CacheLumpName ("brdr_b", PU_CACHE));
V_DrawPatch (x, viewwindowy - offset, &screen,
W_CacheLumpName (border->t, PU_CACHE));
V_DrawPatch (x, viewwindowy + realviewheight, &screen,
W_CacheLumpName (border->b, PU_CACHE));
}
for (y = viewwindowy; y < viewwindowy + realviewheight; y += 8)
for (y = viewwindowy; y < viewwindowy + realviewheight; y += size)
{
V_DrawPatch (viewwindowx - 8, y, &screen, W_CacheLumpName ("brdr_l", PU_CACHE));
V_DrawPatch (viewwindowx + realviewwidth, y, &screen, W_CacheLumpName ("brdr_r", PU_CACHE));
V_DrawPatch (viewwindowx - offset, y, &screen,
W_CacheLumpName (border->l, PU_CACHE));
V_DrawPatch (viewwindowx + realviewwidth, y, &screen,
W_CacheLumpName (border->r, PU_CACHE));
}
// Draw beveled edge.
V_DrawPatch (viewwindowx-8,
viewwindowy-8,
V_DrawPatch (viewwindowx-offset, viewwindowy-offset,
&screen,
W_CacheLumpName ("brdr_tl",PU_CACHE));
W_CacheLumpName (border->tl, PU_CACHE));
V_DrawPatch (viewwindowx+realviewwidth,
viewwindowy-8,
V_DrawPatch (viewwindowx+realviewwidth, viewwindowy-offset,
&screen,
W_CacheLumpName ("brdr_tr",PU_CACHE));
W_CacheLumpName (border->tr, PU_CACHE));
V_DrawPatch (viewwindowx-8,
viewwindowy+realviewheight,
V_DrawPatch (viewwindowx-offset, viewwindowy+realviewheight,
&screen,
W_CacheLumpName ("brdr_bl",PU_CACHE));
W_CacheLumpName (border->bl, PU_CACHE));
V_DrawPatch (viewwindowx+realviewwidth,
viewwindowy+realviewheight,
V_DrawPatch (viewwindowx+realviewwidth, viewwindowy+realviewheight,
&screen,
W_CacheLumpName ("brdr_br",PU_CACHE));
W_CacheLumpName (border->br, PU_CACHE));
V_MarkRect (0,0,screen.width, ST_Y);
V_MarkRect (0, 0, screen.width, ST_Y);
}
/*
@ -1264,7 +1318,7 @@ void R_InitColumnDrawers (BOOL is8bit)
R_DrawColumn = R_DrawColumnP_ASM;
R_DrawColumnHoriz = R_DrawColumnHorizP_ASM;
R_DrawFuzzColumn = R_DrawFuzzColumnP_ASM;
R_DrawTranslucentColumn = R_DrawTranslucentColumnP_ASM;
R_DrawTranslucentColumn = R_DrawTranslucentColumnP_C;
R_DrawTranslatedColumn = R_DrawTranslatedColumnP_C;
if (screen.width <= 320)
R_DrawSpan = R_DrawSpanP_Unrolled;

View file

@ -149,7 +149,7 @@ void R_DrawSpanP_Unrolled (void);
void R_DrawColumnHorizP_ASM (void);
void R_DrawColumnP_ASM (void);
void R_DrawFuzzColumnP_ASM (void);
void R_DrawTranslucentColumnP_ASM (void);
void R_DrawTranslucentColumnP_C (void);
void R_DrawTranslatedColumnP_C (void);
void R_DrawSpanP (void);
@ -191,7 +191,7 @@ extern int ds_color; // [RH] For flat color (no texturing)
extern byte* translationtables;
extern byte* dc_translation;
extern byte* dc_transmap;
extern fixed_t dc_translevel;
/* [Petteri] R_DrawSpan8() optimized inner loop (does two pixels

View file

@ -1026,12 +1026,14 @@ void R_RenderPlayerView (player_t *player)
colfunc = R_FillColumnP;
//spanfunc = R_FillSpan;
}
hcolfunc_pre = R_DrawColumnHoriz;
colfunc = basecolfunc;
hcolfunc_post1 = rt_map1col;
hcolfunc_post2 = rt_map2cols;
hcolfunc_post4 = rt_map4cols;
else
{
hcolfunc_pre = R_DrawColumnHoriz;
colfunc = basecolfunc;
hcolfunc_post1 = rt_map1col;
hcolfunc_post2 = rt_map2cols;
hcolfunc_post4 = rt_map4cols;
}
// Never draw the player unless in chasecam mode
if (camera->player && !(camera->player->cheats & CF_CHASECAM)) {

View file

@ -88,7 +88,6 @@ short *ceilingclip;
// initialized to 0 at start
//
int *spanstart;
int *spanstop;
//
// texture mapping
@ -132,18 +131,14 @@ void R_InitPlanes (void)
void R_MapPlane (int y, int x1, int x2)
{
angle_t angle;
fixed_t distance;
fixed_t length;
unsigned index;
angle_t angle;
fixed_t distance, length;
unsigned index;
#ifdef RANGECHECK
if (x2 < x1
|| x1<0
|| x2>=viewwidth
|| (unsigned)y>=(unsigned)viewheight)
if (x2 < x1 || x1<0 || x2>=viewwidth || (unsigned)y>=(unsigned)viewheight)
{
I_FatalError ("R_MapPlane: %i, %i at %i",x1,x2,y);
I_FatalError ("R_MapPlane: %i, %i at %i", x1, x2, y);
}
#endif
if (planeheight != cachedheight[y])
@ -198,8 +193,8 @@ void R_MapPlane (int y, int x1, int x2)
void R_ClearPlanes (void)
{
int i;
angle_t angle;
int i;
angle_t angle;
// opening / clipping determination
for (i = 0; i < viewwidth ; i++)
@ -214,10 +209,10 @@ void R_ClearPlanes (void)
lastopening = openings;
// texture calculation
// Texture calculation
memset (cachedheight, 0, sizeof(*cachedheight) * screen.height);
angle = (viewangle - ANG90)>>ANGLETOFINESHIFT; // left to right mapping
// scale will be unit scale at SCREENWIDTH/2 distance
// Scale will be unit scale at SCREENWIDTH/2 distance
basexscale = FixedDiv (finecosine[angle], centerxfrac);
baseyscale = -FixedDiv (finesine[angle], centerxfrac);
}
@ -259,8 +254,8 @@ visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel,
visplane_t *check;
unsigned hash; // killough
if (picnum == skyflatnum)
height = lightlevel = 0; // all skys map together
if (picnum == skyflatnum || picnum & PL_SKYFLAT) // killough 10/98
height = lightlevel = 0; // most skies map together
// New visplane algorithm uses hash table -- killough
hash = visplane_hash (picnum, lightlevel, height);
@ -282,7 +277,7 @@ visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel,
check->xoffs = xoffs; // killough 2/28/98: Save offsets
check->yoffs = yoffs;
check->colormap = basecolormap; // [RH] Save colormap
check->minx = screen.width;
check->minx = viewwidth; // Was SCREENWIDTH -- killough 11/98
check->maxx = -1;
memset (check->top, 0xff, sizeof(*check->top) * screen.width);
@ -383,6 +378,9 @@ void R_MakeSpans (int x, int t1, int b1, int t2, int b2)
//==========================================================================
static visplane_t *_skypl;
static int frontskytex, backskytex;
static angle_t skyflip;
static int frontpos, backpos;
static void _skycolumn (void (*drawfunc)(void), int x)
{
@ -390,11 +388,11 @@ static void _skycolumn (void (*drawfunc)(void), int x)
dc_yh = _skypl->bottom[x];
if (dc_yl <= dc_yh) {
int angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + sky1pos)>>16);
int angle = ((((viewangle + xtoviewangle[x])^skyflip)>>(ANGLETOSKYSHIFT-16)) + frontpos)>>16;
if (!(level.flags & LEVEL_DOUBLESKY))
if (backskytex == -1)
{
dc_source = R_GetColumn (sky1texture, angle);
dc_source = R_GetColumn (frontskytex, angle);
drawfunc ();
}
else
@ -413,9 +411,9 @@ static void _skycolumn (void (*drawfunc)(void), int x)
bottom >>= FRACBITS;
count = bottom - top + 1;
source = R_GetColumn (sky1texture, angle) + top;
angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + sky2pos)>>16);
source2 = R_GetColumn (sky2texture, angle) + top;
source = R_GetColumn (frontskytex, angle) + top;
angle = ((((viewangle + xtoviewangle[x])^skyflip)>>(ANGLETOSKYSHIFT-16)) + backpos)>>16;
source2 = R_GetColumn (backskytex, angle) + top;
dest = composite + top;
do
@ -538,8 +536,55 @@ void R_DrawPlanes (void)
continue;
// sky flat
if (pl->picnum == skyflatnum)
if (pl->picnum == skyflatnum || pl->picnum & PL_SKYFLAT)
{
if (pl->picnum == skyflatnum)
{ // use sky1
frontskytex = sky1texture;
if (level.flags & LEVEL_DOUBLESKY)
backskytex = sky2texture;
else
backskytex = -1;
skyflip = 0;
frontpos = sky1pos;
backpos = sky2pos;
}
else if (pl->picnum == PL_SKYFLAT)
{ // use sky2
frontskytex = sky2texture;
backskytex = -1;
skyflip = 0;
frontpos = sky2pos;
}
else
{ // MBF's linedef-controlled skies
// Sky Linedef
const line_t *l = &lines[(pl->picnum & ~PL_SKYFLAT)-1];
// Sky transferred from first sidedef
const side_t *s = *l->sidenum + sides;
// Texture comes from upper texture of reference sidedef
frontskytex = texturetranslation[s->toptexture];
backskytex = -1;
// Horizontal offset is turned into an angle offset,
// to allow sky rotation as well as careful positioning.
// However, the offset is scaled very small, so that it
// allows a long-period of sky rotation.
frontpos = (-s->textureoffset) >> (ANGLETOSKYSHIFT-16);
// Vertical offset allows careful sky positioning.
dc_texturemid = s->rowoffset - 28*FRACUNIT;
// We sometimes flip the picture horizontally.
//
// Doom always flipped the picture, so we make it optional,
// to make it easier to use the new feature, while to still
// allow old sky textures to be used.
skyflip = l->args[2] ? 0u : ~0u;
}
if (fixedlightlev) {
dc_colormap = DefaultPalette->maps.colormaps + fixedlightlev;
} else if (fixedcolormap) {
@ -616,7 +661,6 @@ BOOL R_PlaneInitData (void)
ceilingclip = Malloc (screen.width * sizeof(*ceilingclip));
spanstart = Calloc (screen.height, sizeof(*spanstart));
spanstop = Calloc (screen.height, sizeof(*spanstop));
yslopetab = Calloc ((screen.height<<1)+(screen.height>>1), sizeof(*yslopetab));
distscale = Calloc (screen.width, sizeof(*distscale));

View file

@ -27,6 +27,9 @@
#include "r_data.h"
// killough 10/98: special mask indicates sky flat comes from sidedef
#define PL_SKYFLAT (0x80000000)
// Visplane related.
extern short* lastopening;
@ -46,35 +49,18 @@ extern fixed_t *distscale;
void R_InitPlanes (void);
void R_ClearPlanes (void);
void
R_MapPlane
( int y,
int x1,
int x2 );
void
R_MakeSpans
( int x,
int t1,
int b1,
int t2,
int b2 );
void R_MapPlane (int y, int x1, int x2);
void R_MakeSpans (int x, int t1, int b1, int t2, int b2);
void R_DrawPlanes (void);
visplane_t*
R_FindPlane
visplane_t *R_FindPlane
( fixed_t height,
int picnum,
int lightlevel,
fixed_t xoffs, // killough 2/28/98: add x-y offsets
fixed_t yoffs );
visplane_t*
R_CheckPlane
( visplane_t* pl,
int start,
int stop );
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
// [RH] Added for multires support

View file

@ -164,7 +164,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
if (!r_columnmethod->value) {
if (curline->linedef->lucency < 240) {
colfunc = lucentcolfunc;
dc_transmap = TransTable + ((curline->linedef->lucency << 10) & 0x30000);
dc_translevel = curline->linedef->lucency << 8;
} else
colfunc = basecolfunc;
// killough 4/11/98: end translucent 2s normal code
@ -175,7 +175,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
hcolfunc_post1 = rt_lucent1col;
hcolfunc_post2 = rt_lucent2cols;
hcolfunc_post4 = rt_lucent4cols;
dc_transmap = TransTable + ((curline->linedef->lucency << 10) & 0x30000);
dc_translevel = curline->linedef->lucency << 8;
} else {
hcolfunc_post1 = rt_map1col;
hcolfunc_post2 = rt_map2cols;

View file

@ -84,6 +84,7 @@ short *negonearray;
short *screenheightarray;
#define MAX_SPRITE_FRAMES 29 // [RH] Macro-ized as in BOOM.
#define SPRITE_NEEDS_INFO MAXINT
cvar_t *r_drawplayersprites; // [RH] Draw player sprites?
@ -113,6 +114,30 @@ particle_t *Particles;
cvar_t *r_particles;
void R_CacheSprite (spritedef_t *sprite)
{
int i, r;
patch_t *patch;
DPrintf ("cache sprite %s\n",
sprite - sprites < NUMSPRITES ? sprnames[sprite - sprites] : "");
for (i = 0; i < sprite->numframes; i++)
{
for (r = 0; r < 8; r++)
{
if (sprite->spriteframes[i].width[r] == SPRITE_NEEDS_INFO)
{
if (sprite->spriteframes[i].lump[r] == -1)
I_Error ("Sprite %d, rotation %d has no lump", i, r);
patch = W_CacheLumpNum (sprite->spriteframes[i].lump[r], PU_CACHE);
sprite->spriteframes[i].width[r] = SHORT(patch->width)<<FRACBITS;
sprite->spriteframes[i].offset[r] = SHORT(patch->leftoffset)<<FRACBITS;
sprite->spriteframes[i].topoffset[r] = SHORT(patch->topoffset)<<FRACBITS;
}
}
}
}
//
// R_InstallSpriteLump
// Local function for R_InitSprites.
@ -124,18 +149,9 @@ static void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BO
{
static unsigned int called;
// [RH] Record the sprite's width, offset, and topoffset here
// instead of in R_InitSpriteLumps().
patch_t *patch;
if (!((called++) & 63))
C_SetTicker (called);
if (frame >= MAX_SPRITE_FRAMES || rotation > 8)
I_FatalError ("R_InstallSpriteLump: Bad frame characters in lump %i", lump);
patch = W_CacheLumpNum (lump, PU_CACHE);
if ((int)frame > maxframe)
maxframe = frame;
@ -150,22 +166,14 @@ static void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BO
sprtemp[frame].lump[r] = (short)(lump);
sprtemp[frame].flip[r] = (byte)flipped;
sprtemp[frame].rotate = false;
// [RH] Need to set these, too.
sprtemp[frame].width[r] = SHORT(patch->width)<<FRACBITS;
sprtemp[frame].offset[r] = SHORT(patch->leftoffset)<<FRACBITS;
sprtemp[frame].topoffset[r] = SHORT(patch->topoffset)<<FRACBITS;
sprtemp[frame].width[r] = SPRITE_NEEDS_INFO;
}
} else if (sprtemp[frame].lump[--rotation] == -1) {
// the lump is only used for one rotation
sprtemp[frame].lump[rotation] = (short)(lump);
sprtemp[frame].flip[rotation] = (byte)flipped;
sprtemp[frame].rotate = true;
// [RH] Need to set these, too.
sprtemp[frame].width[rotation] = SHORT(patch->width)<<FRACBITS;
sprtemp[frame].offset[rotation] = SHORT(patch->leftoffset)<<FRACBITS;
sprtemp[frame].topoffset[rotation] = SHORT(patch->topoffset)<<FRACBITS;
sprtemp[frame].width[rotation] = SPRITE_NEEDS_INFO;
}
}
@ -176,7 +184,8 @@ static void R_InstallSprite (const char *name, int num)
char sprname[5];
int frame;
if (maxframe == -1) {
if (maxframe == -1)
{
sprites[num].numframes = 0;
return;
}
@ -255,8 +264,6 @@ void R_InitSpriteDefs (char **namelist)
if (!numsprites)
return;
C_InitTicker ("sprites", W_GetNumForName ("S_END") - W_GetNumForName ("S_START") - 2);
sprites = Z_Malloc (numsprites * sizeof(*sprites), PU_STATIC, NULL);
start = firstspritelump - 1;
@ -294,7 +301,6 @@ void R_InitSpriteDefs (char **namelist)
R_InstallSprite (namelist[i], i);
}
C_InitTicker (NULL, 0);
}
// [RH]
@ -475,7 +481,6 @@ void R_InitSkins (void)
}
}
}
C_InitTicker (NULL, 0);
// Grrk. May have changed sound table. Fix it.
if (numskins > 1)
S_HashSounds ();
@ -693,9 +698,9 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
{
// [RH] I use MF_SHADOW to recognize fuzz effect now instead of
// a NULL colormap. This allow proper substition of
// MF_TRANSLUC25 with light levels if desired. The original
// code used colormap == NULL instead.
dc_transmap = TransTable + 65536; // Just in case
// translucency with light levels if desired. The original
// code used colormap == NULL to indicate shadows.
dc_translevel = FRACUNIT/5;
if (r_drawfuzz->value) {
colfunc = fuzzcolfunc;
} else {
@ -705,13 +710,13 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
colfunc = tlatedlucentcolfunc;
}
}
else if ((vis->mobjflags & MF_TRANSLUCBITS) && TransTable)
else if (vis->translucency < FRACUNIT)
{ // [RH] draw translucent column
if (colfunc == basecolfunc)
colfunc = lucentcolfunc;
else
colfunc = tlatedlucentcolfunc;
dc_transmap = TransTable + ((vis->mobjflags & MF_TRANSLUCBITS) >> (MF_TRANSLUCSHIFT - 16));
dc_translevel = vis->translucency;
}
//dc_iscale = abs(vis->xiscale)>>detailshift;
@ -870,8 +875,7 @@ void R_ProjectSprite (mobj_t *thing)
int heightsec; // killough 3/27/98
// [RH] Andy Baker's stealth monsters
if (thing->flags2 & MF2_DONTDRAW)
if (thing->flags2 & MF2_DONTDRAW || thing->translucency == 0)
return;
// transform the origin point
@ -913,7 +917,7 @@ void R_ProjectSprite (mobj_t *thing)
return;
}
#endif
sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];
if (sprframe->rotate)
{
@ -929,6 +933,9 @@ void R_ProjectSprite (mobj_t *thing)
lump = sprframe->lump[rot = 0];
flip = (BOOL)sprframe->flip[0];
}
if (sprframe->width[rot] == SPRITE_NEEDS_INFO)
R_CacheSprite (sprdef); // [RH] speeds up game startup time
// calculate edges of the shape
tx -= sprframe->offset[rot]; // [RH] Moved out of spriteoffset[]
@ -990,6 +997,7 @@ void R_ProjectSprite (mobj_t *thing)
vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
vis->translation = thing->translation; // [RH] thing translation table
vis->translucency = thing->translucency;
iscale = FixedDiv (FRACUNIT, xscale);
if (flip)
@ -1103,6 +1111,9 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
lump = sprframe->lump[0];
flip = (BOOL)sprframe->flip[0];
if (sprframe->width[0] == SPRITE_NEEDS_INFO)
R_CacheSprite (sprdef); // [RH] speeds up game startup time
// calculate edges of the shape
tx = psp->sx-((320/2)<<FRACBITS);
@ -1130,6 +1141,7 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
vis->scale = pspriteyscale;
vis->translation = NULL; // [RH] Use default colors
vis->translucency = FRACUNIT;
if (flip)
{
@ -1680,7 +1692,7 @@ void R_ProjectParticle (particle_t *particle)
vis->mobjflags = particle->trans;
if (fixedlightlev) {
vis->colormap = basecolormap + fixedlightlev;
vis->colormap = sector->colormap->maps + fixedlightlev;
} else if (fixedcolormap) {
vis->colormap = fixedcolormap;
} else if (sector) {
@ -1695,7 +1707,7 @@ void R_ProjectParticle (particle_t *particle)
if (index >= MAXLIGHTSCALE)
index = MAXLIGHTSCALE-1;
vis->colormap = scalelight[lightnum][index] + basecolormap;
vis->colormap = scalelight[lightnum][index] + sector->colormap->maps;
} else {
vis->colormap = realcolormaps;
}
@ -1706,12 +1718,9 @@ void R_DrawParticle (vissprite_t *vis, int x1, int x2)
byte color = vis->colormap[vis->startfrac];
int yl = (centeryfrac - FixedMul(vis->texturemid, vis->scale) + FRACUNIT - 1) >> FRACBITS;
int yh;
int y;
x1 = vis->x1;
x2 = vis->x2;
// dc_transmap = TransTable + ((vis->mobjflags & MF_TRANSLUCBITS) >> (MF_TRANSLUCSHIFT - 16));
if (x1 < 0)
x1 = 0;
if (x2 < x1)
@ -1731,34 +1740,46 @@ void R_DrawParticle (vissprite_t *vis, int x1, int x2)
if (yl <= mceilingclip[x2])
yl = mceilingclip[x2]+1;
// vis->mobjflags holds translucency level (1-255)
if (!TransTable || vis->mobjflags >= 192) {
for (y = yl; y <= yh; y++) {
byte *dest = ylookup[y] + columnofs[x1];
int count = x2 - x1 + 1;
do {
*dest = color;
dest += ds_colsize;
} while (--count);
}
} else {
byte *transmap;
// vis->mobjflags holds translucency level (0-255)
{
unsigned int *bg2rgb;
int countbase = x2 - x1 + 1;
int ycount;
int colsize = ds_colsize;
int spacing;
byte *dest;
unsigned int fg;
if (vis->mobjflags >= 128)
transmap = TransTable + 65536;
else if (vis->mobjflags >= 64)
transmap = TransTable + 65536*2;
else
transmap = TransTable + 65536*3;
transmap += color << 8;
ycount = yh - yl;
if (ycount < 0)
return;
ycount++;
for (y = yl; y <= yh; y++) {
byte *dest = ylookup[y] + columnofs[x1];
int count = x2 - x1 + 1;
do {
*dest = transmap[*dest];
dest += ds_colsize;
} while (--count);
{
fixed_t fglevel, bglevel;
unsigned int *fg2rgb;
fglevel = ((vis->mobjflags + 1) << 8) & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
fg = fg2rgb[color];
}
spacing = screen.pitch - (countbase << detailxshift);
dest = ylookup[yl] + columnofs[x1];
do
{
int count = countbase;
do
{
unsigned int bg = bg2rgb[*dest];
bg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(bg>>5) & (bg>>19)];
dest += colsize;
} while (--count);
dest += spacing;
} while (--ycount);
}
}

View file

@ -88,8 +88,8 @@ extern fixed_t pspriteyscale; // [RH] Aspect ratio stuff (from Doom Legacy)
void R_DrawMaskedColumn (column_t* column);
void R_CacheSprite (spritedef_t *sprite);
void R_SortVisSprites (void);
void R_AddSprites (sector_t *sec, int lightlevel);
void R_AddPSprites (void);
void R_DrawSprites (void);

View file

@ -40,6 +40,11 @@
#include "v_video.h"
#include "v_text.h"
#define SELECT_ATTEN(a) ((a)==ATTN_NONE ? 0 : (a)==ATTN_SURROUND ? -1 : \
(a)==ATTN_STATIC ? 3 : 1)
#ifndef FIXED2FLOAT
#define FIXED2FLOAT(f) (((float)(f))/(float)65536)
#endif
#define MAX_SND_DIST 2025
#define PRIORITY_MAX_ADJUST 10
@ -62,7 +67,7 @@ typedef struct
int sound_id;
int entchannel; // entity's sound channel
int basepriority;
int attenuation;
float attenuation;
float volume;
int pitch;
int priority;
@ -116,10 +121,15 @@ static fixed_t P_AproxDistance2 (mobj_t *listener, fixed_t x, fixed_t y)
{
// calculate the distance to sound origin
// and clip it if necessary
fixed_t adx = abs (listener->x - x);
fixed_t ady = abs (listener->y - y);
// From _GG1_ p.428. Appox. eucledian distance fast.
return adx + ady - ((adx < ady ? adx : ady)>>1);
if (listener)
{
fixed_t adx = abs (listener->x - x);
fixed_t ady = abs (listener->y - y);
// From _GG1_ p.428. Appox. eucledian distance fast.
return adx + ady - ((adx < ady ? adx : ady)>>1);
}
else
return 0;
}
//
@ -136,9 +146,9 @@ void S_NoiseDebug (void)
y += 8;
V_DrawText (CR_GREY, 0, y, "name");
V_DrawText (CR_GREY, 70, y, "mo.x");
V_DrawText (CR_GREY, 120, y, "mo.y");
V_DrawText (CR_GREY, 170, y, "id");
V_DrawText (CR_GREY, 70, y, "x");
V_DrawText (CR_GREY, 120, y, "y");
V_DrawText (CR_GREY, 170, y, "vol");
V_DrawText (CR_GREY, 200, y, "pri");
V_DrawText (CR_GREY, 240, y, "dist");
V_DrawText (CR_GREY, 280, y, "chan");
@ -149,14 +159,18 @@ void S_NoiseDebug (void)
char temp[16];
mobj_t *origin = Channel[i].mo;
if (Channel[i].attenuation == ATTN_NONE ||
Channel[i].attenuation == ATTN_SURROUND) {
if (Channel[i].attenuation <= 0)
{
ox = players[consoleplayer].camera->x;
oy = players[consoleplayer].camera->y;
} else if (origin) {
}
else if (origin)
{
ox = origin->x;
oy = origin->y;
} else {
}
else
{
ox = Channel[i].x;
oy = Channel[i].y;
}
@ -168,7 +182,7 @@ void S_NoiseDebug (void)
V_DrawText (color, 70, y, temp);
sprintf (temp, "%d", oy / FRACUNIT);
V_DrawText (color, 120, y, temp);
sprintf (temp, "%ld", Channel[i].sfxinfo - S_sfx);
sprintf (temp, "%g", Channel[i].volume);
V_DrawText (color, 170, y, temp);
sprintf (temp, "%d", Channel[i].priority);
V_DrawText (color, 200, y, temp);
@ -284,8 +298,14 @@ void S_Start (void)
// [RH] Split S_StartSoundAtVolume into multiple parts so that sounds can
// be specified both by id and by name. Also borrowed some stuff from
// Hexen and parameters from Quake.
//
// 0 attenuation means full volume over whole level
// -1 attenuation means full volume in surround over whole level
// 0<attenuation<=1 means to scale the distance by that amount when
// calculating volume
static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
int sound_id, float volume, int attenuation, BOOL looping)
int sound_id, float volume, float attenuation, BOOL looping)
{
sfxinfo_t *sfx;
int dist, vol;
@ -299,12 +319,17 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
if (sound_id == -1 || volume <= 0)
return;
if (ent == NULL) {
if (attenuation != ATTN_SURROUND)
attenuation = ATTN_NONE;
} else if (ent == (mobj_t *)(~0)) {
if (ent == NULL)
{
if (attenuation > 0)
attenuation = 0;
}
else if (ent == (mobj_t *)(~0))
{
ent = NULL;
} else {
}
else
{
x = ent->x;
y = ent->y;
}
@ -313,24 +338,31 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
if (volume > 1)
volume = 1;
if (attenuation == ATTN_NONE) {
if (attenuation == 0)
{
sep = NORM_SEP;
dist = 0;
} else if (attenuation == ATTN_SURROUND) {
}
else if (attenuation < 0)
{
sep = -1;
dist = 0;
} else {
}
else
{
// calculate the distance before other stuff so we can throw out
// sounds that are beyond the hearing range.
dist = P_AproxDistance2 (players[consoleplayer].camera, x, y) >> FRACBITS;
if (attenuation == ATTN_STATIC)
dist *= 3;
if (dist >= MAX_SND_DIST) {
dist = (int)(FIXED2FLOAT
(P_AproxDistance2 (players[consoleplayer].camera, x, y))
* attenuation);
if (dist >= MAX_SND_DIST)
{
if (level.flags & LEVEL_NOSOUNDCLIPPING)
dist = MAX_SND_DIST;
else
return; // sound is beyond the hearing range...
} else if (dist < 0)
}
else if (dist < 0)
dist = 0;
sep = -2; // Calculate separation later on
}
@ -344,12 +376,18 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
sfx = sfx->link;
}
if (sfx->lumpnum == sfx_empty) {
if (sfx->lumpnum == sfx_empty)
{
basepriority = -1000;
} else if (attenuation == ATTN_NONE || attenuation == ATTN_SURROUND) {
}
else if (attenuation <= 0)
{
basepriority = 200;
} else {
switch (channel) {
}
else
{
switch (channel)
{
case CHAN_WEAPON:
basepriority = 100;
break;
@ -364,7 +402,7 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
basepriority = 25;
break;
}
if (attenuation == ATTN_NORM)
if (attenuation == 1)
basepriority += 50;
if (dist == 0)
basepriority += 30;
@ -374,30 +412,41 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
if (!S_StopSoundID (sound_id, priority))
return; // other sounds have greater priority
if (ent) {
for (i = 0; i < numChannels; i++) {
if (ent)
{
for (i = 0; i < numChannels; i++)
{
if (Channel[i].sfxinfo &&
ent == Channel[i].mo &&
Channel[i].entchannel == channel) {
Channel[i].entchannel == channel)
{
break;
}
}
if (i < numChannels && channel != CHAN_AUTO) {
if (i < numChannels && channel != CHAN_AUTO)
{
S_StopChannel (i);
} else if (channel == CHAN_AUTO) {
}
else if (channel == CHAN_AUTO)
{
int chansused[8], freechan;
memset (chansused, 0, sizeof(chansused));
freechan = numChannels;
for (i = 0; i < numChannels; i++) {
if (!Channel[i].sfxinfo) {
for (i = 0; i < numChannels; i++)
{
if (!Channel[i].sfxinfo)
{
freechan = i;
} else if (ent == Channel[i].mo) {
}
else if (ent == Channel[i].mo)
{
chansused[Channel[i].entchannel] = 1;
}
}
for (i = 7; i >= 0; i--) {
for (i = 7; i >= 0; i--)
{
if (!chansused[i])
break;
}
@ -406,31 +455,42 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
channel = i;
i = freechan;
}
} else {
}
else
{
i = numChannels;
}
if (i >= numChannels) {
for (i = 0; i < numChannels; i++) {
if (Channel[i].sfxinfo == NULL) {
if (i >= numChannels)
{
for (i = 0; i < numChannels; i++)
{
if (Channel[i].sfxinfo == NULL)
{
break;
}
}
if (i >= numChannels) {
if (i >= numChannels)
{
// look for a lower priority sound to replace.
sndcount++;
if (sndcount >= numChannels)
sndcount = 0;
for (chan = 0; chan < numChannels; chan++) {
for (chan = 0; chan < numChannels; chan++)
{
i = (sndcount + chan) % numChannels;
if (priority >= Channel[i].priority) {
if (priority >= Channel[i].priority)
{
chan = -1; //denote that sound should be replaced.
break;
}
}
if (chan != -1) {
if (chan != -1)
{
return; // no free channels.
} else {
}
else
{
// replace the lower priority sound.
S_StopChannel (i);
}
@ -438,11 +498,15 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
}
vol = (int)(SoundCurve[dist]*volume*2);
if (sep == -2) {
if (sep == -2)
{
mobj_t *listener = players[consoleplayer].camera;
if (!listener || dist == 0) {
if (!listener || dist == 0)
{
sep = NORM_SEP;
} else {
}
else
{
angle = R_PointToAngle2 (listener->x, listener->y, x, y);
if (angle > listener->angle)
angle = angle - listener->angle;
@ -482,16 +546,16 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
void S_SoundID (mobj_t *ent, int channel, int sound_id, float volume, int attenuation)
{
S_StartSound (ent, 0, 0, channel, sound_id, volume, attenuation, false);
S_StartSound (ent, 0, 0, channel, sound_id, volume, SELECT_ATTEN(attenuation), false);
}
void S_LoopedSoundID (mobj_t *ent, int channel, int sound_id, float volume, int attenuation)
{
S_StartSound (ent, 0, 0, channel, sound_id, volume, attenuation, true);
S_StartSound (ent, 0, 0, channel, sound_id, volume, SELECT_ATTEN(attenuation), true);
}
static void S_StartNamedSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
char *name, float volume, int attenuation, BOOL looping)
char *name, float volume, float attenuation, BOOL looping)
{
int sfx_id;
@ -526,17 +590,17 @@ static void S_StartNamedSound (mobj_t *ent, fixed_t x, fixed_t y, int channel,
void S_Sound (mobj_t *ent, int channel, char *name, float volume, int attenuation)
{
S_StartNamedSound (ent, 0, 0, channel, name, volume, attenuation, false);
S_StartNamedSound (ent, 0, 0, channel, name, volume, SELECT_ATTEN(attenuation), false);
}
void S_LoopedSound (mobj_t *ent, int channel, char *name, float volume, int attenuation)
{
S_StartNamedSound (ent, 0, 0, channel, name, volume, attenuation, true);
S_StartNamedSound (ent, 0, 0, channel, name, volume, SELECT_ATTEN(attenuation), true);
}
void S_PositionedSound (fixed_t x, fixed_t y, int channel, char *name, float volume, int attenuation)
{
S_StartNamedSound ((mobj_t *)(~0), x, y, channel, name, volume, attenuation, false);
S_StartNamedSound ((mobj_t *)(~0), x, y, channel, name, volume, SELECT_ATTEN(attenuation), false);
}
// S_StopSoundID from Hexen (albeit, modified somewhat)
@ -675,8 +739,7 @@ void S_UpdateSounds (void *listener_p)
S_StopChannel (i);
}
if (Channel[i].sound_id == -1
|| Channel[i].mo == listener || Channel[i].attenuation == ATTN_NONE
|| Channel[i].attenuation == ATTN_SURROUND)
|| Channel[i].mo == listener || Channel[i].attenuation <= 0)
{
continue;
}
@ -689,9 +752,8 @@ void S_UpdateSounds (void *listener_p)
x = Channel[i].mo->x;
y = Channel[i].mo->y;
}
dist = P_AproxDistance2 (listener, x, y) >> FRACBITS;
if (Channel[i].attenuation == ATTN_STATIC)
dist *= 3;
dist = (int)(FIXED2FLOAT(P_AproxDistance2 (listener, x, y))
* Channel[i].attenuation);
if (dist >= MAX_SND_DIST)
{
if (!(level.flags & LEVEL_NOSOUNDCLIPPING)) {
@ -864,7 +926,8 @@ static struct AmbientSound {
unsigned type; // type of ambient sound
int periodmin; // # of tics between repeats
int periodmax; // max # of tics for random ambients
int volume; // relative volume of sound
float volume; // relative volume of sound
float attenuation;
char sound[MAX_SNDNAME+1]; // Logical name of sound to play
} Ambients[256];
@ -976,7 +1039,7 @@ void S_ParseSndInfo (void)
// com_token is a command
if (!stricmp (com_token + 1, "ambient")) {
// $ambient <num> <logical name> [point|surround] <type> [secs] <relative volume>
// $ambient <num> <logical name> [point [atten]|surround] <type> [secs] <relative volume>
struct AmbientSound *ambient, dummy;
int index;
@ -993,16 +1056,28 @@ void S_ParseSndInfo (void)
sndinfo = COM_Parse (sndinfo);
strncpy (ambient->sound, com_token, MAX_SNDNAME);
ambient->sound[MAX_SNDNAME] = 0;
ambient->attenuation = 0;
sndinfo = COM_Parse (sndinfo);
if (!stricmp (com_token, "point")) {
float attenuation;
ambient->type = POSITIONAL;
sndinfo = COM_Parse (sndinfo);
} else {
if (!stricmp (com_token, "surround")) {
ambient->type = SURROUND;
attenuation = (float)atof (com_token);
if (attenuation > 0)
{
ambient->attenuation = attenuation;
sndinfo = COM_Parse (sndinfo);
}
else
{
ambient->attenuation = 1;
}
} else if (!stricmp (com_token, "surround")) {
ambient->type = SURROUND;
sndinfo = COM_Parse (sndinfo);
ambient->attenuation = -1;
}
if (!stricmp (com_token, "continuous")) {
@ -1022,9 +1097,9 @@ void S_ParseSndInfo (void)
}
sndinfo = COM_Parse (sndinfo);
ambient->volume = (int)(atof (com_token) * 255.0);
if (ambient->volume > 255)
ambient->volume = 255;
ambient->volume = (float)atof (com_token);
if (ambient->volume > 1)
ambient->volume = 1;
else if (ambient->volume < 0)
ambient->volume = 0;
} else if (!stricmp (com_token + 1, "map")) {
@ -1076,10 +1151,12 @@ void Cmd_Soundlist (void *plyr, int argc, char **argv)
lumpname[8] = 0;
for (i = 0; i < numsfx; i++)
if (S_sfx[i].lumpnum != -1) {
if (S_sfx[i].lumpnum != -1)
{
strncpy (lumpname, lumpinfo[S_sfx[i].lumpnum].name, 8);
Printf (PRINT_HIGH, "%3d. %s (%s)\n", i+1, S_sfx[i].name, lumpname);
} else
}
else
Printf (PRINT_HIGH, "%3d. %s **not present**\n", i+1, S_sfx[i].name);
}
@ -1094,13 +1171,18 @@ void Cmd_Soundlinks (void *plyr, int argc, char **argv)
static void SetTicker (int *tics, struct AmbientSound *ambient)
{
if ((ambient->type & CONTINUOUS) == CONTINUOUS) {
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
{
*tics = 1;
} else if (ambient->type & RANDOM) {
}
else if (ambient->type & RANDOM)
{
*tics = (int)(((float)rand() / (float)RAND_MAX) *
(float)(ambient->periodmax - ambient->periodmin)) +
ambient->periodmin;
} else {
}
else
{
*tics = ambient->periodmin;
}
}
@ -1114,25 +1196,29 @@ void A_Ambient (mobj_t *actor)
if (S_GetSoundPlayingInfo (actor, S_FindSound (ambient->sound)))
return;
if (ambient->sound[0]) {
S_LoopedSound (actor, CHAN_BODY, ambient->sound, ambient->volume,
ambient->type & POSITIONAL ? ATTN_NORM :
(ambient->type & SURROUND ? ATTN_SURROUND : ATTN_NONE));
if (ambient->sound[0])
{
S_StartNamedSound (actor, 0, 0, CHAN_BODY,
ambient->sound, ambient->volume, ambient->attenuation, true);
SetTicker (&actor->tics, ambient);
} else {
}
else
{
P_RemoveMobj (actor);
}
}
else
{
if (ambient->sound[0]) {
S_Sound (actor, CHAN_BODY, ambient->sound, ambient->volume,
ambient->type & POSITIONAL ? ATTN_NORM :
(ambient->type & SURROUND ? ATTN_SURROUND : ATTN_NONE));
if (ambient->sound[0])
{
S_StartNamedSound (actor, 0, 0, CHAN_BODY,
ambient->sound, ambient->volume, ambient->attenuation, false);
SetTicker (&actor->tics, ambient);
} else {
}
else
{
P_RemoveMobj (actor);
}
}
@ -1142,7 +1228,8 @@ void S_ActivateAmbient (mobj_t *origin, int ambient)
{
struct AmbientSound *amb = &Ambients[ambient];
if (!(amb->type & 3) && !amb->periodmin) {
if (!(amb->type & 3) && !amb->periodmin)
{
sfxinfo_t *sfx = S_sfx + S_FindSound (amb->sound);
// Make sure the sound has been loaded so we know how long it is

View file

@ -37,8 +37,9 @@ typedef struct sfxinfo_struct sfxinfo_t;
struct sfxinfo_struct
{
char name[MAX_SNDNAME+1]; // [RH] Sound name defined in SNDINFO
void* data; // sound data
void* loopdata; // Sound data for looping sounds
unsigned normal; // Normal sample handle
unsigned looping; // Looping sample handle
void* data;
struct sfxinfo_struct *link;

View file

@ -126,7 +126,9 @@ void ST_newDraw (void)
if (plyr->armortype && plyr->armorpoints) {
if (armors[plyr->armortype])
V_DrawPatchCleanNoMove (20 * CleanXfac, y - 4*CleanYfac,
&screen, armors[plyr->armortype-1]);
&screen,
plyr->armortype > 2 ? armors[1] :
armors[plyr->armortype-1]);
ST_DrawNum (40*CleanXfac, y - (SHORT(armors[0]->height)+3)*CleanYfac,
&screen, plyr->armorpoints);
}
@ -160,19 +162,45 @@ void ST_newDraw (void)
void ST_nameDraw (int y)
{
int x, color;
char conbuff[64], *string, pnum[4];
BOOL inconsistant;
if (!netgame || level.time > NameUp + 5 || (level.time < TICRATE * 3 && !demoplayback))
inconsistant = false;
for (x = 0; x < MAXPLAYERS; x++)
{
if (playeringame[x] && players[x].inconsistant)
{
if (!inconsistant)
{
strcpy (conbuff, "Consistency failure: ");
inconsistant = true;
}
pnum[0] = '0' + x;
pnum[1] = 0;
strcat (conbuff, pnum);
}
}
if (!inconsistant && (!netgame || level.time > NameUp + 5 || (level.time < TICRATE * 3 && !demoplayback)))
return;
if (plyr - players == consoleplayer)
color = CR_GOLD;
else
if (inconsistant)
{
color = CR_GREEN;
x = (screen.width - V_StringWidth (plyr->userinfo.netname)*CleanXfac) >> 1;
if (level.time < NameUp)
V_DrawTextClean (color, x, y, plyr->userinfo.netname);
string = conbuff;
}
else
V_DrawTextCleanLuc (color, x, y, plyr->userinfo.netname);
{
string = plyr->userinfo.netname;
if (plyr - players == consoleplayer)
color = CR_GOLD;
else
color = CR_GREEN;
}
x = (screen.width - V_StringWidth (string)*CleanXfac) >> 1;
if (level.time < NameUp || inconsistant)
V_DrawTextClean (color, x, y, string);
else
V_DrawTextCleanLuc (color, x, y, string);
BorderNeedRefresh = true;
}

View file

@ -929,7 +929,8 @@ void ST_updateWidgets(void)
void ST_Ticker (void)
{
//FIXME
//return;
st_clock++;
st_randomnumber = M_Random();
ST_updateWidgets();
@ -1084,6 +1085,8 @@ void ST_Drawer (void)
"Demo was recorded with a different version\n"
"of ZDoom. Expect it to go out of sync.");
//FIXME
//return;
if (realviewheight == screen.height && viewactive)
{
if (DrawNewHUD)
@ -1485,7 +1488,8 @@ static BOOL st_stopped = true;
void ST_Start (void)
{
// FIXME
//return;
if (!st_stopped)
ST_Stop();
@ -1535,6 +1539,8 @@ void ST_ChangeScale (cvar_t *var)
void ST_Init (void)
{
//FIXME
//return;
veryfirsttime = 0;
if (!V_AllocScreen (&stbarscreen, 320, 32, 8) ||

View file

@ -17,7 +17,6 @@ BITS 32
; External variables:
EXTERN _columnofs
EXTERN _TransTable
EXTERN _ylookup
EXTERN _centery
EXTERN _fuzzpos
@ -27,7 +26,6 @@ EXTERN _realviewheight
EXTERN _dc_pitch
EXTERN _dc_colormap
EXTERN _dc_transmap
EXTERN _dc_iscale
EXTERN _dc_texturemid
EXTERN _dc_source
@ -193,27 +191,20 @@ _ASM_PatchPitch:
mov [rdcp1+2],edx
mov [f1a+3],edx
mov [f1b+2],edx
mov [l1a+2],edx
mov [l1b+2],edx
; 2 * dc_pitch
add edx,[_dc_pitch]
mov [f2a+3],edx
mov [f2b+2],edx
mov [l2a+2],edx
mov [l2b+2],edx
; 3 * dc_pitch
add edx,[_dc_pitch]
mov [f3a+3],edx
mov [f3b+2],edx
mov [l3a+2],edx
mov [l3b+2],edx
; 4 * dc_pitch
add edx,[_dc_pitch]
mov [f4+2],edx
mov [l4+2],edx
jmp _PatchUnrolled
@ -461,197 +452,6 @@ dfcdone:
pop ebx
ret
;*----------------------------------------------------------------------
;*
;* R_DrawTranslucentColumnP
;*
;*----------------------------------------------------------------------
GLOBAL _R_DrawTranslucentColumnP_ASM
GLOBAL @R_DrawTranslucentColumnP_ASM@0
align 16
_R_DrawTranslucentColumnP_ASM:
@R_DrawTranslucentColumnP_ASM@0:
;
; dest = ylookup[dc_yl] + columnofs[dc_x];
;
push ebp
push ebx
push edi
push esi
mov ebp,[_dc_yl]
;
; pixelcount = yh - yl + 1
;
mov eax,[_dc_yh]
mov ebx,ebp
inc eax
sub eax,ebp ; pixel count
mov [pixelcount],eax ; save for final pixel
jle near ldone ; nothing to scale
mov edi,[_ylookup]
push ebp ; make space for ystep frac. later
mov edi,[edi+ebx*4]
mov esi,[_columnofs]
mov ebx,[_dc_x]
add edi,[esi+ebx*4] ; edi = dest
;
; frac = dc_texturemid - (centery-dc_yl)*fracstep;
;
mov ecx,[_dc_iscale] ; fracstep
mov eax,[_centery]
sub eax,ebp
imul eax,ecx
mov edx,[_dc_texturemid]
sub edx,eax
mov ebx,edx
shr ebx,16 ; frac int.
and ebx,[_dc_mask]
shl edx,16 ; y frac up
mov ebp,ecx
shl ebp,16 ; fracstep f. up
shr ecx,16 ; fracstep i. ->cl
and cl,[_dc_mask]
mov esi,[_dc_source]
mov eax,[pixelcount]
mov [esp],ebp
mov ebp,edx
mov ch,al
shr eax,2
mov edx,[_dc_transmap]
test ch,3
jz .l4quadloop
mov eax,[_dc_colormap]
;
; [esp] : ystep frac. upper 24 bits
; ebp : y frac. upper 24 bits
; ebx : y i. lower 8 bits, masked for index
; ecx : ch = counter, cl = y step i.
; eax : colormap aligned 256
; edx : transtable aligned 65536
; esi : source texture column
; edi : dest screen
;
;
; do un-even pixel
;
test ch,1
jz .lc2
mov al,[esi+ebx]
mov dh,[edi]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
mov [edi],al
and ebx,[_dc_mask]
add edi,[_dc_pitch]
;
; do two non-quad-aligned pixels
;
.lc2:
test ch,2
jz .lc3
mov al,[esi+ebx]
mov dh,[edi]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
mov [edi],al
and ebx,[_dc_mask]
mov al,[esi+ebx]
mov dh,[edi]
add edi,[_dc_pitch]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
mov [edi],al
and ebx,[_dc_mask]
add edi,[_dc_pitch]
;
; test if there were at least 4 pixels
;
.lc3:
mov eax,[pixelcount]
shr eax,2
test eax,eax ; test quad count
jz near ldone
.l4quadloop:
mov ch,al
mov eax,[_dc_colormap]
; .align 4
lquadloop:
mov al,[esi+ebx]
mov dh,[edi]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
mov [edi],al
and ebx,[_dc_mask]
mov al,[esi+ebx]
l1a: mov dh,[edi+0x12345678]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
l1b: mov [edi+0x12345678],al
and ebx,[_dc_mask]
mov al,[esi+ebx]
l2a: mov dh,[edi+2*0x12345678]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
l2b: mov [edi+2*0x12345678],al
and ebx,[_dc_mask]
mov al,[esi+ebx]
l3a: mov dh,[edi+3*0x12345678]
mov dl,[eax]
add ebp,[esp]
mov al,[edx]
adc bl,cl
l3b: mov [edi+3*0x12345678],al
and ebx,[_dc_mask]
l4: add edi,4*0x12345678
dec ch
jnz lquadloop
ldone:
pop ebp
pop esi
pop edi
pop ebx
pop ebp
ret
;*----------------------------------------------------------------------
;*

View file

@ -61,12 +61,13 @@
#include "c_dispch.h"
#include "cmdlib.h"
extern void STACK_ARGS DimScreenPLoop (byte *colormap, byte *screen, int width, int modulo, int height);
extern char *IdStrings[22];
extern int DisplayID;
unsigned int Col2RGB8[65][256];
byte RGB8k[16][32][16];
// [RH] The framebuffer is no longer a mere byte array.
@ -78,8 +79,6 @@ int dirtybox[4];
cvar_t *vid_defwidth, *vid_defheight, *vid_defid;
cvar_t *dimamount, *dimcolor;
byte *TransTable;
palette_t *DefaultPalette;
@ -203,44 +202,40 @@ void V_Clear (int left, int top, int right, int bottom, screen_t *scrn, int colo
void V_DimScreen (screen_t *screen)
{
byte *fadetable;
if (dimamount->value < 0)
SetCVarFloat (dimamount, 0);
else if (dimamount->value > 1)
SetCVarFloat (dimamount, 1);
if (dimamount->value < 0.0)
SetCVarFloat (dimamount, 0.0);
else if (dimamount->value > 3.0)
SetCVarFloat (dimamount, 3.0);
if (dimamount->value == 0.0)
if (dimamount->value == 0)
return;
if (screen->is8bit) {
if (!TransTable)
fadetable = DefaultPalette->maps.colormaps + (NUMCOLORMAPS/2) * 256;
else
fadetable = TransTable + 65536*(4-(int)dimamount->value) +
256*V_GetColorFromString (DefaultPalette->basecolors, dimcolor->string);
unsigned int *bg2rgb;
unsigned int fg;
int gap;
byte *spot;
int x, y;
{
#ifdef USEASM
DimScreenPLoop (fadetable, screen->buffer, screen->width, screen->pitch-screen->width, screen->height);
#else
unsigned int *spot, s;
int x, y;
byte a, b, c, d;
unsigned int *fg2rgb;
fixed_t amount;
spot = (unsigned int *)(screen->buffer);
for (y = 0; y < screen->height; y++) {
for (x = 0; x < (screen->width >> 2); x++) {
s = *spot;
a = fadetable[s & 0xff];
b = fadetable[(s >> 8) & 0xff];
c = fadetable[(s >> 16) & 0xff];
d = fadetable[s >> 24];
*spot++ = a | (b << 8) | (c << 16) | (d << 24);
}
spot += (screen->pitch - screen->width) >> 2;
amount = (fixed_t)(dimamount->value * 64);
fg2rgb = Col2RGB8[amount];
bg2rgb = Col2RGB8[64-amount];
fg = fg2rgb[V_GetColorFromString (DefaultPalette->basecolors, dimcolor->string)];
}
spot = screen->buffer;
gap = screen->pitch - screen->width;
for (y = 0; y < screen->height; y++) {
for (x = 0; x < screen->width; x++) {
unsigned int bg = bg2rgb[*spot];
bg = (fg+bg) | 0xf07c3e1f;
*spot++ = RGB8k[0][0][(bg>>5) & (bg>>19)];
}
#endif
spot += gap;
}
} else {
int x, y;
@ -412,57 +407,30 @@ void Cmd_SetColor (void *plyr, int argc, char **argv)
}
}
void BuildTransTable (byte *transtab, unsigned int *palette)
// This is DOSDoom 0.65's translucency table code, cleaned up.
// I also removed the use of Allegro's RGB table code, because
// it just wasn't accurate enough.
void BuildTransTable (unsigned int *palette)
{
int a, b, c, count;
byte *trans25, *trans50, *trans75, *mtrans, *trans;
trans25 = transtab;
trans50 = transtab + 65536;
trans75 = transtab + 131072;
count = 0;
{
int r, g, b;
C_InitTicker ("translucency", 98176);
// Build the 50% translucency table
trans = trans50;
for (a = 0; a < 256; a++) {
mtrans = trans50 + a;
for (b = 0; b < a; b++) {
c = BestColor (palette,
(RPART(palette[a]) + RPART(palette[b])) >> 1,
(GPART(palette[a]) + GPART(palette[b])) >> 1,
(BPART(palette[a]) + BPART(palette[b])) >> 1,
256);
*trans++ = c;
*mtrans = c;
mtrans += 256;
}
*trans = a;
trans += 256 - a;
if ((count & ~8191) != ((count + a) & ~8191))
C_SetTicker (count);
count += a;
// create the small RGB table
for (r = 0; r < 16; r++)
for (g = 0; g < 32; g++)
for (b = 0; b < 16; b++)
RGB8k[r][g][b] = BestColor (palette, r * 16, g * 8, b * 16, 256);
}
// Build the 25% and 75% tables
trans = trans75;
for (a = 0; a < 256; a++) {
for (b = 0; b < 256; b++) {
c = BestColor (palette,
(RPART(palette[a]) + RPART(palette[b]) * 3) >> 2,
(GPART(palette[a]) + GPART(palette[b]) * 3) >> 2,
(BPART(palette[a]) + BPART(palette[b]) * 3) >> 2,
256);
*trans++ = c;
trans25[(b << 8) | a] = c;
}
count += 256;
if (!(a & 31))
C_SetTicker (count);
}
{
int x, y;
C_InitTicker (NULL, 0);
for (x = 0; x < 65; x++)
for (y = 0; y < 256; y++)
Col2RGB8[x][y] = (((RPART(palette[y])*x)>>5)<<9) |
(((GPART(palette[y])*x)>>4)<<18) |
((BPART(palette[y])*x)>>5);
}
}
void V_LockScreen (screen_t *scrn)
@ -644,7 +612,6 @@ static int IdNameToId (char *name)
void V_Init (void)
{
static const char tag[] = "LZO-Compressed ZDoom Translucency Cache File v01";
int i;
int width, height, id;
@ -696,135 +663,7 @@ void V_Init (void)
V_Palette = DefaultPalette->colors;
if (!M_CheckParm ("-notrans")) {
char cachename[256];
byte *palette;
FILE *cache;
int i;
// Align TransTable on a 64k boundary
TransTable = Malloc (65536*3+65535);
TransTable = (byte *)(((unsigned int)TransTable + 0xffff) & 0xffff0000);
i = M_CheckParm("-transfile");
if (i && i < myargc - 1) {
strcpy (cachename, myargv[i+1]);
FixPathSeperator (cachename);
DefaultExtension (cachename, ".tch");
} else {
sprintf (cachename, "%stranstab.tch", progdir);
}
palette = W_CacheLumpName ("PLAYPAL", PU_CACHE);
{ // Check for cached translucency table
byte *cachemem;
byte *out;
int newlen;
int cachelen;
int insidelen;
int r;
cache = fopen (cachename, "rb");
if (cache) {
fseek (cache, 0, SEEK_END);
cachelen = ftell (cache);
fseek (cache, 0, SEEK_SET);
if (cachelen <= strlen(tag) + sizeof(int)) {
fclose (cache);
cache = NULL;
goto maketable;
}
cachemem = Z_Malloc (cachelen, PU_STATIC, 0);
if (fread (cachemem, 1, cachelen, cache) != cachelen) {
fclose (cache);
cache = NULL;
Printf (PRINT_HIGH, "Trouble reading tranlucency cache\n");
goto maketable;
}
fclose (cache);
if (strncmp (tag, cachemem, strlen(tag)) != 0) {
Printf (PRINT_HIGH, "Regenerating old translucency cache\n");
cache = NULL;
goto maketable;
}
// So far, so good. Try expanding the cached data.
memcpy (&insidelen, cachemem + strlen(tag), sizeof(int));
if (insidelen != cachelen - strlen(tag) - sizeof(int)) {
Printf (PRINT_HIGH, "Translucency cache wrong size\n");
cache = NULL;
goto maketable;
}
out = Z_Malloc (65536*3+768, PU_STATIC, 0);
r = lzo1x_decompress (cachemem + strlen(tag) + sizeof(int),
insidelen, out, &newlen, NULL);
if (r != LZO_E_OK || newlen != 65536*3+768) {
Printf (PRINT_HIGH, "Bad translucency cache\n");
cache = NULL;
Z_Free (out);
goto maketable;
}
// Check to make sure if the cache was generated from the
// current PLAYPAL. If not, we need to generate it, but
// don't bother replacing this one.
if (memcmp (out, palette, 768)) {
Printf (PRINT_HIGH, "Translucency cache was generated with a different palette\n");
Z_Free (out);
goto maketable;
}
// Everything's good. Use the cached data.
memcpy (TransTable, out+768, 65536*3);
TransTable -= 65536;
Z_Free (out);
return;
}
}
maketable:
Printf (PRINT_HIGH, "Creating translucency tables\n");
BuildTransTable (TransTable, DefaultPalette->basecolors);
if (!cache) {
byte *out, *wrkmem, *in;
int outlen, r;
wrkmem = Malloc (LZO1X_1_MEM_COMPRESS);
in = Malloc (768 + 65536*3);
out = Malloc (768 + 65536*3);
strncpy (in, tag, strlen (tag));
memcpy (in, palette, 768);
memcpy (in+768, TransTable, 65536*3);
r = lzo1x_1_compress (in, 768+65536*3, out, &outlen, wrkmem);
free (wrkmem);
free (in);
if (r == LZO_E_OK) {
cache = fopen (cachename, "wb");
if (cache) {
fwrite (tag, 1, strlen(tag), cache);
fwrite (&outlen, sizeof(outlen), 1, cache);
fwrite (out, 1, outlen, cache);
fclose (cache);
}
}
free (out);
}
TransTable -= 65536;
}
BuildTransTable (DefaultPalette->basecolors);
}
void V_AttachPalette (screen_t *scrn, palette_t *pal)

View file

@ -70,7 +70,9 @@ extern int dirtybox[4];
extern byte newgamma[256];
extern cvar_t *gammalevel;
extern byte* TransTable; // Translucency tables (minus 65536)
// DOSDoom 0.65's neat-o translucency tables
extern unsigned int Col2RGB8[65][256];
extern byte RGB8k[16][32][16];
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;

View file

@ -1,27 +1,16 @@
// 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:
// Handles WAD file header, directory, lump I/O.
// [RH] Changed to use buffered I/O (fread, etc)
//
//-----------------------------------------------------------------------------
//**************************************************************************
//**
//** w_wad.c : Heretic 2 : Raven Software, Corp.
//**
//** $RCSfile: w_wad.c,v $
//** $Revision: 1.6 $
//** $Date: 95/10/06 20:56:47 $
//** $Author: cjr $
//**
//**************************************************************************
// HEADER FILES ------------------------------------------------------------
#include <stdlib.h>
#include <io.h>
@ -31,6 +20,10 @@
#include <fcntl.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include "m_alloc.h"
#include "doomtype.h"
#include "doomstat.h"
@ -40,40 +33,74 @@
#include "i_system.h"
#include "z_zone.h"
#include "cmdlib.h"
#include "w_wad.h"
#ifndef _WIN32
#include <unistd.h>
// MACROS ------------------------------------------------------------------
#ifdef NeXT
// NeXT doesn't need a binary flag in open call
#define O_BINARY 0
#define strcmpi strcasecmp
#endif
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
lumpinfo_t *lumpinfo;
int numlumps;
void **lumpcache;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE --------------------------------------------------------------------
#ifdef NeXT
//==========================================================================
//
// GLOBALS
// strupr
//
//==========================================================================
// Location of each lump on disk.
lumpinfo_t* lumpinfo;
int numlumps;
void** lumpcache;
int W_filelength (FILE *handle)
void strupr (char *s)
{
int len;
if (fseek (handle, 0, SEEK_END))
I_Error ("Error fseeking");
len = ftell (handle);
if (fseek (handle, 0, SEEK_SET))
I_Error ("Error fseeking");
return len;
while (*s)
*s++ = toupper (*s);
}
//==========================================================================
//
// filelength
//
//==========================================================================
int filelength (int handle)
{
struct stat fileinfo;
if (fstat (handle, &fileinfo) == -1)
{
close (handle);
I_Error ("Error fstating");
}
return fileinfo.st_size;
}
#endif
//==========================================================================
//
// uppercoppy
//
// [RH] Copy up to 8 chars, upper-casing them in the process
//==========================================================================
void uppercopy (char *to, const char *from)
{
@ -85,22 +112,15 @@ void uppercopy (char *to, const char *from)
to[i] = 0;
}
//
// LUMP BASED ROUTINES.
//
//==========================================================================
//
// W_AddFile
// All files are optional, but at least one file must be
// found (PWAD, if all required lumps are present).
// Files with a .wad extension are wadlink files
// with multiple lumps.
// Other files are single lumps with the base filename
// for the lump name.
//
// Files with a .wad extension are wadlink files with multiple lumps,
// other files are single lumps with the base filename for the lump name.
//
// [RH] Removed reload hack
//==========================================================================
void W_AddFile (char *filename)
{
@ -108,7 +128,7 @@ void W_AddFile (char *filename)
wadinfo_t header;
lumpinfo_t* lump_p;
unsigned i;
FILE *handle;
int handle;
int length;
int startlump;
filelump_t* fileinfo, *fileinfo2free;
@ -121,9 +141,8 @@ void W_AddFile (char *filename)
DefaultExtension (name, ".wad");
// open the file and add to directory
if ((handle = fopen (name, "rb")) == NULL)
{
if ((handle = open (name, O_RDONLY|O_BINARY)) == -1)
{ // Didn't find file
Printf (PRINT_HIGH, " couldn't open %s\n",filename);
return;
}
@ -132,27 +151,27 @@ void W_AddFile (char *filename)
startlump = numlumps;
// [RH] Determine if file is a WAD based on its signature, not its name.
fread (&header, sizeof(header), 1, handle);
read (handle, &header, sizeof(header));
if (header.identification == IWAD_ID ||
header.identification == PWAD_ID) {
// This is a WAD file
if (header.identification == IWAD_ID || header.identification == PWAD_ID)
{ // This is a WAD file
header.numlumps = LONG(header.numlumps);
header.infotableofs = LONG(header.infotableofs);
length = header.numlumps * sizeof(filelump_t);
fileinfo = fileinfo2free = Z_Malloc (length, PU_STATIC, 0);
fseek (handle, header.infotableofs, SEEK_SET);
fread (fileinfo, 1, length, handle);
lseek (handle, header.infotableofs, SEEK_SET);
read (handle, fileinfo, length);
numlumps += header.numlumps;
Printf (PRINT_HIGH, " (%d lumps)", header.numlumps);
} else {
// This is just a single lump file
}
else
{ // This is just a single lump file
fileinfo2free = NULL;
fileinfo = &singleinfo;
singleinfo.filepos = 0;
singleinfo.size = LONG(W_filelength(handle));
singleinfo.size = LONG(filelength(handle));
ExtractFileBase (filename, name);
strupr (name);
strncpy (singleinfo.name, name, 8);
@ -162,15 +181,12 @@ void W_AddFile (char *filename)
// Fill in lumpinfo
lumpinfo = Realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
lump_p = &lumpinfo[startlump];
for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
for (i = startlump; i < numlumps; i++, lump_p++, fileinfo++)
{
lump_p->handle = handle;
lump_p->position = LONG(fileinfo->filepos);
lump_p->size = LONG(fileinfo->size);
// [RH] Convert name to uppercase during copy
uppercopy (lump_p->name, fileinfo->name);
}
@ -181,30 +197,27 @@ void W_AddFile (char *filename)
//==========================================================================
//
// W_InitMultipleFiles
// Pass a null terminated list of files to use.
// All files are optional, but at least one file
// must be found.
// Files with a .wad extension are idlink files
// with multiple lumps.
// Other files are single lumps with the base filename
// for the lump name.
// Lump names can appear multiple times.
// The name searcher looks backwards, so a later file
// does override all earlier ones.
//
// Pass a null terminated list of files to use. All files are optional,
// but at least one file must be found. Lump names can appear multiple
// times. The name searcher looks backwards, so a later file can
// override an earlier one.
//
//==========================================================================
void W_InitMultipleFiles (wadlist_t **filenames)
{
int i;
// open all the files, load headers, and count lumps
numlumps = 0;
lumpinfo = NULL; // will be realloced as lumps are added
// will be realloced as lumps are added
lumpinfo = NULL; // [RH] Start out as NULL
while (*filenames) {
while (*filenames)
{
wadlist_t *next = (*filenames)->next;
W_AddFile ((*filenames)->name);
@ -213,7 +226,9 @@ void W_InitMultipleFiles (wadlist_t **filenames)
}
if (!numlumps)
I_FatalError ("W_InitFiles: no files found");
{
I_FatalError ("W_InitMultipleFiles: no files found");
}
// [RH] Set namespace markers to global for everything
for (i = 0; i < numlumps; i++)
@ -222,11 +237,8 @@ void W_InitMultipleFiles (wadlist_t **filenames)
// [RH] Merge sprite and flat groups.
// (We don't need to bother with patches, since
// Doom doesn't use markers to identify them.)
W_Profile ("waddump1.txt");
W_MergeLumps ("S_START", "S_END", ns_sprites);
W_Profile ("waddump2.txt");
W_MergeLumps ("F_START", "F_END", ns_flats);
W_Profile ("waddump3.txt");
W_MergeLumps ("C_START", "C_END", ns_colormaps);
// [RH] Set up hash table
@ -238,13 +250,14 @@ void W_InitMultipleFiles (wadlist_t **filenames)
memset (lumpcache, 0, i);
}
//===========================================================================
//
// W_InitFile
// Just initialize from a single file.
//
// Initialize the primary from a single file.
//
//==========================================================================
void W_InitFile (char *filename)
{
wadlist_t *names = Z_Malloc (sizeof(*names)+strlen(filename), PU_STATIC, 0);
@ -254,25 +267,27 @@ void W_InitFile (char *filename)
W_InitMultipleFiles (&names);
}
//==========================================================================
//
// W_NumLumps
//
//==========================================================================
int W_NumLumps (void)
{
return numlumps;
}
//==========================================================================
//
// W_CheckNumForName
//
// Returns -1 if name not found.
//
// [RH] Changed to use hash lookup ala BOOM instead of a linear search
// and namespace parameter
//
// and namespace parameter
//==========================================================================
int (W_CheckNumForName) (const char *name, int space)
{
char uname[8];
@ -281,7 +296,8 @@ int (W_CheckNumForName) (const char *name, int space)
uppercopy (uname, name);
i = lumpinfo[W_LumpNameHash (uname) % (unsigned)numlumps].index;
while (i != -1) {
while (i != -1)
{
if (!strncmp (lumpinfo[i].name, uname, 8) && lumpinfo[i].namespc == space)
break;
i = lumpinfo[i].next;
@ -290,13 +306,14 @@ int (W_CheckNumForName) (const char *name, int space)
return i;
}
//==========================================================================
//
// W_GetNumForName
//
// Calls W_CheckNumForName, but bombs out if not found.
//
//==========================================================================
int W_GetNumForName (const char *name)
{
int i;
@ -310,10 +327,14 @@ int W_GetNumForName (const char *name)
}
//==========================================================================
//
// W_LumpLength
//
// Returns the buffer size needed to load the given lump.
//
//==========================================================================
int W_LumpLength (int lump)
{
if (lump >= numlumps)
@ -322,44 +343,50 @@ int W_LumpLength (int lump)
return lumpinfo[lump].size;
}
//==========================================================================
//
// W_ReadLump
// Loads the lump into the given buffer,
// which must be >= W_LumpLength().
//
// [RH] Removed reload hack
// Loads the lump into the given buffer, which must be >= W_LumpLength().
//
//==========================================================================
void W_ReadLump (int lump, void *dest)
{
int c;
lumpinfo_t* l;
int c;
lumpinfo_t *l;
if (lump >= numlumps)
{
I_Error ("W_ReadLump: %i >= numlumps",lump);
}
l = lumpinfo + lump;
fseek (l->handle, l->position, SEEK_SET);
c = fread (dest, 1, l->size, l->handle);
//I_BeginRead();
lseek (l->handle, l->position, SEEK_SET);
c = read (l->handle, dest, l->size);
if (c < l->size)
{
I_Error ("W_ReadLump: only read %i of %i on lump %i",
c,l->size,lump);
c, l->size, lump);
}
//I_EndRead();
}
//==========================================================================
//
// W_CacheLumpNum
//
//==========================================================================
void *W_CacheLumpNum (int lump, int tag)
{
byte *ptr;
int lumplen;
if ((unsigned)lump >= numlumps)
{
I_Error ("W_CacheLumpNum: %u >= numlumps",lump);
}
if (!lumpcache[lump])
{
// read the lump in
@ -378,13 +405,13 @@ void *W_CacheLumpNum (int lump, int tag)
//DPrintf ("cache hit on lump %i\n",lump);
Z_ChangeTag (lumpcache[lump],tag);
}
return lumpcache[lump];
}
// [RH] W_CacheLumpName macro-ized
//==========================================================================
//
// W_LumpNameHash
//
// [RH] This is from Boom.
// NOTE: s should already be uppercase.
// This is different from the BOOM version.
@ -393,6 +420,8 @@ void *W_CacheLumpNum (int lump, int tag)
// Must be mod'ed with table size.
// Can be used for any 8-character names.
// by Lee Killough
//
//==========================================================================
unsigned W_LumpNameHash (const char *s)
{
@ -410,10 +439,14 @@ unsigned W_LumpNameHash (const char *s)
return hash;
}
// [RH] W_InitHashChains
//==========================================================================
//
// W_InitHashChains
//
// Prepares the lumpinfos for hashing.
// (Hey! This looks suspiciously like something from Boom! :-)
//
//==========================================================================
void W_InitHashChains (void)
{
@ -426,7 +459,8 @@ void W_InitHashChains (void)
lumpinfo[i].index = -1;
// Now set up the chains
for (i = 0; i < numlumps; i++) {
for (i = 0; i < numlumps; i++)
{
uppercopy (name, lumpinfo[i].name);
j = W_LumpNameHash (name) % (unsigned) numlumps;
lumpinfo[i].next = lumpinfo[j].index;
@ -434,17 +468,29 @@ void W_InitHashChains (void)
}
}
// [RH] From Boom also
//==========================================================================
//
// IsMarker
//
// (from BOOM)
//
//==========================================================================
static BOOL IsMarker (const lumpinfo_t *lump, const char *marker)
{
return (lump->namespc == ns_global) && (!strncmp (lump->name, marker, 8) ||
(*(lump->name) == *marker && !strncmp (lump->name + 1, marker, 7)));
}
// [RH] Merge multiple tagged groups into one
//==========================================================================
//
// Basically from Boom, too, although I tried to write
// it independently.
// W_MergeLumps
//
// Merge multiple tagged groups into one
// Basically from BOOM, too, although I tried to write it independently.
//
//==========================================================================
void W_MergeLumps (const char *start, const char *end, int space)
{
char ustart[8], uend[8];
@ -459,7 +505,8 @@ void W_MergeLumps (const char *start, const char *end, int space)
// Some pwads use an icky hack to get flats with regular Doom.
// This tries to detect them.
flatHack = 0;
if (!strcmp ("F_START", ustart) && !M_CheckParm ("-noflathack")) {
if (!strcmp ("F_START", ustart) && !M_CheckParm ("-noflathack"))
{
int fudge = 0, start = 0;
for (i = 0; i < numlumps; i++) {
@ -480,48 +527,69 @@ void W_MergeLumps (const char *start, const char *end, int space)
oldlumps = 0;
insideBlock = false;
for (i = 0; i < numlumps; i++) {
if (!insideBlock) {
for (i = 0; i < numlumps; i++)
{
if (!insideBlock)
{
// Check if this is the start of a block
if (IsMarker (lumpinfo + i, ustart)) {
if (IsMarker (lumpinfo + i, ustart))
{
insideBlock = true;
// Create start marker if we haven't already
if (!newlumps) {
if (!newlumps)
{
newlumps++;
strncpy (newlumpinfos[0].name, ustart, 8);
newlumpinfos[0].handle = NULL;
newlumpinfos[0].handle = -1;
newlumpinfos[0].position =
newlumpinfos[0].size = 0;
newlumpinfos[0].namespc = ns_global;
}
} else {
}
else
{
// Copy lumpinfo down this list
lumpinfo[oldlumps++] = lumpinfo[i];
}
} else {
}
else
{
// Check if this is the end of a block
if (flatHack) {
if (flatHack == i) {
if (flatHack)
{
if (flatHack == i)
{
insideBlock = false;
flatHack = 0;
} else {
if (lumpinfo[i].size != 4096) {
}
else
{
if (lumpinfo[i].size != 4096)
{
lumpinfo[oldlumps++] = lumpinfo[i];
} else {
}
else
{
newlumpinfos[newlumps] = lumpinfo[i];
newlumpinfos[newlumps++].namespc = space;
}
}
} else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle) {
}
else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle)
{
// Blocks cannot span multiple files
insideBlock = false;
lumpinfo[oldlumps++] = lumpinfo[i];
} else if (IsMarker (lumpinfo + i, uend)) {
}
else if (IsMarker (lumpinfo + i, uend))
{
// It is. We'll add the end marker once
// we've processed everything.
insideBlock = false;
} else {
}
else
{
newlumpinfos[newlumps] = lumpinfo[i];
newlumpinfos[newlumps++].namespc = space;
}
@ -531,7 +599,8 @@ void W_MergeLumps (const char *start, const char *end, int space)
// Now copy the merged lumps to the end of the old list
// and create the end marker entry.
if (newlumps) {
if (newlumps)
{
if (oldlumps + newlumps > numlumps)
lumpinfo = Realloc (lumpinfo, oldlumps + newlumps);
@ -540,7 +609,7 @@ void W_MergeLumps (const char *start, const char *end, int space)
numlumps = oldlumps + newlumps;
strncpy (lumpinfo[numlumps].name, uend, 8);
lumpinfo[numlumps].handle = NULL;
lumpinfo[numlumps].handle = -1;
lumpinfo[numlumps].position =
lumpinfo[numlumps].size = 0;
lumpinfo[numlumps].namespc = ns_global;
@ -550,9 +619,12 @@ void W_MergeLumps (const char *start, const char *end, int space)
free (newlumpinfos);
}
//==========================================================================
//
// W_Profile
//
//==========================================================================
// [RH] Unused
void W_Profile (const char *fname)
{
@ -599,49 +671,47 @@ void W_Profile (const char *fname)
}
// [RH] Find a named lump. Specifically allows duplicates for
// merging of e.g. SNDINFO lumps. Sorry, this uses a linear
// search. (Not a big deal, since it only gets called
// a few times during game setup.)
//==========================================================================
//
// W_FindLump
//
// Find a named lump. Specifically allows duplicates for merging of e.g.
// SNDINFO lumps.
//
//==========================================================================
int W_FindLump (const char *name, int *lastlump)
{
int lump;
union {
char s[8];
int x[2];
} name8;
int v1;
int v2;
lumpinfo_t* lump_p;
char name8[8];
int v1, v2;
lumpinfo_t *lump_p;
// make the name into two integers for easy compares
uppercopy (name8.s, name);
v1 = name8.x[0];
v2 = name8.x[1];
uppercopy (name8, name);
v1 = *(int *)name8;
v2 = *(int *)&name8[4];
lump_p = lumpinfo + *lastlump;
while (lump_p < lumpinfo + numlumps) {
if ( *(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
break;
while (lump_p < lumpinfo + numlumps)
{
if (*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
{
int lump = lump_p - lumpinfo;
*lastlump = lump + 1;
return lump;
}
lump_p++;
}
lump = lump_p - lumpinfo;
if (lump < numlumps) {
*lastlump = lump + 1;
return lump;
} else {
*lastlump = numlumps;
return -1;
}
*lastlump = numlumps;
return -1;
}
// [RH] Used by P_SetupLevel() to check for the presence of
// a BEHAVIOR lump and adjust its behavior accordingly.
//==========================================================================
//
// W_CheckLumpName
//
//==========================================================================
BOOL W_CheckLumpName (int lump, const char *name)
{
@ -651,7 +721,12 @@ BOOL W_CheckLumpName (int lump, const char *name)
return !strnicmp (lumpinfo[lump].name, name, 8);
}
// [RH] Copies the lump name to to using uppercopy
//==========================================================================
//
// W_GetLumpName
//
//==========================================================================
void W_GetLumpName (char *to, int lump)
{
if (lump >= numlumps)
@ -660,16 +735,26 @@ void W_GetLumpName (char *to, int lump)
uppercopy (to, lumpinfo[lump].name);
}
// [RH] Returns file ptr for specified lump
FILE *W_GetLumpFile (int lump)
//==========================================================================
//
// W_GetLumpHandle
//
//==========================================================================
int W_GetLumpHandle (int lump)
{
if (lump >= numlumps)
return NULL;
return -1;
else
return lumpinfo[lump].handle;
}
// [RH] Put a lump in a certain namespace
//==========================================================================
//
// W_SetLumpNamespace
//
//==========================================================================
void W_SetLumpNamespace (int lump, int nmspace)
{
if (lump < numlumps)

View file

@ -25,9 +25,10 @@
#include "st_stuff.h"
#include "s_sound.h"
#include "s_sndseq.h"
#include "doomstat.h"
#include "gi.h"
static void C_TabComplete (void);
static BOOL TabbedLast; // Last key pressed was tab
@ -151,21 +152,33 @@ void C_InitConsole (int width, int height, BOOL ingame)
if ( (vidactive = ingame) ) {
if (!gotconback) {
BOOL stylize = false;
patch_t *patch;
BOOL isRaw = false;
patch_t *bg;
int num;
num = W_CheckNumForName ("CONBACK");
if (num == -1) {
stylize = true;
num = W_GetNumForName ("TITLEPIC");
num = W_GetNumForName (gameinfo.titlePage);
isRaw = gameinfo.flags & GI_PAGESARERAW;
}
patch = W_CacheLumpNum (num, PU_CACHE);
bg = W_CacheLumpNum (num, PU_CACHE);
if (isRaw)
V_AllocScreen (&conback, 320, 200, 8);
else
V_AllocScreen (&conback, SHORT(bg->width), SHORT(bg->height), 8);
if (!conback.impdata)
I_FatalError ("No memory for console backdrop");
V_AllocScreen (&conback, SHORT(patch->width), SHORT(patch->height), 8);
V_LockScreen (&conback);
V_DrawPatch (0, 0, &conback, patch);
if (isRaw)
V_DrawBlock (0, 0, &conback, 320, 200, (byte *)bg);
else
V_DrawPatch (0, 0, &conback, bg);
if (stylize) {
byte *fadetable = W_CacheLumpName ("COLORMAP", PU_CACHE), f, *v, *i;
@ -1117,14 +1130,19 @@ void C_MidPrint (char *msg)
if (MidMsg)
V_FreeBrokenLines (MidMsg);
if ( (MidMsg = V_BreakLines (con_scaletext->value ? screen.width / CleanXfac : screen.width, msg)) ) {
MidTicker = (int)(con_midtime->value * TICRATE) + gametic;
if (msg)
{
if ( (MidMsg = V_BreakLines (con_scaletext->value ? screen.width / CleanXfac : screen.width, msg)) ) {
MidTicker = (int)(con_midtime->value * TICRATE) + gametic;
for (i = 0; MidMsg[i].width != -1; i++)
;
for (i = 0; MidMsg[i].width != -1; i++)
;
MidLines = i;
MidLines = i;
}
}
else
MidMsg = NULL;
}
void C_DrawMid (void)

View file

@ -12,6 +12,7 @@ typedef struct {
} cvarinit_t;
extern cvar_t *gammalevel,
*wipetype,
*st_scale,
*gameskill,
*crosshair,
@ -94,6 +95,7 @@ extern cvar_t *gammalevel,
*teamplay,
*deathmatch,
*fakedmatch,
*dmflagsvar,
*fraglimit,
*timelimit,
@ -119,9 +121,10 @@ extern cvar_t *gammalevel,
static const cvarinit_t Initializers[] = {
{ &gammalevel, "gamma", "1", CVAR_ARCHIVE|CVAR_CALLBACK },
{ &wipetype, "wipetype", "1", CVAR_ARCHIVE },
{ &testgibs, "testgibs", "0", 0 },
{ &st_scale, "st_scale", "0", CVAR_ARCHIVE|CVAR_CALLBACK },
{ &dimamount, "dimamount", "1", CVAR_ARCHIVE },
{ &dimamount, "dimamount", "0.2", CVAR_ARCHIVE },
{ &dimcolor, "dimcolor", "ff d7 00", CVAR_ARCHIVE },
{ &crosshair, "crosshair", "0", CVAR_ARCHIVE },
{ &developer, "developer", "0", 0 },
@ -210,6 +213,7 @@ static const cvarinit_t Initializers[] = {
{ &teamplay, "teamplay", "0", CVAR_SERVERINFO },
{ &deathmatch, "deathmatch", "0", CVAR_SERVERINFO|CVAR_LATCH },
{ &fakedmatch, "alwaysapplydmflags", "0", CVAR_SERVERINFO },
{ &dmflagsvar, "dmflags", "0", CVAR_SERVERINFO|CVAR_CALLBACK },
{ &timelimit, "timelimit", "0", CVAR_SERVERINFO },
{ &fraglimit, "fraglimit", "0", CVAR_SERVERINFO },

View file

@ -381,7 +381,7 @@ gitem_t itemlist[] = {
IT_POWERUP,
pw_invisibility,
0,
"Partial Invisibility"
"Invisibility"
},
{
@ -391,7 +391,7 @@ gitem_t itemlist[] = {
IT_POWERUP,
pw_ironfeet,
0,
"Iron Feet"
"Radiation Suit"
},
{

View file

@ -28,11 +28,6 @@
#include <setjmp.h>
#include "d_event.h"
void D_AddFile (char *file);
//
// D_DoomMain()
// Not a globally visible function, just included for source reference,

View file

@ -153,7 +153,8 @@ badwave:
sfx->link = S_sfx + i;
sfx->ms = S_sfx[i].ms;
sfx->data = S_sfx[i].data;
sfx->loopdata = S_sfx[i].loopdata;
sfx->normal = S_sfx[i].normal;
sfx->looping = S_sfx[i].looping;
return;
}
@ -290,7 +291,7 @@ badwave:
smp.loop1Start = smp.loop1End = 0;
smp.loop1Type = loopNone;
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->data)) != OK)
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->normal)) != OK)
I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error));
/* With loop: */
@ -299,7 +300,7 @@ badwave:
smp.loop1End = smp.sampleLength;
smp.loop1Type = loopUnidir;
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->loopdata)) != OK)
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->looping)) != OK)
I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error));
}
@ -308,6 +309,7 @@ badwave:
if (sfx->frequency == 0)
sfx->frequency = 11025;
sfx->ms = (sfx->ms * 1000) / (sfx->frequency);
sfx->data = sfxcopy;
}
@ -383,8 +385,8 @@ int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel, BOOL
}
ChannelMap[channel].playHandle = MIDASplaySample (
looping ? (MIDASsample)sfx->loopdata
: (MIDASsample)sfx->data,
looping ? (MIDASsample)sfx->looping
: (MIDASsample)sfx->normal,
ChannelMap[channel].midasChannel,
0,
PITCH(sfx->frequency,pitch),
@ -593,7 +595,6 @@ void STACK_ARGS I_ShutdownSound (void)
size_t len = 0;
if (MidasInited) {
Printf (PRINT_HIGH, "I_ShutdownSound: Stopping sounds\n");
if (ChannelMap) {
for (i = 0; i < numChannels; i++ ) {
if (ChannelMap[i].playHandle) {
@ -607,23 +608,23 @@ void STACK_ARGS I_ShutdownSound (void)
I_ShutdownMusic();
Printf (PRINT_HIGH, "I_ShutdownSound: Uninitializing MIDAS\n");
// [RH] Free all loaded samples
for (i = 0; i < numsfx; i++) {
if (!S_sfx[i].link) {
if (S_sfx[i].data) {
MIDASfreeSample ((MIDASsample)S_sfx[i].data);
if (S_sfx[i].normal) {
MIDASfreeSample ((MIDASsample)S_sfx[i].normal);
len += S_sfx[i].length;
c++;
}
if (S_sfx[i].loopdata) {
MIDASfreeSample ((MIDASsample)S_sfx[i].loopdata);
if (S_sfx[i].looping) {
MIDASfreeSample ((MIDASsample)S_sfx[i].looping);
}
if (S_sfx[i].data) {
free (S_sfx[i].data);
}
}
S_sfx[i].data = S_sfx[i].link = NULL;
}
Printf (PRINT_HIGH, "%d sounds expunged (%d bytes)\n", c, len);
if ( !MIDASstopBackgroundPlay() )
MIDASerror();

View file

@ -54,7 +54,7 @@ typedef unsigned long DWORD;
#include "../../midas/src/midas/midasdll.h"
#ifdef USEASM
BOOL MIDAS_CALL CheckMMX (char *vendorid);
BOOL STACK_ARGS CheckMMX (char *vendorid);
#endif
BOOL UseMMX;
@ -63,6 +63,7 @@ BOOL fastdemo;
float mb_used = 6.0;
int (*I_GetTime) (void);
int (*I_WaitForTic) (int);
void I_Tactile (int on, int off, int total)
@ -144,18 +145,30 @@ static void MIDAS_CALL TimerCallback (void)
}
static void TimerEnd (void) { }
int I_GetTimeReally (void)
int I_GetTimePolled (void)
{
return counter;
}
int I_WaitForTicPolled (int prevtic)
{
while (counter <= prevtic)
;
return counter;
}
// [RH] Increments the time count every time it gets called.
// Used only by -fastdemo (just like BOOM).
static int faketic = 0;
int I_GetTimeFake (void)
{
static int tic = 0;
return faketic++;
}
return tic++;
int I_WaitForTicFake (int whocares)
{
return faketic++;
}
@ -202,9 +215,15 @@ void I_Init(void)
// [RH] Support for BOOM's -fastdemo
if (fastdemo)
{
I_GetTime = I_GetTimeFake;
I_WaitForTic = I_WaitForTicFake;
}
else
I_GetTime = I_GetTimeReally;
{
I_GetTime = I_GetTimePolled;
I_WaitForTic = I_WaitForTicPolled;
}
I_InitSound();
@ -284,9 +303,6 @@ void I_Error (const char *error, ...)
I_FatalError ("humph");
}
// killough 2/22/98: Add support for ENDBOOM, which is PC-specific
// [RH] Use ENDOOM if ENDBOOM not found.
void I_EndDoom(void)
{
int lump = W_CheckNumForName ("ENDOOM");

View file

@ -40,8 +40,9 @@ byte *I_ZoneBase (int *size);
// Called by D_DoomLoop,
// returns current time in tics.
int (*I_GetTime) (void);
int (*I_WaitForTic) (int);
int I_GetTimeReally (void);
int I_GetTimePolled (void);
int I_GetTimeFake (void);
//

View file

@ -1,4 +1,164 @@
March 15, 1999
- Added support for custom ambient sound attenuations. This is an optional
floating point value that follows the point keyword.
- For 1.17, I had changed the sound volumes in s_sound.c to floats
*except* for the ambient sounds which were still being treated as byte
values between 0-255, so they would always play at full volume. Fixed.
March 14, 1999
- Discovered a savegame bug: An mobj's translation table was being saved
improperly and could point to invalid memory on reload. Fixed.
- Added another dmflag, DF_RESPAWN_SUPER, to cause invulnerability and
invisibility to respawn. No room in menu, so you have to set it by hand.
- Added an alwaysapplydmflags cvar that can be used to cause dmflags that
normally only affect deathmatch to apply to single player and coop games
as well.
- Changed P_Thing_Spawn() so that it can spawns things anywhere and not
just at map spots. (Useful for making it look like a monster was carrying
an item.)
- Added support for MBF's sky texture transfer linedefs. Also added support
for Hexen's Sky2 sector special.
- In r_plane.c, spanstop was never used anywhere. Removed it.
March 10, 1999
- Made the network code "better." htons is used in the appropriate places,
and the port a packet is sent from is used to determine which node sent
a packet (so now I can test more than two-player games on my machine).
- Added an event-driven timer routine. Instead of busy waiting for a new tic,
I can wait on an event and give other processes some CPU time. This makes
two-player games on one machine run much more smoothly on Windows 95/98.
(It was already smooth for the foreground player on NT.)
March 8, 1999
- Fixed a problem with R_DrawPSprite. It was leaving vis->translucency unset,
which could produce odd results depending on the contents of the stack.
March 7, 1999
- Discovered a big problem with my linked list of ceiling_t's implementation.
Fixed.
March 6, 1999
- Added two new screen wipes: burn and crossfade.
- The mid-screen message gets cleared out on level load now.
- Stopped using the zone heap to store level snapshots.
- Enhanced the stealth monsters so that they will take advantage of all
translucency levels available.
- Fixed the damage for A_MonsterRail. I guess DOOM doesn't copy the damage
amount out of the mobjinfo when an mobj is spawned.
- Added a check to the fullscreen HUD to prevent it from going outside the
array of armor pictures if the AC was above 2.
- The DeHackEd code was setting the Blue AC for max soulsphere health. Fixed.
- Tried out Rick Clark's toxplant.wad and discovered a bug with the
particles: They were colored by whichever sector was drawn last and not
the sector they were in. Fixed.
- Pulled the old info.h from the 1.17a source so I could get things in a
working state to put up a fixed DeHackEd version for the Ground Zero TC.
March 4, 1999
- Word of advice: When you have 2847 states and 399 mobjinfos (from Hexen)
to reformat, don't try to do it all by hand. I was smart enough to use a
program to convert all the states into the multigen format, but I thought
I could handle the mobjs myself. Ha ha ha ha ha ha! After a few hours,
my arm was aching, and I had only done about one fourth of the mobjinfos.
Then I wrote a program to convert the ones from Hexen's info.c into
multigen format, and all I had to do was drag them to the correct place
with my mouse. Much easier, and much less strenuous. (Also much less
error-prone.)
For comparison, Heretic has 161 mobjinfos and 1205 states.
Doom 2 has a mere 137 mobjinfos and 967 states.
March 3, 1999
- Had a change of plans about how I want to implement multiple games in a
single executable. All the data in info.c and info.h will be moved to an
external data file whose format is based on that used by multigen (the
tool id used to generate info.c). The list of spawnable things will also
be moved out of p_things.c and into this file.
This means that everything I did in info.h on March 1 was wasted. Oh well.
March 1, 1999
- Pasted labels for the Heretic and Hexen things into info.c. Had to
shuffle a few of them around:
--- Things renamed ---
MT_MISC* -> MT_DMISC* (if Doom)
MT_HMISC* (if Heretic)
MT_XMISC* (if Hexen)
MT_BARREL -> MT_HBARREL (for Heretic)
MT_DBARREL (for Doom)
MT_TFOG -> MT_DTFOG, MT_HTFOG, MT_XTFOG
created a new MT_TFOG elsewhere. the others should be
copied on top of it as appropriate.
MT_HEAD -> renamed Doom's to MT_CACODEMON
MT_KNIGHT -> renamed Doom's to MT_HELLKNIGHT
MT_FIREBOMB -> MT_HFIREBOMB, MT_XFIREBOMB
--- Things moved into common Heretic/Hexen section ---
MT_ARTIFLY
MT_ARTIINVULNERABILITY -> ditto
MT_ARTIEGG -> ditto
MT_EGGFX -> ditto
MT_ARTISUPERHEAL -> ditto
MT_ARTITELEPORT -> ditto
MT_SPLASH
MT_SPLASHBASE
MT_LAVASPLASH
MT_LAVASMAKE
MT_SLUDGECHUNK
MT_SLUDGESPLASH
MT_BLOODSPLATTER
MT_BLOODYSKULL
MT_MNTRFX1
MT_MNTRFX2 (deathsound is sfx_phohit in Heretic, no sound in Hexen)
MT_MNTRFX3
MT_SOUNDWATERFALL
--- Things moved to global section ---
MT_BLOOD (note that Hexen's blood has mass 5, not 100. was #38)
MT_TELEPORTMAN (was #41)
MT_PLAYER (was #0) Hexen's is name differently, so it didn't move.
(Hexen things renamed)
MT_MINOTAUR -> MT_MAULATOR
MT_SOUNDWIND -> MT_XSOUNDWIND
- Added a pulsating effect for the invisibility powerup that slowly
"pulses" it in and out of visibility, but never going below 25%, so it's
never totally invisible.
- Spent a few hours with the DOSDoom translucency code. I think the
greenness of it is probably more the fault of DOOM's limited palette,
particularly after comparing the 25% translucency table from before
with 25% translucency now. Very low levels of translucency with one
of the colors being dark are still too green, though.
February 28, 1999
- Added DOSDoom 0.65's translucency code. I'm not sure if it was really
worth it, though. I tried Allegro's RGB table code to speed up the
generation of the translucency table, but it didn't seem to produce
very satisfactory results, so I use BestColor to find palette colors
to use. The results are satisfactory, but they seem a bit too green.
- Delayed gathering of data on a sprite's patches (width, topoffset, and
offset) until it is needed (either when the level is precached, or when
the sprite is first seen). Game startup is a great deal quicker without
any noticable performance hit elsewhere. Cool.
February 27, 1999
- Note: Hexen's friction is roughly equivalent to a Sector_SetFriction of
171 (ends up as 0xf909, Hexen uses 0xf900). Player movement thrust should
be halved at this level. Changed the calculation of sector->movefactor
accordingly. (With the BOOM code, player thrust was nearly one fourth
normal with that level of friction.)
- Discovered that MBF's code to affect monsters with friction doesn't
work without the change it made to how mobjs are linked into the blockmap.
February 24, 1999
- Stopped using stdio in w_wad.c.
- Had left some calls to W_Profile in W_InitMultipleFiles(). Removed.
February 21, 1999
- Added support for real looping sounds, because Herian 2 used so many of
them, and the old method sounded pretty bad with them.
- Found a problem with sliding polyobj doors: If, when they try to close,
they can't move anywhere from their open position, they would move
slightly further open and leave a gap when they managed to close. Fixed.

3136
code/doominfo.lmp Normal file

File diff suppressed because it is too large Load diff

View file

@ -27,41 +27,9 @@
// SCREEN WIPE PACKAGE
//
enum
{
// simple gradual pixel change for 8-bit only
wipe_ColorXForm,
// weird screen melt
wipe_Melt,
wipe_NUMWIPES
};
int
wipe_StartScreen
( int x,
int y,
int width,
int height );
int
wipe_EndScreen
( int x,
int y,
int width,
int height );
int
wipe_ScreenWipe
( int wipeno,
int x,
int y,
int width,
int height,
int ticks );
int wipe_StartScreen (void);
int wipe_EndScreen (void);
int wipe_ScreenWipe (int ticks);
#endif
//-----------------------------------------------------------------------------

206
code/gi.c Normal file
View file

@ -0,0 +1,206 @@
#include <stdlib.h>
#include "info.h"
#include "gi.h"
gameinfo_t gameinfo;
static char *quitsounds[8] =
{
"player/male/death1",
"demon/pain",
"grunt/pain",
"misc/gibbed",
"misc/teleport",
"grunt/sight1",
"grunt/sight3",
"demon/melee"
};
static char *quitsounds2[8] =
{
"vile/active",
"misc/p_pkup",
"brain/cube",
"misc/gibbed",
"skeleton/swing",
"knight/death",
"baby/active",
"demon/melee"
};
static gameborder_t DoomBorder =
{
8, 8,
"brdr_tl", "brdr_t", "brdr_tr",
"brdr_l", "brdr_r",
"brdr_bl", "brdr_b", "brdr_br"
};
static gameborder_t HereticBorder =
{
4, 16,
"bordtl", "bordt", "bordtr",
"bordl", "bordr",
"bordbl", "bordb", "bordbr"
};
gameinfo_t HexenGameInfo =
{
GI_PAGESARERAW | GI_MAPxx | GI_NOLOOPFINALEMUSIC | GI_INFOINDEXED,
"TITLE",
"CREDIT",
"CREDIT",
"HEXEN",
280/35,
210/35,
200/35,
"Chat",
"hall",
"-NOFLAT-",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "TITLE", 4 } },
NULL,
33,
"F_022",
&HereticBorder
};
gameinfo_t HereticGameInfo =
{
GI_PAGESARERAW | GI_INFOINDEXED,
"TITLE",
"CREDIT",
"CREDIT",
"MUS_TITL",
280/35,
210/35,
200/35,
"misc/chat",
"MUS_CPTD",
"FLOOR25",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "TITLE", 4 } },
NULL,
17,
"FLAT513",
&HereticBorder
};
gameinfo_t HereticSWGameInfo =
{
GI_PAGESARERAW | GI_SHAREWARE | GI_INFOINDEXED,
"TITLE",
"CREDIT",
"ORDER",
"MUS_TITL",
280/35,
210/35,
200/35,
"misc/chat",
"MUS_CPTD",
"FLOOR25",
"ORDER",
"CREDIT",
"CREDIT",
{ { "TITLE", 5 } },
NULL,
17,
"FLOOR04",
&HereticBorder
};
gameinfo_t SharewareGameInfo =
{
GI_SHAREWARE | GI_NOCRAZYDEATH,
"TITLEPIC",
"CREDIT",
"HELP2",
"D_INTRO",
5,
0,
200/35,
"misc/chat2",
"D_VICTOR",
"FLOOR4_8",
"HELP2",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "HELP2" } },
quitsounds,
1,
"FLOOR7_2",
&DoomBorder
};
gameinfo_t RegisteredGameInfo =
{
GI_NOCRAZYDEATH,
"TITLEPIC",
"CREDIT",
"HELP2",
"D_INTRO",
5,
0,
200/35,
"misc/chat2",
"D_VICTOR",
"FLOOR4_8",
"HELP2",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "HELP2" } },
quitsounds,
2,
"FLOOR7_2",
&DoomBorder
};
gameinfo_t RetailGameInfo =
{
GI_MENUHACK_RETAIL | GI_NOCRAZYDEATH,
"TITLEPIC",
"CREDIT",
"CREDIT",
"D_INTRO",
5,
0,
200/35,
"misc/chat2",
"D_VICTOR",
"FLOOR4_8",
"CREDIT",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "CREDIT" } },
quitsounds,
2,
"FLOOR7_2",
&DoomBorder
};
gameinfo_t CommercialGameInfo =
{
GI_MAPxx | GI_MENUHACK_COMMERCIAL,
"TITLEPIC",
"CREDIT",
"CREDIT",
"D_DM2TTL",
11,
0,
200/35,
"misc/chat",
"D_READ_M",
"SLIME16",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "HELP", "CREDIT" } },
quitsounds2,
3,
"GRNROCK",
&DoomBorder
};

64
code/gi.h Normal file
View file

@ -0,0 +1,64 @@
#ifndef __GI_H__
#define __GI_H__
#include "doomtype.h"
#define GI_MAPxx 0x00000001
#define GI_PAGESARERAW 0x00000002
#define GI_SHAREWARE 0x00000004
#define GI_NOLOOPFINALEMUSIC 0x00000008
#define GI_INFOINDEXED 0x00000010
#define GI_MENUHACK 0x00000060
#define GI_MENUHACK_RETAIL 0x00000020
#define GI_MENUHACK_EXTENDED 0x00000040 // (Heretic)
#define GI_MENUHACK_COMMERCIAL 0x00000060
#define GI_NOCRAZYDEATH 0x00000080
typedef struct
{
byte offset;
byte size;
char tl[8];
char t[8];
char tr[8];
char l[8];
char r[8];
char bl[8];
char b[8];
char br[8];
} gameborder_t;
typedef struct
{
int flags;
char titlePage[8];
char creditPage1[8];
char creditPage2[8];
char titleMusic[8];
float titleTime;
float advisoryTime;
float pageTime;
char chatSound[16];
char finaleMusic[8];
char finaleFlat[8];
char finalePage1[8];
char finalePage2[8];
char finalePage3[8];
union
{
char infoPage[2][8];
struct
{
char basePage[8];
int numPages;
} indexed;
} info;
char **quitSounds;
int maxSwitch;
char borderFlat[8];
gameborder_t *border;
} gameinfo_t;
extern gameinfo_t gameinfo;
#endif //__GI_H__

6963
code/hexninfo.lmp Normal file

File diff suppressed because it is too large Load diff

View file

@ -200,7 +200,9 @@ extern cvar_t *am_rotate,
*r_drawfuzz,
*cl_rockettrails,
*cl_pufftype,
*cl_bloodtype;
*cl_bloodtype,
*wipetype,
*vid_palettehack;
static value_t Crosshairs[] = {
{ 0.0, "None" },
@ -237,6 +239,13 @@ static value_t PuffTypes[] = {
{ 1.0, "Particles" }
};
static value_t Wipes[] = {
{ 0.0, "None" },
{ 1.0, "Melt" },
{ 2.0, "Burn" },
{ 3.0, "Crossfade" }
};
static menuitem_t VideoItems[] = {
{ more, "Messages", NULL, 0.0, 0.0, 0.0, (value_t *)StartMessagesMenu },
{ redtext, " ", NULL, 0.0, 0.0, 0.0, NULL },
@ -246,7 +255,11 @@ static menuitem_t VideoItems[] = {
{ discrete, "Column render mode", (cvar_t **)&r_columnmethod,2.0,0.0, 0.0, ColumnMethods },
{ discrete, "Detail mode", (cvar_t **)&r_detail, 4.0, 0.0, 0.0, DetailModes },
{ discrete, "Stretch short skies", (cvar_t **)&r_stretchsky, 2.0,0.0, 0.0, OnOff },
{ discrete, "Scale status bar", (cvar_t **)&st_scale, 2.0, 0.0, 0.0, OnOff },
{ discrete, "Stretch status bar", (cvar_t **)&st_scale, 2.0, 0.0, 0.0, OnOff },
{ discrete, "Screen wipe style", (cvar_t **)&wipetype, 4.0, 0.0, 0.0, Wipes },
#ifdef _WIN32
{ discrete, "DirectDraw palette hack", (cvar_t **)&vid_palettehack, 2.0,0.0,0.0,OnOff },
#endif
{ redtext, " ", NULL, 0.0, 0.0, 0.0, NULL },
{ discrete, "Use fuzz effect", (cvar_t **)&r_drawfuzz, 2.0, 0.0, 0.0, YesNo },
{ discrete, "Rocket Trails", (cvar_t **)&cl_rockettrails, 2.0, 0.0, 0.0, OnOff },
@ -261,7 +274,11 @@ static menuitem_t VideoItems[] = {
menu_t VideoMenu = {
"M_VIDEO",
0,
17,
#ifdef _WIN32
20,
#else
19,
#endif
0,
VideoItems,
};

View file

@ -465,7 +465,7 @@ void P_DisconnectEffect (mobj_t *actor)
int i;
for (i = 64; i; i--) {
particle_t *p = JitterParticle (40);
particle_t *p = JitterParticle (TICRATE*2);
if (!p)
break;

View file

@ -2,6 +2,7 @@
#define FX_ROCKET 0x00000001
#define FX_GRENADE 0x00000002
#define FX_VISIBILITYPULSE 0x00000040
#define FX_FOUNTAINMASK 0x00070000
#define FX_FOUNTAINSHIFT 16

View file

@ -184,9 +184,6 @@ BOOL P_Thing_Spawn (int tid, int type, angle_t angle, BOOL fog)
return false;
while ( (spot = P_FindMobjByTid (spot, tid)) ) {
if (spot->type != MT_MAPSPOT && spot->type != MT_MAPSPOTGRAV)
continue;
if (mobjinfo[kind].flags2 & MF2_FLOATBOB) {
z = spot->z - spot->floorz;
} else {
@ -201,7 +198,7 @@ BOOL P_Thing_Spawn (int tid, int type, angle_t angle, BOOL fog)
if (fog)
S_Sound (P_SpawnMobj (spot->x, spot->y, spot->z, MT_TFOG),
CHAN_VOICE, "misc/teleport", 1, ATTN_NORM);
mobj->flags2 |= MF2_DROPPED; // Don't respawn
mobj->flags |= MF_DROPPED; // Don't respawn
if (mobj->flags2 & MF2_FLOATBOB) {
mobj->special1 = mobj->z - mobj->floorz;
}
@ -233,7 +230,7 @@ BOOL P_Thing_Projectile (int tid, int type, angle_t angle,
return false;
while ( (spot = P_FindMobjByTid (spot, tid)) ) {
if (spot->type != MT_MAPSPOT && spot->type != MT_MAPSPOTGRAV)
if (spot->type != MT_MAPSPOT && spot->type != MT_MAPSPOTGRAVITY)
continue;
mobj = P_SpawnMobj (spot->x, spot->y, spot->z, kind);

View file

@ -13,6 +13,7 @@
#include "r_draw.h"
#include "r_main.h"
#include "r_things.h"
#include "v_video.h"
byte dc_temp[1200*4];
unsigned int dc_tspans[4][256];
@ -339,23 +340,37 @@ void rt_lucent1col (int hx, int sx, int yl, int yh)
byte *colormap;
byte *source;
byte *dest;
byte *transmap;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
count = yh-yl;
if (count < 0)
return;
count++;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
dest = ylookup[yl] + columnofs[sx];
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
transmap = dc_transmap;
colormap = dc_colormap;
do {
*dest = transmap[colormap[*source] | ((*dest) << 8)];
unsigned int fg = colormap[*source];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);
@ -367,24 +382,44 @@ void rt_lucent2cols (int hx, int sx, int yl, int yh)
byte *colormap;
byte *source;
byte *dest;
byte *transmap;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
count = yh-yl;
if (count < 0)
return;
count++;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
dest = ylookup[yl] + columnofs[sx];
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
transmap = dc_transmap;
colormap = dc_colormap;
do {
dest[0] = transmap[colormap[source[0]] | (dest[0] << 8)];
dest[1] = transmap[colormap[source[1]] | (dest[1] << 8)];
unsigned int fg = colormap[source[0]];
unsigned int bg = dest[0];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[0] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[source[1]];
bg = dest[1];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[1] = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);
@ -396,26 +431,59 @@ void rt_lucent4cols (int sx, int yl, int yh)
byte *colormap;
byte *source;
byte *dest;
byte *transmap;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
count = yh-yl;
if (count < 0)
return;
count++;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
dest = ylookup[yl] + columnofs[sx];
source = &dc_temp[yl*4];
pitch = dc_pitch;
transmap = dc_transmap;
colormap = dc_colormap;
do {
dest[0] = transmap[colormap[source[0]] | (dest[0] << 8)];
dest[1] = transmap[colormap[source[1]] | (dest[1] << 8)];
dest[2] = transmap[colormap[source[2]] | (dest[2] << 8)];
dest[3] = transmap[colormap[source[3]] | (dest[3] << 8)];
unsigned int fg = colormap[source[0]];
unsigned int bg = dest[0];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[0] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[source[1]];
bg = dest[1];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[1] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[source[2]];
bg = dest[2];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[2] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[source[3]];
bg = dest[3];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[3] = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);
@ -424,20 +492,28 @@ void rt_lucent4cols (int sx, int yl, int yh)
// Translates and mixes one span at hx to the screen at sx.
void rt_tlatelucent1col (int hx, int sx, int yl, int yh)
{
byte *transmap;
byte *translation;
byte *colormap;
byte *source;
byte *dest;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
count = yh-yl;
if (count < 0)
return;
count++;
transmap = dc_transmap;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
translation = dc_translation;
colormap = dc_colormap;
dest = ylookup[yl] + columnofs[sx];
@ -445,7 +521,13 @@ void rt_tlatelucent1col (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
do {
*dest = transmap[colormap[translation[*source]] | ((*dest) << 8)];
unsigned int fg = colormap[translation[*source]];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);
@ -454,20 +536,28 @@ void rt_tlatelucent1col (int hx, int sx, int yl, int yh)
// Translates and mixes two spans at hx and hx+1 to the screen at sx and sx+1.
void rt_tlatelucent2cols (int hx, int sx, int yl, int yh)
{
byte *transmap;
byte *translation;
byte *colormap;
byte *source;
byte *dest;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
count = yh-yl;
if (count < 0)
return;
count++;
transmap = dc_transmap;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
translation = dc_translation;
colormap = dc_colormap;
dest = ylookup[yl] + columnofs[sx];
@ -475,8 +565,20 @@ void rt_tlatelucent2cols (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
do {
dest[0] = transmap[colormap[translation[source[0]]] | (dest[0] << 8)];
dest[1] = transmap[colormap[translation[source[1]]] | (dest[1] << 8)];
unsigned int fg = colormap[translation[source[0]]];
unsigned int bg = dest[0];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[0] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[translation[source[1]]];
bg = dest[1];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[1] = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);
@ -485,31 +587,64 @@ void rt_tlatelucent2cols (int hx, int sx, int yl, int yh)
// Translates and mixes all four spans to the screen starting at sx.
void rt_tlatelucent4cols (int sx, int yl, int yh)
{
byte *transmap;
byte *translation;
byte *colormap;
byte *source;
byte *dest;
int count;
int pitch;
unsigned int *fg2rgb, *bg2rgb;
transmap = dc_transmap;
translation = dc_translation;
count = yh-yl;
if (count < 0)
return;
count++;
{
fixed_t fglevel, bglevel;
fglevel = dc_translevel & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
translation = dc_translation;
colormap = dc_colormap;
dest = ylookup[yl] + columnofs[sx];
source = &dc_temp[yl*4];
pitch = dc_pitch;
do {
dest[0] = transmap[colormap[translation[source[0]]] | (dest[0] << 8)];
dest[1] = transmap[colormap[translation[source[1]]] | (dest[1] << 8)];
dest[2] = transmap[colormap[translation[source[2]]] | (dest[2] << 8)];
dest[3] = transmap[colormap[translation[source[3]]] | (dest[3] << 8)];
unsigned int fg = colormap[translation[source[0]]];
unsigned int bg = dest[0];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[0] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[translation[source[1]]];
bg = dest[1];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[1] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[translation[source[2]]];
bg = dest[2];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[2] = RGB8k[0][0][(fg>>5) & (fg>>19)];
fg = colormap[translation[source[3]]];
bg = dest[3];
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
dest[3] = RGB8k[0][0][(fg>>5) & (fg>>19)];
source += 4;
dest += pitch;
} while (--count);

3173
code/ticinfo.lmp Normal file

File diff suppressed because it is too large Load diff

View file

@ -116,23 +116,53 @@ void V_DrawPatchSP (byte *source, byte *dest, int count, int pitch, int yinc)
// Translucent patch drawers (always 50%)
void V_DrawLucentPatchP (byte *source, byte *dest, int count, int pitch)
{
byte *map = TransTable + 65536 * 2;
unsigned int *fg2rgb, *bg2rgb;
{
fixed_t fglevel, bglevel;
fglevel = 0x8000 & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
do
{
*dest = map[(*dest)|((*source++)<<8)];
unsigned int fg = *source++;
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
} while (--count);
}
void V_DrawLucentPatchSP (byte *source, byte *dest, int count, int pitch, int yinc)
{
byte *map = TransTable + 65536 * 2;
unsigned int *fg2rgb, *bg2rgb;
int c = 0;
{
fixed_t fglevel, bglevel;
fglevel = 0x8000 & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
do
{
*dest = map[(*dest)|((source[c >> 16])<<8)];
unsigned int fg = source[c >> 16];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
c += yinc;
} while (--count);
@ -165,23 +195,55 @@ void V_DrawTranslatedPatchSP (byte *source, byte *dest, int count, int pitch, in
// Translated, translucent patch drawers
void V_DrawTlatedLucentPatchP (byte *source, byte *dest, int count, int pitch)
{
byte *map = TransTable + 65536 * 2;
unsigned int *fg2rgb, *bg2rgb;
byte *colormap = V_ColorMap;
{
fixed_t fglevel, bglevel;
fglevel = 0x8000 & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
do
{
*dest = map[(*dest)|(V_ColorMap[*source++]<<8)];
unsigned int fg = colormap[*source++];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
} while (--count);
}
void V_DrawTlatedLucentPatchSP (byte *source, byte *dest, int count, int pitch, int yinc)
{
byte *map = TransTable + 65536 * 2;
int c = 0;
unsigned int *fg2rgb, *bg2rgb;
byte *colormap = V_ColorMap;
{
fixed_t fglevel, bglevel;
fglevel = 0x8000 & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
}
do
{
*dest = map[(*dest)|(V_ColorMap[source[c >> 16]]<<8)];
unsigned int fg = colormap[source[c >> 16]];
unsigned int bg = *dest;
fg = fg2rgb[fg];
bg = bg2rgb[bg];
fg = (fg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(fg>>5) & (fg>>19)];
dest += pitch;
c += yinc;
} while (--count);
@ -210,12 +272,26 @@ void V_DrawColoredPatchP (byte *source, byte *dest, int count, int pitch)
// care about the patch's actual contents, just it's outline.
void V_DrawColorLucentPatchP (byte *source, byte *dest, int count, int pitch)
{
byte *map = TransTable + 65536 * 2;
int fill = V_ColorFill << 8;
unsigned int *bg2rgb;
unsigned int fg;
byte *colormap = V_ColorMap;
{
unsigned int *fg2rgb;
fixed_t fglevel, bglevel;
fglevel = 0x8000 & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
fg = fg2rgb[V_ColorFill];
}
do
{
*dest = map[(*dest)|fill];
unsigned int bg = bg2rgb[*dest];
bg = (bg+bg) | 0xf07c3e1f;
*dest = RGB8k[0][0][(bg>>5) & (bg>>19)];
dest += pitch;
} while (--count);
}

View file

@ -6,6 +6,6 @@ enum { VERSION = 117 };
#define VERSIONSTR "117"
#define DOTVERSIONSTR "1.17:"
#define GAMEVER (0x0111)
#define SAVESIG "ZDOOMSAVE117 " // Needs to be exactly 16 chars long
#define SAVESIG "ZDOOMSAVE117b " // Needs to be exactly 16 chars long
#endif //__VERSION_H__

View file

@ -68,7 +68,7 @@ typedef struct
typedef struct lumpinfo_s
{
char name[8];
FILE *handle; // [RH] Use stdio routines
int handle;
int position;
int size;
@ -124,8 +124,8 @@ void uppercopy (char *to, const char *from);
// [RH] Copies the lump name to to using uppercopy
void W_GetLumpName (char *to, int lump);
// [RH] Returns file ptr for specified lump
FILE *W_GetLumpFile (int lump);
// [RH] Returns file handle for specified lump
int W_GetLumpFile (int lump);
// [RH] Put a lump in a certain namespace
void W_SetLumpNamespace (int lump, int nmspace);

View file

@ -1096,6 +1096,8 @@ void I_GetEvent(void)
else
MouseRead_Win32 ();
}
if (usejoystick->value)
DI_JoyCheck ();
}
@ -1112,6 +1114,4 @@ void I_StartTic (void)
//
void I_StartFrame (void)
{
if (usejoystick->value)
DI_JoyCheck ();
}

View file

@ -21,11 +21,9 @@
//
//-----------------------------------------------------------------------------
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include "resource.h"
#include <stdio.h>
@ -52,17 +50,27 @@ HWND Window;
HINSTANCE hInstance;
extern float mb_used;
extern UINT TimerPeriod;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int nCmdShow)
{
LONG WinWidth, WinHeight;
int height, width;
RECT cRect;
TIMECAPS tc;
g_hInst = hInstance;
myargc = __argc;
myargv = __argv;
// Set the timer to be as accurate as possible
if (timeGetDevCaps (&tc, sizeof(tc) != TIMERR_NOERROR))
TimerPeriod = 1; // Assume minimum resolution of 1 ms
else
TimerPeriod = tc.wPeriodMin;
timeBeginPeriod (TimerPeriod);
/*
killough 1/98:

View file

@ -14,18 +14,8 @@
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log: i_net.c,v $
// Revision 1.2 1997/12/29 19:50:54 pekangas
// Ported to WinNT/95 environment using Watcom C 10.6.
// Everything expect joystick support is implemented, but networking is
// untested. Crashes way too often with problems in FixedDiv().
// Compiles with no warnings at warning level 3, uses MIDAS 1.1.1.
//
// Revision 1.1.1.1 1997/12/28 12:59:03 pekangas
// Initial DOOM source release from id Software
//
//
// DESCRIPTION:
// Low-level networking code. Uses BSD sockets for UDP networking.
//
//-----------------------------------------------------------------------------
@ -74,12 +64,15 @@ typedef int SOCKET;
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define closesocket close
#define ioctlsocket ioctl
#endif
#ifdef __WIN32__
# define IPPORT_USERRESERVED 5000
#endif
extern BOOL CheckAbort (void);
static void NetSend (void);
static BOOL NetListen (void);
@ -88,64 +81,91 @@ static BOOL NetListen (void);
// NETWORKING
//
static int DOOMPORT = (IPPORT_USERRESERVED +0x1d );
static u_short DOOMPORT = (IPPORT_USERRESERVED + 0x1d);
static SOCKET mysocket = INVALID_SOCKET;
static struct sockaddr_in sendaddress[MAXNETNODES];
static int sendsocket;
static int insocket;
static struct sockaddr_in sendaddress[MAXNETNODES];
void (*netget) (void);
void (*netsend) (void);
void (*netget) (void);
void (*netsend) (void);
#ifdef __WIN32__
char *neterror (void);
#else
#define neterror() strerror(errno)
#endif
enum
{
PRE_CONNECT,
PRE_DISCONNECT,
PRE_ALLHERE,
PRE_CONACK,
PRE_ALLHEREACK,
PRE_GO,
PRE_GOACK
};
struct PreGamePacket
{
u_short message;
u_short numnodes;
struct
{
u_long address;
u_short port;
} machines[MAXNETNODES];
};
//
// UDPsocket
//
int UDPsocket (void)
SOCKET UDPsocket (void)
{
SOCKET s;
// allocate a socket
s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#ifdef __WIN32__
if ( s == INVALID_SOCKET )
I_FatalError ("can't create socket: %s", neterror());
#else
if (s<0)
I_FatalError ("can't create socket: %s",strerror(errno));
#endif
return (int) s;
if (s == INVALID_SOCKET)
I_FatalError ("can't create socket: %s", neterror ());
return s;
}
//
// BindToLocalPort
//
void BindToLocalPort (int s, int port)
void BindToLocalPort (SOCKET s, u_short port)
{
int v;
struct sockaddr_in address;
int v;
struct sockaddr_in address;
memset (&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = (USHORT)port;
address.sin_port = htons(port);
v = bind ((SOCKET) s, (void *)&address, sizeof(address));
#ifdef __WIN32__
if (v == -1)
I_FatalError ("BindToPort: bind: %s", neterror());
#else
if (v == -1)
I_FatalError ("BindToPort: bind: %s", strerror(errno));
#endif
v = bind (s, (void *)&address, sizeof(address));
if (v == SOCKET_ERROR)
I_FatalError ("BindToPort: %s", neterror ());
}
int FindNode (struct sockaddr_in *address)
{
int i;
// find remote node number
for (i = 0; i<doomcom->numnodes; i++)
if (address->sin_addr.s_addr == sendaddress[i].sin_addr.s_addr
&& address->sin_port == sendaddress[i].sin_port)
break;
if (i == doomcom->numnodes)
{
// packet is not from one of the players (new game broadcast?)
i = -1;
}
return i;
}
//
// PacketSend
@ -153,17 +173,12 @@ void BindToLocalPort (int s, int port)
void PacketSend (void)
{
int c;
// byte swap
netbuffer->checksum = LONG(netbuffer->checksum);
//printf ("sending %i\n",gametic);
c = sendto (sendsocket , (const char*)netbuffer, doomcom->datalength
//printf ("sending %i\n",gametic);
c = sendto (mysocket , (const char*)netbuffer, doomcom->datalength
,0,(void *)&sendaddress[doomcom->remotenode]
,sizeof(sendaddress[doomcom->remotenode]));
netbuffer->checksum = LONG(netbuffer->checksum);
// if (c == -1)
// I_Error ("SendPacket error: %s",strerror(errno));
}
@ -174,93 +189,435 @@ void PacketSend (void)
//
void PacketGet (void)
{
int i;
int c;
struct sockaddr_in fromaddress;
int fromlen;
int c, fromlen;
struct sockaddr_in fromaddress;
fromlen = sizeof(fromaddress);
c = recvfrom (insocket, (char*)netbuffer, sizeof(doomdata_t), 0
, (struct sockaddr *)&fromaddress, &fromlen );
if (c == -1 )
c = recvfrom (mysocket, (char*)netbuffer, sizeof(doomdata_t), 0
, (struct sockaddr *)&fromaddress, &fromlen);
if (c == SOCKET_ERROR)
{
#ifdef __WIN32__
if ( WSAGetLastError() != WSAEWOULDBLOCK )
I_Error("GetPacket: %s",neterror());
if (WSAGetLastError() != WSAEWOULDBLOCK)
I_Error ("GetPacket: %s", neterror ());
#else
if (errno != EWOULDBLOCK)
I_Error ("GetPacket: %s",strerror(errno));
I_Error ("GetPacket: %s", neterror ());
#endif
doomcom->remotenode = -1; // no packet
return;
}
// find remote node number
for (i = 0; i<doomcom->numnodes; i++)
if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr )
break;
if (i == doomcom->numnodes)
{
// packet is not from one of the players (new game broadcast)
doomcom->remotenode = -1; // no packet
return;
}
doomcom->remotenode = (short)i; // good packet from a game player
doomcom->remotenode = (short)FindNode (&fromaddress);
doomcom->datalength = (short)c;
// byte swap
netbuffer->checksum = LONG(netbuffer->checksum);
}
int GetLocalAddress (void)
/*
struct sockaddr_in *PreGet (void *buffer, int bufferlen)
{
char hostname[1024];
struct hostent* hostentry; // host information entry
int v;
static struct sockaddr_in fromaddress;
int fromlen;
int c;
// get local address
v = gethostname (hostname, sizeof(hostname));
fromlen = sizeof(fromaddress);
c = recvfrom (mysocket, buffer, bufferlen, 0,
(struct sockaddr *)&fromaddress, &fromlen);
if (c == SOCKET_ERROR)
{
#ifdef __WIN32__
if (v == -1)
I_FatalError ("GetLocalAddress : gethostname: %s", neterror());
if (WSAGetLastError() != WSAEWOULDBLOCK)
I_Error ("PreGet: %s", neterror ());
#else
if (v == -1)
I_FatalError ("GetLocalAddress : gethostname: errno %d",errno);
#endif
hostentry = gethostbyname (hostname);
#ifdef __WIN32__
if (!hostentry)
I_FatalError ("GetLocalAddress : gethostbyname: %s", neterror());
#else
if (!hostentry)
I_FatalError ("GetLocalAddress : gethostbyname: couldn't get local host");
#endif
return *(int *)hostentry->h_addr_list[0];
if (errno != EWOULDBLOCK)
I_Error ("PreGet: %s", neterror ());
#endif
return NULL; // no packet
}
return &fromaddress;
}
void PreSend (void *buffer, int bufferlen, struct sockaddr_in *to)
{
sendto (mysocket, buffer, bufferlen, 0, (void *)to, sizeof(*to));
}
*/
void BuildAddress (struct sockaddr_in *address, char *name)
{
struct hostent *hostentry; // host information entry
u_short port;
char *portpart;
BOOL isnamed = false;
int curchar;
char c;
address->sin_family = AF_INET;
if (portpart = strchr (name, ':'))
{
*portpart = 0;
port = atoi (portpart + 1);
if (!port)
{
Printf (PRINT_HIGH, "Weird port: %s (using %d)\n", portpart + 1, DOOMPORT);
port = DOOMPORT;
}
}
else
{
port = DOOMPORT;
}
address->sin_port = htons(port);
for (curchar = 0; c = name[curchar]; curchar++)
{
if ((c < '0' || c > '9') && c != '.')
{
isnamed = true;
break;
}
}
if (!isnamed)
{
address->sin_addr.s_addr = inet_addr (name);
Printf (PRINT_HIGH, "Node number %d address %s\n", doomcom->numnodes, name);
}
else
{
hostentry = gethostbyname (name);
if (!hostentry)
I_FatalError ("gethostbyname: couldn't find %s\n%s", name, neterror());
address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
Printf (PRINT_HIGH, "Node number %d hostname %s\n",
doomcom->numnodes, hostentry->h_name);
}
if (portpart)
*portpart = ':';
}
void STACK_ARGS CloseNetwork (void)
{
if (mysocket != INVALID_SOCKET)
{
closesocket (mysocket);
mysocket = INVALID_SOCKET;
}
#ifdef __WIN32__
WSACleanup ();
#endif
}
void StartNetwork (void)
{
u_long trueval = 1;
#ifdef __WIN32__
WSADATA wsad;
if (WSAStartup (0x0101, &wsad))
{
I_FatalError ("Could not initialize Windows Sockets");
}
#endif
atexit (CloseNetwork);
netsend = PacketSend;
netget = PacketGet;
netgame = true;
// create communication socket
mysocket = UDPsocket ();
BindToLocalPort (mysocket, DOOMPORT);
ioctlsocket (mysocket, FIONBIO, &trueval);
}
void WaitForPlayers (int i)
{
if (i == myargc - 1)
I_FatalError ("Not enough parameters after -net");
StartNetwork ();
// parse player number and host list
doomcom->consoleplayer = (short)(myargv[i+1][0]-'1');
Printf (PRINT_HIGH, "Console player number: %d\n", doomcom->consoleplayer);
doomcom->numnodes = 1; // this node for sure
i++;
while (++i < myargc && myargv[i][0] != '-' && myargv[i][0] != '+')
{
BuildAddress (&sendaddress[doomcom->numnodes], myargv[i]);
doomcom->numnodes++;
}
Printf (PRINT_HIGH, "Total players: %d\n", doomcom->numnodes);
doomcom->id = DOOMCOM_ID;
doomcom->numplayers = doomcom->numnodes;
}
/*
void SendAbort (void)
{
u_short dis = htons (PRE_DISCONNECT);
doomcom->numnodes--;
while (doomcom->numnodes)
{
PreSend (&dis, 2, &sendaddress[--doomcom->numnodes]);
PreSend (&dis, 2, &sendaddress[doomcom->numnodes]);
PreSend (&dis, 2, &sendaddress[doomcom->numnodes]);
PreSend (&dis, 2, &sendaddress[doomcom->numnodes]);
}
I_FatalError ("Network game synchronization aborted.");
}
void HostGame (int i)
{
struct PreGamePacket packet;
int numplayers;
BOOL gotack[MAXNETNODES];
int ackcount;
struct sockaddr_in *from;
int node;
if ((i == myargc - 1) || !(numplayers = atoi (myargv[i+1])))
{ // No player count specified, assume 2
numplayers = 2;
}
StartNetwork ();
doomcom->numnodes = 1;
Printf (PRINT_HIGH, "Waiting for players...\n");
// Wait for numplayers-1 different connections
while (doomcom->numnodes < numplayers)
{
while (doomcom->numnodes < numplayers)
{
if (CheckAbort ())
{
SendAbort ();
}
while (from = PreGet (&packet, sizeof(packet)))
{
switch (ntohs (packet.message))
{
case PRE_CONNECT:
node = FindNode (from);
if (node == -1)
{
node = doomcom->numnodes++;
sendaddress[node] = *from;
}
Printf (PRINT_HIGH, "Got connect from node %d\n", node);
packet.message = htons (PRE_CONACK);
PreSend (&packet, 2, from);
break;
case PRE_DISCONNECT:
node = FindNode (from);
if (node >= 0)
{
Printf (PRINT_HIGH, "Got disconnect from node %d\n", node);
doomcom->numnodes--;
while (node < doomcom->numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
}
break;
}
}
}
// It's possible somebody bailed out after all players were found.
// Unfortunately, this isn't guaranteed to catch all of them.
// Oh well. Better than nothing.
while ( (from = PreGet (&packet, sizeof(packet))) )
{
if (ntohs (packet.message) == PRE_DISCONNECT)
{
node = FindNode (from);
if (node >= 0)
{
doomcom->numnodes--;
while (node < doomcom->numnodes)
{
sendaddress[node] = sendaddress[node+1];
node++;
}
}
break;
}
}
}
// Now inform everyone of all machines involved in the game
ackcount = 0;
memset (gotack, 0, sizeof(gotack));
Printf (PRINT_HIGH, "Sending all here\n");
while (ackcount < doomcom->numnodes - 1)
{
packet.message = htons (PRE_ALLHERE);
packet.numnodes = htons ((u_short)(doomcom->numnodes - 1));
for (node = 0; node < doomcom->numnodes - 1; node++)
{
int machine, spot;
if (!gotack[node])
{
for (spot = machine = 0; machine < doomcom->numnodes; machine++)
{
if (node != machine)
{
packet.machines[spot].address =
sendaddress[machine].sin_addr.s_addr;
packet.machines[spot].port =
sendaddress[machine].sin_port;
}
}
}
PreSend (&packet, sizeof(packet), &sendaddress[node]);
}
if (CheckAbort ())
SendAbort ();
while (from = PreGet (&packet, sizeof(packet)))
{
if (ntohs (packet.message) == PRE_ALLHEREACK)
{
node = FindNode (from);
if (node >= 0)
{
if (!gotack[node])
{
gotack[node] = true;
ackcount++;
}
}
PreSend (&packet, 2, from);
}
}
}
// Now go
Printf (PRINT_HIGH, "Go\n");
packet.message = htons (PRE_GO);
for (node = 0; node < doomcom->numnodes - 1; node++)
{
PreSend (&packet, sizeof(packet), &sendaddress[node]);
PreSend (&packet, sizeof(packet), &sendaddress[node]);
PreSend (&packet, sizeof(packet), &sendaddress[node]);
PreSend (&packet, sizeof(packet), &sendaddress[node]);
}
}
void SendToHost (u_short message, u_short ackmess, BOOL abortable)
{
struct sockaddr_in *from;
BOOL waiting = true;
u_short packet;
message = htons (message);
ackmess = htons (ackmess);
while (waiting)
{
if (abortable && CheckAbort ())
SendAbort ();
// Let host know we are here
PreSend (&message, 2, &sendaddress[0]);
Sleep (300);
// Listen for acknowledgement
while ( (from = PreGet (&packet, sizeof(packet))) )
{
if (packet == ackmess)
waiting = false;
}
}
}
void JoinGame (int i)
{
struct sockaddr_in *from;
BOOL waiting;
struct PreGamePacket packet;
if ((i == myargc - 1) || (myargv[i+1][0] == '-') || (myargv[i+1][0] == '+'))
I_FatalError ("You need to specify the host machine's address");
StartNetwork ();
// Host is always node 0
BuildAddress (&sendaddress[0], myargv[i+1]);
// Let host know we are here
SendToHost (PRE_CONNECT, PRE_CONACK, true);
// Wait for everyone else to connect
waiting = true;
doomcom->numnodes = 0;
while (waiting)
{
if (CheckAbort ())
SendAbort ();
Sleep (300);
while (from = PreGet (&packet, sizeof(packet)))
{
switch (ntohs (packet.message))
{
case PRE_ALLHERE:
if (doomcom->numnodes == 0)
{
int node;
packet.numnodes = ntohs (packet.numnodes);
doomcom->numnodes = packet.numnodes + 1;
for (node = 0; node < packet.numnodes; node++)
{
sendaddress[node+1].sin_addr.s_addr =
packet.machines[node].address;
sendaddress[node+1].sin_port =
packet.machines[node].port;
}
}
packet.message = htons (PRE_ALLHEREACK);
PreSend (&packet, 2, &sendaddress[0]);
break;
case PRE_GO:
waiting = false;
break;
case PRE_DISCONNECT:
I_FatalError ("Host cancelled the game");
break;
}
}
}
// Clear out any waiting packets
while (PreGet (&packet, sizeof(packet)))
;
}
*/
//
// I_InitNetwork
//
void I_InitNetwork (void)
{
u_long trueval = true;
int i;
int p;
struct hostent* hostentry; // host information entry
int i, p;
#ifdef __WIN32__
WSADATA wsad;
#endif
doomcom = Malloc (sizeof (*doomcom) );
memset (doomcom, 0, sizeof(*doomcom) );
doomcom = Malloc (sizeof (*doomcom));
memset (doomcom, 0, sizeof(*doomcom));
// set up for network
i = M_CheckParm ("-dup");
@ -284,12 +641,24 @@ void I_InitNetwork (void)
if (p && p<myargc-1)
{
DOOMPORT = atoi (myargv[p+1]);
Printf (PRINT_HIGH, "using alternate port %i\n",DOOMPORT);
Printf (PRINT_HIGH, "using alternate port %i\n", DOOMPORT);
}
// parse network game options,
// -net <consoleplayer> <host> <host> ...
if ( !(i = M_CheckParm ("-net")) ) {
// -net <consoleplayer> <host> <host> ...
// -or-
// player 1: -host <numplayers>
// player x: -join <player 1's address>
if ( (i = M_CheckParm ("-net")) )
WaitForPlayers (i);
/*
else if ( (i = M_CheckParm ("-host")) )
HostGame (i);
else if ( (i = M_CheckParm ("-join")) )
JoinGame (i);
*/
else
{
// single player game
netgame = false;
doomcom->id = DOOMCOM_ID;
@ -297,92 +666,6 @@ void I_InitNetwork (void)
doomcom->consoleplayer = 0;
return;
}
#ifdef __WIN32__
WSAStartup( 0x0101, &wsad );
#endif
netsend = PacketSend;
netget = PacketGet;
netgame = true;
// parse player number and host list
doomcom->consoleplayer = (short)(myargv[i+1][0]-'1');
Printf (PRINT_HIGH, "Console player number: %d\n", doomcom->consoleplayer);
doomcom->numnodes = 1; // this node for sure
i++;
while (++i < myargc && myargv[i][0] != '-' && myargv[i][0] != '+')
{
int port;
char *portpart;
BOOL isnamed = false;
int curchar;
char c;
sendaddress[doomcom->numnodes].sin_family = AF_INET;
if (portpart = strchr (myargv[i], ':')) {
*portpart = 0;
port = atoi (portpart + 1);
if (!port) {
Printf (PRINT_HIGH, "Weird port: %s (using %d)\n", portpart + 1, DOOMPORT);
port = DOOMPORT;
}
} else {
port = DOOMPORT;
}
sendaddress[doomcom->numnodes].sin_port = (USHORT)port;
for (curchar = 0; c = myargv[i][curchar]; curchar++) {
if ((c < '0' || c > '9') && c != '.') {
isnamed = true;
break;
}
}
if (!isnamed)
{
sendaddress[doomcom->numnodes].sin_addr.s_addr
= inet_addr (myargv[i]);
Printf (PRINT_HIGH, "Node number %d address %s\n", doomcom->numnodes, myargv[i]);
}
else
{
hostentry = gethostbyname (myargv[i]);
if (!hostentry)
#ifdef __WIN32__
I_FatalError ("gethostbyname: couldn't find %s\n%s", myargv[i], neterror());
#else
I_FatalError ("gethostbyname: couldn't find %s\n%s", myargv[i], strerror(errno));
#endif
sendaddress[doomcom->numnodes].sin_addr.s_addr
= *(int *)hostentry->h_addr_list[0];
Printf (PRINT_HIGH, "Node number %d hostname %s\n", doomcom->numnodes, hostentry->h_name);
}
if (portpart)
*portpart = ':';
doomcom->numnodes++;
}
Printf (PRINT_HIGH, "Total players: %d\n", doomcom->numnodes);
doomcom->id = DOOMCOM_ID;
doomcom->numplayers = doomcom->numnodes;
// build message to receive
insocket = UDPsocket ();
BindToLocalPort (insocket, DOOMPORT);
#ifdef __WIN32__
ioctlsocket (insocket, FIONBIO, &trueval);
#else
ioctl (insocket, FIONBIO, &trueval);
#endif
sendsocket = UDPsocket ();
}
@ -401,55 +684,54 @@ void I_NetCmd (void)
}
#ifdef __WIN32__
#ifdef _DEBUG
char *neterror (void)
{
static char neterr[16];
int code;
switch (code = WSAGetLastError ()) {
case WSAEACCES: return "Permission denied";
case WSAEADDRINUSE: return "Address already in use";
case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
case WSAEALREADY: return "Operation already in progress";
case WSAECONNABORTED: return "Software caused connection abort";
case WSAECONNREFUSED: return "Connection refused";
case WSAECONNRESET: return "Connection reset by peer";
case WSAEDESTADDRREQ: return "Destination address required";
case WSAEFAULT: return "Bad address";
case WSAEHOSTDOWN: return "Host is down";
case WSAEHOSTUNREACH: return "No route to host";
case WSAEINPROGRESS: return "Operation now in progress";
case WSAEINTR: return "Interrupted function call";
case WSAEINVAL: return "Invalid argument";
case WSAEISCONN: return "Socket is already connected";
case WSAEMFILE: return "Too many open files";
case WSAEMSGSIZE: return "Message too long";
case WSAENETDOWN: return "Network is down";
case WSAENETRESET: return "Network dropped connection or reset";
case WSAENETUNREACH: return "Network is unreachable";
case WSAENOBUFS: return "No buffer space available";
case WSAENOPROTOOPT: return "Bad protocol option";
case WSAENOTCONN: return "Socket is not connected";
case WSAENOTSOCK: return "Socket operation on non-socket";
case WSAEOPNOTSUPP: return "Operation not supported";
case WSAEPFNOSUPPORT: return "Protocol family not supported";
case WSAEPROCLIM: return "Too many processes";
case WSAEPROTONOSUPPORT: return "Protocol not supported";
case WSAEPROTOTYPE: return "Protocol wrong type for socket";
case WSAESHUTDOWN: return "Cannot send after socket shutdown";
case WSAESOCKTNOSUPPORT: return "Socket type not supported";
case WSAETIMEDOUT: return "Connection timed out";
case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
case WSAHOST_NOT_FOUND: return "Host not found";
case WSANOTINITIALISED: return "Successful WSAStartup not yet performed";
case WSANO_DATA: return "Valid name, no data record of requested type";
case WSANO_RECOVERY: return "This is a non-recoverable error";
case WSASYSNOTREADY: return "Network subsystem is unavailable";
case WSATRY_AGAIN: return "Non-authoritative host not found";
case WSAVERNOTSUPPORTED: return "WINSOCK.DLL version out of range";
case WSAEDISCON: return "Graceful shutdown in progress";
case WSAEACCES: return "EACCES";
case WSAEADDRINUSE: return "EADDRINUSE";
case WSAEADDRNOTAVAIL: return "EADDRNOTAVAIL";
case WSAEAFNOSUPPORT: return "EAFNOSUPPORT";
case WSAEALREADY: return "EALREADY";
case WSAECONNABORTED: return "ECONNABORTED";
case WSAECONNREFUSED: return "ECONNREFUSED";
case WSAECONNRESET: return "ECONNRESET";
case WSAEDESTADDRREQ: return "EDESTADDRREQ";
case WSAEFAULT: return "EFAULT";
case WSAEHOSTDOWN: return "EHOSTDOWN";
case WSAEHOSTUNREACH: return "EHOSTUNREACH";
case WSAEINPROGRESS: return "EINPROGRESS";
case WSAEINTR: return "EINTR";
case WSAEINVAL: return "EINVAL";
case WSAEISCONN: return "EISCONN";
case WSAEMFILE: return "EMFILE";
case WSAEMSGSIZE: return "EMSGSIZE";
case WSAENETDOWN: return "ENETDOWN";
case WSAENETRESET: return "ENETRESET";
case WSAENETUNREACH: return "ENETUNREACH";
case WSAENOBUFS: return "ENOBUFS";
case WSAENOPROTOOPT: return "ENOPROTOOPT";
case WSAENOTCONN: return "ENOTCONN";
case WSAENOTSOCK: return "ENOTSOCK";
case WSAEOPNOTSUPP: return "EOPNOTSUPP";
case WSAEPFNOSUPPORT: return "EPFNOSUPPORT";
case WSAEPROCLIM: return "EPROCLIM";
case WSAEPROTONOSUPPORT: return "EPROTONOSUPPORT";
case WSAEPROTOTYPE: return "EPROTOTYPE";
case WSAESHUTDOWN: return "ESHUTDOWN";
case WSAESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
case WSAETIMEDOUT: return "ETIMEDOUT";
case WSAEWOULDBLOCK: return "EWOULDBLOCK";
case WSAHOST_NOT_FOUND: return "HOST_NOT_FOUND";
case WSANOTINITIALISED: return "NOTINITIALISED";
case WSANO_DATA: return "NO_DATA";
case WSANO_RECOVERY: return "NO_RECOVERY";
case WSASYSNOTREADY: return "SYSNOTREADY";
case WSATRY_AGAIN: return "TRY_AGAIN";
case WSAVERNOTSUPPORTED: return "VERNOTSUPPORTED";
case WSAEDISCON: return "EDISCON";
default:
sprintf (neterr, "%d", code);
@ -465,4 +747,3 @@ char *neterror (void)
return neterr;
}
#endif
#endif

View file

@ -153,7 +153,8 @@ badwave:
sfx->link = S_sfx + i;
sfx->ms = S_sfx[i].ms;
sfx->data = S_sfx[i].data;
sfx->loopdata = S_sfx[i].loopdata;
sfx->normal = S_sfx[i].normal;
sfx->looping = S_sfx[i].looping;
return;
}
@ -290,7 +291,7 @@ badwave:
smp.loop1Start = smp.loop1End = 0;
smp.loop1Type = loopNone;
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->data)) != OK)
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->normal)) != OK)
I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error));
/* With loop: */
@ -299,7 +300,7 @@ badwave:
smp.loop1End = smp.sampleLength;
smp.loop1Type = loopUnidir;
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->loopdata)) != OK)
if ( (error = blargh (&smp, 0, (unsigned *)&sfx->looping)) != OK)
I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error));
}
@ -308,6 +309,7 @@ badwave:
if (sfx->frequency == 0)
sfx->frequency = 11025;
sfx->ms = (sfx->ms * 1000) / (sfx->frequency);
sfx->data = sfxcopy;
}
@ -383,8 +385,8 @@ int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel, BOOL
}
ChannelMap[channel].playHandle = MIDASplaySample (
looping ? (MIDASsample)sfx->loopdata
: (MIDASsample)sfx->data,
looping ? (MIDASsample)sfx->looping
: (MIDASsample)sfx->normal,
ChannelMap[channel].midasChannel,
0,
PITCH(sfx->frequency,pitch),
@ -593,7 +595,6 @@ void STACK_ARGS I_ShutdownSound (void)
size_t len = 0;
if (MidasInited) {
Printf (PRINT_HIGH, "I_ShutdownSound: Stopping sounds\n");
if (ChannelMap) {
for (i = 0; i < numChannels; i++ ) {
if (ChannelMap[i].playHandle) {
@ -607,23 +608,23 @@ void STACK_ARGS I_ShutdownSound (void)
I_ShutdownMusic();
Printf (PRINT_HIGH, "I_ShutdownSound: Uninitializing MIDAS\n");
// [RH] Free all loaded samples
for (i = 0; i < numsfx; i++) {
if (!S_sfx[i].link) {
if (S_sfx[i].data) {
MIDASfreeSample ((MIDASsample)S_sfx[i].data);
if (S_sfx[i].normal) {
MIDASfreeSample ((MIDASsample)S_sfx[i].normal);
len += S_sfx[i].length;
c++;
}
if (S_sfx[i].loopdata) {
MIDASfreeSample ((MIDASsample)S_sfx[i].loopdata);
if (S_sfx[i].looping) {
MIDASfreeSample ((MIDASsample)S_sfx[i].looping);
}
if (S_sfx[i].data) {
free (S_sfx[i].data);
}
}
S_sfx[i].data = S_sfx[i].link = NULL;
}
Printf (PRINT_HIGH, "%d sounds expunged (%d bytes)\n", c, len);
if ( !MIDASstopBackgroundPlay() )
MIDASerror();

View file

@ -57,12 +57,16 @@ BOOL STACK_ARGS CheckMMX (char *vendorid);
extern HWND Window;
BOOL UseMMX;
BOOL fastdemo;
BOOL UseMMX;
BOOL fastdemo;
UINT TimerPeriod;
UINT TimerEventID;
HANDLE NewTicArrived;
float mb_used = 8.0;
float mb_used = 8.0;
int (*I_GetTime) (void);
int (*I_WaitForTic) (int);
os_t OSPlatform;
@ -72,19 +76,18 @@ void I_Tactile (int on, int off, int total)
on = off = total = 0;
}
ticcmd_t emptycmd;
ticcmd_t* I_BaseTiccmd(void)
ticcmd_t emptycmd;
ticcmd_t *I_BaseTiccmd(void)
{
return &emptycmd;
}
int I_GetHeapSize (void)
int I_GetHeapSize (void)
{
return (int)(mb_used*1024*1024);
}
byte* I_ZoneBase (int *size)
byte *I_ZoneBase (int *size)
{
int i;
@ -103,7 +106,7 @@ void I_EndRead(void)
{
}
byte* I_AllocLow(int length)
byte *I_AllocLow(int length)
{
byte* mem;
@ -133,7 +136,7 @@ unsigned int I_MSTime (void)
// I_GetTime
// returns time in 1/35th second tics
//
int I_GetTimeReally (void)
int I_GetTimePolled (void)
{
DWORD tm;
@ -144,20 +147,59 @@ int I_GetTimeReally (void)
return ((tm-basetime)*TICRATE)/1000;
}
int I_WaitForTicPolled (int prevtic)
{
int time;
while ((time = I_GetTimePolled()) <= prevtic)
;
return time;
}
static int tics;
int I_GetTimeEventDriven (void)
{
return tics;
}
int I_WaitForTicEvent (int prevtic)
{
if (prevtic >= tics)
do
{
WaitForSingleObject (NewTicArrived, INFINITE);
} while (prevtic >= tics);
return tics;
}
void CALLBACK TimerTicked (UINT id, UINT msg, DWORD user, DWORD dw1, DWORD dw2)
{
tics++;
SetEvent (NewTicArrived);
}
// [RH] Increments the time count every time it gets called.
// Used only by -fastdemo (just like BOOM).
static int faketic = 0;
int I_GetTimeFake (void)
{
static int tic = 0;
return faketic++;
}
return tic++;
int I_WaitForTicFake (int whocares)
{
return faketic++;
}
void I_WaitVBL (int count)
{
// I_WaitVBL is never used to actually synchronize to the
// vertical blank. Instead, it's used for delay purposes.
Sleep (1000 * count / 70);
}
@ -233,9 +275,35 @@ void I_Init (void)
// [RH] Support for BOOM's -fastdemo
if (fastdemo)
{
I_GetTime = I_GetTimeFake;
I_WaitForTic = I_WaitForTicFake;
}
else
I_GetTime = I_GetTimeReally;
{ // Use a timer event if possible
NewTicArrived = CreateEvent (NULL, FALSE, FALSE, NULL);
if (NewTicArrived)
{
TimerEventID = timeSetEvent
(
1000/TICRATE,
0,
TimerTicked,
0,
TIME_PERIODIC
);
}
if (TimerEventID != 0)
{
I_GetTime = I_GetTimeEventDriven;
I_WaitForTic = I_WaitForTicEvent;
}
else
{ // Otherwise, busy-loop with timeGetTime
I_GetTime = I_GetTimePolled;
I_WaitForTic = I_WaitForTicPolled;
}
}
I_InitSound();
I_InitInput (Window);
@ -250,6 +318,13 @@ void STACK_ARGS I_Quit (void)
{
has_exited = 1; /* Prevent infinitely recursive exits -- killough */
if (TimerEventID)
timeKillEvent (TimerEventID);
if (NewTicArrived)
CloseHandle (NewTicArrived);
timeEndPeriod (TimerPeriod);
if (demorecording)
G_CheckDemoStatus();
M_SaveDefaults ();

View file

@ -56,7 +56,10 @@ byte *I_ZoneBase (int *size);
// returns current time in tics.
int (*I_GetTime) (void);
int I_GetTimeReally (void);
// like I_GetTime, except it waits for a new tic before returning
int (*I_WaitForTic) (int);
int I_GetTimePolled (void);
int I_GetTimeFake (void);

View file

@ -104,6 +104,7 @@ cvar_t *ticker;
cvar_t *win_stretchx;
cvar_t *win_stretchy;
cvar_t *fullscreen;
cvar_t *vid_palettehack;
BOOL Fullscreen;
static modelist_t *IteratorMode;
static int IteratorID;
@ -390,6 +391,14 @@ void I_FinishUpdate (void)
}
lastms = ms;
if (vid_palettehack->value)
{
if (NeedPalChange <= 0)
NeedPalChange = 1;
else
NeedPalChange++;
}
// draws little dots on the bottom of the screen
if (ticker->value) {
i = I_GetTime();
@ -710,6 +719,7 @@ void I_InitGraphics (void)
win_stretchy = cvar ("win_stretchy", "1.0", CVAR_ARCHIVE|CVAR_CALLBACK);
fullscreen = cvar ("fullscreen", "1", CVAR_ARCHIVE|CVAR_CALLBACK);
vid_noptc = cvar ("vid_noptc", "0", CVAR_ARCHIVE);
vid_palettehack = cvar ("vid_palettehack", "0", CVAR_ARCHIVE);
Fullscreen = (BOOL)fullscreen->value;

View file

@ -100,8 +100,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,17,0,0
PRODUCTVERSION 1,17,0,0
FILEVERSION 1,17,2,0
PRODUCTVERSION 1,17,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -119,13 +119,13 @@ BEGIN
VALUE "Comments", "Thanks to id Software for creating DOOM and then releasing the source code. Thanks also to TeamTNT for creating BOOM, which ZDoom is partially based on.\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "ZDoom\0"
VALUE "FileVersion", "1.17\0"
VALUE "FileVersion", "1.17b\0"
VALUE "InternalName", "ZDoom\0"
VALUE "LegalCopyright", "Copyright © 1999, id Software & Randy Heit\0"
VALUE "LegalTrademarks", "Doom® is a Registered Trademark of id Software, Inc.\0"
VALUE "OriginalFilename", "zdoom.exe\0"
VALUE "ProductName", "ZDoom\0"
VALUE "ProductVersion", "1.17\0"
VALUE "ProductVersion", "1.17b\0"
END
END
BLOCK "VarFileInfo"

View file

@ -394,6 +394,10 @@ SOURCE=.\g_level.c
# End Source File
# Begin Source File
SOURCE=.\gi.c
# End Source File
# Begin Source File
SOURCE=.\info.c
!IF "$(CFG)" == "zdoom - Win32 Release"
@ -1410,6 +1414,10 @@ SOURCE=.\g_level.h
# End Source File
# Begin Source File
SOURCE=.\gi.h
# End Source File
# Begin Source File
SOURCE=.\hu_stuff.h
# End Source File
# Begin Source File
@ -1741,8 +1749,20 @@ SOURCE=..\commands.txt
# End Source File
# Begin Source File
SOURCE=.\doominfo.lmp
# End Source File
# Begin Source File
SOURCE=.\hexninfo.lmp
# End Source File
# Begin Source File
SOURCE=".\docs\Rh-log.txt"
# End Source File
# Begin Source File
SOURCE=.\ticinfo.lmp
# End Source File
# End Group
# Begin Group "Win32 Files"
@ -1830,15 +1850,6 @@ SOURCE=.\win32\resource.h
# Begin Source File
SOURCE=.\win32\zdoom.rc
!IF "$(CFG)" == "zdoom - Win32 Release"
!ELSEIF "$(CFG)" == "zdoom - Win32 Debug"
!ELSEIF "$(CFG)" == "zdoom - Win32 Profiling"
!ENDIF
# End Source File
# End Group
# End Target

View file

@ -1,4 +1,4 @@
This is the source code for ZDoom 1.17a released on 21 February 1999.
This is the source code for ZDoom 1.17b released on 15 March 1999.
It is based on the Linux DOOM sources that were prepared by B. Krenheimer
and generously released by John Carmack shortly before Christmas, 1997. If
@ -88,7 +88,7 @@ If you want to recompile the DOS code, you need DJGPP and allegro. Allegro
is only needed because MIDAS uses its interrupt wrappers. I don't use it
for anything myself. The makefile.dj file can be used with make to
generate either a release or debug build. (Create the appropriate
subdirectories in the code/djgpp directory first.)
subdirectories under code/djgpp first.)
Randy Heit