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