TempleOSTS_130315.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:45:37 +02:00
1 parent e57428affb
commit 17b71f1a2d
958 files changed
+26043 -15907

No files matched your search

+603
View File
@@ -0,0 +1,603 @@
#define GEBM_END 0
#define GEBM_CONT 1
#define GEBM_COLOR 2
#define GEBM_DITHER_COLOR 3
#define GEBM_WIDTH 4
#define GEBM_SNAP 5
#define GEBM_PT 6
#define GEBM_LINE 7
#define GEBM_ARROW 8
#define GEBM_RECT 9
#define GEBM_CIRCLE 10
#define GEBM_TEXT 11
#define GEBM_TEXT_BOX 12
#define GEBM_TEXT_DIAMOND 13
#define GEBM_FLOOD_FILL 14
#define GEBM_FLOOD_FILL_NOT 15
#define GEBM_POLYLINE 16
#define GEBM_POLYPT 17
#define GEBM_CUT 18
#define GEBM_DELETE 19
#define GEBM_PASTE 20
#define GEBM_PASTE_TRANSPARENT 21
#define GEBM_FIND_AND_REPLACE 22
#define GEBM_TRIM_TO_EXTENTS 23
#define GEBM_UNDO 24
I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width,I64 snap,F64 ip_scaler)
{
I64 i;
U8 *st1,*st2,buf[136];
CDoc *doc=DocNew;
Color2Text(buf,color);
if (color&ROPF_DITHER) {
st1="";
st2=buf;
} else {
st1=buf;
st2="";
}
DocPrintF(doc,"$$FG,PURPLE$$$$TX+CX,\"BitMap Menu\"$$$$FG$$\n"
"$$FG,RED$$Settings$$FG$$\n"
"$$MU-UL,\"Color %s\",GEBM_COLOR$$\n"
"$$MU-UL,\"Dither Color %s\",GEBM_DITHER_COLOR$$\n"
"$$MU-UL,\"Width %d\",GEBM_WIDTH$$\n"
"$$MU-UL,\"Snap %d %5.3f\",GEBM_SNAP$$\n"
"$$MU-UL,\"Find & Replace Color\",GEBM_FIND_AND_REPLACE$$\n"
"$$MU-UL,\"Trim to Extents\",GEBM_TRIM_TO_EXTENTS$$\n"
"\n$$FG,RED$$Objects$$FG$$\n"
"$$MU-UL,\"Point\",GEBM_PT$$\n"
"$$MU-UL,\"Line\",GEBM_LINE$$\n"
"$$MU-UL,\"Arrow\",GEBM_ARROW$$\n"
"$$MU-UL,\"Rect\",GEBM_RECT$$\n"
"$$MU-UL,\"Circle\",GEBM_CIRCLE$$\n"
"$$MU-UL,\"Text\",GEBM_TEXT$$\n"
"$$MU-UL,\"Text Box\",GEBM_TEXT_BOX$$\n"
"$$MU-UL,\"Text Diamond\",GEBM_TEXT_DIAMOND$$\n"
"$$MU-UL,\"Flood Fill\",GEBM_FLOOD_FILL$$\n"
"$$MU-UL,\"Flood Fill Not Color\",GEBM_FLOOD_FILL_NOT$$\n"
"$$MU-UL,\"PolyLine\",GEBM_POLYLINE$$\n"
"$$MU-UL,\"PolyPoint\",GEBM_POLYPT$$\n"
"\n$$FG,RED$$Clipboard$$FG$$\n"
"$$MU-UL,\"Cut\",GEBM_CUT$$\n"
"$$MU-UL,\"Delete\",GEBM_DELETE$$\n"
"$$MU-UL,\"Paste\",GEBM_PASTE$$\n"
"$$MU-UL,\"Paste Transparent\",GEBM_PASTE_TRANSPARENT$$\n"
"\n$$MU-UL,\"Undo\",GEBM_UNDO$$\n"
"\n$$FM,PURPLE$$$$MU-UL,\"+] Vect Object Menu\",GEBM_CONT$$$$FM,LTBLUE$$\n"
"$$MU-UL,\"End\",GEBM_END$$\n"
"$$MU-UL,\"Cancel\",DOCM_CANCEL$$\n",st1,st2,width,snap,ip_scaler);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U0 GrBMEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
{
DCFill(dc);
GrBlot(dc,xx1,yy1,img);
}
U0 GrBMEFindReplaceColor(CDC *img,I64 pattern,I64 replace)
{
U8 *dst=img->body;
I64 d0=img->height*img->width_internal;
while (d0--) {
if (*dst==pattern)
*dst=replace;
dst++;
}
}
U0 GrBMETrimToExtents(CDC **_img,I64 *_xx1,I64 *_yy1,I64 *_xx2,I64 *_yy2,CColorROPU32 bkcolor)
{
CDC *img=*_img;
I64 i,c,
x1=0,y1=0,x2=img->width-1,y2=img->height-1; //inclusive
while (y1<y2) {
for (i=x1;i<=x2;i++) {
c=GrPeek(img,i,y1);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_y2;
}
y1++;
}
tr_y2:
while (y1<y2) {
for (i=x1;i<=x2;i++) {
c=GrPeek(img,i,y2);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_x1;
}
y2--;
}
tr_x1:
while (x1<x2) {
for (i=y1;i<=y2;i++) {
c=GrPeek(img,x1,i);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_x2;
}
x1++;
}
tr_x2:
while (x1<x2) {
for (i=y1;i<=y2;i++) {
c=GrPeek(img,x2,i);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_done;
}
x2--;
}
tr_done:
*_img=DCExtract(img,x1,y1,x2,y2);
*_xx1+=x1; *_yy1+=y1;
*_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
DCDel(img);
}
I64 SpriteBitMap(CDC *dc,I64 *_xx1,I64 *_yy1,I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor,I64 *_import_snap=NULL,F64 *_import_ip_scaler=NULL)
{
I64 i,j,mode=GEBM_LINE,color=BLACK,width=1,msg_code,p1,p2,x1,y1,x11,y11,x22,y22,new_snap=1,
result,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2;
Bool down=FALSE;
F64 new_ip_scaler=1.0;
U8 *st=NULL;
CDC *img=*_img,
*clipboard=NULL,*undo=NULL,*dc2;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
if (_import_snap) new_snap=*_import_snap;
if (_import_ip_scaler) new_ip_scaler=*_import_ip_scaler;
SetSnap(&Fs->snap,new_snap,new_ip_scaler);
goto bm_menu;
while (TRUE) {
if (sys_cur_scan_code&SCF_CTRL)//grab scroll update?
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
while (msg_code=ScanMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_IP_L_UP|1<<MSG_IP_R_DOWN|
1<<MSG_IP_MOVE|1<<MSG_KEY_DOWN)) {
switch (msg_code) {
case MSG_KEY_DOWN:
if (p1==CH_SHIFT_ESC) {
result=GE_CANCEL;
goto bm_key_up_done;
} else if (p1==CH_ESC) {
result=GE_OKAY_CONT;
goto bm_key_up_done;
}
break;
case MSG_IP_R_DOWN:
bm_menu:
DCFill(dc);
switch (i=PopUpSpriteBitMap(color,width,new_snap,new_ip_scaler)) {
case DOCM_CANCEL:
result=GE_CANCEL;
goto bm_done;
case GEBM_END:
result=GE_OKAY_DONE;
goto bm_done;
case GEBM_CONT:
result=GE_OKAY_CONT;
goto bm_done;
case GEBM_COLOR:
i=PopUpColor(,,FALSE);
if (i>=0) color=i;
goto bm_menu;
case GEBM_FIND_AND_REPLACE:
i=PopUpColor("Find Color\n",,FALSE);
if (i>=0) {
j=PopUpColor("Replace Color\n",,FALSE);
if (j>=0) {
GrBMEFindReplaceColor(img,i,j);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
}
goto bm_menu;
case GEBM_TRIM_TO_EXTENTS:
GrBMETrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
goto bm_menu;
case GEBM_DITHER_COLOR:
i=PopUpDitherColor;
if (i>=0) color=i;
goto bm_menu;
case GEBM_WIDTH:
i=PopUpRangeI64(1,16,1,"Pen Width\n");
if (i>=0) width=i;
goto bm_menu;
case GEBM_SNAP:
PopUpSnap(&Fs->snap);
new_snap=Fs->snap.x;
new_ip_scaler=Fs->snap.dx;
goto bm_menu;
case GEBM_UNDO:
if (undo) {
Beep;
img->color=ROP_EQU;
GrBlot(img,0,0,undo);
DCDel(undo);
undo=NULL;
}
goto bm_menu;
case GEBM_PT:
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_FLOOD_FILL:
case GEBM_FLOOD_FILL_NOT:
case GEBM_POLYPT:
case GEBM_POLYLINE:
case GEBM_CUT:
case GEBM_DELETE:
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
mode=i;
break;
case GEBM_TEXT:
case GEBM_TEXT_BOX:
case GEBM_TEXT_DIAMOND:
Free(st);
st=PopUpMGetS("Enter text and press <ESC>.\n");
if (st && *st)
mode=i;
else
goto bm_menu;
break;
}
DCDel(undo);
undo=DCExtract(img,0,0,img->width-1,img->height-1);
undo->bkcolor=bkcolor;
WinMgrSync(2,TRUE); //Let popup close
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
down=FALSE;
break;
case MSG_IP_L_DOWN:
switch (mode) {
case GEBM_PT:
img->color=color;
img->pen_width=width;
GrPlot3(img,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_CUT:
case GEBM_DELETE:
if (down)
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
switch (mode) {
case GEBM_LINE:
GrLine3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_ARROW:
GrArrow3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_RECT:
GrRect(dc,x1,y1,1,1);
break;
case GEBM_CIRCLE:
GrCircle3(dc,x1,y1,0,1);
break;
case GEBM_CUT:
case GEBM_DELETE:
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x1,y1,x1,y1);
break;
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPutS(dc,p1,p2,st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_FLOOD_FILL:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_FLOOD_FILL_NOT:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1,TRUE);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_POLYLINE:
if (!down) {
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_POLYPT:
x1=p1; y1=p2;
down=TRUE;
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
}
break;
case MSG_IP_MOVE:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYLINE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(dc,x1,y1,0,p1,p2,0);
else
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_RECT:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=color;
GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
}
break;
case GEBM_CUT:
case GEBM_DELETE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x11,y11,x22,y22);
}
break;
case GEBM_CIRCLE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPutS(dc,p1,p2,st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_POLYPT:
if (down) {
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
}
break;
}
break;
case MSG_IP_L_UP:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYPT:
case GEBM_POLYLINE:
img->color=color;
img->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
else
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_POLYLINE) {
x1=p1; y1=p2;
} else
down=FALSE;
break;
case GEBM_RECT:
img->color=color;
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_CUT:
case GEBM_DELETE:
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
DCDel(clipboard);
clipboard=DCExtract(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
clipboard->bkcolor=bkcolor;
if (mode==GEBM_DELETE) {
img->color=bkcolor;
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
}
goto bm_menu;
case GEBM_CIRCLE:
img->color=color;
img->pen_width=width;
GrCircle3(img,x1-xx1,y1-yy1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(img,p1-xx1,p2-yy1,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(img,p1-xx1,p2-yy1,dc2);
DCDel(dc2);
}
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
break;
case GEBM_TEXT:
img->color=color;
GrPutS(img,p1-xx1,p2-yy1,st);
goto bm_menu;
case GEBM_TEXT_BOX:
img->color=color;
GrTextBox3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
case GEBM_TEXT_DIAMOND:
img->color=color;
GrTextDiamond3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
}
break;
}
}
WinMgrSync;
}
bm_key_up_done:
GetMsg(,,1<<MSG_KEY_UP);
bm_done:
DCDel(clipboard);
DCDel(undo);
Free(st);
DCFill(dc);
SettingsPop;
if (_import_snap) *_import_snap=new_snap;
if (_import_ip_scaler) *_import_ip_scaler=new_ip_scaler;
*_img=img;
*_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
return result;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+235
View File
@@ -0,0 +1,235 @@
#help_index "Graphics/CSprite"
#help_file "::/TempleOS/Doc/Sprite"
I64 gr_sprite_base_size[GRST_NUM_TYPES]=
{
offset(CSprite.x1)-offset(CSprite.start), //GRST_END
1,
1+offset(CSprite.color8)-offset(CSprite.start), //GRST_COLOR8
1,
offset(CSprite.x2)-offset(CSprite.start), //GRST_PT
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_LINE
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYLINE
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYPT
offset(CSprite.y1)-offset(CSprite.start), //GRST_WIDTH
offset(CSprite.x2)-offset(CSprite.start), //GRST_SHIFT
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2_CLOSED
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3_CLOSED
1,
1,
1,
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_RECT
offset(CSprite.y2)-offset(CSprite.start), //GRST_CIRCLE
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL_NOT
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_BITMAP8
1,
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT
offset(CSprite.sides)-offset(CSprite.start), //GRST_ELLIPSE
sizeof(CSprite)-offset(CSprite.start), //GRST_REG_POLY
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_PLANAR_SYMMETRY
2+offset(CSprite.dither_color8)-offset(CSprite.start), //GRST_DITHER_COLOR8
offset(CSprite.sides)-offset(CSprite.start), //GRST_ROTATED_RECT
offset(CSprite.x2)-offset(CSprite.start), //GRST_MESH
offset(CSprite.shiftable_triangle_cnt)+sizeof(I32)-offset(CSprite.start), //GRST_SHIFTABLE_MESH
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_ON
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_OFF
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_ARROW
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_BOX
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_DIAMOND
};
I64 gr_sprite_qued_base_size[GRST_NUM_TYPES]=
{
offset(CSprite.x1),//GRST_END
1,
1+offset(CSprite.color8), //GRST_COLOR8
1,
offset(CSprite.x2), //GRST_PT
offset(CSprite.linespeed), //GRST_LINE
offset(CSprite.y1), //GRST_POLYLINE
offset(CSprite.y1), //GRST_POLYPT
offset(CSprite.y1), //GRST_WIDTH
offset(CSprite.x2), //GRST_SHIFT
offset(CSprite.y1), //GRST_BSPLINE2
offset(CSprite.y1), //GRST_BSPLINE3
offset(CSprite.y1), //GRST_BSPLINE2_CLOSED
offset(CSprite.y1), //GRST_BSPLINE3_CLOSED
1,
1,
1,
offset(CSprite.linespeed), //GRST_RECT
offset(CSprite.y2), //GRST_CIRCLE
offset(CSprite.x2), //GRST_FLOOD_FILL_NOT
offset(CSprite.x2), //GRST_FLOOD_FILL
offset(CSprite.linespeed), //GRST_BITMAP8
1,
offset(CSprite.st), //GRST_TEXT
offset(CSprite.sides), //GRST_ELLIPSE
sizeof(CSprite), //GRST_REG_POLY
offset(CSprite.linespeed), //GRST_PLANAR_SYMMETRY
2+offset(CSprite.dither_color8), //GRST_DITHER_COLOR8
offset(CSprite.sides), //GRST_ROTATED_RECT
offset(CSprite.x2), //GRST_MESH
offset(CSprite.shiftable_triangle_cnt)+sizeof(I32), //GRST_SHIFTABLE_MESH
offset(CSprite.x1), //GRST_TRANSFORM_ON
offset(CSprite.x1), //GRST_TRANSFORM_OFF
offset(CSprite.linespeed), //GRST_ARROW
offset(CSprite.st), //GRST_TEXT_BOX
offset(CSprite.st), //GRST_TEXT_DIAMOND
};
I64 SpriteElemSize(CSprite *tempg)
{
I64 i=gr_sprite_base_size[tempg->type];
switch (tempg->type) {
case GRST_POLYLINE:
i+=tempg->num<<1*sizeof(I32);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
i+=StrLen(tempg->st)+1;
break;
case GRST_BITMAP8:
i+=((tempg->width+7)&~7)*tempg->height;
break;
case GRST_POLYPT:
i+=sizeof(I32)<<1+(tempg->num*3+7)>>3;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
i+=tempg->num*sizeof(CD3I32);
break;
case GRST_MESH:
i+=tempg->vertex_cnt*sizeof(CD3I32)+tempg->triangle_cnt*sizeof(CMeshTri);
break;
case GRST_SHIFTABLE_MESH:
i+=tempg->shiftable_vertex_cnt*sizeof(CD3I32)+tempg->shiftable_triangle_cnt*sizeof(CMeshTri);
break;
}
return i;
}
public I64 SpriteSize(U8 *elems)
{
CSprite *tempg=elems-offset(CSprite.start),*tempg1=tempg;
while (tempg->type)
tempg(U8 *)+=SpriteElemSize(tempg);
return tempg(U8 *)-tempg1(U8 *)+gr_sprite_base_size[GRST_END];
}
I64 SpriteTypeMask(U8 *elems)
{
I64 result=0;
CSprite *tempg=elems-offset(CSprite.start);
while (tempg->type) {
if (tempg->type>=GRST_NUM_TYPES)
return 1<<GRST_NUM_TYPES;
Bts(&result,tempg->type);
tempg(U8 *)+=SpriteElemSize(tempg);
}
return result;
}
public U8 *DC2Sprite(CDC *tempb)
{
CSprite *tempg;
CDC *tempb1;
Bool temp_bitmap;
if (tempb->type!=DCT_COLOR8) {
tempb1=DCNew(DCT_COLOR8,tempb->width,tempb->height,Fs);
tempb1->color=WHITE;
GrBlot(tempb1,0,0,tempb);
temp_bitmap=TRUE;
} else {
tempb1=tempb;
temp_bitmap=FALSE;
}
tempg=CAlloc(gr_sprite_base_size[GRST_BITMAP8]+
tempb1->width_internal*tempb1->height+
gr_sprite_base_size[GRST_END])
(U8 *)-offset(CSprite.start);
tempg->type=GRST_BITMAP8;
tempg->width=tempb1->width;
tempg->height=tempb1->height;
tempg->x2=0;
tempg->y2=0;
MemCpy(tempg(U8 *)+offset(CSprite.linespeed),tempb1->body,
tempb1->width_internal*tempb1->height);
if (temp_bitmap)
DCDel(tempb1);
return tempg(U8 *)+offset(CSprite.start);
}
public U8 *Sprite2Text(CSprite *tempg)
{ //Study $LK-A,"::/TempleOS/Demo/Graphics/SpriteText.CPP"$.
U8 buf[256],buf2[256],buf3[136];
I32 *ptr;
SPrintF(buf,"%Z",tempg->type,"ST_CSPRITE_TYPES");
*buf2=0;
switch (tempg->type) {
case GRST_COLOR8:
SPrintF(buf2," %s",Color2Text(buf3,tempg->color8));
break;
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
SPrintF(buf2," %d,%d",tempg->x1,tempg->y1);
break;
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
case GRST_RECT:
case GRST_ROTATED_RECT:
SPrintF(buf2," (%d,%d)-(%d,%d)",
tempg->x1,tempg->y1,tempg->x2,tempg->y2);
break;
case GRST_CIRCLE:
SPrintF(buf2," %d,%d:%dR",
tempg->x1,tempg->y1,tempg->x2);
break;
case GRST_WIDTH:
SPrintF(buf2," %d",tempg->width);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
SPrintF(buf2," %d,%d:%-16tQ",tempg->x1,tempg->y1,tempg->st);
break;
case GRST_DITHER_COLOR8:
SPrintF(buf2," %s",Color2Text(buf3,ROPF_DITHER|tempg->dither_color8.u8[0]|tempg->dither_color8.u8[1]<<COLORROP_BITS));
break;
case GRST_POLYLINE:
case GRST_POLYPT:
ptr=&tempg->y1;
SPrintF(buf2," %d %d,%d",tempg->num,ptr[0],ptr[1]);
break;
case GRST_ELLIPSE:
case GRST_REG_POLY:
case GRST_BITMAP8:
SPrintF(buf2," %dW,%dH:%d,%d",
tempg->width,tempg->height,tempg->x2,tempg->y2);
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
SPrintF(buf2," %d",tempg->num);
break;
case GRST_MESH:
SPrintF(buf2," %dV,%dT",tempg->vertex_cnt,tempg->triangle_cnt);
break;
case GRST_SHIFTABLE_MESH:
SPrintF(buf2," %dV,%dT",tempg->shiftable_vertex_cnt,tempg->shiftable_triangle_cnt);
break;
}
StrCat(buf,buf2);
return StrNew(buf);
}
File diff suppressed because it is too large. Load diff
+129
View File
@@ -0,0 +1,129 @@
#help_index "Graphics"
U0 GrInit()
{
DefineLstLoad("ST_CSPRITE_TYPES","End\0 \0Color 8Bit\0 \0Point\0"
"Line\0PolyLine\0PolyPoint\0Width\0Shift\0"
"BSpline2\0BSpline3\0BSpline2 Closed\0BSpline3 Closed\0"
" \0 \0 \0Rect\0Circle\0Flood Fill Not Color\0Flood Fill\0BitMap 8Bit\0"
" \0Text\0Ellipse\0Reg Polygon\0Planar Symmetry\0"
"Dither Color 8Bit\0Rotated Rect\0Mesh\0Shiftable Mesh\0"
"Transform On\0Transform Off\0Arrow\0Text Box\0Text Diamond\0");
}
GrInit;
#help_index "Graphics/CSprite"
#define GRST_END 0
//Unused
#define GRST_COLOR8 2
//Unused
#define GRST_PT 4
#define GRST_LINE 5
#define GRST_POLYLINE 6
#define GRST_POLYPT 7
#define GRST_WIDTH 8
#define GRST_SHIFT 9
#define GRST_BSPLINE2 10
#define GRST_BSPLINE3 11
#define GRST_BSPLINE2_CLOSED 12
#define GRST_BSPLINE3_CLOSED 13
//Unused
//Unused
//Unused
#define GRST_RECT 17
#define GRST_CIRCLE 18
#define GRST_FLOOD_FILL_NOT 19
#define GRST_FLOOD_FILL 20
#define GRST_BITMAP8 21
//Unused
#define GRST_TEXT 23
#define GRST_ELLIPSE 24
#define GRST_REG_POLY 25
#define GRST_PLANAR_SYMMETRY 26
#define GRST_DITHER_COLOR8 27
#define GRST_ROTATED_RECT 28
#define GRST_MESH 29
#define GRST_SHIFTABLE_MESH 30
#define GRST_TRANSFORM_ON 31
#define GRST_TRANSFORM_OFF 32
#define GRST_ARROW 33
#define GRST_TEXT_BOX 34
#define GRST_TEXT_DIAMOND 35
#define GRST_NUM_TYPES 36
class CMeshTri
{
I32 color; //Give one of 0-7 colors. Colors 8-15 are 0-7 with intensity bit set.
I32 nums[3]; //Vertex number
};
public class CSprite
{
//See $LK,"Graphics/CSprite","HI:Graphics/CSprite"$
//See $LK,"::/TempleOS/Adam/Gr/GrSpritePlot.CPP","FL:::/TempleOS/Adam/Gr/GrSpritePlot.CPP,1"$ for how CSprite are stored.
CSprite *next,*last;
U0 start;
U8 type;
union {
U8 color8;
U16 dither_color8;
I32 x1;
I32 num;
I32 width;
I32 vertex_cnt; //Mesh
}
union {
I32 y1;
I32 height;
I32 triangle_cnt; //Mesh
}
union {
I32 z1;
I32 x2;
U8 st[4];
}
union {
I32 y2;
I32 shiftable_vertex_cnt //Shiftable Mesh
}
union {
F64 linespeed;
F64 rot_angle;
I32 shiftable_triangle_cnt //Shiftable Mesh
}
I32 sides;
};
#help_index "Graphics"
extern CDC *DCNew(I64 type,I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE);
extern CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL);
extern U0 DCDel(CDC *dc);
extern U0 EdExistingGraphic(CDoc *doc,I64 x,I64 y,I64 *import_snap=NULL,F64 *import_ip_scaler=NULL);
extern CSprite *SpriteDoc2Que(CDoc *doc,CSprite *root,I64 *cur_num);
extern Bool GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
#include "GrCfg"
#include "GrAsm"
#include "MathGr"
#include "GrScreen"
#include "GrDC"
#include "GrBitMap"
#include "GrPrimatives"
#include "GrComposites"
#include "GrChar"
#define GE_CANCEL (-1)
#define GE_OKAY_DONE 0
#define GE_OKAY_CONT 1
#include "CSpriteNew"
#include "GrSpritePlot"
#include "CSpriteMesh"
#include "CSpriteBitMap"
#include "CSpriteVect"
#include "CSpriteEd"
#include "GrVectMap"
#help_index ""
+765
View File
@@ -0,0 +1,765 @@
#help_index "Graphics"
I64 *gr_1_to_8_bits,*gr_1_to_8_colors;
#help_index "Graphics/Char;Char/Graphics"
U32 *gr_text_base;
U16 *gr_win_z_buf;
asm {
USE64
// ************************************
_PLOT_SCREEN_U8::
ENTER 0
MOV RBX,U64 SF_ARG2[RBP]
MOV RAX,U64 SF_ARG3[RBP]
OR RBX,RBX
JS @@05
OR RAX,RAX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG1[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
LEAVE
RET1 24
@@05: XOR RAX,RAX
LEAVE
RET1 24
// ************************************
_PLOT_WIN_U8::
ENTER 0
MOV RCX,U64 SF_ARG1[RBP]
MOV RBX,U64 CTask.win_scroll_x[RCX]
SAR RBX,3
ADD RBX,U64 SF_ARG3[RBP]
MOV RAX,U64 CTask.win_scroll_y[RCX]
SAR RAX,3
ADD RAX,U64 SF_ARG4[RBP]
OR RBX,RBX
JS @@05
ADD RBX,U64 CTask.win_left[RCX]
CMP RBX,U64 CTask.win_right[RCX]
JG @@05
OR RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
OR RAX,RAX
JS @@05
ADD RAX,U64 CTask.win_top[RCX]
CMP RAX,U64 CTask.win_bottom[RCX]
JG @@05
OR RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
LEAVE
RET1 32
@@05: XOR RAX,RAX
LEAVE
RET1 32
// ************************************
/*
Bool PlotWinStr2(CTask *task,U8 *s,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_WIN_STR2::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG5[RBP]
MOV RCX,U64 SF_ARG3[RBP]
OR RDI,RDI
JNS @@05
ADD RCX,RDI
SUB RSI,RDI
XOR RDI,RDI
@@05: ADD RDI,U64 CTask.win_left[RBX]
MOV RDX,RCX
ADD RDX,RDI
DEC RDX
CMP RDX,U64 CTask.win_right[RBX]
JLE @@10
MOV RAX,RDX
SUB RAX,U64 CTask.win_right[RBX]
SUB RDX,RAX
SUB RCX,RAX
@@10: OR RDI,RDI
JNS @@15
ADD RCX,RDI
SUB RSI,RDI
XOR RDI,RDI
@@15: INC RDX
SUB RDX,TEXT_COLS
JLE @@20
SUB RCX,RDX
@@20: CMP RCX,1
JL @@30
MOV RAX,U64 CTask.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG6[RBP]
OR RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
OR RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
MOV RAX,U64 SF_ARG4[RBP]
@@25: LODSB
STOSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 48
@@30: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 48
// ************************************
/*
Bool PlotAttrStr2(CTask *task,U32 *hl,I64 len,I64 x,I64 y)
*/
_PLOT_ATTR_STR2::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG3[RBP]
OR RDI,RDI
JNS @@05
ADD RCX,RDI
SHL RDI,2
SUB RSI,RDI
XOR RDI,RDI
@@05: ADD RDI,U64 CTask.win_left[RBX]
MOV RDX,RCX
ADD RDX,RDI
DEC RDX
CMP RDX,U64 CTask.win_right[RBX]
JLE @@10
MOV RAX,RDX
SUB RAX,U64 CTask.win_right[RBX]
SUB RDX,RAX
SUB RCX,RAX
@@10: OR RDI,RDI
JNS @@15
ADD RCX,RDI
SHL RDI,2
SUB RSI,RDI
XOR RDI,RDI
@@15: INC RDX
SUB RDX,TEXT_COLS
JLE @@20
SUB RCX,RDX
@@20: CMP RCX,1
JL @@30
MOV RAX,U64 CTask.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG5[RBP]
OR RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
OR RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
@@25: MOVSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 40
@@30: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 40
// ************************************
/*
Bool PlotAttr(CTask *task,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_ATTR::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG2[RBP]
OR RDI,RDI
JNS @@05
ADD RCX,RDI
XOR RDI,RDI
@@05: ADD RDI,U64 CTask.win_left[RBX]
MOV RDX,RCX
ADD RDX,RDI
DEC RDX
CMP RDX,U64 CTask.win_right[RBX]
JLE @@10
MOV RAX,RDX
SUB RAX,U64 CTask.win_right[RBX]
SUB RDX,RAX
SUB RCX,RAX
@@10: OR RDI,RDI
JNS @@15
ADD RCX,RDI
XOR RDI,RDI
@@15: INC RDX
SUB RDX,TEXT_COLS
JLE @@20
SUB RCX,RDX
@@20: CMP RCX,1
JL @@35
MOV RAX,U64 CTask.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG5[RBP]
OR RAX,RAX
JS @@35
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@35
OR RAX,RAX
JS @@35
CMP RAX,TEXT_ROWS
JGE @@35
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
MOV RBX,U64 SF_ARG3[RBP]
MOV RSI,RDI
@@25: LODSD
OR AL,AL
JNZ @@30
MOV RAX,RBX
STOSD
DEC RCX
JNZ @@25
@@30: POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 40
@@35: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 40
// ************************************
_PLOT_BORDER_U8::
ENTER 0
MOV R9,U64 [&gr_text_base]
MOV RCX,U64 SF_ARG1[RBP]
MOV RBX,U64 CTask.win_scroll_x[RCX]
SAR RBX,3
ADD RBX,U64 SF_ARG3[RBP]
MOV RAX,U64 CTask.win_scroll_y[RCX]
SAR RAX,3
ADD RAX,U64 SF_ARG4[RBP]
MOV RDX,-1
CMP RBX,RDX
JL @@05
ADD RBX,U64 CTask.win_left[RCX]
MOV RDX,U64 CTask.win_right[RCX]
INC RDX
CMP RBX,RDX
JG @@05
OR RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
MOV RDX,-1
CMP RAX,RDX
JL @@05
ADD RAX,U64 CTask.win_top[RCX]
MOV RDX,U64 CTask.win_bottom[RCX]
INC RDX
CMP RAX,RDX
JG @@05
OR RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,R9
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,TRUE
LEAVE
RET1 32
@@05: XOR RAX,RAX
LEAVE
RET1 32
// ************************************
_GR_UPDATE_LINE32::
ENTER 0
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
CMP U32 [RDI],EAX
JE @@10
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
@@10: ADD RDI,4
ADD R8,4
DEC RCX
JNZ @@05
MOV RAX,U64 SF_ARG1[RBP]
MOV U64 [RAX],R8
MOV RAX,U64 SF_ARG4[RBP]
MOV U64 [RAX],RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV U64 [RAX],RSI
POP RDI
POP RSI
LEAVE
RET1 32
// ************************************
_GR_UPDATE_LINE32_FLUSH_CACHE::
ENTER 0
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
ADD RDI,4
ADD R8,4
DEC RCX
JNZ @@05
MOV RAX,U64 SF_ARG1[RBP]
MOV U64 [RAX],R8
MOV RAX,U64 SF_ARG4[RBP]
MOV U64 [RAX],RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV U64 [RAX],RSI
POP RDI
POP RSI
LEAVE
RET1 32
// ************************************
_DC_BLOT_COLOR4::
ENTER 0
PUSH RSI
PUSH RDI
PUSH R10
MOV RDI,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RBX,U64 SF_ARG3[RBP]
MOV RCX,U64 SF_ARG4[RBP]
MOV R8,RDI
ADD R8,RCX
MOV R9,R8
ADD R9,RCX
MOV R10,R9
ADD R10,RCX
@@5: LODSQ
MOV RDX,U64 [RBX]
CMP RAX,RDX
JE I32 @@10
MOV U64 [RBX],RAX
XOR RDX,RDX
BT RAX,7*8+0
ADC RDX,0
SHL1 RDX
BT RAX,6*8+0
ADC RDX,0
SHL1 RDX
BT RAX,5*8+0
ADC RDX,0
SHL1 RDX
BT RAX,4*8+0
ADC RDX,0
SHL1 RDX
BT RAX,3*8+0
ADC RDX,0
SHL1 RDX
BT RAX,2*8+0
ADC RDX,0
SHL1 RDX
BT RAX,1*8+0
ADC RDX,0
SHL1 RDX
BT RAX,0*8+0
ADC RDX,0
MOV U8 [RDI],DL
XOR RDX,RDX
BT RAX,7*8+1
ADC RDX,0
SHL1 RDX
BT RAX,6*8+1
ADC RDX,0
SHL1 RDX
BT RAX,5*8+1
ADC RDX,0
SHL1 RDX
BT RAX,4*8+1
ADC RDX,0
SHL1 RDX
BT RAX,3*8+1
ADC RDX,0
SHL1 RDX
BT RAX,2*8+1
ADC RDX,0
SHL1 RDX
BT RAX,1*8+1
ADC RDX,0
SHL1 RDX
BT RAX,0*8+1
ADC RDX,0
MOV U8 [R8],DL
XOR RDX,RDX
BT RAX,7*8+2
ADC RDX,0
SHL1 RDX
BT RAX,6*8+2
ADC RDX,0
SHL1 RDX
BT RAX,5*8+2
ADC RDX,0
SHL1 RDX
BT RAX,4*8+2
ADC RDX,0
SHL1 RDX
BT RAX,3*8+2
ADC RDX,0
SHL1 RDX
BT RAX,2*8+2
ADC RDX,0
SHL1 RDX
BT RAX,1*8+2
ADC RDX,0
SHL1 RDX
BT RAX,0*8+2
ADC RDX,0
MOV U8 [R9],DL
XOR RDX,RDX
BT RAX,7*8+3
ADC RDX,0
SHL1 RDX
BT RAX,6*8+3
ADC RDX,0
SHL1 RDX
BT RAX,5*8+3
ADC RDX,0
SHL1 RDX
BT RAX,4*8+3
ADC RDX,0
SHL1 RDX
BT RAX,3*8+3
ADC RDX,0
SHL1 RDX
BT RAX,2*8+3
ADC RDX,0
SHL1 RDX
BT RAX,1*8+3
ADC RDX,0
SHL1 RDX
BT RAX,0*8+3
ADC RDX,0
MOV U8 [R10],DL
@@10: ADD RBX,8
INC RDI
INC R8
INC R9
INC R10
DEC RCX
JNZ I32 @@5
POP R10
POP RSI
POP RDI
LEAVE
RET1 32
// ************************************
_IS_PIXEL_COVERED0::
ENTER 0
#assert FONT_WIDTH==FONT_HEIGHT==8
MOV RCX,U64 SF_ARG3[RBP]
SAR RCX,3
MOV RAX,U64 SF_ARG2[RBP]
SAR RAX,3
MOV RDX,U64 SF_ARG1[RBP]
IMUL2 RCX,TEXT_COLS
MOV RBX,U64 [&gr_win_z_buf]
MOV DX,U16 CTask.win_z_num[RDX]
ADD RCX,RAX
XOR RAX,RAX
CMP DX,U16 [RBX+RCX*2]
JAE @@05 //Jump not covered
INC RAX
@@05: LEAVE
RET1 24
// ************************************
_GR_ROP_EQU_U8_NO_CLIPPING::
//Puts foreground char shape onto gr_dc.
//ch.u8[1] is color as a whole byte
//ch DOCEt_UNDERLINE attr flag is used.
ENTER 0
MOVZX RAX,U8 SF_ARG1[RBP]
MOV RDX,U64 [&gr_font]
MOV RAX,U64 [RDX+RAX*8] //RAX is 8x8 char font data, 64-bits
BT U64 SF_ARG1[RBP],DOCEt_UNDERLINE
JNC @@05
MOV RBX,0xFF00000000000000
OR RAX,RBX
@@05: OR RAX,RAX
JZ I32 @@10
PUSH RSI
PUSH RDI
MOVZX RBX,U8 SF_ARG1+1[RBP] //Warning color is 8-bit
MOV RDX,U64 [&gr_1_to_8_colors]
MOV R8,U64 [RDX+RBX*8] //R8 is color repeated 8 times.
MOV R9,U64 SF_ARG3[RBP] //R9 is width_internal
MOV RDI,U64 SF_ARG2[RBP]
MOV RSI,U64 [&gr_1_to_8_bits] //RSI is gr_1_to_8_bits
// m=my_1_to_8_bits[ch&255];ch>>=8;
// *dst=*dst&~m|c&m;
// dst(U8 *)+=w1;
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOV RDX,U64 [RSI+RAX*8]
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
POP RDI
POP RSI
@@10: LEAVE
RET1 24
}
#help_index "Graphics/Char;Char/Graphics"
public _extern _PLOT_SCREEN_U8 Bool PlotScreenU8(I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_U8 Bool PlotWinU8(CTask *task,I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_STR2 Bool PlotWinStr2(
CTask *task,U8 *s,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_ATTR_STR2 Bool PlotAttrStr2(
CTask *task,U32 *hl,I64 len,I64 x,I64 y);
public _extern _PLOT_ATTR Bool PlotWinAttr(
CTask *task,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_BORDER_U8 Bool PlotBorderU8(CTask *task,I64 w,I64 x,I64 y);
_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,U8 *dst,I64 width_internal);
#help_index "Graphics"
//No clipping
public _extern _IS_PIXEL_COVERED0 Bool IsPixelCovered0(CTask *task,I64 x,I64 y);
_extern _GR_UPDATE_LINE32 U0 GrUpdateLine32(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _GR_UPDATE_LINE32_FLUSH_CACHE U0 GrUpdateLine32FlushCache(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
#help_index ""
File diff suppressed because it is too large. Load diff
+10
View File
@@ -0,0 +1,10 @@
//See $LK,"SYS_BIOS_GR_MODE","FF:D:/TempleOS/Kernel/KStart.CPP,SYS_BIOS_GR_MODE:2"$
//See $LK,"SysGrInit","MN:SysGrInit"$()
//This allows constants to be used
//instead of vars.
DefinePrintF("BIOS_GR_MODE","%d",bios_gr_mode);
DefinePrintF("GR_WIDTH","%d",gr_width);
DefinePrintF("GR_HEIGHT","%d",gr_height);
DefinePrintF("TEXT_ROWS","%d",text_rows);
DefinePrintF("TEXT_COLS","%d",text_cols);
+106
View File
@@ -0,0 +1,106 @@
#help_index "Graphics/Char;Char/Graphics"
public U0 PlotScreenStr(U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotScreenU8(ch+attr,x,y);
x++;
}
}
public U0 PlotWinStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotWinU8(task,ch+attr,x,y);
x++;
}
}
public U0 PlotBorderStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotBorderU8(task,ch+attr,x,y);
x++;
}
}
public U0 DrawBorder(CTask *task,Bool solid,I64 l,I64 r,I64 t,I64 b,I64 attr,Bool clip_to_win)
{
I64 i;
attr<<=8;
if (clip_to_win) {
if (solid) {
PlotWinU8(task,'É'+attr,l-1,t-1);
PlotWinU8(task,'»'+attr,r+1,t-1);
PlotWinU8(task,'È'+attr,l-1,b+1);
PlotWinU8(task,'¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Í'+attr,i,t-1);
PlotWinU8(task,'Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'º'+attr,l-1,i);
PlotWinU8(task,'º'+attr,r+1,i);
}
} else {
PlotWinU8(task,'Ú'+attr,l-1,t-1);
PlotWinU8(task,'¿'+attr,r+1,t-1);
PlotWinU8(task,'À'+attr,l-1,b+1);
PlotWinU8(task,'Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Ä'+attr,i,t-1);
PlotWinU8(task,'Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'³'+attr,l-1,i);
PlotWinU8(task,'³'+attr,r+1,i);
}
}
} else {
if (solid) {
PlotScreenU8('É'+attr,l-1,t-1);
PlotScreenU8('»'+attr,r+1,t-1);
PlotScreenU8('È'+attr,l-1,b+1);
PlotScreenU8('¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Í'+attr,i,t-1);
PlotScreenU8('Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('º'+attr,l-1,i);
PlotScreenU8('º'+attr,r+1,i);
}
} else {
PlotScreenU8('Ú'+attr,l-1,t-1);
PlotScreenU8('¿'+attr,r+1,t-1);
PlotScreenU8('À'+attr,l-1,b+1);
PlotScreenU8('Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Ä'+attr,i,t-1);
PlotScreenU8('Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('³'+attr,l-1,i);
PlotScreenU8('³'+attr,r+1,i);
}
}
}
}
U0 DrawTaskBorder(CTask *task)
{
PushFD;
Cli;
DrawBorder(task,task==sys_focus_task,
task->win_left,task->win_right,
task->win_top,task->win_bottom,
task->border_attr,FALSE);
PopFD;
}
#help_index "Graphics"
+180
View File
@@ -0,0 +1,180 @@
#help_index "Graphics"
public U0 GrLineRect4(CDC *dc,I64 x1,I64 y1,I64 x2,I64 y2,I64 step=1,I64 start=0)
{
//Can be used with ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK
//for dotted rect.
GrLine3(dc,x1,y1,0,x2,y1,0,step,start);
GrLine3(dc,x2,y1,0,x2,y2,0,step,start);
GrLine3(dc,x2,y2,0,x1,y2,0,step,start);
GrLine3(dc,x1,y2,0,x1,y1,0,step,start);
}
public U0 GrArrow3(CDC *dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
{ //transformation with pen width
I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
F64 d;
Bool was_transform=FALSE,was_symmetry=FALSE;
if (dc->flags & DCF_TRANSFORMATION) {
(*dc->transform)(dc,&x1,&y1,&z1);
(*dc->transform)(dc,&x2,&y2,&z2);
dc->flags&=~DCF_TRANSFORMATION;
was_transform=TRUE;
}
if (dc->flags & DCF_SYMMETRY) {
_x1=x1; _y1=y1; _z1=z1;
GrReflect(dc,&_x1,&_y1,&_z1);
_x2=x2; _y2=y2; _z2=z2;
GrReflect(dc,&_x2,&_y2,&_z2);
dc->flags&=~DCF_SYMMETRY;
Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
dx=_x2-_x1; dy=_y2-_y1;
if (d=Sqrt(dx*dx+dy*dy)) {
d=w*dc->pen_width/d;
Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,_x2,_y2,_z2,&GrPlot3,step);
Line(dc,_x2-dx*d-dy*d+0.5,_y2-dy*d+dx*d+0.5,_z2,_x2,_y2,_z2,&GrPlot3,step);
}
was_symmetry=TRUE;
if (dc->flags&DCF_JUST_MIRROR)
goto gr_done;
}
Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
dx=x2-x1; dy=y2-y1;
if (d=Sqrt(dx*dx+dy*dy)) {
d=w*dc->pen_width/d;
Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,x2,y2,z2,&GrPlot3,step);
Line(dc,x2-dx*d-dy*d+0.5,y2-dy*d+dx*d+0.5,z2,x2,y2,z2,&GrPlot3,step);
}
gr_done:
if (was_transform)
dc->flags|=DCF_TRANSFORMATION;
if (was_symmetry)
dc->flags|=DCF_SYMMETRY;
}
#help_index "Graphics/Char;Char/Graphics"
public Bool GrTextBox3(CDC *dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
Bool result;
U8 ch,*ptr=s;
I64 w=0,w_max=0,h=FONT_HEIGHT;
if (!s) return FALSE;
if (dc->flags & DCF_TRANSFORMATION)
(*dc->transform)(dc,&x1,&y1,&z1);
while (ch=*ptr++) {
if (ch=='\t')
w=CeilU64(w+FONT_WIDTH,FONT_WIDTH*8);
else if (ch=='\n') {
if (w>w_max) w_max=w;
w=0;
h+=FONT_HEIGHT;
} else
w+=FONT_WIDTH;
}
if (w>w_max) w_max=w;
result=GrPutS(dc,x1,y1,s);
GrLine(dc,x1-border ,y1-border ,x1+w_max+border,y1-border);
GrLine(dc,x1-border ,y1+h+border,x1+w_max+border,y1+h+border);
GrLine(dc,x1-border ,y1-border ,x1-border,y1+h+border);
GrLine(dc,x1+w_max+border,y1-border ,x1+w_max+border,y1+h+border);
return result;
}
#define MAX_DIAMOND_SLOPE 2.75
public Bool GrTextDiamond3(CDC *dc,I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
Bool result=FALSE,first=TRUE;
U8 ch,*ptr,*ptr_end,*st,*s;
I64 y,dx,dy,dx_old,dy_old,w,h=FONT_HEIGHT;
F64 m;
if (!_s) return FALSE;
if (dc->flags & DCF_TRANSFORMATION)
(*dc->transform)(dc,&x1,&y1,&z1);
ptr=s=StrNew(_s);
while (ch=*ptr) {
if (ch==CH_CARRIAGE_RETURN||ch=='\t')
*ptr=CH_SPACE;
if (ch=='\n') {
*ptr=0;
h+=FONT_HEIGHT;
}
ptr++;
}
ptr_end=ptr+1;
y=y1-h>>1;
dx=FONT_WIDTH +border; //Minimum
dy=FONT_HEIGHT+border+h>>1; //Minimum
ptr=s;
while (ptr!=ptr_end) {
st=ptr;
while (*ptr++);
StrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
w=(StrLen(st)*FONT_WIDTH)>>1;
if (first) {
result=GrPutS(dc,x1-w,y,st);
first=FALSE;
} else
GrPutS(dc,x1-w,y,st);
if (w) {
w+=border;
do {
dx_old=dx; dy_old=dy;
m=ToF64(dx)/dy;
if (m<1/MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(MAX_DIAMOND_SLOPE*dx));
m=1/MAX_DIAMOND_SLOPE;
} else if (m>MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(dx/MAX_DIAMOND_SLOPE));
m=MAX_DIAMOND_SLOPE;
}
dx=MaxI64(dx,w+Ceil(m*AbsI64(y-y1)));
dx=MaxI64(dx,w+Ceil(m*AbsI64(y+FONT_HEIGHT-y1)));
} while (dx!=dx_old || dy!=dy_old);
}
y+=FONT_HEIGHT;
}
Free(s);
GrLine(dc,x1,y1-dy,x1+dx,y1);
GrLine(dc,x1+dx,y1,x1,y1+dy);
GrLine(dc,x1,y1+dy,x1-dx,y1);
GrLine(dc,x1-dx,y1,x1,y1-dy);
return result;
}
#help_index "Graphics;Input Pointer/Displayed Image"
//Called by $LK,"DrawInputPtr","MN:DrawInputPtr"$() which is
//called by $LK,"WinFinalUpdate","MN:WinFinalUpdate"$().
public U0 DrawStdInputPtr(CDC *dc,I64 x,I64 y)
{
dc->pen_width=1;
dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
GrArrow3(dc,x+8,y+8,0,x,y,0);
}
public U0 (*fp_draw_input_ptr)(CDC *dc,I64 x,I64 y)=&DrawStdInputPtr;
public U0 (*fp_draw_grab_input_ptr)(CDC *dc,I64 x,I64 y,Bool closed)=NULL;
public U8 *gr_empty_sprite=NULL; //Gets assigned $LK,"gr_empty_sprite","FI:::/TempleOS/Adam/WallPaper.CPP"$
public U0 DrawWaitInputPtr(CDC *dc,I64 x,I64 y)
{
I64 old_pen_width=dc->pen_width;
CColorROPU32 old_color=dc->color;
dc->pen_width=3;
dc->color=LTRED;
GrCircle3(dc,x,y,0,7);
GrLine3(dc,x-6,y+6,0,x+6,y-6,0);
dc->color=RED;
GrCircle(dc,x,y,7);
GrLine(dc,x-6,y+6,x+6,y-6);
dc->pen_width=old_pen_width;
dc->color=old_color;
}
#help_index "Graphics"
+304
View File
@@ -0,0 +1,304 @@
#help_index "Graphics/DCs"
public U0 DCRst(CDC *dc)
{
dc->color=BLACK;
dc->color2=BLACK;
dc->bkcolor=BLACK;
dc->collision_cnt=0;
dc->pen_width=1;
dc->ls.x=37837; //1<<16/Sqrt(3)
dc->ls.y=37837;
dc->ls.z=37837;
dc->x=0;
dc->y=0;
dc->z=0;
dc->transform=&GrTransform;
dc->lighting =&GrLighting;
GrIdentEqu(dc->r);
dc->r_norm=gr_scale;
dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
}
public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
{
CDC *result;
if (!dc) dc=gr_dc2;
if (!task) task=Fs;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAlloc(sizeof(CDC),task);
MemCpy(result,dc,sizeof(CDC));
result->win_task=task;
result->mem_task=task;
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->flags|=DCF_ALIAS;
result->alias=dc;
return result;
}
public CDC *DCNew(I64 type,I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
{ //This internally only allows widths which are divisible by 8
//Don't forget these $MA+A-X+PU,"sizeof(CDC)","Grep(\"sizeof(CDC)\",\"/TempleOS/\"FILENAME_MASK_TXT);View;"$.
CDC *result;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
result->type=type;
result->width=width;
result->width_internal=(width+7)&~7;
result->height=height;
switch (type) {
case DCT_COLOR4:
result->plane_size=(result->width_internal*result->height)>>3;
if (!null_bitmap)
result->body=CAlloc(result->plane_size<<2,task);
break;
case DCT_COLOR8:
result->plane_size=result->width_internal*result->height;
if (!null_bitmap)
result->body=CAlloc(result->plane_size,task);
break;
default:
throw(EXCEPT_GRAPHICS,1);
}
if (null_bitmap)
result->flags|=DCF_DONT_DRAW;
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->dc_signature=DCS_SIGNATURE_VAL;
return result;
}
public U0 DCDel(CDC *dc)
{
if (!dc) return;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
dc->dc_signature=0;
Free(dc->r);
if (!(dc->flags & DCF_ALIAS))
Free(dc->body);
Free(dc->depth_buf);
Free(dc);
}
public I64 DCSize(CDC *dc)
{
if (dc)
return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
else
return 0;
}
public U0 DCDepthBufRst(CDC *dc)
{
if (dc->depth_buf)
MemSetU32(dc->depth_buf,MAX_I32,dc->width_internal*dc->height);
}
public U0 DCAllocDepthBuf(CDC *dc)
{
Free(dc->depth_buf);
dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
DCDepthBufRst(dc);
}
public CDC *DCCopy(CDC *dc,CTask *task=NULL)
{
CDC *result;
if (!dc) return NULL;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAllocIdentical(dc,task);
GrSetRotMat(result,MAllocIdentical(dc->r,task));
result->mem_task=task;
result->body=MAllocIdentical(dc->body,task);
return result;
}
public U0 DCMono(CDC *dc,
I64 quest=COLOR_TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
{
I64 i;
U8 *dst;
if (dc->type==DCT_COLOR8) {
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==quest)
*dst++=true_color;
else
*dst++=false_color;
}
}
public U0 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=COLOR_TRANSPARENT)
{
I64 i;
U8 *dst;
if (dc->type==DCT_COLOR8) {
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==src_color)
*dst++=dst_color;
else
dst++;
}
}
public U8 *DCSave(CDC *dc,I64 *_size=NULL,Bool compressed=TRUE)
{ //stores to mem
U8 *result,*ptr,*body;
Bool old_preempt;
CArcCompress *ac;
I64 i,j,old_flags=dc->flags;
if (dc->type==DCT_COLOR8)
i=dc->plane_size;
else
throw(EXCEPT_GRAPHICS,2);
if (compressed) {
ac=CompressBuf(dc->body,i);
j=ac->compressed_size;
body=ac;
} else {
ac=NULL;
j=i;
body=dc->body;
}
ptr=result=MAlloc(offset(CDC.end_saved_area)-
offset(CDC.start_saved_area)+j);
old_preempt=Preempt(OFF); //in case it is a screen bitmap
if (compressed) dc->flags|=DCF_COMPRESSED;
dc->flags&=DCF_COMPRESSED;
MemCpy(result,&dc->start_saved_area,
offset(CDC.end_saved_area)-
offset(CDC.start_saved_area));
dc->flags=old_flags;
Preempt(old_preempt);
ptr+=offset(CDC.end_saved_area)-
offset(CDC.start_saved_area);
MemCpy(ptr,body,j);
ptr+=j;
Free(ac);
if (_size) *_size=ptr-result;
return result;
}
public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
{ //loads from mem
CDC *result;
I64 i;
U8 *ptr=src;
CArcCompress *ac;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
MemCpy(&result->start_saved_area,src,
offset(CDC.end_saved_area)-
offset(CDC.start_saved_area));
ptr+=offset(CDC.end_saved_area)-
offset(CDC.start_saved_area);
if (result->type==DCT_COLOR8)
i=result->plane_size;
else
throw(EXCEPT_GRAPHICS,3);
if (result->flags&DCF_COMPRESSED) {
result->flags&=~DCF_COMPRESSED;
ac=ptr;
result->body=ExpandBuf(ac,task);
ptr+=ac->compressed_size;
} else {
result->body=MAlloc(i,task);
MemCpy(result->body,ptr,i);
}
result->pen_width=1;
result->r=GrIdent(task);
result->r_norm.u32[1]=1;
result->dc_signature=DCS_SIGNATURE_VAL;
if (_size) *_size=ptr-src;
return result;
}
public I64 GRAWrite(U8 *filename,CDC *dc)
{ // TempleOS GRA File
I64 size;
U8 *st=DftExt(filename,"GRA.Z"),
*src=DCSave(dc,&size);
FileWrite(st,src,size);
Free(st);
Free(src);
return size;
}
public CDC *GRARead(U8 *filename,CTask *task=NULL)
{ // TempleOS GRA File
CDC *dc=NULL;
U8 *st=DftExt(filename,"GRA.Z"),
*src=FileRead(st);
if (src)
dc=DCLoad(src,NULL,task);
Free(src);
Free(st);
return dc;
}
#help_index "Graphics/CSprite;Graphics/DCs;Doc/Output"
public U0 DocPutGRAFile(CDoc *doc=NULL,U8 *fname)
{
CDC *dc=GRARead(fname);
CSprite *elems=DC2Sprite(dc);
DocPutSprite(doc,elems);
Free(elems);
DCDel(dc);
}
#help_index "Graphics/DCs;Graphics/Screen"
public CDC *DCCaptureScreen(CTask *task=NULL)
{
CDC *dc;
U8 *dst;
WinMgrSync(2,TRUE);
dc=DCCopy(gr_screen_image,task);
if (dc->type==DCT_COLOR4) {
dc->type=DCT_COLOR8;
dc->plane_size*=8;
dst=MAlloc(dc->plane_size,task);
GrBitMap4ToBitMap8(dst,dc->body,dc->plane_size/2,COLOR_INVALID);
Free(dc->body);
dc->body=dst;
}
return dc;
}
public I64 GRACaptureScreen(U8 *filename)
{ // TempleOS GRA File
I64 size;
CDC *dc=DCCaptureScreen;
size=GRAWrite(filename,dc);
DCDel(dc);
return size;
}
#help_index "Graphics;Graphics/DCs"
public U0 DCExtentsInit(CDC *dc)
{//See $LK-A,"::/TempleOS/Demo/Graphics/Extents.CPP"$
//You should clear the record flag yourself
dc->flags|=DCF_RECORD_EXTENTS;
dc->min_x=MAX_I64;
dc->max_x=MIN_I64;
dc->min_y=MAX_I64;
dc->max_y=MIN_I64;
}
File diff suppressed because it is too large. Load diff
+785
View File
@@ -0,0 +1,785 @@
#help_index "Graphics/DCs;Graphics/Screen"
public CDC *gr_screen_image; //This is read only
#help_index "Graphics/DCs"
public CDC *gr_dc=NULL, //This is updated every refresh
*gr_dc_cache,
*gr_dc1=NULL,
*gr_dc2=NULL;
CDC *gr_zoomed_dc;
U16 *gr_win_uncovered_bitmap=NULL,gr_highest_uncovered;
U16 *gr_vga_text_cache;
public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=COLOR_TRANSPARENT)
{
if (!dc) dc=gr_dc2;
nobound_switch (dc->type) {
case DCT_COLOR4:
MemSet(dc->body,val,(dc->width_internal*dc->height)>>1);
break;
case DCT_COLOR8:
MemSet(dc->body,val,dc->width_internal*dc->height);
break;
}
}
public U0 DCClear(CDC *dc=NULL)
{
if (!dc) dc=gr_dc2;
DCFill(dc,0);
}
#help_index "Graphics/Screen"
public U0 (*fp_final_screen_update)(CDC *dc)=NULL;
public U0 (*fp_wall_paper)(CTask *task)=NULL;
#help_index "Graphics/Screen;Windows"
U0 WinZBufFill(CTask *task)
{ //Not public
I64 y,t,dc,l,r,w;
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
t= task->win_top-1>0
? task->win_top-1 : 0,
dc= task->win_bottom+1<TEXT_ROWS
? task->win_bottom+1 : TEXT_ROWS-1,
l= task->win_left-1>0
? task->win_left-1 : 0,
r= task->win_right+1<TEXT_COLS
? task->win_right+1 : TEXT_COLS-1;
} else {
t= task->win_top>0
? task->win_top : 0,
dc= task->win_bottom<TEXT_ROWS
? task->win_bottom : TEXT_ROWS-1,
l= task->win_left>0
? task->win_left : 0,
r= task->win_right<TEXT_COLS
? task->win_right : TEXT_COLS-1;
}
t=LimitI64(t,0,TEXT_ROWS-1);
dc=LimitI64(dc,t,TEXT_ROWS-1);
l=LimitI64(l,0,TEXT_COLS-1);
r=LimitI64(r,l,TEXT_COLS-1);
if (w=r-l+1)
for (y=t;y<=dc;y++)
MemSetU16(gr_win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
task->win_z_num,w);
}
public U0 WinZBufUpdate()
{ //You might have to call this if you are doing graphics outside
//the window mgr callback routines. Call it if, for example,
//a pop-up window closes and you need to refresh before graphics.
I64 i,z=1;
U16 *ptr;
CTask *task,*task1;
Bool old_preempt=Preempt(OFF);
if (gr_win_z_buf) {
LBtr(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0);
task1=task=sys_winmgr_task;
do {
if (!TaskValidate(task)) break;
if (Bt(&task->display_flags,DISPLAYf_SHOW)) {
task->win_z_num=z++;
WinZBufFill(task);
}
task=task->next_task;
} while (task!=task1 && z<0x10000);
MemSet(gr_win_uncovered_bitmap,0,(gr_highest_uncovered+7)>>3+1);
gr_highest_uncovered=z-1;
for (ptr=gr_win_z_buf,i=TEXT_ROWS*TEXT_COLS;i;i--)
Bts(gr_win_uncovered_bitmap,*ptr++);
}
Preempt(old_preempt);
}
#help_index "Graphics/Char;Char"
public U0 WinTextFill(I64 d,CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
I64 y,w,
t= task->win_top>0
? task->win_top : 0,
dc= task->win_bottom<TEXT_ROWS
? task->win_bottom : TEXT_ROWS-1,
l= task->win_left>0
? task->win_left : 0,
r= task->win_right<TEXT_COLS
? task->win_right : TEXT_COLS-1;
if (w=r-l+1)
for (y=t;y<=dc;y++)
MemSetU32(gr_text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),
d,w);
}
public U0 WinTextClear(CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
WinTextFill(task->text_attr<<8,task);
}
public U0 SetWinBkColor(I64 c,CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
task->text_attr=task->text_attr&0x0F | c<<4;
WinTextFill(c<<12,task);
}
#help_index "Graphics/Color"
public I32 gr_rainbow_10[10]=
{
BLACK,BROWN,RED,LTRED,YELLOW,
GREEN,BLUE,PURPLE,LTGRAY,WHITE
};
DefineLstLoad("ST_RAINBOW_10",
"BLACK\0BROWN\0RED\0LTRED\0YELLOW\0"
"GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
U0 SetVGAPalette4Indices()
{//4-bit (16 color)
/*There is a level of indirection we wish to identity map.
This sets the 16-colors to use
the first 16 DAC rgb entries, so
we never need to worry about indexes,
just DAC palette settings.
*/
I64 i;
if (text_mode) return;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
InU8(VGA_INPUT_STAT); //Rsts attr index/data
for (i=0;i<16;i++) {
OutU8(VGA_ATTR_INDEX,i);
OutU8(VGA_ATTR_DATA_WRITE,i);
}
OutU8(VGA_ATTR_INDEX,0x20);
OutU8(VGA_ATTR_DATA_WRITE,0); //Dummy write
InU8(VGA_INPUT_STAT); //Rsts attr index/data
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
}
public U0 SetVGAPaletteColor(I64 color_num,CBGR bgr)
{ //6-bits per r,dc and g
if (text_mode) return;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_WRITE,color_num);
OutU8(VGA_PALETTE_DATA,bgr.r>>2);
OutU8(VGA_PALETTE_DATA,bgr.g>>2);
OutU8(VGA_PALETTE_DATA,bgr.b>>2);
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
}
public CBGR GetVGAPaletteColor(I64 color_num)
{ //6-bits per r,dc and g
CBGR result=0;
if (text_mode) return 0;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_READ,color_num);
result.r=InU8(VGA_PALETTE_DATA)<<2;
result.g=InU8(VGA_PALETTE_DATA)<<2;
result.b=InU8(VGA_PALETTE_DATA)<<2;
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
return result;
}
public CBGR vga_palette4_std[16]={
0x000000,0x0000AA,0x00AA00,0x00AAAA,
0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,
0x555555,0x5555FF,0x55FF55,0x55FFFF,
0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF};
public CBGR vga_palette4_gray[16]={
0x000000,0x111111,0x222222,0x333333,
0x444444,0x555555,0x666666,0x777777,
0x888888,0x999999,0xAAAAAA,0xBBBBBB,
0xCCCCCC,0xDDDDDD,0xEEEEEE,0xFFFFFF};
public U0 GetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
bgr[i]=GetVGAPaletteColor(i);
}
public U0 SetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
SetVGAPaletteColor(i,bgr[i]);
}
public U0 SetStdPalette()
{
SetVGAPalette4(vga_palette4_std);
}
#help_index "Graphics/Screen"
#define GR_NUM_PEN_BRUSHES 64
CDC *gr_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_collision_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_even_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_odd_pen_brushes[GR_NUM_PEN_BRUSHES];
#define GR_MAX_SCREEN_ZOOM 8
U8 *gr_screen_zoom_tables[GR_MAX_SCREEN_ZOOM+1];
I64 gr_screen_zoom=1,grsx=0,grsy=0;
//When zoomed, this keeps the mouse centered.
public Bool gr_continuous_scroll=FALSE;
#define GR_REFRESH_LOG_CNT 16
F64 gr_refresh_time_stamps[GR_REFRESH_LOG_CNT];
I64 gr_refresh_ts_ptr=0;
U0 GrSetUpTables()
{
CDC *dc;
I64 i,j,k,l,m,x,y,rr;
U8 *dst;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
if (Bt(&i,j))
gr_1_to_8_bits(U8 *)[k++]=0xFF;
else
gr_1_to_8_bits(U8 *)[k++]=0x00;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
gr_1_to_8_colors(U8 *)[k++]=i;
for (i=0;i<GR_NUM_PEN_BRUSHES;i++) {
k=i+1;
dc=DCNew(DCT_COLOR8,i,i);
gr_pen_brushes[i]=dc;
dc->color=COLOR_MONO;
rr=k*k;
for (y=1;y<k;y++)
for (x=1;x<k;x++)
if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
GrPlot0(dc,x-1,y-1);
dc=DCNew(DCT_COLOR8,i,i);
gr_collision_pen_brushes[i]=dc;
dc->color=COLOR_INVALID;
rr=k*k;
for (y=1;y<k;y++)
for (x=1;x<k;x++)
if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
GrPlot0(dc,x-1,y-1);
dc=DCNew(DCT_COLOR8,i,i);
gr_even_pen_brushes[i]=dc;
dc->color=COLOR_MONO;
rr=k*k;
for (y=1;y<k;y++)
for (x=1;x<k;x++)
if (!(((x-1)^(y-1))&1) && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
GrPlot0(dc,x-1,y-1);
dc=DCNew(DCT_COLOR8,i,i);
gr_odd_pen_brushes[i]=dc;
dc->color=COLOR_MONO;
rr=k*k;
for (y=1;y<k;y++)
for (x=1;x<k;x++)
if (((x-1)^(y-1))&1 && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
GrPlot0(dc,x-1,y-1);
}
if (text_mode) {
MemSet(VGA_TEXT_MEM_BASE,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
MemSet(gr_vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
} else {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,0x0F);
//Virtual Box crashes on the following for some reason.
// MemSet(VGA_GRAPHIC_MEM_BASE,0,GR_HEIGHT*GR_WIDTH>>3);
MemSet(gr_screen_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
}
for (i=1;i<=GR_MAX_SCREEN_ZOOM;i++) {
dst=gr_screen_zoom_tables[i]=MAlloc(256*i);
for (j=0;j<256;j++) {
m=0;
for (k=0;k<8;k++) {
if (Bt(&j,k)) {
for (l=0;l<i;l++)
Bts(&m,l+k*i);
}
}
for (l=0;l<i;l++)
dst[j+l*256]=m.u8[l];
}
}
for (i=0;i<GR_REFRESH_LOG_CNT;i++)
gr_refresh_time_stamps[i]=tT;
}
U0 GrInit()
{
SetStdPalette;
fp_set_std_palette=&SetStdPalette;
SetVGAPalette4Indices;
gr_1_to_8_bits =MAlloc(256*sizeof(I64));
gr_1_to_8_colors=MAlloc(256*sizeof(I64));
gr_text_base=CAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U32));
gr_vga_text_cache=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
gr_win_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
gr_win_uncovered_bitmap=CAlloc(65536/8);
gr_highest_uncovered=0;
gr_dc=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc->flags|=DCF_SCREEN_BITMAP;
gr_dc_cache=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc2=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc2->flags|=DCF_SCREEN_BITMAP;
DCFill;
gr_dc1=DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_dc1->flags|=DCF_SCREEN_BITMAP;
gr_screen_image=DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_zoomed_dc =DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_zoomed_dc->flags|=DCF_SCREEN_BITMAP;
GrSetUpTables;
WinZBufUpdate;
}
U0 GrUpdateWins()
{ //Only called by WinMgr
I64 i;
CTask *task,*task1;
CD3I64 saved_scroll;
CDC *dc;
Bool old_preempt=Preempt(OFF);
try {
refresh_ode_time=0;
if (Bt(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0))
WinZBufUpdate;
task1=task=sys_winmgr_task;
do {
if (!TaskValidate(task))
break;
sys_task_being_screen_updated=task;
Preempt(old_preempt);
ODEsUpdate(task);
Preempt(OFF);
if (!TaskValidate(task))
break;
if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
Bt(gr_win_uncovered_bitmap,task->win_z_num)) {
try {
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
DrawTaskBorder(task);
WinTextClear(task);
Preempt(old_preempt);
if (task==sys_winmgr_task) {
if (fp_wall_paper)
(*fp_wall_paper)(task);
} else {
if (!(task->win_inhibit&WIF_DOC))
DocUpdateTaskDocs(task);
}
if (TaskValidate(task)) {
if (task->draw_it) {
dc=DCAlias(gr_dc,task);
(*task->draw_it)(task,dc);
DCDel(dc);
}
if (TaskValidate(task)) {
Preempt(OFF);
WinScrollNull(task,&saved_scroll);
DrawCtrls(task);
WinScrollRestore(task,&saved_scroll);
}
}
} catch {
if (task!=Fs && TaskValidate(task)) {
LBtr(&task->display_flags,DISPLAYf_SHOW);
"Exception in WinMgr: DrawIt\n";
PutExcept;
Sleep(3000);
VGAFlush;
Fs->catch_except=TRUE;
}
}
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
for (i=1;i<mp_cnt;i++) {
task1=task=cpu_structs[i].seth_task;
do {
if (!TaskValidate(task))
break;
try {
sys_task_being_screen_updated=task;
Preempt(old_preempt);
ODEsUpdate(task);
Preempt(OFF);
} catch {
LBts(&task->win_inhibit,WIf_ODE);
"Exception in WinMgr: ODE\n";
PutExcept;
Sleep(3000);
VGAFlush;
Fs->catch_except=TRUE;
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
}
} catch {
PutExcept;
Dbg("Exception in WinMgr");
}
last_refresh_ode_time=refresh_ode_time;
ode_allocated_factor=LowPass1(0.1,ode_allocated_factor,
Limit(Gs->idle_factor-0.1,0.2,0.8),1/win_actual_refresh);
sys_task_being_screen_updated=NULL;
gr_refresh_time_stamps[gr_refresh_ts_ptr++&(GR_REFRESH_LOG_CNT-1)]=tT;
win_actual_refresh=(GR_REFRESH_LOG_CNT-1)/
(gr_refresh_time_stamps[(gr_refresh_ts_ptr-1)&(GR_REFRESH_LOG_CNT-1)]-
gr_refresh_time_stamps[gr_refresh_ts_ptr&(GR_REFRESH_LOG_CNT-1)]);
Preempt(old_preempt);
}
U0 GrFixZoomScale()
{
gr_screen_zoom=LimitI64(gr_screen_zoom,1,GR_MAX_SCREEN_ZOOM);
if (gr_screen_zoom==1) {
grsx=0;
grsy=0;
} else {
grsx=LimitI64(grsx,0,GR_WIDTH-GR_WIDTH/gr_screen_zoom)&~7;
grsy=LimitI64(grsy,0,GR_HEIGHT-GR_HEIGHT/gr_screen_zoom);
}
}
public U0 GrScaleZoom(F64 scale)
{
Bool old_preempt=Preempt(OFF);
F64 s=gr_screen_zoom;
gr_screen_zoom=gr_screen_zoom*scale;
GrFixZoomScale;
s/=gr_screen_zoom;
ipx_scale*=s;
ipy_scale*=s;
ipz_scale*=s;
ipx_offset=ipx-(ipx-ipx_offset)*s;
ipy_offset=ipy-(ipy-ipy_offset)*s;
ipz_offset=ipz-(ipz-ipz_offset)*s;
grsx=ipx-gr_zoomed_dc->width >>1/gr_screen_zoom;
grsy=ipy-gr_zoomed_dc->height>>1/gr_screen_zoom;
GrFixZoomScale;
Preempt(old_preempt);
}
public U0 GrZoomIn()
{
GrScaleZoom(2.0);
}
public U0 GrZoomOut()
{
GrScaleZoom(0.5);
}
U0 CtrlAltZ(I64 sc)
{
if (sc&SCF_SHIFT)
GrZoomOut;
else
GrZoomIn;
}
SetCtrlAltLetCB('Z',&CtrlAltZ,"Sys/Zoom In or Out");
U0 GrZoomInScreen()
{
GrFixZoomScale;
I64 plane,row,col,k,l,
d2=gr_zoomed_dc->width>>3/gr_screen_zoom,
d4=gr_zoomed_dc->width_internal>>3,
d5=d4-d2*gr_screen_zoom,
d3=gr_zoomed_dc->height/gr_screen_zoom,
d6=(gr_zoomed_dc->height-d3)*gr_dc1->width_internal>>3,
d7=gr_zoomed_dc->height%gr_screen_zoom*d4;
U8 *src,*src2,*dst,*src3,*map=gr_screen_zoom_tables[gr_screen_zoom];
src=gr_dc1->body+grsx>>3+grsy*gr_dc1->width_internal>>3;
dst=gr_zoomed_dc->body;
for (plane=1;plane<0x10;plane<<=1) {
row=d3;
while (row--) {
k=gr_screen_zoom;
while (k--) {
src2=src;
col=d2;
while (col--) {
src3=&map[*src2++];
l=gr_screen_zoom;
while (l--) {
*dst++=*src3;
src3+=256;
}
}
l=d5;
while (l--)
*dst++=0;
}
src+=d4;
}
l=d7;
while (l--)
*dst++=0;
src+=d6;
}
}
U0 GrUpdateBackgroundOfText()
{
I64 reg RSI *dst=gr_dc->body,reg R13 c,row,col,,cur_ch,
reg R12 w1=gr_dc->width_internal,reg R10 w2=-7*w1+8,w3=7*w1,
reg *my_1_to_8_colors=gr_1_to_8_colors;
U32 reg *src=gr_text_base;
$HL,1$ Bool blink_flag=Blink;
nounusedwarn w2;
for (row=TEXT_ROWS;row--;) {
for (col=TEXT_COLS;col--;) {
cur_ch=*src++;
if (cur_ch & (DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
}
c=my_1_to_8_colors[cur_ch.u8[1]>>4];
asm {
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R12
MOV U64 [RSI],R13
ADD RSI,R10
}
}
dst(U8 *)+=w3;
}
}
//$AN,"ExtScreenCodes","ExtScreenCodes"$
// Bits 0-7 ASCII (Screen Code)
// Bits 8-11 Foreground color
// Bits 12-15 Background color
// Bits 16-20 Signed X pos shift val
// Bits 21-25 Signed Y pos shift val
// Bit 28 Blink
// Bit 29 Inverted (Swap foreground and background)
// Bit 30 Selected (XOR colors with FF)
// Bit 31 Underline
U0 GrUpdateForegroundOfText()
{
U32 *src=gr_text_base;
I64 i,j,cur_ch,reg *dst=gr_dc->body,
reg w1=gr_dc->width_internal,w2=7*w1,
row,col;
U8 *dst_start=gr_dc->body,*dst_end=dst_start+w1*gr_dc->height-7*w1-8;
Bool blink_flag=Blink;
for (row=TEXT_ROWS;row--;) {
for (col=TEXT_COLS;col--;) {
cur_ch=*src++;
if (cur_ch & (DOCET_UNDERLINE | DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
}
if (i=cur_ch.u16[1]&0x3FF) {
j=i&0x1F;
if (j&0x10) j|=~0x1F;
i>>=5;
if (i&0x10) i|=~0x1F;
i=w1*i+j;
if (dst_start<=dst(U8 *)+i<dst_end)
GrRopEquU8NoClipping(cur_ch&(DOCET_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
} else
GrRopEquU8NoClipping(cur_ch&(DOCET_UNDERLINE+0xFFF),dst,w1);
dst(U8 *)+=8;
}
dst(U8 *)+=w2;
}
}
U0 DCBlotColor8(CDC *dc,CDC *img)
{
U8 reg *src=img->body,*b0=dc->body;
I64 reg j,reg k,reg d0=img->width_internal*img->height;
for (k=0;k<d0;k++) {
j=*src++;
if (j!=COLOR_TRANSPARENT)
*b0++=j;
else
b0++;
}
}
U0 GrUpdateTextModeText()
{
U32 *src=gr_text_base;
I64 cur_ch,i,d0=TEXT_COLS*TEXT_ROWS;
U16 *dst=VGA_TEXT_MEM_BASE,*dst2=gr_vga_text_cache;
Bool blink_flag=Blink;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
cur_ch&=0x7FFF;
*dst++=*dst2++=cur_ch;
}
} else {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
cur_ch&=0x7FFF;
if (*dst2!=cur_ch)
*dst++=*dst2++=cur_ch;
else {
dst++;
dst2++;
}
}
}
}
U0 GrUpdateVGAGraphics()
{
I64 row,plane,d2=gr_zoomed_dc->width_internal>>5;
U32 *src,*dst,*dst2;
//Update Graphic Card
if (gr_screen_zoom==1)
src=gr_dc1->body;
else {
GrZoomInScreen;
src=gr_zoomed_dc->body;
}
dst2=gr_screen_image->body;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32FlushCache(&dst,&src,d2,&dst2);
}
} else {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32(&dst,&src,d2,&dst2);
}
}
}
U0 GrUpdateScreen()
{
CDC *dc;
Bool old_preempt=IsPreempt;
if (!IsSysDeterministic)
Preempt(ON);
if (text_mode)
GrUpdateWins;
else {
GrUpdateBackgroundOfText;
GrUpdateForegroundOfText;
GrUpdateWins;
DCBlotColor8(gr_dc,gr_dc2);
}
dc=DCAlias(gr_dc,Fs);
dc->flags|=DCF_ON_TOP;
if (fp_final_screen_update)
(*fp_final_screen_update)(dc);
DCDel(dc);
if (text_mode)
GrUpdateTextModeText;
else {
DCBlotColor4(gr_dc1->body,gr_dc->body,gr_dc_cache->body,
gr_dc->height*gr_dc->width_internal>>3);
GrUpdateVGAGraphics;
}
Preempt(old_preempt);
}
#help_index "Graphics"
+526
View File
@@ -0,0 +1,526 @@
#help_index "Graphics/CSprite"
/*
$LK,"CSprite","MN:CSprite"$s are stored as a sequence of var
length operations with a 1-byte type leading
each operation. The types available are lsted
here, $LK,"GRST_PT","MN:GRST_PT"$. They are stored, one after another,
in a chunk of memory terminated by a type $LK,"GRST_END","MN:GRST_END"$.
$LK,"SpritePlot3","MN:SpritePlot3"$() and $LK,"SpriteVect","MN:SpriteVect"$() shows how the
unions are used. It's kind-of a mess using a union.
$LK,"SpriteSize","MN:SpriteSize"$() will return the size of a single
operation, while $LK,"SpriteSize","MN:SpriteSize"$() with an 's' will
return the size of an entire lst. Look at
$LK,"gr_sprite_base_size","MN:gr_sprite_base_size"$.
To get familiar, type <CTRL-R> on sprite in
a document and select "Display as Text". It
will show the raw data for each CSprite. This
is how they are stored in files, as well.
See $MA+A-X+PU,"::/TempleOS/Apps/GrModels","Cd(\"::/TempleOS/Apps/GrModels\");Dir;View;\n"$ for an example of
making CSprite by hand. Those are type
$LK,"GRST_MESH","MN:GRST_MESH"$, one of the most complicated.
*/
public U0 SpritePlot3(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,Bool just_one=FALSE)
{
CSprite *tempg=elems-offset(CSprite.start);
I64 i,j,k,x1,y1,z1,x2,y2,
cur_sprite_elem_num=0,*old_r,*r2,
old_flags=dc->flags,
old_pen_width=dc->pen_width;
I32 *ptr;
CColorROPU32 old_color=dc->color;
CDC *img;
CD3I32 *p;
CGrSym old_sym;
MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
while (tempg->type) {
dc->cur_sprite_elem_num=cur_sprite_elem_num++;
switch (tempg->type) {
case GRST_COLOR8:
dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tempg->color8;
break;
case GRST_DITHER_COLOR8:
dc->color=dc->color&~COLORROP_COLORS_MASK|
tempg->dither_color8.u8[0]|
tempg->dither_color8.u8[1]<<COLORROP_BITS|ROPF_DITHER;
break;
case GRST_WIDTH:
dc->pen_width=tempg->width;
GrScalePenWidth(dc);
break;
case GRST_TRANSFORM_ON:
if (!(dc->flags&DCF_TRANSFORMATION)) {
x-=dc->x;
y-=dc->y;
z-=dc->z;
}
dc->flags|=DCF_TRANSFORMATION;
break;
case GRST_TRANSFORM_OFF:
if (dc->flags&DCF_TRANSFORMATION) {
x+=dc->x;
y+=dc->y;
z+=dc->z;
}
dc->flags&=~DCF_TRANSFORMATION;
break;
case GRST_PT:
GrPlot3(dc,tempg->x1+x,tempg->y1+y,z);
break;
case GRST_TEXT:
GrPutS3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_TEXT_BOX:
GrTextBox3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_TEXT_DIAMOND:
GrTextDiamond3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_FLOOD_FILL:
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,FALSE);
break;
case GRST_FLOOD_FILL_NOT:
i=dc->color;
dc->color=dc->color.c0;
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,TRUE);
dc->color=i;
break;
case GRST_SHIFT:
x+=tempg->x1;
y+=tempg->y1;
break;
case GRST_LINE:
GrLine3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_ARROW:
GrArrow3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_PLANAR_SYMMETRY:
if (GrSetSymmetry3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z,tempg->x2+x,tempg->y2+y,z+1))
dc->flags|=DCF_SYMMETRY;
else
dc->flags&=~DCF_SYMMETRY;
break;
case GRST_BITMAP8:
img=CAlloc(sizeof(CDC));
img->type=DCT_COLOR8;
img->width=tempg->width;
img->width_internal=(tempg->width+7)&~7;
img->height=tempg->height;
img->plane_size=img->width_internal*img->height;
img->body=tempg(U8 *)+offset(CSprite.linespeed);
img->dc_signature=DCS_SIGNATURE_VAL;
GrBlot3(dc,tempg->x2+x,tempg->y2+y,z,img);
Free(img);
break;
case GRST_RECT:
GrRect3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
break;
case GRST_ROTATED_RECT:
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=z;
GrRot(dc->r,&x1,&y1,&z1);
old_r=dc->r;
dc->flags|=DCF_TRANSFORMATION;
r2=GrRotZ(-tempg->rot_angle);
GrSetTranslation(r2,x1,y1,z1);
GrSetRotMat(dc,GrMulMat(old_r,r2));
GrRect3(dc,0,0,0,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
Free(dc->r);
Free(r2);
GrSetRotMat(dc,old_r);
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
break;
case GRST_CIRCLE:
GrCircle3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2);
break;
case GRST_ELLIPSE:
GrEllipse3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->rot_angle);
break;
case GRST_REG_POLY:
GrRegPoly3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->sides,tempg->rot_angle);
break;
case GRST_POLYLINE:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
for (i=1;i<tempg->num;i++) {
x2=ptr[i<<1];
y2=ptr[i<<1+1];
GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);
x1=x2;y1=y2;
}
break;
case GRST_POLYPT:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
ptr+=2;
k=tempg->num*3;
GrPlot3(dc,x1+x,y1+y,z);
for (i=0;i<k;i+=3) {
j=BFieldExtU32(ptr,i,3);
x1+=gr_x_offsets[j];
y1+=gr_y_offsets[j];
GrPlot3(dc,x1+x,y1+y,z);
}
break;
case GRST_BSPLINE2:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr2BSpline3(dc,&tempg->y1,tempg->num,FALSE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE3:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3BSpline3(dc,&tempg->y1,tempg->num,FALSE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE2_CLOSED:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr2BSpline3(dc,&tempg->y1,tempg->num,TRUE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE3_CLOSED:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3BSpline3(dc,&tempg->y1,tempg->num,TRUE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_MESH:
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3Mesh(dc,tempg->vertex_cnt,&tempg->x2,tempg->triangle_cnt,(&tempg->x2)(U8 *)+sizeof(CD3I32)*tempg->vertex_cnt);
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_SHIFTABLE_MESH:
if (dc->flags&DCF_TRANSFORMATION) {
dc->x+=tempg->x1;
dc->y+=tempg->y1;
dc->z+=tempg->z1;
x1=x;
y1=y;
z1=z;
} else {
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=tempg->z1+z;
}
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x+=x1;
p->y+=y1;
p->z+=z1;
}
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
Gr3Mesh(dc,tempg->shiftable_vertex_cnt,p,tempg->shiftable_triangle_cnt,p(U8 *)+sizeof(CD3I32)*tempg->shiftable_vertex_cnt);
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x-=x1;
p->y-=y1;
p->z-=z1;
}
if (dc->flags&DCF_TRANSFORMATION) {
dc->x-=tempg->x1;
dc->y-=tempg->y1;
dc->z-=tempg->z1;
}
break;
}
if (just_one) break;
tempg(U8 *)+=SpriteElemSize(tempg);
}
MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));
dc->color=old_color;
dc->pen_width=old_pen_width;
dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |
old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);
}
public U0 SpritePlot3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems)
{
I64 old_x=dc->x,old_y=dc->y,old_z=dc->z,
old_flags=dc->flags&DCF_TRANSFORMATION;
dc->x=x; dc->y=y; dc->z=z;
dc->flags|=DCF_TRANSFORMATION;
SpritePlot3(dc,0,0,0,elems);
dc->x=old_x; dc->y=old_y; dc->z=old_z;
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
}
public U0 SpritePlotRotMat3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
{
I64 *old_r=dc->r,old_m[16],
old_flags=dc->flags&DCF_TRANSFORMATION;
MemCpy(old_m,m,16*sizeof(I64));
dc->flags|=DCF_TRANSFORMATION;
GrAddTranslation(m,x,y,z);
dc->r=GrMulMat(old_r,m);
SpritePlot3(dc,0,0,0,elems);
Free(dc->r);
dc->r=old_r;
MemCpy(m,old_m,16*sizeof(I64));
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
}
public U0 SpritePlotRotX3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 è=0)
{
I64 *r=GrRotX(è);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpritePlotRotY3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 ê=0)
{
I64 *r=GrRotY(ê);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpritePlotRotZ3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 é=0)
{
I64 *r=GrRotZ(é);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,
I64 *min_y=NULL,I64 *max_y=NULL)
{ //Ignores flood fills.
CDC *dc=DCNew(DCT_COLOR8,MAX_I32,MAX_I32,Fs,TRUE);
DCExtentsInit(dc);
SpritePlot3(dc,MAX_I32/2,MAX_I32/2,MAX_I32/2,elems);
if (dc->min_x<=dc->max_x) {
dc->min_x-=MAX_I32/2;
dc->max_x-=MAX_I32/2;
}
if (dc->min_y<=dc->max_y) {
dc->min_y-=MAX_I32/2;
dc->max_y-=MAX_I32/2;
}
if (min_x) *min_x=dc->min_x;
if (max_x) *max_x=dc->max_x;
if (min_y) *min_y=dc->min_y;
if (max_y) *max_y=dc->max_y;
DCDel(dc);
}
public CDC *Sprite2DC(U8 *elems,I64 type=DCT_COLOR8)
{
CDC *result;
I64 min_x,max_x,min_y,max_y;
SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
result=DCNew(type,max_x-min_x+1,max_y-min_y+1);
SpritePlot3(result,-min_x,-min_y,0,elems);
return result;
}
public U8 *SpriteInterpolate(U8 *elems0,U8 *elems1,F64 t)
{
//The two CSprite should be identical
//except for points shifted around.
//t ranges from 0.0 to 1.0
//
//See $LK-A,"::/TempleOS/Demo/Graphics/Golf.CPP"$ for an example.
I64 i=SpriteSize(elems0),
t1=gr_scale*t,t0=gr_scale-t1;
I32 *ptr0,*ptr1,*ptrr;
CD3I32 *p0,*p1,*pr;
U8 *result=MAlloc(i);
CSprite *tempg0=elems0-offset(CSprite.start),
*tempg1=elems1-offset(CSprite.start),
*tempgr=result-offset(CSprite.start);
MemCpy(result,elems0,i);
while (tempg0->type) {
if (tempg0->type!=tempg1->type)
throw(EXCEPT_GRAPHICS,4);
switch (tempg0->type) {
case GRST_ROTATED_RECT:
tempgr->rot_angle=(tempg0->rot_angle*t0+tempg1->rot_angle*t1)/gr_scale;
case GRST_RECT:
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_CIRCLE:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_ELLIPSE:
case GRST_REG_POLY:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
tempgr->width=(tempg0->width*t0+tempg1->width*t1)>>32;
tempgr->height=(tempg0->height*t0+tempg1->height*t1)>>32;
break;
case GRST_BITMAP8:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
break;
case GRST_POLYLINE:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
for (i=0;i<tempg0->num;i++) {
ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;
ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;
}
break;
case GRST_POLYPT:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
ptrr[0]=(ptr0[0]*t0+ptr1[0]*t1)>>32;
ptrr[1]=(ptr0[1]*t0+ptr1[1]*t1)>>32;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
p0=&tempg0->y1;
p1=&tempg1->y1;
pr=&tempgr->y1;
for (i=0;i<tempg0->num;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
case GRST_MESH:
p0=&tempg0->x2;
p1=&tempg1->x2;
pr=&tempgr->x2;
for (i=0;i<tempg0->vertex_cnt;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
case GRST_SHIFTABLE_MESH:
p0=(&tempg0->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
p1=(&tempg1->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
pr=(&tempgr->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg0->shiftable_vertex_cnt;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
}
i=SpriteElemSize(tempg0);
tempg0(U8 *)+=i;
tempg1(U8 *)+=i;
tempgr(U8 *)+=i;
}
return result;
}
#help_index "Graphics/CSprite;Doc/Output"
public CDocEntry *DocPutSprite(CDoc *doc=NULL,U8 *elems,U8 *txt=NULL)
{
I64 size;
U8 *st;
Bool unlock;
CDocEntry *doc_e;
CDocBin *tempb;
if (!doc && !(doc=DocCur)) return NULL;
unlock=DocLock(doc);
size=SpriteSize(elems);
tempb=CAlloc(sizeof(CDocBin),doc->mem_task);
tempb->type=DOCBT_CSPRITE;
tempb->size=size;
tempb->data=MAlloc(size,doc->mem_task);
MemCpy(tempb->data,elems,size);
tempb->num=doc->cur_bin_num;
tempb->use_cnt=1;
QueIns(tempb,doc->bin_root.last);
if (txt)
st=MSPrintF(txt,doc->cur_bin_num++);
else
st=MSPrintF("$$SP,\"\",%d$$",doc->cur_bin_num++);
doc_e=DocPutS(doc,st);
Free(st);
doc_e->bin_data=tempb;
if (doc_e && Bt(doc_tag_types,doc_e->type_u8) && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,doc->mem_task);
if (unlock)
DocUnlock(doc);
return doc_e;
}
public CDocEntry *PutSprite(U8 *elems,U8 *txt=NULL)
{
//If you set txt,
//then include dollarsigns ("$$SP ...$$")
//and leave a %d for the number.
CDoc *doc;
if (doc=DocCur)
return DocPutSprite(doc,elems,txt);
return NULL;
}
+486
View File
@@ -0,0 +1,486 @@
#help_index "Graphics/CGrVectMap"
/*
This processes a monocrome map, finds edges and generates vect graphic
representations of the map broken into small rectangles. The rectangles
are encoded a bit-oriented structure.
PolyLineStruct {
1 Bit : set is valid polyline, clear is end of polyline lst
(R_BITS) : X-coordinate of polyline start
(R_BITS) : Y-coordinate of polyline start
(poly_line_cnt_bits): Number of polyline direction entries
N*3 : N-long seq of 1 pixel directional movements
}
FloodFillStruct {
1 Bit : set is valid flood fill entry, clear is end of floodfill lst
(1+R_BITS): X-coordinate*2 of flood fill (half pixels)
(1+R_BITS): Y-coordinate*2 of flood fill (half pixels)
}
Rect {
1 Bit : set is valid rectangle entry, clear is end of rectangle lst
PolyLineStructLst
FloodFillStructLst
}
*/
#define R_BITS 6
#define R_BORDER 1
#define R_WIDTH (1<<R_BITS-2*R_BORDER)
#define R_HEIGHT (1<<R_BITS-2*R_BORDER)
U0 VectMapBlotRect(CDC *dc,CGrVectMap *vm,I64 bit,F64 scale)
{
I64 k,cnt,i0,j0,i,j,rect_dft,not_rect_dft;
U8 *body=vm->body;
F64 d=scale/2;
dc->pen_width=scale+0.5;
dc->color=rect_dft=Bt(body,bit++);
not_rect_dft=1-rect_dft;
dc->bkcolor=vm->bkcolor;
GrRect(dc,0,0,dc->width,dc->height);
dc->color=not_rect_dft;
while (Bt(body,bit++)) {
j=BFieldExtU32(body,bit,R_BITS);
bit+=R_BITS;
i=BFieldExtU32(body,bit,R_BITS);
bit+=R_BITS;
cnt=BFieldExtU32(body,bit,vm->poly_line_cnt_bits);
bit+=vm->poly_line_cnt_bits;
if (!cnt)
GrPlot3(dc,(j-R_BORDER)*scale+d,(i-R_BORDER)*scale+d,0);
else {
i0=i;j0=j;
while (cnt--) {
k=BFieldExtU32(body,bit,3);
bit+=3;
i+=gr_y_offsets[k];
j+=gr_x_offsets[k];
GrLine3(dc,(j0-R_BORDER)*scale+d,(i0-R_BORDER)*scale+d,0,
(j-R_BORDER)*scale+d,(i-R_BORDER)*scale+d,0);
i0=i; j0=j;
}
}
}
while (Bt(body,bit++)) {
j=BFieldExtU32(body,bit,R_BITS+1);
bit+=R_BITS+1;
i=BFieldExtU32(body,bit,R_BITS+1);
bit+=R_BITS+1;
if (GrPeek(dc,(j/2.0-R_BORDER)*scale+d,(i/2.0-R_BORDER)*scale+d)==rect_dft)
GrFloodFill(dc,(j/2.0-R_BORDER)*scale+d,(i/2.0-R_BORDER)*scale+d);
}
}
class CMPVMBlot
{
CDC *dc,*rect_dc;
CGrVectMap *vm;
I64 bit;
I64 xx,yy;
F64 scale;
I64 busy;
};
U0 VectMapBlotRectMP(CMPVMBlot *mp)
{
VectMapBlotRect(mp->rect_dc,mp->vm,mp->bit,mp->scale);
GrBlot(mp->dc,mp->xx,mp->yy,mp->rect_dc);
mp->busy=FALSE;
}
public U0 VectMapBlotMP(CDC *dc,I64 x,I64 y,CGrVectMap *vm,F64 scale=1.0,I64 _mp_cnt=0)
{
I64 i,i_lo,i_hi,j,j_lo,j_hi,k,cpu,pass,
w=(vm->width +R_WIDTH-1)/R_WIDTH,
h=(vm->height+R_HEIGHT-1)/R_HEIGHT;
F64 xx,yy,r_scale=scale*(R_WIDTH+1.0/scale)/R_WIDTH;
CMPVMBlot *mp;
if (!dc || !vm) return;
if (Gs->num)
_mp_cnt=1; //Only core #0 can be master
else if (!_mp_cnt)
_mp_cnt=mp_cnt;
else if (_mp_cnt>mp_cnt)
_mp_cnt=mp_cnt;
cpu=_mp_cnt-1;
mp=MAlloc(_mp_cnt*sizeof(CMPVMBlot));
for (i=0;i<_mp_cnt;i++) {
mp[i].rect_dc=DCNew(DCT_COLOR8,R_WIDTH*r_scale,R_HEIGHT*r_scale,Fs);
mp[i].dc=DCAlias(dc,dc->win_task);
mp[i].dc->color=dc->color;
mp[i].vm=vm;
mp[i].scale=r_scale;
mp[i].busy=FALSE;
}
if (y<0)
i_lo=-y/(R_HEIGHT*scale);
else
i_lo=0;
if (R_HEIGHT*scale*h+y>dc->height)
i_hi=MinI64((dc->height-y)/(R_HEIGHT*scale)+1,h);
else
i_hi=h;
if (x<0)
j_lo=-x/(R_WIDTH*scale);
else
j_lo=0;
if (R_WIDTH*scale*w+x>dc->width)
j_hi=MinI64((dc->width-x)/(R_WIDTH*scale)+1,w);
else
j_hi=w;
xx=x+j_lo*R_WIDTH*scale;
for (j=j_lo;j<j_hi;j++) {
yy=y+i_lo*R_WIDTH*scale;
k=i_lo*w+j;
for (i=i_lo;i<i_hi;i++) {
if (_mp_cnt>1) {
pass=0;
//Does up to two passes
while (TRUE)
if (!pass && !cpu) {
pass++;
cpu=_mp_cnt-1;
} else if (mp[cpu].busy) //by the way, core #0 is never busy
cpu--;
else
break;
}
mp[cpu].xx=xx;
mp[cpu].yy=yy;
mp[cpu].bit=vm->rect_start_bits[k];
if (!cpu)
VectMapBlotRectMP(mp);
else {
mp[cpu].busy=TRUE;
MPJob(&VectMapBlotRectMP,&mp[cpu],cpu);
}
k+=w;
yy+=R_HEIGHT*scale;
}
xx+=R_WIDTH*scale;
}
for (i=_mp_cnt-1;i>=0;i--) {
while(mp[i].busy)
Yield;
DCDel(mp[i].rect_dc);
DCDel(mp[i].dc);
}
Free(mp);
}
Bool IsSolidSquare(CDC *dc,I64 x,I64 y,I64 edge,CColorROPU32 color)
{
I64 i,j;
edge>>=1;
for (i=-edge;i<edge;i++)
for (j=-edge;j<edge;j++)
if (GrPeek(dc,x+j,y+i)!=color)
return FALSE;
return TRUE;
}
I64 VectizeRect(CDC *dc,I64 _x,I64 _y,CGrVectMap *vm,I64 _bit,
I64 poly_line_cnt_bits,I64 *_max_poly_line_cnt_bits)
{ //Returns number of bits to represent rect
CDC *b_desired =DCExtract(dc,_x-R_BORDER,_y-R_BORDER,_x+R_WIDTH+R_BORDER*2-1,_y+R_BORDER*2+R_HEIGHT-1),
*b_edge=DCNew(DCT_COLOR8,R_WIDTH+R_BORDER*2,R_HEIGHT+R_BORDER*2,Fs),
*b_actual,
*b_link_check=DCNew(DCT_COLOR8,R_WIDTH+R_BORDER*2,R_HEIGHT+R_BORDER*2,Fs);
I64 step,step_bits,x,y,xx,yy,xx1,yy1,xx2,yy2,cnt=0,k,kk,rect_dft,not_rect_dft,
cnt_bit,link_bit1,link_bit2,link_bit_limit,bit=_bit,max_poly_line_cnt_bits;
U8 *body=vm->body;
Bool found;
if (_max_poly_line_cnt_bits)
max_poly_line_cnt_bits=*_max_poly_line_cnt_bits;
else
max_poly_line_cnt_bits=3;
//Count ON pixels
for (y=0;y<R_HEIGHT;y++)
for (x=0;x<R_WIDTH;x++)
if (GrPeek(b_desired,R_BORDER+x,R_BORDER+y)==1)
cnt++;
if (cnt>=R_WIDTH*R_HEIGHT/2)
rect_dft=1;
else
rect_dft=0;
not_rect_dft=1-rect_dft;
BEqu(body,bit++,rect_dft);
if (!cnt || cnt==R_WIDTH*R_HEIGHT) {
//Rect is all ON or OFF
Btr(body,bit++); //End of poly-line lst
Btr(body,bit++); //End of flood-fill lst
} else {
for (y=0;y<R_HEIGHT+R_BORDER*2;y++)
for (x=0;x<R_WIDTH+R_BORDER*2;x++) {
b_edge->color=0;
if (GrPeek(b_desired,x,y)==not_rect_dft)
for (k=0;k<8;k++)
if (GrPeek(b_desired,x+gr_x_offsets[k],y+gr_y_offsets[k])==rect_dft)
b_edge->color=1;
GrPlot(b_edge,x,y);
}
b_edge->color=0;
link_bit1=bit;
for (y=0;y<R_HEIGHT+R_BORDER*2;y++)
for (x=0;x<R_WIDTH+R_BORDER*2;x++)
if (GrPeek(b_edge,x,y)==1) {
Bts(body,bit++); //Show not end of poly-line lst
GrPlot(b_edge,x,y);
BFieldOrU32(body,bit,x); //Poly-line starting X coordinate in rect
bit+=R_BITS;
BFieldOrU32(body,bit,y); //Poly-line starting Y coordinate in rect
bit+=R_BITS;
yy=y; xx=x;
cnt_bit=bit;
bit+=poly_line_cnt_bits; //Reserve space for count of direction offsets in poly-line
cnt=0;
do {
found=FALSE;
for (k=0;k<8;k++) {
yy2=yy+gr_y_offsets[k];
xx2=xx+gr_x_offsets[k];
if (0<=xx2<R_WIDTH+R_BORDER*2 &&
0<=yy2<R_HEIGHT+R_BORDER*2 &&
GrPeek(b_edge,xx2,yy2)==1) {
cnt++;
BFieldOrU32(body,bit,k); //3-bit (or 2) incoding of direction movement
bit+=3;
GrPlot(b_edge,xx2,yy2);
yy=yy2; xx=xx2;
found=TRUE;
break;
}
}
} while (found);
BFieldOrU32(body,cnt_bit,cnt);
if (cnt && Bsr(cnt)+1>max_poly_line_cnt_bits)
max_poly_line_cnt_bits=Bsr(cnt)+1;
}
//Connect adjacent groups with link to prevent flood-fill leaks.
link_bit_limit=bit;
while (link_bit1<link_bit_limit) {
link_bit1++;
x=BFieldExtU32(body,link_bit1,R_BITS);
link_bit1+=R_BITS;
y=BFieldExtU32(body,link_bit1,R_BITS);
link_bit1+=R_BITS;
link_bit2=link_bit1;
yy=y;xx=x;
cnt=BFieldExtU32(body,link_bit2,poly_line_cnt_bits);
link_bit2+=poly_line_cnt_bits;
while (TRUE) {
for (k=0;k<8;k++) {
yy2=yy+gr_y_offsets[k];
xx2=xx+gr_x_offsets[k];
if (0<=xx2<R_WIDTH+R_BORDER*2 &&
0<=yy2<R_HEIGHT+R_BORDER*2 &&
GrPeek(b_link_check,xx2,yy2)==1) {
Bts(body,bit++);
BFieldOrU32(body,bit,xx);
bit+=R_BITS;
BFieldOrU32(body,bit,yy);
bit+=R_BITS;
BFieldOrU32(body,bit,1);
bit+=poly_line_cnt_bits;
BFieldOrU32(body,bit,k);
bit+=3;
}
}
if (!cnt--)
break;
kk=BFieldExtU32(body,link_bit2,3);
link_bit2+=3;
yy+=gr_y_offsets[kk];
xx+=gr_x_offsets[kk];
}
link_bit2=link_bit1;
yy=y;xx=x;
b_link_check->color=1;
GrPlot(b_link_check,xx,yy);
cnt=BFieldExtU32(body,link_bit2,poly_line_cnt_bits);
link_bit2+=poly_line_cnt_bits;
while (cnt--) {
kk=BFieldExtU32(body,link_bit2,3);
link_bit2+=3;
yy+=gr_y_offsets[kk];
xx+=gr_x_offsets[kk];
GrPlot(b_link_check,xx,yy);
}
link_bit1=link_bit2;
}
Btr(body,bit++); //End of poly-line lst
b_desired->color=rect_dft;
GrLineRect4(b_desired,0,0,R_WIDTH+2*R_BORDER-1,R_HEIGHT+2*R_BORDER-1);
Btr(body,bit); //Temp end of flood-fill lst
for (step_bits=2;step_bits>=1;step_bits-=1) {
step=1<<step_bits;
b_actual=DCNew(DCT_COLOR8,R_WIDTH/step,R_HEIGHT/step,Fs);
VectMapBlotRect(b_actual,vm,_bit,1.0/step);
b_actual->color=not_rect_dft;
GrLineRect4(b_actual,0,0,R_WIDTH+2*R_BORDER-1,R_HEIGHT+2*R_BORDER-1);
//Flood fill
for (y=R_BORDER;y<R_HEIGHT+R_BORDER;y+=step)
for (x=R_BORDER;x<R_WIDTH+R_BORDER;x+=step)
if (IsSolidSquare(b_desired,x,y,step,not_rect_dft) && GrPeek(b_actual,x>>step_bits,y>>step_bits)==rect_dft) {
Bts(body,bit++); //Show not end of flood-fill lst
yy=y; xx=x;
for (k=0;k<4;k++) {
yy2=yy;
while (yy2<R_HEIGHT+R_BORDER-1 &&
IsSolidSquare(b_desired,xx,yy2,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy2>>step_bits)==rect_dft)
yy2++;
while (yy>R_BORDER &&
IsSolidSquare(b_desired,xx,yy,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy>>step_bits)==rect_dft)
yy--;
yy1=yy+yy2;
yy=yy1/2;
xx2=xx;
while (xx2<R_WIDTH+R_BORDER-1 &&
IsSolidSquare(b_desired,xx2,yy,step,not_rect_dft) && GrPeek(b_actual,xx2>>step_bits,yy>>step_bits)==rect_dft)
xx2++;
while (xx>R_BORDER &&
IsSolidSquare(b_desired,xx,yy,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy>>step_bits)==rect_dft)
xx--;
xx1=xx+xx2;
xx=xx1/2;
}
GrFloodFill(b_actual,xx>>step_bits,yy>>step_bits);
BFieldOrU32(body,bit,xx1); //Flood fill X-coordinate in rect
bit+=R_BITS+1;
BFieldOrU32(body,bit,yy1); //Flood fill Y-coordinate in rect
bit+=R_BITS+1;
}
DCDel(b_actual);
Btr(body,bit); //Temp end of flood-fill lst
}
bit++; //End of flood-fill lst
}
DCDel(b_desired);
DCDel(b_edge);
DCDel(b_link_check);
if (_max_poly_line_cnt_bits) *_max_poly_line_cnt_bits=max_poly_line_cnt_bits;
return bit-_bit;
}
#define TEMP_BODY_SIZE 0x10000
public CGrVectMap *DC2VectMap(CDC *dc,CTask *mem_task=NULL,I64 *_size=NULL)
{ //Currently does not convert outer 1 pixel border
I64 i,j,k,cnt,size,
w=(dc->width-R_BORDER*2+R_WIDTH-1)/R_WIDTH,
h=(dc->height-R_BORDER*2+R_HEIGHT-1)/R_HEIGHT,
rect_cnt=w*h,poly_line_cnt_bits=12,max_poly_line_cnt_bits=3;
U32 *rect_start_bits;
U8 *body;
CGrVectMap *result,tempv;
body=MAlloc(TEMP_BODY_SIZE);
//Pass 1: Get max_poly_line_cnt_bits
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
MemSet(&tempv,0,sizeof(CGrVectMap));
MemSet(body,0,TEMP_BODY_SIZE);
tempv.width =dc->width-R_BORDER*2;
tempv.height=dc->height-R_BORDER*2;
tempv.body=body;
tempv.rect_cnt=rect_cnt;
tempv.r_bits=R_BITS;
tempv.poly_line_cnt_bits=poly_line_cnt_bits;
VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,&tempv,0,poly_line_cnt_bits,&max_poly_line_cnt_bits);
}
//Pass 2: Get cnt
poly_line_cnt_bits=max_poly_line_cnt_bits;
cnt=0;
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
MemSet(&tempv,0,sizeof(CGrVectMap));
MemSet(body,0,TEMP_BODY_SIZE);
tempv.width =dc->width-R_BORDER*2;
tempv.height=dc->height-R_BORDER*2;
tempv.body=body;
tempv.rect_cnt=rect_cnt;
tempv.r_bits=R_BITS;
tempv.poly_line_cnt_bits=poly_line_cnt_bits;
cnt+=VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,&tempv,0,poly_line_cnt_bits,NULL);
}
Free(body);
//Pass 3
size=(cnt+7)/8;
result=CAlloc(sizeof(CGrVectMap),mem_task);
result->body=CAlloc(size,mem_task);
rect_start_bits=MAlloc((rect_cnt+1)*sizeof(U32),mem_task);
result->width =dc->width-R_BORDER*2;
result->height=dc->height-R_BORDER*2;
result->rect_cnt=rect_cnt;
result->r_bits=R_BITS;
result->poly_line_cnt_bits=poly_line_cnt_bits;
result->rect_start_bits=rect_start_bits;
k=0;
cnt=0;
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
rect_start_bits[k++]=cnt;
cnt+=VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,result,cnt,poly_line_cnt_bits,NULL);
}
rect_start_bits[k]=cnt;
if (_size) *_size=size;
return result;
}
public U0 VectMapDel(CGrVectMap *vm)
{
Free(vm->rect_start_bits);
Free(vm->body);
Free(vm);
}
U32 *VectMapRectStartBits(CGrVectMap *vm,CTask *mem_task=NULL)
{
I64 k=0,bit=0;
U8 *body=vm->body;
U32 *result=MAlloc((vm->rect_cnt+1)*sizeof(U32),mem_task);
for (k=0;k<vm->rect_cnt;k++) {
result[k]=bit++;
while (Bt(body,bit++)) {
bit+=2*R_BITS;
bit+=vm->poly_line_cnt_bits+3*BFieldExtU32(body,bit,vm->poly_line_cnt_bits);
}
while (Bt(body,bit++))
bit+=2*(R_BITS+1);
}
result[k]=bit;
return result;
}
File diff suppressed because it is too large. Load diff