hschumann2/TempleOS-Source-Code
0832
1 2#help_index "Graphics/Sprite;Sprites"3 4U0 SpriteElem2Code(CDoc *doc,CSprite *tmpg)5{6 U8 buf1[STR_LEN],buf2[STR_LEN];7 I32 *ptr;8 I64 i,j,k,col,width_internal;9 CD3I32 *p;10 CMeshTri *tri;11 if (!doc) doc=DocPut;12 DocPrint(doc,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_CODES");13 switch (tmpg->type&SPG_TYPE_MASK) {14 case SPT_COLOR:15 DocPrint(doc,"{%s}",16 Color2Str(buf1,tmpg->c.color));17 break;18 case SPT_DITHER_COLOR:19 DocPrint(doc,"{%s}",20 Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|21 tmpg->d.dither_color.u8[1]<<COLORROP_BITS));22 break;23 case SPT_TRANSFORM_ON:24 DocPrint(doc,"{ON}");25 break;26 case SPT_TRANSFORM_OFF:27 DocPrint(doc,"{OFF}");28 break;29 case SPT_LINE:30 case SPT_ARROW:31 case SPT_PLANAR_SYMMETRY:32 DocPrint(doc,"{(%d,%d),(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,33 tmpg->pp.x2,tmpg->pp.y2);34 break;35 case SPT_RECT:36 DocPrint(doc,"{(%d,%d):(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,37 tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);38 break;39 case SPT_ROTATED_RECT:40 DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->ppa.x1,tmpg->ppa.y1,41 tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1,42 180/pi*Wrap(tmpg->ppa.angle));43 break;44 case SPT_PT:45 case SPT_FLOOD_FILL:46 case SPT_SHIFT:47 DocPrint(doc,"{(%d,%d)}",tmpg->p.x1,tmpg->p.y1);48 break;49 case SPT_FLOOD_FILL_NOT:50 DocPrint(doc,"{(%d,%d),TRUE}",tmpg->p.x1,tmpg->p.y1);51 break;52 case SPT_CIRCLE:53 DocPrint(doc,"{(%d,%d):%d}",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);54 break;55 case SPT_THICK:56 DocPrint(doc,"{%d}",tmpg->t.thick);57 break;58 case SPT_ELLIPSE:59 DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->pwha.x1,tmpg->pwha.y1,60 tmpg->pwha.width,tmpg->pwha.height,180/pi*Wrap(tmpg->pwha.angle));61 break;62 case SPT_POLYGON:63 DocPrint(doc,"{%d,(%d,%d):(%d,%d),%0.4f}",tmpg->pwhas.sides,64 tmpg->pwhas.x1,tmpg->pwhas.y1,65 tmpg->pwhas.width,tmpg->pwhas.height,66 180/pi*Wrap(tmpg->pwhas.angle));67 break;68 case SPT_TEXT:69 case SPT_TEXT_BOX:70 case SPT_TEXT_DIAMOND:71 DocPrint(doc,"{(%d,%d),\"%Q\"}",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);72 break;73 case SPT_POLYLINE:74 ptr=&tmpg->nu.u;75 DocPrint(doc,"{");76 for (i=0;i<tmpg->nu.num;i++,ptr+=2) {77 DocPrint(doc,"(%d,%d)",ptr[0],ptr[1]);78 if (i+1<tmpg->nu.num) DocPrint(doc,",");79 if (i&3==3 && i+1<tmpg->nu.num)80 DocPrint(doc,"\n");81 }82 DocPrint(doc,"}");83 break;84 case SPT_BSPLINE2:85 case SPT_BSPLINE3:86 case SPT_BSPLINE2_CLOSED:87 case SPT_BSPLINE3_CLOSED:88 ptr=&tmpg->nu.u;89 DocPrint(doc,"{");90 for (i=0;i<tmpg->nu.num;i++,ptr+=3) {91 DocPrint(doc,"(%d,%d,%d)",ptr[0],ptr[1],ptr[2]);92 if (i+1<tmpg->nu.num) DocPrint(doc,",");93 if (i&3==3 && i+1<tmpg->nu.num)94 DocPrint(doc,"\n");95 }96 if (tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE2||97 tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE3)98 DocPrint(doc,",FALSE}");99 else100 DocPrint(doc,",TRUE}");101 break;102 case SPT_POLYPT:103 DocPrint(doc,"{(%d,%d),",tmpg->npu.x,tmpg->npu.y);104 ptr=&tmpg->npu.u;105 col=16;106 for (i=0;i<tmpg->npu.num;i++) {107 DocPrint(doc,"%d",BFieldExtU32(ptr,i*3,3));108 if (++col>=64 && i+1<tmpg->npu.num) {109 DocPrint(doc,"\n");110 col=0;111 }112 }113 DocPrint(doc,"}");114 break;115 case SPT_BITMAP:116 DocPrint(doc,"{(%d,%d):(%d,%d),\n",tmpg->pwhu.x1,tmpg->pwhu.y1,117 tmpg->pwhu.width,tmpg->pwhu.height);118 width_internal=(tmpg->pwhu.width+7)&~7;119 if (width_internal<80)120 k=width_internal;121 else122 k=64;123 ptr=&tmpg->pwhu.u;124 col=0;125 for (j=0;j<tmpg->pwhu.height;j++)126 for (i=0;i<width_internal;i++,ptr(U8 *)++) {127 if (i>=tmpg->pwhu.width)128 DocPrint(doc,"_");129 else if (*ptr(U8 *)<16)130 DocPrint(doc,"%X",*ptr(U8 *));131 else132 DocPrint(doc,"%c",CH_SHIFT_SPACE);133 if (++col>=k && (i+1<width_internal||j+1<tmpg->pwhu.height)) {134 DocPrint(doc,"\n");135 col=0;136 }137 }138 DocPrint(doc,"}");139 break;140 case SPT_MESH:141 DocPrint(doc,"{FALSE,");142 p=&tmpg->mu.u;143 col=0;144 for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {145 DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);146 if (i+1<tmpg->mu.vertex_cnt) DocPrint(doc,",");147 if (++col==4) {148 DocPrint(doc,"\t//%d\n",i);149 col=0;150 }151 }152 DocPrint(doc,":");153 tri=p;154 for (i=0;i<tmpg->mu.tri_cnt;i++,tri++) {155 DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),156 tri->nums[0],tri->nums[1],tri->nums[2]);157 if (i+1<tmpg->mu.tri_cnt) DocPrint(doc,",");158 if (++col>=3 && i+1<tmpg->mu.tri_cnt) {159 DocPrint(doc,"\n");160 col=0;161 }162 }163 DocPrint(doc,"}");164 break;165 case SPT_SHIFTABLE_MESH:166 DocPrint(doc,"{TRUE,(%d,%d,%d):",tmpg->pmu.x,tmpg->pmu.y,tmpg->pmu.z);167 p=&tmpg->pmu.u;168 col=1;169 for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {170 DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);171 if (i+1<tmpg->pmu.vertex_cnt) DocPrint(doc,",");172 if (++col==4) {173 DocPrint(doc,"\t//%d\n",i);174 col=0;175 }176 }177 DocPrint(doc,":");178 tri=p;179 for (i=0;i<tmpg->pmu.tri_cnt;i++,tri++) {180 DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),181 tri->nums[0],tri->nums[1],tri->nums[2]);182 if (i+1<tmpg->pmu.tri_cnt) DocPrint(doc,",");183 if (++col>=3 && i+1<tmpg->pmu.tri_cnt) {184 DocPrint(doc,"\n");185 col=0;186 }187 }188 DocPrint(doc,"}");189 break;190 }191 DocPrint(doc,";\n");192}193 194public U0 Sprite2Code(CDoc *doc=NULL,U8 *elems)195{//Sprite to text.196 CSprite *tmpg=elems-offset(CSprite.start);197 while (tmpg->type&SPG_TYPE_MASK) {198 SpriteElem2Code(doc,tmpg);199 tmpg(U8 *)+=SpriteElemSize(tmpg);200 }201}202 203CSprite *Code2SpriteElem(CCmpCtrl *cc,I64 type)204{205 I64 i,num1,num2,size;206 CSprite *res,g;207 CColorROPU32 color;208 U8 *st,*ptr;209 CQueD3I32 headp,*tmpp,*tmpa1;210 CQueMeshTri headt,*tmpt,*tmpt1;211 CQueVectU8 *tmpv;212 MemSet(&g,0,sizeof(CSprite));213 switch (type) {214 start:215 case SPT_COLOR:216 case SPT_DITHER_COLOR:217 st=LexFirstRem(cc,"}");218 color=Str2ColorU32(st);219 Free(st);220 Lex(cc); //Skip color221 g.c.color=color.c0.color;222 if (color&ROPF_DITHER) {223 g.d.dither_color.u8[1]=color.c1.color;224 g.type=SPT_DITHER_COLOR;225 } else226 g.type=SPT_COLOR;227 break;228 case SPT_TRANSFORM_ON:229 case SPT_TRANSFORM_OFF:230 Lex(cc); //Skip {231 if (LexExpressionI64(cc))232 g.type=SPT_TRANSFORM_ON;233 else234 g.type=SPT_TRANSFORM_OFF;235 break;236 case SPT_LINE:237 case SPT_ARROW:238 case SPT_PLANAR_SYMMETRY:239 Lex(cc); //Skip {240 g.type=type;241 LexD2I32(cc,&g.pp.x1);242 if (cc->token!=',')243 LexExcept(cc,"Expecting ',' at ");244 Lex(cc); //Skip ,245 LexD2I32(cc,&g.pp.x2);246 break;247 case SPT_RECT:248 case SPT_ROTATED_RECT:249 Lex(cc); //Skip {250 LexD2I32(cc,&g.pp.x1);251 if (cc->token!=':')252 LexExcept(cc,"Expecting ':' at ");253 Lex(cc); //Skip :254 LexD2I32(cc,&g.pp.x2);255 g.ppa.x2+=g.pp.x1;256 g.ppa.y2+=g.pp.y1;257 if (cc->token==',') {258 Lex(cc); //Skip ,259 g.ppa.angle=pi/180*LexExpressionF64(cc);260 g.type=SPT_ROTATED_RECT;261 } else262 g.type=SPT_RECT;263 break;264 case SPT_PT:265 case SPT_SHIFT:266 Lex(cc); //Skip {267 g.type=type;268 LexD2I32(cc,&g.p.x1);269 break;270 case SPT_FLOOD_FILL:271 case SPT_FLOOD_FILL_NOT:272 Lex(cc); //Skip {273 LexD2I32(cc,&g.p.x1);274 if (cc->token==',') {275 Lex(cc); //Skip ,276 i=LexExpressionI64(cc);277 } else278 i=0;279 if (i)280 g.type=SPT_FLOOD_FILL_NOT;281 else282 g.type=SPT_FLOOD_FILL;283 break;284 case SPT_THICK:285 Lex(cc); //Skip {286 g.t.thick=LexExpressionI64(cc);287 g.type=SPT_THICK;288 break;289 case SPT_CIRCLE:290 Lex(cc); //Skip {291 g.type=SPT_CIRCLE;292 LexD2I32(cc,&g.pr.x1);293 if (cc->token!=':')294 LexExcept(cc,"Expecting ':' at ");295 Lex(cc); //Skip :296 g.pr.radius=LexExpressionI64(cc);297 break;298 case SPT_POLYGON:299 Lex(cc); //Skip {300 g.pwhas.sides=LexExpressionI64(cc);301 if (cc->token!=',')302 LexExcept(cc,"Expecting ',' at ");303 case SPT_ELLIPSE:304 Lex(cc); //Skip {305 g.type=type;306 LexD2I32(cc,&g.pwha.x1);307 if (cc->token!=':')308 LexExcept(cc,"Expecting ':' at ");309 Lex(cc); //Skip :310 LexD2I32(cc,&g.pwha.width);311 if (cc->token!=',')312 LexExcept(cc,"Expecting ',' at ");313 Lex(cc); //Skip ,314 g.pwha.angle=pi/180*LexExpressionF64(cc);315 break;316 end:317 size=SpriteElemSize(&g)+offset(CSprite.start);318 res=MAlloc(size);319 MemCpy(res,&g,size);320 break;321 case SPT_TEXT:322 case SPT_TEXT_BOX:323 case SPT_TEXT_DIAMOND:324 Lex(cc); //Skip {325 g.type=type;326 LexD2I32(cc,&g.ps.x1);327 if (cc->token!=',')328 LexExcept(cc,"Expecting ',' at ");329 if (Lex(cc)==TK_STR) //Skip ,330 st=LexExtStr(cc);331 else332 LexExcept(cc,"Expecting string at ");333 size=SpriteElemQuedBaseSize(type);334 i=StrLen(st)+1;335 res=MAlloc(size+i);336 MemCpy(res,&g,size);337 MemCpy(res(U8 *)+size,st,i);338 Free(st);339 break;340 case SPT_POLYLINE:341 Lex(cc); //Skip {342 g.type=SPT_POLYLINE;343 QueInit(&headp);344 while (cc->token=='(') {345 tmpp=CAlloc(sizeof(CQueD3I32));346 LexD2I32(cc,&tmpp->p);347 QueIns(tmpp,headp.last);348 g.nu.num++;349 if (cc->token==',')350 Lex(cc); //Skip ,351 }352 if (g.nu.num<2)353 LexExcept(cc,"Expecting point at ");354 size=SpriteElemQuedBaseSize(SPT_POLYLINE);355 res=MAlloc(size+g.nu.num*sizeof(CD2I32));356 MemCpy(res,&g,size);357 ptr=&res->nu.u;358 tmpp=headp.next;359 while (tmpp!=&headp) {360 tmpa1=tmpp->next;361 MemCpy(ptr,&tmpp->p,sizeof(CD2I32));362 ptr+=sizeof(CD2I32);363 Free(tmpp);364 tmpp=tmpa1;365 }366 break;367 case SPT_BSPLINE2:368 case SPT_BSPLINE3:369 case SPT_BSPLINE2_CLOSED:370 case SPT_BSPLINE3_CLOSED:371 Lex(cc); //Skip {372 QueInit(&headp);373 while (cc->token=='(') {374 tmpp=CAlloc(sizeof(CQueD3I32));375 LexD3I32(cc,&tmpp->p);376 QueIns(tmpp,headp.last);377 g.nu.num++;378 if (cc->token==',')379 Lex(cc); //Skip ,380 }381 if (g.nu.num<2)382 LexExcept(cc,"Expecting point at ");383 size=SpriteElemQuedBaseSize(type);384 res=MAlloc(size+g.nu.num*sizeof(CD3I32));385 if (LexExpressionI64(cc)) {386 if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)387 g.type=SPT_BSPLINE2_CLOSED;388 else389 g.type=SPT_BSPLINE3_CLOSED;390 } else {391 if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)392 g.type=SPT_BSPLINE2;393 else394 g.type=SPT_BSPLINE3;395 }396 MemCpy(res,&g,size);397 ptr=&res->nu.u;398 tmpp=headp.next;399 while (tmpp!=&headp) {400 tmpa1=tmpp->next;401 MemCpy(ptr,&tmpp->p,sizeof(CD3I32));402 ptr+=sizeof(CD3I32);403 Free(tmpp);404 tmpp=tmpa1;405 }406 break;407 case SPT_POLYPT:408 Lex(cc); //Skip {409 LexD2I32(cc,&g.npu.x);410 if (cc->token!=',')411 LexExcept(cc,"Expecting ',' at ");412 tmpv=QueVectU8New;413 while (TRUE) {414 if (!(i=LexGetChar(cc)))415 LexExcept(cc,"Expecting '}' at ");416 if (i=='}')417 break;418 if ('0'<=i<='7')419 QueVectU8Put(tmpv,g.npu.num++,i-'0');420 }421 Bts(&cc->flags,CCf_USE_LAST_U16);422 Lex(cc); //Load '}'423 g.type=SPT_POLYPT;424 size=SpriteElemQuedBaseSize(SPT_POLYPT);425 res=CAlloc(size+(g.npu.num*3+7)>>3);426 MemCpy(res,&g,size);427 ptr=&res->npu.u;428 for (i=0;i<g.npu.num;i++)429 BFieldOrU32(ptr,i*3,QueVectU8Get(tmpv,i));430 QueVectU8Del(tmpv);431 break;432 case SPT_BITMAP:433 Lex(cc); //Skip {434 LexD2I32(cc,&g.pwhu.x1);435 if (cc->token!=':')436 LexExcept(cc,"Expecting ':' at ");437 Lex(cc); //Skip :438 LexD2I32(cc,&g.pwhu.width);439 if (cc->token!=',')440 LexExcept(cc,"Expecting ',' at ");441 tmpv=QueVectU8New;442 num1=0;443 while (TRUE) {444 if (!(i=ToUpper(LexGetChar(cc))))445 LexExcept(cc,"Expecting '}' at ");446 if (i=='}')447 break;448 if ('0'<=i<='9')449 QueVectU8Put(tmpv,num1++,i-'0');450 else if ('A'<=i<='F')451 QueVectU8Put(tmpv,num1++,i-'A'+10);452 else if (i==CH_SPACE||i==CH_SHIFT_SPACE)453 QueVectU8Put(tmpv,num1++,TRANSPARENT);454 else if (i=='_')455 QueVectU8Put(tmpv,num1++,0);456 }457 Bts(&cc->flags,CCf_USE_LAST_U16);458 Lex(cc); //Load '}'459 g.type=SPT_BITMAP;460 size=SpriteElemQuedBaseSize(SPT_BITMAP);461 res=CAlloc(size+num1);462 MemCpy(res,&g,size);463 ptr=&res->pwhu.u;464 for (i=0;i<num1;i++)465 *ptr++=QueVectU8Get(tmpv,i);466 QueVectU8Del(tmpv);467 break;468 case SPT_MESH:469 case SPT_SHIFTABLE_MESH:470 Lex(cc); //Skip {471 if (LexExpressionI64(cc)) {472 g.type=SPT_SHIFTABLE_MESH;473 if (cc->token!=',')474 LexExcept(cc,"Expecting ',' at ");475 Lex(cc); //Skip ,476 LexD3I32(cc,&g.pmu.x);477 if (cc->token!=':')478 LexExcept(cc,"Expecting ':' at ");479 Lex(cc); //Skip :480 } else {481 g.type=SPT_MESH;482 if (cc->token!=',')483 LexExcept(cc,"Expecting ',' at ");484 Lex(cc); //Skip ,485 }486 num1=0;487 QueInit(&headp);488 while (cc->token=='(') {489 tmpp=CAlloc(sizeof(CQueD3I32));490 LexD3I32(cc,&tmpp->p);491 QueIns(tmpp,headp.last);492 num1++;493 if (cc->token==',')494 Lex(cc); //Skip ,495 }496 if (cc->token!=':')497 LexExcept(cc,"Expecting ':' at ");498 Lex(cc); //Skip :499 num2=0;500 QueInit(&headt);501 while (cc->token=='(') {502 tmpt=CAlloc(sizeof(CQueMeshTri));503 st=LexFirstRem(cc,",");504 tmpt->color=Str2ColorU32(st);505 Free(st);506 Lex(cc); //Skip color507 if (cc->token!=',')508 LexExcept(cc,"Expecting ',' at ");509 Lex(cc); //Skip ,510 tmpt->nums[0]=LexExpressionI64(cc);511 if (cc->token!=',')512 LexExcept(cc,"Expecting ',' at ");513 Lex(cc); //Skip ,514 tmpt->nums[1]=LexExpressionI64(cc);515 if (cc->token!=',')516 LexExcept(cc,"Expecting ',' at ");517 Lex(cc); //Skip ,518 tmpt->nums[2]=LexExpressionI64(cc);519 if (cc->token!=')')520 LexExcept(cc,"Expecting ')' at ");521 Lex(cc); //Skip )522 QueIns(tmpt,headt.last);523 num2++;524 if (cc->token==',')525 Lex(cc); //Skip ,526 }527 if (g.type==SPT_MESH) {528 g.mu.vertex_cnt=num1;529 g.mu.tri_cnt=num2;530 size=SpriteElemQuedBaseSize(SPT_MESH);531 } else {532 g.pmu.vertex_cnt=num1;533 g.pmu.tri_cnt=num2;534 }535 size=SpriteElemQuedBaseSize(g.type);536 res=MAlloc(size+num1*sizeof(CD3I32)+num2*sizeof(CMeshTri));537 MemCpy(res,&g,size);538 ptr=res(U8 *)+size;539 tmpp=headp.next;540 while (tmpp!=&headp) {541 tmpa1=tmpp->next;542 MemCpy(ptr,&tmpp->p,sizeof(CD3I32));543 ptr+=sizeof(CD3I32);544 Free(tmpp);545 tmpp=tmpa1;546 }547 tmpt=headt.next;548 while (tmpt!=&headt) {549 tmpt1=tmpt->next;550 MemCpy(ptr,&tmpt->start,sizeof(CMeshTri));551 ptr+=sizeof(CMeshTri);552 Free(tmpt);553 tmpt=tmpt1;554 }555 break;556 }557 if (cc->token!='}')558 LexExcept(cc,"Expecting '}' at ");559 if (Lex(cc)!=';')560 LexExcept(cc,"Expecting ';' at ");561 return res;562}563 564public U8 *Code2Sprite(CDoc *doc,I64 *_size=NULL)565{//Text to sprite.566 CSprite head;567 U8 *res;568 Bool okay=TRUE,unlock_doc=DocLock(doc);569 CCmpCtrl *cc=CmpCtrlNew(,CCF_DONT_FREE_BUF);570 CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;571 CHashGeneric *tmph;572 I64 i,size=0;573 QueInit(&head);574 LexAttachDoc(cc,,doc);575 try {576 do {577 cc->htc.hash_table_lst=NULL;578 if (Lex(cc)==TK_IDENT && //Skip ;579 (tmph=HashFind(cc->cur_str,gr.sprite_hash,SPHT_ELEM_CODE))) {580 i=tmph->user_data0;581 cc->htc.hash_table_lst=old_hash_table_lst;582 if (Lex(cc)=='{') //Skip ident583 QueIns(Code2SpriteElem(cc,i),head.last);584 } else if (cc->token)585 LexExcept(cc,"Expecting sprite element type name at ");586 } while (cc->token);587 okay=TRUE;588 } catch {589 Fs->catch_except=TRUE;590 okay=FALSE;591 }592 if (unlock_doc)593 DocUnlock(doc);594 if (okay) {595 CmpCtrlDel(cc); //TODO: can crash596 res=SpriteQue2Sprite(&head,&size);597 } else {598 res=NULL;599 size=0;600 }601 if (_size) *_size=size;602 QueDel(&head);603 return res;604}605 