Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
GrSpritePlot.txt477 linesDownload Raw Back to Gr
1 2#help_index "Graphics/Sprite;Sprites"3/*4CSprites are stored as a sequence of var5length operations with a 1-byte type leading6each operation.  They are stored, one after another,7in a chunk of memory terminated by a zero.8Sprite3() shows how the CSprite unions are used.9 10SpriteElemSize() will return the size of a single11element, while SpriteSize() will return the size12of an entire list.  Look at sprite_elem_base_sizes.13 14See ::/Apps/GrModels for an example of15making CSprite by hand.  It uses SPT_MESH,16one of the most complicated.17*/18 19public U0 Sprite3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,20        Bool just_one_elem=FALSE)21{//Plot a sprite into a CDC.22  CSprite *tmpg=elems-offset(CSprite.start);23  I64 i,j,k,x1,y1,z1,x2,y2,24        *old_r,*r2,old_flags=dc->flags,old_pen_width=dc->thick;25  I32 *ptr;26  CColorROPU32 old_color=dc->color;27  CDC *img;28  CD3I32 *p,*p2;29  CGrSym old_sym;30  MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));31  if (dc->flags & DCF_LOCATE_NEAREST)32    dc->nearest_dist=I64_MAX;33  while (tmpg->type&SPG_TYPE_MASK) {34    switch (tmpg->type&SPG_TYPE_MASK) {35      case SPT_COLOR:36        dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tmpg->c.color;37        break;38      case SPT_DITHER_COLOR:39        dc->color=dc->color&~COLORROP_COLORS_MASK|40              tmpg->d.dither_color.u8[0]|41              tmpg->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;42        break;43      case SPT_THICK:44        dc->thick=tmpg->t.thick;45        DCThickScale(dc);46        break;47      case SPT_TRANSFORM_ON:48        if (!(dc->flags&DCF_TRANSFORMATION)) {49          x-=dc->x;50          y-=dc->y;51          z-=dc->z;52        }53        dc->flags|=DCF_TRANSFORMATION;54        break;55      case SPT_TRANSFORM_OFF:56        if (dc->flags&DCF_TRANSFORMATION) {57          x+=dc->x;58          y+=dc->y;59          z+=dc->z;60        }61        dc->flags&=~DCF_TRANSFORMATION;62        break;63      case SPT_PT:64        GrPlot3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z);65        break;66      case SPT_TEXT:67        GrPrint3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,"%s",tmpg->ps.st);68        break;69      case SPT_TEXT_BOX:70        GrTextBox3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);71        break;72      case SPT_TEXT_DIAMOND:73        GrTextDiamond3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);74        break;75      case SPT_FLOOD_FILL:76        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,FALSE);77        break;78      case SPT_FLOOD_FILL_NOT:79        i=dc->color;80        dc->color=dc->color.c0;81        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,TRUE);82        dc->color=i;83        break;84      case SPT_SHIFT:85        x+=tmpg->p.x1;86        y+=tmpg->p.y1;87        break;88      case SPT_LINE:89        GrLine3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,90              tmpg->pp.x2+x,tmpg->pp.y2+y,z);91        break;92      case SPT_ARROW:93        GrArrow3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,94              tmpg->pp.x2+x,tmpg->pp.y2+y,z);95        break;96      case SPT_PLANAR_SYMMETRY:97        if (DCSymmetry3Set(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,98              tmpg->pp.x2+x,tmpg->pp.y2+y,z,99              tmpg->pp.x2+x,tmpg->pp.y2+y,z+1))100          dc->flags|=DCF_SYMMETRY;101        else102          dc->flags&=~DCF_SYMMETRY;103        break;104      case SPT_BITMAP:105        img=CAlloc(sizeof(CDC));106        img->width=tmpg->pwhu.width;107        img->width_internal=(tmpg->pwhu.width+7)&~7;108        img->height=tmpg->pwhu.height;109        img->body=&tmpg->pwhu.u;110        img->dc_signature=DCS_SIGNATURE_VAL;111        GrBlot3(dc,tmpg->pwhu.x1+x,tmpg->pwhu.y1+y,z,img);112        Free(img);113        break;114      case SPT_RECT:115        GrRect3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,116              tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);117        break;118      case SPT_ROTATED_RECT:119        x1=tmpg->ppa.x1+x;120        y1=tmpg->ppa.y1+y;121        z1=z;122        Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);123        old_r=dc->r;124        dc->flags|=DCF_TRANSFORMATION;125        r2=Mat4x4IdentNew;126        Mat4x4RotZ(r2,-tmpg->ppa.angle);127        Mat4x4TranslationEqu(r2,x1,y1,z1);128        DCMat4x4Set(dc,Mat4x4MulMat4x4New(old_r,r2));129        GrRect3(dc,0,0,0,130              tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1);131        Free(dc->r);132        Free(r2);133        DCMat4x4Set(dc,old_r);134        dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;135        break;136      case SPT_CIRCLE:137        GrCircle3(dc,tmpg->pr.x1+x,tmpg->pr.y1+y,z,tmpg->pr.radius);138        break;139      case SPT_ELLIPSE:140        GrEllipse3(dc,tmpg->pwha.x1+x,tmpg->pwha.y1+y,z,tmpg->pwha.width,141              tmpg->pwha.height,tmpg->pwha.angle);142        break;143      case SPT_POLYGON:144        GrRegPoly3(dc,tmpg->pwhas.x1+x,tmpg->pwhas.y1+y,z,tmpg->pwhas.width,145              tmpg->pwhas.height,tmpg->pwhas.sides,tmpg->pwhas.angle);146        break;147      case SPT_POLYLINE:148        ptr=&tmpg->nu.u;149        x1=ptr[0];150        y1=ptr[1];151        for (i=1;i<tmpg->nu.num;i++) {152          x2=ptr[i<<1];153          y2=ptr[i<<1+1];154          GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);155          x1=x2;y1=y2;156        }157        break;158      case SPT_POLYPT:159        x1=tmpg->npu.x;160        y1=tmpg->npu.y;161        ptr=&tmpg->npu.u;162        k=tmpg->npu.num*3;163        GrPlot3(dc,x1+x,y1+y,z);164        for (i=0;i<k;i+=3) {165          j=BFieldExtU32(ptr,i,3);166          x1+=gr_x_offsets[j];167          y1+=gr_y_offsets[j];168          GrPlot3(dc,x1+x,y1+y,z);169        }170        break;171      start:172        p2=p=MAlloc(tmpg->nu.num*sizeof(CD3I32));173        MemCpy(p,&tmpg->nu.u,tmpg->nu.num*sizeof(CD3I32));174        for (i=0;i<tmpg->nu.num;i++,p2++) {175          p2->x+=x;176          p2->y+=y;177          p2->z+=z;178        }179        case SPT_BSPLINE2:180          Gr2BSpline3(dc,p,tmpg->nu.num,FALSE);181          break;182        case SPT_BSPLINE3:183          Gr3BSpline3(dc,p,tmpg->nu.num,FALSE);184          break;185        case SPT_BSPLINE2_CLOSED:186          Gr2BSpline3(dc,p,tmpg->nu.num,TRUE);187          break;188        case SPT_BSPLINE3_CLOSED:189          Gr3BSpline3(dc,p,tmpg->nu.num,TRUE);190          break;191      end:192        Free(p);193        break;194      case SPT_MESH:195        p2=p=MAlloc(tmpg->mu.vertex_cnt*sizeof(CD3I32));196        MemCpy(p,&tmpg->mu.u,tmpg->mu.vertex_cnt*sizeof(CD3I32));197        for (i=0;i<tmpg->mu.vertex_cnt;i++,p2++) {198          p2->x+=x;199          p2->y+=y;200          p2->z+=z;201        }202        Gr3Mesh(dc,tmpg->mu.vertex_cnt,p,tmpg->mu.tri_cnt,203              (&tmpg->mu.u)(U8 *)+sizeof(CD3I32)*tmpg->mu.vertex_cnt);204        Free(p);205        break;206      case SPT_SHIFTABLE_MESH:207        if (dc->flags&DCF_TRANSFORMATION) {208          dc->x+=tmpg->pmu.x;209          dc->y+=tmpg->pmu.y;210          dc->z+=tmpg->pmu.z;211          x1=x;212          y1=y;213          z1=z;214        } else {215          x1=tmpg->pmu.x+x;216          y1=tmpg->pmu.y+y;217          z1=tmpg->pmu.z+z;218        }219        p2=p=MAlloc(tmpg->pmu.vertex_cnt*sizeof(CD3I32));220        MemCpy(p,&tmpg->pmu.u,tmpg->pmu.vertex_cnt*sizeof(CD3I32));221        for (i=0;i<tmpg->pmu.vertex_cnt;i++,p2++) {222          p2->x+=x1;223          p2->y+=y1;224          p2->z+=z1;225        }226        Gr3Mesh(dc,tmpg->pmu.vertex_cnt,p,tmpg->pmu.tri_cnt,227              (&tmpg->pmu.u)(U8 *)+sizeof(CD3I32)*tmpg->pmu.vertex_cnt);228        Free(p);229        if (dc->flags&DCF_TRANSFORMATION) {230          dc->x-=tmpg->pmu.x;231          dc->y-=tmpg->pmu.y;232          dc->z-=tmpg->pmu.z;233        }234        break;235    }236    if (just_one_elem) break;237    tmpg(U8 *)+=SpriteElemSize(tmpg);238  }239  MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));240  dc->color=old_color;241  dc->thick=old_pen_width;242  dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |243        old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);244}245 246public U0 Sprite3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems)247{//Plot a sprite into a CDC, post transform xyz translation.248  I64 old_x=dc->x,old_y=dc->y,old_z=dc->z,249        old_flags=dc->flags&DCF_TRANSFORMATION;250  dc->x=x; dc->y=y; dc->z=z;251  dc->flags|=DCF_TRANSFORMATION;252  Sprite3(dc,0,0,0,elems);253  dc->x=old_x; dc->y=old_y; dc->z=old_z;254  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;255}256 257public U0 Sprite3Mat4x4B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)258{//Plot rotated by matrix.259  I64 r[16],*old_r=dc->r,new_m[16],260        old_flags=dc->flags&DCF_TRANSFORMATION;261  MemCpy(new_m,m,16*sizeof(I64));262  dc->flags|=DCF_TRANSFORMATION;263  Mat4x4TranslationAdd(new_m,x,y,z);264  dc->r=Mat4x4MulMat4x4Equ(r,old_r,new_m);265  Sprite3(dc,0,0,0,elems);266  dc->r=old_r;267  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;268}269 270public U0 Sprite3XB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 phi=0)271{//Plot rotated around X axis.272  I64 r[16];273  Mat4x4IdentEqu(r);274  Mat4x4RotX(r,phi);275  Sprite3Mat4x4B(dc,x,y,z,elems,r);276}277 278public U0 Sprite3YB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 omega=0)279{//Plot rotated around Y axis.280  I64 r[16];281  Mat4x4IdentEqu(r);282  Mat4x4RotY(r,omega);283  Sprite3Mat4x4B(dc,x,y,z,elems,r);284}285 286public U0 Sprite3ZB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 theta=0)287{//Plot rotated around Z axis.288  I64 r[16];289  Mat4x4IdentEqu(r);290  Mat4x4RotZ(r,theta);291  Sprite3Mat4x4B(dc,x,y,z,elems,r);292}293 294public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,295                                   I64 *min_y=NULL,I64 *max_y=NULL)296{//Ignores flood fills.297  CDC *dc=DCNew(I32_MAX,I32_MAX,Fs,TRUE);298  DCExtentsInit(dc);299  Sprite3(dc,I32_MAX/2,I32_MAX/2,I32_MAX/2,elems);300  if (dc->min_x<=dc->max_x) {301    dc->min_x-=I32_MAX/2;302    dc->max_x-=I32_MAX/2;303  }304  if (dc->min_y<=dc->max_y) {305    dc->min_y-=I32_MAX/2;306    dc->max_y-=I32_MAX/2;307  }308  if (min_x) *min_x=dc->min_x;309  if (max_x) *max_x=dc->max_x;310  if (min_y) *min_y=dc->min_y;311  if (max_y) *max_y=dc->max_y;312  DCDel(dc);313}314 315public CDC *Sprite2DC(U8 *elems)316{//Convert sprite to device context.317  CDC *res;318  I64 min_x,max_x,min_y,max_y;319  SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);320  res=DCNew(max_x-min_x+1,max_y-min_y+1);321  Sprite3(res,-min_x,-min_y,0,elems);322  return res;323}324 325public U8 *SpriteInterpolate(F64 t,U8 *elems0,U8 *elems1)326{//The two CSprite should be ident except for points shifted around.327//t ranges from 0.0 to 1.0.328  I64 i,t1=GR_SCALE*t,t0=GR_SCALE-t1;329  I32 *ptr0,*ptr1,*ptrr;330  CD3I32 *p0,*p1,*pr;331  U8 *res;332  CSprite *tmpg0=elems0-offset(CSprite.start),333        *tmpg1=elems1-offset(CSprite.start),*tmpgr;334  if (t<0.5) {335    i=SpriteSize(elems0),336          res=MAlloc(i);337    MemCpy(res,elems0,i);338  } else {339    i=SpriteSize(elems1),340          res=MAlloc(i);341    MemCpy(res,elems1,i);342  }343  tmpgr=res-offset(CSprite.start);344  while (tmpg0->type&SPG_TYPE_MASK) {345    if (tmpg0->type&SPG_TYPE_MASK!=tmpg1->type&SPG_TYPE_MASK)346      throw('Graphics');347    switch (tmpg0->type&SPG_TYPE_MASK) {348      case SPT_ROTATED_RECT:349        tmpgr->ppa.angle=(tmpg0->ppa.angle*t0+tmpg1->ppa.angle*t1)/GR_SCALE;350      case SPT_RECT:351      case SPT_LINE:352      case SPT_ARROW:353      case SPT_PLANAR_SYMMETRY:354        tmpgr->pp.x2=(tmpg0->pp.x2*t0+tmpg1->pp.x2*t1)>>32;355        tmpgr->pp.y2=(tmpg0->pp.y2*t0+tmpg1->pp.y2*t1)>>32;356      case SPT_TEXT:357      case SPT_TEXT_BOX:358      case SPT_TEXT_DIAMOND:359      case SPT_PT:360      case SPT_FLOOD_FILL:361      case SPT_FLOOD_FILL_NOT:362      case SPT_SHIFT:363        tmpgr->p.x1=(tmpg0->p.x1*t0+tmpg1->p.x1*t1)>>32;364        tmpgr->p.y1=(tmpg0->p.y1*t0+tmpg1->p.y1*t1)>>32;365        break;366      case SPT_CIRCLE:367        tmpgr->pr.radius=(tmpg0->pr.radius*t0+tmpg1->pr.radius*t1)>>32;368        tmpgr->pr.x1=(tmpg0->pr.x1*t0+tmpg1->pr.x1*t1)>>32;369        tmpgr->pr.y1=(tmpg0->pr.y1*t0+tmpg1->pr.y1*t1)>>32;370        break;371      case SPT_ELLIPSE:372      case SPT_POLYGON:373        tmpgr->pwha.x1=(tmpg0->pwha.x1*t0+tmpg1->pwha.x1*t1)>>32;374        tmpgr->pwha.y1=(tmpg0->pwha.y1*t0+tmpg1->pwha.y1*t1)>>32;375        tmpgr->pwha.width =(tmpg0->pwha.width *t0+tmpg1->pwha.width*t1)>>32;376        tmpgr->pwha.height=(tmpg0->pwha.height*t0+tmpg1->pwha.height*t1)>>32;377        break;378      case SPT_BITMAP:379        tmpgr->pwhu.x1=(tmpg0->pwhu.x1*t0+tmpg1->pwhu.x1*t1)>>32;380        tmpgr->pwhu.y1=(tmpg0->pwhu.y1*t0+tmpg1->pwhu.y1*t1)>>32;381        break;382      case SPT_POLYLINE:383        ptr0=&tmpg0->nu.u;384        ptr1=&tmpg1->nu.u;385        ptrr=&tmpgr->nu.u;386        for (i=0;i<tmpg0->nu.num;i++) {387          ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;388          ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;389        }390        break;391      case SPT_POLYPT:392        tmpgr->npu.x=(tmpg0->npu.x*t0+tmpg1->npu.x*t1)>>32;393        tmpgr->npu.y=(tmpg0->npu.y*t0+tmpg1->npu.y*t1)>>32;394        break;395      case SPT_BSPLINE2:396      case SPT_BSPLINE3:397      case SPT_BSPLINE2_CLOSED:398      case SPT_BSPLINE3_CLOSED:399        p0=&tmpg0->nu.u;400        p1=&tmpg1->nu.u;401        pr=&tmpgr->nu.u;402        for (i=0;i<tmpg0->nu.num;i++) {403          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;404          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;405          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;406        }407        break;408      case SPT_MESH:409        p0=&tmpg0->mu.u;410        p1=&tmpg1->mu.u;411        pr=&tmpgr->mu.u;412        for (i=0;i<tmpg0->mu.vertex_cnt;i++) {413          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;414          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;415          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;416        }417        break;418      case SPT_SHIFTABLE_MESH:419        p0=&tmpg0->pmu.u;420        p1=&tmpg1->pmu.u;421        pr=&tmpgr->pmu.u;422        for (i=0;i<tmpg0->pmu.vertex_cnt;i++) {423          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;424          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;425          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;426        }427        break;428    }429    tmpg0(U8 *)+=SpriteElemSize(tmpg0);430    tmpg1(U8 *)+=SpriteElemSize(tmpg1);431    tmpgr(U8 *)+=SpriteElemSize(tmpgr);432  }433  return res;434}435 436#help_index "Graphics/Sprite;DolDoc/Output;StdOut/DolDoc"437public CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL)438{//Put a sprite into a document.  You can, optionally, supply a fmt string439//for DolDoc cmd with a %d for the bin_num.440  I64 size;441  U8 *st;442  Bool unlock;443  CDocEntry *doc_e;444  CDocBin *tmpb;445  if (!doc && !(doc=DocPut)) return NULL;446  unlock=DocLock(doc);447  size=SpriteSize(elems);448  tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);449  tmpb->size=size;450  tmpb->data=MAlloc(size,doc->mem_task);451  MemCpy(tmpb->data,elems,size);452  tmpb->num=doc->cur_bin_num;453  tmpb->use_cnt=1;454  QueIns(tmpb,doc->bin_head.last);455  if (fmt)456    st=MStrPrint(fmt,doc->cur_bin_num++);457  else458    st=MStrPrint("$SP,\"\",BI=%d$",doc->cur_bin_num++);459  doc_e=DocPrint(doc,"%s",st);460  Free(st);461  doc_e->bin_data=tmpb;462  if (doc_e && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)463    tmpb->tag=StrNew(doc_e->tag,doc->mem_task);464  if (unlock)465    DocUnlock(doc);466  return doc_e;467}468 469public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)470{//Put sprite to the command-line, DocPut.471//If you set fmt, then include dollars ("$SP ...$") and leave %d for num.472  CDoc *doc;473  if (doc=DocPut)474    return DocSprite(doc,elems,fmt);475  return NULL;476}477