Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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");
|
||||
@@ -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);
|
||||
@@ -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);;;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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("..");;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user