|
|
#help_index "Graphics/Sprite;Sprites" |
|
|
|
|
|
CSprite *SpriteSetSettings(CDC *dc=NULL,CSprite *head,I64 elem_num, |
|
|
I64 x=0,I64 y=0,CColorROPU32 *_color=NULL,I64 *_width=NULL, |
|
|
I64 *_xx=NULL,I64 *_yy=NULL) |
|
|
{ |
|
|
CSprite *res=head->next; |
|
|
I64 width=1,xx=0,yy=0; |
|
|
CColorROPU32 color=BLACK; |
|
|
if (dc) DCRst(dc); |
|
|
while (elem_num-->0 && res!=head) { |
|
|
switch (res->type&SPG_TYPE_MASK) { |
|
|
case SPT_COLOR: |
|
|
color=res->c.color; |
|
|
if (dc) dc->color=color; |
|
|
break; |
|
|
case SPT_DITHER_COLOR: |
|
|
color=res->d.dither_color.u8[0]| |
|
|
res->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER; |
|
|
if (dc) dc->color=color; |
|
|
break; |
|
|
case SPT_WIDTH: |
|
|
width=res->w.width; |
|
|
if (dc) dc->pen_width=width; |
|
|
break; |
|
|
case SPT_SHIFT: |
|
|
xx+=res->p.x1; |
|
|
yy+=res->p.y1; |
|
|
x+=res->p.x1; |
|
|
y+=res->p.y1; |
|
|
break; |
|
|
case SPT_PLANAR_SYMMETRY: |
|
|
if (dc) { |
|
|
if (DCSymmetry3Set(dc,res->pp.x1+x,res->pp.y1+y,0, |
|
|
res->pp.x2+x,res->pp.y2+y,0, |
|
|
res->pp.x2+x,res->pp.y2+y,1)) |
|
|
dc->flags|=DCF_SYMMETRY; |
|
|
else |
|
|
dc->flags&=~DCF_SYMMETRY; |
|
|
} |
|
|
break; |
|
|
} |
|
|
res=res->next; |
|
|
} |
|
|
if (_color) *_color=color; |
|
|
if (_width) *_width=width; |
|
|
if (_xx) *_xx=xx; |
|
|
if (_yy) *_yy=yy; |
|
|
return res; |
|
|
} |
|
|
|
|
|
Bool SpritePolyPtPlot(CSprite *head,I64 x,I64 y,I64) |
|
|
{ |
|
|
CSprite *tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_PT)); |
|
|
tmpg->type=SPT_PT; |
|
|
tmpg->p.x1=x; |
|
|
tmpg->p.y1=y; |
|
|
QueIns(tmpg,head->last); |
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
CSprite *Sprite2SpriteQue(U8 *elems) |
|
|
{ |
|
|
I64 s; |
|
|
CSprite *res=CAlloc(sizeof(CSprite)), |
|
|
*tmpg=elems-offset(CSprite.start),*tmpg1; |
|
|
QueInit(res); |
|
|
while (tmpg->type&SPG_TYPE_MASK) { |
|
|
tmpg1=MAlloc(SpriteElemSize(tmpg)+offset(CSprite.start)); |
|
|
s=SpriteElemSize(tmpg); |
|
|
MemCpy(&tmpg1->start,&tmpg->start,s); |
|
|
QueIns(tmpg1,res->last); |
|
|
tmpg(U8 *)+=s; |
|
|
} |
|
|
return res; |
|
|
} |
|
|
|
|
|
U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL) |
|
|
{ |
|
|
I64 i,size=sprite_elem_base_sizes[SPT_END]; |
|
|
CSprite *tmpg=head->next; |
|
|
U8 *res,*dst; |
|
|
while (tmpg!=head) { |
|
|
size+=SpriteElemSize(tmpg); |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
if (_size) *_size=size; |
|
|
res=dst=MAlloc(size); |
|
|
tmpg=head->next; |
|
|
while (tmpg!=head) { |
|
|
i=SpriteElemSize(tmpg); |
|
|
MemCpy(dst,&tmpg->start,i); |
|
|
dst+=i; |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
*dst=SPT_END; |
|
|
return res; |
|
|
} |
|
|
|
|
|
U0 SpriteEdUpdate(CDoc *doc,CDocEntry *doc_ce,CSprite *head) |
|
|
{ |
|
|
CDocBin *tmpb=doc_ce->bin_data; |
|
|
I64 size; |
|
|
Bool unlock=DocLock(doc); |
|
|
Free(tmpb->data); |
|
|
tmpb->data=SpriteQue2Sprite(head,&size); |
|
|
tmpb->size=size; |
|
|
if (unlock) |
|
|
DocUnlock(doc); |
|
|
} |
|
|
|
|
|
U0 SpriteSetOrigin(CSprite *head,I64 dx,I64 dy,I64 dz) |
|
|
{ |
|
|
I64 i; |
|
|
I32 *ptr; |
|
|
CD3I32 *p; |
|
|
CSprite *tmpg=head->next; |
|
|
while (tmpg!=head) { |
|
|
if (Bt(&tmpg->type,SPf_SEL)) |
|
|
switch (tmpg->type&SPG_TYPE_MASK) { |
|
|
case SPT_ARROW: |
|
|
case SPT_LINE: |
|
|
case SPT_PLANAR_SYMMETRY: |
|
|
case SPT_RECT: |
|
|
case SPT_ROTATED_RECT: |
|
|
tmpg->pp.x2+=dx; |
|
|
tmpg->pp.y2+=dy; |
|
|
case SPT_PT: |
|
|
case SPT_FLOOD_FILL: |
|
|
case SPT_FLOOD_FILL_NOT: |
|
|
case SPT_TEXT: |
|
|
case SPT_TEXT_BOX: |
|
|
case SPT_TEXT_DIAMOND: |
|
|
case SPT_CIRCLE: |
|
|
case SPT_BITMAP: |
|
|
case SPT_ELLIPSE: |
|
|
case SPT_POLYGON: |
|
|
tmpg->p.x1+=dx; |
|
|
tmpg->p.y1+=dy; |
|
|
break; |
|
|
case SPT_POLYLINE: |
|
|
ptr=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++) { |
|
|
ptr[i<<1]+=dx; |
|
|
ptr[i<<1+1]+=dy; |
|
|
} |
|
|
break; |
|
|
case SPT_POLYPT: |
|
|
tmpg->npu.x+=dx; |
|
|
tmpg->npu.y+=dy; |
|
|
break; |
|
|
case SPT_BSPLINE2: |
|
|
case SPT_BSPLINE3: |
|
|
case SPT_BSPLINE2_CLOSED: |
|
|
case SPT_BSPLINE3_CLOSED: |
|
|
p=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++,p++) { |
|
|
p->x+=dx; |
|
|
p->y+=dy; |
|
|
p->z+=dz; |
|
|
} |
|
|
break; |
|
|
case SPT_MESH: |
|
|
p=&tmpg->mu.u; |
|
|
for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) { |
|
|
p->x+=dx; |
|
|
p->y+=dy; |
|
|
p->z+=dz; |
|
|
} |
|
|
break; |
|
|
case SPT_SHIFTABLE_MESH: |
|
|
tmpg->pmu.x+=dx; |
|
|
tmpg->pmu.y+=dy; |
|
|
tmpg->pmu.z+=dz; |
|
|
break; |
|
|
} |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
} |
|
|
|
|
|
CSprite *SpriteTransformCircle(I64 *r,CSprite *tmpg) |
|
|
{ |
|
|
I64 x,y,z; |
|
|
F64 m1,arg1,m2,radius=tmpg->pr.radius<<16; |
|
|
CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ELLIPSE)); |
|
|
tmpg1->type=SPT_ELLIPSE; |
|
|
|
|
|
x=tmpg->pr.x1; y=tmpg->pr.y1; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg1->pwha.x1=x; |
|
|
tmpg1->pwha.y1=y; |
|
|
|
|
|
x=radius; y=0; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
R2P(&m1,&arg1,x,y); |
|
|
|
|
|
x=0; y=radius; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
m2=Sqrt(x*x+y*y); |
|
|
|
|
|
tmpg1->pwha.width =ToI64(m1)/0x10000; |
|
|
tmpg1->pwha.height=ToI64(m2)/0x10000; |
|
|
tmpg1->pwha.angle=-arg1; |
|
|
|
|
|
tmpg1->type|=tmpg->type&SPF_SEL; |
|
|
return tmpg1; |
|
|
} |
|
|
|
|
|
CSprite *SpriteTransformEllipse(I64 *r,CSprite *tmpg) |
|
|
{ |
|
|
I64 x,y,z; |
|
|
F64 m1,arg1,m2,arg2,s,c,x_radius=tmpg->pwha.width<<16, |
|
|
y_radius=tmpg->pwha.height<<16; |
|
|
CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(tmpg->type&SPG_TYPE_MASK)); |
|
|
tmpg1->type=tmpg->type; |
|
|
if (tmpg->type&SPG_TYPE_MASK==SPT_POLYGON) |
|
|
tmpg1->pwhas.sides=tmpg->pwhas.sides; |
|
|
|
|
|
x=tmpg->pwha.x1; y=tmpg->pwha.y1; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg1->pwha.x1=x; |
|
|
tmpg1->pwha.y1=y; |
|
|
|
|
|
c=Cos(-tmpg->pwha.angle); |
|
|
s=Sin(-tmpg->pwha.angle); |
|
|
|
|
|
x=x_radius*c; |
|
|
y=x_radius*s; |
|
|
z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
R2P(&m1,&arg1,x,y); |
|
|
|
|
|
x=-y_radius*s; |
|
|
y=y_radius*c; |
|
|
z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
R2P(&m2,&arg2,x,y); |
|
|
m2*=Abs(Sin(arg2-arg1)); |
|
|
|
|
|
tmpg1->pwha.width=ToI64(m1)/0x10000; |
|
|
if (tmpg1->pwha.width<1) tmpg1->pwha.width=1; |
|
|
tmpg1->pwha.height=ToI64(m2)/0x10000; |
|
|
if (tmpg1->pwha.height<1) tmpg1->pwha.height=1; |
|
|
tmpg1->pwha.angle=-arg1; |
|
|
|
|
|
tmpg1->type|=tmpg->type&SPF_SEL; |
|
|
return tmpg1; |
|
|
} |
|
|
|
|
|
CSprite *SpriteTransformRect(I64 *r,CSprite *tmpg,F64 <EFBFBD>) |
|
|
{ |
|
|
I64 x,y,z,w,h; |
|
|
F64 m1,arg1,m2,arg2,s,c, |
|
|
x_radius=(tmpg->pp.x2-tmpg->pp.x1)<<16, |
|
|
y_radius=(tmpg->pp.y2-tmpg->pp.y1)<<16; |
|
|
CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ROTATED_RECT)); |
|
|
tmpg1->type=SPT_ROTATED_RECT; |
|
|
|
|
|
x=tmpg->pp.x1; y=tmpg->pp.y1; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg1->ppa.x1=x; |
|
|
tmpg1->ppa.y1=y; |
|
|
|
|
|
c=Cos(-<EFBFBD>); |
|
|
s=Sin(-<EFBFBD>); |
|
|
|
|
|
x=x_radius*c; |
|
|
y=x_radius*s; |
|
|
z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
R2P(&m1,&arg1,x,y); |
|
|
|
|
|
x=-y_radius*s; |
|
|
y=y_radius*c; |
|
|
z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
R2P(&m2,&arg2,x,y); |
|
|
m2*=Abs(Sin(arg2-arg1)); |
|
|
|
|
|
w=ToI64(m1)/0x10000; |
|
|
if (w<1) w=1; |
|
|
h=ToI64(m2)/0x10000; |
|
|
if (h<1) h=1; |
|
|
tmpg1->ppa.x2=tmpg1->ppa.x1+w; |
|
|
tmpg1->ppa.y2=tmpg1->ppa.y1+h; |
|
|
tmpg1->ppa.angle=-arg1; |
|
|
|
|
|
tmpg1->type|=tmpg->type&SPF_SEL; |
|
|
return tmpg1; |
|
|
} |
|
|
|
|
|
CSprite *SpriteTransformBitMap(I64 *r,CSprite *tmpg) |
|
|
{ |
|
|
CDC *img,*dc3; |
|
|
U8 *elems; |
|
|
I64 x,y,z,minx,maxx,miny,maxy,minz,maxz; |
|
|
CSprite *tmpg1; |
|
|
|
|
|
x=0; y=0; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
minx=maxx=x; |
|
|
miny=maxy=y; |
|
|
minz=maxz=z; |
|
|
|
|
|
x=0; y=tmpg->pwhu.height; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
if (x<minx) minx=x; |
|
|
if (x>maxx) maxx=x; |
|
|
if (y<minx) miny=y; |
|
|
if (y>maxx) maxy=y; |
|
|
if (z<minx) minz=z; |
|
|
if (z>maxx) maxz=z; |
|
|
|
|
|
x=tmpg->pwhu.width; y=0; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
if (x<minx) minx=x; |
|
|
if (x>maxx) maxx=x; |
|
|
if (y<minx) miny=y; |
|
|
if (y>maxx) maxy=y; |
|
|
if (z<minx) minz=z; |
|
|
if (z>maxx) maxz=z; |
|
|
|
|
|
x=tmpg->pwhu.width; y=tmpg->pwhu.height; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
if (x<minx) minx=x; |
|
|
if (x>maxx) maxx=x; |
|
|
if (y<minx) miny=y; |
|
|
if (y>maxx) maxy=y; |
|
|
if (z<minx) minz=z; |
|
|
if (z>maxx) maxz=z; |
|
|
|
|
|
dc3=DCNew(maxx-minx+1,maxy-miny+1); |
|
|
|
|
|
img=CAlloc(sizeof(CDC)); |
|
|
img->width=tmpg->pwhu.width; |
|
|
img->width_internal=(tmpg->pwhu.width+7)&~7; |
|
|
img->height=tmpg->pwhu.height; |
|
|
img->body=&tmpg->pwhu.u; |
|
|
img->dc_signature=DCS_SIGNATURE_VAL; |
|
|
|
|
|
dc3->color=TRANSPARENT; |
|
|
GrRect(dc3,0,0,maxx-minx+1,maxy-miny+1); |
|
|
|
|
|
Free(dc3->r); |
|
|
DCMat4x4Set(dc3,r); |
|
|
dc3->flags|=DCF_TRANSFORMATION; |
|
|
|
|
|
dc3->x=-minx; |
|
|
dc3->y=-miny; |
|
|
dc3->z=-minz; |
|
|
GrBlot3(dc3,0,0,0,img); |
|
|
Free(img); |
|
|
|
|
|
elems=DC2Sprite(dc3); |
|
|
dc3->r=NULL; |
|
|
DCDel(dc3); |
|
|
tmpg1=CAlloc(offset(CSprite.start)+MSize(elems)); |
|
|
MemCpy(tmpg1(U8 *)+offset(CSprite.start),elems,MSize(elems)); |
|
|
tmpg1->type=tmpg->type; |
|
|
|
|
|
x=tmpg->pwhu.x1; y=tmpg->pwhu.y1; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg1->pwhu.x1=x; |
|
|
tmpg1->pwhu.y1=y; |
|
|
|
|
|
x=0; y=0; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg1->pwhu.x1+=minx-x; |
|
|
tmpg1->pwhu.y1+=miny-y; |
|
|
|
|
|
return tmpg1; |
|
|
} |
|
|
|
|
|
U0 SpriteTransformQue(CSprite *head,I64 *r) |
|
|
{ |
|
|
I64 i,j,k,num,x,y,z,x1,y1,z1,x2,y2,z2,x3,y3,z3; |
|
|
I32 *ptr; |
|
|
CD3I32 *p; |
|
|
CSprite *tmpg=head->next,head2,*tmpg1,*tmpg2,*tmpg3; |
|
|
while (tmpg!=head) { |
|
|
if (Bt(&tmpg->type,SPf_SEL)) |
|
|
switch (tmpg->type&SPG_TYPE_MASK) { |
|
|
case SPT_WIDTH: |
|
|
tmpg->w.width*=Sqrt(Mat4x4NormSqr65536(r))/65536; |
|
|
if (tmpg->w.width<0) tmpg->w.width=0; |
|
|
break; |
|
|
case SPT_PLANAR_SYMMETRY: |
|
|
case SPT_ARROW: |
|
|
case SPT_LINE: |
|
|
x=tmpg->pp.x2; y=tmpg->pp.y2; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg->pp.x2=x; |
|
|
tmpg->pp.y2=y; |
|
|
case SPT_PT: |
|
|
case SPT_FLOOD_FILL: |
|
|
case SPT_FLOOD_FILL_NOT: |
|
|
case SPT_TEXT: |
|
|
case SPT_TEXT_BOX: |
|
|
case SPT_TEXT_DIAMOND: |
|
|
x=tmpg->p.x1; y=tmpg->p.y1; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg->p.x1=x; |
|
|
tmpg->p.y1=y; |
|
|
break; |
|
|
case SPT_BITMAP: |
|
|
tmpg1=SpriteTransformBitMap(r,tmpg); |
|
|
QueIns(tmpg1,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg1; |
|
|
break; |
|
|
case SPT_ROTATED_RECT: |
|
|
tmpg1=SpriteTransformRect(r,tmpg,tmpg->ppa.angle); |
|
|
QueIns(tmpg1,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg1; |
|
|
break; |
|
|
case SPT_RECT: |
|
|
tmpg1=SpriteTransformRect(r,tmpg,0); |
|
|
QueIns(tmpg1,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg1; |
|
|
break; |
|
|
case SPT_CIRCLE: |
|
|
tmpg1=SpriteTransformCircle(r,tmpg); |
|
|
QueIns(tmpg1,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg1; |
|
|
break; |
|
|
case SPT_ELLIPSE: |
|
|
case SPT_POLYGON: |
|
|
tmpg1=SpriteTransformEllipse(r,tmpg); |
|
|
QueIns(tmpg1,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg1; |
|
|
break; |
|
|
case SPT_POLYLINE: |
|
|
ptr=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++) { |
|
|
x=ptr[i<<1]; y=ptr[i<<1+1]; z=0; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
ptr[i<<1]=x; |
|
|
ptr[i<<1+1]=y; |
|
|
} |
|
|
break; |
|
|
case SPT_POLYPT: |
|
|
QueInit(&head2); |
|
|
x=tmpg->npu.x; y=tmpg->npu.y; z=0; |
|
|
x1=x; y1=y; z1=z; //unrotated cur coordinates |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
ptr=&tmpg->npu.u; |
|
|
k=tmpg->npu.num*3; |
|
|
x2=x; y2=y; z2=z; //rotated start coordinates |
|
|
x3=x; y3=y; z3=z; //lag 1 rotated coordinates |
|
|
for (i=0;i<k;i+=3) { |
|
|
j=BFieldExtU32(ptr,i,3); |
|
|
x1+=gr_x_offsets[j]; |
|
|
y1+=gr_y_offsets[j]; |
|
|
x=x1; y=y1; z=z1; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
Line(&head2,x3-x2,y3-y2,0,x-x2,y-y2,0,&SpritePolyPtPlot); |
|
|
x3=x; y3=y; z3=z; |
|
|
} |
|
|
|
|
|
num=0; |
|
|
tmpg1=head2.next; |
|
|
x3=0; y3=0; z3=0; |
|
|
while (tmpg1!=&head2) { |
|
|
tmpg2=tmpg1->next; |
|
|
if (tmpg1->p.x1==x3 && tmpg1->p.y1==y3) { |
|
|
QueRem(tmpg1); |
|
|
Free(tmpg1); |
|
|
} else { |
|
|
num++; |
|
|
x3=tmpg1->p.x1; |
|
|
y3=tmpg1->p.y1; |
|
|
} |
|
|
tmpg1=tmpg2; |
|
|
} |
|
|
|
|
|
tmpg3=CAlloc(SpriteElemQuedBaseSize(SPT_POLYPT)+(num*3+7)>>3); |
|
|
tmpg3->npu.x=x2; |
|
|
tmpg3->npu.y=y2; |
|
|
ptr=&tmpg3->npu.u; |
|
|
x3=0;y3=0; z3=0; |
|
|
i=0; |
|
|
tmpg1=head2.next; |
|
|
while (tmpg1!=&head2) { |
|
|
tmpg2=tmpg1->next; |
|
|
BFieldOrU32(ptr,i, |
|
|
polypt_map[SignI64(tmpg1->p.x1-x3)+1+ |
|
|
3*(SignI64(tmpg1->p.y1-y3)+1)]); |
|
|
i+=3; |
|
|
x3=tmpg1->p.x1;y3=tmpg1->p.y1; |
|
|
QueRem(tmpg1); |
|
|
Free(tmpg1); |
|
|
tmpg1=tmpg2; |
|
|
} |
|
|
tmpg3->type=SPT_POLYPT|tmpg->type&SPF_SEL; |
|
|
tmpg3->npu.num=num; |
|
|
QueIns(tmpg3,tmpg); |
|
|
QueRem(tmpg); |
|
|
Free(tmpg); |
|
|
tmpg=tmpg3; |
|
|
break; |
|
|
case SPT_BSPLINE2: |
|
|
case SPT_BSPLINE3: |
|
|
case SPT_BSPLINE2_CLOSED: |
|
|
case SPT_BSPLINE3_CLOSED: |
|
|
p=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++,p++) { |
|
|
x=p->x; y=p->y; z=p->z; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
p->x=x; |
|
|
p->y=y; |
|
|
p->z=z; |
|
|
} |
|
|
break; |
|
|
case SPT_SHIFTABLE_MESH: |
|
|
x=tmpg->pmu.x; y=tmpg->pmu.y; z=tmpg->pmu.z; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
tmpg->pmu.x=x; |
|
|
tmpg->pmu.y=y; |
|
|
tmpg->pmu.z=z; |
|
|
p=&tmpg->pmu.u; |
|
|
for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) { |
|
|
x=p->x; y=p->y; z=p->z; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
p->x=x; |
|
|
p->y=y; |
|
|
p->z=z; |
|
|
} |
|
|
break; |
|
|
case SPT_MESH: |
|
|
p=&tmpg->mu.u; |
|
|
for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) { |
|
|
x=p->x; y=p->y; z=p->z; |
|
|
Mat4x4MulXYZ(r,&x,&y,&z); |
|
|
p->x=x; |
|
|
p->y=y; |
|
|
p->z=z; |
|
|
} |
|
|
break; |
|
|
} |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
} |
|
|
|
|
|
I64 SpriteQueSelCnt(CSprite *head,Bool val=TRUE) |
|
|
{ |
|
|
I64 res=0; |
|
|
CSprite *tmpg=head->next; |
|
|
val=ToBool(val); |
|
|
while (tmpg!=head) { |
|
|
if (Bt(&tmpg->type,SPf_SEL)==val) |
|
|
res++; |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
return res; |
|
|
} |
|
|
|
|
|
I64 SpriteQueSelAll(CSprite *head,Bool val=TRUE) |
|
|
{ |
|
|
I64 res=0; |
|
|
CSprite *tmpg=head->next; |
|
|
while (tmpg!=head) { |
|
|
BEqu(&tmpg->type,SPf_SEL,val); |
|
|
res++; |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
return res; |
|
|
} |
|
|
|
|
|
CSprite *SpriteSideBar2SpriteQue(CDoc *doc,CSprite *head,I64 *_cur_elem_num) |
|
|
{//For the side-bar |
|
|
CSprite *res=CAlloc(sizeof(CSprite)),*tmpg; |
|
|
CDocEntry *doc_e=doc->head.next; |
|
|
Bool found=FALSE; |
|
|
I64 num=0; |
|
|
QueInit(res); |
|
|
while (doc_e!=doc) { |
|
|
if (doc_e->type_u8==DOCT_MENU_VAL && doc_e->left_exp>=0) { |
|
|
tmpg=SpriteSetSettings(,head,doc_e->left_exp); |
|
|
if (tmpg!=head) { |
|
|
tmpg=MAllocIdent(tmpg); |
|
|
BEqu(&tmpg->type,SPf_SEL,Bt(&doc_e->type,DOCEt_SEL)); |
|
|
if (*_cur_elem_num==doc_e->left_exp) { |
|
|
*_cur_elem_num=num; |
|
|
found=TRUE; |
|
|
} |
|
|
QueIns(tmpg,res->last); |
|
|
num++; |
|
|
} |
|
|
} |
|
|
doc_e=doc_e->next; |
|
|
} |
|
|
if (!found) |
|
|
*_cur_elem_num=num; |
|
|
QueDel(head); |
|
|
Free(head); |
|
|
return res; |
|
|
} |
|
|
|
|
|
U0 SpriteSideBarPickNew(CDoc *doc,CSprite *head,I64 old_num) |
|
|
{ |
|
|
CSprite *tmpg; |
|
|
CDocEntry *doc_cur_e=NULL,*doc_e; |
|
|
I64 cur_elem_num=0; |
|
|
U8 *st; |
|
|
DocPrint(doc,"$$PURPLE$$$$TX+CX,\"Sprite SideBar\"$$\n" |
|
|
"$$LK+PU+CX,\"Click for Help\"," |
|
|
"A=\"FI:::/Doc/SpriteSideBar.DD.Z\"$$\n\n"); |
|
|
tmpg=head->next; |
|
|
while (tmpg!=head) { |
|
|
st=SpriteElem2Summary(tmpg); |
|
|
if (cur_elem_num==old_num) { |
|
|
DocPrint(doc,"$$LTRED$$"); |
|
|
doc_e=doc_cur_e=DocPrint(doc,"$$MU-UL,\"%Q\",LE=%d$$\n",st,cur_elem_num++); |
|
|
} else { |
|
|
DocPrint(doc,"$$LTBLUE$$"); |
|
|
doc_e=DocPrint(doc,"$$MU-UL,\"%$$Q\",LE=%d$$\n",st,cur_elem_num++); |
|
|
} |
|
|
BEqu(&doc_e->de_flags,DOCEf_SEL,Bt(&tmpg->type,&SPf_SEL)); |
|
|
BEqu(&doc_e->type,DOCEt_SEL,Bt(&tmpg->type,SPf_SEL)); |
|
|
Free(st); |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
if (cur_elem_num==old_num) { |
|
|
DocPrint(doc,"$$LTRED$$"); |
|
|
doc_cur_e=DocPrint(doc,"$$MU-UL,\"END\",LE=%d$$\n",cur_elem_num); |
|
|
} else { |
|
|
DocPrint(doc,"$$LTBLUE$$"); |
|
|
DocPrint(doc,"$$MU-UL,\"END\",LE=%d$$\n",cur_elem_num); |
|
|
} |
|
|
if (doc_cur_e) |
|
|
doc->cur_entry=doc_cur_e; |
|
|
} |
|
|
|
|
|
U0 SpriteSideBarTask2(CTask *grand_parent) |
|
|
{ |
|
|
I64 w,h; |
|
|
CTask *parent=Fs->parent_task,*pu_task; |
|
|
while (TRUE) { |
|
|
pu_task=grand_parent->popup_task; |
|
|
if (TaskValidate(pu_task)) { |
|
|
w=parent->win_right-parent->win_left; |
|
|
WinHorz(pu_task->win_right+2,pu_task->win_right+2+w,parent); |
|
|
h=parent->win_bottom-parent->win_top; |
|
|
WinVert(pu_task->win_top,pu_task->win_top+h,parent); |
|
|
} |
|
|
Refresh; |
|
|
} |
|
|
} |
|
|
|
|
|
U0 SpriteSideBarTask(CTask *parent,CSprite **_head,I64 *_cur_elem_num) |
|
|
{ |
|
|
CDocEntry *doc_e; |
|
|
CDoc *doc=DocPut; |
|
|
Spawn(&SpriteSideBarTask2,parent,"CSpriteTask",,Fs); |
|
|
doc->flags|=DOCF_SIZE_MIN|DOCF_FORM; |
|
|
while (TRUE) { |
|
|
SpriteSideBarPickNew(doc,*_head,*_cur_elem_num); |
|
|
DocHighlightCursor(,doc); |
|
|
View; |
|
|
doc_e=doc->cur_entry; |
|
|
if (doc_e->type_u8==DOCT_MENU_VAL) |
|
|
*_cur_elem_num=doc_e->left_exp; |
|
|
*_head=SpriteSideBar2SpriteQue(doc,*_head,_cur_elem_num); |
|
|
DocClear(doc); |
|
|
} |
|
|
} |
|
|
|
|
|
Bool SpriteEdText(CSprite **_head,I64 *_cur_elem_num) |
|
|
{ |
|
|
Bool res; |
|
|
CSprite *head=*_head; |
|
|
U8 *elems=SpriteQue2Sprite(head); |
|
|
CDoc *doc=DocNew,*doc2,*old_put=DocPut; |
|
|
StrPrint(doc->filename.name,"AI:0x%X",doc); |
|
|
DocPrint(doc,"//$$PURPLE$$$$TX+CX,\"Sprite Edit as Text\"$$$$FG$$\n" |
|
|
"//$$LK+PU+CX,\"Click for Help\"," |
|
|
"A=\"FI:::/Doc/SpriteEdText.DD.Z\"$$\n\n"); |
|
|
Sprite2Code(doc,elems); |
|
|
Free(elems); |
|
|
while (TRUE) { |
|
|
if (res=PopUpPrint("DocEd(0x%X,0x%X);",doc,0)) { |
|
|
Fs->put_doc=doc2=DocNew; |
|
|
"$$WW,1$$"; |
|
|
if (elems=Code2Sprite(doc)) { |
|
|
DocDel(doc2); |
|
|
Fs->put_doc=old_put; |
|
|
QueDel(head); |
|
|
Free(head); |
|
|
head=Sprite2SpriteQue(elems); |
|
|
Free(elems); |
|
|
*_cur_elem_num=QueCnt(head); //TODO: Might want to improve this. |
|
|
break; |
|
|
} else { |
|
|
PopUpPrint("DocEd(0x%X,0x%X);",doc2,0); |
|
|
DocDel(doc2); |
|
|
Fs->put_doc=old_put; |
|
|
} |
|
|
} else |
|
|
break; |
|
|
} |
|
|
DocDel(doc); |
|
|
if (_head) *_head=head; |
|
|
return res; |
|
|
} |
|
|
|
|
|
#define SPED_SEL_UNSEL_ALL 0 |
|
|
#define SPED_SEL 2 |
|
|
#define SPED_SEL_RECTS 3 |
|
|
#define SPED_UNSEL 4 |
|
|
#define SPED_UNSEL_RECTS 5 |
|
|
#define SPED_SHIFT_PTS 6 |
|
|
#define SPED_SHIFT_RECTS 7 |
|
|
#define SPED_SHIFT_SEL 8 |
|
|
#define SPED_TRANSFORM_SEL 9 |
|
|
#define SPED_SET_ORIGIN 10 |
|
|
#define SPED_SHIFT_SUB_ORIGIN 11 |
|
|
#define SPED_TEXT_ED 12 |
|
|
#define SPED_INS_CLIP 13 |
|
|
#define SPED_MAIN_MENU 14 |
|
|
#define SPED_EXIT 15 |
|
|
|
|
|
U0 GrInit3() |
|
|
{ |
|
|
DefineLstLoad("ST_SPRITE_ED_MENU","Select/Unselect All\0 \0Select\0" |
|
|
"Select Rects\0Unselect\0Unselect Rects\0Shift Points\0Shift Rects\0" |
|
|
"Shift Selected\0Transform Selected\0Set Origin\0" |
|
|
"Insert Shift SubOrigin\0Edit as Text\0Insert Clip\0Main Menu\0"); |
|
|
} |
|
|
GrInit3; |
|
|
|
|
|
I64 PopUpSpriteEd(CSprite **_head,I64 *_cur_elem_num) |
|
|
{ |
|
|
U8 *st; |
|
|
CTask *pu_task; |
|
|
I64 i; |
|
|
CDoc *doc=DocNew; |
|
|
DocPrint(doc,"$$PURPLE$$$$TX+CX,\"Sprite Edit Menu\"$$\n" |
|
|
"$$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteEd.DD.Z\"$$\n\n" |
|
|
"$$LTBLUE$$$$MU-UL,\"Select/Unselect All\",LE=SPED_SEL_UNSEL_ALL$$\n" |
|
|
"$$MU-UL,\"Select Elems\",LE=SPED_SEL$$\n" |
|
|
"$$MU-UL,\"Select Elems with Rects\",LE=SPED_SEL_RECTS$$\n" |
|
|
"$$MU-UL,\"Unsel Elems\",LE=SPED_UNSEL$$\n" |
|
|
"$$MU-UL,\"Unsel Elems with Rects\",LE=SPED_UNSEL_RECTS$$\n\n" |
|
|
"$$MU-UL,\"Shift Points\",LE=SPED_SHIFT_PTS$$\n" |
|
|
"$$MU-UL,\"Shift Points with Rects\",LE=SPED_SHIFT_RECTS$$\n" |
|
|
"$$MU-UL,\"Shift Selected Elems\",LE=SPED_SHIFT_SEL$$\n" |
|
|
"$$MU-UL,\"Transform Selected Elems\",LE=SPED_TRANSFORM_SEL$$\n\n" |
|
|
"$$MU-UL,\"Set Origin\",LE=SPED_SET_ORIGIN$$\n" |
|
|
"$$MU-UL,\"Insert Shift SubOrigin\",LE=SPED_SHIFT_SUB_ORIGIN$$\n\n" |
|
|
"$$MU-UL,\"Edit as Text\",LE=SPED_TEXT_ED$$\n" |
|
|
"$$MU-UL,\"Insert Clip Sprite's\",LE=SPED_INS_CLIP$$\n\n" |
|
|
"$$PURPLE$$$$MU-UL,\"+] Sprite Main Menu\",LE=SPED_MAIN_MENU$$$$LTBLUE$$\n" |
|
|
"$$MU-UL,\"Exit Sprite\",LE=SPED_EXIT$$\n" |
|
|
"$$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$$"); |
|
|
st=MStrPrint("SpriteSideBarTask(0x%X,0x%X,0x%X);",Fs,_head,_cur_elem_num); |
|
|
PopUp(st,NULL,&pu_task); |
|
|
Free(st); |
|
|
i=PopUpMenu(doc); |
|
|
if (TaskValidate(pu_task)) { |
|
|
*_head=SpriteSideBar2SpriteQue(DocPut(pu_task),*_head,_cur_elem_num); |
|
|
Kill(pu_task); |
|
|
} |
|
|
DocDel(doc); |
|
|
return i; |
|
|
} |
|
|
|
|
|
#define SPEDT_SIMPLE_PT 0 |
|
|
#define SPEDT_WIDTH_HEIGHT 1 |
|
|
|
|
|
#define SPEDF_SEL 1 |
|
|
|
|
|
class CEdSprite |
|
|
{ |
|
|
CEdSprite *next,*last; |
|
|
CSprite *g; |
|
|
I32 type,num,flags,xx,yy,zz; |
|
|
I32 *x,*y,*z,*w,*h; |
|
|
}; |
|
|
|
|
|
CEdSprite *EdSpriteNew(I64 type,CSprite *tmpg) |
|
|
{ |
|
|
CEdSprite *res=CAlloc(sizeof(CEdSprite)); |
|
|
res->g=tmpg; |
|
|
if (tmpg->type&SPF_SEL) |
|
|
res->flags|=SPEDF_SEL; |
|
|
res->type=type; |
|
|
return res; |
|
|
} |
|
|
|
|
|
U0 SpritePtQueNew(U8 *elems,I64 x,I64 y,CEdSprite *head) |
|
|
{ |
|
|
I64 i,num=0; |
|
|
I32 *ptr; |
|
|
CD3I32 *p; |
|
|
CEdSprite *tmpes; |
|
|
CSprite *tmpg=elems-offset(CSprite.start); |
|
|
QueInit(head); |
|
|
while (tmpg->type&SPG_TYPE_MASK) { |
|
|
switch (tmpg->type&SPG_TYPE_MASK) { |
|
|
case SPT_ELLIPSE: |
|
|
case SPT_POLYGON: |
|
|
tmpes=EdSpriteNew(SPEDT_WIDTH_HEIGHT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&tmpg->pwha.x1; |
|
|
tmpes->y=&tmpg->pwha.y1; |
|
|
tmpes->w=&tmpg->pwha.width; |
|
|
tmpes->h=&tmpg->pwha.height; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
goto pq_x1_y1; |
|
|
case SPT_RECT: |
|
|
case SPT_ROTATED_RECT: |
|
|
case SPT_LINE: |
|
|
case SPT_ARROW: |
|
|
case SPT_PLANAR_SYMMETRY: |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&tmpg->pp.x2; |
|
|
tmpes->y=&tmpg->pp.y2; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
case SPT_TEXT: |
|
|
case SPT_TEXT_BOX: |
|
|
case SPT_TEXT_DIAMOND: |
|
|
case SPT_PT: |
|
|
case SPT_BITMAP: |
|
|
case SPT_FLOOD_FILL: |
|
|
case SPT_FLOOD_FILL_NOT: |
|
|
case SPT_CIRCLE: |
|
|
pq_x1_y1: |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&tmpg->p.x1; |
|
|
tmpes->y=&tmpg->p.y1; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
break; |
|
|
case SPT_SHIFT: |
|
|
x+=tmpg->p.x1; |
|
|
y+=tmpg->p.y1; |
|
|
break; |
|
|
case SPT_POLYLINE: |
|
|
ptr=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++) { |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&ptr[i<<1]; |
|
|
tmpes->y=&ptr[i<<1+1]; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
} |
|
|
break; |
|
|
case SPT_POLYPT: |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&tmpg->npu.x; |
|
|
tmpes->y=&tmpg->npu.y; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
break; |
|
|
case SPT_BSPLINE2: |
|
|
case SPT_BSPLINE3: |
|
|
case SPT_BSPLINE2_CLOSED: |
|
|
case SPT_BSPLINE3_CLOSED: |
|
|
p=&tmpg->nu.u; |
|
|
for (i=0;i<tmpg->nu.num;i++) { |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&p[i].x; |
|
|
tmpes->y=&p[i].y; |
|
|
tmpes->z=&p[i].z; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
} |
|
|
break; |
|
|
case SPT_MESH: |
|
|
break; |
|
|
case SPT_SHIFTABLE_MESH: |
|
|
tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg); |
|
|
tmpes->xx=x; |
|
|
tmpes->yy=y; |
|
|
tmpes->x=&tmpg->pmu.x; |
|
|
tmpes->y=&tmpg->pmu.y; |
|
|
tmpes->z=&tmpg->pmu.z; |
|
|
tmpes->num=num; |
|
|
QueIns(tmpes,head->last); |
|
|
break; |
|
|
} |
|
|
tmpg(U8 *)+=SpriteElemSize(tmpg); |
|
|
num++; |
|
|
} |
|
|
} |
|
|
|
|
|
U0 SpriteCtrlPtsDraw(CDC *dc,CEdSprite *head) |
|
|
{ |
|
|
I64 x,y; |
|
|
CEdSprite *tmpes; |
|
|
Refresh; |
|
|
DCFill(dc); |
|
|
if (Blink(20)) { |
|
|
tmpes=head->next; |
|
|
while (tmpes!=head) { |
|
|
switch (tmpes->type) { |
|
|
case SPEDT_SIMPLE_PT: |
|
|
x=*tmpes->x+tmpes->xx; |
|
|
y=*tmpes->y+tmpes->yy; |
|
|
break; |
|
|
case SPEDT_WIDTH_HEIGHT: |
|
|
x=*tmpes->w+*tmpes->x+tmpes->xx; |
|
|
y=*tmpes->h+*tmpes->y+tmpes->yy; |
|
|
break; |
|
|
} |
|
|
if (tmpes->flags&SPEDF_SEL) |
|
|
dc->color=RED; |
|
|
else |
|
|
dc->color=BLACK; |
|
|
GrRect(dc,x-2,y-2,4,4); |
|
|
dc->color=WHITE; |
|
|
GrRect(dc,x-1,y-1,2,2); |
|
|
tmpes=tmpes->next; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
U0 SpriteCtrlPtsMove(CEdSprite *head,I64 dx,I64 dy) |
|
|
{ |
|
|
CEdSprite *tmpes; |
|
|
tmpes=head->next; |
|
|
while (tmpes!=head) { |
|
|
if (tmpes->flags&SPEDF_SEL) |
|
|
switch (tmpes->type) { |
|
|
case SPEDT_SIMPLE_PT: |
|
|
if (tmpes->x) *tmpes->x+=dx; |
|
|
if (tmpes->y) *tmpes->y+=dy; |
|
|
break; |
|
|
case SPEDT_WIDTH_HEIGHT: |
|
|
if (tmpes->w) *tmpes->w+=dx; |
|
|
if (tmpes->h) *tmpes->h+=dy; |
|
|
break; |
|
|
} |
|
|
tmpes=tmpes->next; |
|
|
} |
|
|
} |
|
|
|
|
|
Bool SpriteSelUnselShiftPts(U8 *elems,I64 x,I64 y,I64 *_cur_elem_num,I64 mode) |
|
|
{ |
|
|
I64 msg_code,arg1,arg2,xx,yy,xx2,yy2,dd,best_dd,cur_elem_num; |
|
|
Bool res=TRUE; |
|
|
CDC *dc=DCAlias; |
|
|
CEdSprite head,*tmpes,*best_es; |
|
|
|
|
|
SpritePtQueNew(elems,x,y,&head); |
|
|
cur_elem_num=0; |
|
|
if (head.next!=&head) { |
|
|
while (TRUE) { |
|
|
SpriteCtrlPtsDraw(dc,&head); //has Refresh |
|
|
switch (msg_code=ScanMsg(&arg1,&arg2, |
|
|
1<<MSG_MS_R_UP|1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN)) { |
|
|
case MSG_MS_L_DOWN: |
|
|
switch (mode) { |
|
|
case SPED_SEL: |
|
|
case SPED_UNSEL: |
|
|
case SPED_SHIFT_PTS: |
|
|
xx=arg1; yy=arg2; |
|
|
best_dd=I64_MAX; |
|
|
tmpes=head.next; |
|
|
while (tmpes!=&head) { |
|
|
switch (tmpes->type) { |
|
|
case SPEDT_SIMPLE_PT: |
|
|
dd=SqrI64(*tmpes->x+tmpes->xx-xx)+ |
|
|
SqrI64(*tmpes->y+tmpes->yy-yy); |
|
|
break; |
|
|
case SPEDT_WIDTH_HEIGHT: |
|
|
dd=SqrI64(*tmpes->x+*tmpes->w+tmpes->xx-xx)+ |
|
|
SqrI64(*tmpes->y+*tmpes->h+tmpes->yy-yy); |
|
|
break; |
|
|
} |
|
|
if (dd<best_dd) { |
|
|
best_dd=dd; |
|
|
best_es=tmpes; |
|
|
} |
|
|
tmpes=tmpes->next; |
|
|
} |
|
|
cur_elem_num=best_es->num; |
|
|
if (mode!=SPED_UNSEL) { |
|
|
best_es->flags|=SPEDF_SEL; |
|
|
best_es->g->type|=SPF_SEL; |
|
|
} else { |
|
|
best_es->flags&=~SPEDF_SEL; |
|
|
best_es->g->type&=~SPF_SEL; |
|
|
} |
|
|
break; |
|
|
start: |
|
|
xx2=xx=arg1; yy2=yy=arg2; |
|
|
while (TRUE) { |
|
|
SpriteCtrlPtsDraw(dc,&head); |
|
|
dc->color=ROPF_DITHER+WHITE<<16+RED; |
|
|
GrBorder(dc,xx,yy,xx2,yy2); |
|
|
if (msg_code=ScanMsg(&arg1,&arg2, |
|
|
1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) { |
|
|
if (msg_code==MSG_MS_MOVE) { |
|
|
xx2=arg1; yy2=arg2; |
|
|
} else |
|
|
break; |
|
|
} |
|
|
} |
|
|
if (xx2<xx) SwapI64(&xx,&xx2); |
|
|
if (yy2<yy) SwapI64(&yy,&yy2); |
|
|
tmpes=head.next; |
|
|
while (tmpes!=&head) { |
|
|
switch (tmpes->type) { |
|
|
case SPEDT_SIMPLE_PT: |
|
|
if (xx<=*tmpes->x+tmpes->xx<=xx2 && |
|
|
yy<=*tmpes->y+tmpes->yy<=yy2) { |
|
|
if (mode!=SPED_UNSEL_RECTS) { |
|
|
tmpes->flags|=SPEDF_SEL; |
|
|
tmpes->g->type|=SPF_SEL; |
|
|
} else { |
|
|
tmpes->flags&=~SPEDF_SEL; |
|
|
tmpes->g->type&=~SPF_SEL; |
|
|
} |
|
|
} |
|
|
break; |
|
|
case SPEDT_WIDTH_HEIGHT: |
|
|
if (xx<=*tmpes->x+*tmpes->w+tmpes->xx<=xx2 && |
|
|
yy<=*tmpes->y+*tmpes->h+tmpes->yy<=yy2) { |
|
|
if (mode!=SPED_UNSEL_RECTS) { |
|
|
tmpes->flags|=SPEDF_SEL; |
|
|
tmpes->g->type|=SPF_SEL; |
|
|
} else { |
|
|
tmpes->flags&=~SPEDF_SEL; |
|
|
tmpes->g->type&=~SPF_SEL; |
|
|
} |
|
|
} |
|
|
break; |
|
|
} |
|
|
tmpes=tmpes->next; |
|
|
} |
|
|
case SPED_SEL_RECTS: |
|
|
case SPED_UNSEL_RECTS: |
|
|
break; |
|
|
case SPED_SHIFT_RECTS: |
|
|
do { |
|
|
SpriteCtrlPtsDraw(dc,&head); |
|
|
msg_code=ScanMsg(&arg1,&arg2, |
|
|
1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN); |
|
|
if (msg_code==MSG_KEY_DOWN) goto gs_key; |
|
|
} while (msg_code!=MSG_MS_L_DOWN); |
|
|
xx=arg1;yy=arg2; |
|
|
break; |
|
|
end: |
|
|
} |
|
|
switch (mode) { |
|
|
case SPED_SHIFT_PTS: |
|
|
case SPED_SHIFT_RECTS: |
|
|
do { |
|
|
SpriteCtrlPtsDraw(dc,&head); |
|
|
if (msg_code=ScanMsg(&arg1,&arg2, |
|
|
1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) { |
|
|
SpriteCtrlPtsMove(&head,arg1-xx,arg2-yy); |
|
|
xx=arg1;yy=arg2; |
|
|
} |
|
|
} while (msg_code!=MSG_MS_L_UP); |
|
|
tmpes=head.next; |
|
|
while (tmpes!=&head) { |
|
|
tmpes->flags&=~SPEDF_SEL; |
|
|
tmpes->g->type&=~SPF_SEL; |
|
|
tmpes=tmpes->next; |
|
|
} |
|
|
break; |
|
|
} |
|
|
break; |
|
|
case MSG_KEY_DOWN: |
|
|
gs_key: |
|
|
switch (arg1.u8[0]) { |
|
|
case CH_SHIFT_ESC: |
|
|
res=FALSE; |
|
|
case CH_ESC: |
|
|
GetMsg(&arg1,&arg2,1<<MSG_KEY_UP); |
|
|
goto gs_done; |
|
|
case 'p': |
|
|
case 'P': |
|
|
mode&=~1; |
|
|
break; |
|
|
case 'r': |
|
|
case 'R': |
|
|
mode|=1; |
|
|
break; |
|
|
} |
|
|
break; |
|
|
case MSG_MS_R_UP: |
|
|
goto gs_done; |
|
|
} |
|
|
} |
|
|
gs_done: |
|
|
QueDel(&head,TRUE); |
|
|
} |
|
|
DCFill(dc); |
|
|
DCDel(dc); |
|
|
if (_cur_elem_num && res) |
|
|
*_cur_elem_num=cur_elem_num; |
|
|
return res; |
|
|
} |
|
|
|
|
|
I64 SpriteEd(CDoc *doc,CDocEntry *doc_ce,I64 x,I64 y, |
|
|
CSprite **_head,I64 *_cur_elem_num) |
|
|
{ |
|
|
CDocEntry *doc_e2; |
|
|
CDocBin *tmpb; |
|
|
Bool unlock; |
|
|
I64 i,r[16],msg_code,arg1,arg2,xx,yy, |
|
|
old_de_flags; |
|
|
CSprite *head2,*next,*last,*tmpg,*insert_pt; |
|
|
|
|
|
old_de_flags=doc_ce->de_flags; |
|
|
tmpb=doc_ce->bin_data; |
|
|
DocUnlock(doc); |
|
|
SpriteQueSelAll(*_head,FALSE); |
|
|
do { |
|
|
if (winmgr.fps<10) |
|
|
doc_ce->de_flags|=DOCEF_DONT_DRAW; |
|
|
StrCpy(Fs->task_title,"Sprite Edit Menu"); |
|
|
i=PopUpSpriteEd(_head,_cur_elem_num); |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
if (0<=i<SPED_EXIT) { |
|
|
StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_ED_MENU")); |
|
|
switch (i) { |
|
|
case SPED_SEL_UNSEL_ALL: |
|
|
if (!SpriteQueSelCnt(*_head)) |
|
|
SpriteQueSelAll(*_head); |
|
|
else |
|
|
SpriteQueSelAll(*_head,FALSE); |
|
|
break; |
|
|
case SPED_SET_ORIGIN: |
|
|
SpriteQueSelAll(*_head); |
|
|
doc_ce->de_flags=old_de_flags; |
|
|
GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP); |
|
|
SpriteSetOrigin(*_head,x-arg1,y-arg2,0); |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
SpriteQueSelAll(*_head,FALSE); |
|
|
break; |
|
|
case SPED_SHIFT_SEL: |
|
|
if (!SpriteQueSelCnt(*_head)) |
|
|
SpriteQueSelAll(*_head); |
|
|
doc_ce->de_flags=old_de_flags; |
|
|
GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN); |
|
|
xx=arg1; yy=arg2; |
|
|
do { |
|
|
msg_code=GetMsg(&arg1,&arg2, |
|
|
1<<MSG_MS_L_UP+1<<MSG_MS_MOVE); |
|
|
SpriteSetOrigin(*_head,arg1-xx,arg2-yy,0); |
|
|
xx=arg1; yy=arg2; |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
} while (msg_code!=MSG_MS_L_UP); |
|
|
if (!SpriteQueSelCnt(*_head,FALSE)) |
|
|
SpriteQueSelAll(*_head,FALSE); |
|
|
break; |
|
|
case SPED_SEL: |
|
|
case SPED_SEL_RECTS: |
|
|
case SPED_UNSEL: |
|
|
case SPED_UNSEL_RECTS: |
|
|
case SPED_SHIFT_PTS: |
|
|
case SPED_SHIFT_RECTS: |
|
|
RegOneTimePopUp(ARf_CSPRITE_PTS_RECTANGLES, |
|
|
"You can switch between points\n" |
|
|
"and rectangles with '$$GREEN$$p$$FG$$' and '$$GREEN$$r$$FG$$'.\n" |
|
|
"Press '$$GREEN$$r$$FG$$' after one rectangle\n" |
|
|
"to OR another rectangle.\n"); |
|
|
doc_ce->de_flags=old_de_flags; |
|
|
if (SpriteSelUnselShiftPts(tmpb->data,x,y,_cur_elem_num,i)) { |
|
|
QueDel(*_head); |
|
|
Free(*_head); |
|
|
*_head=Sprite2SpriteQue(tmpb->data); |
|
|
} else |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
break; |
|
|
case SPED_TRANSFORM_SEL: |
|
|
if (!SpriteQueSelCnt(*_head)) |
|
|
SpriteQueSelAll(*_head); |
|
|
if (PopUpTransform(r)) { |
|
|
SpriteTransformQue(*_head,r); |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
} |
|
|
if (!SpriteQueSelCnt(*_head,FALSE)) |
|
|
SpriteQueSelAll(*_head,FALSE); |
|
|
break; |
|
|
case SPED_SHIFT_SUB_ORIGIN: |
|
|
doc_ce->de_flags=old_de_flags; |
|
|
insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num); |
|
|
tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_SHIFT)); |
|
|
tmpg->type=SPT_SHIFT; |
|
|
tmpg->p.x1=0; |
|
|
tmpg->p.y1=0; |
|
|
QueIns(tmpg,insert_pt->last); |
|
|
GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN); |
|
|
xx=arg1; yy=arg2; |
|
|
do { |
|
|
msg_code=GetMsg(&arg1,&arg2, |
|
|
1<<MSG_MS_L_UP+1<<MSG_MS_MOVE); |
|
|
tmpg->p.x1=arg1-xx; |
|
|
tmpg->p.y1=arg2-yy; |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
} while (msg_code!=MSG_MS_L_UP); |
|
|
*_cur_elem_num+=1; |
|
|
break; |
|
|
case SPED_INS_CLIP: |
|
|
RegOneTimePopUp(ARf_CSPRITE_INS_CLIP, |
|
|
"You will probably want to shift around\n" |
|
|
"the location of element groups. Use\n" |
|
|
"'Insert shift sub-origin' after picking the\n" |
|
|
"element to insert before. Or,\n" |
|
|
"use 'shift points'.\n"); |
|
|
insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num); |
|
|
unlock=DocLock(sys_clip_doc); |
|
|
doc_e2=sys_clip_doc->head.next; |
|
|
while (doc_e2!=sys_clip_doc) { |
|
|
if (doc_e2->type_u8==DOCT_SPRITE) { |
|
|
head2=Sprite2SpriteQue(doc_e2->bin_data->data); |
|
|
if (head2->next!=head2) { |
|
|
tmpg=head2->next; |
|
|
while (tmpg!=head2) { |
|
|
*_cur_elem_num+=1; |
|
|
tmpg=tmpg->next; |
|
|
} |
|
|
next=head2->next; |
|
|
last=head2->last; |
|
|
insert_pt->last->next=next; |
|
|
next->last=insert_pt->last; |
|
|
insert_pt->last=last; |
|
|
last->next=insert_pt; |
|
|
} |
|
|
Free(head2); |
|
|
} |
|
|
doc_e2=doc_e2->next; |
|
|
} |
|
|
if (unlock) |
|
|
DocUnlock(sys_clip_doc); |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
break; |
|
|
case SPED_TEXT_ED: |
|
|
if (SpriteEdText(_head,_cur_elem_num)) |
|
|
SpriteEdUpdate(doc,doc_ce,*_head); |
|
|
break; |
|
|
} |
|
|
} |
|
|
} while (i!=DOCM_CANCEL && i!=SPED_EXIT && i!=SPED_MAIN_MENU); |
|
|
doc_ce->de_flags=old_de_flags; |
|
|
|
|
|
switch (i) { |
|
|
case DOCM_CANCEL: return SPE_ABORT; |
|
|
case SPED_EXIT: return SPE_EXIT; |
|
|
case SPED_MAIN_MENU: return SPE_CONT; |
|
|
} |
|
|
} |
|
|
|
|
|
#help_index "Graphics/Sprite;Sprites;Graphics/Math/3D Transformation" |
|
|
public U8 *SpriteTransform(U8 *elems,I64 *r) |
|
|
{//Rotate Sprite using 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$. |
|
|
U8 *res; |
|
|
CSprite *head=Sprite2SpriteQue(elems); |
|
|
SpriteQueSelAll(head); |
|
|
SpriteTransformQue(head,r); |
|
|
res=SpriteQue2Sprite(head); |
|
|
QueDel(head); |
|
|
Free(head); |
|
|
return res; |
|
|
}
|
|
|
|