view draw_smart.pde @ 0:ebd5689e2985

Initial import of Multipaint sketch version 22.5.2017.
author Tero Heikkinen
date Tue, 03 Jul 2018 20:56:55 +0300
parents
children 5eb3559e1778
line wrap: on
line source

//all "intelligent" stuff, the color behavior
//and flood fills

void consistency()
{
  int xx,yy,ad,a,b,x0,y0,x2,y2;
  int pat,mat,fad,bad,maxxy,mulu,ymax;
  if(g_multic==1||g_multic==2)return;
  maxxy=MY;mat=64;mulu=8;ymax=7;
  if(g_attrimode==0){mat=8;mulu=1;maxxy=Y;ymax=0;}
  for(yy=0;yy<MY;yy++){
    for(xx=0;xx<MX;xx++){
      a=getattra(xx*8,yy*mulu,0);
      b=getattra(xx*8,yy*mulu,1);
      if(a==b){
          for(y0=0;y0<=ymax;y0++){
             for(x0=0;x0<=7;x0++){
               ad=1024+(xx*8)+(yy*X*mulu)+x0+y0*X;
               g_map[ad]=byte(0);
           }
        }
      }
      pat=0;
       for(y0=0;y0<=ymax;y0++){
         for(x0=0;x0<=7;x0++){
           ad=1024+(xx*8)+(yy*X*mulu)+x0+y0*X;
           pat=pat+int(g_map[ad]);
         }
      }
      if(pat==mat||pat==0){
        for(y0=0;y0<=ymax;y0++){
          fad=65536+xx+(yy*mulu+y0)*MX;  
          bad=fad+(MX*MY*8);  
          if(pat==0)g_map[fad]=g_map[bad];
          if(pat==mat)g_map[bad]=g_map[fad];
        }      
      }
   }
  }
}

void floodfillmc(int xx,int yy,int mou)
{
  int x,y,molox,ax,ay,valid,okay,par,npar;
  npar=0;par=0;molox=1;

  for(x=0;x<X;x++){
    for(y=0;y<Y;y++){
      g_fillmap[1024+x+y*X]=0;
    }
  }
  
  if(g_multic==1||g_hzoomer==2)molox=2;
  if(molox==2){xx=xx/2;xx=xx*2;}
  if(mou==LEFT){par=g_farge;npar=getmultic(xx,yy,0);}
  if(mou==RIGHT){par=g_backg;npar=getmultic(xx,yy,0);}

  g_fillmap[1024+xx+yy*X]=byte(100);
  if(molox==2)g_fillmap[1024+xx+yy*X+1]=byte(0);
  valid=0;okay=0;
  
  while(okay==0){
    
    valid=0;

    for(x=0;x<X;x=x+molox){
      for(y=0;y<Y;y++){
        ax=int(g_fillmap[1024+x+y*X]);
        if(ax>=100&&ax<=199){
        valid=1;   
        if(y>0){
         if(getmultic(x,y-1,0)==npar&&g_fillmap[1024+x+(y-1)*X]==0){g_fillmap[1024+x+(y-1)*X]=byte(100);
           if(molox==2){g_fillmap[1024+x+(y-1)*X+1]=byte(0);}
           valid=1;} 
        }
        if(x>0){
         if(getmultic(x-molox,y,0)==npar&&g_fillmap[1024+(x-molox)+(y)*X]==0){g_fillmap[1024+(x-molox)+y*X]=byte(100);
           if(molox==2){g_fillmap[1024+(x-molox)+y*X+1]=byte(0);}
           valid=1;} 
        }      
        if(x<X-2){
         if(getmultic(x+molox,y,0)==npar&&g_fillmap[1024+(x+molox)+(y)*X]==0){g_fillmap[1024+(x+molox)+y*X]=byte(100);
           if(molox==2){g_fillmap[1024+(x+molox)+y*X+1]=byte(0);}
           valid=1;} 
        }          
        if(y<Y-1){
         if(getmultic(x,y+1,0)==npar&&g_fillmap[1024+x+(y+1)*X]==0){g_fillmap[1024+x+(y+1)*X]=byte(100);
           if(molox==2){g_fillmap[1024+x+(y+1)*X+1]=byte(0);}
           valid=1;} 
        }      
        
         g_fillmap[1024+x+y*X]=byte(200);
         if(molox==2)g_fillmap[1024+x+y*X+1]=byte(0);
       }
    }
  }
  
  if(valid==0)okay=1;
  
  }  
  
  for(x=0;x<X;x=x+molox){
    for(y=0;y<Y;y++){
      if(int(g_fillmap[1024+x+y*X])>=200){g_farge=par;mkaveri(x,y,par,0);makepoint(x,y);g_farge=g_ofarge;}
   }
  }  
}

