void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2)
{
	if(!m_sel.zb)
	{
		return;
	}

	// int za = fza_base.y + fza_offset->y;

	movsxd(rbp, dword[rsi + 4]);
	movsxd(rax, dword[rdi + 4]);
	add(rbp, rax);

	// GSVector4i zs = zi;

	if(!m_sel.sprite)
	{
		if(m_sel.zoverflow)
		{
			// zs = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001());
			
			mov(rax, (size_t)&GSVector4::m_half);

			vbroadcastss(xmm0, ptr[rax]);
			vmulps(xmm0, xmm8);
			vcvttps2dq(xmm0, xmm0);
			vpslld(xmm0, 1);

			vcvttps2dq(xmm1, xmm8);
			vpcmpeqd(xmm2, xmm2);
			vpsrld(xmm2, 31);
			vpand(xmm1, xmm2);

			vpor(xmm0, xmm1);
		}
		else
		{
			// zs = GSVector4i(z);

			vcvttps2dq(xmm0, xmm8);
		}

		if(m_sel.zwrite)
		{
			vmovdqa(ptr[r11 + offsetof(GSScanlineLocalData, temp.zs)], xmm0);
		}
	}

	if(m_sel.ztest)
	{
		ReadPixel(xmm1, rbp);

		if(m_sel.zwrite && m_sel.zpsm < 2)
		{
			vmovdqa(ptr[r11 + offsetof(GSScanlineLocalData, temp.zd)], xmm1);
		}

		// zd &= 0xffffffff >> m_sel.zpsm * 8;

		if(m_sel.zpsm)
		{
			vpslld(xmm1, m_sel.zpsm * 8);
			vpsrld(xmm1, m_sel.zpsm * 8);
		}

		if(m_sel.zoverflow || m_sel.zpsm == 0)
		{
			// GSVector4i off = GSVector4i::x80000000();

			vpcmpeqd(xmm2, xmm2);
			vpslld(xmm2, 31);

			// GSVector4i zso = zs - off;
			// GSVector4i zdo = zd - off;

			vpsubd(xmm0, xmm2);
			vpsubd(xmm1, xmm2);
		}

		switch(m_sel.ztst)
		{
		case ZTST_GEQUAL:
			// test |= zso < zdo; // ~(zso >= zdo)
			vpcmpgtd(xmm1, xmm0);
			vpor(xmm15, xmm1);
			break;

		case ZTST_GREATER: // TODO: tidus hair and chocobo wings only appear fully when this is tested as ZTST_GEQUAL
			// test |= zso <= zdo; // ~(zso > zdo)
			vpcmpgtd(xmm0, xmm1);
			vpcmpeqd(xmm2, xmm2);
			vpxor(xmm0, xmm2);
			vpor(xmm15, xmm0);
			break;
		}

		alltrue();
	}
}
Exemplo n.º 2
0
/**********************************************************
 Stretch2Lines stretches two source lines with same length
 and different y-coordinates onto two destination lines
 with same length and different y-coordinates. Used by
 CircleStretch.
 Entry:
	x1,x2 - x-coordinates of the destination line
	y1,y2 - x-coordinates of the source line
	yr1   - y-coordinate of source line # 1
	yw1   - y-coordinate of destination line # 1
	yr2   - y-coordinate of source line # 2
	yw2   - y-coordinate of destination line # 2
**********************************************************/
void Stretch2Lines(long x1,long x2,long y1,long y2,long yr1,long yw1,long yr2,long yw2)
{
	long dx,dy,e,d,dx2;
	short sx,sy,color;
	dx=abs((int)(x2-x1));
	dy=abs((int)(y2-y1));
	sx=sign(x2-x1);
	sy=sign(y2-y1);
	e=(dy<<1)-dx;
	dx2=dx<<1;
	dy<<=1;
	for(d=0;d<=dx;d++)
	{
		color=ReadPixel(y1,yr1);
		SetColor(color);
		WritePixel(x1,yw1);
		color=ReadPixel(y1,yr2);
		SetColor(color);
		WritePixel(x1,yw2);
 
		while(e>=0)
		{
			y1+=sy;
			e-=dx2;
		}
		x1+=sx;
		e+=dy;
	}
}
Exemplo n.º 3
0
/**
* \fn int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection)
* \brief Detecte s'il y a collision entre deux surfaces selon le sens de déplacement du worms.
*
* \param[in] pSurfaceMap, pointer to the surface of the map.
* \param[in] pSurfaceMotion, pointer to the surface in motion.
* \param[in] pDirection, pointer to the object direction.
* \returns int, indicateur de collision : 1 = collision, 0 sinon
*/
int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection, int checkMode)
{
	//Variables d'acquisitions
	Uint32 pixelS1 = 0;	//Variable stockant le pixel en cours de lecture de la surface de la map
	Uint8 rS1 = 0, gS1 = 0, bS1 = 0, aS1 = 0;	//Variables stockant les informations sur les couleurs du pixel lu de la surface de la map
	Uint32 pixelS2 = 0;	//Variable stockant le pixel en cours de lecture de la surface en mouvement
	Uint8 rS2 = 0, gS2 = 0, bS2 = 0, aS2 = 0;	//Variables stockant les informations sur les couleurs du pixel lu de la surface en mouvement
	int offset_xS2 = pSurfaceMotion->clip_rect.x;	//Offset en x de la surface en mouvement dans la map
	int offset_yS2 = pSurfaceMotion->clip_rect.y;	//Offset en y de la surface en mouvement dans la map
	SDL_PixelFormat* formatS1 = pSurfaceMap->format;	//Pointeur du format de pixels de la surface de la map
	SDL_PixelFormat* formatS2 = pSurfaceMotion->format;	//Pointeur du format de pixels de la surface en mouvement
	//Variables de balayage
	int x = 0, y = 0;	//Variables de balayage des x, y
	int xStart = pSurfaceMotion->clip_rect.x, xEnd = pSurfaceMotion->clip_rect.x + pSurfaceMotion->clip_rect.w, xInc = 1;	//Variables de début, de fin et d'incrément du balayage des x
	int yStart = pSurfaceMotion->clip_rect.y, yEnd = pSurfaceMotion->clip_rect.y + pSurfaceMotion->clip_rect.h, yInc = 1;	//Variables de début, de fin et d'incrément du balayage des y
	int zone[4] = { 0, 0, 0, 0 }, balayageGen = 0;
	//Variable de collision
	int collision = 0;	//Booleen de collision, 0 = pas de collision, 1 = collision

	/*Test des limites de la map et de la fenetre*/
	if (collisionSurfaceWithMapLimits(pSurfaceMap, pSurfaceMotion))	//Detection d'un dépassement de la map
		return 1;

	/*Détermination de l'ordre des zones à balayer*/
	calculOrdreBalayage(*pDirection, zone);

	for (balayageGen = 0; (balayageGen < 4) && (collision == 0); balayageGen += 1)
	{
		/*Détermination de yStart, yEnd, xStart et xEnd*/
		calculXYBalayage(pSurfaceMotion, &xStart, &xEnd, &yStart, &yEnd, zone[balayageGen]);	//Calcul des valeurs de balayage des boucles for pour optimiser la vitesse de traitement

		/*Calcul de la collision*/
		for (y = yStart; (y < yEnd) && (collision == 0); y += yInc)
		{
			for (x = xStart; (x < xEnd) && (collision == 0); x += xInc)
			{
				/*Acquisition des pixels des surfaces 1 et 2*/
				pixelS1 = ReadPixel(pSurfaceMap, MY_ABS(x), MY_ABS(y));	//Lecture du pixel de la map
				pixelS2 = ReadPixel(pSurfaceMotion, MY_ABS(x) - offset_xS2, MY_ABS(y) - offset_yS2);	//Lecture du pixel de la surface en mouvement

				/*Récupération des composantes colorimétriques*/
				SDL_GetRGBA(pixelS1, formatS1, &rS1, &gS1, &bS1, &aS1);	//Informations sur les couleurs du pixel de la surface de la map
				SDL_GetRGBA(pixelS2, formatS2, &rS2, &gS2, &bS2, &aS2);	//Informations sur les couleurs du pixel de la surface en mouvement

				/*Détermination de la collision*/
				if (aS1 != 255 || aS2 != 255)	//Si le pixel de la surface de la map ou le pixel de la surface en mouvement est transparent
					collision = 0;	//Collision = 0 -> pas de collision
				else	//Au moins l'un des pixels n'est pas transparent
				{
					collision = 1;	//Collision = 1 -> collision
					*pDirection = calculDirectionCollision(*pDirection, zone[balayageGen], checkMode);	//Calcul de la direction de la collision pour affiner le traitement
				}
			}
		}
	}
	formatS1 = NULL;	//Remise à 0 des pointeurs de format
	formatS2 = NULL;	//Remise à 0 des pointeurs de format
	return collision;
}
Exemplo n.º 4
0
void Save_Minu_Hand_BK(void)
{
  unsigned int i                                          ;
  for(i=0;i<400+minu_comp;i++)
   MINU_HAND_BK_BUF[i]= ReadPixel(MINU_HAND_BUF[i][0],
                                  MINU_HAND_BUF[i][1] )   ;  
}
Exemplo n.º 5
0
void Save_Hour_Hand_BK(void)
{
  unsigned int i                                          ;
  for(i=0;i<300+hour_comp;i++)
   HOUR_HAND_BK_BUF[i]= ReadPixel(HOUR_HAND_BUF[i][0],
                                  HOUR_HAND_BUF[i][1] )   ;  
}
Exemplo n.º 6
0
void Save_Second_Hand_BK(void)
{
  unsigned int i                                          ;
  for(i=0;i<100;i++)
    SEC_HAND_BK_BUF[i]= ReadPixel(SEC_HAND_BUF[i][0],
                                  SEC_HAND_BUF[i][1] )    ;  
}
Exemplo n.º 7
0
void InitializeRLEBitmapFromPartialBitmap(RLEBitmap *self,const Bitmap *bitmap,int x0,int y0,int width,int height)
{
	self->width=width;
	self->height=height;
	Pixel *ptr=self->codes;

	for(int y=0;y<height;y++)
	{
		int x=0;
		while(x<width)
		{
			int emptystart=x;
			while(x<width && x-emptystart<0xff)
			{
				Pixel p=ReadPixel(bitmap,x+x0,y+y0);
				if(!IsPixelTransparent(p)) break;
				x++;
			}
			int empty=x-emptystart;

			int filledstart=x;
			while(x<width && x-filledstart<0xff)
			{
				Pixel p=ReadPixel(bitmap,x+x0,y+y0);
				if(IsPixelTransparent(p)) break;
				x++;
			}
			int filled=x-filledstart;

			#ifdef SingleBytePixels
			*ptr++=empty;
			if(x<width || filled!=0) *ptr++=filled;
			#else
			*ptr++=RLECode(empty,filled);
			memcpy(ptr,ConstBitmapPixelPointer(bitmap,filledstart+x0,y+y0),filled*sizeof(Pixel));
			ptr+=filled;
			#endif
		}
	}
}
Exemplo n.º 8
0
size_t SizeOfRLEBitmapFromPartialBitmap(const Bitmap *bitmap,int x0,int y0,int width,int height)
{
	size_t numpixels=0;

	for(int y=0;y<height;y++)
	{
		int x=0;
		while(x<width)
		{
			int emptystart=x;
			while(x<width && x-emptystart<0xff)
			{
				Pixel p=ReadPixel(bitmap,x+x0,y+y0);
				if(!IsPixelTransparent(p)) break;
				x++;
			}
			//int empty=x-emptystart;

			int filledstart=x;
			while(x<width && x-filledstart<0xff)
			{
				Pixel p=ReadPixel(bitmap,x+x0,y+y0);
				if(IsPixelTransparent(p)) break;
				x++;
			}
			int filled=x-filledstart;

			numpixels+=1+filled;

			#ifdef SingleBytePixels
			if(x<width || filled!=0) numpixels++;
			#endif
		}
	}

	return sizeof(RLEBitmap)+numpixels*sizeof(Pixel);
}
Exemplo n.º 9
0
VOID test_readpixel(struct Window *w)
{
    ULONG i;
    
    for (i = 0; i < 16; i ++) {
    	UBYTE pen;
    	SetAPen(w->RPort, i);
	WritePixel(w->RPort, 70, 70);
	
	pen = ReadPixel(w->RPort, 70, 70);
	
	printf("Wrote pen %ld, read pen %d\n", (long)i, pen);
    
    }
}
Exemplo n.º 10
0
LONG neighbor(struct RastPort *r, LONG dir)
{
	switch (dir) {
	case 0:tx = x;ty = y+1;break;
	case 1:tx = x+1;ty = y+1;break;
	case 2:tx = x+1;ty = y;break;
	case 3:tx = x+1;ty = y-1;break;
	case 4:tx = x;ty = y-1;break;
	case 5:tx = x-1;ty = y-1;break;
	case 6:tx = x-1;ty = y;break;
	case 7:tx = x-1;ty = y+1;break;
	default: return -1;break;
	}
	if (tx < 0 || tx >= Width || ty < 0 || ty >= Height)
		return -1; 
	
	return (LONG)ReadPixel(r, tx, ty);
}
Exemplo n.º 11
0
Draw_Dot(short dotcode,short dotx,short doty)
{
 dotread=ReadPixel(rastport,dotx,doty);
 if(dotread!=DOTCOLOR && dotread!=ENERGCOLOR)
 {
  if(dotcode&ENERGIZER)
  {
   SetAPen(rastport,ENERGCOLOR);
   for(tx=-1;tx<2;tx++) for(ty=-1;ty<2;ty++)
    WritePixel(rastport,dotx+tx,doty+ty);                   /* BIG dot! */
   SetAPen(rastport,DOTCOLOR);
  }
  else 
   WritePixel(rastport,dotx,doty);
  numdots++;
 }
 return 0;
}
Exemplo n.º 12
0
void TestReadPixel()
{
	int i;
	CLR clr;
	char szBuf[17];
	
	SetPixelBox(6, 6, 9, 9, false);
	
	for (i = 0; i < 16; ++i)
	{
		clr = ReadPixel();
		snprintf(szBuf, sizeof(szBuf), "(%02x, %02x, %02x)",
			RFromClr(clr), GFromClr(clr), BFromClr(clr));
		Print(szBuf);
		if (i % 4 == 3)
			PrintLn(0);
	}
}
void GSDrawScanlineCodeGenerator::ReadFrame()
{
    if(!m_sel.fb)
    {
        return;
    }

    // int fa = fza_base.x + fza_offset->x;

    mov(ebx, dword[esi]);
    add(ebx, dword[edi]);

    if(!m_sel.rfb)
    {
        return;
    }

    ReadPixel(xmm2, ebx);
}
Exemplo n.º 14
0
LONG FracBlank( struct Screen *Scr, UWORD Wid, UWORD Hei )
{
	float x = 0, y = 0, xx, yy, a, b, c;
	LONG i, xe, ye, flg_end = OK, mod = ( 1L << Scr->BitMap.Depth ) - 1;
	struct RastPort *Rast = &( Scr->RastPort );
	
	SetRast( Rast, 0 );
	ScreenToFront( Scr );
	
	a = (float)RangeRand( 1000 ) / 10 - 50.0;
	do
		b = (float)RangeRand( 1000 ) / 10 - 50.0;
	while( b == 0.0 );
	c = (float)RangeRand( 1000 ) / 10 - 50.0;
	
	for( i = 0; i < 50000 && flg_end == OK; i++ )
	{
		if(!( i % 50 ))
		{
			ScreenToFront( Scr );
			flg_end = ContinueBlanking();
		}
		
		if( x < 0 )
			xx = y + sqrt( fabs( b * x - c ));
		else
			xx = y - sqrt( fabs( b * x - c ));
		yy = a - x;
		xe = Wid / 2 + (SHORT)x;
		ye = Hei / 2 + (SHORT)y;
		
		if(( xe >= 0 )&&( ye >= 0 )&&( xe < Wid )&&( ye < Hei ))
		{
			SetAPen( Rast, ( ReadPixel( Rast, xe, ye ) + 1 ) % mod + 1 );
			WritePixel( Rast, xe, ye );
		}
		
		x = xx;
		y = yy;
	}

	return flg_end;
}
Exemplo n.º 15
0
PlayMaze()
{
    PrintStatus();             /* Prints the score and everything else */

    BlackOut(ALLBLACK);     /* Hide the reconstruction of the viewPort */
    WaitTOF(),WaitTOF();            /* Wait for the Blackout to finish */

    InitializeStarting();

    ScrollDisplay(SCROLLDEFINITELY);

    killallsound();

    button=0;
    joyx=0;
    joyy=0;     /* Initialize Joy Regs */

    JoyRead(CTRLR_RESET);

    while(!(joyx || joyy))
    {
        WaitTOF();
        JoyRead(CTRLR_READ);
    }

    playsound(SND_BACKGRND,0),playsound(SND_BACKGRND,0);

    SetAPen(rastport,PATHCOLOR);            /* We will be erasing dots */
    for(i=0; i<numghosts; i++) energized[i]=0;

    while(dead>=0 && numdots)
    {
        tx=xposn[0]+XOFF;
        ty=yposn[0]+YOFF;

        if(tx>=minx-1 && tx<=maxx+1 && ty>=miny-1 && ty<=maxy+1)
        {
            lookhere=ReadPixel(rastport,tx+x_dir,ty+y_dir);
            if(lookhere==DOTCOLOR)
            {
                atedot++;
                WritePixel(rastport,tx+x_dir,ty+y_dir);
                INCSCORE(10);
                if(--numdots==advspeed[speedindex])
                {
                    speedindex++;
                    if(killsound(SND_BACKGRND))
                        playsound(SND_BACKGRND,0),playsound(SND_BACKGRND,0);
                }
                playsound(SND_DOT,1);
            }
            else if(lookhere==ENERGCOLOR)
            {
                atedot=1;
                for(i=-1; i<2; i++) for(c=-1; c<2; c++)      /* Erase energizer */
                        WritePixel(rastport,tx+(x_dir<<1)+c,ty+(y_dir<<1)+i);
                INCSCORE(50);
                if(--numdots==advspeed[speedindex])
                {
                    speedindex++;
                    if(killsound(SND_BACKGRND))
                        playsound(SND_BACKGRND,0),playsound(SND_BACKGRND,0);
                }
                playsound(SND_DOT,1);
                Energize();
            }
        }
        if((!joyx)^(!joyy)) joy_dir =(joyy)?(1+joyy):(2-joyx);
        if(x_dir || y_dir) dir_code=(y_dir)?(1+y_dir):(2-x_dir);
        dvx=xposn[0]+XOFF-pdest_v->x;
        dvy=yposn[0]+YOFF-pdest_v->y;
        old_dcode = dir_code;
        if((ABS(dvx)+ABS(dvy))<2 && joy_dir!=dir_code
                && pdest_v->next[joy_dir])
        {
            dir_code = joy_dir;
            dvx=0;
            dvy=0;
            xposn[0]=pdest_v->x-XOFF;
            yposn[0]=pdest_v->y-YOFF;
            at_vertex = TRUE;
        }
        else at_vertex=((!dvx && !dvy) || (x_dir==y_dir));

        if ((!joyx)^(!joyy))     /* if joy movement */
        {
            if (at_vertex)
            {
                if(joyx && pdest_v->next[joy_dir]
                        && !(pdest_v->code[joy_dir]&FORBID))
                {
                    pmv=pdest_v;
                    pdest_v=pdest_v->next[joy_dir];       /* Destination vertex */
                    x_dir=joyx;                  /* Direction we are now headed */
                    y_dir=0;
                }
                else if(joyy && pdest_v->next[1+joyy]
                        && !(pdest_v->code[1+joyy]&FORBID))
                {
                    pmv=pdest_v;
                    pdest_v=pdest_v->next[1+joyy];
                    x_dir=0;
                    y_dir=joyy;
                }
                else if ((!(pdest_v->next[joy_dir])
                          || (pdest_v->code[joy_dir]&FORBID))
                         && ((!(pdest_v->next[old_dcode])
                              || (pdest_v->code[old_dcode]&FORBID))))
                    /* If(at_vertex && no (allowable) next vertex) dead end;stop */
                {
                    x_dir=0;
                    y_dir=0;
                }
                else if (x_dir||y_dir) /* Joy in invalid dir on vertex */
                {
                    pmv=pdest_v;  /* There is a path in current dir - follow it */
                    pdest_v=pdest_v->next[old_dcode];
                    dir_code = old_dcode;
                }
            }                          /* End of block for if at a vertex */
            else if (joyx && !(joyx+x_dir)) /* Reverses direction on edge */
            {
                x_dir=-x_dir;              /* Reverse current direction */
                tv=pdest_v;            /* Swap pdest_v with last vertex */
                pdest_v=pmv;
                pmv=tv;
            }
            else if (joyy && !(joyy+y_dir))       /* Reverses dir along y */
            {
                y_dir=-y_dir;              /* Reverse current direction */
                tv=pdest_v;            /* Swap pdest_v with last vertex */
                pdest_v=pmv;
                pmv=tv;
            }
        } /* End of block for if no button but movement on joystick */
        else if (at_vertex && (y_dir || x_dir))   /* move but no joymove */
        {
            if(x_dir && (!pdest_v->next[old_dcode]
                         || (pdest_v->code[old_dcode]&FORBID)))
                x_dir=0;/* Stop @ Dead End */
            else if(y_dir && (!pdest_v->next[old_dcode]
                              || (pdest_v->code[old_dcode]&FORBID)))
                y_dir=0;
            else
            {
                pmv=pdest_v;                 /* Continue moving to next vertex */
                pdest_v=pdest_v->next[old_dcode];
            }
        }
        if (atedot<2)
        {
            xposn[0]+=x_dir;
            yposn[0]+=y_dir;
        }
        else atedot=0;

        WrapSprite(0,x_dir,y_dir);                /* Wrap around routine */
        spoff=((xposn[0]+yposn[0])>>1)&3;
        spoff=(spoff>2) ? (1+3*dir_code) : (spoff+3*dir_code);
        ChangeSprite(svp,&sprite[0],(short *)(pacmen+spoff));

        if ((dead=MoveGhosts())<0) {
            dead=-1;
            --lives;                        /* Kill a PACMAN */
            Die();
        }
        else {
            ScrollDisplay(SCROLLMAYBE);
            PrintScore();
        }
        if(dead>0) {
            killallsound();
            playsound(SND_MONSTER,1);
            playsound(SND_MONSTER,1);
            DeEnergize(dead-1,0);                          /* Eat a ghost! */
            playsound(SND_EYES,0);
        }
        JoyRead(CTRLR_READ);
    }                             /* End of main control loop */
    return 0;
}                                /* End of loop to decrement lives. */
Exemplo n.º 16
0
void ImageTile::ReadPixelBilinear(double x, double y, unsigned char& r, unsigned char& g, unsigned char& b, unsigned char& a)
{
   double uf = math::Fract<double>(x);
   double vf = math::Fract<double>(y);

   int nPixelX = int(x);
   int nPixelY = int(y);

   int u00,v00,u10,v10,u01,v01,u11,v11;
   u00 = nPixelX;
   v00 = nPixelY;
   u10 = nPixelX+1;
   v10 = nPixelY;
   u01 = nPixelX;
   v01 = nPixelY+1;
   u11 = nPixelX+1;
   v11 = nPixelY+1;

   if (u00<0) u00 = 0;
   if (v00<0) v00 = 0;
   if (u10<0) u10 = 0;
   if (v10<0) v10 = 0;
   if (u01<0) u01 = 0;
   if (v01<0) v01 = 0;
   if (u11<0) u11 = 0;
   if (v11<0) v11 = 0;

   if (u00>(int)nTileSize-1) u00 = (int)nTileSize-1;
   if (v00>(int)nTileSize-1) v00 = (int)nTileSize-1;
   if (u10>(int)nTileSize-1) u10 = (int)nTileSize-1;
   if (v10>(int)nTileSize-1) v10 = (int)nTileSize-1;
   if (u01>(int)nTileSize-1) u01 = (int)nTileSize-1;
   if (v01>(int)nTileSize-1) v01 = (int)nTileSize-1;
   if (u11>(int)nTileSize-1) u11 = (int)nTileSize-1;
   if (v11>(int)nTileSize-1) v11 = (int)nTileSize-1;

   unsigned char r00;
   unsigned char g00; 
   unsigned char b00;
   unsigned char a00;

   unsigned char r10; 
   unsigned char g10; 
   unsigned char b10;
   unsigned char a10;

   unsigned char r01; 
   unsigned char g01; 
   unsigned char b01;
   unsigned char a01;

   unsigned char r11; 
   unsigned char g11; 
   unsigned char b11;
   unsigned char a11;

   // 
   ReadPixel(u00, v00, r00, g00, b00, a00);
   ReadPixel(u10, v10, r10, g10, b10, a10);
   ReadPixel(u01, v01, r01, g01, b01, a01);
   ReadPixel(u11, v11, r11, g11, b11, a11);
   //

   r = (unsigned char) (r00*(1-uf)*(1-vf)+r10*uf*(1-vf)+r01*(1-uf)*vf+r11*uf*vf);
   g = (unsigned char) (g00*(1-uf)*(1-vf)+g10*uf*(1-vf)+g01*(1-uf)*vf+g11*uf*vf);
   b = (unsigned char) (b00*(1-uf)*(1-vf)+b10*uf*(1-vf)+b01*(1-uf)*vf+b11*uf*vf);
   a = (unsigned char) (a00*(1-uf)*(1-vf)+a10*uf*(1-vf)+a01*(1-uf)*vf+a11*uf*vf);
}
Exemplo n.º 17
0
void ImageTile::ReadPixelBicubic(double x, double y, unsigned char& r, unsigned char& g, unsigned char& b, unsigned char& a)
{
   int nPixelX = int(x);
   int nPixelY = int(y);

   double uf = math::Fract<double>(x);
   double vf = math::Fract<double>(y);

   int u00,v00,u01,v01,u02,v02,u03,v03;
   int u10,v10,u11,v11,u12,v12,u13,v13;
   int u20,v20,u21,v21,u22,v22,u23,v23;
   int u30,v30,u31,v31,u32,v32,u33,v33;

   u00 = nPixelX -1; v00 = nPixelY-1;
   u01 = nPixelX; v01 = nPixelY-1;
   u02 = nPixelX+1; v02 = nPixelY-1;
   u03 = nPixelX+2; v03 = nPixelY-1;

   u10 = nPixelX-1; v10 = nPixelY;
   u11 = nPixelX; v11 = nPixelY;
   u12 = nPixelX+1; v12 = nPixelY;
   u13 = nPixelX+2; v13 = nPixelY;

   u20 = nPixelX-1; v20 = nPixelY+1;
   u21 = nPixelX; v21 = nPixelY+1;
   u22 = nPixelX+1; v22 = nPixelY+1;
   u23 = nPixelX+2; v23 = nPixelY+1;

   u30 = nPixelX-1; v30 = nPixelY+2;
   u31 = nPixelX; v31 = nPixelY+2;
   u32 = nPixelX+1; v32 = nPixelY+2;
   u33 = nPixelX+2; v33 = nPixelY+2;


   if (u00<0) u00 = 0; if (v00<0) v00 = 0;
   if (u01<0) u01 = 0; if (v01<0) v01 = 0;
   if (u02<0) u02 = 0; if (v02<0) v02 = 0;
   if (u03<0) u03 = 0; if (v03<0) v03 = 0;

   if (u10<0) u10 = 0; if (v10<0) v10 = 0;
   if (u11<0) u11 = 0; if (v11<0) v11 = 0;
   if (u12<0) u12 = 0; if (v12<0) v12 = 0;
   if (u13<0) u13 = 0; if (v13<0) v13 = 0;

   if (u20<0) u20 = 0; if (v20<0) v20 = 0;
   if (u21<0) u21 = 0; if (v21<0) v21 = 0;
   if (u22<0) u22 = 0; if (v22<0) v22 = 0;
   if (u23<0) u23 = 0; if (v23<0) v23 = 0;

   if (u30<0) u30 = 0; if (v30<0) v30 = 0;
   if (u31<0) u31 = 0; if (v31<0) v31 = 0;
   if (u32<0) u32 = 0; if (v32<0) v32 = 0;
   if (u33<0) u33 = 0; if (v33<0) v33 = 0;


   if (u00>(int)nTileSize-1) u00 = (int)nTileSize-1;
   if (v00>(int)nTileSize-1) v00 = (int)nTileSize-1;
   if (u01>(int)nTileSize-1) u01 = (int)nTileSize-1;
   if (v01>(int)nTileSize-1) v01 = (int)nTileSize-1;
   if (u02>(int)nTileSize-1) u02 = (int)nTileSize-1;
   if (v02>(int)nTileSize-1) v02 = (int)nTileSize-1;
   if (u03>(int)nTileSize-1) u03 = (int)nTileSize-1;
   if (v03>(int)nTileSize-1) v03 = (int)nTileSize-1;

   if (u10>(int)nTileSize-1) u10 = (int)nTileSize-1;
   if (v10>(int)nTileSize-1) v10 = (int)nTileSize-1;
   if (u11>(int)nTileSize-1) u11 = (int)nTileSize-1;
   if (v11>(int)nTileSize-1) v11 = (int)nTileSize-1;
   if (u12>(int)nTileSize-1) u12 = (int)nTileSize-1;
   if (v12>(int)nTileSize-1) v12 = (int)nTileSize-1;
   if (u13>(int)nTileSize-1) u13 = (int)nTileSize-1;
   if (v13>(int)nTileSize-1) v13 = (int)nTileSize-1;

   if (u20>(int)nTileSize-1) u20 = (int)nTileSize-1;
   if (v20>(int)nTileSize-1) v20 = (int)nTileSize-1;
   if (u21>(int)nTileSize-1) u21 = (int)nTileSize-1;
   if (v21>(int)nTileSize-1) v21 = (int)nTileSize-1;
   if (u22>(int)nTileSize-1) u22 = (int)nTileSize-1;
   if (v22>(int)nTileSize-1) v22 = (int)nTileSize-1;
   if (u23>(int)nTileSize-1) u23 = (int)nTileSize-1;
   if (v23>(int)nTileSize-1) v23 = (int)nTileSize-1;

   if (u30>(int)nTileSize-1) u30 = (int)nTileSize-1;
   if (v30>(int)nTileSize-1) v30 = (int)nTileSize-1;
   if (u31>(int)nTileSize-1) u31 = (int)nTileSize-1;
   if (v31>(int)nTileSize-1) v31 = (int)nTileSize-1;
   if (u32>(int)nTileSize-1) u32 = (int)nTileSize-1;
   if (v32>(int)nTileSize-1) v32 = (int)nTileSize-1;
   if (u33>(int)nTileSize-1) u33 = (int)nTileSize-1;
   if (v33>(int)nTileSize-1) v33 = (int)nTileSize-1;


   unsigned char r00,r01,r02,r03;
   unsigned char r10,r11,r12,r13;
   unsigned char r20,r21,r22,r23;
   unsigned char r30,r31,r32,r33;

   unsigned char g00,g01,g02,g03;
   unsigned char g10,g11,g12,g13;
   unsigned char g20,g21,g22,g23;
   unsigned char g30,g31,g32,g33;

   unsigned char b00,b01,b02,b03;
   unsigned char b10,b11,b12,b13;
   unsigned char b20,b21,b22,b23;
   unsigned char b30,b31,b32,b33;

   unsigned char a00,a01,a02,a03;
   unsigned char a10,a11,a12,a13;
   unsigned char a20,a21,a22,a23;
   unsigned char a30,a31,a32,a33;


   ReadPixel(u00, v00, r00, g00, b00, a00);
   ReadPixel(u01, v01, r01, g01, b01, a01);
   ReadPixel(u02, v02, r02, g02, b02, a02);
   ReadPixel(u03, v03, r03, g03, b03, a03);

   ReadPixel(u10, v10, r10, g10, b10, a10);
   ReadPixel(u11, v11, r11, g11, b11, a11);
   ReadPixel(u12, v12, r12, g12, b12, a12);
   ReadPixel(u13, v13, r13, g13, b13, a13);

   ReadPixel(u20, v20, r20, g20, b20, a20);
   ReadPixel(u21, v21, r21, g21, b21, a21);
   ReadPixel(u22, v22, r22, g22, b22, a22);
   ReadPixel(u23, v23, r23, g23, b23, a23);

   ReadPixel(u30, v30, r30, g30, b30, a30);
   ReadPixel(u31, v31, r31, g31, b31, a31);
   ReadPixel(u32, v32, r32, g32, b32, a32);
   ReadPixel(u33, v33, r33, g33, b33, a33);

   double r0 = _CalcCubic(r00,r01,r02,r03, uf);
   double r1 = _CalcCubic(r10,r11,r12,r13, uf);
   double r2 = _CalcCubic(r20,r21,r22,r23, uf);
   double r3 = _CalcCubic(r30,r31,r32,r33, uf);

   double g0 = _CalcCubic(g00,g01,g02,g03, uf);
   double g1 = _CalcCubic(g10,g11,g12,g13, uf);
   double g2 = _CalcCubic(g20,g21,g22,g23, uf);
   double g3 = _CalcCubic(g30,g31,g32,g33, uf);

   double b0 = _CalcCubic(b00,b01,b02,b03, uf);
   double b1 = _CalcCubic(b10,b11,b12,b13, uf);
   double b2 = _CalcCubic(b20,b21,b22,b23, uf);
   double b3 = _CalcCubic(b30,b31,b32,b33, uf);

   double a0 = _CalcCubic(a00,a01,a02,a03, uf);
   double a1 = _CalcCubic(a10,a11,a12,a13, uf);
   double a2 = _CalcCubic(a20,a21,a22,a23, uf);
   double a3 = _CalcCubic(a30,a31,a32,a33, uf);

   double rd = _CalcCubic(r0,r1,r2,r3,vf);
   double gd = _CalcCubic(g0,g1,g2,g3,vf);
   double bd = _CalcCubic(b0,b1,b2,b3,vf);
   double ad = _CalcCubic(a0,a1,a2,a3,vf);

   if (rd>255) rd = 255.0;
   if (gd>255) gd = 255.0;
   if (bd>255) bd = 255.0;
   if (ad>255) ad = 255.0;
   if (rd<0) rd = 0;
   if (gd<0) gd = 0;
   if (bd<0) bd = 0;
   if (ad<0) ad = 0;

   r = unsigned char(rd);
   g = unsigned char(gd);
   b = unsigned char(bd);
   a = unsigned char(ad);
}
void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2)
{
    if(!m_sel.zb)
    {
        return;
    }

    // int za = fza_base.y + fza_offset->y;

    mov(ebp, dword[esi + 4]);
    add(ebp, dword[edi + 4]);

    // GSVector4i zs = zi;

    if(!m_sel.sprite)
    {
        if(m_sel.zoverflow)
        {
            // zs = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001());

            static float half = 0.5f;

            movss(temp1, dword[&half]);
            shufps(temp1, temp1, _MM_SHUFFLE(0, 0, 0, 0));
            mulps(temp1, xmm0);
            cvttps2dq(temp1, temp1);
            pslld(temp1, 1);

            cvttps2dq(xmm0, xmm0);
            pcmpeqd(temp2, temp2);
            psrld(temp2, 31);
            pand(xmm0, temp2);

            por(xmm0, temp1);
        }
        else
        {
            // zs = GSVector4i(z);

            cvttps2dq(xmm0, xmm0);
        }

        if(m_sel.zwrite)
        {
            movdqa(xmmword[&m_env.temp.zs], xmm0);
        }
    }

    if(m_sel.ztest)
    {
        ReadPixel(xmm1, ebp);

        if(m_sel.zwrite && m_sel.zpsm < 2)
        {
            movdqa(xmmword[&m_env.temp.zd], xmm1);
        }

        // zd &= 0xffffffff >> m_sel.zpsm * 8;

        if(m_sel.zpsm)
        {
            pslld(xmm1, m_sel.zpsm * 8);
            psrld(xmm1, m_sel.zpsm * 8);
        }

        if(m_sel.zoverflow || m_sel.zpsm == 0)
        {
            // GSVector4i o = GSVector4i::x80000000();

            pcmpeqd(xmm4, xmm4);
            pslld(xmm4, 31);

            // GSVector4i zso = zs - o;

            psubd(xmm0, xmm4);

            // GSVector4i zdo = zd - o;

            psubd(xmm1, xmm4);
        }

        switch(m_sel.ztst)
        {
        case ZTST_GEQUAL:
            // test |= zso < zdo; // ~(zso >= zdo)
            pcmpgtd(xmm1, xmm0);
            por(xmm7, xmm1);
            break;

        case ZTST_GREATER: // TODO: tidus hair and chocobo wings only appear fully when this is tested as ZTST_GEQUAL
            // test |= zso <= zdo; // ~(zso > zdo)
            pcmpgtd(xmm0, xmm1);
            pcmpeqd(xmm4, xmm4);
            pxor(xmm0, xmm4);
            por(xmm7, xmm0);
            break;
        }

        alltrue();
    }
}
Exemplo n.º 19
0
void SearchEdge() {
	int x = 0;
	int z = 0;
	int tmp;
	int tmp1, tmp2;
	int LorR = 0;
	int buffer[160];
	int F_continueSearch[2] = { 1, 1 };
	int F_maybeCrossRoad[2] = { 0, 0 };
	int F_reborn = 0;

	uchar buffer_startLine[80][2];
	int n_startLine = 1;
	int C_startLine = 0;
	int startLineX[2];

	Pr_SelectFIFO = ~Pr_SelectFIFO;
	al422b_SelectFIFO(Pr_SelectFIFO);
	al422b_Reset();

	// initial parameters --->>>
	F_startLine = 0;

	edgeStartZ[left] = 0;
	edgeStartZ[right] = 0;

	C_activePoint[left] = 0;
	C_activePoint[right] = 0;

	searchRange[right].start = rightSearchRange;
	searchRange[right].end = midSearchRange;
	searchRange[left].start = midSearchRange;
	searchRange[left].end = leftSearchRange;

	SkipLines(skipLines-1);

	SkipPixels(40);
	for (x = 0; x < 80; x++)
		buffer_startLine[x][0] = ReadPixel();
	SkipPixels(40);

	for (z = 0; z < 30; z++) {

		if(z<8)
		{
			SkipLines(((29 - z) / skiplineControl) - 1);
			//ÆðÅÜÏßËÑË÷
			startLineX[left] = 79;
			startLineX[right] = 0;

			tmp1 = n_startLine % 2;
			tmp2 = (n_startLine - 1) % 2;

			SkipPixels(40);
			for(x=0;x<80;x++)buffer_startLine[x][tmp1] = ReadPixel();
			SkipPixels(40);

			C_startLine = 0;
			for(x=0;x<50;x++)
			{

				if((ABS(buffer_startLine[x][tmp1] - buffer_startLine[x][tmp2])) > (thresholdEdge+10))
				{
					C_startLine ++;
				}
				else
				{
					if(C_startLine>5)
					{
						startLineX[right] = x;
						break;
					}
					else C_startLine = 0;
				}
			}
			
			C_startLine = 0;
			for(x=79;x>50;x--)
			{
				if((ABS(buffer_startLine[x][tmp1] - buffer_startLine[x][tmp2])) > (thresholdEdge+10))
				{
					C_startLine ++;
				}
				else
				{
					
					if(C_startLine>5)
					{
						startLineX[left] = x;
						break;
					}
					else C_startLine = 0;
				}

			}

			if((ABS(startLineX[left] - startLineX[right])) < (50))
					F_startLine = 1;
			
			n_startLine ++;
		}
		else
		{
			SkipLines((29 - z) / skiplineControl);
		}

		if(searchRange[right].end > searchRange[left].start)
		{
			searchRange[left].start = (searchRange[right].end + searchRange[left].start) / 2;
			searchRange[right].end = searchRange[left].start;
		}

		tmp = searchRange[right].start;
		SkipPixels(tmp);
		for(x=searchRange[right].start;x<searchRange[right].end;x++)buffer[x] = ReadPixel();
		tmp = searchRange[left].start - searchRange[right].end;
		SkipPixels(tmp);
		for(x=searchRange[left].start;x<searchRange[left].end;x++)buffer[x] = ReadPixel();
		tmp = 160 - searchRange[left].end;
		SkipPixels(tmp);

		//right
		LorR = right;
		if(F_continueSearch[LorR] == 1)
		{
			F_continueSearch[LorR] = 0;
			for(x=(searchRange[LorR].end-1-2);x>=searchRange[LorR].start;x--)
			{
				if(Gradient(buffer[x+2] ,buffer[x]) > thresholdEdge)
				{
					if(F_reborn == 1)
					edgeStartZ[LorR] = 10;
					else
					{
						if(z>1)//ÅжÏÕÛ½Ç
						{
							if((ABS((x - edgePoint[LorR][z-1].x) - (edgePoint[LorR][z-1].x - edgePoint[LorR][z-2].x)))> 5)
							{
								break;
							}
						}
					}
					edgePoint[LorR][z].x = x;
					edgePoint[LorR][z].z = z;
					SetSearchRange(LorR, x, defaultRange);
					F_continueSearch[LorR] = 1;
					C_activePoint[LorR] ++;

					break;
				}
			}
		}

		//left
		LorR = left;
		if(F_continueSearch[LorR] == 1)
		{
			F_continueSearch[LorR] = 0;
			for(x=searchRange[LorR].start+2;x<searchRange[LorR].end;x++)
			{
				if(Gradient(buffer[x-2] ,buffer[x]) > thresholdEdge)
				{
					if(F_reborn == 1)
					edgeStartZ[LorR] = 10;
					else
					{
						if(z>1)//ÅжÏÕÛ½Ç
						{
							if((ABS((x - edgePoint[LorR][z-1].x) - (edgePoint[LorR][z-1].x - edgePoint[LorR][z-2].x)))> 5)
							{
								break;
							}
						}
					}
					edgePoint[LorR][z].x = x;
					edgePoint[LorR][z].z = z;
					SetSearchRange(LorR, x, defaultRange);
					F_continueSearch[LorR] = 1;
					C_activePoint[LorR] ++;
					break;
				}
			}
		}

		switch(z)
		{
			case 2://Í·Á½Ðж¼Ã»ÓÐ×¥µ½±ßÑصÄÇé¿ö Åж¨
			if((C_activePoint[left] + C_activePoint[right]) < 3)
			F_reborn = 1;
			break;

			case 9://¡°¸´»î°É,ÎÒµÄÓÂÊ¿¡±
			if(F_reborn == 1)
			{
				F_continueSearch[left] = 1;
				F_continueSearch[right] = 1;

				C_activePoint[left] = 0;
				C_activePoint[right] = 0;

				searchRange[right].start = 30;
				searchRange[right].end = 79;
				searchRange[left].start = 79;
				searchRange[left].end = 130;

			}
			break;

			case 10:
			if((C_activePoint[left]+ C_activePoint[right]) < 2)goto myEnd;
			break;
		}

	}

	myEnd:

	if ((C_activePoint[left] + C_activePoint[right]) < 8) {
		F_crossRoad = 1;
	}
	if ((C_activePoint[left] + C_activePoint[right]) > 20) {
		F_crossRoad = 0;
	}
	for (LorR = 0; LorR < 2; LorR++) {
		if(C_activePoint[LorR] == 0)C_activePoint[LorR] = 1;
		crctr_BTX[LorR].tail = edgePoint[LorR][(C_activePoint[LorR]-1) + edgeStartZ[LorR]];
		crctr_BTX[LorR].head = edgePoint[LorR][edgeStartZ[LorR]];
		crctr_BTX[LorR].inflection = GetInflectionPoint(LorR);

		crctr_BTX[LorR].k_hi =KPP(crctr_BTX[LorR].inflection,crctr_BTX[LorR].head);
		crctr_BTX[LorR].k_it =KPP(crctr_BTX[LorR].tail,crctr_BTX[LorR].inflection);
		crctr_BTX[LorR].k_ht =KPP(crctr_BTX[LorR].tail,crctr_BTX[LorR].head);

		crctr_BTX[LorR].R_hit = crctr_BTX[LorR].k_it- crctr_BTX[LorR].k_hi;
	}

}
int WINAPI 
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine,
         int nCmdShow)
{
   char buff[256 + _MAX_PATH];
   TGAHeaderInfo TGAHeader;
   FILE *finput, *foutput;
   DWORD bytesRead;
   int x, y;
   unsigned char *descBytes;
   pixel pix, *srcImage, *dstImage;
   float dX, dY, nX, nY, nZ, oolen;

   // Loop until the user cancels the open dialog
   while (TRUE) 
      {
      // Either take the input and output filename from the command line
      // or grab it from the user.
      char inFilename[_MAX_PATH];
      inFilename[0] = '\0';
      char outFilename[_MAX_PATH];
      if (!GetFileName (NULL, inFilename)) 
         {
         return 0;
         }
      strcpy (outFilename, inFilename);
      char *dot = strrchr (outFilename, '.');
      if (dot == NULL)
         {
         strcat (outFilename, "DOT3.tga");
         }
      else
         {
         strcpy (dot, "DOT3.tga");
         }
      
      //Put filename in here
      if ((finput = fopen (inFilename, "rb")) == NULL)
         {
         sprintf (buff, "Unable to open input TGA file: %s", inFilename);
         MessageBox (NULL, buff, "Error", MB_OK | MB_ICONERROR);
         continue;
         }
      
      // Open output file
      if ((foutput = fopen (outFilename, "wb")) == NULL)
         {
         sprintf (buff, "Unable to open output TGA file: %s", inFilename);
         MessageBox (NULL, buff, "Error", MB_OK | MB_ICONERROR);
         continue;
         }
      
      //Read TARGA header.
      if ((bytesRead = fread (&TGAHeader, sizeof (unsigned char), 
                              sizeof (TGAHeader), finput)) != sizeof (TGAHeader))
         {
         MessageBox (NULL, "Bad Targa header", "Error", MB_OK | MB_ICONERROR);
         continue;
         }
      
      //Write to output file TARGA header
      if ((bytesRead = fwrite (&TGAHeader, sizeof (unsigned char), 
                               sizeof (TGAHeader), foutput)) != sizeof (TGAHeader))
         {
         MessageBox (NULL, "Bad Targa header writing out", "Error", 
                     MB_OK | MB_ICONERROR);
         continue;
         }
      
      descBytes = (unsigned char *) malloc (sizeof (unsigned char) * TGAHeader.idlen);
      if (descBytes == NULL)
         {
         MessageBox (NULL, "Unable to allocate enough memory.", "Error", 
                     MB_OK | MB_ICONERROR);
         continue;
         }
      
      // Steal descriptive bytes at end of header
      if ((bytesRead = fread (descBytes, sizeof (unsigned char), 
                              TGAHeader.idlen, finput)) != TGAHeader.idlen)
         {
         MessageBox (NULL, "Couldn't seek past Targa header", "Error", 
                     MB_OK | MB_ICONERROR);
         continue;
         }
      
      if ((bytesRead = fwrite (descBytes, sizeof (unsigned char), 
                               TGAHeader.idlen, foutput)) != TGAHeader.idlen)
         {
         MessageBox (NULL, "Bad Targa descriptive data writing out", "Error", 
                     MB_OK | MB_ICONERROR);
         continue;
         }
      
      gWidth  = TGAHeader.imwidth;
      gHeight = TGAHeader.imheight;
      
      
      // allocate storage
      srcImage = (pixel *) malloc (sizeof (pixel) * gHeight * gWidth);
      dstImage = (pixel *) malloc (sizeof (pixel) * gHeight * gWidth);

      if ((srcImage == NULL) || (dstImage == NULL))
         {
         MessageBox (NULL, "Unable to allocate enough memory.", "Error", 
                     MB_OK | MB_ICONERROR);
         continue;
         }
      
      for (y = 0; y < gHeight; y++)
         {
         for (x = 0; x < gWidth; x++)
            {
            fread(&pix.blue, sizeof(BYTE), 1, finput);
            fread(&pix.green, sizeof(BYTE), 1, finput);
            fread(&pix.red, sizeof(BYTE), 1, finput);
            
            if (TGAHeader.imdepth == 32)
               fread(&pix.alpha, sizeof(BYTE), 1, finput);
            else
               pix.alpha = 0xcc;
            
            WritePixel(srcImage, &pix, x, y);
            }
         }
      
      
      for(y = 0; y < gHeight; y++)
         {
         for(x = 0; x < gWidth; x++)
            {
            // Do Y Sobel filter
            ReadPixel(srcImage, &pix, (x-1+gWidth) % gWidth, (y+1) % gHeight);
            dY  = ((float) pix.red) / 255.0f * -1.0f;
            
            ReadPixel(srcImage, &pix,   x   % gWidth, (y+1) % gHeight);
            dY += ((float) pix.red) / 255.0f * -2.0f;
            
            ReadPixel(srcImage, &pix, (x+1) % gWidth, (y+1) % gHeight);
            dY += ((float) pix.red) / 255.0f * -1.0f;
            
            ReadPixel(srcImage, &pix, (x-1+gWidth) % gWidth, (y-1+gHeight) % gHeight);
            dY += ((float) pix.red) / 255.0f *  1.0f;
            
            ReadPixel(srcImage, &pix,   x   % gWidth, (y-1+gHeight) % gHeight);
            dY += ((float) pix.red) / 255.0f *  2.0f;
            
            ReadPixel(srcImage, &pix, (x+1) % gWidth, (y-1+gHeight) % gHeight);
            dY += ((float) pix.red) / 255.0f *  1.0f;
            
            // Do X Sobel filter
            ReadPixel(srcImage, &pix, (x-1+gWidth) % gWidth, (y-1+gHeight) % gHeight);
            dX  = ((float) pix.red) / 255.0f * -1.0f;
            
            ReadPixel(srcImage, &pix, (x-1+gWidth) % gWidth,   y   % gHeight);
            dX += ((float) pix.red) / 255.0f * -2.0f;
            
            ReadPixel(srcImage, &pix, (x-1+gWidth) % gWidth, (y+1) % gHeight);
            dX += ((float) pix.red) / 255.0f * -1.0f;
            
            ReadPixel(srcImage, &pix, (x+1) % gWidth, (y-1+gHeight) % gHeight);
            dX += ((float) pix.red) / 255.0f *  1.0f;
            
            ReadPixel(srcImage, &pix, (x+1) % gWidth,   y   % gHeight);
            dX += ((float) pix.red) / 255.0f *  2.0f;
            
            ReadPixel(srcImage, &pix, (x+1) % gWidth, (y+1) % gHeight);
            dX += ((float) pix.red) / 255.0f *  1.0f;
            
            
            // Cross Product of components of gradient reduces to
            nX = -dX;
            nY = -dY;
            nZ = 1;
            
            // Normalize
            oolen = 1.0f/((float) sqrt(nX*nX + nY*nY + nZ*nZ));
            nX *= oolen;
            nY *= oolen;
            nZ *= oolen;
            
            pix.red   = (BYTE) PackFloatInByte(nX);
            pix.green = (BYTE) PackFloatInByte(nY);
            pix.blue  = (BYTE) PackFloatInByte(nZ);
            
            WritePixel(dstImage, &pix, x, y);
            }
         }
      
      
      for(y = 0; y < gHeight; y++)
         {
         for(x = 0; x < gWidth; x++)
            {
            ReadPixel(dstImage, &pix, x, y);
            
            fwrite(&pix.blue, sizeof(BYTE), 1, foutput);
            fwrite(&pix.green, sizeof(BYTE), 1, foutput);
            fwrite(&pix.red, sizeof(BYTE), 1, foutput);
            
            if(TGAHeader.imdepth == 32)
               fwrite(&pix.alpha, sizeof(BYTE), 1, foutput);
            }
         }
      
      free(srcImage);
      free(dstImage);
      free(descBytes);
      
      fclose(finput); // close the input file
      fclose(foutput); // close the output file
      
      sprintf (buff, "Success! New TGA file: %s", outFilename);
      MessageBox (NULL, buff, "Success", MB_OK);
      }
   return(0);
}