Exemplo n.º 1
0
void
free_rotate (ppm_t *p, double amount)
{
  int    x, y;
  double nx, ny;
  ppm_t  tmp = {0, 0, NULL};
  double f = amount * G_PI * 2 / 360.0;
  int    rowstride = p->width * 3;

  ppm_new (&tmp, p->width, p->height);
  for (y = 0; y < p->height; y++)
    {
      for (x = 0; x < p->width; x++)
        {
          double r, d;

          nx = fabs (x - p->width / 2.0);
          ny = fabs (y - p->height / 2.0);
          r = sqrt (nx * nx + ny * ny);

          d = atan2 ((y - p->height / 2.0), (x - p->width / 2.0));

          nx = (p->width / 2.0 + cos (d - f) * r);
          ny = (p->height / 2.0 + sin (d - f) * r);
          get_rgb (p, nx, ny, tmp.col + y * rowstride + x * 3);
        }
    }
  ppm_kill (p);
  p->width = tmp.width;
  p->height = tmp.height;
  p->col = tmp.col;
}
Exemplo n.º 2
0
void create_image_ppm(uint32_t *pic, int32_t size_x, int32_t size_y, char *filename)
{
	//ouverture du fichier et ecriture de l'entete
    FILE *file = fopen(filename, "wb");
	fprintf(file, "P6\n%d %d\n255\n", size_x, size_y);

	unsigned char color[3];

	//ecriture de chaque pixel de picture
	for (int32_t i = 0; i < size_x * size_y; i++) {
			get_rgb(pic[i], color);
			fwrite(color, 1, 3, file);
	}

	//fermeture du fichier
	fclose(file);
}
Exemplo n.º 3
0
void
make_pillar(char *prefix, int ix, int iy, fastf_t *center, fastf_t *lwh, struct wmember *headp)


    /* center of base */


