#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) { 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]<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) { tmpg1=MAlloc(SpriteElemSize(tmpg)+offset(CSprite.start)); s=SpriteElemSize(tmpg); MemCpy(&tmpg1->start,&tmpg->start,s); tmpg1->sel=FALSE; 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 (tmpg->sel) switch (tmpg->type) { 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;inu.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;inu.num;i++,p++) { p->x+=dx; p->y+=dy; p->z+=dz; } break; case SPT_MESH: p=&tmpg->mu.u; for (i=0;imu.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,a1,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,&a1,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=-a1; tmpg1->sel=tmpg->sel; return tmpg1; } CSprite *SpriteTransformEllipse(I64 *r,CSprite *tmpg) { I64 x,y,z; F64 m1,a1,m2,a2,s,c,x_radius=tmpg->pwha.width<<16, y_radius=tmpg->pwha.height<<16; CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(tmpg->type)); tmpg1->type=tmpg->type; if (tmpg->type==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,&a1,x,y); x=-y_radius*s; y=y_radius*c; z=0; Mat4x4MulXYZ(r,&x,&y,&z); R2P(&m2,&a2,x,y); m2*=Abs(Sin(a2-a1)); 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=-a1; tmpg1->sel=tmpg->sel; return tmpg1; } CSprite *SpriteTransformRect(I64 *r,CSprite *tmpg,F64 é) { I64 x,y,z,w,h; F64 m1,a1,m2,a2,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(-é); s=Sin(-é); x=x_radius*c; y=x_radius*s; z=0; Mat4x4MulXYZ(r,&x,&y,&z); R2P(&m1,&a1,x,y); x=-y_radius*s; y=y_radius*c; z=0; Mat4x4MulXYZ(r,&x,&y,&z); R2P(&m2,&a2,x,y); m2*=Abs(Sin(a2-a1)); 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=-a1; tmpg1->sel=tmpg->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 (xmaxx) maxx=x; if (ymaxx) maxy=y; if (zmaxx) maxz=z; x=tmpg->pwhu.width; y=0; z=0; Mat4x4MulXYZ(r,&x,&y,&z); if (xmaxx) maxx=x; if (ymaxx) maxy=y; if (zmaxx) maxz=z; x=tmpg->pwhu.width; y=tmpg->pwhu.height; z=0; Mat4x4MulXYZ(r,&x,&y,&z); if (xmaxx) maxx=x; if (ymaxx) maxy=y; if (zmaxx) 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 SpriteTransform(I64 *r,CSprite *head) { 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 (tmpg->sel) switch (tmpg->type) { 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;inu.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;inext; 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; tmpg3->npu.num=num; QueIns(tmpg3,tmpg); QueRem(tmpg); tmpg3->sel=tmpg->sel; 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;inu.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;ipmu.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;imu.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 (ToBool(tmpg->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) { tmpg->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); tmpg->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,tmpg->sel); BEqu(&doc_e->type,DOCEt_SEL,tmpg->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_MIN_SIZE|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 1 #define SPED_UNSEL 2 #define SPED_SHIFT_PTS 3 #define SPED_SHIFT_RECTS 4 #define SPED_SHIFT_SEL 5 #define SPED_TRANSFORM_SEL 6 #define SPED_SET_ORIGIN 7 #define SPED_SHIFT_SUB_ORIGIN 8 #define SPED_TEXT_ED 9 #define SPED_INS_CLIPBOARD 10 #define SPED_MAIN_MENU 11 #define SPED_EXIT 12 U0 GrInit3() { DefineLstLoad("ST_SPRITE_ED_MENU","Select/Unselect All\0" "Select\0Unselect\0Shift Points\0Shift Rects\0Shift Selected\0" "Transform Selected\0Set Origin\0Insert Shift SubOrigin\0" "Edit as Text\0Insert Clipboard\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,\"Unsel Elems\",LE=SPED_UNSEL$$\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 Clipboard Sprite's\",LE=SPED_INS_CLIPBOARD$$\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; I32 type,num,flags,xx,yy,zz; I32 *x,*y,*z,*w,*h; }; 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) { switch (tmpg->type) { case SPT_ELLIPSE: case SPT_POLYGON: tmpes=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_WIDTH_HEIGHT; 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=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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;inu.num;i++) { tmpes=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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;inu.num;i++) { tmpes=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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=CAlloc(sizeof(CEdSprite)); tmpes->type=SPEDT_SIMPLE_PT; 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 SpriteShiftPts(U8 *elems,I64 x,I64 y,I64 *_cur_elem_num,I64 mode) { I64 msg_code,a1,a2,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(&a1,&a2, 1<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 (ddnext; } cur_elem_num=best_es->num; best_es->flags|=SPEDF_SEL; break; case SPED_SHIFT_RECTS: xx2=xx=a1; yy2=yy=a2; while (TRUE) { SpriteCtrlPtsDraw(dc,&head); dc->color=ROPF_DITHER+WHITE<<16+RED; GrBorder(dc,xx,yy,xx2,yy2); if (msg_code=ScanMsg(&a1,&a2,1<type) { case SPEDT_SIMPLE_PT: if (xx<=*tmpes->x+tmpes->xx<=xx2 && yy<=*tmpes->y+tmpes->yy<=yy2) tmpes->flags|=SPEDF_SEL; break; case SPEDT_WIDTH_HEIGHT: if (xx<=*tmpes->x+*tmpes->w+tmpes->xx<=xx2 && yy<=*tmpes->y+*tmpes->h+tmpes->yy<=yy2) tmpes->flags|=SPEDF_SEL; break; } tmpes=tmpes->next; } do { SpriteCtrlPtsDraw(dc,&head); msg_code=ScanMsg(&a1,&a2,1<flags&=~SPEDF_SEL; tmpes=tmpes->next; } break; case MSG_KEY_DOWN: gs_key: switch (a1.u8[0]) { case CH_SHIFT_ESC: res=FALSE; case CH_ESC: GetMsg(&a1,&a2,1<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<=itask_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_SEL: case SPED_UNSEL: doc_ce->de_flags=old_de_flags; doc->cur_sprite=tmpb->data; do { doc->nearest_sprite_elem_num=0; msg_code=GetMsg(&a1,&a2,1<nearest_sprite_elem_num; cur_elem=SpriteSetSettings(,*_head,*_cur_elem_num); cur_elem->sel=ToBool(i==SPED_SEL); GetMsg(,,1<cur_sprite=NULL; break; case SPED_SET_ORIGIN: SpriteQueSelAll(*_head); doc_ce->de_flags=old_de_flags; GetMsg(&a1,&a2,1<de_flags=old_de_flags; GetMsg(&a1,&a2,1<de_flags=old_de_flags; if (SpriteShiftPts(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)) { SpriteTransform(r,*_head); 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(&a1,&a2,1<p.x1=a1-xx; tmpg->p.y1=a2-yy; SpriteEdUpdate(doc,doc_ce,*_head); } while (msg_code!=MSG_IP_L_UP); *_cur_elem_num+=1; break; case SPED_INS_CLIPBOARD: RegOneTimePopUp(ARf_CSPRITE_INS_CLIPBOARD, "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_clipboard_doc); doc_e2=sys_clipboard_doc->head.next; while (doc_e2!=sys_clipboard_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_clipboard_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; } }