⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f_wipe.c

📁 游戏类程序源代码---WinDoom 3D源程序.zip
💻 C
字号:
// 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:
//	Mission begin melt/wipe screen special effect.
//
//-----------------------------------------------------------------------------


static const char rcsid[] = "$Id: f_wipe.c,v 1.2 1997/02/03 22:45:09 b1 Exp $";



#include "z_zone.h"
#include "i_video.h"
#include "v_video.h"
#include "m_random.h"

#include "doomdef.h"

#include "f_wipe.h"

void WriteDebug(char *);

//
//                       SCREEN WIPE PACKAGE
//

// when zero, stop the wipe
static boolean	go = 0;

//static byte*	wipe_scr_start;
//static byte*	wipe_scr_end;
//static byte*	wipe_scr;

void
wipe_shittyColMajorXform
( short*	array,
  int		width,
  int		height )
{
    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,
  /*DQ*/
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)
{
	// DQ start
	// buffer width may not equal buffer pitch
	int y;
	BYTE * RBuffer;
	long * RYLookup;
	BYTE * StartBuffer;
	long * StartYLookup;

	RBuffer = RenderBuffer->Buffer;
	RYLookup = RenderBuffer->YLookup;
	StartBuffer = WipeStartBuffer->Buffer;
	StartYLookup = WipeStartBuffer->YLookup;
	for (y=0; y < height; y++)
	{
		memcpy(RBuffer + RYLookup[y], StartBuffer + StartYLookup[y], width);
	}
	// DQ end
   // memcpy(wipe_scr, wipe_scr_start, width*height); // original
    return 0;
}

int
wipe_doColorXForm
( int	width,
  int	height,
  int	ticks,
  /*DQ*/
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)
{
    boolean	changed;
    byte*	w;
    byte*	e;
    int		newval;
	 // DQ start
	 int x, y;
	 BYTE * RBuffer;
	 long * RYLookup;
	 BYTE * EndBuffer;
	 long * EndYLookup;

	 RBuffer = RenderBuffer->Buffer;
	 RYLookup = RenderBuffer->YLookup;
	 EndBuffer = WipeEndBuffer->Buffer;
	 EndYLookup = WipeEndBuffer->YLookup;
	 // DQ end

    changed = false;
    //w = wipe_scr;
    //e = wipe_scr_end;
    
	 for (y = 0; y < height; y++) // DQ
	 {
	   w = RBuffer + RYLookup[y];
		e = EndBuffer + EndYLookup[y];
		for (x = 0; x < width; x++)
		//while (w!=wipe_scr+width*height)
		{
			if (*w != *e)
			{
				if (*w > *e)
				{
					newval = *w - ticks;
					if (newval < *e)
						*w = *e;
					else
						*w = newval;
					changed = true;
				}
				else if (*w < *e)
				{
					newval = *w + ticks;
					if (newval > *e)
						*w = *e;
					else
						*w = newval;
					changed = true;
				}
			}
			w++;
			e++;
		}
	 }
    return !changed;

}

int
wipe_exitColorXForm
( int	width,
  int	height,
  int	ticks,
  /*DQ*/
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)
{
    return 0;
}


static int*	yArray;	// renamed by DQ
//static int*	y;

// DQ changed the init melt to support stereoscopic views
//int
//wipe_initMelt
//( int	width,
//  int	height,
//  int	ticks )
//{
//    int i, r;
//    
//    // copy start screen to main screen
//    memcpy(wipe_scr, wipe_scr_start, width*height);
//    
//    // makes this wipe faster (in theory)
//    // to have stuff in column-major format
//    wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
//    wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
//    
//    // setup initial column positions
//    // (y<0 => not ready to scroll yet)
//    y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
//    y[0] = -(M_Random()%16);
//    for (i=1;i<width;i++)
//    {
//	r = (M_Random()%3) - 1;
//	y[i] = y[i-1] + r;
//	if (y[i] > 0) y[i] = 0;
//	else if (y[i] == -16) y[i] = -15;
//    }
//
//    return 0;
//}

