DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

f_wipe.cpp (5091B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 #include "z_zone.h"
     33 #include "i_video.h"
     34 #include "i_system.h"
     35 #include "v_video.h"
     36 #include "m_random.h"
     37 #include "doomdef.h"
     38 #include "f_wipe.h"
     39 
     40 //
     41 //                       SCREEN WIPE PACKAGE
     42 //
     43 
     44 // when zero, stop the wipe
     45 
     46 
     47 void
     48 wipe_shittyColMajorXform
     49 ( short*	array,
     50   int		width,
     51   int		height )
     52 {
     53     int		x;
     54     int		y;
     55     short*	dest;
     56 
     57     //dest = (short*) DoomLib::Z_Malloc(width*height*2, PU_STATIC, 0 );
     58 	dest = new short[ width * height ];
     59 
     60     for(y=0;y<height;y++)
     61 		for(x=0;x<width;x++)
     62 			dest[x*height+y] = array[y*width+x];
     63 
     64     memcpy(array, dest, width*height*2);
     65 
     66     //Z_Free(dest);
     67 	delete[] dest;
     68 }
     69 
     70 
     71 int
     72 wipe_initMelt
     73 ( int	width,
     74   int	height,
     75   int	ticks )
     76 {
     77     int i, r;
     78     
     79     // copy start screen to main screen
     80     memcpy(::g->wipe_scr, ::g->wipe_scr_start, width*height);
     81     
     82     // makes this wipe faster (in theory)
     83     // to have stuff in column-major format
     84     wipe_shittyColMajorXform((short*)::g->wipe_scr_start, width/2, height);
     85     wipe_shittyColMajorXform((short*)::g->wipe_scr_end, width/2, height);
     86     
     87     // setup initial column positions
     88     // (::g->wipe_y<0 => not ready to scroll yet)
     89     ::g->wipe_y = (int *) DoomLib::Z_Malloc(width*sizeof(int), PU_STATIC, 0);
     90 
     91     ::g->wipe_y[0] = -(M_Random()%16);
     92 
     93 	for (i=1;i<width;i++)
     94 	{
     95 		r = (M_Random()%3) - 1;
     96 
     97 		::g->wipe_y[i] = ::g->wipe_y[i-1] + r;
     98 
     99 		if (::g->wipe_y[i] > 0)
    100 			::g->wipe_y[i] = 0;
    101 		else if (::g->wipe_y[i] == -16)
    102 			::g->wipe_y[i] = -15;
    103 	}
    104 
    105     return 0;
    106 }
    107 
    108 int wipe_doMelt( int width, int height, int ticks ) {
    109 	int		i;
    110 	int		j;
    111 	int		dy;
    112 	int		idx;
    113 
    114 	short*	s;
    115 	short*	d;
    116 	qboolean	done = true;
    117 
    118 	width/=2;
    119 
    120 	while (ticks--)
    121 	{
    122 		for (i=0;i<width;i++)
    123 		{
    124 			if (::g->wipe_y[i]<0) {
    125 
    126 				::g->wipe_y[i]++;
    127 				done = false;
    128 			}
    129 			else if (::g->wipe_y[i] < height) {
    130 
    131 				dy = (::g->wipe_y[i] < 16 * GLOBAL_IMAGE_SCALER) ? ::g->wipe_y[i]+1 : 8 * GLOBAL_IMAGE_SCALER;
    132 
    133 				if (::g->wipe_y[i]+dy >= height)
    134 					dy = height - ::g->wipe_y[i];
    135 
    136 				s = &((short *)::g->wipe_scr_end)[i*height+::g->wipe_y[i]];
    137 				d = &((short *)::g->wipe_scr)[::g->wipe_y[i]*width+i];
    138 
    139 				idx = 0;
    140 				for (j=dy;j;j--)
    141 				{
    142 					d[idx] = *(s++);
    143 					idx += width;
    144 				}
    145 
    146 				::g->wipe_y[i] += dy;
    147 
    148 				s = &((short *)::g->wipe_scr_start)[i*height];
    149 				d = &((short *)::g->wipe_scr)[::g->wipe_y[i]*width+i];
    150 
    151 				idx = 0;
    152 				for (j=height-::g->wipe_y[i];j;j--)
    153 				{
    154 					d[idx] = *(s++);
    155 					idx += width;
    156 				}
    157 
    158 				done = false;
    159 			}
    160 		}
    161 	}
    162 
    163 	return done;
    164 }
    165 
    166 int
    167 wipe_exitMelt
    168 ( int	width,
    169   int	height,
    170   int	ticks )
    171 {
    172     Z_Free(::g->wipe_y);
    173 	::g->wipe_y = NULL;
    174     return 0;
    175 }
    176 
    177 int
    178 wipe_StartScreen
    179 ( int	x,
    180   int	y,
    181   int	width,
    182   int	height )
    183 {
    184     ::g->wipe_scr_start = ::g->screens[2];
    185     I_ReadScreen(::g->wipe_scr_start);
    186     return 0;
    187 }
    188 
    189 int
    190 wipe_EndScreen
    191 ( int	x,
    192   int	y,
    193   int	width,
    194   int	height )
    195 {
    196     ::g->wipe_scr_end = ::g->screens[3];
    197     I_ReadScreen(::g->wipe_scr_end);
    198     V_DrawBlock(x, y, 0, width, height, ::g->wipe_scr_start); // restore start scr.
    199     return 0;
    200 }
    201 
    202 int
    203 wipe_ScreenWipe
    204 ( int	x,
    205   int	y,
    206   int	width,
    207   int	height,
    208   int	ticks )
    209 {
    210 	int rc;
    211 
    212 	// initial stuff
    213 	if (!::g->go)
    214 	{
    215 		::g->go = 1;
    216 		::g->wipe_scr = ::g->screens[0];
    217 
    218 		wipe_initMelt(width, height, ticks);
    219 	}
    220 
    221 	// do a piece of wipe-in
    222 	V_MarkRect(0, 0, width, height);
    223 
    224 	rc = wipe_doMelt(width, height, ticks);
    225 
    226 	// final stuff
    227 	if (rc)
    228 	{
    229 		::g->go = 0;
    230 		wipe_exitMelt(width, height, ticks);
    231 	}
    232 
    233 	return !::g->go;
    234 }
    235