{
    vect_t	min, max;
    unsigned char	rgb[4];		/* needs all 4 */
    char	pilname[32], rname[32], sname[32], oname[32];
    int	i;
    struct wmember head;
    struct wmember *wp;

    BU_LIST_INIT( &head.l );

    snprintf( pilname, 32, "%s%d,%d", prefix, ix, iy );
    snprintf( rname, 32, "%s.r", pilname );
    snprintf( sname, 32, "%s.s", pilname );
    snprintf( oname, 32, "Obj%d,%d", ix, iy );

    VMOVE( min, center );
    min[X] -= lwh[X];
    min[Y] -= lwh[Y];
    VADD2( max, center, lwh );
    mk_rpp( outfp, sname, min, max );

    /* Needs to be in a region, with color!  */
    get_rgb(rgb);
    i = PICK_MAT;
    mk_region1( outfp, rname, sname,
		mtab[i].mt_name, mtab[i].mt_param, rgb );

    (void)mk_addmember( rname, &head.l, NULL, WMOP_UNION );
    wp = mk_addmember( oname, &head.l, NULL, WMOP_UNION );
    MAT_DELTAS( wp->wm_mat, center[X], center[Y], center[Z]+lwh[Z] );
    mk_lfcomb( outfp, pilname, &head, 0 );

    (void)mk_addmember( pilname, &(headp->l), NULL, WMOP_UNION );
}
Exemplo n.º 4
0
void
resize (ppm_t *p, int nx, int ny)
{
  int   x, y;
  float xs = p->width / (float)nx;
  float ys = p->height / (float)ny;
  ppm_t tmp = {0, 0, NULL};

  ppm_new (&tmp, nx, ny);
  for (y = 0; y < ny; y++)
    {
      guchar *row = tmp.col + y * tmp.width * 3;

      for (x = 0; x < nx; x++)
        {
          get_rgb (p, x * xs, y * ys, &row[x * 3]);
        }
    }
  ppm_kill (p);
  p->width = tmp.width;
  p->height = tmp.height;
  p->col = tmp.col;
}
Exemplo n.º 5
0
/* The main drawing function. */
void DrawGLScene(){

   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
   glLoadIdentity();

   double RotationAngleX = 0.0;
   double RotationAngleY = 0.0;
   double RotationAngleZ = 0.0;

   if( dim3d==1 ) RotationAngleX = -60.0;
   if( dim3d==2 ) RotationAngleX = -90.0;
 
   glTranslatef( 0.0 , 0.0 , -CAM_BACKUP );

   glRotatef(RotationAngleX, 1, 0, 0);
   glRotatef(RotationAngleY, 0, 1, 0);
   glRotatef(RotationAngleZ, 0, 0, 1);

   int q = valq;

   getMaxMin();
   if( print_vals==0 ){
      printf("Max = %e Min = %e\n",maxval,minval);
      print_vals=1;
   }

   double camdist = 0.0;//-CAM_BACKUP;
   double xoff    = offx;
   double yoff    = offy;
   double zoff    = 0.0;

   if( draw_1d ){
      glColor3f(1.0,1.0,1.0);
      glBegin(GL_QUADS);
      glVertex3f(-1./rescale-xoff,-1./rescale-yoff, camdist + zoff );
      glVertex3f( 1./rescale-xoff,-1./rescale-yoff, camdist + zoff );
      glVertex3f( 1./rescale-xoff, 1./rescale-yoff, camdist + zoff );
      glVertex3f(-1./rescale-xoff, 1./rescale-yoff, camdist + zoff );
      glEnd();
      glLineWidth( 3.0f );
      glColor3f(0.0,0.0,0.0);
      glBegin( GL_LINE_STRIP );
      int j;
//      for( j=0 ; j<Nr ; ++j ){
      for( j=0 ; j<Nr ; ++j ){
         //if(logscale) val = log(getval(theZones[i],q))/log(10.);
         double rm = r_jph[j-1];
         double rp = r_jph[j]; 
         double val = theRadialData[j][q]/max_1d;//*pow(.5*(rp+rm),1.5);//2.*(theRadialData[j][q]-minval)/(maxval-minval) - 1.;//getval(theZones[i],q);
         if( q==1 ) val *= 1e2;
         val = 2.*val - 1.;
         double c0 = 2.*((.5*(rp+rm)-r_jph[-1])/(r_jph[Nr-1]-r_jph[-1]) - .5)/rescale;
         double c1 = val/rescale;
         glVertex3f( c0-xoff, c1-yoff, camdist-zoff+.001 );
      }    
      glEnd();
/*
      glColor3f(0.5,0.5,0.5);
      glBegin( GL_LINE_STRIP );

      for( j=0 ; j<Nr ; ++j ){
         //if(logscale) val = log(getval(theZones[i],q))/log(10.);
         double rm = r_jph[j-1];
         double rp = r_jph[j];
         double r = .5*(rp+rm); 
         double val = pow(r,-1.5)/max_1d;// *pow(.5*(rp+rm),1.5);//2.*(theRadialData[j][q]-minval)/(maxval-minval) - 1.;//getval(theZones[i],q);         if( q==1 ) val *= 1e2;
         val = 2.*val - 1.;
         double c0 = 2.*((.5*(rp+rm)-r_jph[-1])/(r_jph[Nr-1]-r_jph[-1]) - .5)/rescale;                 double c1 = val/rescale;
         glVertex3f( c0-xoff, c1-yoff, camdist-zoff+.001 );
      }       
      glEnd();
*/
      if( draw_planet ){
         double eps = 0.01;
         int p;
         for( p=0 ; p<Npl ; ++p ){
            double r   = thePlanets[p][0];
            double x = 2.*(( r - r_jph[-1] )/( r_jph[Nr-1]-r_jph[-1] ) - .5)/rescale;
            glColor3f(0.0,0.0,0.0);
            glLineWidth(2.0);
            glBegin(GL_LINE_LOOP);
            glVertex3f( x-xoff+eps , 1./rescale-yoff+eps , camdist+.001 );
            glVertex3f( x-xoff-eps , 1./rescale-yoff+eps , camdist+.001 );
            glVertex3f( x-xoff-eps , 1./rescale-yoff-eps , camdist+.001 );
            glVertex3f( x-xoff+eps , 1./rescale-yoff-eps , camdist+.001 );
            glEnd();
         }
      }

   }else{
      int Num_Draws = 1+reflect+draw_border;
      int count;
      int i,j;
      for( count = 0 ; count < Num_Draws ; ++count ){
         int draw_border_now = 0;
         int draw_reflected_now = 0;
         if( count==reflect+1 ) draw_border_now = 1;
         if( reflect && count==1 ) draw_reflected_now = 1;
         if( draw_border_now ) zoff -= .0001;
      for( j=0 ; j<Nr ; ++j ){
         double rm = r_jph[j-1]/rescale;
         double rp = r_jph[j]/rescale;
         double rc = .5*(rp+rm);
         double dr = rp-rm;
      
         if( !draw_border ){
            rm = rc-.55*dr;
            rp = rc+.55*dr;
         }
         for( i=0 ; i<Np[j] ; ++i ){

            double phip = p_iph[j][i];
            double phim;
            if( i==0 ) phim = p_iph[j][Np[j]-1]; else phim = p_iph[j][i-1];
            if( t_off && !p_off ){ phip -= t; phim -= t; }
            if( p_off ){ phip -= thePlanets[1][1]; phim -= thePlanets[1][1]; }
            double dp   = phip-phim;
            while( dp < 0.0 ) dp += 2.*M_PI;
            while( dp > 2.*M_PI ) dp -= 2.*M_PI;
            double phi = phim + 0.5*dp;
            if( !draw_border ){
               phip = phi+.55*dp;
               phim = phi-.55*dp;
            }

            double val = (getval(theZones[j][i],q)-minval)/(maxval-minval);
            if(logscale) val = (log(getval(theZones[j][i],q))/log(10.)-minval)/(maxval-minval);
            if( val > 1.0 ) val = 1.0;
            if( val < 0.0 ) val = 0.0;
            //double u = getval( theZones[j][i] , 2 );
            //if( uMax < u ) uMax = u;

            float rrr,ggg,bbb;
            get_rgb( val , &rrr , &ggg , &bbb , cmap );

            //if( (!dim3d || (sin(phi)>0 || cos(phi+.25)<0.0)) && dim3d !=2 ){
            if( dp < 1.5 && (!dim3d || (sin(phi)>0 && cos(phi)>0.0)) && dim3d !=2 ){
               if( !draw_border_now ){ 
                  glColor3f( rrr , ggg , bbb );
                  glBegin(GL_POLYGON);
               }else{
                  glLineWidth(3.0f);
                  glColor3f(0.0,0.0,0.0);
                  glBegin(GL_LINE_LOOP);
               }

               double z0 = 0.0;
               if( dim3d ) z0 = z_kph[Nz-1]/rescale;
     
               double c0 = rm*cos(phim);
               double c1 = rm*sin(phim);
               glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 );

               c0 = rp*cos(phim);
               c1 = rp*sin(phim);
               glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 );

               c0 = rp*cos(phi)/cos(.5*dp);
               c1 = rp*sin(phi)/cos(.5*dp);
               glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 );

               c0 = rp*cos(phip);
               c1 = rp*sin(phip);
               glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 );

               c0 = rm*cos(phip);
               c1 = rm*sin(phip);
               glVertex3f( c0-xoff, c1-yoff, camdist-zoff+z0 );

               glEnd();
            }
         }
         if( dim3d ){
            int k;
            for( k=0 ; k<Nz ; ++k ){
               int jk = j*Nz+k;
               double rp = r_jph[j]/rescale;
               double rm = r_jph[j-1]/rescale;
               double zp = z_kph[k]/rescale;
               double zm = z_kph[k-1]/rescale;

               double phi = 0.0;//rzZones[jk][Nq];

            double val = (getval(rzZones[jk],q)-minval)/(maxval-minval);
            if(logscale) val = (log(getval(rzZones[jk],q))/log(10.)-minval)/(maxval-minval);
            if( val > 1.0 ) val = 1.0;
            if( val < 0.0 ) val = 0.0;
            float rrr,ggg,bbb;
            get_rgb( val , &rrr , &ggg , &bbb , cmap );
               if( !draw_border_now ){ 
                  glColor3f( rrr , ggg , bbb );
                  glBegin(GL_POLYGON);
               }else{
                  glLineWidth(2.0f);
                  glColor3f(0.0,0.0,0.0);
                  glBegin(GL_LINE_LOOP);
               } 
                  
                  glVertex3f( rp*cos(phi) - xoff , rp*sin(phi) - yoff + zoff, zp );
                  glVertex3f( rm*cos(phi) - xoff , rm*sin(phi) - yoff + zoff, zp );
                  glVertex3f( rm*cos(phi) - xoff , rm*sin(phi) - yoff + zoff, zm );
                  glVertex3f( rp*cos(phi) - xoff , rp*sin(phi) - yoff + zoff, zm );
                  glEnd();
            }
            if( draw_border_now || dim3d == 1 ){
               glLineWidth(2.0f);
               glColor3f(0.0,0.0,0.0);
               glBegin(GL_LINE_LOOP);

               double rp = r_jph[Nr-1]/rescale;
               //double rm =-r_jph[Nr-1]/rescale;
               double rm = r_jph[-1]/rescale;
               double zp = z_kph[Nz-1]/rescale;
               double zm = z_kph[  -1]/rescale;

               glVertex3f( rp-xoff , -yoff+zoff , zp );
               glVertex3f( rm-xoff , -yoff+zoff , zp );
               glVertex3f( rm-xoff , -yoff+zoff , zm );
               glVertex3f( rp-xoff , -yoff+zoff , zm );
               glEnd();
            }
         }
      }
   }


   if( draw_bar ){
      double xb = 0.6;
      double hb = 1.0;
      double wb = 0.02;
      int Nb = 1000;
      double dy = hb/(double)Nb;
      int k;
      for( k=0 ; k<Nb ; ++k ){
         double y = (double)k*dy - .5*hb;
         double val = (double)k/(double)Nb;
         float rrr,ggg,bbb;
         get_rgb( val , &rrr , &ggg , &bbb , cmap );
         glLineWidth(0.0f);
         glColor3f( rrr , ggg , bbb );
         glBegin(GL_POLYGON);
         glVertex3f( xb    , y    , camdist + .001 ); 
         glVertex3f( xb+wb , y    , camdist + .001 ); 
         glVertex3f( xb+wb , y+dy , camdist + .001 ); 
         glVertex3f( xb    , y+dy , camdist + .001 ); 
         glEnd();
      }
      int Nv = 8;
      for( k=0 ; k<Nv ; ++k ){
         double y = (double)k*hb/(double)(Nv-1) - .5*hb;
         double val = (double)k/(double)(Nv-1)*(maxval-minval) + minval;
         char valname[256];
         sprintf(valname,"%+.2e",val);
         glLineWidth(1.0f);
         glColor3f(0.0,0.0,0.0);
         glBegin(GL_LINE_LOOP);
         glVertex3f( xb    , y , camdist + .0011 );
         glVertex3f( xb+wb , y , camdist + .0011 );
         glEnd();
         glutPrint( xb+1.5*wb , y-.007 , camdist + .001 ,glutFonts[6] , valname , 0.0f, 0.0f , 0.0f , 0.5f );
      }
   } 

   if( draw_planet ){
      double eps = 0.01;
      int p;
      for( p=0 ; p<Npl ; ++p ){
         double r   = thePlanets[p][0]/rescale;
         double phi = thePlanets[p][1];
         if( t_off && !p_off ) phi -= t;
         if( p_off ) phi -= thePlanets[1][1];
         glColor3f(0.0,0.0,0.0);
         glLineWidth(2.0);
         glBegin(GL_LINE_LOOP);
         glVertex3f( r*cos(phi)-xoff+eps , r*sin(phi)-yoff+eps , camdist+.001 );
         glVertex3f( r*cos(phi)-xoff-eps , r*sin(phi)-yoff+eps , camdist+.001 );
         glVertex3f( r*cos(phi)-xoff-eps , r*sin(phi)-yoff-eps , camdist+.001 );
         glVertex3f( r*cos(phi)-xoff+eps , r*sin(phi)-yoff-eps , camdist+.001 );
         glEnd();
      }
   }

   if( draw_spiral ){
      double rp   = 5.0;//thePlanets[1][0];
      double Mach = 3.65;
      double p0 = 1.2;
      double dr = .07;
      int Nr = 200;
      double Rmin = 0.5;
      double Rmax = 1.1;
      int k;
      glLineWidth(3.0f);
      glColor3f(0.0,0.0,0.0);
      //glColor3f(1.0,1.0,1.0);
      glBegin(GL_LINE_LOOP);
      for( k=0 ; k<Nr ; ++k ){
         //double phi0 = ((double)k+.5)/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.;
         double x = ((double)k+.5)/(double)Nr;
         //double r = .001*pow(.5/.001,x);
         double r = .5*pow(1.5/.5,x);
         //double phi0 = p0-log(r/0.001)*Mach;//(3.-2.*sqrt(1./r)-r)*5.;
         double phi0 = (3.-2.*sqrt(1./r)-r)*20.;
         if( r<1. ) phi0 = -phi0;
//         double x0 = rp + dr*cos(phi0);
//         double y0 = dr*sin(phi0);
  
         double phi = phi0;
//         double r = rp;       

//         double phi = atan2(y0,x0);
//         double phi = ((double)k+.5)/(double)Nr*2.*M_PI*9.32 + 4.*M_PI;
//         double r   = sqrt(x0*x0+y0*y0);
//         double r = pow(phi/10.,-2.);
//         double r   = 2./(1.+sin(phi));//1.0;//((double)k+0.5)/(double)Nr*(Rmax-Rmin) + Rmin;
//         if( r<1. ) phi = -phi;
         r /= rescale;
         
         glVertex3f( r*cos(phi)-xoff , r*sin(phi)-yoff , camdist + .0011 );
         if( k%2==1 ){
            glEnd();
            glBegin(GL_LINE_LOOP);
         }
      }
      glEnd();
/*
      e += 0.01;
      glBegin(GL_LINE_LOOP);
      for( k=0 ; k<Nr ; ++k ){
         double phi0 = ((double)k-.5)/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.;
         double x0 = 1.+e*cos(phi0);
         double y0 = e*sin(phi0);
         
         double phi = atan2(y0,x0);
         double r   = sqrt(x0*x0+y0*y0);
//         double phi = (double)k/(double)Nr*2.*M_PI;//(3.-2.*sqrt(1./r)-r)*20.;
//         double r   = 2./(1.+sin(phi));//1.0;//((double)k+0.5)/(double)Nr*(Rmax-Rmin) + Rmin;
//         if( r<1. ) phi = -phi;
         r /= rescale;
         
         glVertex3f( r*cos(phi)-xoff , r*sin(phi)-yoff , camdist + .0011 );
         if( k%2==1 ){
            glEnd();
            glBegin(GL_LINE_LOOP);
         }
      }
      glEnd();
*/
   }
   }

   if( draw_t ){
      char tprint[256];
      sprintf(tprint,"t = %.2e",t/2./M_PI);
      glutPrint( -.6 , .5 , camdist + .001 , glutFonts[6] , tprint , 0.0f, 0.0f , 0.0f , 0.5f );
  //    sprintf(tprint,"uMax = %.1f",uMax);
  //    glutPrint( -.8 , .4 , camdist + .001 , glutFonts[6] , tprint , 0.0f, 0.0f , 0.0f , 0.5f );
   }
   if( help_screen ){
      int NLines = 9;
      double dy = -.04;
      char help[NLines][256];
      sprintf(help[0],"Help Display:");
      sprintf(help[1],"b - Toggle Colorbar");
      sprintf(help[2],"c - Change Colormap");
      sprintf(help[3],"f - Toggle Max/Min Floors");
      sprintf(help[4],"p - Toggle Planet Data");
      sprintf(help[5],"1-9 - Choose Primitive Variable to Display");
      sprintf(help[6],"wasd - Move Camera");
      sprintf(help[7],"z/x - Zoom in/out");
      sprintf(help[8],"h - Toggle Help Screen");
      int i;
      for( i=0 ; i<NLines ; ++i ){
         glutPrint( -.8 , i*dy , camdist + .001 , glutFonts[6] , help[i] , 0.0f, 0.0f , 0.0f , 0.5f );
      }
   } 

   if( CommandMode ){
      TakeScreenshot("out.ppm");
      exit(1);
   }

   glutSwapBuffers();

}
Exemplo n.º 6
0
void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *pixel_data)
{
	// initialise the blink timer
	if (m_blink_start > screen.frame_number())
		m_blink_start = screen.frame_number();

	// compute the blink state according to the programmed duty cycle
	const bool blink_state = ((screen.frame_number() - m_blink_start) & (
		(m_command_0 & CR0302) == CR0302_1616 ? 0x10 :
		(m_command_0 & CR0302) == CR0302_3232 ? 0x20 :
		(m_command_0 & CR0302) == CR0302_6464 ? 0x40 : 0x30)) == 0;

	// compute the pixel mask from the pixel read mask and blink mask/state
	const u8 pixel_mask = m_pixel_read_mask & (blink_state ? 0xffU : ~m_pixel_blink_mask);

	// draw visible pixel data
	switch (m_command_0 & CR0100)
	{
	case CR0100_1BPP:
		for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
			for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8)
			{
				u8 data = *pixel_data++;

				bitmap.pix(y, x + 7) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 6) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 5) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 4) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 3) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 2) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 1) = get_rgb(data & 0x1, pixel_mask); data >>= 1;
				bitmap.pix(y, x + 0) = get_rgb(data & 0x1, pixel_mask);
			}
		break;

	case CR0100_2BPP:
		for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
			for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4)
			{
				u8 data = *pixel_data++;

				bitmap.pix(y, x + 3) = get_rgb(data & 0x3, pixel_mask); data >>= 2;
				bitmap.pix(y, x + 2) = get_rgb(data & 0x3, pixel_mask); data >>= 2;
				bitmap.pix(y, x + 1) = get_rgb(data & 0x3, pixel_mask); data >>= 2;
				bitmap.pix(y, x + 0) = get_rgb(data & 0x3, pixel_mask);
			}
		break;

	case CR0100_4BPP:
		for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
			for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2)
			{
				u8 data = *pixel_data++;

				bitmap.pix(y, x + 1) = get_rgb(data & 0x7, pixel_mask); data >>= 4;
				bitmap.pix(y, x + 0) = get_rgb(data & 0x7, pixel_mask);
			}
		break;

	case CR0100_8BPP:
		for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
			for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++)
				bitmap.pix(y, x) = get_rgb(*pixel_data++, pixel_mask);
		break;
	}

	// draw cursors when visible and not blinked off
	if ((m_cursor_command & (CR47 | CR46 | CR45 | CR44)) && ((m_cursor_command & CR40) == 0 || blink_state))
	{
		// get 64x64 bitmap and cross hair cursor plane enable
		const u8 bm_cursor_enable = (m_cursor_command & (CR47 | CR46)) >> 6;
		const u8 ch_cursor_enable = (m_cursor_command & (CR45 | CR44)) >> 4;

		// get cross hair cursor half thickness
		const int ch_thickness = (m_cursor_command & CR4241) >> 1;

		/*
		 * The cursor (x) value to be written is calculated as follows:
		 *
		 *   Cx = desired display screen (x) position + H - P
		 *
		 * where
		 *
		 *   P = 37 if 1:1 input multiplexing, 52 if 4:1 input multiplexing,
		 *       57 if 5:1 input multiplexing
		 *   H = number of pixels between the first rising edge of LD*
		 *       following the falling edge of HSYNC* to active video
		 *
		 * The cursor (y) value to be written is calculated as follows:
		 *
		 *   Cy = desired display screen (y) position + V - 32
		 *
		 * where
		 *
		 *   V = number of scan lines from the second sync pulse during
		 *       vertical blanking to active video
		 *
		 * Values from $0FC0 (-64) to $0FBF (+4031) may be loaded into the
		 * cursor (y) register. The negative values ($0FC0 to $0FFF) are used
		 * in situations where V < 32, and the cursor must be moved off the
		 * top of the screen.
		 */
		const int cursor_x = m_cursor_x + (
			(m_command_0 & CR0706) == CR0706_11MPX ? 37 :
			(m_command_0 & CR0706) == CR0706_41MPX ? 52 :
			(m_command_0 & CR0706) == CR0706_51MPX ? 57 : 0);
		const int cursor_y = (m_cursor_y < 0xfc0 ? m_cursor_y : m_cursor_y - 0x1000) + 32;

		// 64x64 bitmap cursor
		if (bm_cursor_enable)
		{
			// compute target 64x64 rectangle
			rectangle cursor(cursor_x - 31, cursor_x + 32, cursor_y - 31, cursor_y + 32);

			// intersect with screen bitmap
			cursor &= bitmap.cliprect();

			// draw if any portion is visible
			if (!cursor.empty())
			{
				for (int y = 0; y < 64; y++)
				{
					// get screen y pixel coordinate
					const int ypos = cursor_y - 31 + y;

					for (int x = 0; x < 64; x++)
					{
						// get screen x pixel coordinate
						const int xpos = cursor_x - 31 + x;

						// check if pixel is visible
						if (cursor.contains(xpos, ypos))
						{
							// retrieve 2 bits of 64x64 bitmap cursor data
							u8 data = (m_cursor_ram[y * 16 + (x >> 2)] >> ((3 - (x & 3)) << 1)) & bm_cursor_enable;

							// check for dual-cursor mode and combine with cross-hair data
							if (ch_cursor_enable)
								if (((x >= 31 - ch_thickness) && (x <= 31 + ch_thickness)) || ((y >= 31 - ch_thickness) && (y <= 31 + ch_thickness)))
									data = (m_cursor_command & CR43) ? data | ch_cursor_enable : data ^ ch_cursor_enable;

							// write cursor data to screen (normal or X Window mode)
							if (data && !((m_command_2 & CR21) && data == 1))
								bitmap.pix(ypos, xpos) = m_cursor_color[data - 1];
						}
					}
				}
			}
		}

		// cross hair cursor
		if (ch_cursor_enable)
		{
			// get the cross hair cursor color
			const rgb_t ch_color = m_cursor_color[ch_cursor_enable - 1];

			/*
			 * The window (x) value to be written is calculated as follows:
			 *
			 *   Wx = desired display screen (x) position + H - P
			 *
			 * where
			 *
			 *   P = 5 if 1:1 input multiplexing, 20 if 4:1 input multiplexing,
			 *       25 if 5:1 input multiplexing
			 *   H = number of pixels between the first rising edge of LD*
			 *       following the falling edge of HSYNC* to active video
			 *
			 * The window (y) value to be written is calculated as follows:
			 *
			 *   Wy = desired display screen (y) position + V
			 *
			 * where
			 *
			 *   V = number of scan lines from the second sync pulse during
			 *       vertical blanking to active video
			 *
			 * Values from $0000 to $0FFF may be written to the window (x) and
			 * (y) registers. A full-screen cross hair is implemented by
			 * loading the window (x,y) registers with $0000, and the window
			 * width and height registers with $0FFF.
			 */
			const bool full_screen = (m_window_x == 0 && m_window_y == 0 && m_window_w == 0x0fff && m_window_h == 0x0fff);
			const int window_x = full_screen ? screen.visible_area().min_x : m_window_x + (
				(m_command_0 & CR0706) == CR0706_11MPX ? 5 :
				(m_command_0 & CR0706) == CR0706_41MPX ? 20 :
				(m_command_0 & CR0706) == CR0706_51MPX ? 25 : 0);
			const int window_y = full_screen ? screen.visible_area().min_y : m_window_y;

			/*
			 * The actual window width is 2, 8 or 10 pixels more than the
			 * value specified by the window width register, depending on
			 * whether 1:1, 4:1 or 5:1 input multiplexing is specified. The
			 * actual window height is 2 pixels more than the value specified
			 * by the window height register. Therefore, the minimum window
			 * width is 2, 8 or 10 pixels for 1:1, 4:1 and 5:1 multiplexing,
			 * respectively. The minimum window height is 2 pixels.
			 *
			 * Values from $0000 to $0FFF may be written to the window width
			 * and height registers.
			 *
			 * Note: testing indicates the cross-hair cursor should be drawn
			 * strictly inside the window, although this is not 100% clear from
			 * the documentation.
			 */
			const int window_w = full_screen ? screen.visible_area().width() : m_window_w + (
				(m_command_0 & CR0706) == CR0706_11MPX ? 2 :
				(m_command_0 & CR0706) == CR0706_41MPX ? 8 :
				(m_command_0 & CR0706) == CR0706_51MPX ? 10 : 0);
			const int window_h = full_screen ? screen.visible_area().height() : m_window_h + 2;

			// check for dual-cursor mode
			if (bm_cursor_enable)
			{
				// draw the cross hair cursor as vertical and horizontal filled rectangles broken by the 64x64 cursor area
				rectangle v1(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, cursor_y - 32);
				rectangle v2(cursor_x - ch_thickness, cursor_x + ch_thickness, cursor_y + 33, window_y + window_h);
				rectangle h1(window_x + 1, cursor_x - 32, cursor_y - ch_thickness, cursor_y + ch_thickness);
				rectangle h2(cursor_x + 33, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness);

				v1 &= bitmap.cliprect();
				v2 &= bitmap.cliprect();
				h1 &= bitmap.cliprect();
				h2 &= bitmap.cliprect();

				if (!v1.empty())
					bitmap.fill(ch_color, v1);
				if (!v2.empty())
					bitmap.fill(ch_color, v2);
				if (!h1.empty())
					bitmap.fill(ch_color, h1);
				if (!h2.empty())
					bitmap.fill(ch_color, h2);
			}
			else
			{
				// draw the cross hair cursor as unbroken vertical and horizontal filled rectangles
				rectangle v(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, window_y + window_h);
				rectangle h(window_x + 1, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness);

				v &= bitmap.cliprect();
				h &= bitmap.cliprect();

				if (!v.empty())
					bitmap.fill(ch_color, v);
				if (!h.empty())
					bitmap.fill(ch_color, h);
			}
		}
	}
