Ejemplo n.º 1
0
void draw_line(fixedPointCoord start, fixedPointCoord end) {
	fixedPoint dx = end.x - start.x;
	fixedPoint dy = end.y - start.y;
	//pick the mode that will increment along the correct dimension
	if (absint(dx) >= absint(dy)) {
		//we are now incrementing along the x direction
		line_algorithm(start, end, 0);
	} else {
		fixedPointCoord start_t;
		fixedPointCoord end_t;
		start_t.x = start.y;
		start_t.y = start.x;
		end_t.x = end.y;
		end_t.y = end.x;
		//we use the transpose indicator to flip the algorithm to increment along the y direction
		line_algorithm(start_t, end_t, 1);
	}
}
Ejemplo n.º 2
0
//-----------------------------------------
// devuelve la distancia entre dos angulos.
//----------------------------------------- 
s32 distAngle(s32 s1, s32 s2){
	s32 temp;
	if (s2 >= s1)
		temp = s2 - s1;
	else
		temp = s1 - s2;
	if (temp > 30) temp -= 360;
	return absint(temp);
}//fin de la función.
Ejemplo n.º 3
0
//subpixel line drawing is pretty: http://www.antigrain.com/doc/introduction/introduction.agdoc.html (Bresenham's)
void line_algorithm(fixedPointCoord start, fixedPointCoord end, int8_t transpose) {
//transpose make x and y be flipped when written (for incrementing in the y direction
	//initialise and draw the first pointcurrent
	fixedPoint dx = end.x - start.x;
	fixedPoint dy = end.y - start.y;
	fixedPoint d = fip(dy)/dx; //be careful of divides and multiplies
	uintCoord current; //records the current pixel we are writing to
	if (end.x < start.x) {
		fixedPointCoord tmp = start;
		start = end;
		end = tmp;
		d=(-1)*d;
	}
	
	current.x = roundfip(start.x);
	fixedPoint yf = start.y + roundfip(d * (fip(current.x) - start.x)); //because of multiplying, we have to take a layer of fipping off - roundfip does this
	current.y = roundfip(yf);
	yf = yf - fip(current.y);
	LCD_set_pixel_tr(current, transpose);
	
	//make sure the iteration goes the right way
	int y_dir = 1;
	if (end.y < start.y) {
		y_dir = -1;
		yf = -1 * yf; //we will be only be incrementing Yf as it it simply a reference to proportion through the pixel we are. If we are moving negatively through y, we should move yf to the other end of its range
	}
	while (fip(current.x) < (end.x - fip(0.5))) {
		current.x += 1;
		yf += absint(d);
		if (yf > fip(0.5)) {
			current.y += y_dir;
			yf -= fip(1);
		}
		LCD_set_pixel_tr(current, transpose);
	}
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------------
// Esta función nos permite pintar los muros que forman parte del mapa definido.
//------------------------------------------------------------------------------
void renderWalls(){
	u32		loop;		
	s16		curAngle;
	s32		gridX;		// coordenada X en el mapa
	s32		gridY;		// coordenada Y en el MAPA
	u16*	destBuffer = videoBuffer; // apunta al buffer donde se pintan los muros.
	u8		x,y;		
	
	double	horzLength; // distancia al muro en horizontal (desde el pto de perpectiva del tio que anda.)
	double	vertLength; // distancia al muro en vertical (desde el pto de perpectiva del tio que anda.)
	double*	minLength;	
	u32		lineLength;	

	char darkgray = 0;	// vertical --> darkgray, horzontal --> lightgray

	double	fdistNextX;
	double	fdistNextY;
	int		ndistNextX; 
	int		ndistNextY;

	int		horzY;
	double  horzX;
	int		vertX;
	double	vertY; 

	curAngle = nPlayerAngle + 30;		// angulo de inicio.
	if (curAngle >= 360) curAngle -= 360;

	// 4 = SCREENWIDTH / 64 (TILEHEIGHT)
	for (loop = 0; loop < SCREENWIDTH; loop+=4) {
		// calcula la distancia horizontal.
		if (curAngle == 0 || curAngle == 180){
			// no hay un muro en la dirección horizontal
			horzLength = 9999999.00;
		}
		else{
			if (curAngle < 180){
				horzY = (nPlayerY/64) * 64; 
				ndistNextY = -64;
				double amountChange = ((s32) (horzY - nPlayerY) ) * tableINVTAN[curAngle];
				if (curAngle < 90 || curAngle > 270){
					if (amountChange < 0) amountChange *= -1;
				}
				else {
					if (amountChange > 0) amountChange *= -1;
				}
				horzX = nPlayerX + amountChange; 
				horzY--;
			}
			else {
				horzY = (nPlayerY/64) * 64 + 64; 
				ndistNextY = 64; 
				double amountChange = ((s32)(horzY - nPlayerY)) * tableINVTAN[curAngle];
				if (curAngle < 90 || curAngle > 270){
					if (amountChange < 0) amountChange *= -1; // should be pos
				}
				else {
					if (amountChange > 0) amountChange *= -1;
				}
				horzX = nPlayerX + amountChange;
			}
			fdistNextX = (64.00 * tableINVTAN[curAngle]);
			if ( (curAngle < 90) || (curAngle>270) ){
				if (fdistNextX < 0) fdistNextX *= -1;		// distancia positiva al siguiente bloque
			}
			else{
				if (fdistNextX > 0) fdistNextX *= -1;		// distancia negativa al siguiente bloque
			}

			while (true){
				gridX = (s32)(horzX / 64);
				gridY = (s32)(horzY / 64);
				if (gridX >= MAPWIDTH || gridY >= MAPHEIGHT || gridX < 0 || gridY < 0)
				{
					horzLength = 9999999.00;
					break;
				}
				else if (fMap[gridX+gridY*MAPHEIGHT])
				{
					horzLength = (horzX - nPlayerX) * tableINVCOS[curAngle];
					break;
				}
				horzX += fdistNextX;
				horzY += ndistNextY;
			}
		}
		// calcula la distancia vertical.
		if (curAngle == 90 || curAngle == 270){
			vertLength = 9999999.00;
		}
		else{
			if (curAngle < 90 || curAngle > 270){
				vertX = (nPlayerX/64) * 64 + 64;
				ndistNextX = 64;
				double amountChange = tableTAN[curAngle]*((s32)(vertX-nPlayerX));
				if (curAngle < 180){
					if (amountChange > 0) amountChange *= -1;
				}
				else
				{
					if (amountChange < 0) amountChange *= -1;
				}
				vertY = nPlayerY + amountChange; 
			}
			else{
				vertX = (nPlayerX/64) * 64; 
				ndistNextX = -64;			
				double amountChange = tableTAN[curAngle]*((s32)(vertX-nPlayerX));
				if (curAngle < 180){
					if (amountChange > 0) amountChange *= -1;
				}
				else{
					if (amountChange < 0) amountChange *= -1;
				}
				vertY = nPlayerY + amountChange; 
				vertX--;
			}
			fdistNextY = 64.00 * tableTAN[curAngle]; 
			if (curAngle < 180) {
				if (fdistNextY > 0) fdistNextY *= -1;
			}
			else{
				if (fdistNextY < 0) fdistNextY *= -1;
			}

			while (true){
				gridX = (s32)(vertX / 64);
				gridY = (s32)(vertY / 64);
				if (gridX >= MAPWIDTH || gridY >= MAPHEIGHT || gridX < 0 || gridY < 0)
				{
					vertLength = 9999999.00;
					break;
				}
				else if (fMap[gridX+gridY*MAPHEIGHT])
				{
					vertLength = (vertY - nPlayerY) * tableINVSIN[curAngle];
					break;
				}
				vertX += ndistNextX;
				vertY += fdistNextY;
			}
		}

		if (vertLength < 0) vertLength *= -1; 
		if (horzLength < 0) horzLength *= -1;

		if (vertLength < horzLength){
			minLength = &vertLength;
			darkgray = 1;
		}
		else{
			darkgray = 0;
			minLength = &horzLength;
		}

		//arreglar la distorsión.
		(*minLength) = (*minLength) * tableCOS[distAngle(curAngle, nPlayerAngle)];

		lineLength = absint((s32)((64.00 / *minLength) * PLAY_LENGTH)   );

		int end = (80 - lineLength/2);
		int start;
		if (end < 0){
			end = 160;
			start = 0;
		}
		else{
			start = end;
			end += lineLength;
		}

		u32 where = loop/2 + start*120;
		if (darkgray){
			for(y = start; y<end; y++)
			{
					destBuffer[where] = 0x0f0f;
					destBuffer[where+1] = 0x0f0f;
					where += 120;
			}
		}
		else{
			for(y = start; y<end; y++){
					destBuffer[where] = 0x0e0e;
					destBuffer[where+1] = 0x0e0e;
					where += 120;
			}
		}

		curAngle -= 1;
		if (curAngle < 0) curAngle += 360;

	}
}//fin de la función.
Ejemplo n.º 5
0
/* monLen -- length of array. numMon -- index into array to set */
void setMonitorPosition( Monitor *mon[], int monLen, int numMon, int x, int y, double threshold )
{
	int i; 
	int left, top, right, bottom;
	Monitor *monTemp;
	boolean overlapping;

	mon[numMon]->x = x;
	mon[numMon]->y = y;

	i = 0;
	overlapping = FALSE;
	while( i < monLen && overlapping == FALSE )
	{
		if( mon[i] != NULL && mon[i] != mon[numMon] )
		{
			overlapping = doesOverlap( mon[numMon], mon[i] );
		}
		i++;
	}

	/* Remove overlaps */
	if( overlapping == TRUE )
	{
		int dleft, dtop, dright, dbot;

		/* Remove current monitor so it doesn't contribute to bounding box */
		monTemp = mon[numMon];
		mon[numMon] = NULL;
		getBoundingRectangle( mon, monLen, &left, &top, &right, &bottom );
		mon[numMon] = monTemp;

		dleft = mon[numMon]->x + mon[numMon]->width - left;
		dtop = mon[numMon]->y + mon[numMon]->height - top;
		dright = right - mon[numMon]->x;
		dbot = bottom - mon[numMon]->y;

		if( MINARG( absint( dleft ), absint( dtop ), absint( dright ), absint( dbot ) )  == absint( dleft ) )
		{
			mon[numMon]->x = left - mon[numMon]->width - 1;
		}
		else if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dtop ) )
		{
			mon[numMon]->y = top - mon[numMon]->height - 1;
		}
		else if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dbot ) )
		{
			mon[numMon]->y = bottom + 1;
		}
		else
		{
			mon[numMon]->x = right + 1;
		}
	}

	/* Now that overlaps are gone, snap the rectangles together to make sure that at least one of their sides are touching */
	for( i = 0; i < monLen; i++ )
	{
		int dleft, dtop, dright, dbot, j;
		dleft = dtop = dright = dbot = 0;
		if( mon[i] != NULL )
		{
			for( j = 0; j < monLen; j++ )
			{
				if(  mon[j] != NULL && mon[j] != mon[i] )
				{
					if( dleft == 0 || absint(  mon[j]->x + mon[j]->width - mon[i]->x ) < absint( dleft ) )
					{
						dleft = mon[i]->x - ( mon[j]->x + mon[j]->width );
					}
					if( dright == 0 || absint( mon[j]->x - ( mon[i]->x + mon[i]->width ) ) < absint( dright ) )
					{ 
						dright = mon[j]->x - ( mon[i]->x + mon[i]->width );
					}
					if( dtop == 0 || absint( mon[j]->y + mon[j]->height - mon[i]->y ) < absint( dtop ) )
					{
						dtop =  mon[i]->y - ( mon[j]->y + mon[j]->height );
					}
					if( dbot == 0 || absint( mon[j]->y - (mon[i]->y + mon[i]->height ) ) < absint( dbot ) )
					{
						dbot = mon[j]->y - ( mon[i]->y + mon[i]->height );
					}
				}	
			}
			if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dleft ) || absint( dleft ) < mon[i]->width * threshold )
			{
				if( dleft != 0 ) /* 0 means no other monitors present */
				{
					mon[i]->x = mon[i]->x - dleft + 1;
				}	
			}

			if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dtop ) || absint( dtop ) < mon[i]->height * threshold )
			{
				if( dtop != 0 )
				{
					mon[i]->y = mon[i]->y - dtop + 1;
				}
			}

			if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dbot ) || absint( dbot ) < mon[i]->height * threshold )
			{
				if( dbot != 0 )
				{
					mon[i]->y = mon[i]->y + dbot - 1;
				}
			}

			if( MINARG( absint( dleft ), absint( dtop ), absint( dbot ), absint( dright ) ) == absint( dright ) || absint( dright ) < mon[i]->width * threshold  )
			{
				if( dright != 0 )
				{
					mon[i]->x = mon[i]->x + dright - 1;
				}
			}
			printf(" Monitor %d final position: x = %d y = %d\n", i, mon[i]->x, mon[i]->y );
		}
	}

	monTemp = mon[numMon];
	mon[numMon] = NULL;
	getBoundingRectangle( mon, monLen, &left, &top, &right, &bottom );
	mon[numMon] = monTemp;
	/* At least one side is in line, now ensure that they are actually touching */
	/*for( i = 0; i < monLen; i++ )
	{
		if( mon[i] != NULL && mon[i] != mon[numMon] )
		{
			Check to see which edge of bounding box it is against and then which edge of rectangle it is against. Once found, align this monitor with the found monitor 
			if( ( left == mon[numMon]->x + mon[numMon]->width + 1 && mon[numMon]->x + mon[numMon]->width - mon[i]->x == -1 ) || ( right == mon[numMon]->x - 1 && mon[numMon]->x - ( mon[i]->x + mon[i]->width ) == 1 ) )
			{
				printf("Snapping 1\n");
				if( ( mon[numMon]->y + mon[numMon]->width < mon[i]->y ) || ( mon[numMon]->y > mon[i]->y + mon[i]->height ) )
				{
					mon[numMon]->y = mon[i]->y;
				}
			}
			else if( ( top == mon[numMon]->y + mon[numMon]->width + 1 && mon[numMon]->y + mon[numMon]->height - mon[i]->y == -1 ) || ( bottom == mon[numMon]->y - 1 && mon[numMon]->y - ( mon[i]->y + mon[i]->height ) == 1 ))
			{
				printf("Snapping 2\n");
				if( ( mon[numMon]->x + mon[numMon]->width < mon[i]->x ) || ( mon[numMon]->x > mon[i]->x + mon[i]->width ) )
				{
					mon[numMon]->x = mon[i]->x;
				}
			}
		}
	}*/
}