Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
GrDC.txt432 linesDownload Raw Back to Gr
1 2#help_index "Graphics/Math/3D Transformation"3#help_file "::/Doc/Transform"4 5#define GR_SCALE        (1<<32)6 7public U0 Mat4x4MulXYZ(I64 *r,I64 *_x,I64 *_y,I64 *_z)8{//Rotate 3D point using 4x4 matrix. Uses fixed-point.9  I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;10  x1=(r[0*4+0]*xx+r[0*4+1]*yy+r[0*4+2]*zz+r[0*4+3])>>32;11  y1=(r[1*4+0]*xx+r[1*4+1]*yy+r[1*4+2]*zz+r[1*4+3])>>32;12  z1=(r[2*4+0]*xx+r[2*4+1]*yy+r[2*4+2]*zz+r[2*4+3])>>32;13  *_x=x1;*_y=y1;*_z=z1;14}15 16public U0 DCTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)17{//This is the dft dc->transform() callback.18//Uses fixed-point.19  Mat4x4MulXYZ(dc->r,_x,_y,_z);20  *_x+=dc->x;21  *_y+=dc->y;22  *_z+=dc->z;23}24 25public I64 *Mat4x4IdentEqu(I64 *r)26{//Set matrix to identity. Uses fixed-point.27  MemSet(r,0,sizeof(I64)*16);28  r[0*4+0].i32[1]=1;29  r[1*4+1].i32[1]=1;30  r[2*4+2].i32[1]=1;31  r[3*4+3].i32[1]=1;32  return r;33}34 35public I64 *Mat4x4IdentNew(CTask *mem_task=NULL)36{//MAlloc an identity matrix. Uses fixed-point.37  return Mat4x4IdentEqu(MAlloc(sizeof(I64)*16,mem_task));38}39 40public I64 Mat4x4NormSqr65536(I64 *r)41{//Norm Squared of r.42//(1.0/Sqrt(3))*65536=37837.2243  return SqrI64((r[0*4+0]*37838+r[0*4+1]*37838+r[0*4+2]*37838)>>32)+44        SqrI64((r[1*4+0]*37837+r[1*4+1]*37837+r[1*4+2]*37837)>>32)+45        SqrI64((r[2*4+0]*37837+r[2*4+1]*37837+r[2*4+2]*37837)>>32);46}47 48public U0 DCMat4x4Set(CDC *dc=NULL,I64 *r)49{//Set device context's rot matrix. Will be Freed() in DCDel().Uses fixed-point.50//The main purpose is to set matrix norm for thick scaling.51  //NULL as dc means gr.dc52  if (!dc)   dc=gr.dc;53  dc->r=r;54  dc->r_norm=Sqrt(Mat4x4NormSqr65536(r))*65536; //scaled 32 bits55}56 57#help_index "Graphics/Mesh"58public U0 DCLighting(CDC *dc,59        CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)60{//This is the dft dc->lighting() callback.61  CD3I32 v1,v2;62  I64 i,vn_x,vn_y,vn_z;63  F64 d;64 65  v1.x=p1->x-p2->x;66  v1.y=p1->y-p2->y;67  v1.z=p1->z-p2->z;68 69  v2.x=p3->x-p2->x;70  v2.y=p3->y-p2->y;71  v2.z=p3->z-p2->z;72 73  //V1 and V2 are vects along two sides74  //of the tri joined at p2.75 76  vn_x=v1.y*v2.z-v1.z*v2.y;77  vn_y=v1.z*v2.x-v1.x*v2.z;78  vn_z=v1.x*v2.y-v1.y*v2.x;79  if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))80    d=1<<16/d;81  vn_x*=d;82  vn_y*=d;83  vn_z*=d;84//Vn is the cross product of V1 and V385  //which means it is perpendicular.  It86  //is the normal vect to the surface.87  //It has been scaled to length 65536.88 89  //Light source has been scaled to length 65536.90  i=(vn_x*dc->ls.x+vn_y*dc->ls.y+vn_z*dc->ls.z)>>16;91//The dot product of the light source92  //vect and the surface normal93  //gives an illumination number.94  //65536*65536>>16=6553695 96  //TempleOS will generate a random U1697  //and compare to dither_probability_u16 and98  //will pick from two colors.99  //Probability dithering does not work with thick>1 at this time.100  if (color.c0.rop&ROPBF_TWO_SIDED) {101    color.c0.rop&=~ROPBF_TWO_SIDED;102    i=AbsI64(i)<<1;103  } else104    i+=65536;105  if (color.c0.rop&ROPBF_HALF_RANGE_COLOR) {106    color.c0.rop&=~ROPBF_HALF_RANGE_COLOR;107    i>>=1;108    if (color>=8) {109      color-=8;110      i+=65536;111    }112  }113  if (i<65536) {114    dc->color=ROPF_PROBABILITY_DITHER+color<<16+BLACK;115    dc->dither_probability_u16=i;116  } else {117    dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;118    dc->dither_probability_u16=i-65536;119  }120}121 122#help_index "Graphics/Device Contexts"123public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=TRANSPARENT)124{//Fill entire device context with color.125  if (!dc) dc=gr.dc;126  MemSet(dc->body,val,dc->width_internal*dc->height);127}128 129public U0 DCClear(CDC *dc=NULL)130{//Set entire device context image body to 0 (BLACK).131  if (!dc) dc=gr.dc;132  DCFill(dc,0);133}134 135public U0 DCRst(CDC *dc)136{//Reset CDC structure members but not image body, itself.137  dc->color=BLACK;138  dc->color2=BLACK;139  dc->bkcolor=BLACK;140  dc->collision_cnt=0;141  dc->thick=1;142  dc->ls.x=37837; //1<<16/Sqrt(3)143  dc->ls.y=37837;144  dc->ls.z=37837;145  dc->x=0;146  dc->y=0;147  dc->z=0;148  dc->transform=&DCTransform;149  dc->lighting =&DCLighting;150  Mat4x4IdentEqu(dc->r);151  dc->r_norm=GR_SCALE;152  dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);153  MemCpy(dc->palette,gr_palette_std,sizeof(CBGR48)*COLORS_NUM);154}155 156public U0 DCExtentsInit(CDC *dc=NULL)157{//Init markers for extent of next newly drawn graphics.158//NULL means gr.dc159  //See ::/Demo/Graphics/Extents.HC160  //You should clear the record flag yourself161  if (!dc)   dc=gr.dc;162  dc->flags|=DCF_RECORD_EXTENTS;163  dc->min_x=I64_MAX;164  dc->max_x=I64_MIN;165  dc->min_y=I64_MAX;166  dc->max_y=I64_MIN;167}168 169public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)170{//Create alias of dc, so can change pen, color, etc.171//NULL means gr.dc172  CDC *res;173  if (!dc)   dc=gr.dc;174  if (!task) task=Fs;175  if (dc->dc_signature!=DCS_SIGNATURE_VAL)176    throw('Graphics');177  res=MAlloc(sizeof(CDC),task);178  MemCpy(res,dc,sizeof(CDC));179  res->win_task=res->mem_task=task;180  res->r=MAlloc(16*sizeof(I64),task);181  DCRst(res);182  res->flags|=DCF_ALIAS;183  res->alias=dc;184  return res;185}186 187public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)188{//Create new width x height device context.189//Internally only allows widths which are divisible by 8.190  //Don't forget these sizeof(CDC).191  CDC *res;192  if (!task) task=Fs;193  res=CAlloc(sizeof(CDC),task);194  res->win_task=task;195  res->mem_task=task;196  res->width=width;197  res->width_internal=(width+7)&~7;198  res->height=height;199  if (null_bitmap)200    res->flags|=DCF_DONT_DRAW;201  else202    res->body=CAlloc(res->width_internal*res->height,task);203  res->r=MAlloc(16*sizeof(I64),task);204  DCRst(res);205  res->dc_signature=DCS_SIGNATURE_VAL;206  return res;207}208 209public U0 DCDel(CDC *dc)210{//Free dc, image body, rot mat and depth buf.211  if (!dc) return;212  if (dc->dc_signature!=DCS_SIGNATURE_VAL)213    throw('Graphics');214  dc->dc_signature=0;215  Free(dc->r);216  if (!(dc->flags & DCF_ALIAS))217    Free(dc->body);218  Free(dc->depth_buf);219  Free(dc);220}221 222public I64 DCSize(CDC *dc)223{//Mem size of header, image body and depth buffer.224  if (dc)225    return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);226  else227    return 0;228}229 230public I32 *DCDepthBufRst(CDC *dc)231{//Reset device context depth buf to far away.232  if (dc->depth_buf)233    MemSetU32(dc->depth_buf,I32_MAX,dc->width_internal*dc->height);234  return dc->depth_buf;235}236 237public I32 *DCDepthBufAlloc(CDC *dc)238{//Alloc a 32-bit depth buffer for device context.239  Free(dc->depth_buf);240  dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);241  return DCDepthBufRst(dc);242}243 244public CDC *DCCopy(CDC *dc,CTask *task=NULL)245{//Alloc copy of dc, including image body, rot mat and depth buf.246  CDC *res;247  if (!dc) return NULL;248  if (dc->dc_signature!=DCS_SIGNATURE_VAL)249    throw('Graphics');250  res=MAllocIdent(dc,task);251  DCMat4x4Set(res,Mat4x4New(dc->r,task));252  res->mem_task=task;253  res->body=MAllocIdent(dc->body,task);254  res->depth_buf=MAllocIdent(dc->depth_buf,task);255  return res;256}257 258public U0 DCMono(CDC *dc,259  I64 quest=TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)260{//Set entire device context to one of two colors.261  I64 i;262  U8 *dst;263  dst=dc->body;264  i=dc->width_internal*dc->height;265  while (i--)266    if (*dst==quest)267      *dst++=true_color;268    else269      *dst++=false_color;270}271 272public I64 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=TRANSPARENT)273{//Find and replace src color with dst in device context.274  I64 i,res=0;275  U8 *dst;276  dst=dc->body;277  i=dc->width_internal*dc->height;278  while (i--)279    if (*dst==src_color) {280      *dst++=dst_color;281      res++;282    } else283      dst++;284  return res;285}286 287public U8 *DCSave(CDC *dc,I64 *_size=NULL,I64 dcsf_flags=DCSF_COMPRESSED)288{//Stores device context to mem, perhaps, with compression.289  U8 *res,*ptr,*body;290  CArcCompress *arc;291  I64 body_size=dc->width_internal*dc->height,total_size,flags;292  CBGR48 palette[COLORS_NUM];293 294  if (dcsf_flags&DCSF_COMPRESSED) {295    arc=CompressBuf(dc->body,body_size);296    body_size=arc->compressed_size;297    body=arc;298  } else {299    arc=NULL;300    body=dc->body;301  }302 303  total_size=offset(CDC.end)-offset(CDC.start)+body_size;304  if (dcsf_flags&DCSF_COMPRESSED)305    flags=DCF_COMPRESSED;306  else307    flags=0;308 309  if (dcsf_flags&DCSF_PALETTE_GET)310    GrPaletteGet(palette);311  else312    MemCpy(palette,&dc->palette,COLORS_NUM*sizeof(CBGR48));313  if (MemCmp(palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48))) {314    flags|=DCF_PALETTE;315    total_size+=COLORS_NUM*sizeof(CBGR48);316  }317 318  ptr=res=MAlloc(total_size);319 320#assert !offset(CDC.start)321  MemCpy(ptr,&dc->start,offset(CDC.end)-offset(CDC.start));322  ptr(CDC *)->flags=flags;323  ptr+=offset(CDC.end)-offset(CDC.start);324 325#assert offset(CDC.end)==offset(CDC.palette)326  if (flags&DCF_PALETTE) {327    MemCpy(ptr,palette,COLORS_NUM*sizeof(CBGR48));328    ptr+=COLORS_NUM*sizeof(CBGR48);329  }330 331  MemCpy(ptr,body,body_size);332  ptr+=body_size;333 334  Free(arc);335  if (_size) *_size=total_size;336  return res;337}338 339public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)340{//Loads device context from mem.341  CDC *res;342  U8 *ptr=src;343  CArcCompress *arc;344  I64 body_size;345  if (!task) task=Fs;346  res=CAlloc(sizeof(CDC),task);347  res->win_task=task;348  res->mem_task=task;349  MemCpy(&res->start,ptr,offset(CDC.end)-offset(CDC.start));350  ptr+=offset(CDC.end)-offset(CDC.start);351 352  if (res->flags&DCF_PALETTE) {353    MemCpy(&res->palette,ptr,COLORS_NUM*sizeof(CBGR48));354    ptr+=COLORS_NUM*sizeof(CBGR48);355  } else356    MemCpy(&res->palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48));357 358  body_size=res->width_internal*res->height;359  if (res->flags&DCF_COMPRESSED) {360    res->flags&=~DCF_COMPRESSED;361    arc=ptr;362    res->body=ExpandBuf(arc,task);363    ptr+=arc->compressed_size;364  } else {365    res->body=MAlloc(body_size,task);366    MemCpy(res->body,ptr,body_size);367    ptr+=body_size;368  }369  res->thick=1;370  res->r=Mat4x4IdentNew(task);371  res->r_norm.u32[1]=1;372  res->dc_signature=DCS_SIGNATURE_VAL;373  if (_size) *_size=ptr-src;374  return res;375}376 377#help_index "Graphics/GR Files"378#help_file "::/Doc/GRFiles"379#help_index "Graphics/Device Contexts;Graphics/GR Files"380public I64 GRWrite(U8 *filename,CDC *dc,I64 dcsf_flags=DCSF_COMPRESSED)381{//TempleOS GR File.382  I64   size;383  U8    *st=ExtDft(filename,"GR.Z"),384        *src=DCSave(dc,&size,dcsf_flags);385  FileWrite(st,src,size);386  Free(st);387  Free(src);388  return size;389}390 391public CDC *GRRead(U8 *filename,CTask *task=NULL)392{//TempleOS GR File.393  CDC   *dc=NULL;394  U8    *st=ExtDft(filename,"GR.Z"),395        *src=FileRead(st);396  if (src)397    dc=DCLoad(src,,task);398  Free(src);399  Free(st);400  return dc;401}402 403#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"404public U0 DocGR(CDoc *doc=NULL,U8 *filename)405{//Put a GR file into a document as asprite.406  CDC *dc=GRRead(filename);407  CSprite *elems=DC2Sprite(dc);408  DocSprite(doc,elems);409  Free(elems);410  DCDel(dc);411}412 413#help_index "Graphics/Device Contexts;Graphics/Scrn"414public CDC *DCScrnCapture(Bool include_zoom=TRUE,CTask *task=NULL)415{//Capture scrn to a device context.416  CDC *dc;417  U8 *dst;418  Refresh(2,TRUE);419  if (include_zoom)420    dc=DCCopy(gr.scrn_image,task);421  else422    dc=DCCopy(gr.dc1,task);423  dc->flags&=~DCF_SCRN_BITMAP;424  dst=MAlloc(dc->width_internal*dc->height,task);425//Pick background color that never occurs. COLOR_INVALID426  GrBitMap4ToBitMap8(dst,dc->body,427        (dc->width_internal*dc->height)>>1,COLOR_INVALID);428  Free(dc->body);429  dc->body=dst;430  return dc;431}432