void transchar(int xx,int yy)
{
  int fad,bad,ad,pt,x0,y0;
  int aa,bb,pp,ya,yb;
    ya=0;yb=0;
    xx=xx/8;
    
    if(g_attrimode==1){yy=yy/8;yy=yy*8;ya=0;yb=7;}//zx spec etc
    if(g_attrimode==0){ya=0;yb=0;}//msx
    
    for(y0=ya;y0<=yb;y0++){
       fad=65536+xx+(yy+y0)*MX;  
       bad=fad+(MX*MY*8);   
       aa=int(g_map[fad]);
       bb=int(g_map[bad]);
       g_map[fad]=byte(bb);
       g_map[bad]=byte(aa);
    }
    for(y0=ya;y0<=yb;y0++){
      for(x0=0;x0<=7;x0++){
         ad=1024+(xx*8)+(yy*X)+x0+y0*X;
         pp=int(g_map[ad]);
         pp=1-pp;
         g_map[ad]=byte(pp);
     }
    }
}

void prepare_char(int xx,int yy,int farbe)
{

  //changes the char foreg/backg into "favorable" relative to used color
  //needed in floodfill
  
  int fad,bad,ad,pt,x0,y0;
  int aa,bb,pp,ya,yb;
  ya=0;yb=0;
  
  pt=int(g_map[1024+xx+yy*X]);
  if(pt==0&&g_data['r']==0&&g_data['R']==0){
    //println("trans char "+xx+"."+yy);
    xx=xx/8;
    if(g_attrimode==1){yy=yy/8;yy=yy*8;ya=0;yb=7;}//zx spec etc
    if(g_attrimode==0){ya=0;yb=0;}//msx style
    for(y0=ya;y0<=yb;y0++){
      fad=65536+xx+(yy+y0)*MX;  
      bad=fad+(MX*MY*8);   
      aa=int(g_map[fad]);
      bb=int(g_map[bad]);
      g_map[fad]=byte(bb);
      g_map[bad]=byte(aa);
    }
    for(y0=ya;y0<=yb;y0++){
     for(x0=0;x0<=7;x0++){
       ad=1024+(xx*8)+(yy*X)+x0+y0*X;
       pp=int(g_map[ad]);
       pp=1-pp;
       g_map[ad]=byte(pp);
     }
    }
  }
}

