CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

ROTBMP.CPP (11107B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/ROTBMP.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : ROTBMP.CPP                                                   *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 07/05/96                                                     *
     28  *                                                                                             *
     29  *                  Last Update : July 5, 1996 [JLB]                                           *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     34 
     35 #if (0)//PG
     36 //#include	"function.h"
     37 #include	"watcom.h"
     38 #include "rotbmp.h"
     39 #define FILE_H
     40 #define WWMEM_H
     41 #include	<wwlib32.h>
     42 
     43 
     44 int Rotate_Bitmap(GraphicViewPortClass * srcvp, GraphicViewPortClass * destvp, int angle);
     45 
     46 struct WPPOINT {
     47 	int x;
     48 	int y;
     49 };
     50 
     51 /***************************************************************************
     52  * Rotate_bitmap -- rotate a bitmap from srcvp to destvp                   *
     53  *                                                                         *
     54  * INPUT: note that angles are 0 - 255 (best if used in increments of 4!)  *
     55  *                                                                         *
     56  * OUTPUT:                                                                 *
     57  *                                                                         *
     58  * WARNINGS:                                                               *
     59  *	   destvp should be a square. width and height should be equal to : 	 	*
     60  * 	MAX(srcvp->width,srcvp->height) * 1.7 (square root of 2!!)    		 	*
     61  *																								 	*
     62  *																								 	*
     63  * HISTORY:                                                                *
     64  *   01/02/1996  BP : Created.                                             *
     65  *=========================================================================*/
     66 Rotate_Bitmap(GraphicViewPortClass * srcvp, GraphicViewPortClass * destvp, int a)
     67 {
     68 	int shift = 7;
     69 	int fixpoint1 = 1 << shift; // this is a fixed point 1
     70 	int Deltax;
     71 	int Deltay;
     72 	int sx,sy,dx,dy;
     73 	int Error = 0;
     74 	int Decimal = 0;
     75 	// this is used if I walk in Y
     76 	int buffwidth = srcvp->Get_Width() + srcvp->Get_XAdd();
     77 	int buffwid2 = destvp->Get_Width() + destvp->Get_XAdd();
     78 	char * dest;
     79 	char * src;
     80 	int sa,ca;
     81 	int t;
     82 	int x,y;
     83 	int rx,ry;
     84 	int w,h;
     85 	int dw = destvp->Get_Width();
     86 	int dh = destvp->Get_Height();
     87 	WPPOINT sp[4];
     88 	WPPOINT dp[4];
     89 	sa = Sin256[a];
     90 	ca = Cos256[a];
     91 	// get rectangle size
     92 	x = 0;
     93 	y = 0;
     94 	w = srcvp->Get_Width();
     95 	h = srcvp->Get_Height();
     96 
     97 	int halfws = w >> 1;
     98 	int halfhs = h >> 1;
     99 	int halfwd = dw >> 1;
    100 	int halfhd = dh >> 1;
    101 
    102 
    103 	// make the src rectangle
    104 	sp[0].x = x;
    105 	sp[0].y = y;
    106 
    107 	sp[1].x = x + w;
    108 	sp[1].y = y;
    109 
    110 	// now calculate the rotated rectangle
    111 	dp[0].x = ( ((sp[0].x - halfws) * ca) - ((sp[0].y - halfhs) * sa) ) >> shift;
    112 	dp[0].x += halfwd;
    113 
    114 	dp[0].y = ( ((sp[0].x - halfws) * sa) + ((sp[0].y - halfhs) * ca) ) >> shift;
    115 	dp[0].y += halfhd;
    116 
    117 	dp[1].x = ( ((sp[1].x - halfws) * ca) - ((sp[1].y - halfhs) * sa) ) >> shift;
    118 	dp[1].x += halfwd;
    119 
    120 	dp[1].y = ( ((sp[1].x - halfws) * sa) + ((sp[1].y - halfhs) * ca) ) >> shift;
    121 	dp[1].y += halfhd;
    122 
    123 	rx = dp[0].x;
    124 	ry = dp[0].y;
    125 	// now calculate slope
    126 
    127 	// diff from new to old x
    128 
    129 	Deltax = (dp[1].x - dp[0].x);
    130 
    131 	// diff from new to old y
    132 
    133 	Deltay = (dp[1].y - dp[0].y);
    134 
    135 	// handle the easy cases
    136 
    137 	// no change in x
    138 	int r;
    139 	if (!Deltax) { // must be 90 or 270 degree transpose!
    140 		if (Deltay < 0) {
    141 			// walk across source in the x + dir
    142 			// walk across dest in the y - dir
    143 
    144 			x = 0;
    145 			dy = 0;
    146 			dx = 0;
    147 			for (t = 0; t< h; t++) {
    148 				x = 0;
    149 				src = MAKE_PTR(srcvp, x, y);
    150 				dest = MAKE_PTR(destvp, rx + dx, ry - dy);
    151 				for (r = 0; r< w; r++) {
    152 					// transparency
    153 					if (* src)
    154 						*dest = *src;
    155 					src++;
    156 					dest -= buffwid2;
    157 				}
    158 				y++;
    159 				dx++;
    160 			}
    161 		} else {
    162 			// walk across source in the x + dir
    163 			// walk across dest in the y + dir
    164 
    165 			x = 0;
    166 			dy = 0;
    167 			dx = 0;
    168 			for (t = 0; t< h; t++) {
    169 				x = 0;
    170 				src = MAKE_PTR(srcvp, x, y);
    171 				dest = MAKE_PTR(destvp, rx - dx, ry + dy);
    172 				for (r = 0; r< w; r++) {
    173 					// transparency
    174 					if (*src)
    175 						*dest = *src;
    176 					src++;
    177 					dest += buffwid2;
    178 				}
    179 				y++;
    180 				dx++;
    181 			}
    182 		}
    183 		return 0;
    184 	}
    185 	// no change in y
    186 
    187 	if (!Deltay) { // must be 0 or 180 degree transpose !
    188 		if (Deltax < 0) {
    189 			y = 0;
    190 			for (y = 0; y< h; y++) {
    191 				x = 0;
    192 				src = MAKE_PTR(srcvp, x, y);
    193 				dest = MAKE_PTR(destvp, rx - x , ry - y);
    194 				for (x = 0 ; x< w; x++) {
    195 					// transparency
    196 					if (*src)
    197 						*dest = *src;
    198 					dest--;
    199 					src++;
    200 				}
    201 			}
    202 		} else {
    203 			for (y = 0; y< h; y++) {
    204 				x = 0;
    205 				src = MAKE_PTR(srcvp, x, y);
    206 				dest = MAKE_PTR(destvp, rx + x, ry + y);
    207 				for (x = 0 ; x< w; x++) {
    208 					// transparency
    209 					if (*src)
    210 						*dest = *src;
    211 					dest++;
    212 					src++;
    213 				}
    214 			}
    215 		}
    216 		return 0;
    217 	}
    218 
    219 
    220 	// ok now the hard part
    221 
    222 	// make them 16.16
    223 	if ( ABS(Deltax) < ABS(Deltay)) { // ok this means we want to walk in y
    224 
    225 		// walk in  + x in the src and
    226 		// walk in  + y in the dest
    227 		Error = 0;
    228 		// start at left top corner in src and dest
    229 
    230 		sx = 0;
    231 		sy = 0;
    232 
    233 		dx = 0;
    234 		dy = 0;
    235 
    236 		dest = MAKE_PTR(destvp, rx + dx, ry + dy);
    237 
    238 		src = MAKE_PTR(srcvp, x + sx, y + sy);
    239 
    240 		// this gets added to error each inc of x
    241 		// when error is > 1 then inc y!
    242 		int xinc = 1;
    243 		if (Deltax < 0) {
    244 			Deltax = -Deltax;
    245 			xinc = -1;
    246 		}
    247 		int yinc = 1;
    248 		int yinc1 = 1;
    249 		if (Deltay < 0) {
    250 			Deltay = - Deltay;
    251 			buffwid2 = - buffwid2;
    252 		}
    253 		Decimal = ( Deltax << shift) / Deltay ;
    254 		// walk in X
    255 
    256 		int Deltax2 = Deltax << shift;
    257 		int Deltay2 = Deltay << shift;
    258 
    259 		// this is the ratio between the source height and the dest height
    260 		// as the rectangle rotates the height and width change
    261 		int DeltaH = (w << shift) / Deltay;
    262 		int Error2 = 0;
    263 		sy = 0;
    264 		for (int r = 0; r< h ;r++) {
    265 			// now we walk across the top calculating each rotated point
    266 			// along the side
    267 			// the use delta formula to walk in x and y in destination space
    268 			// always walking in the x in the source!
    269 			// figure out rotated location to start in dest
    270 			rx = ( ( (sx - halfws) * ca) - ( (sy - halfhs) * sa) ) >> shift;
    271 			rx += halfwd;
    272 			ry = ( ( (sx - halfws) * sa) + ( (sy - halfhs) * ca) ) >> shift;
    273 			ry += halfhd;
    274 
    275 			// this is the end point of the line
    276 
    277 			int y2 = ( ( ((w) - halfws) * sa) + ( (sy - halfhs) * ca) ) >> shift;
    278 			y2 += halfhd;
    279 
    280 			// length of line
    281 
    282 			int diff = ABS(y2 - ry);
    283 
    284 			// if walking backwards reveres diff to reflect sign
    285 
    286 			src = MAKE_PTR(srcvp, x, y + sy);
    287 
    288 			dest = MAKE_PTR(destvp, rx, ry);
    289 
    290 			Error = 0;
    291 			Error2 = 0;
    292 			char * baseptr = src;
    293 			// while walking line
    294 			while (diff--) {
    295 				char c = *src;
    296 				// transparency
    297 				if (c)
    298 					*dest = *src;
    299 				Error2 += DeltaH;
    300 				dest += buffwid2;
    301 				Error += Decimal;
    302 				src = baseptr + (Error2 >> shift) ;
    303 				// this is time to inc x in src y in dest
    304 				if (Error >= fixpoint1) {
    305 					Error -= fixpoint1;
    306 					if (*src)
    307 						*dest = *src;
    308 					dest += xinc;
    309 				}
    310 			}
    311 			sy += yinc;
    312 		}
    313 		return 0;
    314 	} else { // else we walk in X
    315 		int lasterror = 0;
    316 		Error = 0;
    317 		// start at left top corner in src and dest
    318 
    319 		sx = 0;
    320 		sy = 0;
    321 
    322 		dx = 0;
    323 		dy = 0;
    324 
    325 		dest = MAKE_PTR(destvp, rx + dx, ry + dy);
    326 
    327 		src = MAKE_PTR(srcvp, x + sx, y + sy);
    328 
    329 		// this gets added to error each inc of x
    330 		// when error is > 1 then inc y!
    331 		int xinc = 1;
    332 		if (Deltax < 0) {
    333 			Deltax = -Deltax;
    334 			xinc = -1;
    335 		}
    336 		int yinc = 1;
    337 		if (Deltay < 0) {
    338 			Deltay = - Deltay;
    339 			buffwid2 = - buffwid2;
    340 			sy = sy + h - 1;
    341 			yinc = -1;
    342 		}
    343 
    344 
    345 		Decimal = ( Deltay << shift) / Deltax ;
    346 		// walk in X
    347 
    348 		int Deltax2 = Deltax << shift;
    349 		int Deltay2 = Deltay << shift;
    350 
    351 		// this is the ratios between the source width and the dest width
    352 		// as the rectangle rotates the actual size changes!
    353 
    354 		int DeltaW = (w << shift) / Deltax;
    355 		int Error2 = 0;
    356 		for (int r = 0; r< h ;r++) {
    357 			sx = 0;
    358 
    359 			// now we walk across the side calculating each rotated point
    360 			// along the side
    361 			// the use delta formula to walk in x and y in destination space
    362 			// always walking in the x in the source!
    363 			// figure out rotated location to start
    364 
    365 			rx = ( ( (sx - halfws) * ca) - ( (sy - halfhs) * sa) ) >> shift;
    366 			rx += halfwd;
    367 			ry = ( ( (sx - halfws) * sa) + ( (sy - halfhs) * ca) ) >> shift;
    368 			ry += halfhd;
    369 			// this is the other side of the box
    370 
    371 			int x2 = ( ( ((sx + w) - halfws) * ca) - ( (sy - halfhs) * sa) ) >> shift;
    372 
    373 			x2 += halfwd;
    374 
    375 			int diff = x2 - rx;
    376 
    377 
    378 			dx = 0;
    379 			dy = 0;
    380 
    381 			if (xinc == -1) {
    382 				diff = -diff;
    383 			}
    384 
    385 			src = MAKE_PTR(srcvp, x + sx, y + sy);
    386 
    387 			dest = MAKE_PTR(destvp, rx + dx, ry + dy);
    388 			Error = 0;
    389 			Error2 = 0;
    390 			char * baseptr = src;
    391 
    392 			while (diff--) {
    393 				char c = *src;
    394 				// transparency
    395 				if (c)
    396 					*dest = *src;
    397 				Error2 += DeltaW;
    398  				rx++;
    399 				dest += xinc;
    400 				Error += Decimal;
    401 				src = baseptr + (Error2 >> shift);
    402 				if (Error >= fixpoint1) {
    403 					Error -= fixpoint1;
    404 					if (*src)
    405 						*dest = *src;
    406 					dest += buffwid2;
    407 				}
    408 			}
    409 			sy += yinc;
    410 		}
    411 	}
    412 	return 0;
    413 }
    414 #endif