Exemplo n.º 7
0
void
ccv(const cv::Mat &src, feature_ccv &ret)
{
        boost::shared_array<uint32_t>  labeled;
        boost::unordered_map<uint32_t, label_info> labels;
        cv::Mat resized;
        int i;

        if (src.channels() != 3)
                return;

        cv::resize(src, resized, cv::Size(ccv_width, ccv_height));
        cv::GaussianBlur(resized, resized, cv::Size(3, 3), 0);

        ret.m_alpha = feature_ccv::float_arr(new float[NUM_CCV_COLOR]);
        ret.m_beta  = feature_ccv::float_arr(new float[NUM_CCV_COLOR]);

        for (i = 0; i < NUM_CCV_COLOR; i++) {
                ret.m_alpha[i] = 0.0f;
                ret.m_beta[i]  = 0.0f;
        }

        label_info info;
        rgb        color;
        uint32_t   label;
        int        size;

        size = ccv_width * ccv_height;
        labeled = boost::shared_array<uint32_t>(new uint32_t[size]);

        get_rgb(color, resized, 0, 0);

        label = 0;

        labeled[0] = label;

        info.m_color = color;
        info.m_alias = label;
        info.m_count = 1;

        labels[label] = info;

        int x, y;
        for (x = 1; x < ccv_width; x++) {
                rgb color_here, color_left;

                get_rgb(color_here, resized, x,     0);
                get_rgb(color_left, resized, x - 1, 0);

                if (color_here == color_left) {
                        labels[label].m_count++;
                        labeled[x] = label;
                } else {
                        label++;
                        labeled[x] = label;

                        info.m_color = color_here;
                        info.m_alias = label;
                        info.m_count = 1;

                        labels[label] = info;
                }
        }

        for (y = 1; y < ccv_height; y++) {
                rgb c_here, c_left, c_above, c_above_l, c_above_r;
                for (x = 0; x < ccv_width; x++) {
                        get_rgb(c_here, resized, x, y);

                        if (x == 0) {
                                c_left.m_color32    = 0xffffffff;
                                c_above_l.m_color32 = 0xffffffff;
                        }

                        if (x + 1 < ccv_width)
                                get_rgb(c_above_r, resized, x + 1, y - 1);
                        else
                                c_above_r.m_color32 = 0xffffffff;

                        get_rgb(c_above, resized, x, y - 1);


                        uint32_t same[4];
                        uint32_t l;
                        int      num_same = 0;

                        if (c_here == c_left) {
                                l = labeled[x - 1 + y * ccv_width];
                                same[num_same] = find_label(l, labels);
                                num_same++;
                        }

                        if (c_here == c_above) {
                                l = labeled[x + (y - 1) * ccv_width];
                                same[num_same] = find_label(l, labels);
                                num_same++;
                        }

                        if (c_here == c_above_l) {
                                l = labeled[x - 1 + (y - 1) * ccv_width];
                                same[num_same] = find_label(l, labels);
                                num_same++;
                        }

                        if (c_here == c_above_r) {
                                l = labeled[x + 1 + (y - 1) * ccv_width];
                                same[num_same] = find_label(l, labels);
                                num_same++;
                        }

                        if (num_same > 0) {
                                boost::unordered_map<uint32_t,
                                        label_info>::iterator it1, it2;
                                uint32_t label_min = same[0];

                                for (i = 1; i < num_same; i++) {
                                        if (same[i] < label_min) {
                                                label_min = same[i];
                                        }
                                }

                                it1 = labels.find(label_min);
                                it1->second.m_count++;

                                for (i = 0; i < num_same; i++) {
                                        if (label_min < same[i]) {
                                                it2 = labels.find(same[i]);

                                                int count = it2->second.m_count;

                                                it2->second.m_alias = label_min;
                                                it2->second.m_count = 0;

                                                it1->second.m_count += count;
                                        }
                                }

                                labeled[x + y * ccv_width] = label_min;
                        } else {
                                label++;
                                labeled[x + y * ccv_width] = label;

                                info.m_color = c_here;
                                info.m_alias = label;
                                info.m_count = 1;

                                labels[label] = info;
                        }
                }

                c_left    = c_here;
                c_above   = c_above_r;
                c_above_l = c_above;
        }

        boost::unordered_map<uint32_t, label_info>::iterator it;
        for (it = labels.begin(); it != labels.end(); ++it) {
                int idx;
                idx = rgb2idx(it->second.m_color);

                if (it->second.m_count > t_ccv) {
                        ret.m_alpha[idx] += it->second.m_count;
                } else {
                        ret.m_beta[idx] += it->second.m_count;
                }
        }

        float num_pix = ccv_width * ccv_height;
        for (i = 0; i < NUM_CCV_COLOR; i++) {
                ret.m_alpha[i] /= num_pix;
                ret.m_beta[i]  /= num_pix;
        }
}