void floodfill_iq(int xx,int yy,int mou)
{
  int x,y,ax,ay,valid,okay,par,npar;
  npar=0;par=0;
  if(mou==LEFT)par=g_farge;
  if(mou==RIGHT)par=g_backg;
  if(getabsa(xx,yy,0)==par)return;
  consistency();
  npar=getabsa(xx,yy,0);
  prepare_char(xx,yy,npar);
  for(x=0;x<X;x++){
    for(y=0;y<Y;y++){
      g_fillmap[1024+x+y*X]=0;
    }
  }
  g_fillmap[1024+xx+yy*X]=byte(100);
  valid=0;okay=0;
  while(okay==0){
    valid=0;

    for(x=0;x<X;x++){
      for(y=0;y<Y;y++){
        ax=int(g_fillmap[1024+x+y*X]);
        if(ax==100){
          valid=1;   
          if(y>0){
             if(getabsa(x,y-1,0)==npar&&g_fillmap[1024+x+(y-1)*X]==0){prepare_char(x,y-1,npar);g_fillmap[1024+x+(y-1)*X]=byte(100);valid=1;} 
          }
          if(x>0){
             if(getabsa(x-1,y,0)==npar&&g_fillmap[1024+(x-1)+y*X]==0){prepare_char(x-1,y,npar);g_fillmap[1024+(x-1)+y*X]=byte(100);valid=1;} 
          }      
          if(x<X-1){
             if(getabsa(x+1,y,0)==npar&&g_fillmap[1024+(x+1)+y*X]==0){prepare_char(x+1,y,npar);g_fillmap[1024+(x+1)+y*X]=byte(100);valid=1;} 
          }          
          if(y<Y-1){
             if(getabsa(x,y+1,0)==npar&&g_fillmap[1024+x+(y+1)*X]==0){prepare_char(x,y+1,npar);g_fillmap[1024+x+(y+1)*X]=byte(100);valid=1;} 
          }      
          g_fillmap[1024+x+y*X]=byte(200);
      }
    }
  }
  if(valid==0)okay=1;
  }
  
  for(x=0;x<X;x++){
    for(y=0;y<Y;y++){
      ax=int(g_fillmap[1024+x+y*X]);
      if(ax==200){
         g_farge=par;
         makepoint(x,y);
         g_fillmap[1024+x+y*X]=0;
      } 
    }
  }
  g_farge=g_ofarge; 
}

//adaptive color helper for low-attribute modes
//reasons the background color for each char as you draw
//=changed

void fixattr(int x,int y,int foreg,int backg)
{
  int bad,cad,miny,maxy;
  
  if(g_britemode==1){
    if(foreg==8||backg==8||foreg==0||backg==0)return;
  }
  
  miny=y/8;miny=miny*8;maxy=y-miny;miny=maxy;
  y=y/8;y=y*8;
  if(g_attrimode==1){miny=0;maxy=7;}
  
  for(int i=miny;i<=maxy;i++){
    bad=65536+(x/8)+(y+i)*MX;
    cad=bad+MX*(MY*8);
    if(foreg>=0){
      g_map[bad]=byte(foreg);
      if(foreg>=8&&g_map[cad]<8)g_map[cad]=byte(g_map[cad]+8);
      if(foreg<8&&g_map[cad]>=8)g_map[cad]=byte(g_map[cad]-8);    
    }
    if(backg>=0){
      g_map[cad]=byte(backg);
      if(backg>=8&&g_map[bad]<8)g_map[bad]=byte(g_map[bad]+8);
      if(backg<8&&g_map[bad]>=8)g_map[bad]=byte(g_map[bad]-8);        
    }
  }
  updatepoint(x,y);
}

//multicolor color behavior
//different behavior depending on whether color area already has max colors,
//or if forcecolor is pressed.
//bit different for C64 and PLUS4M

void skaveri(int x,int y,int foreg,int backg)
{
  int mx=x/8;
  int my=y/8;
  if(g_control==false)return;
  int cc=easygetcolor(x,y);
  mx=mx*8;my=my*8;
  for(int xx=0;xx<=7;xx++){
    for(int yy=0;yy<=7;yy++){
      if(easygetcolor(mx+xx,my+yy)==cc){
        g_map[1024+mx+xx+(my+yy)*X]=byte(foreg);
      }
    }
  }
  updatepoint(x,y);
}

