Initial (manual) import

This commit is contained in:
minexew committed 2017-01-22 20:26:44 +01:00
1 parent f39611c506
commit 895fe109de
661 files changed
+245862

No files matched your search

+180
View File
@@ -0,0 +1,180 @@
#help_index "Sprites/Binary"
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
};
class CQueMeshTri
{
CQueMeshTri *next,*last;
U0 start;
I32 color;
I32 nums[3];
};
public class CSpriteBase
{
U8 type;
};
public class CSpriteColor : CSpriteBase
{
U8 color;
};
public class CSpriteDitherColor : CSpriteBase
{
U16 dither_color;
};
public class CSpriteW : CSpriteBase
{
I32 width;
};
public class CSpritePt : CSpriteBase
{
I32 x1;
I32 y1;
};
public class CSpritePtRad : CSpritePt
{
I32 radius;
};
public class CSpritePtPt : CSpritePt
{
I32 x2;
I32 y2;
};
public class CSpritePtPtAng : CSpritePtPt
{
F64 angle;
};
public class CSpritePtWH : CSpritePt
{
I32 width;
I32 height;
};
public class CSpritePtWHU8s : CSpritePtWH
{
U8 u[0];
};
public class CSpritePtWHAng : CSpritePtWH
{
F64 angle;
};
public class CSpritePtWHAngSides : CSpritePtWHAng
{
I32 sides;
};
public class CSpriteNumU8s : CSpriteBase
{
I32 num;
U8 u[0];
};
public class CSpriteNumPtU8s : CSpriteBase
{
I32 num;
I32 x;
I32 y;
U8 u[0];
};
public class CSpritePtStr : CSpritePt
{
U8 st[0];
};
public class CSpriteMeshU8s : CSpriteBase
{
I32 vertex_cnt;
I32 tri_cnt;
U8 u[0];
};
public class CSpritePtMeshU8s : CSpriteBase
{
I32 x;
I32 y;
I32 z;
I32 vertex_cnt;
I32 tri_cnt;
U8 u[0];
};
#define SPF_SEL 128
#define SPf_SEL 7
#define SPT_END 0 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
#define SPT_COLOR 1 //$LK,"CSpriteColor",A="MN:CSpriteColor"$
#define SPT_DITHER_COLOR 2 //$LK,"CSpriteDitherColor",A="MN:CSpriteDitherColor"$
#define SPT_WIDTH 3 //$LK,"CSpriteW",A="MN:CSpriteW"$
#define SPT_PLANAR_SYMMETRY 4 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
#define SPT_TRANSFORM_ON 5 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
#define SPT_TRANSFORM_OFF 6 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
#define SPT_SHIFT 7 //$LK,"CSpritePt",A="MN:CSpritePt"$
#define SPT_PT 8 //$LK,"CSpritePt",A="MN:CSpritePt"$
#define SPT_POLYPT 9 //$LK,"CSpriteNumPtU8s",A="MN:CSpriteNumPtU8s"$
#define SPT_LINE 10 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
#define SPT_POLYLINE 11 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
#define SPT_RECT 12 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
#define SPT_ROTATED_RECT 13 //$LK,"CSpritePtPtAng",A="MN:CSpritePtPtAng"$
#define SPT_CIRCLE 14 //$LK,"CSpritePtRad",A="MN:CSpritePtRad"$
#define SPT_ELLIPSE 15 //$LK,"CSpritePtWHAng",A="MN:CSpritePtWHAng"$
#define SPT_POLYGON 16 //$LK,"CSpritePtWHAngSides",A="MN:CSpritePtWHAngSides"$
#define SPT_BSPLINE2 17 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
#define SPT_BSPLINE2_CLOSED 18 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
#define SPT_BSPLINE3 19 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
#define SPT_BSPLINE3_CLOSED 20 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
#define SPT_FLOOD_FILL 21 //$LK,"CSpritePt",A="MN:CSpritePt"$
#define SPT_FLOOD_FILL_NOT 22 //$LK,"CSpritePt",A="MN:CSpritePt"$
#define SPT_BITMAP 23 //$LK,"CSpritePtWHU8s",A="MN:CSpritePtWHU8s"$
#define SPT_MESH 24 //$LK,"CSpriteMeshU8s",A="MN:CSpriteMeshU8s"$ See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$.
#define SPT_SHIFTABLE_MESH 25 //$LK,"CSpritePtMeshU8s",A="MN:CSpritePtMeshU8s"$ See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$.
#define SPT_ARROW 26 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
#define SPT_TEXT 27 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
#define SPT_TEXT_BOX 28 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
#define SPT_TEXT_DIAMOND 29 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
#define SPT_TYPES_NUM 30
#define SPG_TYPE_MASK 0x7F
#help_index "Graphics/Sprite;Sprites;Sprites/Binary"
//See $LK,"Sprites",A="HI:Sprites"$. See $LK,"::/Adam/Gr/GrSpritePlot.HC",A="FL:::/Adam/Gr/GrSpritePlot.HC,1"$ and
//$LK,"::/Demo/Graphics/SpriteRaw.HC"$ for how CSprite are stored.
public class CSprite
{
CSprite *next,*last;
U0 start;
union {
U8 type;
CSpriteBase b;
CSpriteColor c;
CSpriteDitherColor d;
CSpriteW w;
CSpritePt p;
CSpritePtPt pp;
CSpritePtPtAng ppa;
CSpritePtRad pr;
CSpritePtWHU8s pwhu;
CSpritePtWHAng pwha;
CSpritePtWHAngSides pwhas;
CSpriteNumU8s nu;
CSpriteNumPtU8s npu;
CSpriteMeshU8s mu;
CSpritePtMeshU8s pmu;
CSpritePtStr ps;
}
};
+410
View File
@@ -0,0 +1,410 @@
#help_index "Graphics/Misc"
asm {
//************************************
_GR_UPDATE_LINE64::
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src
MOV RBX,U64 [&rev_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSQ
CMP U64 [RDI],RAX
JE @@10
MOV U64 [RDI],RAX
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
MOV U64 [R8],RAX
@@10: ADD RDI,8
ADD R8,8
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
POP RBP
RET1 32
//************************************
_GR_UPDATE_LINE64_FLUSH_CACHE::
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src
MOV RBX,U64 [&rev_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSQ
MOV U64 [RDI],RAX
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
XLATB
ROR RAX,8
MOV U64 [R8],RAX
ADD RDI,8
ADD R8,8
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
POP RBP
RET1 32
//************************************
_DC_BLOT_COLOR4::
PUSH RBP
MOV RBP,RSP
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 RDI
POP RSI
POP RBP
RET1 32
//************************************
_IS_PIX_COVERED0::
PUSH RBP
MOV RBP,RSP
#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: POP RBP
RET1 24
//************************************
_GR_ROP_EQU_U8_NO_CLIPPING::
//Puts foreground char shape onto gr.dc2.
//ch.u8[1] is color as a whole byte
//ch ATTRf_UNDERLINE attr flag is used.
PUSH RBP
MOV RBP,RSP
MOVZX RAX,U8 SF_ARG1[RBP]
MOV RDX,U64 [&text.font]
MOV RAX,U64 [RDX+RAX*8] //RAX is 8x8 char font data, 64-bits
BT U64 SF_ARG1[RBP],ATTRf_UNDERLINE
JNC @@05
MOV RBX,0xFF00000000000000
OR RAX,RBX
@@05: TEST 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.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.to_8_bits] //RSI is gr.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: POP RBP
RET1 24
}
_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,
U8 *dst,I64 width_internal);
public _extern _IS_PIX_COVERED0 Bool IsPixCovered0(
CTask *task,I64 x,I64 y);//No clipping
_extern _GR_UPDATE_LINE64 U0 GrUpdateLine64(
U64 **_vga,U64 **_src,I64 d,U8 **_dst);
_extern _GR_UPDATE_LINE64_FLUSH_CACHE U0 GrUpdateLine64FlushCache(
U64 **_vga,U64 **_src,I64 d,U8 **_dst);
_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
File diff suppressed because it is too large. Load diff
+344
View File
@@ -0,0 +1,344 @@
#help_index "Graphics"
public I64 GrFillPoly3(CDC *dc=gr.dc,I64 n,CD3I32 *poly)
{//3D. Must be convex.
//Returns cnt of pixs changed
CD3I32 tri[3];
I64 i,j,x,y,z,res=0;
if (n<3) return 0;
if (dc->flags & DCF_SYMMETRY) {
for (i=1;i<n-1;i++) {
j=i-1;
if (i==1) {
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
DCReflect(dc,&x,&y,&z);
tri[0].x=x; tri[0].y=y; tri[0].z=z;
}
j++;
if (i==1) {
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
DCReflect(dc,&x,&y,&z);
}
tri[1].x=x; tri[1].y=y; tri[1].z=z;
j++;
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
DCReflect(dc,&x,&y,&z);
tri[2].x=x; tri[2].y=y; tri[2].z=z;
res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
}
}
if (dc->flags&DCF_JUST_MIRROR)
return res;
for (i=1;i<n-1;i++) {
j=i-1;
if (i==1) {
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
tri[0].x=x; tri[0].y=y; tri[0].z=z;
}
j++;
if (i==1) {
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
}
tri[1].x=x; tri[1].y=y; tri[1].z=z;
j++;
x=poly[j].x; y=poly[j].y; z=poly[j].z;
if (dc->flags&DCF_TRANSFORMATION)
(*dc->transform)(dc,&x,&y,&z);
tri[2].x=x; tri[2].y=y; tri[2].z=z;
res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
}
return res;
}
public I64 GrRectB(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
{//2D. Two point. Clipping but not transformation.
if (x2<x1) SwapI64(&x1,&x2);
if (y2<y1) SwapI64(&y1,&y2);
return GrRect(dc,x1,y1,x2-x1+1,y2-y1+1);
}
public I64 GrRect3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,I64 w,I64 h)
{//3D. Width Height. Clipping and transformation.
CD3I32 poly[4];
poly[0].x=x;
poly[0].y=y;
poly[0].z=z;
poly[1].x=x+w;
poly[1].y=y;
poly[1].z=z;
poly[2].x=x+w;
poly[2].y=y+h;
poly[2].z=z;
poly[3].x=x;
poly[3].y=y+h;
poly[3].z=z;
return GrFillPoly3(dc,4,poly);
}
public U0 GrBorder(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
I64 step=1,I64 start=0)
{//2D. Transformation with pen width.
//Can be used with ROPF_DITHER+WHITE<<16+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 Bool GrArrow3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
{//3D. Transformation with pen width.
I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
F64 d;
Bool res=FALSE,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;
DCReflect(dc,&_x1,&_y1,&_z1);
_x2=x2; _y2=y2; _z2=z2;
DCReflect(dc,&_x2,&_y2,&_z2);
dc->flags&=~DCF_SYMMETRY;
res=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;
res|=Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,
_x2,_y2,_z2,&GrPlot3,step);
res|=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;
}
res|=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;
res|=Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,
x2,y2,z2,&GrPlot3,step);
res|=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;
return res;
}
#help_index "Graphics/Char;Char/Graphics"
public Bool GrTextBox3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
{//3D. Transformation. DCF_SYMMETRY is silly.
U8 *ptr;
I64 ch,res,w,w_max,h;
if (!s) return FALSE;
ptr=s;
w=0; w_max=0; h=FONT_HEIGHT;
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;
res=GrPrint(dc,x1,y1,"%s",s);
res|=GrLine(dc,x1-border ,y1-border ,x1+w_max+border,y1-border);
res|=GrLine(dc,x1-border ,y1+h+border,x1+w_max+border,y1+h+border);
res|=GrLine(dc,x1-border ,y1-border ,x1-border,y1+h+border);
res|=GrLine(dc,x1+w_max+border,y1-border ,x1+w_max+border,y1+h+border);
return ToBool(res);
}
#define DIAMOND_SLOPE_MAX 2.75
public Bool GrTextDiamond3(CDC *dc=gr.dc,
I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
{//3D. Transformation. DCF_SYMMETRY is silly.
Bool first=TRUE;
U8 ch,*ptr,*ptr_end,*st,*s;
I64 res=0,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=='\r'||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) {
res|=GrPrint(dc,x1-w,y,"%s",st);
first=FALSE;
} else
res|=GrPrint(dc,x1-w,y,"%s",st);
if (w) {
w+=border;
do {
dx_old=dx; dy_old=dy;
m=ToF64(dx)/dy;
if (m<1/DIAMOND_SLOPE_MAX) {
dy=MaxI64(dy,Ceil(DIAMOND_SLOPE_MAX*dx));
m=1/DIAMOND_SLOPE_MAX;
} else if (m>DIAMOND_SLOPE_MAX) {
dy=MaxI64(dy,Ceil(dx/DIAMOND_SLOPE_MAX));
m=DIAMOND_SLOPE_MAX;
}
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);
res|=GrLine(dc,x1,y1-dy,x1+dx,y1);
res|=GrLine(dc,x1+dx,y1,x1,y1+dy);
res|=GrLine(dc,x1,y1+dy,x1-dx,y1);
res|=GrLine(dc,x1-dx,y1,x1,y1-dy);
return ToBool(res);
}
#help_index "Graphics/Mesh"
public I64 Gr3Mesh(CDC *dc=gr.dc,I64 vertex_cnt,CD3I32 *p,
I64 tri_cnt,CMeshTri *tri)
{//Returns cnt of pixs changed.
CColorROPU32 old_color=dc->color;
I64 i,x,y,z,res=0;
CD3I32 *pt,*pt_sym,*p_sym,*dst;
CMeshTri *tri_sym=tri;
if (dc->flags&DCF_TRANSFORMATION) {
dst=pt=MAlloc(sizeof(CD3I32)*vertex_cnt);
for (i=0;i<vertex_cnt;i++,p++,dst++) {
x=p->x; y=p->y; z=p->z;
(*dc->transform)(dc,&x,&y,&z);
dst->x=x; dst->y=y; dst->z=z;
}
p=pt;
} else
pt=NULL;
if (dc->flags & DCF_SYMMETRY) {
dst=pt_sym=MAlloc(sizeof(CD3I32)*vertex_cnt);
p_sym=p;
for (i=0;i<vertex_cnt;i++,p_sym++,dst++) {
x=p_sym->x; y=p_sym->y; z=p_sym->z;
DCReflect(dc,&x,&y,&z);
dst->x=x; dst->y=y; dst->z=z;
}
p_sym=pt_sym;
for (i=0;i<tri_cnt;i++,tri_sym++) {
(*dc->lighting)(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
&p_sym[tri_sym->nums[1]],tri_sym->color);
res+=GrFillTri0(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
&p_sym[tri_sym->nums[1]]);
}
Free(pt_sym);
if (dc->flags&DCF_JUST_MIRROR)
goto mesh_done;
}
for (i=0;i<tri_cnt;i++,tri++) {
(*dc->lighting)(dc,&p[tri->nums[0]],&p[tri->nums[1]],
&p[tri->nums[2]],tri->color);
res+=GrFillTri0(dc,&p[tri->nums[0]],&p[tri->nums[1]],&p[tri->nums[2]]);
}
mesh_done:
dc->color=old_color;
Free(pt);
return res;
}
#help_index "Graphics/Misc;Mouse/Ptr"
public U0 DrawStdMs(CDC *dc,I64 x,I64 y)
{//This is a callback. See $LK,"::/Demo/Graphics/Grid.HC"$.
//Called by $LK,"DrawMs",A="MN:DrawMs"$() which is
//called by $LK,"WinFinalUpdate",A="MN:WinFinalUpdate"$().
dc->pen_width=1;
dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
GrArrow3(dc,x+8,y+8,0,x,y,0);
}
gr.fp_draw_ms=&DrawStdMs;
public U0 DrawWaitMs(CDC *dc,I64 x,I64 y)
{//This is a callback. See $LK,"::/Demo/Graphics/Grid.HC"$.
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/GR Files;Graphics/Scrn"
public Bool GRScrnCaptureRead(U8 *filename,CDC *dc=gr.dc,I64 x=0,I64 y=0)
{//GrBlot TempleOS GR File to dc,x,y.
CDC *dc2;
if (dc2=GRRead(filename)) {
dc->color=ROP_EQU;
GrBlot(dc,x,y,dc2);
DCDel(dc2);
return TRUE;
}
return FALSE;
}
public I64 GRScrnCaptureWrite(U8 *filename,Bool include_zoom=TRUE)
{//Capture scrn to a TempleOS GR File.
I64 size;
CDC *dc=DCScrnCapture(include_zoom);
size=GRWrite(filename,dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
DCDel(dc);
return size;
}
+430
View File
@@ -0,0 +1,430 @@
#help_index "Graphics/Math/3D Transformation"
#help_file "::/Doc/Transform"
#define GR_SCALE (1<<32)
public U0 Mat4x4MulXYZ(I64 *r,I64 *_x,I64 *_y,I64 *_z)
{//Rotate 3D point using 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;
x1=(r[0*4+0]*xx+r[0*4+1]*yy+r[0*4+2]*zz+r[0*4+3])>>32;
y1=(r[1*4+0]*xx+r[1*4+1]*yy+r[1*4+2]*zz+r[1*4+3])>>32;
z1=(r[2*4+0]*xx+r[2*4+1]*yy+r[2*4+2]*zz+r[2*4+3])>>32;
*_x=x1;*_y=y1;*_z=z1;
}
public U0 DCTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
{//This is the dft dc->transform() callback.
//Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
Mat4x4MulXYZ(dc->r,_x,_y,_z);
*_x+=dc->x;
*_y+=dc->y;
*_z+=dc->z;
}
public I64 *Mat4x4IdentEqu(I64 *r)
{//Set matrix to identity. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
MemSet(r,0,sizeof(I64)*16);
r[0*4+0].i32[1]=1;
r[1*4+1].i32[1]=1;
r[2*4+2].i32[1]=1;
r[3*4+3].i32[1]=1;
return r;
}
public I64 *Mat4x4IdentNew(CTask *mem_task=NULL)
{//MAlloc an identity matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
return Mat4x4IdentEqu(MAlloc(sizeof(I64)*16,mem_task));
}
public I64 Mat4x4NormSqr65536(I64 *r)
{//Norm Squared of r.
//(1.0/Sqrt(3))*65536=37837.22
return SqrI64((r[0*4+0]*37838+r[0*4+1]*37838+r[0*4+2]*37838)>>32)+
SqrI64((r[1*4+0]*37837+r[1*4+1]*37837+r[1*4+2]*37837)>>32)+
SqrI64((r[2*4+0]*37837+r[2*4+1]*37837+r[2*4+2]*37837)>>32);
}
public U0 DCMat4x4Set(CDC *dc=NULL,I64 *r)
{//Set device context's rot matrix. Will be $LK,"Free",A="MN:Free"$d() in $LK,"DCDel",A="MN:DCDel"$().Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
//The main purpose is to set matrix norm for pen width scaling.
//NULL as dc means gr.dc
if (!dc) dc=gr.dc;
dc->r=r;
dc->r_norm=Sqrt(Mat4x4NormSqr65536(r))*65536; //scaled 32 bits
}
#help_index "Graphics/Mesh"
public U0 DCLighting(CDC *dc,
CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)
{//This is the dft dc->lighting() callback.
CD3I32 v1,v2;
I64 i,vn_x,vn_y,vn_z;
F64 d;
v1.x=p1->x-p2->x;
v1.y=p1->y-p2->y;
v1.z=p1->z-p2->z;
v2.x=p3->x-p2->x;
v2.y=p3->y-p2->y;
v2.z=p3->z-p2->z;
//V1 and V2 are vects along two sides
//of the tri joined at p2.
vn_x=v1.y*v2.z-v1.z*v2.y;
vn_y=v1.z*v2.x-v1.x*v2.z;
vn_z=v1.x*v2.y-v1.y*v2.x;
if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
d=1<<16/d;
vn_x*=d;
vn_y*=d;
vn_z*=d;
//Vn is the cross product of V1 and V3
//which means it is perpendicular. It
//is the normal vect to the surface.
//It has been scaled to length 65536.
//Light source has been scaled to length 65536.
i=(vn_x*dc->ls.x+vn_y*dc->ls.y+vn_z*dc->ls.z)>>16;
//The dot product of the light source
//vect and the surface normal
//gives an illumination number.
//65536*65536>>16=65536
//TempleOS will generate a random U16
//and compare to dither_probability_u16 and
//will pick from two colors.
//Probability dithering does not work with pen_width>1 at this time.
if (color.c0.rop&ROPBF_TWO_SIDED) {
color.c0.rop&=~ROPBF_TWO_SIDED;
i=AbsI64(i)<<1;
} else
i+=65536;
if (color.c0.rop&ROPBF_HALF_RANGE_COLOR) {
color.c0.rop&=~ROPBF_HALF_RANGE_COLOR;
i>>=1;
if (color>=8) {
color-=8;
i+=65536;
}
}
if (i<65536) {
dc->color=ROPF_PROBABILITY_DITHER+color<<16+BLACK;
dc->dither_probability_u16=i;
} else {
dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
dc->dither_probability_u16=i-65536;
}
}
#help_index "Graphics/Device Contexts"
public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=TRANSPARENT)
{//Fill entire device context with color.
if (!dc) dc=gr.dc;
MemSet(dc->body,val,dc->width_internal*dc->height);
}
public U0 DCClear(CDC *dc=NULL)
{//Set entire device context image body to 0 (BLACK).
if (!dc) dc=gr.dc;
DCFill(dc,0);
}
public U0 DCRst(CDC *dc)
{//Reset $LK,"CDC",A="MN:CDC"$ structure members but not image body, itself.
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=&DCTransform;
dc->lighting =&DCLighting;
Mat4x4IdentEqu(dc->r);
dc->r_norm=GR_SCALE;
dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
MemCpy(dc->palette,gr_palette_std,sizeof(CBGR48)*COLORS_NUM);
}
public U0 DCExtentsInit(CDC *dc=NULL)
{//Init markers for extent of next newly drawn graphics.
//NULL means gr.dc
//See $LK,"::/Demo/Graphics/Extents.HC"$
//You should clear the record flag yourself
if (!dc) dc=gr.dc;
dc->flags|=DCF_RECORD_EXTENTS;
dc->min_x=I64_MAX;
dc->max_x=I64_MIN;
dc->min_y=I64_MAX;
dc->max_y=I64_MIN;
}
public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
{//Create alias of dc, so can change pen, color, etc.
//NULL means gr.dc
CDC *res;
if (!dc) dc=gr.dc;
if (!task) task=Fs;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
throw('Graphics');
res=MAlloc(sizeof(CDC),task);
MemCpy(res,dc,sizeof(CDC));
res->win_task=res->mem_task=task;
res->r=MAlloc(16*sizeof(I64),task);
DCRst(res);
res->flags|=DCF_ALIAS;
res->alias=dc;
return res;
}
public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
{//Create new width x height device context.
//Internally only allows widths which are divisible by 8.
//Don't forget these $MA-X+PU,"sizeof(CDC)",LM="Find(\"sizeof(CDC)\",\"/*\");View;"$.
CDC *res;
if (!task) task=Fs;
res=CAlloc(sizeof(CDC),task);
res->win_task=task;
res->mem_task=task;
res->width=width;
res->width_internal=(width+7)&~7;
res->height=height;
if (null_bitmap)
res->flags|=DCF_DONT_DRAW;
else
res->body=CAlloc(res->width_internal*res->height,task);
res->r=MAlloc(16*sizeof(I64),task);
DCRst(res);
res->dc_signature=DCS_SIGNATURE_VAL;
return res;
}
public U0 DCDel(CDC *dc)
{//Free dc, image body, rot mat and depth buf.
if (!dc) return;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
throw('Graphics');
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)
{//Mem size of header, image body and depth buffer.
if (dc)
return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
else
return 0;
}
public I32 *DCDepthBufRst(CDC *dc)
{//Reset device context depth buf to far away.
if (dc->depth_buf)
MemSetU32(dc->depth_buf,I32_MAX,dc->width_internal*dc->height);
return dc->depth_buf;
}
public I32 *DCDepthBufAlloc(CDC *dc)
{//Alloc a 32-bit depth buffer for device context.
Free(dc->depth_buf);
dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
return DCDepthBufRst(dc);
}
public CDC *DCCopy(CDC *dc,CTask *task=NULL)
{//Alloc copy of dc, including image body, rot mat and depth buf.
CDC *res;
if (!dc) return NULL;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
throw('Graphics');
res=MAllocIdent(dc,task);
DCMat4x4Set(res,Mat4x4New(dc->r,task));
res->mem_task=task;
res->body=MAllocIdent(dc->body,task);
res->depth_buf=MAllocIdent(dc->depth_buf,task);
return res;
}
public U0 DCMono(CDC *dc,
I64 quest=TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
{//Set entire device context to one of two colors.
I64 i;
U8 *dst;
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==quest)
*dst++=true_color;
else
*dst++=false_color;
}
public I64 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=TRANSPARENT)
{//Find and replace src color with dst in device context.
I64 i,res=0;
U8 *dst;
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==src_color) {
*dst++=dst_color;
res++;
} else
dst++;
return res;
}
public U8 *DCSave(CDC *dc,I64 *_size=NULL,I64 dcsf_flags=DCSF_COMPRESSED)
{//Stores device context to mem, perhaps, with compression.
U8 *res,*ptr,*body;
CArcCompress *arc;
I64 body_size=dc->width_internal*dc->height,total_size,flags;
CBGR48 palette[COLORS_NUM];
if (dcsf_flags&DCSF_COMPRESSED) {
arc=CompressBuf(dc->body,body_size);
body_size=arc->compressed_size;
body=arc;
} else {
arc=NULL;
body=dc->body;
}
total_size=offset(CDC.end)-offset(CDC.start)+body_size;
if (dcsf_flags&DCSF_COMPRESSED)
flags=DCF_COMPRESSED;
else
flags=0;
if (dcsf_flags&DCSF_PALETTE_GET)
GrPaletteGet(palette);
else
MemCpy(palette,&dc->palette,COLORS_NUM*sizeof(CBGR48));
if (MemCmp(palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48))) {
flags|=DCF_PALETTE;
total_size+=COLORS_NUM*sizeof(CBGR48);
}
ptr=res=MAlloc(total_size);
#assert !offset(CDC.start)
MemCpy(ptr,&dc->start,offset(CDC.end)-offset(CDC.start));
ptr(CDC *)->flags=flags;
ptr+=offset(CDC.end)-offset(CDC.start);
#assert offset(CDC.end)==offset(CDC.palette)
if (flags&DCF_PALETTE) {
MemCpy(ptr,palette,COLORS_NUM*sizeof(CBGR48));
ptr+=COLORS_NUM*sizeof(CBGR48);
}
MemCpy(ptr,body,body_size);
ptr+=body_size;
Free(arc);
if (_size) *_size=total_size;
return res;
}
public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
{//Loads device context from mem.
CDC *res;
U8 *ptr=src;
CArcCompress *arc;
I64 body_size;
if (!task) task=Fs;
res=CAlloc(sizeof(CDC),task);
res->win_task=task;
res->mem_task=task;
MemCpy(&res->start,ptr,offset(CDC.end)-offset(CDC.start));
ptr+=offset(CDC.end)-offset(CDC.start);
if (res->flags&DCF_PALETTE) {
MemCpy(&res->palette,ptr,COLORS_NUM*sizeof(CBGR48));
ptr+=COLORS_NUM*sizeof(CBGR48);
} else
MemCpy(&res->palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48));
body_size=res->width_internal*res->height;
if (res->flags&DCF_COMPRESSED) {
res->flags&=~DCF_COMPRESSED;
arc=ptr;
res->body=ExpandBuf(arc,task);
ptr+=arc->compressed_size;
} else {
res->body=MAlloc(body_size,task);
MemCpy(res->body,ptr,body_size);
ptr+=body_size;
}
res->pen_width=1;
res->r=Mat4x4IdentNew(task);
res->r_norm.u32[1]=1;
res->dc_signature=DCS_SIGNATURE_VAL;
if (_size) *_size=ptr-src;
return res;
}
#help_index "Graphics/GR Files"
#help_file "::/Doc/GRFiles"
#help_index "Graphics/Device Contexts;Graphics/GR Files"
public I64 GRWrite(U8 *filename,CDC *dc,I64 dcsf_flags=DCSF_COMPRESSED)
{//TempleOS GR File.
I64 size;
U8 *st=DftExt(filename,"GR.Z"),
*src=DCSave(dc,&size,dcsf_flags);
FileWrite(st,src,size);
Free(st);
Free(src);
return size;
}
public CDC *GRRead(U8 *filename,CTask *task=NULL)
{//TempleOS GR File.
CDC *dc=NULL;
U8 *st=DftExt(filename,"GR.Z"),
*src=FileRead(st);
if (src)
dc=DCLoad(src,,task);
Free(src);
Free(st);
return dc;
}
#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
public U0 DocGR(CDoc *doc=NULL,U8 *filename)
{//Put a GR file into a document as asprite.
CDC *dc=GRRead(filename);
CSprite *elems=DC2Sprite(dc);
DocSprite(doc,elems);
Free(elems);
DCDel(dc);
}
#help_index "Graphics/Device Contexts;Graphics/Scrn"
public CDC *DCScrnCapture(Bool include_zoom=TRUE,CTask *task=NULL)
{//Capture scrn to a device context.
CDC *dc;
U8 *dst;
Refresh(2,TRUE);
if (include_zoom)
dc=DCCopy(gr.scrn_image,task);
else
dc=DCCopy(gr.dc1,task);
dc->flags&=~DCF_SCRN_BITMAP;
dst=MAlloc(dc->width_internal*dc->height,task);
//Pick background color that never occurs. COLOR_INVALID
GrBitMap4ToBitMap8(dst,dc->body,
(dc->width_internal*dc->height)>>1,COLOR_INVALID);
Free(dc->body);
dc->body=dst;
return dc;
}
+29
View File
@@ -0,0 +1,29 @@
#help_index "Graphics/Scrn"
U0 CtrlAltZ(I64 sc)
{
if (sc&SCF_SHIFT)
GrScaleZoom(0.5);
else
GrScaleZoom(2.0);
}
CtrlAltCBSet('Z',&CtrlAltZ,"Cmd /Zoom In",
"Cmd /Zoom Out");
U0 Scrn2Clipboard(I64)
{
CDC *dc=DCScrnCapture;
U8 *elems=DC2Sprite(dc);
Bool unlock_doc=DocLock(sys_clipboard_doc);
ClipboardDel;
DocSprite(sys_clipboard_doc,elems);
if (unlock_doc)
DocUnlock(sys_clipboard_doc);
Free(elems);
DCDel(dc);
}
U0 CtrlAltS(I64)
{
Spawn(&Scrn2Clipboard);
}
CtrlAltCBSet('S',&CtrlAltS,"Cmd /Scrn Shot to Clipboard");
+5
View File
@@ -0,0 +1,5 @@
#help_index "Graphics"
extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
extern I64 GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
extern I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL);
extern U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL);
+55
View File
@@ -0,0 +1,55 @@
#help_index "Graphics"
public class CGrGlbls
{
I64 *to_8_bits,*to_8_colors;
CDC *scrn_image, //Read only.
*dc, //Persistent
*dc1,
*dc2, //Updated every refresh
*dc_cache,
*zoomed_dc;
U32 *text_base; //See $LK,"TextBase Layer",A="HI:TextBase Layer"$. (Similar to 0xB8000 but 32 bits)
U16 *win_z_buf;
#define SPHT_ELEM_CODE 1
CHashTable *sprite_hash;
U16 *win_uncovered_bitmap;
I64 highest_uncovered;
U16 *vga_text_cache;
I64 pan_text_x,pan_text_y; //[-7,7]
U0 (*fp_final_scrn_update)(CDC *dc);//Mouse cursor is handled here.
U0 (*fp_wall_paper)(CTask *task);
U0 (*fp_draw_ms)(CDC *dc,I64 x,I64 y);
U0 (*fp_draw_grab_ms)(CDC *dc,I64 x,I64 y,Bool closed);
U8 *empty_sprite; //Gets assigned $LK,"gr.empty_sprite",A="FF:::/Adam/AMouse.HC,empty_sprite"$
#define GR_PEN_BRUSHES_NUM 64
CDC *pen_brushes[GR_PEN_BRUSHES_NUM],
*collision_pen_brushes[GR_PEN_BRUSHES_NUM],
*even_pen_brushes[GR_PEN_BRUSHES_NUM],
*odd_pen_brushes[GR_PEN_BRUSHES_NUM];
I8 circle_lo[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM],
circle_hi[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM];
#define GR_SCRN_ZOOM_MAX 8
U8 *scrn_zoom_tables[GR_SCRN_ZOOM_MAX+1];
I64 scrn_zoom,sx,sy;
//When zoomed, this keeps the mouse centered.
Bool continuous_scroll,
hide_row,hide_col;
} gr;
//See $LK,"RLf_VGA",A="FF:::/Kernel/KStart16.HC,RLf_VGA"$
//See $LK,"SysGrInit",A="MN:SysGrInit"$()
//Allows consts to be used instead of vars.
HashPublic("GR_WIDTH",HTT_DEFINE_STR);;
HashPublic("GR_HEIGHT",HTT_DEFINE_STR);;
#help_index "Char;TextBase Layer/Char"
DefinePrint("TEXT_ROWS","%d",text.rows);;;
HashPublic("TEXT_ROWS",HTT_DEFINE_STR);;;
DefinePrint("TEXT_COLS","%d",text.cols);;;
HashPublic("TEXT_COLS",HTT_DEFINE_STR);;;
+21
View File
@@ -0,0 +1,21 @@
#help_index "Graphics"
U0 GrInit1()
{
DefineLstLoad("ST_SPRITE_ELEM_TYPES",
"End\0Color\0Dither Color\0"
"Width\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
"Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
"Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
"BSpline3\0BSpline3 Closed\0"
"Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
"Arrow\0Text\0Text Box\0Text Diamond\0");
DefineLstLoad("ST_SPRITE_ELEM_CODES",
"End\0Color\0Color\0"
"Width\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
"Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
"Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
"FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
"Arrow\0Text\0TextBox\0TextDiamond\0");
}
GrInit1;
+209
View File
@@ -0,0 +1,209 @@
#help_index "Graphics/Scrn"
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.to_8_bits(U8 *)[k++]=0xFF;
else
gr.to_8_bits(U8 *)[k++]=0x00;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
gr.to_8_colors(U8 *)[k++]=i;
for (i=0;i<GR_PEN_BRUSHES_NUM;i++) {
k=i+1;
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) {
if (x-1-i>>1<gr.circle_lo[i][i-y])
gr.circle_lo[i][i-y]=x-1-i>>1;
if (x-1-i>>1>gr.circle_hi[i][i-y])
gr.circle_hi[i][i-y]=x-1-i>>1;
}
dc=DCNew(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(i,i);
gr.collision_pen_brushes[i]=dc;
dc->color=COLOR_INVALID;//Want color that never occurs.
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(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(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 (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
MemSet(text.vga_text_alias,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
MemSet(gr.vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
} else {
OutU8(VGAP_IDX,VGAR_MAP_MASK);
OutU8(VGAP_DATA,0x0F);
//Virtual Box crashes on the following for some reason.
// MemSet(text.vga_alias,0,GR_HEIGHT*GR_WIDTH>>3);
MemSet(gr.scrn_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
}
for (i=1;i<=GR_SCRN_ZOOM_MAX;i++) {
dst=gr.scrn_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];
}
}
}
#help_index "Graphics/Scrn;Windows"
U0 WinZBufFill(CTask *task)
{//Not public
I64 y,t,b,l,r,w;
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
if (task->win_top-1>0)
t=task->win_top-1;
else
t=0;
if (task->win_bottom+1<TEXT_ROWS)
b=task->win_bottom+1;
else
b=TEXT_ROWS-1;
if (task->win_left-1>0)
l=task->win_left-1;
else
l=0;
if (task->win_right+1<TEXT_COLS)
r=task->win_right+1;
else
r=TEXT_COLS-1;
} else {
if (task->win_top>0)
t=task->win_top;
else
t=0;
if (task->win_bottom<TEXT_ROWS)
b=task->win_bottom;
else
b=TEXT_ROWS-1;
if (task->win_left>0)
l=task->win_left;
else
l=0;
if (task->win_right<TEXT_COLS)
r=task->win_right;
else
r=TEXT_COLS-1;
}
t=ClampI64(t,0,TEXT_ROWS-1);
b=ClampI64(b,t,TEXT_ROWS-1);
l=ClampI64(l,0,TEXT_COLS-1);
r=ClampI64(r,l,TEXT_COLS-1);
if (w=r-l+1)
for (y=t;y<=b;y++)
MemSetU16(gr.win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
task->win_z_num,w);
}
public U0 WinZBufUpdate()
{//Might have to call if doing graphics outside winmgr callback routines.
//Call it if, for example, when a pop-up window closes and you need to refresh
//before graphics.
I64 i,z=1;
U16 *ptr;
CTask *task,*task1;
if (gr.win_z_buf) {
LBtr(&sys_semas[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++);
}
}
#help_index "Graphics"
U0 GrInit2()
{
MemSet(&gr,0,sizeof(CGrGlbls));
gr.sprite_hash=HashTableNew(512);
HashDefineLstAdd("ST_SPRITE_ELEM_CODES",SPHT_ELEM_CODE,gr.sprite_hash);
gr.scrn_zoom=1;
PaletteSetStd;
fp_set_std_palette=&PaletteSetStd;
GrPaletteIndicesSet;
gr.to_8_bits =MAlloc(256*sizeof(I64));
gr.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_uncovered_bitmap=CAlloc(65536/8);
gr.highest_uncovered=0;
gr.win_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
gr.dc2=DCNew(GR_WIDTH,GR_HEIGHT);
gr.dc2->flags|=DCF_SCRN_BITMAP;
gr.dc_cache=DCNew(GR_WIDTH,GR_HEIGHT);
gr.dc=DCNew(GR_WIDTH,GR_HEIGHT);
gr.dc->flags|=DCF_SCRN_BITMAP|DCF_ON_TOP;
DCFill;
gr.dc1=DCNew(GR_WIDTH,GR_HEIGHT);
gr.dc1->flags|=DCF_SCRN_BITMAP;
gr.scrn_image=DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
gr.zoomed_dc =DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
gr.zoomed_dc->flags|=DCF_SCRN_BITMAP;
}
GrInit2;
+805
View File
@@ -0,0 +1,805 @@
#help_index "Graphics/Math"
public I64 gr_x_offsets[8]={-1, 0, 1,-1,1,-1,0,1},
gr_y_offsets[8]={-1,-1,-1, 0,0, 1,1,1},
gr_x_offsets2[4]={ 0,-1, 1, 0},
gr_y_offsets2[4]={-1, 0, 0, 1};
public Bool Line(U8 *aux_data,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),I64 step=1,I64 start=0)
{//Step through line segment calling callback.
//Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
I64 i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,
adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
Bool first=TRUE;
if (adx>=ady) {
if (adx>=adz) {
if (d=adx) {
if (dx>=0)
dx=0x100000000;
else
dx=-0x100000000;
dy=dy<<32/d;
dz=dz<<32/d;
}
} else {
if (d=adz) {
dx=dx<<32/d;
dy=dy<<32/d;
if (dz>=0)
dz=0x100000000;
else
dz=-0x100000000;
}
}
} else {
if (ady>=adz) {
if (d=ady) {
dx=dx<<32/d;
if (dy>=0)
dy=0x100000000;
else
dy=-0x100000000;
dz=dz<<32/d;
}
} else {
if (d=adz) {
dx=dx<<32/d;
dy=dy<<32/d;
if (dz>=0)
dz=0x100000000;
else
dz=-0x100000000;
}
}
}
x1<<=32; y1<<=32; z1<<=32;
for (j=0;j<start;j++) {
x1+=dx; y1+=dy; z1+=dz;
}
if (step!=1 && step!=0) {
dx*=step;
dy*=step;
dz*=step;
d/=step;
}
for (i=start;i<=d;i++) {
if ((_x!=x1.i32[1] || _y!=y1.i32[1] || _z!=z1.i32[1] || first) &&
!(*fp_plot)(aux_data,x1.i32[1],y1.i32[1],z1.i32[1]))
return FALSE;
first=FALSE;
_x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
x1+=dx; y1+=dy; z1+=dz;
}
if (step==1 && (_x!=x2||_y!=y2||_z!=z2) && !(*fp_plot)(aux_data,x2,y2,z2))
return FALSE;
return TRUE;
}
#help_index "Graphics/Math/3D Transformation"
public I64 *Mat4x4MulMat4x4Equ(I64 *dst,I64 *m1,I64 *m2)
{//Multiply 4x4 matrices and store in dst. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
//Conceptually, the transform m1 is applied after m2
I64 i,j,k;
F64 sum;
for (i=0;i<4;i++) {
for (j=0;j<4;j++) {
sum=0;
for (k=0;k<4;k++)
sum+=ToF64(m1[k+4*j])*ToF64(m2[i+4*k]);
dst[i+4*j]=sum/GR_SCALE;
}
}
return dst;
}
public I64 *Mat4x4MulMat4x4New(I64 *m1,I64 *m2,CTask *mem_task=NULL)
{//Multiply 4x4 matrices. Return MAlloced matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
//Conceptually, the transform m1 is applied after m2
return Mat4x4MulMat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),m1,m2);
}
public I64 *Mat4x4Equ(I64 *dst,I64 *src)
{//Copy 4x4 Rot matrix.
MemCpy(dst,src,sizeof(I64)*16);
return dst;
}
public I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL)
{//Return MAlloced copy of 4x4 Rot matrix.
return Mat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),src);
}
public I64 *Mat4x4RotX(I64 *m,F64 è)
{//Rot matrix about X axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
F64 my_cos=Cos(è)*GR_SCALE,my_sin=Sin(è)*GR_SCALE;
I64 r[16],r2[16];
MemSet(r,0,sizeof(r));
r[5]=my_cos;
r[10]=my_cos;
r[9]=my_sin;
r[6]=-my_sin;
r[0]=GR_SCALE;
r[15]=GR_SCALE;
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
}
public I64 *Mat4x4RotY(I64 *m,F64 ê)
{//Rot matrix about Y axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
F64 my_cos=Cos(ê)*GR_SCALE,my_sin=Sin(ê)*GR_SCALE;
I64 r[16],r2[16];
MemSet(r,0,sizeof(r));
r[0]=my_cos;
r[10]=my_cos;
r[8]=-my_sin;
r[2]=my_sin;
r[5]=GR_SCALE;
r[15]=GR_SCALE;
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
}
public I64 *Mat4x4RotZ(I64 *m,F64 é)
{//Rot matrix about Z axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
F64 my_cos=Cos(é)*GR_SCALE,my_sin=Sin(é)*GR_SCALE;
I64 r[16],r2[16];
MemSet(r,0,sizeof(r));
r[0]=my_cos;
r[5]=my_cos;
r[4]=my_sin;
r[1]=-my_sin;
r[10]=GR_SCALE;
r[15]=GR_SCALE;
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
}
public I64 *Mat4x4Scale(I64 *m,F64 s)
{//Scale 4x4 matrix by value.
I64 i;
for (i=0;i<16;i++)
m[i]*=s;
return m;
}
public U0 DCPenWidthScale(CDC *dc=gr.dc)
{//Scale device context's pen width by norm of transformation.
I64 d;
if (dc->flags&DCF_TRANSFORMATION) {
if (dc->pen_width) {
d=dc->pen_width*dc->r_norm+0x80000000; //Round
dc->pen_width=d.i32[1];
if (dc->pen_width<1)
dc->pen_width=1;
}
}
}
public I64 *Mat4x4TranslationEqu(I64 *r,I64 x,I64 y,I64 z)
{//Set translation values in 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
r[0*4+3]=x<<32;
r[1*4+3]=y<<32;
r[2*4+3]=z<<32;
r[3*4+3]=GR_SCALE;
return r;
}
public I64 *Mat4x4TranslationAdd(I64 *r,I64 x,I64 y,I64 z)
{//Add translation to 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
r[0*4+3]+=x<<32;
r[1*4+3]+=y<<32;
r[2*4+3]+=z<<32;
r[3*4+3]=GR_SCALE;
return r;
}
public Bool DCSymmetrySet(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
{//2D. Set device context's symmetry.
F64 d;
if (y1==y2 && x1==x2)
return FALSE;
dc->sym.snx=y2-y1;
dc->sym.sny=x1-x2;
dc->sym.snz=0;
if (d=Sqrt(SqrI64(dc->sym.snx)+
SqrI64(dc->sym.sny)+
SqrI64(dc->sym.snz))) {
d=GR_SCALE/d;
dc->sym.snx *= d;
dc->sym.sny *= d;
dc->sym.snz *= d;
}
dc->sym.sx=x1;
dc->sym.sy=y1;
dc->sym.sz=0;
return TRUE;
}
public Bool DCSymmetry3Set(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
I64 x2,I64 y2,I64 z2,I64 x3,I64 y3,I64 z3)
{//3D. Set device context's symmetry.
F64 d,x,y,z,xx,yy,zz;
I64 xx1,yy1,zz1,xx2,yy2,zz2,*r;
xx1=x1-x2; yy1=y1-y2; zz1=z1-z2;
xx2=x3-x2; yy2=y3-y2; zz2=z3-z2;
if (!xx1 && !yy1 && !zz1 ||
!xx2 && !yy2 && !zz2 ||
xx1==xx2 && yy1==yy2 && zz1==zz2)
return FALSE;
x=yy1*zz2-zz1*yy2;
y=-xx1*zz2+zz1*xx2;
z=xx1*yy2-yy1*xx2;
if (dc->flags & DCF_TRANSFORMATION) {
r=dc->r;
xx=x*r[0]+y*r[1]+z*r[2];
yy=x*r[4]+y*r[5]+z*r[6];
zz=x*r[8]+y*r[9]+z*r[10];
x=xx; y=yy; z=zz;
}
if (d=Sqrt(Sqr(x)+Sqr(y)+Sqr(z))) {
d=GR_SCALE/d;
dc->sym.snx = d*x;
dc->sym.sny = d*y;
dc->sym.snz = d*z;
}
if (dc->flags & DCF_TRANSFORMATION)
(*dc->transform)(dc,&x1,&y1,&z1);
dc->sym.sx=x1;
dc->sym.sy=y1;
dc->sym.sz=z1;
return TRUE;
}
public U0 DCReflect(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
{//Reflect 3D point about device context's symmetry. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
I64 x=*_x<<32,y=*_y<<32,z=*_z<<32,
xx=*_x-dc->sym.sx,yy=*_y-dc->sym.sy,zz=*_z-dc->sym.sz,
d=(xx*dc->sym.snx+yy*dc->sym.sny+zz*dc->sym.snz)>>16,
xn,yn,zn,xx2,yy2,zz2;
xn=d*dc->sym.snx>>15;
yn=d*dc->sym.sny>>15;
zn=d*dc->sym.snz>>15;
xx=x-xn;
yy=y-yn;
zz=z-zn;
xx2=x+xn;
yy2=y+yn;
zz2=z+zn;
if (SqrI64(xx>>16 -dc->sym.sx<<16)+
SqrI64(yy>>16 -dc->sym.sy<<16)+
SqrI64(zz>>16 -dc->sym.sz<<16)<
SqrI64(xx2>>16-dc->sym.sx<<16)+
SqrI64(yy2>>16-dc->sym.sy<<16)+
SqrI64(zz2>>16-dc->sym.sz<<16)) {
*_x=xx.i32[1]; *_y=yy.i32[1]; *_z=zz.i32[1];
} else {
*_x=xx2.i32[1]; *_y=yy2.i32[1]; *_z=zz2.i32[1];
}
}
#help_index "Graphics/Math"
#define GR_SCALE1_BITS 24
#define GR_SCALE2_BITS 8
public Bool Circle(U8 *aux_data,I64 cx,I64 cy,I64 cz,I64 radius,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
{//Step through circle arc calling callback.
I64 i,j,len=Ceil(len_radians*radius),
x,y,x1,y1,s1,s2,c;
F64 t;
if (radius<=0||!step) return TRUE;
t=1.0/radius;
c=1<<GR_SCALE1_BITS*Cos(t);
if (step<0) {
step=-step;
s2=1<<GR_SCALE1_BITS*Sin(t);
s1=-s2;
} else {
s1=1<<GR_SCALE1_BITS*Sin(t);
s2=-s1;
}
if (start_radians) {
x=radius*Cos(start_radians);
y=-radius*Sin(start_radians);
} else {
x=radius;
y=0;
}
x<<=GR_SCALE2_BITS;
y<<=GR_SCALE2_BITS;
for (i=0;i<=len;i+=step) {
if (!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
return FALSE;
for (j=0;j<step;j++) {
x1=(c*x+s1*y)>>GR_SCALE1_BITS;
y1=(s2*x+c*y)>>GR_SCALE1_BITS;
x=x1; y=y1;
}
}
return TRUE;
}
public Bool Ellipse(U8 *aux_data,I64 cx,I64 cy,I64 cz,
I64 x_radius,I64 y_radius,Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
{//Step through ellipse arc calling callback.
I64 i,j,len,
x,y,_x,_y,x1,y1,x2,y2, s1,s2,c, s12,s22,c2;
F64 t;
Bool first=TRUE;
if (x_radius<=0 || y_radius<=0 || !step)
return TRUE;
if (x_radius>=y_radius) {
t=1.0/x_radius;
len=Ceil(len_radians*x_radius);
} else {
t=1.0/y_radius;
len=Ceil(len_radians*y_radius);
}
c=1<<GR_SCALE1_BITS*Cos(t);
if (step<0) {
step=-step;
s2=1<<GR_SCALE1_BITS*Sin(t);
s1=-s2;
} else {
s1=1<<GR_SCALE1_BITS*Sin(t);
s2=-s1;
}
c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
s22=-s12;
if (start_radians) {
x=x_radius*Cos(start_radians);
y=-x_radius*Sin(start_radians);
} else {
x=x_radius;
y=0;
}
x<<=GR_SCALE2_BITS;
y<<=GR_SCALE2_BITS;
x2=x;
y2=y;
y1=y2*y_radius/x_radius;
x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
for (i=0;i<=len;i+=step) {
if ((x>>GR_SCALE2_BITS!=_x || y>>GR_SCALE2_BITS!=_y || first) &&
!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
return FALSE;
_x=x>>GR_SCALE2_BITS; _y=y>>GR_SCALE2_BITS; first=FALSE;
for (j=0;j<step;j++) {
x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
x2=x1;
y2=y1;
y1=y1*y_radius/x_radius;
x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
}
}
return TRUE;
}
public Bool RegPoly(U8 *aux_data,I64 cx,I64 cy,I64 cz,
I64 x_radius,I64 y_radius,I64 sides,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
{//Step through regular polygon calling callback.
I64 i,n,x,y,x1,y1,x2,y2,
xx1,yy1,xx2,yy2,
s1,s2,c, s12,s22,c2;
F64 angle_step;
if (sides<=0 || x_radius<=0 || y_radius<=0)
return TRUE;
angle_step=2*ã/sides;
n=len_radians*sides/(2*ã);
s1=1<<GR_SCALE1_BITS*Sin(angle_step);
s2=-s1;
c=1<<GR_SCALE1_BITS*Cos(angle_step);
s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
s22=-s12;
c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
if (start_radians) {
x=x_radius*Cos(start_radians);
y=-x_radius*Sin(start_radians);
} else {
x=x_radius;
y=0;
}
x<<=GR_SCALE2_BITS;
y<<=GR_SCALE2_BITS;
x2=x;
y2=y;
y1=y2*y_radius/x_radius;
x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
xx1=cx+x>>GR_SCALE2_BITS;
yy1=cy+y>>GR_SCALE2_BITS;
for (i=0;i<n;i++) {
x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
x2=x1;
y2=y1;
y1=y1*y_radius/x_radius;
x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
xx2=cx+x>>GR_SCALE2_BITS;
yy2=cy+y>>GR_SCALE2_BITS;
if (!Line(aux_data,xx1,yy1,cz,xx2,yy2,cz,fp_plot,step))
return FALSE;
xx1=xx2; yy1=yy2;
}
return TRUE;
}
#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
public F64 D3I32Dist(CD3I32 *p1,CD3I32 *p2)
{//Distance
return Sqrt(SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z));
}
public I64 D3I32DistSqr(CD3I32 *p1,CD3I32 *p2)
{//Distance Squared
return SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z);
}
public F64 D3I32Norm(CD3I32 *p)
{//Norm
return Sqrt(SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z));
}
public I64 D3I32NormSqr(CD3I32 *p)
{//Norm Squared
return SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z);
}
#help_index "Graphics/Math"
public Bool Bezier2(U8 *aux_data,CD3I32 *ctrl,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
{//Go in 2nd order bezier calling callback.
I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
D3I32Dist(&ctrl[1],&ctrl[2])+
D3I32Dist(&ctrl[2],&ctrl[0]),
s=0.5/d,t1,t2;
xx=x0; yy=y0; zz=z0;
if (first && !(*fp_plot)(aux_data,xx,yy,zz))
return FALSE;
for (t=0.0;t<=1.0;t+=s) {
t1=t*(1.0-t);
t2=t*t;
x=x0+x1*t1+x2*t2;
y=y0+y1*t1+y2*t2;
z=z0+z1*t1+z2*t2;
dx=AbsI64(x-xx);
dy=AbsI64(y-yy);
dz=AbsI64(z-zz);
if (dx>dy)
d_max=dx;
else
d_max=dy;
if (dz>d_max)
d_max=dz;
if (!d_max)
s*=1.1;
else {
s*=0.9;
if (!(*fp_plot)(aux_data,x,y,z))
return FALSE;
xx=x;yy=y;zz=z;
}
}
x=ctrl[2].x; y=ctrl[2].y; z=ctrl[2].z;
if ((xx!=x || yy!=y || zz!=z) &&
!(*fp_plot)(aux_data,x,y,z))
return FALSE;
return TRUE;
}
public Bool Bezier3(U8 *aux_data,CD3I32 *ctrl,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
{//Go in 3rd order bezier calling callback.
I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
x3=ctrl[3].x-x0,y3=ctrl[3].y-y0,z3=ctrl[3].z-z0,
t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
D3I32Dist(&ctrl[1],&ctrl[2])+
D3I32Dist(&ctrl[2],&ctrl[3])+
D3I32Dist(&ctrl[3],&ctrl[0]),
s=0.5/d,nt,t1,t2,t3;
xx=x0; yy=y0; zz=z0;
if (first && !(*fp_plot)(aux_data,xx,yy,zz))
return FALSE;
for (t=0.0;t<=1.0;t+=s) {
nt=1.0-t;
t1=t*nt*nt;
t2=t*t*nt;
t3=t*t*t;
x=x0+x1*t1+x2*t2+x3*t3;
y=y0+y1*t1+y2*t2+y3*t3;
z=z0+z1*t1+z2*t2+z3*t3;
dx=AbsI64(x-xx);
dy=AbsI64(y-yy);
dz=AbsI64(z-zz);
if (dx>dy)
d_max=dx;
else
d_max=dy;
if (dz>d_max)
d_max=dz;
if (!d_max)
s*=1.1;
else {
s*=0.9;
if (!(*fp_plot)(aux_data,x,y,z))
return FALSE;
xx=x;yy=y;zz=z;
}
}
x=ctrl[3].x; y=ctrl[3].y; z=ctrl[3].z;
if ((xx!=x || yy!=y || zz!=z) &&
!(*fp_plot)(aux_data,x,y,z))
return FALSE;
return TRUE;
}
public Bool BSpline2(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
{//Go in 2nd order spline calling callback.
I64 i,j;
CD3I32 *c;
Bool first;
if (cnt<3) return FALSE;
first=TRUE;
if (closed) {
cnt++;
c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
j=1;
for (i=0;i<cnt-2;i++) {
c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
j+=2;
}
c[j].x=(ctrl[0].x+ctrl[cnt-2].x)/2.0;
c[j].y=(ctrl[0].y+ctrl[cnt-2].y)/2.0;
c[j].z=(ctrl[0].z+ctrl[cnt-2].z)/2.0;
c[0].x=(c[1].x+c[j].x)/2.0;
c[0].y=(c[1].y+c[j].y)/2.0;
c[0].z=(c[1].z+c[j].z)/2.0;
j=2;
for (i=0;i<cnt-2;i++) {
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
j+=2;
}
c[j].x=c[0].x;
c[j].y=c[0].y;
c[j].z=c[0].z;
} else {
c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
c[0].x=ctrl[0].x;
c[0].y=ctrl[0].y;
c[0].z=ctrl[0].z;
c[cnt*2-2].x=ctrl[cnt-1].x;
c[cnt*2-2].y=ctrl[cnt-1].y;
c[cnt*2-2].z=ctrl[cnt-1].z;
j=1;
for (i=0;i<cnt-1;i++) {
c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
j+=2;
}
j=2;
for (i=0;i<cnt-2;i++) {
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
j+=2;
}
}
for (i=0;i<cnt*2-2;i+=2) {
if (!Bezier2(aux_data,&c[i],fp_plot,first))
return FALSE;
first=FALSE;
}
Free(c);
return TRUE;
}
public Bool BSpline3(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
{//Go in 3rd order spline calling callback.
I64 i,j;
F64 x,y,z;
CD3I32 *c;
Bool first;
if (cnt<3) return FALSE;
first=TRUE;
if (closed) {
cnt++;
c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
j=1;
for (i=0;i<cnt-2;i++) {
x=ctrl[i].x;
y=ctrl[i].y;
z=ctrl[i].z;
c[j].x=(ctrl[i+1].x-x)/3.0+x;
c[j].y=(ctrl[i+1].y-y)/3.0+y;
c[j].z=(ctrl[i+1].z-z)/3.0+z;
j++;
c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
j+=2;
}
x=ctrl[cnt-2].x;
y=ctrl[cnt-2].y;
z=ctrl[cnt-2].z;
c[j].x=(ctrl[0].x-x)/3.0+x;
c[j].y=(ctrl[0].y-y)/3.0+y;
c[j].z=(ctrl[0].z-z)/3.0+z;
j++;
c[j].x=2.0*(ctrl[0].x-x)/3.0+x;
c[j].y=2.0*(ctrl[0].y-y)/3.0+y;
c[j].z=2.0*(ctrl[0].z-z)/3.0+z;
c[0].x=(c[1].x+c[j].x)/2.0;
c[0].y=(c[1].y+c[j].y)/2.0;
c[0].z=(c[1].z+c[j].z)/2.0;
j=3;
for (i=0;i<cnt-2;i++) {
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
j+=3;
}
c[j].x=c[0].x;
c[j].y=c[0].y;
c[j].z=c[0].z;
} else {
c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
c[0].x=ctrl[0].x;
c[0].y=ctrl[0].y;
c[0].z=ctrl[0].z;
c[cnt*3-3].x=ctrl[cnt-1].x;
c[cnt*3-3].y=ctrl[cnt-1].y;
c[cnt*3-3].z=ctrl[cnt-1].z;
j=1;
for (i=0;i<cnt-1;i++) {
x=ctrl[i].x;
y=ctrl[i].y;
z=ctrl[i].z;
c[j].x=(ctrl[i+1].x-x)/3.0+x;
c[j].y=(ctrl[i+1].y-y)/3.0+y;
c[j].z=(ctrl[i+1].z-z)/3.0+z;
j++;
c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
j+=2;
}
j=3;
for (i=0;i<cnt-2;i++) {
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
j+=3;
}
}
for (i=0;i<cnt*3-3;i+=3) {
if (!Bezier3(aux_data,&c[i],fp_plot,first))
return FALSE;
first=FALSE;
}
Free(c);
return TRUE;
}
#define CC_LEFT 1
#define CC_RIGHT 2
#define CC_TOP 4
#define CC_BOTTOM 8
public Bool ClipLine(I64 *_x1,I64 *_y1,I64 *_x2,I64 *_y2,
I64 left,I64 top,I64 right,I64 bottom)
{//Clip x1,y1 x2,y2 with left,top,right,bottom.
I64 x,y,x1=*_x1,y1=*_y1,x2=*_x2,y2=*_y2,
cc,cc1,cc2;
if (y1>bottom)
cc1=CC_BOTTOM;
else if (y1<top)
cc1=CC_TOP;
else
cc1=0;
if (x1>right)
cc1|=CC_RIGHT;
else if (x1<left)
cc1|=CC_LEFT;
if (y2>bottom)
cc2=CC_BOTTOM;
else if (y2<top)
cc2=CC_TOP;
else
cc2=0;
if (x2>right)
cc2|=CC_RIGHT;
else if (x2<left)
cc2|=CC_LEFT;
while (TRUE) {
if (!(cc1|cc2))
return TRUE;
if (cc1&cc2)
return FALSE;
if (cc1)
cc=cc1;
else
cc=cc2;
if (cc&CC_BOTTOM) {
x=x1+(x2-x1)*(bottom-y1)/(y2-y1);
y=bottom;
} else if (cc&CC_TOP) {
x=x1+(x2-x1)*(top-y1)/(y2-y1);
y=top;
} else if (cc&CC_RIGHT) {
y=y1+(y2-y1)*(right-x1)/(x2-x1);
x=right;
} else {
y=y1+(y2-y1)*(left-x1)/(x2-x1);
x=left;
}
if (cc==cc1) {
*_x1=x1=x;
*_y1=y1=y;
if (y1>bottom)
cc1=CC_BOTTOM;
else if (y1<top)
cc1=CC_TOP;
else
cc1=0;
if (x1>right)
cc1|=CC_RIGHT;
else if (x1<left)
cc1|=CC_LEFT;
} else {
*_x2=x2=x;
*_y2=y2=y;
if (y2>bottom)
cc2=CC_BOTTOM;
else if (y2<top)
cc2=CC_TOP;
else
cc2=0;
if (x2>right)
cc2|=CC_RIGHT;
else if (x2<left)
cc2|=CC_LEFT;
}
}
}
+93
View File
@@ -0,0 +1,93 @@
#help_index "Graphics/Color"
public U8 gr_rainbow_10[10]={
BLACK,BROWN,RED,LTRED,YELLOW,GREEN,BLUE,PURPLE,LTGRAY,WHITE};
DefineLstLoad("ST_RAINBOW_10",
"BLACK\0BROWN\0RED\0LTRED\0YELLOW\0GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
U0 GrPaletteIndicesSet()
{//There is a level of indirection that we identity map.
// Set 16-colors to use first 16 DAC BGR entries, so we
// never need to worry about indexes, just DAC palette settings.
I64 i;
if (!Bt(&sys_run_level,RLf_VGA)) return;
PUSHFD
CLI
while (LBts(&sys_semas[SEMA_VGA],0))
Yield;
InU8(VGAP_INPUT_STAT); //Rsts attr index/data
for (i=0;i<COLORS_NUM;i++) {
OutU8(VGAP_ATTR_INDEX,i);
OutU8(VGAP_ATTR_DATA_WRITE,i);
}
OutU8(VGAP_ATTR_INDEX,0x20);
OutU8(VGAP_ATTR_DATA_WRITE,0); //Dummy write
InU8(VGAP_INPUT_STAT); //Rsts attr index/data
LBtr(&sys_semas[SEMA_VGA],0);
POPFD
}
public U0 GrPaletteColorSet(I64 color_num,CBGR48 bgr48)
{//VGA has 6-bits for blue, for green, and for red.
if (!Bt(&sys_run_level,RLf_VGA)) return;
PUSHFD
CLI
while (LBts(&sys_semas[SEMA_VGA],0))
Yield;
OutU8(VGAP_PALETTE_MASK,0xFF);
OutU8(VGAP_REG_WRITE,color_num);
OutU8(VGAP_PALETTE_DATA,bgr48.r>>10);
OutU8(VGAP_PALETTE_DATA,bgr48.g>>10);
OutU8(VGAP_PALETTE_DATA,bgr48.b>>10);
LBtr(&sys_semas[SEMA_VGA],0);
POPFD
}
public CBGR48 GrPaletteColorGet(I64 color_num)
{//VGA has 6-bits for blue, for green, and for red.
CBGR48 res=0;
if (!Bt(&sys_run_level,RLf_VGA)) return 0;
PUSHFD
CLI
while (LBts(&sys_semas[SEMA_VGA],0))
Yield;
OutU8(VGAP_PALETTE_MASK,0xFF);
OutU8(VGAP_REG_READ,color_num);
res.r=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
res.g=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
res.b=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
LBtr(&sys_semas[SEMA_VGA],0);
POPFD
return res;
}
public CBGR48 gr_palette_std[COLORS_NUM]={
0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
public CBGR48 gr_palette_gray[COLORS_NUM]={
0x000000000000,0x111111111111,0x222222222222,0x333333333333,
0x444444444444,0x555555555555,0x666666666666,0x777777777777,
0x888888888888,0x999999999999,0xAAAAAAAAAAAA,0xBBBBBBBBBBBB,
0xCCCCCCCCCCCC,0xDDDDDDDDDDDD,0xEEEEEEEEEEEE,0xFFFFFFFFFFFF};
public U0 GrPaletteGet(CBGR48 *bgr48)
{//16 colors
I64 i;
for (i=0;i<COLORS_NUM;i++)
bgr48[i]=GrPaletteColorGet(i);
}
public U0 GrPaletteSet(CBGR48 *bgr48)
{//16 colors
I64 i;
for (i=0;i<COLORS_NUM;i++)
GrPaletteColorSet(i,bgr48[i]);
}
public U0 PaletteSetStd()
{//Activate std palette.
GrPaletteSet(gr_palette_std);
}
File diff suppressed because it is too large. Load diff
+423
View File
@@ -0,0 +1,423 @@
#help_index "Graphics/Scrn"
U0 GrUpdateTaskODEs(CTask *task)
{
sys_task_being_scrn_updated=task;
try
ODEsUpdate(task);
catch {
LBts(&task->win_inhibit,WIf_SELF_ODE);
"Exception in WinMgr: Update Task ODEs\n";
PutExcept;
Sleep(3000);
VGAFlush;
}
sys_task_being_scrn_updated=NULL;
}
U0 GrUpdateTaskWin(CTask *task)
{ //Draw a win. Only Core0 tasks have a win.
CDC *dc;
CD3I64 saved_scroll;
sys_task_being_scrn_updated=task;
try {
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
TextBorder(Fs,task->win_left,task->win_right,task->win_top,
task->win_bottom,task->border_attr,task==sys_focus_task);
TextRect(task->win_left,task->win_right,
task->win_top,task->win_bottom,task->text_attr<<8);
if (task==sys_winmgr_task) {
if (gr.fp_wall_paper)
(*gr.fp_wall_paper)(task);
} else if (!(task->win_inhibit&WIF_SELF_DOC))
DocUpdateTaskDocs(task);
if (TaskValidate(task)) {
if (task->draw_it) {
dc=DCAlias(gr.dc2,task);
(*task->draw_it)(task,dc);
DCDel(dc);
}
if (TaskValidate(task)) {
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: Update Task Win\n";
PutExcept;
Sleep(3000);
VGAFlush;
}
}
sys_task_being_scrn_updated=NULL;
}
U0 GrUpdateTasks()
{//Only called by WinMgr
I64 i;
CTask *task,*task1;
try {
winmgr.ode_time=0;
if (Bt(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0))
WinZBufUpdate;
task1=task=sys_winmgr_task;
do { //Loop through Core0 tasks.
if (!TaskValidate(task)) break;
if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
Bt(gr.win_uncovered_bitmap,task->win_z_num))
GrUpdateTaskWin(task);
if (!TaskValidate(task)) break;
task=task->next_task;
} while (task!=task1);
for (i=0;i<mp_cnt;i++) { //Loop through all cores.
task1=task=cpu_structs[i].seth_task;
do {
if (!TaskValidate(task)) break;
GrUpdateTaskODEs(task);
if (!TaskValidate(task)) break;
task=task->next_task;
} while (task!=task1);
}
} catch {
PutExcept(FALSE);
Dbg("Exception in WinMgr");
}
winmgr.last_ode_time=winmgr.ode_time;
ode_alloced_factor=LowPass1(0.1,ode_alloced_factor,
Clamp(Gs->idle_factor-0.1,0.2,0.8),1/winmgr.fps);
sys_task_being_scrn_updated=NULL;
}
U0 GrFixZoomScale()
{
gr.scrn_zoom=ClampI64(gr.scrn_zoom,1,GR_SCRN_ZOOM_MAX);
if (gr.scrn_zoom==1) {
gr.sx=0;
gr.sy=0;
} else {
gr.sx=ClampI64(gr.sx,0,GR_WIDTH-GR_WIDTH/gr.scrn_zoom)&~7;
gr.sy=ClampI64(gr.sy,0,GR_HEIGHT-GR_HEIGHT/gr.scrn_zoom);
}
}
public U0 GrScaleZoom(F64 scale)
{//Multiply zoom factor larger or smaller.
F64 s=gr.scrn_zoom;
gr.scrn_zoom=gr.scrn_zoom*scale;
GrFixZoomScale;
s/=gr.scrn_zoom;
ms.scale.x*=s;
ms.scale.y*=s;
ms.scale.z*=s;
ms.offset.x=ms.pos.x-(ms.pos.x-ms.offset.x)*s;
ms.offset.y=ms.pos.y-(ms.pos.y-ms.offset.y)*s;
ms.offset.z=ms.pos.z-(ms.pos.z-ms.offset.z)*s;
gr.sx=ms.pos.x-gr.zoomed_dc->width >>1/gr.scrn_zoom;
gr.sy=ms.pos.y-gr.zoomed_dc->height>>1/gr.scrn_zoom;
GrFixZoomScale;
}
U0 GrZoomInScrn()
{
GrFixZoomScale;
I64 plane,row,col,k,l,
d2=gr.zoomed_dc->width>>3/gr.scrn_zoom,
d4=gr.zoomed_dc->width_internal>>3,
d5=d4-d2*gr.scrn_zoom,
d3=gr.zoomed_dc->height/gr.scrn_zoom,
d6=(gr.zoomed_dc->height-d3)*gr.dc1->width_internal>>3,
d7=gr.zoomed_dc->height%gr.scrn_zoom*d4;
U8 *src,*src2,*dst,*src3,*map=gr.scrn_zoom_tables[gr.scrn_zoom];
src=gr.dc1->body+gr.sx>>3+gr.sy*gr.dc1->width_internal>>3;
dst=gr.zoomed_dc->body;
for (plane=1;plane<0x10;plane<<=1) {
row=d3;
while (row--) {
k=gr.scrn_zoom;
while (k--) {
src2=src;
col=d2;
while (col--) {
src3=&map[*src2++];
l=gr.scrn_zoom;
while (l--) {
*dst++=*src3;
src3+=256;
}
}
l=d5;
while (l--)
*dst++=0;
}
src+=d4;
}
l=d7;
while (l--)
*dst++=0;
src+=d6;
}
}
U0 GrUpdateTextBG()
{
I64 reg RSI *dst=gr.dc2->body,reg R13 c,row,col,
num_rows=TEXT_ROWS,num_cols=TEXT_COLS,i,j,cur_ch,
reg R12 w1=gr.dc2->width_internal,w2=-7*w1+8,w3=7*w1,w4=0;
U32 *src=gr.text_base;
Bool blink_flag=Blink;
U8 *dst2=dst;
if (gr.pan_text_x||gr.hide_col) {
gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
num_cols-=j;
if (gr.pan_text_x<0) {
src+=j;
i=FONT_WIDTH*j+gr.pan_text_x;
} else
i=gr.pan_text_x;
dst2=dst(U8 *)+i;
w4=j;
w3+=j*FONT_WIDTH;
j*=FONT_WIDTH;
dst(U8 *)=gr.dc2->body;
for (row=num_rows*FONT_HEIGHT;row--;) {
for (col=i;col--;)
*dst(U8 *)++=0;
dst(U8 *)+=w1-i-j;
for (col=j;col--;)
*dst(U8 *)++=0;
}
}
dst=dst2;
if (gr.pan_text_y||gr.hide_row) {
gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
num_rows-=j;
if (gr.pan_text_y<0) {
src+=w1/FONT_WIDTH*j;
i=w1*(FONT_HEIGHT*j+gr.pan_text_y);
} else
i=w1*gr.pan_text_y;
dst2=dst(U8 *)+i;
j*=w1*FONT_HEIGHT;
dst(U8 *)=gr.dc2->body;
for (row=i;row--;)
*dst(U8 *)++=0;
dst(U8 *)=gr.dc2->body+TEXT_ROWS*TEXT_COLS*FONT_HEIGHT*FONT_WIDTH-j;
for (row=j;row--;)
*dst(U8 *)++=0;
}
dst=dst2;
for (row=num_rows;row--;) {
for (col=num_cols;col--;) {
cur_ch=*src++;
if (cur_ch & (ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & ATTRF_BLINK && blink_flag)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
}
c=gr.to_8_colors[cur_ch.u8[1]>>4];
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
dst(U8 *)+=w2;
}
src+=w4;
dst(U8 *)+=w3;
}
}
U0 GrUpdateTextFG()
{//See $LK,"TextBase Layer",A="HI:TextBase Layer"$.
U32 *src=gr.text_base;
I64 i,j,cur_ch,*dst=gr.dc2->body,
w1=gr.dc2->width_internal,w2=7*w1,w4=0,
num_rows=TEXT_ROWS,num_cols=TEXT_COLS,row,col;
U8 *dst_start=gr.dc2->body,*dst_end=dst_start+w1*gr.dc2->height-7*w1-8;
Bool blink_flag=Blink;
if (gr.pan_text_x||gr.hide_col) {
gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
num_cols-=j;
if (gr.pan_text_x<0) {
src+=j;
dst(U8 *)+=FONT_WIDTH*j;
}
w4=j;
w2+=j*FONT_WIDTH;
}
if (gr.pan_text_y||gr.hide_row) {
gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
num_rows-=j;
if (gr.pan_text_y<0) {
src+=w1/FONT_WIDTH*j;
dst(U8 *)+=w1*FONT_HEIGHT*j;
}
}
for (row=num_rows;row--;) {
for (col=num_cols;col--;) {
cur_ch=*src++;
if (cur_ch & (ATTRF_UNDERLINE|ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & ATTRF_BLINK && blink_flag)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
}
if (i=cur_ch.u16[1]&0x3FF+gr.pan_text_x+gr.pan_text_y<<5) {
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&(ATTRF_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
} else
GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst,w1);
dst(U8 *)+=8;
}
src+=w4;
dst(U8 *)+=w2;
}
}
U0 DCBlotColor8(CDC *dc,CDC *img)
{
U8 *src=img->body,*b0=dc->body;
I64 j,k,d0=img->width_internal*img->height;
for (k=0;k<d0;k++) {
j=*src++;
if (j!=TRANSPARENT)
*b0++=j;
else
b0++;
}
}
U0 GrUpdateTextModeText()
{
U32 *src=gr.text_base;
I64 cur_ch,i=TEXT_COLS*TEXT_ROWS;
U16 *dst=text.vga_text_alias,*dst2=gr.vga_text_cache;
Bool blink_flag=Blink;
if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
while (i--) {
cur_ch=*src++;
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & ATTRF_BLINK)
if (blink_flag)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
*dst++=*dst2++=cur_ch&0x7FFF;
}
} else {
while (i--) {
cur_ch=*src++;
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & ATTRF_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()
{//Update Graphic Card
I64 row,plane,d=gr.zoomed_dc->width_internal>>6;
U32 *src,*vga,*dst;
if (gr.scrn_zoom==1)
src=gr.dc1->body;
else {
GrZoomInScrn;
src=gr.zoomed_dc->body;
}
dst=gr.scrn_image->body;
if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGAP_IDX,VGAR_MAP_MASK);
OutU8(VGAP_DATA,plane);
vga=text.vga_alias;
row=gr.zoomed_dc->height;
while (row--)
GrUpdateLine64FlushCache(&vga,&src,d,&dst);
}
} else {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGAP_IDX,VGAR_MAP_MASK);
OutU8(VGAP_DATA,plane);
vga=text.vga_alias;
row=gr.zoomed_dc->height;
while (row--)
GrUpdateLine64(&vga,&src,d,&dst);
}
}
}
U0 GrUpdateScrn()
{//Called by the Window Manager $LK,"HERE",A="FF:::/Adam/WinMgr.HC,GrUpdateScrn"$, 30 times a second.
CDC *dc;
if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
GrUpdateTasks;
else {
GrUpdateTextBG;
GrUpdateTextFG;
GrUpdateTasks;
DCBlotColor8(gr.dc2,gr.dc);
}
dc=DCAlias(gr.dc2,Fs);
dc->flags|=DCF_ON_TOP;
if (gr.fp_final_scrn_update)
(*gr.fp_final_scrn_update)(dc);
DCDel(dc);
if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
GrUpdateTextModeText;
else {
DCBlotColor4(gr.dc1->body,gr.dc2->body,gr.dc_cache->body,
gr.dc2->height*gr.dc2->width_internal>>3);
GrUpdateVGAGraphics;
}
}
+475
View File
@@ -0,0 +1,475 @@
#help_index "Graphics/Sprite;Sprites"
/*
$LK,"CSprite",A="MN:CSprite"$s are stored as a sequence of var
length operations with a 1-byte $LK,"type",A="MN:SPT_PT"$ leading
each operation. They are stored, one after another,
in a chunk of memory terminated by a $LK,"zero",A="MN:SPT_END"$.
$LK,"Sprite3",A="MN:Sprite3"$() shows how the $LK,"CSprite",A="MN:CSprite"$ unions are used.
$LK,"SpriteElemSize",A="MN:SpriteElemSize"$() will return the size of a single
element, while $LK,"SpriteSize",A="MN:SpriteSize"$() will return the size
of an entire list. Look at $LK,"sprite_elem_base_sizes",A="MN:sprite_elem_base_sizes"$.
See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$ for an example of
making CSprite by hand. It uses $LK,"SPT_MESH",A="MN:SPT_MESH"$,
one of the most complicated.
*/
public U0 Sprite3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,
Bool just_one_elem=FALSE)
{//Plot a sprite into a CDC.
CSprite *tmpg=elems-offset(CSprite.start);
I64 i,j,k,x1,y1,z1,x2,y2,
*old_r,*r2,old_flags=dc->flags,old_pen_width=dc->pen_width;
I32 *ptr;
CColorROPU32 old_color=dc->color;
CDC *img;
CD3I32 *p,*p2;
CGrSym old_sym;
MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
if (dc->flags & DCF_LOCATE_NEAREST)
dc->nearest_dist=I64_MAX;
while (tmpg->type&SPG_TYPE_MASK) {
switch (tmpg->type&SPG_TYPE_MASK) {
case SPT_COLOR:
dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tmpg->c.color;
break;
case SPT_DITHER_COLOR:
dc->color=dc->color&~COLORROP_COLORS_MASK|
tmpg->d.dither_color.u8[0]|
tmpg->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
break;
case SPT_WIDTH:
dc->pen_width=tmpg->w.width;
DCPenWidthScale(dc);
break;
case SPT_TRANSFORM_ON:
if (!(dc->flags&DCF_TRANSFORMATION)) {
x-=dc->x;
y-=dc->y;
z-=dc->z;
}
dc->flags|=DCF_TRANSFORMATION;
break;
case SPT_TRANSFORM_OFF:
if (dc->flags&DCF_TRANSFORMATION) {
x+=dc->x;
y+=dc->y;
z+=dc->z;
}
dc->flags&=~DCF_TRANSFORMATION;
break;
case SPT_PT:
GrPlot3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z);
break;
case SPT_TEXT:
GrPrint3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,"%s",tmpg->ps.st);
break;
case SPT_TEXT_BOX:
GrTextBox3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
break;
case SPT_TEXT_DIAMOND:
GrTextDiamond3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
break;
case SPT_FLOOD_FILL:
GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,FALSE);
break;
case SPT_FLOOD_FILL_NOT:
i=dc->color;
dc->color=dc->color.c0;
GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,TRUE);
dc->color=i;
break;
case SPT_SHIFT:
x+=tmpg->p.x1;
y+=tmpg->p.y1;
break;
case SPT_LINE:
GrLine3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
tmpg->pp.x2+x,tmpg->pp.y2+y,z);
break;
case SPT_ARROW:
GrArrow3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
tmpg->pp.x2+x,tmpg->pp.y2+y,z);
break;
case SPT_PLANAR_SYMMETRY:
if (DCSymmetry3Set(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
tmpg->pp.x2+x,tmpg->pp.y2+y,z,
tmpg->pp.x2+x,tmpg->pp.y2+y,z+1))
dc->flags|=DCF_SYMMETRY;
else
dc->flags&=~DCF_SYMMETRY;
break;
case SPT_BITMAP:
img=CAlloc(sizeof(CDC));
img->width=tmpg->pwhu.width;
img->width_internal=(tmpg->pwhu.width+7)&~7;
img->height=tmpg->pwhu.height;
img->body=&tmpg->pwhu.u;
img->dc_signature=DCS_SIGNATURE_VAL;
GrBlot3(dc,tmpg->pwhu.x1+x,tmpg->pwhu.y1+y,z,img);
Free(img);
break;
case SPT_RECT:
GrRect3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
break;
case SPT_ROTATED_RECT:
x1=tmpg->ppa.x1+x;
y1=tmpg->ppa.y1+y;
z1=z;
Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
old_r=dc->r;
dc->flags|=DCF_TRANSFORMATION;
r2=Mat4x4IdentNew;
Mat4x4RotZ(r2,-tmpg->ppa.angle);
Mat4x4TranslationEqu(r2,x1,y1,z1);
DCMat4x4Set(dc,Mat4x4MulMat4x4New(old_r,r2));
GrRect3(dc,0,0,0,
tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1);
Free(dc->r);
Free(r2);
DCMat4x4Set(dc,old_r);
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
break;
case SPT_CIRCLE:
GrCircle3(dc,tmpg->pr.x1+x,tmpg->pr.y1+y,z,tmpg->pr.radius);
break;
case SPT_ELLIPSE:
GrEllipse3(dc,tmpg->pwha.x1+x,tmpg->pwha.y1+y,z,tmpg->pwha.width,
tmpg->pwha.height,tmpg->pwha.angle);
break;
case SPT_POLYGON:
GrRegPoly3(dc,tmpg->pwhas.x1+x,tmpg->pwhas.y1+y,z,tmpg->pwhas.width,
tmpg->pwhas.height,tmpg->pwhas.sides,tmpg->pwhas.angle);
break;
case SPT_POLYLINE:
ptr=&tmpg->nu.u;
x1=ptr[0];
y1=ptr[1];
for (i=1;i<tmpg->nu.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 SPT_POLYPT:
x1=tmpg->npu.x;
y1=tmpg->npu.y;
ptr=&tmpg->npu.u;
k=tmpg->npu.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;
start:
p2=p=MAlloc(tmpg->nu.num*sizeof(CD3I32));
MemCpy(p,&tmpg->nu.u,tmpg->nu.num*sizeof(CD3I32));
for (i=0;i<tmpg->nu.num;i++,p2++) {
p2->x+=x;
p2->y+=y;
p2->z+=z;
}
case SPT_BSPLINE2:
Gr2BSpline3(dc,p,tmpg->nu.num,FALSE);
break;
case SPT_BSPLINE3:
Gr3BSpline3(dc,p,tmpg->nu.num,FALSE);
break;
case SPT_BSPLINE2_CLOSED:
Gr2BSpline3(dc,p,tmpg->nu.num,TRUE);
break;
case SPT_BSPLINE3_CLOSED:
Gr3BSpline3(dc,p,tmpg->nu.num,TRUE);
break;
end:
Free(p);
break;
case SPT_MESH:
p2=p=MAlloc(tmpg->mu.vertex_cnt*sizeof(CD3I32));
MemCpy(p,&tmpg->mu.u,tmpg->mu.vertex_cnt*sizeof(CD3I32));
for (i=0;i<tmpg->mu.vertex_cnt;i++,p2++) {
p2->x+=x;
p2->y+=y;
p2->z+=z;
}
Gr3Mesh(dc,tmpg->mu.vertex_cnt,p,tmpg->mu.tri_cnt,
(&tmpg->mu.u)(U8 *)+sizeof(CD3I32)*tmpg->mu.vertex_cnt);
Free(p);
break;
case SPT_SHIFTABLE_MESH:
if (dc->flags&DCF_TRANSFORMATION) {
dc->x+=tmpg->pmu.x;
dc->y+=tmpg->pmu.y;
dc->z+=tmpg->pmu.z;
x1=x;
y1=y;
z1=z;
} else {
x1=tmpg->pmu.x+x;
y1=tmpg->pmu.y+y;
z1=tmpg->pmu.z+z;
}
p2=p=MAlloc(tmpg->pmu.vertex_cnt*sizeof(CD3I32));
MemCpy(p,&tmpg->pmu.u,tmpg->pmu.vertex_cnt*sizeof(CD3I32));
for (i=0;i<tmpg->pmu.vertex_cnt;i++,p2++) {
p2->x+=x1;
p2->y+=y1;
p2->z+=z1;
}
Gr3Mesh(dc,tmpg->pmu.vertex_cnt,p,tmpg->pmu.tri_cnt,
(&tmpg->pmu.u)(U8 *)+sizeof(CD3I32)*tmpg->pmu.vertex_cnt);
Free(p);
if (dc->flags&DCF_TRANSFORMATION) {
dc->x-=tmpg->pmu.x;
dc->y-=tmpg->pmu.y;
dc->z-=tmpg->pmu.z;
}
break;
}
if (just_one_elem) break;
tmpg(U8 *)+=SpriteElemSize(tmpg);
}
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 Sprite3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems)
{//Plot a sprite into a CDC, post transform xyz translation.
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;
Sprite3(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 Sprite3Mat4x4B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
{//Plot rotated by matrix.
I64 r[16],*old_r=dc->r,new_m[16],
old_flags=dc->flags&DCF_TRANSFORMATION;
MemCpy(new_m,m,16*sizeof(I64));
dc->flags|=DCF_TRANSFORMATION;
Mat4x4TranslationAdd(new_m,x,y,z);
dc->r=Mat4x4MulMat4x4Equ(r,old_r,new_m);
Sprite3(dc,0,0,0,elems);
dc->r=old_r;
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
}
public U0 Sprite3XB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 è=0)
{//Plot rotated around X axis.
I64 r[16];
Mat4x4IdentEqu(r);
Mat4x4RotX(r,è);
Sprite3Mat4x4B(dc,x,y,z,elems,r);
}
public U0 Sprite3YB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 ê=0)
{//Plot rotated around Y axis.
I64 r[16];
Mat4x4IdentEqu(r);
Mat4x4RotY(r,ê);
Sprite3Mat4x4B(dc,x,y,z,elems,r);
}
public U0 Sprite3ZB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 é=0)
{//Plot rotated around Z axis.
I64 r[16];
Mat4x4IdentEqu(r);
Mat4x4RotZ(r,é);
Sprite3Mat4x4B(dc,x,y,z,elems,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(I32_MAX,I32_MAX,Fs,TRUE);
DCExtentsInit(dc);
Sprite3(dc,I32_MAX/2,I32_MAX/2,I32_MAX/2,elems);
if (dc->min_x<=dc->max_x) {
dc->min_x-=I32_MAX/2;
dc->max_x-=I32_MAX/2;
}
if (dc->min_y<=dc->max_y) {
dc->min_y-=I32_MAX/2;
dc->max_y-=I32_MAX/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)
{//Convert sprite to device context.
CDC *res;
I64 min_x,max_x,min_y,max_y;
SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
res=DCNew(max_x-min_x+1,max_y-min_y+1);
Sprite3(res,-min_x,-min_y,0,elems);
return res;
}
public U8 *SpriteInterpolate(F64 t,U8 *elems0,U8 *elems1)
{//The two CSprite should be ident except for points shifted around.
//t ranges from 0.0 to 1.0.
I64 i,t1=GR_SCALE*t,t0=GR_SCALE-t1;
I32 *ptr0,*ptr1,*ptrr;
CD3I32 *p0,*p1,*pr;
U8 *res;
CSprite *tmpg0=elems0-offset(CSprite.start),
*tmpg1=elems1-offset(CSprite.start),*tmpgr;
if (t<0.5) {
i=SpriteSize(elems0),
res=MAlloc(i);
MemCpy(res,elems0,i);
} else {
i=SpriteSize(elems1),
res=MAlloc(i);
MemCpy(res,elems1,i);
}
tmpgr=res-offset(CSprite.start);
while (tmpg0->type&SPG_TYPE_MASK) {
if (tmpg0->type&SPG_TYPE_MASK!=tmpg1->type&SPG_TYPE_MASK)
throw('Graphics');
switch (tmpg0->type&SPG_TYPE_MASK) {
case SPT_ROTATED_RECT:
tmpgr->ppa.angle=(tmpg0->ppa.angle*t0+tmpg1->ppa.angle*t1)/GR_SCALE;
case SPT_RECT:
case SPT_LINE:
case SPT_ARROW:
case SPT_PLANAR_SYMMETRY:
tmpgr->pp.x2=(tmpg0->pp.x2*t0+tmpg1->pp.x2*t1)>>32;
tmpgr->pp.y2=(tmpg0->pp.y2*t0+tmpg1->pp.y2*t1)>>32;
case SPT_TEXT:
case SPT_TEXT_BOX:
case SPT_TEXT_DIAMOND:
case SPT_PT:
case SPT_FLOOD_FILL:
case SPT_FLOOD_FILL_NOT:
case SPT_SHIFT:
tmpgr->p.x1=(tmpg0->p.x1*t0+tmpg1->p.x1*t1)>>32;
tmpgr->p.y1=(tmpg0->p.y1*t0+tmpg1->p.y1*t1)>>32;
break;
case SPT_CIRCLE:
tmpgr->pr.radius=(tmpg0->pr.radius*t0+tmpg1->pr.radius*t1)>>32;
tmpgr->pr.x1=(tmpg0->pr.x1*t0+tmpg1->pr.x1*t1)>>32;
tmpgr->pr.y1=(tmpg0->pr.y1*t0+tmpg1->pr.y1*t1)>>32;
break;
case SPT_ELLIPSE:
case SPT_POLYGON:
tmpgr->pwha.x1=(tmpg0->pwha.x1*t0+tmpg1->pwha.x1*t1)>>32;
tmpgr->pwha.y1=(tmpg0->pwha.y1*t0+tmpg1->pwha.y1*t1)>>32;
tmpgr->pwha.width =(tmpg0->pwha.width *t0+tmpg1->pwha.width*t1)>>32;
tmpgr->pwha.height=(tmpg0->pwha.height*t0+tmpg1->pwha.height*t1)>>32;
break;
case SPT_BITMAP:
tmpgr->pwhu.x1=(tmpg0->pwhu.x1*t0+tmpg1->pwhu.x1*t1)>>32;
tmpgr->pwhu.y1=(tmpg0->pwhu.y1*t0+tmpg1->pwhu.y1*t1)>>32;
break;
case SPT_POLYLINE:
ptr0=&tmpg0->nu.u;
ptr1=&tmpg1->nu.u;
ptrr=&tmpgr->nu.u;
for (i=0;i<tmpg0->nu.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 SPT_POLYPT:
tmpgr->npu.x=(tmpg0->npu.x*t0+tmpg1->npu.x*t1)>>32;
tmpgr->npu.y=(tmpg0->npu.y*t0+tmpg1->npu.y*t1)>>32;
break;
case SPT_BSPLINE2:
case SPT_BSPLINE3:
case SPT_BSPLINE2_CLOSED:
case SPT_BSPLINE3_CLOSED:
p0=&tmpg0->nu.u;
p1=&tmpg1->nu.u;
pr=&tmpgr->nu.u;
for (i=0;i<tmpg0->nu.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 SPT_MESH:
p0=&tmpg0->mu.u;
p1=&tmpg1->mu.u;
pr=&tmpgr->mu.u;
for (i=0;i<tmpg0->mu.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 SPT_SHIFTABLE_MESH:
p0=&tmpg0->pmu.u;
p1=&tmpg1->pmu.u;
pr=&tmpgr->pmu.u;
for (i=0;i<tmpg0->pmu.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;
}
tmpg0(U8 *)+=SpriteElemSize(tmpg0);
tmpg1(U8 *)+=SpriteElemSize(tmpg1);
tmpgr(U8 *)+=SpriteElemSize(tmpgr);
}
return res;
}
#help_index "Graphics/Sprite;DolDoc/Output;StdOut/DolDoc"
public CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL)
{//Put a sprite into a document. You can, optionally, supply a fmt string
//for $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.DD"$ cmd with a %d for the bin_num.
I64 size;
U8 *st;
Bool unlock;
CDocEntry *doc_e;
CDocBin *tmpb;
if (!doc && !(doc=DocPut)) return NULL;
unlock=DocLock(doc);
size=SpriteSize(elems);
tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
tmpb->size=size;
tmpb->data=MAlloc(size,doc->mem_task);
MemCpy(tmpb->data,elems,size);
tmpb->num=doc->cur_bin_num;
tmpb->use_cnt=1;
QueIns(tmpb,doc->bin_head.last);
if (fmt)
st=MStrPrint(fmt,doc->cur_bin_num++);
else
st=MStrPrint("$$SP,\"\",BI=%d$$",doc->cur_bin_num++);
doc_e=DocPrint(doc,"%s",st);
Free(st);
doc_e->bin_data=tmpb;
if (doc_e && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
if (unlock)
DocUnlock(doc);
return doc_e;
}
public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)
{//Put sprite to the command-line, $LK,"DocPut",A="MN:DocPut"$.
//If you set fmt, then include dollars ("$$SP ...$$") and leave %d for num.
CDoc *doc;
if (doc=DocPut)
return DocSprite(doc,elems,fmt);
return NULL;
}
+363
View File
@@ -0,0 +1,363 @@
#help_index "TextBase Layer;Char/TextBase Layer"
#help_file "::/Doc/TextBase"
asm {
//************************************
_TEXT_CHAR::
//Bool TextChar(CTask *task,Bool allow_border=FALSE,I64 x,I64 y,I64 d);
//Must be called 30fps in Fs->draw_it() callback.
PUSH RBP
MOV RBP,RSP
MOV RCX,U64 SF_ARG1[RBP]
MOV RBX,U64 CTask.scroll_x[RCX]
SAR RBX,3
ADD RBX,U64 SF_ARG3[RBP]
MOV RAX,U64 CTask.scroll_y[RCX]
SAR RAX,3
ADD RAX,U64 SF_ARG4[RBP]
TEST U8 SF_ARG2[RBP],0xFF
JNZ @@10
//Border not allowed
TEST RBX,RBX //Check X
JS @@05
ADD RBX,U64 CTask.win_left[RCX]
CMP RBX,U64 CTask.win_right[RCX]
JG @@05
TEST RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
TEST RAX,RAX //Check Y
JS @@05
ADD RAX,U64 CTask.win_top[RCX]
CMP RAX,U64 CTask.win_bottom[RCX]
JG @@05
TEST RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
JMP @@15
@@05: XOR RAX,RAX //return FALSE
POP RBP
RET1 40
//Border allowed
@@10: MOV RDX,-1 //Check X
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
TEST RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
MOV RDX,-1 //Check Y
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
TEST RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
@@15: IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr.text_base]
MOV RAX,U64 SF_ARG5[RBP]
MOV U32 [RBX],EAX
MOV RAX,TRUE
POP RBP
RET1 40
//************************************
_TEXT_LEN_STR::
//Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,I64 attr,U8 *s)
//Must be called 30fps in Fs->draw_it() callback.
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG6[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG2[RBP]
MOV RCX,U64 SF_ARG4[RBP]
TEST 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: TEST 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.scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG3[RBP]
TEST RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
TEST RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,U64 [&gr.text_base]
MOV RAX,U64 SF_ARG5[RBP]
@@25: LODSB
STOSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
POP RBP
RET1 48
@@30: POP RDI
POP RSI
XOR RAX,RAX
POP RBP
RET1 48
//************************************
_TEXT_LEN_ATTR_STR::
//Bool TextLenAttrStr(CTask *task,I64 x,I64 y,I64 len,U32 *_attr)
//Must be called 30fps in Fs->draw_it() callback.
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG5[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG2[RBP]
MOV RCX,U64 SF_ARG4[RBP]
TEST 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: TEST 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.scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG3[RBP]
TEST RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
TEST RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,U64 [&gr.text_base]
@@25: MOVSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
POP RBP
RET1 40
@@30: POP RDI
POP RSI
XOR RAX,RAX
POP RBP
RET1 40
//************************************
_TEXT_LEN_ATTR:://Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,I64 attr)
//Must be called 30fps in Fs->draw_it() callback.
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG2[RBP]
MOV RCX,U64 SF_ARG4[RBP]
TEST 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: TEST 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.scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG3[RBP]
TEST RAX,RAX
JS @@35
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@35
TEST RAX,RAX
JS @@35
CMP RAX,TEXT_ROWS
JGE @@35
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,U64 [&gr.text_base]
MOV RBX,U64 SF_ARG5[RBP]
MOV RSI,RDI
@@25: LODSD
TEST AL,AL
JNZ @@30
MOV RAX,RBX
STOSD
DEC RCX
JNZ @@25
@@30: POP RDI
POP RSI
MOV RAX,TRUE
POP RBP
RET1 40
@@35: POP RDI
POP RSI
XOR RAX,RAX
POP RBP
RET1 40
}
public _extern _TEXT_CHAR Bool TextChar(CTask *task,Bool allow_border=FALSE,
I64 x,I64 y,I64 d); //Plot char. 30fps in Fs->draw_it() callback.
public _extern _TEXT_LEN_STR Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,
I64 attr,U8 *s); //Plot str with len. 30fps in Fs->draw_it() callback.
public _extern _TEXT_LEN_ATTR_STR Bool TextLenAttrStr(CTask *task,I64 x,I64 y,
I64 len,U32 *_attr); //Plot attr str with len. 30fps in Fs->draw_it() callback.
public _extern _TEXT_LEN_ATTR Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,
I64 attr); //Plot attrs with len. 30fps in Fs->draw_it() callback.
public U0 TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...)
{//Plot chars. 30fps in Fs->draw_it() callback.
//You probably want $LK,"GrPrint",A="MN:GrPrint"$() or just $LK,"Print",A="MN:Print"$().
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
TextLenStr(task,x,y,StrLen(buf),attr<<8,buf);
Free(buf);
}
public U0 TextBorder(CTask *task=NULL,
I64 l,I64 r,I64 t,I64 b,I64 attr,Bool solid)
{//Plot border square. 30fps in Fs->draw_it() callback.
//Draws window borders or DolDoc text bttn borders.
//Set task=sys_winmgr_task for no clipping.
I64 i;
if (!task) task=Fs;
attr<<=8;
TextChar(task,,l-1,t-1,text.border_chars[6+solid]+attr);
TextChar(task,,r+1,t-1,text.border_chars[8+solid]+attr);
TextChar(task,,l-1,b+1,text.border_chars[10+solid]+attr);
TextChar(task,,r+1,b+1,text.border_chars[12+solid]+attr);
for (i=l;i<=r;i++) {
TextChar(task,,i,t-1,text.border_chars[2+solid]+attr);
TextChar(task,,i,b+1,text.border_chars[2+solid]+attr);
}
for (i=t;i<=b;i++) {
TextChar(task,,l-1,i,text.border_chars[4+solid]+attr);
TextChar(task,,r+1,i,text.border_chars[4+solid]+attr);
}
}
public U0 TextRect(I64 l,I64 r,I64 t,I64 b,I64 d)
{//Fill text rect. 30fps in Fs->draw_it() callback.
I64 y,w;
if (l>r || t>b) return;
if (t<0) t=0;
if (b>=TEXT_ROWS) b=TEXT_ROWS-1;
if (l<0) l=0;
if (r>=TEXT_COLS) r=TEXT_COLS-1;
if (w=r-l+1)
for (y=t;y<=b;y++)
MemSetU32(gr.text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),d,w);
}
+31
View File
@@ -0,0 +1,31 @@
Cd(__DIR__);;
#include "GrInitA"
#include "Gr.HH"
#include "GrExt"
#include "GrGlbls"
#include "GrTextBase"
#include "GrAsm"
#include "GrPalette"
#include "GrDC"
#include "GrInitB"
#include "GrMath"
#include "GrScrn"
#include "GrBitMap"
#include "GrPrimatives"
#include "GrComposites"
#define SPE_ABORT (-1)
#define SPE_EXIT 0
#define SPE_CONT 1
#include "SpriteNew"
#include "GrSpritePlot"
#include "SpriteMesh"
#include "SpriteBitMap"
#include "SpriteCode"
#include "SpriteEd"
#include "SpriteMain"
#include "GrEnd"
Cd("..");;
+677
View File
@@ -0,0 +1,677 @@
#help_index "Graphics/Sprite;Sprites"
#define SPBM_EXIT 0
#define SPBM_MAIN_MENU 1
#define SPBM_COLOR 2
#define SPBM_DITHER_COLOR 3
#define SPBM_WIDTH 4
#define SPBM_PT 5
#define SPBM_LINE 6
#define SPBM_ARROW 7
#define SPBM_RECT 8
#define SPBM_CIRCLE 9
#define SPBM_TEXT 10
#define SPBM_TEXT_BOX 11
#define SPBM_TEXT_DIAMOND 12
#define SPBM_FLOOD_FILL 13
#define SPBM_FLOOD_FILL_NOT 14
#define SPBM_POLYLINE 15
#define SPBM_POLYPT 16
#define SPBM_COPY 17
#define SPBM_DELETE 18
#define SPBM_PASTE 19
#define SPBM_PASTE_TRANSPARENT 20
#define SPBM_FIND_AND_REPLACE 21
#define SPBM_TRIM_TO_EXTENTS 22
#define SPBM_ADD_OUTLINE 23
#define SPBM_ETCH 24
#define SPBM_UNDO 25
#define SPBM_SAVE_BMP 26
#define SPBM_SAVE_GRA 27
U0 GrInit4()
{
DefineLstLoad("ST_SPRITE_BITMAP_MENU",
"Exit\0Main Menu\0Color\0Dither Color\0Width\0Point\0Line\0Arrow\0"
"Rect\0Circle\0Text\0Text Box\0Text Diamond\0Flood Fill\0"
"Flood Fill Not Color\0PolyLine\0PolyPoint\0Copy\0Delete\0Paste\0"
"Paste Transparent\0Find and Replace\0Trim to Extents\0Add Outline\0"
"Etch\0Undo\0Save BMP\0Save GR\0");
}
GrInit4;
I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width)
{
I64 i;
U8 *st1,*st2,buf[STR_LEN];
CDoc *doc=DocNew;
Color2Str(buf,color);
if (color&ROPF_DITHER) {
st1="";
st2=buf;
} else {
st1=buf;
st2="";
}
DocPrint(doc,"$$PURPLE$$$$TX+CX,\"Sprite BitMap Menu\"$$\n"
"$$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteBitMap.DD.Z\"$$\n"
"\n$$LTBLUE$$$$MU-UL,\"Color %s\",LE=SPBM_COLOR$$\n"
"$$MU-UL,\"Dither Color %s\",LE=SPBM_DITHER_COLOR$$\n"
"$$MU-UL,\"Width %d\",LE=SPBM_WIDTH$$\n"
"$$MU-UL,\"Find & Replace Color\",LE=SPBM_FIND_AND_REPLACE$$\n"
"$$MU-UL,\"Trim to Extents\",LE=SPBM_TRIM_TO_EXTENTS$$\n"
"$$MU-UL,\"Add Outline\",LE=SPBM_ADD_OUTLINE$$\n"
"$$MU-UL,\"Etch\",LE=SPBM_ETCH$$\n"
"\n$$MU-UL,\"Point\",LE=SPBM_PT$$\n"
"$$MU-UL,\"Line\",LE=SPBM_LINE$$\n"
"$$MU-UL,\"Arrow\",LE=SPBM_ARROW$$\n"
"$$MU-UL,\"Rect\",LE=SPBM_RECT$$\n"
"$$MU-UL,\"Circle\",LE=SPBM_CIRCLE$$\n"
"$$MU-UL,\"Text\",LE=SPBM_TEXT$$\n"
"$$MU-UL,\"Text Box\",LE=SPBM_TEXT_BOX$$\n"
"$$MU-UL,\"Text Diamond\",LE=SPBM_TEXT_DIAMOND$$\n"
"$$MU-UL,\"Flood Fill\",LE=SPBM_FLOOD_FILL$$\n"
"$$MU-UL,\"Flood Fill Not Color\",LE=SPBM_FLOOD_FILL_NOT$$\n"
"$$MU-UL,\"PolyLine\",LE=SPBM_POLYLINE$$\n"
"$$MU-UL,\"PolyPoint\",LE=SPBM_POLYPT$$\n"
"\n$$MU-UL,\"Copy to Clipboard\",LE=SPBM_COPY$$\n"
"$$MU-UL,\"Delete to Clipboard\",LE=SPBM_DELETE$$\n"
"$$MU-UL,\"Paste Clipboard\",LE=SPBM_PASTE$$\n"
"$$MU-UL,\"Paste Transparent Clipboard\",LE=SPBM_PASTE_TRANSPARENT$$\n"
"\n$$MU-UL,\"Save BMP File\",LE=SPBM_SAVE_BMP$$\n"
"$$MU-UL,\"Save GR File\",LE=SPBM_SAVE_GRA$$\n"
"\n$$MU-UL,\"Undo\",LE=SPBM_UNDO$$\n"
"\n$$PURPLE$$$$MU-UL,\"+] Sprite Main Menu\",LE=SPBM_MAIN_MENU$$$$LTBLUE$$\n"
"$$MU-UL,\"Exit Sprite\",LE=SPBM_EXIT$$\n"
"$$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$$\n"
"\nRight-Click to get back to this menu.",st1,st2,width);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U0 GrBitMapEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
{
DCFill(dc);
GrBlot(dc,xx1,yy1,img);
}
U0 GrBitMapEdTrimToExtents(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!=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!=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!=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!=TRANSPARENT) goto tr_done;
}
x2--;
}
tr_done:
*_img=DCExt(img,x1,y1,x2,y2);
*_xx1+=x1; *_yy1+=y1;
*_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
DCDel(img);
}
U0 GrBitMapEdAddOutline(CDC *img,I64 width,
CColorROPU32 color,CColorROPU32 bkcolor)
{
I64 i,j,k,c;
CColorROPU32 old_color;
CDC *src;
if (img->width && img->height) {
old_color=img->color;
img->color=color;
while (width-->0) {
src=DCExt(img,0,0,img->width-1,img->height-1);
for (i=0;i<img->height;i++)
for (j=0;j<img->width;j++)
if (GrPeek(src,j,i)==bkcolor)
for (k=0;k<8;k++) {
c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
if (c>=0 && c!=bkcolor) {
GrPlot(img,j,i);
break;
}
}
DCDel(src);
}
img->color=old_color;
}
}
U0 GrBitMapEdEtch(CDC *img,I64 width,CColorROPU32 bkcolor)
{
I64 i,j,k,c;
CColorROPU32 old_color;
CDC *src;
if (img->width && img->height) {
old_color=img->color;
img->color=bkcolor;
while (width-->0) {
src=DCExt(img,0,0,img->width-1,img->height-1);
for (i=0;i<img->height;i++)
for (j=0;j<img->width;j++)
if (GrPeek(src,j,i)!=bkcolor)
for (k=0;k<8;k++) {
c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
if (c<0 || c==bkcolor) {
GrPlot(img,j,i);
break;
}
}
DCDel(src);
}
img->color=old_color;
}
}
I64 SpriteBitMapEd(CDoc *,CDocEntry *doc_e,CDC *dc,I64 *_xx1,I64 *_yy1,
I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor)
{
I64 i,j,mode=SPBM_LINE,color=BLACK,width=1,msg_code,arg1,arg2,x1,y1,x11,y11,
x22,y22,res,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2,
old_de_flags=doc_e->de_flags;
Bool down=FALSE;
U8 *st=NULL;
CEdFileName filename;
CDC *img=*_img,
*clipboard=NULL,*undo=NULL,*dc2;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
doc_e->de_flags|=DOCEF_DONT_DRAW;
goto bm_menu;
while (TRUE) {
if (kbd.scan_code&SCF_CTRL)//grab scroll update?
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrBorder(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
while (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN)) {
switch (msg_code) {
case MSG_KEY_DOWN:
switch (arg1) {
case CH_SHIFT_ESC:
res=SPE_ABORT;
goto bm_key_up_done;
case CH_ESC:
res=SPE_CONT;
goto bm_key_up_done;
case 'c': //eye-dropper
dc2=DCScrnCapture(FALSE);
color=GrPeek(dc2,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
DCDel(dc2);
break;
case 't': //Set to transparent color
color=TRANSPARENT;
break;
}
break;
case MSG_MS_R_DOWN:
bm_menu:
DCFill(dc);
StrCpy(Fs->task_title,"Sprite BitMap Menu");
i=PopUpSpriteBitMap(color,width);
if (i>=0)
StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_BITMAP_MENU"));
switch (i) {
case DOCM_CANCEL:
res=SPE_ABORT;
goto bm_done;
case SPBM_EXIT:
res=SPE_EXIT;
goto bm_done;
case SPBM_MAIN_MENU:
res=SPE_CONT;
goto bm_done;
case SPBM_COLOR:
i=PopUpColor(,,FALSE);
if (i>=0) color=i;
goto bm_menu;
case SPBM_FIND_AND_REPLACE:
i=PopUpColor("Find Color\n",,FALSE);
if (i>=0) {
j=PopUpColor("Replace Color\n",,FALSE);
if (j>=0) {
DCColorChg(img,i,j);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
}
}
goto bm_menu;
case SPBM_TRIM_TO_EXTENTS:
GrBitMapEdTrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
goto bm_menu;
case SPBM_ADD_OUTLINE:
i=PopUpRangeI64(1,16,1,"Outline Width\n");
if (i>=0) {
GrBitMapEdAddOutline(img,i,color,bkcolor);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
}
goto bm_menu;
case SPBM_ETCH:
i=PopUpRangeI64(1,16,1,"Etch Width\n");
if (i>=0) {
GrBitMapEdEtch(img,i,bkcolor);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
}
goto bm_menu;
case SPBM_SAVE_BMP:
*filename.name=0;
if (DocForm(&filename) && *filename.name)
BMPWrite(filename.name,img);
goto bm_menu;
case SPBM_SAVE_GRA:
*filename.name=0;
if (DocForm(&filename) && *filename.name)
GRWrite(filename.name,img,DCSF_COMPRESSED|DCSF_PALETTE_GET);
goto bm_menu;
case SPBM_DITHER_COLOR:
i=PopUpColorDither;
if (i>=0) color=i;
goto bm_menu;
case SPBM_WIDTH:
i=PopUpRangeI64(1,16,1,"Pen Width\n");
if (i>=0) width=i;
goto bm_menu;
case SPBM_UNDO:
if (undo) {
DCFill(img,bkcolor);
img->color=ROP_EQU;
GrBlot(img,0,0,undo);
DCDel(undo);
undo=NULL;
}
goto bm_menu;
case SPBM_PT:
case SPBM_LINE:
case SPBM_ARROW:
case SPBM_RECT:
case SPBM_CIRCLE:
case SPBM_FLOOD_FILL:
case SPBM_FLOOD_FILL_NOT:
case SPBM_POLYPT:
case SPBM_POLYLINE:
case SPBM_COPY:
case SPBM_DELETE:
case SPBM_PASTE:
case SPBM_PASTE_TRANSPARENT:
mode=i;
break;
case SPBM_TEXT:
case SPBM_TEXT_BOX:
case SPBM_TEXT_DIAMOND:
Free(st);
st=PopUpGetStr("Enter text and press <ESC>.\n");
if (st && *st)
mode=i;
else
goto bm_menu;
break;
}
DCDel(undo);
undo=DCExt(img,0,0,img->width-1,img->height-1);
undo->bkcolor=bkcolor;
Refresh(2,TRUE); //Let popup close
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
down=FALSE;
break;
case MSG_MS_L_DOWN:
switch (mode) {
case SPBM_PT:
img->color=color;
img->pen_width=width;
GrPlot3(img,arg1-xx1,arg2-yy1,0);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
start:
if (down)
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
x1=arg1; y1=arg2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
case SPBM_LINE:
GrLine3(dc,x1,y1,0,arg1,arg2,0);
break;
case SPBM_ARROW:
GrArrow3(dc,x1,y1,0,arg1,arg2,0);
break;
case SPBM_RECT:
GrRect(dc,x1,y1,1,1);
break;
case SPBM_CIRCLE:
GrCircle3(dc,x1,y1,0,1);
break;
case SPBM_COPY:
case SPBM_DELETE:
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrBorder(dc,x1,y1,x1,y1);
break;
end:
break;
case SPBM_PASTE:
case SPBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==SPBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,arg1,arg2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,arg1,arg2,dc2);
DCDel(dc2);
}
}
break;
case SPBM_TEXT:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPrint(dc,arg1,arg2,"%s",st);
break;
case SPBM_TEXT_BOX:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,arg1,arg2,0,st);
break;
case SPBM_TEXT_DIAMOND:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,arg1,arg2,0,st);
break;
case SPBM_FLOOD_FILL:
img->color=color;
GrFloodFill(img,arg1-xx1,arg2-yy1);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case SPBM_FLOOD_FILL_NOT:
img->color=color;
GrFloodFill(img,arg1-xx1,arg2-yy1,TRUE);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case SPBM_POLYLINE:
if (!down) {
x1=arg1; y1=arg2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
GrLine3(dc,x1,y1,0,arg1,arg2,0);
}
break;
case SPBM_POLYPT:
x1=arg1; y1=arg2;
down=TRUE;
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
}
break;
case MSG_MS_MOVE:
switch (mode) {
case SPBM_LINE:
case SPBM_ARROW:
case SPBM_POLYLINE:
if (down) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
if (mode==SPBM_ARROW)
GrArrow3(dc,x1,y1,0,arg1,arg2,0);
else
GrLine3(dc,x1,y1,0,arg1,arg2,0);
}
break;
case SPBM_RECT:
if (down) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<arg1) {
x11=x1;
x22=arg1;
} else {
x11=arg1;
x22=x1;
}
if (y1<arg2) {
y11=y1;
y22=arg2;
} else {
y11=arg2;
y22=y1;
}
dc->color=color;
GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
}
break;
case SPBM_COPY:
case SPBM_DELETE:
if (down) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<arg1) {
x11=x1;
x22=arg1;
} else {
x11=arg1;
x22=x1;
}
if (y1<arg2) {
y11=y1;
y22=arg2;
} else {
y11=arg2;
y22=y1;
}
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrBorder(dc,x11,y11,x22,y22);
}
break;
case SPBM_CIRCLE:
if (down) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
}
break;
case SPBM_PASTE:
case SPBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==SPBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,arg1,arg2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,arg1,arg2,dc2);
DCDel(dc2);
}
}
break;
case SPBM_TEXT:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPrint(dc,arg1,arg2,"%s",st);
break;
case SPBM_TEXT_BOX:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,arg1,arg2,0,st);
break;
case SPBM_TEXT_DIAMOND:
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,arg1,arg2,0,st);
break;
case SPBM_POLYPT:
if (down) {
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
x1=arg1; y1=arg2;
}
break;
}
break;
case MSG_MS_L_UP:
switch (mode) {
case SPBM_LINE:
case SPBM_ARROW:
case SPBM_POLYPT:
case SPBM_POLYLINE:
img->color=color;
img->pen_width=width;
if (mode==SPBM_ARROW)
GrArrow3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
else
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==SPBM_POLYLINE) {
x1=arg1; y1=arg2;
} else
down=FALSE;
break;
case SPBM_RECT:
img->color=color;
if (x1<arg1) {
x11=x1;
x22=arg1;
} else {
x11=arg1;
x22=x1;
}
if (y1<arg2) {
y11=y1;
y22=arg2;
} else {
y11=arg2;
y22=y1;
}
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
down=FALSE;
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case SPBM_COPY:
case SPBM_DELETE:
if (x1<arg1) {
x11=x1;
x22=arg1;
} else {
x11=arg1;
x22=x1;
}
if (y1<arg2) {
y11=y1;
y22=arg2;
} else {
y11=arg2;
y22=y1;
}
DCDel(clipboard);
clipboard=DCExt(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
clipboard->bkcolor=bkcolor;
if (mode==SPBM_DELETE) {
img->color=bkcolor;
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
}
goto bm_menu;
case SPBM_CIRCLE:
img->color=color;
img->pen_width=width;
GrCircle3(img,x1-xx1,y1-yy1,0,
Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
down=FALSE;
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case SPBM_PASTE:
case SPBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==SPBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(img,arg1-xx1,arg2-yy1,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(img,arg1-xx1,arg2-yy1,dc2);
DCDel(dc2);
}
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
}
break;
case SPBM_TEXT:
img->color=color;
GrPrint(img,arg1-xx1,arg2-yy1,"%s",st);
goto bm_menu;
case SPBM_TEXT_BOX:
img->color=color;
GrTextBox3(img,arg1-xx1,arg2-yy1,0,st);
goto bm_menu;
case SPBM_TEXT_DIAMOND:
img->color=color;
GrTextDiamond3(img,arg1-xx1,arg2-yy1,0,st);
goto bm_menu;
}
break;
}
}
Refresh;
}
bm_key_up_done:
GetMsg(,,1<<MSG_KEY_UP);
bm_done:
DCDel(clipboard);
DCDel(undo);
Free(st);
DCFill(dc);
SettingsPop;
doc_e->de_flags=old_de_flags;
*_img=img;
*_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
return res;
}
+603
View File
@@ -0,0 +1,603 @@
#help_index "Graphics/Sprite;Sprites"
U0 SpriteElem2Code(CDoc *doc,CSprite *tmpg)
{
U8 buf1[STR_LEN],buf2[STR_LEN];
I32 *ptr;
I64 i,j,k,col,width_internal;
CD3I32 *p;
CMeshTri *tri;
if (!doc) doc=DocPut;
DocPrint(doc,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_CODES");
switch (tmpg->type&SPG_TYPE_MASK) {
case SPT_COLOR:
DocPrint(doc,"{%s}",
Color2Str(buf1,tmpg->c.color));
break;
case SPT_DITHER_COLOR:
DocPrint(doc,"{%s}",
Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
break;
case SPT_TRANSFORM_ON:
DocPrint(doc,"{ON}");
break;
case SPT_TRANSFORM_OFF:
DocPrint(doc,"{OFF}");
break;
case SPT_LINE:
case SPT_ARROW:
case SPT_PLANAR_SYMMETRY:
DocPrint(doc,"{(%d,%d),(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
tmpg->pp.x2,tmpg->pp.y2);
break;
case SPT_RECT:
DocPrint(doc,"{(%d,%d):(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
break;
case SPT_ROTATED_RECT:
DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->ppa.x1,tmpg->ppa.y1,
tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1,
180/ã*Wrap(tmpg->ppa.angle));
break;
case SPT_PT:
case SPT_FLOOD_FILL:
case SPT_SHIFT:
DocPrint(doc,"{(%d,%d)}",tmpg->p.x1,tmpg->p.y1);
break;
case SPT_FLOOD_FILL_NOT:
DocPrint(doc,"{(%d,%d),TRUE}",tmpg->p.x1,tmpg->p.y1);
break;
case SPT_CIRCLE:
DocPrint(doc,"{(%d,%d):%d}",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
break;
case SPT_WIDTH:
DocPrint(doc,"{%d}",tmpg->w.width);
break;
case SPT_ELLIPSE:
DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->pwha.x1,tmpg->pwha.y1,
tmpg->pwha.width,tmpg->pwha.height,180/ã*Wrap(tmpg->pwha.angle));
break;
case SPT_POLYGON:
DocPrint(doc,"{%d,(%d,%d):(%d,%d),%0.4f}",tmpg->pwhas.sides,
tmpg->pwhas.x1,tmpg->pwhas.y1,
tmpg->pwhas.width,tmpg->pwhas.height,
180/ã*Wrap(tmpg->pwhas.angle));
break;
case SPT_TEXT:
case SPT_TEXT_BOX:
case SPT_TEXT_DIAMOND:
DocPrint(doc,"{(%d,%d),\"%Q\"}",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
break;
case SPT_POLYLINE:
ptr=&tmpg->nu.u;
DocPrint(doc,"{");
for (i=0;i<tmpg->nu.num;i++,ptr+=2) {
DocPrint(doc,"(%d,%d)",ptr[0],ptr[1]);
if (i+1<tmpg->nu.num) DocPrint(doc,",");
if (i&3==3 && i+1<tmpg->nu.num)
DocPrint(doc,"\n");
}
DocPrint(doc,"}");
break;
case SPT_BSPLINE2:
case SPT_BSPLINE3:
case SPT_BSPLINE2_CLOSED:
case SPT_BSPLINE3_CLOSED:
ptr=&tmpg->nu.u;
DocPrint(doc,"{");
for (i=0;i<tmpg->nu.num;i++,ptr+=3) {
DocPrint(doc,"(%d,%d,%d)",ptr[0],ptr[1],ptr[2]);
if (i+1<tmpg->nu.num) DocPrint(doc,",");
if (i&3==3 && i+1<tmpg->nu.num)
DocPrint(doc,"\n");
}
if (tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE2||
tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE3)
DocPrint(doc,",FALSE}");
else
DocPrint(doc,",TRUE}");
break;
case SPT_POLYPT:
DocPrint(doc,"{(%d,%d),",tmpg->npu.x,tmpg->npu.y);
ptr=&tmpg->npu.u;
col=16;
for (i=0;i<tmpg->npu.num;i++) {
DocPrint(doc,"%d",BFieldExtU32(ptr,i*3,3));
if (++col>=64 && i+1<tmpg->npu.num) {
DocPrint(doc,"\n");
col=0;
}
}
DocPrint(doc,"}");
break;
case SPT_BITMAP:
DocPrint(doc,"{(%d,%d):(%d,%d),\n",tmpg->pwhu.x1,tmpg->pwhu.y1,
tmpg->pwhu.width,tmpg->pwhu.height);
width_internal=(tmpg->pwhu.width+7)&~7;
if (width_internal<80)
k=width_internal;
else
k=64;
ptr=&tmpg->pwhu.u;
col=0;
for (j=0;j<tmpg->pwhu.height;j++)
for (i=0;i<width_internal;i++,ptr(U8 *)++) {
if (i>=tmpg->pwhu.width)
DocPrint(doc,"_");
else if (*ptr(U8 *)<16)
DocPrint(doc,"%X",*ptr(U8 *));
else
DocPrint(doc,"%c",CH_SHIFT_SPACE);
if (++col>=k && (i+1<width_internal||j+1<tmpg->pwhu.height)) {
DocPrint(doc,"\n");
col=0;
}
}
DocPrint(doc,"}");
break;
case SPT_MESH:
DocPrint(doc,"{FALSE,");
p=&tmpg->mu.u;
col=0;
for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
if (i+1<tmpg->mu.vertex_cnt) DocPrint(doc,",");
if (++col==4) {
DocPrint(doc,"\t//%d\n",i);
col=0;
}
}
DocPrint(doc,":");
tri=p;
for (i=0;i<tmpg->mu.tri_cnt;i++,tri++) {
DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
tri->nums[0],tri->nums[1],tri->nums[2]);
if (i+1<tmpg->mu.tri_cnt) DocPrint(doc,",");
if (++col>=3 && i+1<tmpg->mu.tri_cnt) {
DocPrint(doc,"\n");
col=0;
}
}
DocPrint(doc,"}");
break;
case SPT_SHIFTABLE_MESH:
DocPrint(doc,"{TRUE,(%d,%d,%d):",tmpg->pmu.x,tmpg->pmu.y,tmpg->pmu.z);
p=&tmpg->pmu.u;
col=1;
for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
if (i+1<tmpg->pmu.vertex_cnt) DocPrint(doc,",");
if (++col==4) {
DocPrint(doc,"\t//%d\n",i);
col=0;
}
}
DocPrint(doc,":");
tri=p;
for (i=0;i<tmpg->pmu.tri_cnt;i++,tri++) {
DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
tri->nums[0],tri->nums[1],tri->nums[2]);
if (i+1<tmpg->pmu.tri_cnt) DocPrint(doc,",");
if (++col>=3 && i+1<tmpg->pmu.tri_cnt) {
DocPrint(doc,"\n");
col=0;
}
}
DocPrint(doc,"}");
break;
}
DocPrint(doc,";\n");
}
public U0 Sprite2Code(CDoc *doc=NULL,U8 *elems)
{//Sprite to text.
CSprite *tmpg=elems-offset(CSprite.start);
while (tmpg->type&SPG_TYPE_MASK) {
SpriteElem2Code(doc,tmpg);
tmpg(U8 *)+=SpriteElemSize(tmpg);
}
}
CSprite *Code2SpriteElem(CCmpCtrl *cc,I64 type)
{
I64 i,num1,num2,size;
CSprite *res,g;
CColorROPU32 color;
U8 *st,*ptr;
CQueD3I32 headp,*tmpp,*tmpa1;
CQueMeshTri headt,*tmpt,*tmpt1;
CQueVectU8 *tmpv;
MemSet(&g,0,sizeof(CSprite));
switch (type) {
start:
case SPT_COLOR:
case SPT_DITHER_COLOR:
st=LexFirstRem(cc,"}");
color=Str2ColorU32(st);
Free(st);
Lex(cc); //Skip color
g.c.color=color.c0.color;
if (color&ROPF_DITHER) {
g.d.dither_color.u8[1]=color.c1.color;
g.type=SPT_DITHER_COLOR;
} else
g.type=SPT_COLOR;
break;
case SPT_TRANSFORM_ON:
case SPT_TRANSFORM_OFF:
Lex(cc); //Skip {
if (LexExpressionI64(cc))
g.type=SPT_TRANSFORM_ON;
else
g.type=SPT_TRANSFORM_OFF;
break;
case SPT_LINE:
case SPT_ARROW:
case SPT_PLANAR_SYMMETRY:
Lex(cc); //Skip {
g.type=type;
LexD2I32(cc,&g.pp.x1);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
LexD2I32(cc,&g.pp.x2);
break;
case SPT_RECT:
case SPT_ROTATED_RECT:
Lex(cc); //Skip {
LexD2I32(cc,&g.pp.x1);
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
LexD2I32(cc,&g.pp.x2);
g.ppa.x2+=g.pp.x1;
g.ppa.y2+=g.pp.y1;
if (cc->token==',') {
Lex(cc); //Skip ,
g.ppa.angle=ã/180*LexExpressionF64(cc);
g.type=SPT_ROTATED_RECT;
} else
g.type=SPT_RECT;
break;
case SPT_PT:
case SPT_SHIFT:
Lex(cc); //Skip {
g.type=type;
LexD2I32(cc,&g.p.x1);
break;
case SPT_FLOOD_FILL:
case SPT_FLOOD_FILL_NOT:
Lex(cc); //Skip {
LexD2I32(cc,&g.p.x1);
if (cc->token==',') {
Lex(cc); //Skip ,
i=LexExpressionI64(cc);
} else
i=0;
if (i)
g.type=SPT_FLOOD_FILL_NOT;
else
g.type=SPT_FLOOD_FILL;
break;
case SPT_WIDTH:
Lex(cc); //Skip {
g.w.width=LexExpressionI64(cc);
g.type=SPT_WIDTH;
break;
case SPT_CIRCLE:
Lex(cc); //Skip {
g.type=SPT_CIRCLE;
LexD2I32(cc,&g.pr.x1);
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
g.pr.radius=LexExpressionI64(cc);
break;
case SPT_POLYGON:
Lex(cc); //Skip {
g.pwhas.sides=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
case SPT_ELLIPSE:
Lex(cc); //Skip {
g.type=type;
LexD2I32(cc,&g.pwha.x1);
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
LexD2I32(cc,&g.pwha.width);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
g.pwha.angle=ã/180*LexExpressionF64(cc);
break;
end:
size=SpriteElemSize(&g)+offset(CSprite.start);
res=MAlloc(size);
MemCpy(res,&g,size);
break;
case SPT_TEXT:
case SPT_TEXT_BOX:
case SPT_TEXT_DIAMOND:
Lex(cc); //Skip {
g.type=type;
LexD2I32(cc,&g.ps.x1);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
if (Lex(cc)==TK_STR) //Skip ,
st=LexExtStr(cc);
else
LexExcept(cc,"Expecting string at ");
size=SpriteElemQuedBaseSize(type);
i=StrLen(st)+1;
res=MAlloc(size+i);
MemCpy(res,&g,size);
MemCpy(res(U8 *)+size,st,i);
Free(st);
break;
case SPT_POLYLINE:
Lex(cc); //Skip {
g.type=SPT_POLYLINE;
QueInit(&headp);
while (cc->token=='(') {
tmpp=CAlloc(sizeof(CQueD3I32));
LexD2I32(cc,&tmpp->p);
QueIns(tmpp,headp.last);
g.nu.num++;
if (cc->token==',')
Lex(cc); //Skip ,
}
if (g.nu.num<2)
LexExcept(cc,"Expecting point at ");
size=SpriteElemQuedBaseSize(SPT_POLYLINE);
res=MAlloc(size+g.nu.num*sizeof(CD2I32));
MemCpy(res,&g,size);
ptr=&res->nu.u;
tmpp=headp.next;
while (tmpp!=&headp) {
tmpa1=tmpp->next;
MemCpy(ptr,&tmpp->p,sizeof(CD2I32));
ptr+=sizeof(CD2I32);
Free(tmpp);
tmpp=tmpa1;
}
break;
case SPT_BSPLINE2:
case SPT_BSPLINE3:
case SPT_BSPLINE2_CLOSED:
case SPT_BSPLINE3_CLOSED:
Lex(cc); //Skip {
QueInit(&headp);
while (cc->token=='(') {
tmpp=CAlloc(sizeof(CQueD3I32));
LexD3I32(cc,&tmpp->p);
QueIns(tmpp,headp.last);
g.nu.num++;
if (cc->token==',')
Lex(cc); //Skip ,
}
if (g.nu.num<2)
LexExcept(cc,"Expecting point at ");
size=SpriteElemQuedBaseSize(type);
res=MAlloc(size+g.nu.num*sizeof(CD3I32));
if (LexExpressionI64(cc)) {
if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
g.type=SPT_BSPLINE2_CLOSED;
else
g.type=SPT_BSPLINE3_CLOSED;
} else {
if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
g.type=SPT_BSPLINE2;
else
g.type=SPT_BSPLINE3;
}
MemCpy(res,&g,size);
ptr=&res->nu.u;
tmpp=headp.next;
while (tmpp!=&headp) {
tmpa1=tmpp->next;
MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
ptr+=sizeof(CD3I32);
Free(tmpp);
tmpp=tmpa1;
}
break;
case SPT_POLYPT:
Lex(cc); //Skip {
LexD2I32(cc,&g.npu.x);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
tmpv=QueVectU8New;
while (TRUE) {
if (!(i=LexGetChar(cc)))
LexExcept(cc,"Expecting '}' at ");
if (i=='}')
break;
if ('0'<=i<='7')
QueVectU8Put(tmpv,g.npu.num++,i-'0');
}
Bts(&cc->flags,CCf_USE_LAST_U16);
Lex(cc); //Load '}'
g.type=SPT_POLYPT;
size=SpriteElemQuedBaseSize(SPT_POLYPT);
res=CAlloc(size+(g.npu.num*3+7)>>3);
MemCpy(res,&g,size);
ptr=&res->npu.u;
for (i=0;i<g.npu.num;i++)
BFieldOrU32(ptr,i*3,QueVectU8Get(tmpv,i));
QueVectU8Del(tmpv);
break;
case SPT_BITMAP:
Lex(cc); //Skip {
LexD2I32(cc,&g.pwhu.x1);
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
LexD2I32(cc,&g.pwhu.width);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
tmpv=QueVectU8New;
num1=0;
while (TRUE) {
if (!(i=ToUpper(LexGetChar(cc))))
LexExcept(cc,"Expecting '}' at ");
if (i=='}')
break;
if ('0'<=i<='9')
QueVectU8Put(tmpv,num1++,i-'0');
else if ('A'<=i<='F')
QueVectU8Put(tmpv,num1++,i-'A'+10);
else if (i==CH_SPACE||i==CH_SHIFT_SPACE)
QueVectU8Put(tmpv,num1++,TRANSPARENT);
else if (i=='_')
QueVectU8Put(tmpv,num1++,0);
}
Bts(&cc->flags,CCf_USE_LAST_U16);
Lex(cc); //Load '}'
g.type=SPT_BITMAP;
size=SpriteElemQuedBaseSize(SPT_BITMAP);
res=CAlloc(size+num1);
MemCpy(res,&g,size);
ptr=&res->pwhu.u;
for (i=0;i<num1;i++)
*ptr++=QueVectU8Get(tmpv,i);
QueVectU8Del(tmpv);
break;
case SPT_MESH:
case SPT_SHIFTABLE_MESH:
Lex(cc); //Skip {
if (LexExpressionI64(cc)) {
g.type=SPT_SHIFTABLE_MESH;
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
LexD3I32(cc,&g.pmu.x);
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
} else {
g.type=SPT_MESH;
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
}
num1=0;
QueInit(&headp);
while (cc->token=='(') {
tmpp=CAlloc(sizeof(CQueD3I32));
LexD3I32(cc,&tmpp->p);
QueIns(tmpp,headp.last);
num1++;
if (cc->token==',')
Lex(cc); //Skip ,
}
if (cc->token!=':')
LexExcept(cc,"Expecting ':' at ");
Lex(cc); //Skip :
num2=0;
QueInit(&headt);
while (cc->token=='(') {
tmpt=CAlloc(sizeof(CQueMeshTri));
st=LexFirstRem(cc,",");
tmpt->color=Str2ColorU32(st);
Free(st);
Lex(cc); //Skip color
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
tmpt->nums[0]=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
tmpt->nums[1]=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
tmpt->nums[2]=LexExpressionI64(cc);
if (cc->token!=')')
LexExcept(cc,"Expecting ')' at ");
Lex(cc); //Skip )
QueIns(tmpt,headt.last);
num2++;
if (cc->token==',')
Lex(cc); //Skip ,
}
if (g.type==SPT_MESH) {
g.mu.vertex_cnt=num1;
g.mu.tri_cnt=num2;
size=SpriteElemQuedBaseSize(SPT_MESH);
} else {
g.pmu.vertex_cnt=num1;
g.pmu.tri_cnt=num2;
}
size=SpriteElemQuedBaseSize(g.type);
res=MAlloc(size+num1*sizeof(CD3I32)+num2*sizeof(CMeshTri));
MemCpy(res,&g,size);
ptr=res(U8 *)+size;
tmpp=headp.next;
while (tmpp!=&headp) {
tmpa1=tmpp->next;
MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
ptr+=sizeof(CD3I32);
Free(tmpp);
tmpp=tmpa1;
}
tmpt=headt.next;
while (tmpt!=&headt) {
tmpt1=tmpt->next;
MemCpy(ptr,&tmpt->start,sizeof(CMeshTri));
ptr+=sizeof(CMeshTri);
Free(tmpt);
tmpt=tmpt1;
}
break;
}
if (cc->token!='}')
LexExcept(cc,"Expecting '}' at ");
if (Lex(cc)!=';')
LexExcept(cc,"Expecting ';' at ");
return res;
}
public U8 *Code2Sprite(CDoc *doc,I64 *_size=NULL)
{//Text to sprite.
CSprite head;
U8 *res;
Bool okay=TRUE,unlock_doc=DocLock(doc);
CCmpCtrl *cc=CmpCtrlNew(,CCF_DONT_FREE_BUF);
CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
CHashGeneric *tmph;
I64 i,size=0;
QueInit(&head);
LexAttachDoc(cc,,doc);
try {
do {
cc->htc.hash_table_lst=NULL;
if (Lex(cc)==TK_IDENT && //Skip ;
(tmph=HashFind(cc->cur_str,gr.sprite_hash,SPHT_ELEM_CODE))) {
i=tmph->user_data0;
cc->htc.hash_table_lst=old_hash_table_lst;
if (Lex(cc)=='{') //Skip ident
QueIns(Code2SpriteElem(cc,i),head.last);
} else if (cc->token)
LexExcept(cc,"Expecting sprite element type name at ");
} while (cc->token);
okay=TRUE;
} catch {
Fs->catch_except=TRUE;
okay=FALSE;
}
if (unlock_doc)
DocUnlock(doc);
if (okay) {
CmpCtrlDel(cc); //TODO: can crash
res=SpriteQue2Sprite(&head,&size);
} else {
res=NULL;
size=0;
}
if (_size) *_size=size;
QueDel(&head);
return res;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+189
View File
@@ -0,0 +1,189 @@
#help_index "Graphics/Sprite;Sprites"
#help_file "::/Doc/Sprite"
U8 polypt_map[9]={0,1,2,3,0,4,5,6,7};
I64 sprite_elem_base_sizes[SPT_TYPES_NUM]={
sizeof(CSpriteBase), //SPT_END
sizeof(CSpriteColor), //SPT_COLOR
sizeof(CSpriteDitherColor), //SPT_DITHER_COLOR
sizeof(CSpriteW), //SPT_WIDTH
sizeof(CSpritePtPt), //SPT_PLANAR_SYMMETRY
sizeof(CSpriteBase), //SPT_TRANSFORM_ON
sizeof(CSpriteBase), //SPT_TRANSFORM_OFF
sizeof(CSpritePt), //SPT_SHIFT
sizeof(CSpritePt), //SPT_PT
sizeof(CSpriteNumPtU8s), //SPT_POLYPT
sizeof(CSpritePtPt), //SPT_LINE
sizeof(CSpriteNumU8s), //SPT_POLYLINE
sizeof(CSpritePtPt), //SPT_RECT
sizeof(CSpritePtPtAng), //SPT_ROTATED_RECT
sizeof(CSpritePtRad), //SPT_CIRCLE
sizeof(CSpritePtWHAng), //SPT_ELLIPSE
sizeof(CSpritePtWHAngSides), //SPT_POLYGON
sizeof(CSpriteNumU8s), //SPT_BSPLINE2
sizeof(CSpriteNumU8s), //SPT_BSPLINE2_CLOSED
sizeof(CSpriteNumU8s), //SPT_BSPLINE3
sizeof(CSpriteNumU8s), //SPT_BSPLINE3_CLOSED
sizeof(CSpritePt), //SPT_FLOOD_FILL
sizeof(CSpritePt), //SPT_FLOOD_FILL_NOT
sizeof(CSpritePtWHU8s), //SPT_BITMAP
sizeof(CSpriteMeshU8s), //SPT_MESH
sizeof(CSpritePtMeshU8s), //SPT_SHIFTABLE_MESH
sizeof(CSpritePtPt), //SPT_ARROW
sizeof(CSpritePtStr), //SPT_TEXT
sizeof(CSpritePtStr), //SPT_TEXT_BOX
sizeof(CSpritePtStr), //SPT_TEXT_DIAMOND
};
I64 SpriteElemQuedBaseSize(I64 type)
{
return sprite_elem_base_sizes[type&SPG_TYPE_MASK]+offset(CSprite.start);
}
I64 SpriteElemSize(CSprite *tmpg)
{
I64 i=sprite_elem_base_sizes[tmpg->type&SPG_TYPE_MASK];
switch (tmpg->type&SPG_TYPE_MASK) {
case SPT_POLYLINE:
i+=tmpg->nu.num*sizeof(CD2I32);
break;
case SPT_TEXT:
case SPT_TEXT_BOX:
case SPT_TEXT_DIAMOND:
i+=StrLen(tmpg->ps.st)+1;
break;
case SPT_BITMAP:
i+=((tmpg->pwhu.width+7)&~7)*tmpg->pwhu.height;
break;
case SPT_POLYPT:
i+=(tmpg->npu.num*3+7)>>3;
break;
case SPT_BSPLINE2:
case SPT_BSPLINE3:
case SPT_BSPLINE2_CLOSED:
case SPT_BSPLINE3_CLOSED:
i+=tmpg->nu.num*sizeof(CD3I32);
break;
case SPT_MESH:
i+=tmpg->mu.vertex_cnt*sizeof(CD3I32)+
tmpg->mu.tri_cnt*sizeof(CMeshTri);
break;
case SPT_SHIFTABLE_MESH:
i+=tmpg->pmu.vertex_cnt*sizeof(CD3I32)+
tmpg->pmu.tri_cnt*sizeof(CMeshTri);
break;
}
return i;
}
public I64 SpriteSize(U8 *elems)
{//Walk sprite elements and return size of sprite as binary data.
CSprite *tmpg=elems-offset(CSprite.start),*tmpg1=tmpg;
while (tmpg->type&SPG_TYPE_MASK)
tmpg(U8 *)+=SpriteElemSize(tmpg);
return tmpg(U8 *)-tmpg1(U8 *)+sprite_elem_base_sizes[SPT_END];
}
I64 SpriteTypeMask(U8 *elems)
{
I64 res=0;
CSprite *tmpg=elems-offset(CSprite.start);
while (tmpg->type&SPG_TYPE_MASK) {
if (tmpg->type&SPG_TYPE_MASK>=SPT_TYPES_NUM)
return 1<<SPT_TYPES_NUM;
Bts(&res,tmpg->type&SPG_TYPE_MASK);
tmpg(U8 *)+=SpriteElemSize(tmpg);
}
return res;
}
U0 SpriteSelAll(U8 *elems,Bool val)
{
CSprite *tmpg=elems-offset(CSprite.start);
while (tmpg->type&SPG_TYPE_MASK) {
BEqu(&tmpg->type,SPf_SEL,val);
tmpg(U8 *)+=SpriteElemSize(tmpg);
}
}
public U8 *DC2Sprite(CDC *tmpb)
{//Convert device context to sprite.
CSprite *tmpg;
tmpg=CAlloc(sprite_elem_base_sizes[SPT_BITMAP]+
tmpb->width_internal*tmpb->height+
sprite_elem_base_sizes[SPT_END])
(U8 *)-offset(CSprite.start);
tmpg->type=SPT_BITMAP;
tmpg->pwhu.width=tmpb->width;
tmpg->pwhu.height=tmpb->height;
tmpg->pwhu.x1=0;
tmpg->pwhu.y1=0;
MemCpy(&tmpg->pwhu.u,tmpb->body,tmpb->width_internal*tmpb->height);
return tmpg(U8 *)+offset(CSprite.start);
}
public U8 *SpriteElem2Summary(CSprite *tmpg)
{//Study $LK,"::/Demo/Graphics/SpriteText.HC"$.
U8 buf[STR_LEN],buf2[STR_LEN];
I32 *ptr;
StrPrint(buf,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_TYPES");
switch (tmpg->type&SPG_TYPE_MASK) {
case SPT_COLOR:
CatPrint(buf," %s",Color2Str(buf2,tmpg->c.color));
break;
case SPT_DITHER_COLOR:
CatPrint(buf," %s",Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
break;
case SPT_PT:
case SPT_FLOOD_FILL:
case SPT_FLOOD_FILL_NOT:
case SPT_SHIFT:
CatPrint(buf," (%d,%d)",tmpg->p.x1,tmpg->p.y1);
break;
case SPT_LINE:
case SPT_ARROW:
case SPT_PLANAR_SYMMETRY:
case SPT_RECT:
case SPT_ROTATED_RECT:
CatPrint(buf," (%d,%d),(%d,%d)",tmpg->pp.x1,tmpg->pp.y1,
tmpg->pp.x2,tmpg->pp.y2);
break;
case SPT_CIRCLE:
CatPrint(buf," (%d,%d):%dR",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
break;
case SPT_WIDTH:
CatPrint(buf," %d",tmpg->w.width);
break;
case SPT_TEXT:
case SPT_TEXT_BOX:
case SPT_TEXT_DIAMOND:
CatPrint(buf," %d,%d:%-16tQ",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
break;
case SPT_POLYLINE:
case SPT_POLYPT:
ptr=&tmpg->npu.x;
CatPrint(buf," %d (%d,%d)",tmpg->npu.num,ptr[0],ptr[1]);
break;
case SPT_ELLIPSE:
case SPT_POLYGON:
case SPT_BITMAP:
CatPrint(buf," (%d,%d):%dW,%dH",tmpg->pwhu.x1,tmpg->pwhu.y1,
tmpg->pwhu.width,tmpg->pwhu.height);
break;
case SPT_BSPLINE2:
case SPT_BSPLINE3:
case SPT_BSPLINE2_CLOSED:
case SPT_BSPLINE3_CLOSED:
CatPrint(buf," %d",tmpg->nu.num);
break;
case SPT_MESH:
CatPrint(buf," %dV,%dT",tmpg->mu.vertex_cnt,tmpg->mu.tri_cnt);
break;
case SPT_SHIFTABLE_MESH:
CatPrint(buf," %dV,%dT",tmpg->pmu.vertex_cnt,tmpg->pmu.tri_cnt);
break;
}
return StrNew(buf);
}