Mercurial > hg > forks > multipaint-js
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); }