// DQ start addition
int
wipe_initMelt
( int	width,
  int	height,
  int	ticks,
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)
{
	int i, r;

	// makes this wipe faster (in theory)
	// to have stuff in column-major format
	// DQ - I removed this step.  The images change between frames (left vs. right)
	// and I don't want to assume that they have changed orientation
	//wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
	//wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
	// setup initial column positions
	// (y<0 => not ready to scroll yet)
	yArray = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
	yArray[0] = -(M_Random()%16);
	for (i=1;i<width;i++)
	{
		r = (M_Random()%3) - 1;
		yArray[i] = yArray[i-1] + r;
		if (yArray[i] > 0) yArray[i] = 0;
		else if (yArray[i] == -16) yArray[i] = -15;
	}

	return 0;
}
// DQ end addition

//int
//wipe_doMelt
//( int	width,
//  int	height,
//  int	ticks )
//{
//    int		i;
//    int		j;
//    int		dy;
//    int		idx;
//    
//    short*	s;
//    short*	d;
//    boolean	done = true;
//
//    width/=2;
//
//    while (ticks--)
//    {
//	for (i=0;i<width;i++)
//	{
//	    if (y[i]<0)
//	    {
//		y[i]++; done = false;
//	    }
//	    else if (y[i] < height)
//	    {
//		dy = (y[i] < 16) ? y[i]+1 : 8;
//		if (y[i]+dy >= height) dy = height - y[i];
//		s = &((short *)wipe_scr_end)[i*height+y[i]];
//		d = &((short *)wipe_scr)[y[i]*width+i];
//		idx = 0;
//		for (j=dy;j;j--)
//		{
//		    d[idx] = *(s++);
//		    idx += width;
//		}
//		y[i] += dy;
//		s = &((short *)wipe_scr_start)[i*height];
//		d = &((short *)wipe_scr)[y[i]*width+i];
//		idx = 0;
//		for (j=height-y[i];j;j--)
//		{
//		    d[idx] = *(s++);
//		    idx += width;
//		}
//		done = false;
//	    }
//	}
//    }
//
//    return done;
//
//}
// DQ start addition
int
wipe_doMelt
( int	width,
  int	height,
  int	ticks,
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)
{
	int		x;
	int		y;
	DWORD		*s;
	DWORD		*d;
	boolean	done = true;
	int		speedupfactor = 1;
	BYTE * RBuffer;
	long * RYLookup;
	BYTE * StartBuffer;
	long * StartYLookup;
	BYTE * EndBuffer;
	long * EndYLookup;

	RBuffer = RenderBuffer->Buffer;
	RYLookup = RenderBuffer->YLookup;
	StartBuffer = WipeStartBuffer->Buffer;
	StartYLookup = WipeStartBuffer->YLookup;
	EndBuffer = WipeEndBuffer->Buffer;
	EndYLookup = WipeEndBuffer->YLookup;

// DQFIXME - rearrange the loops, doing Y on outer, X on inside
	// we want the wipe rate to be about the same as it would be at 320x200.  increase
	// the amount that we wipe downward to compensate.
	speedupfactor = (width * height) / (320L * 200L);
	if (speedupfactor < 1)
	{
		speedupfactor = 1;
	}
	width /= sizeof(*s);

	for (x=0;x<width;x++)
	{
		if (yArray[x] > 0 && yArray[x] <= height)
		{
			// copy the end screen - the screen that appears behind the wipe
			for (y=0;y< yArray[x];y++)
			{
				s = (DWORD *)EndBuffer + (EndYLookup[y])/sizeof(*s) + x;
				d = (DWORD *)RBuffer + (RYLookup[y])/sizeof(*s) + x;
				*d = *s;
			}
			// copy the start image - the part that wipes down
			for (y=yArray[x]; y < height;y++)
			{
				s = (DWORD *)StartBuffer + (StartYLookup[y - yArray[x]])/sizeof(*s) + x;	// DQ
				d = (DWORD *)RBuffer + (RYLookup[y])/sizeof(*s) + x;	// DQ
				*d = *s;
			}
			if (yArray[x] < height)
				done = false;
		}

		// move down the screen
		if (bAdvance)
		{
			// speed up to approximate the wipe rate of 320 x 200
			yArray[x] += (yArray[x] < 8 ? 1 : 8) * speedupfactor;
			if (yArray[x] > height) 
			{
				yArray[x] = height;
			}
			if (yArray[x] < height)
			{
				done = false;
			}
		}
	}

	return done;
}
// DQ end addition

int
wipe_exitMelt
( int	width,
  int	height,
  int	ticks,
  /*DQ*/
  BOOL bAdvance,
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer)

