CnC_Remastered_Collection

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

SPRITE.CPP (10149B)


      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/SPRITE.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /**********************************************************************
     18 
     19 	Sprite.cpp
     20 
     21 	Dec 28,1995
     22 
     23 	GraphicBufferClass member functions for blitting, scaling,
     24 	and rotating bitmaps
     25 
     26 **********************************************************************/
     27 
     28 #ifndef WIN32
     29 class BitmapClass
     30 {
     31 	public:
     32 		BitmapClass(int w, int h, unsigned char * data) :
     33 			Width(w), Height(h), Data(data) {};
     34 
     35 		int Width;
     36 		int Height;
     37 		unsigned char * Data;
     38 };
     39 
     40 class TPoint2D
     41 {
     42 	public:
     43 		TPoint2D(int xx, int yy) : x(xx), y(yy) {};
     44 		TPoint2D(void) : x(0), y(0) {};
     45 
     46 		int x;
     47 		int y;
     48 };
     49 #endif
     50 
     51 
     52 //#include	"function.h"
     53 #define FILE_H
     54 #define RAWFILE_H
     55 #define WWMEM_H
     56 #define WWFILE_Hx
     57 #include	<wwlib32.h>
     58 #include <stdio.h>
     59 //#include "gbuffer.h"
     60 //#include "math.h"
     61 
     62 
     63 long _SineTab[256] = {
     64 0 ,6 ,12 , 18 , 25 , 31 , 37 , 43 , 49 , 56 , 62 , 68 , 74 , 80 , 86 ,
     65 92 , 97 , 103 , 109 , 115 , 120 , 126 , 131 , 136 , 142 , 147 , 152 ,
     66 157 , 162 , 167 , 171 , 176 , 180 , 185 , 189 , 193 , 197 , 201 , 205 ,
     67 209 , 212 , 216 , 219 , 222 , 225 , 228 , 231 , 233 , 236 , 238 , 240 ,
     68 243 , 244 , 246 , 248 , 249 , 251 , 252 , 253 , 254 , 254 , 255 , 255 ,
     69 255 , 255 , 255 , 255 , 255 , 254 , 254 , 253 , 252 , 251 , 249 , 248 ,
     70 246 , 245 , 243 , 241 , 238 , 236 , 234 , 231 , 228 , 225 , 222 , 219 ,
     71 216 , 213 , 209 , 205 , 201 , 198 , 194 , 189 , 185 , 181 , 176 , 172 ,
     72 167 , 162 , 157 , 152 , 147 , 142 , 137 , 131 , 126 , 120 , 115 , 109 ,
     73 104 , 98 , 92 , 86 , 80 , 74 , 68 , 62 , 56 , 50 , 44 , 37 , 31 , 25 ,
     74 19 , 12 , 6 , 0 , -5 , -12 , -18 , -24 , -30 , -37 , -43 , -49 , -55 ,
     75 -61 , -67 , -73 , -79 , -85 , -91 , -97 , -103 , -109 , -114 , -120 ,
     76 -125 , -131 , -136 , -141 , -147 , -152 , -157 , -162 , -166 , -171 ,
     77 -176 , -180 , -185 , -189 , -193 , -197 , -201 , -205 , -208 , -212 ,
     78 -215 , -219 , -222 , -225 , -228 , -231 , -233 , -236 , -238 , -240 ,
     79 -242 , -244 , -246 , -248 , -249 , -250 , -252 , -253 , -254 , -254 ,
     80 -255 , -255 , -255 , -255 , -255 , -255 , -255 , -254 , -254 , -253 ,
     81 -252 , -251 , -249 , -248 , -246 , -245 , -243 , -241 , -239 , -236 ,
     82 -234 , -231 , -228 , -226 , -223 , -219 , -216 , -213 , -209 , -206 ,
     83 -202 , -198 , -194 , -190 , -185 , -181 , -177 , -172 , -167 , -162 ,
     84 -158 , -153 , -148 , -142 , -137 , -132 , -126 , -121 , -115 , -110 ,
     85 -104 , -98 , -92 , -86 , -81 , -75 , -69 , -62 , -56 , -50 , -44 ,
     86 -38 , -32 , -25 , -19 , -13 , -7 ,
     87 };
     88 
     89 long _CosineTab[256] = {
     90 256 , 255 , 255 , 255 , 254 , 254 , 253 , 252 , 251 , 249 , 248 , 246 ,
     91 244 , 243 , 241 , 238 , 236 , 234 , 231 , 228 , 225 , 222 , 219 , 216 ,
     92 212 , 209 , 205 , 201 , 197 , 193 , 189 , 185 , 181 , 176 , 171 , 167 ,
     93 162 , 157 , 152 , 147 , 142 , 137 , 131 , 126 , 120 , 115 , 109 , 103 ,
     94 98 , 92 , 86 , 80 , 74 , 68 , 62 , 56 , 50 , 43 , 37 , 31 , 25 , 19 ,
     95 12 , 6 , 0 , -6 , -12 , -18 , -24 , -31 , -37 , -43 , -49 , -55 , -61 ,
     96 -68 , -74 , -80 , -86 , -91 , -97 , -103 , -109 , -114 , -120 , -125 , -131 ,
     97 -136 , -141 , -147 , -152 , -157 , -162 , -166 , -171 , -176 , -180 ,
     98 -185 , -189 , -193 , -197 , -201 , -205 , -209 , -212 , -216 , -219 , -222 ,
     99 -225 , -228 , -231 , -233 , -236 , -238 , -240 , -242 , -244 , -246 ,
    100 -248 , -249 , -251 , -252 , -253 , -254 , -254 , -255 , -255 , -255 ,
    101 -255 , -255 , -255 , -255 , -254 , -254 , -253 , -252 , -251 , -249 , -248 ,
    102 -246 , -245 , -243 , -241 , -239 , -236 , -234 , -231 , -228 , -225 ,
    103 -222 , -219 , -216 , -213 , -209 , -205 , -202 , -198 , -194 , -190 , -185 ,
    104 -181 , -176 , -172 , -167 , -162 , -157 , -152 , -147 , -142 , -137 , -132 ,
    105 -126 , -121 , -115 , -109 , -104 , -98 , -92 , -86 , -80 , -74 , -68 ,
    106 -62 , -56 , -50 , -44 , -38 , -31 , -25 , -19 , -13 , -6 , 0 , 5 , 11 ,
    107 18 , 24 , 30 , 36 , 43 , 49 , 55 , 61 , 67 , 73 , 79 , 85 , 91 , 97 , 103 ,
    108 108 , 114 , 120 , 125 , 131 , 136 , 141 , 146 , 151 , 156 , 161 , 166 ,
    109 171 , 176 , 180 , 184 , 189 , 193 , 197 , 201 , 205 , 208 , 212 , 215 ,
    110 219 , 222 , 225 , 228 , 231 , 233 , 236 , 238 , 240 , 242 , 244 , 246 ,
    111 248 , 249 , 250 , 252 , 253 , 253 , 254 , 255 , 255 , 255 ,
    112 };
    113 
    114 
    115 
    116 /***************************************************************
    117 *
    118 *	Scale_Rotate
    119 *
    120 *	FUNCTION:
    121 *
    122 *	Using Bi-Linear Interpolation, draws a scaled and rotated
    123 *	bitmap onto the buffer.  No clipping is performed so beware.
    124 *
    125 *	INPUTS
    126 *
    127 *	bmp		- bitmap to draw
    128 *	pt			- desired position of the center
    129 *	scale		- 24.8 fixed point scale factor
    130 *	angle		- 8bit angle (0=0deg, 255=360deg)
    131 *
    132 ***************************************************************/
    133 
    134 void GraphicBufferClass::Scale_Rotate(BitmapClass &bmp,TPoint2D const &pt,long scale,unsigned char angle)
    135 {
    136 	unsigned int scrpos;
    137 	unsigned int temp;
    138 
    139 	int i,j;			// counter vars
    140 	int pxerror	=0;		// these three vars will be used in an
    141 	int pyerror	=0;		// integer difference alg to keep track
    142 	int pixpos	=0;		// of what pixel to draw.
    143 	unsigned char pixel;
    144 
    145 	TPoint2D p0;	// "upper left" corner of the rectangle
    146 	TPoint2D p1;	// "upper right" corner of the rectangle
    147 	TPoint2D p2;	// "lower left" corner of the rectangle
    148 
    149 	/*-------------------------------------------------
    150 		Compute three corner points of the rectangle
    151 	-------------------------------------------------*/
    152 	{
    153 		angle &= 0x0FF;
    154 		long c = _CosineTab[angle];
    155  		long s = _SineTab[angle];
    156 		long W = (scale*bmp.Width)>>1;
    157 		long L = (scale*bmp.Height)>>1;
    158 
    159 		p0.x = (pt.x + ((( (L*c) >> 8)-((W*s) >> 8)) >> 8));
    160 		p0.y = (pt.y + (((-(L*s) >> 8)-((W*c) >> 8)) >> 8));
    161 		p1.x = (pt.x + ((( (L*c) >> 8)+((W*s) >> 8)) >> 8));
    162 		p1.y = (pt.y + (((-(L*s) >> 8)+((W*c) >> 8)) >> 8));
    163 		p2.x = (pt.x + (((-(L*c) >> 8)-((W*s) >> 8)) >> 8));
    164 		p2.y = (pt.y + ((( (L*s) >> 8)-((W*c) >> 8)) >> 8));
    165 	}
    166 
    167 	/*-----------------------------------
    168 		Initialize Breshnam constants
    169 	-----------------------------------*/
    170 
    171 	// This breshnam line goes across the FRONT of the rectangle
    172 	// In the bitmap, this will step from left to right
    173 
    174 	int f_deltax	=(p1.x-p0.x);
    175 	int f_deltay	=(p1.y-p0.y);
    176 	int f_error		=0;
    177 	int f_xstep		=1;
    178 	int f_ystep		=Width;
    179 
    180 	// This breshnam line goes down the SIDE of the rectangle
    181 	// In the bitmap, this line will step from top to bottom
    182 
    183 	int s_deltax	=(p2.x-p0.x);
    184 	int s_deltay	=(p2.y-p0.y);
    185 	int s_error		=0;
    186 	int s_xstep		=1;
    187 	int s_ystep		=Width;
    188 
    189 	/*--------------------------------
    190 		fixup deltas and step values
    191 	--------------------------------*/
    192 
    193 	if (f_deltay<0) {
    194 		f_deltay=-f_deltay;
    195 		f_ystep=-Width;
    196 	};
    197 
    198 	if (f_deltax<0) {
    199 		f_deltax=-f_deltax;
    200 		f_xstep=-1;
    201 	};
    202 
    203 	if (s_deltay<0) {
    204 		s_deltay=-s_deltay;
    205 		s_ystep=-Width;
    206 	};
    207 
    208 	if (s_deltax<0) {
    209 		s_deltax=-s_deltax;
    210 		s_xstep=-1;
    211 	};
    212 
    213 	scrpos=p0.x+Width*p0.y; 	//address of initial screen pos.
    214 	temp=scrpos;
    215 
    216 	/*---------------------------------------------------------------------
    217 		Now all of the differences, errors, and steps are set up so we can
    218 		begin drawing the bitmap...
    219 
    220 		There are two cases here,
    221 		1 - the "Front" line has a slope of <  1.0 (45 degrees)
    222 		2 - the "Front" line has a slope of >= 1.0
    223 
    224 		For case 1, we step along the X direction, for case 2, step in y
    225 	---------------------------------------------------------------------*/
    226 
    227 	if (f_deltax>f_deltay) {		//CASE 1, step front in X, side in Y
    228 
    229 		// outer loop steps from top to bottom of the rectangle
    230 		for (j=0;j<s_deltay;j++)
    231 		{
    232 			temp=scrpos;
    233 
    234 			// The inner loop steps across the rectangle
    235 			for (i=0;i<f_deltax;i++)
    236 			{
    237 				pixel=bmp.Data[pixpos];				//read pixel
    238 				if (pixel) ((unsigned char *)Get_Buffer())[scrpos]=pixel;	//draw if not transparent
    239 //				if (pixel) Data[scrpos]=pixel;	//draw if not transparent
    240 				pxerror+=bmp.Width;		 			//update position in bitmap
    241 				while (pxerror>f_deltax)
    242 				{
    243 					pixpos++;
    244 					pxerror-=f_deltax;
    245 				};
    246 				scrpos+=f_xstep;						//step to next screen pos
    247 				f_error+=f_deltay;
    248 				if (f_error>f_deltax)
    249 				{
    250 					if (pixel) ((unsigned char *)Get_Buffer())[scrpos]=pixel;
    251 					f_error-=f_deltax;
    252 					scrpos+=f_ystep;
    253 				};
    254 			};
    255 			pxerror=0;
    256 			pixpos-=bmp.Width-1;
    257 			pyerror+=bmp.Height;
    258 
    259 			while (pyerror>s_deltay)
    260 			{
    261 				pixpos+=bmp.Width;
    262 				pyerror-=s_deltay;
    263 			};
    264 
    265 			f_error=0;
    266 			scrpos=temp;
    267 			scrpos+=s_ystep;
    268 			s_error+=s_deltax;
    269 
    270 			if (s_error>s_deltay)
    271 			{
    272 				s_error-=s_deltay;
    273 				scrpos+=s_xstep;
    274 			};
    275 		}
    276 
    277 	} else {		// CASE 2, Step front line in X, side line in Y
    278 
    279 		// outer loop steps from top to bottom of the rectangle
    280 		for (j=0;j<s_deltax;j++)
    281 		{
    282 			temp=scrpos;
    283 
    284 			// The inner loop steps across the rectangle
    285 			for (i=0;i<f_deltay;i++)
    286 			{
    287 				pixel=bmp.Data[pixpos];				//read pixel
    288 				if (pixel) ((unsigned char *)Get_Buffer())[scrpos]=pixel;	//draw if not transparent
    289 				pxerror+=bmp.Width;					//update position in bitmap
    290 				while (pxerror>f_deltay)
    291 				{
    292 					pixpos++;
    293 					pxerror-=f_deltay;
    294 				};
    295 
    296 				scrpos+=f_ystep;						//step to next screen pos
    297 				f_error+=f_deltax;
    298 				if (f_error>f_deltay)
    299 				{
    300 					if (pixel) ((unsigned char *)Get_Buffer())[scrpos]=pixel;
    301 					f_error-=f_deltay;
    302 					scrpos+=f_xstep;
    303 				};
    304 			};
    305 
    306 			pxerror=0;
    307 			pixpos-=bmp.Width-1;
    308 			pyerror+=bmp.Height;
    309 			while (pyerror>s_deltax)
    310 			{
    311 				pixpos+=bmp.Width;
    312 				pyerror-=s_deltax;
    313 			};
    314 
    315 			scrpos=temp;
    316 			scrpos+=s_xstep;
    317 			s_error+=s_deltay;
    318 			f_error=0;
    319 			if (s_error>s_deltax)
    320 			{
    321 				s_error-=s_deltax;
    322 				scrpos+=s_ystep;
    323 			};
    324 		}
    325 	}
    326 }