void mkaveri(int x,int y,int foreg,int backg)
{
  int mx=x/8;
  int my=y/8;
  int ad,bad,cad,dad,b0,b1;
  int f0,f1,f2,f3,free1,free2,free3;
  int f,order,numb,suffocatelimit;
  int targetbit0,targetbit1;
  order=0;numb=0;targetbit0=0;targetbit1=0;suffocatelimit=7;
  
  f=getmultic(x,y,0);
  if(g_data['d']==1&&f!=g_backg)return;
  
  cad=65536+mx+(my*MX);
  
  f0=int(g_map[1]); 
  f1=int(g_map[cad]);free1=1;        
  f2=int(g_map[cad+1000]);free2=1;
  f3=int(g_map[cad+2000]);free3=1;
  if(machine==PLUS4M){free3=0;suffocatelimit=3;f3=int(g_map[2]);}
  
  if(foreg==g_map[1]&&g_control==false)return;
  
  if(foreg!=f1&&foreg!=f2&&foreg!=f3||g_control==true){
   for(int yy=0;yy<=7;yy++){
      for(int xx=0;xx<=3;xx++){
        ad=1024+(mx*8+xx*2)+(my*8+yy)*X;
        if(g_map[ad]==0&&g_map[ad+1]==0){//00 = 00
          if(f0==f)order=4;
        }        
        if(g_map[ad]==1&&g_map[ad+1]==0){//01 = 10
          numb=numb|1;free1=0;
          if(f1==f)order=1;
        }
        if(g_map[ad]==0&&g_map[ad+1]==1){//02 = 01
          numb=numb|2;free2=0;
          if(f2==f)order=2;
        }
        if(g_map[ad]==1&&g_map[ad+1]==1){//03 = 11
          if(machine==C64M){numb=numb|4;free3=0;}
          if(f3==f){order=3;targetbit0=1;targetbit1=1;}
        }      
      }
    }
   
   boolean zoink=false;
   if(order==4)zoink=true;
   if(order==3&&machine==PLUS4M)zoink=true;
   
   if((zoink||numb!=suffocatelimit)&&g_control==true){
     if(zoink){ 
       //println("foreg:"+foreg+" f0:"+f0+" f1:"+f1+" f2:"+f2+" f3:"+f3+" free1:"+free1+" free2:"+free2+" free3:"+free3);
       b0=-1;b1=-1;
       if(foreg==f1&&free1==0){b0=1;b1=0;}
       if(foreg==f2&&free2==0){b0=0;b1=1;}
       if(foreg==f3&&machine==C64M&&free3==0){b0=1;b1=1;}
       if(foreg==f3&&machine==PLUS4M){b0=1;b1=1;}
       
       if(free1==1){
         free2=0;free3=0;b0=1;b1=0;g_map[cad]=byte(foreg);
       }
       if(free2==1){
         free3=0;b0=0;b1=1;g_map[cad+1000]=byte(foreg);
       }
       if(free3==1){
         b0=1;b1=1;g_map[cad+2000]=byte(foreg);
       }
       
       for(int yy=0;yy<=7;yy++){
          for(int xx=0;xx<=3;xx++){
              ad=1024+(mx*8+xx*2)+(my*8+yy)*X;
            if(g_map[ad]==targetbit0&&g_map[ad+1]==targetbit1){
              if(b0>=0){
                g_map[ad]=byte(b0);g_map[ad+1]=byte(b1);
              }
            }
          }
       }
     }
   }
   
   //if all color positions are filled, we'll just change the existing one
   
    if(numb==suffocatelimit||g_control==true){
      if(order==1){g_map[cad]=byte(foreg);}//10==1
      if(order==2){g_map[cad+1000]=byte(foreg);}//01==2
      if(order==3&&machine==C64M){g_map[cad+2000]=byte(foreg);}//11==3      
    }
    
    //color redundancy check
    
      for(int yy=0;yy<=7;yy++){
          for(int xx=0;xx<=3;xx++){
            ad=1024+(mx*8+xx*2)+(my*8+yy)*X;
            
            if(machine==C64M){
              if(g_map[cad]==g_map[cad+2000]){
                if(g_map[ad]==1&&g_map[ad+1]==1){
                  g_map[ad]=1;g_map[ad+1]=0;
                }
              }
              if(g_map[cad+1000]==g_map[cad+2000]){
                if(g_map[ad]==1&&g_map[ad+1]==1){
                  g_map[ad]=0;g_map[ad+1]=1;
                }
              }          
            }                
            
            if(g_map[cad]==g_map[cad+1000]){
              if(g_map[ad]==0&&g_map[ad+1]==1){
                g_map[ad]=1;g_map[ad+1]=0;
              }
            }
            if(g_map[1]==g_map[cad]){
                if(g_map[ad]==1&&g_map[ad+1]==0){
                g_map[ad]=0;g_map[ad+1]=0;
                }
            }
            if(g_map[1]==g_map[cad+1000]){
                if(g_map[ad]==0&&g_map[ad+1]==1){
                  g_map[ad]=0;g_map[ad+1]=0;
                }
            }
            
            if(machine==PLUS4M){
              if(g_map[2]==g_map[cad]){
                  if(g_map[ad]==1&&g_map[ad+1]==0){
                  g_map[ad]=1;g_map[ad+1]=1;
                  }
              }
              if(g_map[2]==g_map[cad+1000]){
                  if(g_map[ad]==0&&g_map[ad+1]==1){
                    g_map[ad]=1;g_map[ad+1]=1;
                  }
              }
              if(g_map[1]==g_map[2]){
                if(g_map[ad]==1&&g_map[ad+1]==1){
                  g_map[ad]=0;g_map[ad+1]=0;
                }
              }              
            }
            
            if(machine==C64M){
              if(g_map[1]==g_map[cad+2000]){
                  if(g_map[ad]==1&&g_map[ad+1]==1){
                    g_map[ad]=0;g_map[ad+1]=0;
                  }
              }               
            }
          }
      }
    }
    updatepoint(x,y);
}

void kaveri(int x,int y,int foreg,int backg)
{
  int k_max;
  int maxy,miny;
  int ad,bad,cad;
  int mx,my,val;
  int farge0,farge1;
  if(g_multic!=0||g_hzoomer==2)return;
  if(g_data['d']==1)return;
  mx=x/8;my=y/8;
 
  if(g_attrimode==1)
    {k_max=64;miny=0;maxy=7;}
  else
    {k_max=8;miny=y/8;miny=miny*8;maxy=y-miny;miny=maxy;}
  
  if(g_britemode==1&&foreg==8)foreg=0;

  //check the amount of colors in the area
  //if there is only one, return & draw "normally"
  
  if(g_control==false){
    
    val=0;
    
    for(int yy=miny;yy<=maxy;yy++){
      ad=1024+(mx*8)+(my*8+yy)*X;
      for(int xx=0;xx<=7;xx++){
        val=val+g_map[ad+xx];
      }
    }
    
    if(val>=k_max||val==0)return;
  
    //check the two colors the color area is made of
    //if either of the intended color already exists inside the color area, return & draw "normally"
    
    bad=65536+mx+y*MX;
    cad=bad+MX*(MY*8);
    farge0=g_map[bad];//if(g_britemode==1&&farge0==8){farge0=0;}
    farge1=g_map[cad];//if(g_britemode==1&&farge1==8){farge1=0;}
    
    if(g_britemode==1){
      if(farge0<8){
        if(foreg==farge0+8){
          fixattr(x,y,foreg,-1);return;
        }
      }    
      if(farge1<8){
        if(foreg==farge1+8){
          fixattr(x,y,-1,foreg);return;
        }        
      }
      if(farge0>=8){
        if(foreg==farge0-8){
          fixattr(x,y,foreg,-1);return;
        }
      }        
      if(farge1>=8){
        if(foreg==farge1-8){
          fixattr(x,y,-1,foreg);return;
        }        
      }
    }
    if(foreg==farge0)return;
    if(foreg==farge1)return;

  //new IQ: simply change the underlying color into the intended one, return & draw "normally"
  
  }
  
  int piksuf;
  int bg,fg;
  piksuf=getabsa(x,y,0);
  if(g_britemode==1&&piksuf==8)piksuf=0;
  bad=0;cad=0;
  for(int yy=miny;yy<=maxy;yy++){
      bad=65536+mx+(my*8)*MX+yy*MX;
      cad=bad+MX*(MY*8);
      fg=g_map[bad];if(g_britemode==1&&fg==8)fg=0;
      bg=g_map[cad];if(g_britemode==1&&bg==8)bg=0;
        if(piksuf==fg){
          g_map[bad]=byte(foreg);
          if(g_britemode==1){
            if(foreg>7&&g_map[cad]<8&&g_map[cad]!=0){
              g_map[cad]=byte(g_map[cad]+8);
            }
            if(foreg<8&&g_map[cad]>8&&foreg!=0){
              g_map[cad]=byte(g_map[cad]-8);
            }          
          }
        }
        if(piksuf==bg){
          g_map[cad]=byte(foreg);      
          if(g_britemode==1){
            if(foreg>7&&g_map[bad]<8&&g_map[bad]!=0){
              g_map[bad]=byte(g_map[bad]+8);
            }
            if(foreg<8&&g_map[bad]>8&&foreg!=0){
              g_map[bad]=byte(g_map[bad]-8);
            }
          }          
        }
  } 
  
  // if the result is same color, zero the pixel data
  
  if(g_map[bad]==g_map[cad]){
    for(int yy=miny;yy<=maxy;yy++){
       for(int xx=0;xx<=7;xx++){
         ad=1024+(mx*8+xx)+(my*8+yy)*X;
         g_map[ad]=byte(0);
     }
    }
  }
  updatepoint(x,y);
}

void kaveri_iq(int x,int y,int f1,int f2)
{
  int k_xx,k_yy,k_ad,k_bad,k_ojox,k_ojoy,k_miny,k_maxy,k_xv,k_yv;
  int k_c1,k_c2,k_v0,k_v1,k_tipping,k_maximum;
  byte k_p;
  
  if(g_multic!=0||g_hzoomer==2)return;
  
  int exist;

  exist=getabsa(x,y,0);
  
  if(g_britemode==1){
    if(exist==8){if(g_farge<8){exist=0;}}
    if(exist==0){if(g_farge>7){exist=0;}}
  }
  
  k_v0=0;k_v1=0;k_tipping=4;
  k_xx=x/8;k_yy=y/8;k_yy=k_yy*8;k_ojox=x/8;k_ojoy=y/8;
  k_ojox=k_ojox*8;k_ojoy=k_ojoy*8;k_miny=(y-k_ojoy);k_maxy=k_miny;k_maximum=8;
  
  if(g_attrimode==1){k_miny=0;k_maxy=7;k_tipping=32;k_maximum=64;}//spectrum&c64 style
  
  k_ad=65536+k_xx+(k_yy+k_miny)*MX;k_bad=k_ad+MX*(MY*8);
  k_c1=g_map[k_ad];k_c2=g_map[k_bad];
  
  if(g_britemode==1){
    if(k_c1==8)k_c1=0;
    if(k_c2==8)k_c2=0;
  }
  
  k_bad=1024+k_xx*8+k_yy*X;
  
  //do we have more 0's or 1's
  for(k_yv=k_miny;k_yv<=k_maxy;k_yv++){
    k_ad=k_bad+k_yv*X;
    for(k_xv=0;k_xv<=7;k_xv++){
        if(g_map[k_ad]==1){k_v1++;}else{k_v0++;}
        k_ad++;
    }
  }
  
  //force color
  
  if(g_control){
    
    k_v1=k_tipping+1;
    
    if(k_c1==exist){k_c1=g_farge;  
      if(k_c1==8&&g_britemode==1)k_c1=0;
    }
    if(k_c2==exist){k_c2=g_farge;
      if(k_c2==8&&g_britemode==1)k_c2=0;
    }
    
    if(g_britemode==1){
      if(g_farge>=8){
        if(k_c1<=7)k_c1=k_c1+8;
        if(k_c2<=7)k_c2=k_c2+8;
      }
    if(g_farge<=7){
        if(k_c1>=8)k_c1=k_c1-8;
        if(k_c2>=8)k_c2=k_c2-8;
      }
    }
    
  }
  
  if(k_v1>k_tipping){
      for(k_yv=k_miny;k_yv<=k_maxy;k_yv++){
        k_ad=65536+k_xx+(k_yy+k_yv)*MX;
        k_bad=k_ad+MX*(MY*8);g_map[k_ad]=byte(k_c2);g_map[k_bad]=byte(k_c1);
      }
      for(k_yv=k_miny;k_yv<=k_maxy;k_yv++){
        k_ad=1024+k_xx*8+(k_yy+k_yv)*X;
        for(k_xv=0;k_xv<=7;k_xv++){
          k_p=g_map[k_ad];
          g_map[k_ad]=byte(1-k_p);
          if(k_c1==k_c2)g_map[k_ad]=byte(0);
          k_ad++;
      }
    }    
  }
  updatepoint(x,y);
}