{
    Z_Free(yArray);
    return 0;
}

int
wipe_StartScreen
( int	x,
  int	y,
  int	width,
  int	height,
  PBUFFER WipeStartBuffer, // DQ
  PBUFFER DisplayBuffer // DQ
  )
{
    //wipe_scr_start = screens[2];		// DQ removed
    //I_ReadScreen(wipe_scr_start);		// DQ removed
    I_ReadScreen(WipeStartBuffer, DisplayBuffer);
    return 0;
}

// DQ start addition

void ScreensSwap(byte * ScreenA, byte * ScreenB)
{
	// swap DWORD at a time, to speed up the operation.  All screen sizes are multiples of 4
	// so this will not miss any data
	DWORD dwBucket;
	DWORD * lpdwSource;
	DWORD * lpdwDest;
	long	lCounter;

	lpdwSource = (DWORD *)ScreenA;
	lpdwDest = (DWORD *)ScreenB;

	for (lCounter = 0; lCounter < SCREENWIDTH * SCREENHEIGHT; lCounter += sizeof(DWORD))
	{
		dwBucket = *lpdwDest;
		*lpdwDest = *lpdwSource;
		*lpdwSource = dwBucket;
		lpdwDest++;
		lpdwSource++;
	}
}

int
wipe_RightEndScreen
(PBUFFER RightEndScreen/*DQ*/,
 PBUFFER DisplayBuffer/*DQ*/)
{
    I_ReadScreen(RightEndScreen/*DQ*/, DisplayBuffer/*DQ*/);
    return 0;
}
// DQ end addition

int
wipe_EndScreen
( int	x,
  int	y,
  int	width,
  int	height,
  PBUFFER WipeEndBuffer/*DQ*/,
  PBUFFER DisplayBuffer/*DQ*/)
{
    //wipe_scr_end = screens[3];
    //I_ReadScreen(wipe_scr_end);
    //V_DrawBlock(x, y, RenderBuffer/*DQ 0*/, DestYLookup/*DQ*/, width, height, wipe_scr_start); // restore start scr.
	// DQ start
    I_ReadScreen(WipeEndBuffer/*DQ*/, DisplayBuffer/*DQ*/);
// DQFIXME - why is this needed?
//    V_DrawBlock(x, y, RenderBuffer/*DQ 0*/, width, height, WipeStartBuffer); // restore start scr.
	 // DQ end
    return 0;
}

int
wipe_ScreenWipe
( int	wipeno,
  int	x,
  int	y,
  int	width,
  int	height,
  int	ticks
  // DQ start addition
  , BOOL bAdvance,		// first of the two eyes
  PBUFFER RenderBuffer,
  PBUFFER WipeStartBuffer,
  PBUFFER WipeEndBuffer
  // DQ end addition
  )
{
    int rc;
    static int (*wipes[])(int, int, int, BOOL/*DQ*/, PBUFFER/*DQ*/, PBUFFER/*DQ*/, PBUFFER/*DQ*/) =
    {
	wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
	wipe_initMelt, wipe_doMelt, wipe_exitMelt
    };

    void V_MarkRect(int, int, int, int);

    // initial stuff
    if (!go)
    {
	go = 1;  // original line
	// wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
	//wipe_scr = screens[0];		// DQ removed
	(*wipes[wipeno*3])(width, height, ticks, bAdvance, 
							RenderBuffer,
							WipeStartBuffer,
							WipeEndBuffer);//DQ
	//(*wipes[wipeno*3])(width, height, ticks, bAdvance,);
    }

    // do a piece of wipe-in
    V_MarkRect(0, 0, width, height);
    rc = (*wipes[wipeno*3+1])(width, height, ticks, bAdvance,
							RenderBuffer,
							WipeStartBuffer,
							WipeEndBuffer);//DQ
    //rc = (*wipes[wipeno*3+1])(width, height, ticks, bAdvance);
    //  V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG

    // final stuff
    if (rc && bAdvance /* DQ */)
    {
	go = 0;
	(*wipes[wipeno*3+2])(width, height, ticks, bAdvance,
							RenderBuffer,
							WipeStartBuffer,
							WipeEndBuffer);//DQ
	//(*wipes[wipeno*3+2])(width, height, ticks, bAdvance);
    }

    return !go;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -