TempleOSTS_140317.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:02 +02:00
1 parent 2d2a65d572
commit 7ef616a20e
1416 files changed
+223873 -53917

No files matched your search

+120
View File
@@ -0,0 +1,120 @@
#help_index "Graphics"
U0 GrInit1()
{
DefineLstLoad("ST_SPRITE_TYPES",
"End\0Color 8Bit\0Dither Color 8Bit\0"
"Width\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
"Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
"Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0BSpline3\0BSpline3 Closed\0"
"Flood Fill\0Flood Fill Not Color\0BitMap 8Bit\0Mesh\0Shiftable Mesh\0"
"Arrow\0Text\0Text Box\0Text Diamond\0");
}
GrInit1;
#help_index "Graphics/Sprite"
#define GRST_END 0
#define GRST_COLOR8 1
#define GRST_DITHER_COLOR8 2
#define GRST_WIDTH 3
#define GRST_PLANAR_SYMMETRY 4
#define GRST_TRANSFORM_ON 5
#define GRST_TRANSFORM_OFF 6
#define GRST_SHIFT 7
#define GRST_PT 8
#define GRST_POLYPT 9
#define GRST_LINE 10
#define GRST_POLYLINE 11
#define GRST_RECT 12
#define GRST_ROTATED_RECT 13
#define GRST_CIRCLE 14
#define GRST_ELLIPSE 15
#define GRST_POLYGON 16
#define GRST_BSPLINE2 17
#define GRST_BSPLINE2_CLOSED 18
#define GRST_BSPLINE3 19
#define GRST_BSPLINE3_CLOSED 20
#define GRST_FLOOD_FILL 21
#define GRST_FLOOD_FILL_NOT 22
#define GRST_BITMAP8 23
#define GRST_MESH 24
#define GRST_SHIFTABLE_MESH 25
#define GRST_ARROW 26
#define GRST_TEXT 27
#define GRST_TEXT_BOX 28
#define GRST_TEXT_DIAMOND 29
#define GRST_NUM_TYPES 30
class CMeshTri
{
I32 color; //Give one of 0-7 colors. Colors 8-15 are 0-7 with intensity bit set.
I32 nums[3]; //Vertex number
};
public class CSprite
{
//See $LK,"Graphics/Sprite",A="HI:Graphics/Sprite"$
//See $LK,"::/Adam/Gr/GrSpritePlot.CPP",A="FL:::/Adam/Gr/GrSpritePlot.CPP,1"$ for how CSprite are stored.
CSprite *next,*last;
U0 start;
U8 type;
union {
U8 color8;
U16 dither_color8;
I32 x1;
I32 num;
I32 width;
I32 vertex_cnt; //Mesh
}
union {
I32 y1;
I32 height;
I32 tri_cnt; //Mesh
}
union {
I32 z1;
I32 x2;
U8 st[4];
}
union {
I32 y2;
I32 shiftable_vertex_cnt //Shiftable Mesh
}
union {
F64 linespeed;
F64 rot_angle;
I32 shiftable_tri_cnt //Shiftable Mesh
}
I32 sides;
};
#help_index "Graphics"
extern I64 GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
#include "GrGlbls"
#include "GrAsm"
#include "GrDC"
#include "GrPalette"
#include "GrInit"
#include "MathGr"
#include "GrScreen"
#include "GrBitMap"
#include "GrPrimatives"
#include "GrComposites"
#include "GrChar"
#define GE_ABORT (-1)
#define GE_EXIT 0
#define GE_CONT 1
#include "SpriteNew"
#include "GrSpritePlot"
#include "SpriteMesh"
#include "SpriteBitMap"
#include "SpriteEd"
#include "SpriteMain"
#include "GrEnd"
#help_index ""
+775
View File
@@ -0,0 +1,775 @@
#help_index "Graphics"
I64 *gr_1_to_8_bits,*gr_1_to_8_colors;
#help_index "Graphics/Char;Char/Graphics"
U32 *gr_text_base;
U16 *gr_win_z_buf;
asm {
USE64
// ************************************
_PLOT_SCREEN_U8::
PUSH RBP
MOV RBP,RSP
MOV RBX,U64 SF_ARG2[RBP]
MOV RAX,U64 SF_ARG3[RBP]
TEST RBX,RBX
JS @@05
TEST RAX,RAX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG1[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
POP RBP
RET1 24
@@05: XOR RAX,RAX
POP RBP
RET1 24
// ************************************
_PLOT_WIN_U8::
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 RBX,RBX
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
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
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
POP RBP
RET1 32
@@05: XOR RAX,RAX
POP RBP
RET1 32
// ************************************
/*
Bool PlotWinStr2(CTask *task,U8 *s,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_WIN_STR2::
PUSH RBP
MOV RBP,RSP
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG5[RBP]
MOV RCX,U64 SF_ARG3[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_ARG6[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,R9
MOV RAX,U64 SF_ARG4[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
// ************************************
/*
Bool PlotAttrStr2(CTask *task,U32 *hl,I64 len,I64 x,I64 y)
*/
_PLOT_ATTR_STR2::
PUSH RBP
MOV RBP,RSP
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG3[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_ARG5[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,R9
@@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
// ************************************
/*
Bool PlotAttr(CTask *task,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_ATTR::
PUSH RBP
MOV RBP,RSP
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RDI,U64 CTask.scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG2[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_ARG5[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,R9
MOV RBX,U64 SF_ARG3[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
// ************************************
_PLOT_BORDER_U8::
PUSH RBP
MOV RBP,RSP
MOV R9,U64 [&gr_text_base]
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]
MOV RDX,-1
CMP RBX,RDX
JL @@05
ADD RBX,U64 CTask.win_left[RCX]
MOV RDX,U64 CTask.win_right[RCX]
INC RDX
CMP RBX,RDX
JG @@05
TEST RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
MOV RDX,-1
CMP RAX,RDX
JL @@05
ADD RAX,U64 CTask.win_top[RCX]
MOV RDX,U64 CTask.win_bottom[RCX]
INC RDX
CMP RAX,RDX
JG @@05
TEST RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,R9
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,TRUE
POP RBP
RET1 32
@@05: XOR RAX,RAX
POP RBP
RET1 32
// ************************************
_GR_UPDATE_LINE32::
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
CMP U32 [RDI],EAX
JE @@10
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
@@10: ADD RDI,4
ADD R8,4
DEC RCX
JNZ @@05
MOV RAX,U64 SF_ARG1[RBP]
MOV U64 [RAX],R8
MOV RAX,U64 SF_ARG4[RBP]
MOV U64 [RAX],RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV U64 [RAX],RSI
POP RDI
POP RSI
POP RBP
RET1 32
// ************************************
_GR_UPDATE_LINE32_FLUSH_CACHE::
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
ADD RDI,4
ADD R8,4
DEC RCX
JNZ @@05
MOV RAX,U64 SF_ARG1[RBP]
MOV U64 [RAX],R8
MOV RAX,U64 SF_ARG4[RBP]
MOV U64 [RAX],RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV U64 [RAX],RSI
POP RDI
POP RSI
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 DOCEt_UNDERLINE attr flag is used.
PUSH RBP
MOV RBP,RSP
MOVZX RAX,U8 SF_ARG1[RBP]
MOV RDX,U64 [&gr_font]
MOV RAX,U64 [RDX+RAX*8] //RAX is 8x8 char font data, 64-bits
BT U64 SF_ARG1[RBP],DOCEt_UNDERLINE
JNC @@05
MOV RBX,0xFF00000000000000
OR RAX,RBX
@@05: 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_1_to_8_colors]
MOV R8,U64 [RDX+RBX*8] //R8 is color repeated 8 times.
MOV R9,U64 SF_ARG3[RBP] //R9 is width_internal
MOV RDI,U64 SF_ARG2[RBP]
MOV RSI,U64 [&gr_1_to_8_bits] //RSI is gr_1_to_8_bits
// m=my_1_to_8_bits[ch&255];ch>>=8;
// *dst=*dst&~m|c&m;
// dst(U8 *)+=w1;
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOVZX RBX,AL
MOV RDX,U64 [RSI+RBX*8]
SHR RAX,8
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
ADD RDI,R9
MOV RDX,U64 [RSI+RAX*8]
MOV RBX,U64 [RDI]
MOV RCX,RDX
NOT RCX
AND RDX,R8
AND RCX,RBX
OR RCX,RDX
MOV U64 [RDI],RCX
POP RDI
POP RSI
@@10: POP RBP
RET1 24
}
#help_index "Graphics/Char;Char/Graphics"
public _extern _PLOT_SCREEN_U8 Bool PlotScreenU8(I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_U8 Bool PlotWinU8(CTask *task,I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_STR2 Bool PlotWinStr2(
CTask *task,U8 *s,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_ATTR_STR2 Bool PlotAttrStr2(
CTask *task,U32 *hl,I64 len,I64 x,I64 y);
public _extern _PLOT_ATTR Bool PlotWinAttr(
CTask *task,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_BORDER_U8 Bool PlotBorderU8(CTask *task,I64 w,I64 x,I64 y);
_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,U8 *dst,I64 width_internal);
#help_index "Graphics/Misc"
//No clipping
public _extern _IS_PIX_COVERED0 Bool IsPixCovered0(CTask *task,I64 x,I64 y);
_extern _GR_UPDATE_LINE32 U0 GrUpdateLine32(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _GR_UPDATE_LINE32_FLUSH_CACHE U0 GrUpdateLine32FlushCache(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
+1763
View File
File diff suppressed because it is too large. Load diff
+104
View File
@@ -0,0 +1,104 @@
#help_index "Graphics/Char;Char/Graphics"
public U0 PlotScreenStr(U8 *s,I64 attr,I64 x,I64 y)
{
I64 ch;
attr<<=8;
while (ch=*s++) {
PlotScreenU8(ch+attr,x,y);
x++;
}
}
public U0 PlotWinStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
I64 ch;
attr<<=8;
while (ch=*s++) {
PlotWinU8(task,ch+attr,x,y);
x++;
}
}
public U0 PlotBorderStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
I64 ch;
attr<<=8;
while (ch=*s++) {
PlotBorderU8(task,ch+attr,x,y);
x++;
}
}
public U0 DrawBorder(CTask *task,Bool solid,I64 l,I64 r,I64 t,I64 b,I64 attr,Bool clip_to_win)
{
I64 i;
attr<<=8;
if (clip_to_win) {
if (solid) {
PlotWinU8(task,'É'+attr,l-1,t-1);
PlotWinU8(task,'»'+attr,r+1,t-1);
PlotWinU8(task,'È'+attr,l-1,b+1);
PlotWinU8(task,'¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Í'+attr,i,t-1);
PlotWinU8(task,'Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'º'+attr,l-1,i);
PlotWinU8(task,'º'+attr,r+1,i);
}
} else {
PlotWinU8(task,'Ú'+attr,l-1,t-1);
PlotWinU8(task,'¿'+attr,r+1,t-1);
PlotWinU8(task,'À'+attr,l-1,b+1);
PlotWinU8(task,'Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Ä'+attr,i,t-1);
PlotWinU8(task,'Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'³'+attr,l-1,i);
PlotWinU8(task,'³'+attr,r+1,i);
}
}
} else {
if (solid) {
PlotScreenU8('É'+attr,l-1,t-1);
PlotScreenU8('»'+attr,r+1,t-1);
PlotScreenU8('È'+attr,l-1,b+1);
PlotScreenU8('¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Í'+attr,i,t-1);
PlotScreenU8('Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('º'+attr,l-1,i);
PlotScreenU8('º'+attr,r+1,i);
}
} else {
PlotScreenU8('Ú'+attr,l-1,t-1);
PlotScreenU8('¿'+attr,r+1,t-1);
PlotScreenU8('À'+attr,l-1,b+1);
PlotScreenU8('Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Ä'+attr,i,t-1);
PlotScreenU8('Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('³'+attr,l-1,i);
PlotScreenU8('³'+attr,r+1,i);
}
}
}
}
U0 DrawTaskBorder(CTask *task)
{
PUSHFD
CLI
DrawBorder(task,task==sys_focus_task,
task->win_left,task->win_right,
task->win_top,task->win_bottom,
task->border_attr,FALSE);
POPFD
}
+206
View File
@@ -0,0 +1,206 @@
#help_index "Graphics"
public I64 GrRectB(CDC *dc=gr_dc,I64 x1,I64 y1,I64 x2,I64 y2)
{
if (x2<x1) SwapU64(&x1,&x2);
if (y2<y1) SwapU64(&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)
{ //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 GrLineRect4(CDC *dc=gr_dc,I64 x1,I64 y1,I64 x2,I64 y2,I64 step=1,I64 start=0)
{
//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)
{ //transformation with pen width
I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
F64 d;
Bool result=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;
GrReflect(dc,&_x1,&_y1,&_z1);
_x2=x2; _y2=y2; _z2=z2;
GrReflect(dc,&_x2,&_y2,&_z2);
dc->flags&=~DCF_SYMMETRY;
result=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;
result|=Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,_x2,_y2,_z2,&GrPlot3,step);
result|=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;
}
result|=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;
result|=Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,x2,y2,z2,&GrPlot3,step);
result|=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 result;
}
#help_index "Graphics/Char;Char/Graphics"
public Bool GrTextBox3(CDC *dc=gr_dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
U8 *ptr;
I64 ch,result,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;
result=GrPrint(dc,x1,y1,"%s",s);
result|=GrLine(dc,x1-border ,y1-border ,x1+w_max+border,y1-border);
result|=GrLine(dc,x1-border ,y1+h+border,x1+w_max+border,y1+h+border);
result|=GrLine(dc,x1-border ,y1-border ,x1-border,y1+h+border);
result|=GrLine(dc,x1+w_max+border,y1-border ,x1+w_max+border,y1+h+border);
return ToBool(result);
}
#define MAX_DIAMOND_SLOPE 2.75
public Bool GrTextDiamond3(CDC *dc=gr_dc,I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
Bool first=TRUE;
U8 ch,*ptr,*ptr_end,*st,*s;
I64 result=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) {
result|=GrPrint(dc,x1-w,y,"%s",st);
first=FALSE;
} else
result|=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/MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(MAX_DIAMOND_SLOPE*dx));
m=1/MAX_DIAMOND_SLOPE;
} else if (m>MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(dx/MAX_DIAMOND_SLOPE));
m=MAX_DIAMOND_SLOPE;
}
dx=MaxI64(dx,w+Ceil(m*AbsI64(y-y1)));
dx=MaxI64(dx,w+Ceil(m*AbsI64(y+FONT_HEIGHT-y1)));
} while (dx!=dx_old || dy!=dy_old);
}
y+=FONT_HEIGHT;
}
Free(s);
result|=GrLine(dc,x1,y1-dy,x1+dx,y1);
result|=GrLine(dc,x1+dx,y1,x1,y1+dy);
result|=GrLine(dc,x1,y1+dy,x1-dx,y1);
result|=GrLine(dc,x1-dx,y1,x1,y1-dy);
return ToBool(result);
}
#help_index "Graphics/Misc;Input Pointer/Displayed Image"
//Called by $LK,"DrawInputPtr",A="MN:DrawInputPtr"$() which is
//called by $LK,"WinFinalUpdate",A="MN:WinFinalUpdate"$().
public U0 DrawStdInputPtr(CDC *dc,I64 x,I64 y)
{//This is a callback.
dc->pen_width=1;
dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
GrArrow3(dc,x+8,y+8,0,x,y,0);
}
public U0 (*fp_draw_input_ptr)(CDC *dc,I64 x,I64 y)=&DrawStdInputPtr;
public U0 (*fp_draw_grab_input_ptr)(CDC *dc,I64 x,I64 y,Bool closed)=NULL;
public U8 *gr_empty_sprite=NULL; //Gets assigned $LK,"gr_empty_sprite",A="FI:::/Adam/WallPaper.CPP"$
public U0 DrawWaitInputPtr(CDC *dc,I64 x,I64 y)
{//This is a callback.
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;
}
+409
View File
@@ -0,0 +1,409 @@
#help_index "Graphics/Math/3D Transformation"
#help_file "::/Doc/Transform"
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
I64 gr_scale=1<<32;
public U0 GrRot(I64 r[4][4],I64 *_x,I64 *_y,I64 *_z)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;
x1=(r[0][0]*xx+r[0][1]*yy+r[0][2]*zz+r[0][3])>>32;
y1=(r[1][0]*xx+r[1][1]*yy+r[1][2]*zz+r[1][3])>>32;
z1=(r[2][0]*xx+r[2][1]*yy+r[2][2]*zz+r[2][3])>>32;
*_x=x1;*_y=y1;*_z=z1;
}
public U0 GrTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
{//This is a callback.
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
GrRot(dc->r,_x,_y,_z);
*_x+=dc->x;
*_y+=dc->y;
*_z+=dc->z;
}
public I64 *GrIdentNew(CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
I64 *r=CAlloc(sizeof(I64)*16,mem_task);
r[0] .i32[1]=1;
r[5] .i32[1]=1;
r[10].i32[1]=1;
r[15].i32[1]=1;
return r;
}
public I64 *GrIdentEqu(I64 r[4][4])
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
MemSet(r,0,sizeof(I64)*16);
r[0][0].i32[1]=1;
r[1][1].i32[1]=1;
r[2][2].i32[1]=1;
r[3][3].i32[1]=1;
return r;
}
public U0 GrSetRotMat(CDC *dc=NULL,I64 r[4][4])
{//NULL means gr_dc
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
// (1.0/Sqrt(3))*65536=37837.22
I64 xx=37838,yy=37837,zz=37837;
if (!dc) dc=gr_dc;
dc->r=r;
GrRot(r,&xx,&yy,&zz);
//scaled 32 bits
dc->r_norm=Sqrt(xx*xx+yy*yy+zz*zz)*65536;
}
#help_index "Graphics/Mesh"
public U0 GrLighting(CDC *dc,CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)
{//This is a 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=COLOR_TRANSPARENT)
{
if (!dc) dc=gr_dc;
MemSet(dc->body,val,dc->width_internal*dc->height);
}
public U0 DCClear(CDC *dc=NULL)
{
if (!dc) dc=gr_dc;
DCFill(dc,0);
}
public U0 DCRst(CDC *dc)
{
dc->color=BLACK;
dc->color2=BLACK;
dc->bkcolor=BLACK;
dc->collision_cnt=0;
dc->pen_width=1;
dc->ls.x=37837; //1<<16/Sqrt(3)
dc->ls.y=37837;
dc->ls.z=37837;
dc->x=0;
dc->y=0;
dc->z=0;
dc->transform=&GrTransform;
dc->lighting =&GrLighting;
GrIdentEqu(dc->r);
dc->r_norm=gr_scale;
dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
}
public U0 DCExtentsInit(CDC *dc=NULL)
{//NULL means gr_dc
//See $LK,"::/Demo/Graphics/Extents.CPP"$
//You should clear the record flag yourself
if (!dc) dc=gr_dc;
dc->flags|=DCF_RECORD_EXTENTS;
dc->min_x=MAX_I64;
dc->max_x=MIN_I64;
dc->min_y=MAX_I64;
dc->max_y=MIN_I64;
}
public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
{//NULL means gr_dc
CDC *result;
if (!dc) dc=gr_dc;
if (!task) task=Fs;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAlloc(sizeof(CDC),task);
MemCpy(result,dc,sizeof(CDC));
result->win_task=result->mem_task=task;
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->flags|=DCF_ALIAS;
result->alias=dc;
return result;
}
public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
{//This internally only allows widths which are divisible by 8
//Don't forget these $MA-X+PU,"sizeof(CDC)",LM="Grep(\"sizeof(CDC)\",\"/*\");View;"$.
CDC *result;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
result->width=width;
result->width_internal=(width+7)&~7;
result->height=height;
result->body_size=result->width_internal*result->height;
if (null_bitmap)
result->flags|=DCF_DONT_DRAW;
else
result->body=CAlloc(result->body_size,task);
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->dc_signature=DCS_SIGNATURE_VAL;
return result;
}
public U0 DCDel(CDC *dc)
{
if (!dc) return;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
dc->dc_signature=0;
Free(dc->r);
if (!(dc->flags & DCF_ALIAS))
Free(dc->body);
Free(dc->depth_buf);
Free(dc);
}
public I64 DCSize(CDC *dc)
{
if (dc)
return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
else
return 0;
}
public U0 DCDepthBufRst(CDC *dc)
{
if (dc->depth_buf)
MemSetU32(dc->depth_buf,MAX_I32,dc->width_internal*dc->height);
}
public U0 DCAllocDepthBuf(CDC *dc)
{
Free(dc->depth_buf);
dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
DCDepthBufRst(dc);
}
public CDC *DCCopy(CDC *dc,CTask *task=NULL)
{
CDC *result;
if (!dc) return NULL;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAllocIdentical(dc,task);
GrSetRotMat(result,MAllocIdentical(dc->r,task));
result->mem_task=task;
result->body=MAllocIdentical(dc->body,task);
return result;
}
public U0 DCMono(CDC *dc,
I64 quest=COLOR_TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
{
I64 i;
U8 *dst;
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=COLOR_TRANSPARENT)
{
I64 i,result=0;
U8 *dst;
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==src_color) {
*dst++=dst_color;
result++;
} else
dst++;
return result;
}
public U8 *DCSave(CDC *dc,I64 *_size=NULL,Bool compressed=TRUE)
{ //stores to mem
U8 *result,*ptr,*body;
Bool old_preempt;
CArcCompress *ac;
I64 i,old_flags=dc->flags;
if (compressed) {
ac=CompressBuf(dc->body,dc->body_size);
i=ac->compressed_size;
body=ac;
} else {
ac=NULL;
i=dc->body_size;
body=dc->body;
}
ptr=result=MAlloc(offset(CDC.end_saved_area)-
offset(CDC.start_saved_area)+i);
old_preempt=Preempt(OFF); //in case it is a screen bitmap
if (compressed) dc->flags|=DCF_COMPRESSED;
dc->flags&=DCF_COMPRESSED;
MemCpy(result,&dc->start_saved_area,
offset(CDC.end_saved_area)-
offset(CDC.start_saved_area));
dc->flags=old_flags;
Preempt(old_preempt);
ptr+=offset(CDC.end_saved_area)-
offset(CDC.start_saved_area);
MemCpy(ptr,body,i);
ptr+=i;
Free(ac);
if (_size) *_size=ptr-result;
return result;
}
public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
{ //loads from mem
CDC *result;
U8 *ptr=src;
CArcCompress *ac;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
MemCpy(&result->start_saved_area,src,
offset(CDC.end_saved_area)-offset(CDC.start_saved_area));
ptr+=offset(CDC.end_saved_area)-offset(CDC.start_saved_area);
if (result->flags&DCF_COMPRESSED) {
result->flags&=~DCF_COMPRESSED;
ac=ptr;
result->body=ExpandBuf(ac,task);
ptr+=ac->compressed_size;
} else {
result->body=MAlloc(result->body_size,task);
MemCpy(result->body,ptr,result->body_size);
ptr+=result->body_size;
}
result->pen_width=1;
result->r=GrIdentNew(task);
result->r_norm.u32[1]=1;
result->dc_signature=DCS_SIGNATURE_VAL;
if (_size) *_size=ptr-src;
return result;
}
#help_index "Graphics/Device Contexts;Graphics/GRA Files"
public I64 GRAWrite(U8 *filename,CDC *dc)
{ // TempleOS GRA File
I64 size;
U8 *st=DftExt(filename,"GRA.Z"),
*src=DCSave(dc,&size);
FileWrite(st,src,size);
Free(st);
Free(src);
return size;
}
public CDC *GRARead(U8 *filename,CTask *task=NULL)
{ // TempleOS GRA File
CDC *dc=NULL;
U8 *st=DftExt(filename,"GRA.Z"),
*src=FileRead(st);
if (src)
dc=DCLoad(src,,task);
Free(src);
Free(st);
return dc;
}
#help_index "Graphics/Sprite;Graphics/GRA Files;Doc/Output"
public U0 DocGRAFile(CDoc *doc=NULL,U8 *filename)
{//Put a GRA file into a document as a sprite.
CDC *dc=GRARead(filename);
CSprite *elems=DC2Sprite(dc);
DocSprite(doc,elems);
Free(elems);
DCDel(dc);
}
#help_index "Graphics/Device Contexts;Graphics/Screen"
public CDC *DCCaptureScreen(CTask *task=NULL)
{
CDC *dc;
U8 *dst;
WinMgrSync(2,TRUE);
dc=DCCopy(gr_screen_image,task);
dst=MAlloc(dc->body_size,task);
GrBitMap4ToBitMap8(dst,dc->body,dc->body_size/2,COLOR_INVALID);
Free(dc->body);
dc->body=dst;
return dc;
}
#help_index "Graphics/GRA Files;Graphics/Screen"
public I64 GRACaptureScreen(U8 *filename)
{ // TempleOS GRA File
I64 size;
CDC *dc=DCCaptureScreen;
size=GRAWrite(filename,dc);
DCDel(dc);
return size;
}
+28
View File
@@ -0,0 +1,28 @@
#help_index "Graphics/Screen"
U0 CtrlAltZ(I64 sc)
{
if (sc&SCF_SHIFT)
GrScaleZoom(0.5);
else
GrScaleZoom(2.0);
}
SetCtrlAltLetCB('Z',&CtrlAltZ,"Sys/Zoom In or Out");
U0 Screen2Clipboard(I64)
{
CDC *dc=DCCaptureScreen;
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(&Screen2Clipboard);
}
SetCtrlAltLetCB('S',&CtrlAltS,"Sys/Screen Shot to Clipboard");
+49
View File
@@ -0,0 +1,49 @@
#help_index "Graphics/Device Contexts;Graphics/Screen"
public CDC *gr_screen_image, //This is read only.
*gr_dc=NULL; //Persistent
CDC *gr_dc1=NULL,
*gr_dc2=NULL, //Updated every refresh
*gr_dc_cache,
*gr_zoomed_dc;
#help_index "Graphics/Screen"
U16 *gr_win_uncovered_bitmap=NULL,gr_highest_uncovered;
U16 *gr_vga_text_cache;
public I64 gr_pan_text_x=0,gr_pan_text_y=0; // [-7,7]
public U0 (*fp_final_screen_update)(CDC *dc)=NULL;
public U0 (*fp_wall_paper)(CTask *task)=NULL;
#define GR_NUM_PEN_BRUSHES 64
CDC *gr_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_collision_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_even_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_odd_pen_brushes[GR_NUM_PEN_BRUSHES];
#define GR_MAX_SCREEN_ZOOM 8
U8 *gr_screen_zoom_tables[GR_MAX_SCREEN_ZOOM+1];
I64 gr_screen_zoom=1,grsx=0,grsy=0;
//When zoomed, this keeps the mouse centered.
public Bool gr_continuous_scroll=FALSE;
#define GR_REFRESH_LOG_CNT 16
F64 gr_refresh_time_stamps[GR_REFRESH_LOG_CNT];
I64 gr_refresh_ts_ptr=0;
//See $LK,"SYS_BIOS_GR_MODE",A="FF:D:/Kernel/KStart.CPP,SYS_BIOS_GR_MODE:2"$
//See $LK,"SysGrInit",A="MN:SysGrInit"$()
//This allows consts to be used
//instead of vars.
DefinePrint("GR_WIDTH","%d",gr_width);
HashPublic("GR_WIDTH",HTT_DEFINE_STR);
DefinePrint("GR_HEIGHT","%d",gr_height);
HashPublic("GR_HEIGHT",HTT_DEFINE_STR);
;
#help_index "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);
;
+223
View File
@@ -0,0 +1,223 @@
#help_index "Graphics/Screen"
U0 GrSetUpTables()
{
CDC *dc;
I64 i,j,k,l,m,x,y,rr;
U8 *dst;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
if (Bt(&i,j))
gr_1_to_8_bits(U8 *)[k++]=0xFF;
else
gr_1_to_8_bits(U8 *)[k++]=0x00;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
gr_1_to_8_colors(U8 *)[k++]=i;
for (i=0;i<GR_NUM_PEN_BRUSHES;i++) {
k=i+1;
dc=DCNew(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;
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 (text_mode) {
MemSet(VGA_TEXT_MEM_BASE,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
MemSet(gr_vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
} else {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,0x0F);
//Virtual Box crashes on the following for some reason.
// MemSet(VGA_GRAPHIC_MEM_BASE,0,GR_HEIGHT*GR_WIDTH>>3);
MemSet(gr_screen_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
}
for (i=1;i<=GR_MAX_SCREEN_ZOOM;i++) {
dst=gr_screen_zoom_tables[i]=MAlloc(256*i);
for (j=0;j<256;j++) {
m=0;
for (k=0;k<8;k++) {
if (Bt(&j,k)) {
for (l=0;l<i;l++)
Bts(&m,l+k*i);
}
}
for (l=0;l<i;l++)
dst[j+l*256]=m.u8[l];
}
}
for (i=0;i<GR_REFRESH_LOG_CNT;i++)
gr_refresh_time_stamps[i]=tS;
}
#help_index "Graphics/Screen;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()
{ //You might have to call this if you are doing graphics outside
//the window mgr callback routines. Call it if, for example,
//a pop-up window closes and you need to refresh before graphics.
I64 i,z=1;
U16 *ptr;
CTask *task,*task1;
Bool old_preempt=Preempt(OFF);
if (gr_win_z_buf) {
LBtr(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0);
task1=task=sys_winmgr_task;
do {
if (!TaskValidate(task)) break;
if (Bt(&task->display_flags,DISPLAYf_SHOW)) {
task->win_z_num=z++;
WinZBufFill(task);
}
task=task->next_task;
} while (task!=task1 && z<0x10000);
MemSet(gr_win_uncovered_bitmap,0,(gr_highest_uncovered+7)>>3+1);
gr_highest_uncovered=z-1;
for (ptr=gr_win_z_buf,i=TEXT_ROWS*TEXT_COLS;i;i--)
Bts(gr_win_uncovered_bitmap,*ptr++);
}
Preempt(old_preempt);
}
#help_index "Graphics/Char;Char"
public U0 WinTextFill(I64 d,CTask *task=NULL)
{//You probably don't want this.
I64 y,w,t,b,l,r;
if (!task) task=Fs;
if (!TaskValidate(task)) return;
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;
if (w=r-l+1)
for (y=t;y<=b;y++)
MemSetU32(gr_text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),
d,w);
}
U0 GrInit2()
{
SetStdPalette;
fp_set_std_palette=&SetStdPalette;
SetVGAPalette4Indices;
gr_1_to_8_bits =MAlloc(256*sizeof(I64));
gr_1_to_8_colors=MAlloc(256*sizeof(I64));
gr_text_base=CAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U32));
gr_vga_text_cache=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
gr_win_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_SCREEN_BITMAP;
gr_dc_cache=DCNew(GR_WIDTH,GR_HEIGHT);
gr_dc=DCNew(GR_WIDTH,GR_HEIGHT);
gr_dc->flags|=DCF_SCREEN_BITMAP|DCF_ON_TOP;
DCFill;
gr_dc1=DCNew(GR_WIDTH,GR_HEIGHT);
gr_dc1->flags|=DCF_SCREEN_BITMAP;
gr_screen_image=DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
gr_zoomed_dc =DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
gr_zoomed_dc->flags|=DCF_SCREEN_BITMAP;
}
GrInit2;
+101
View File
@@ -0,0 +1,101 @@
#help_index "Graphics/Color"
public I32 gr_rainbow_10[10]=
{
BLACK,BROWN,RED,LTRED,YELLOW,
GREEN,BLUE,PURPLE,LTGRAY,WHITE
};
DefineLstLoad("ST_RAINBOW_10",
"BLACK\0BROWN\0RED\0LTRED\0YELLOW\0"
"GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
U0 SetVGAPalette4Indices()
{//4-bit (16 color)
/*There is a level of indirection we wish to identity map.
This sets the 16-colors to use
the first 16 DAC rgb entries, so
we never need to worry about indexes,
just DAC palette settings.
*/
I64 i;
if (text_mode) return;
PUSHFD
CLI
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
InU8(VGA_INPUT_STAT); //Rsts attr index/data
for (i=0;i<16;i++) {
OutU8(VGA_ATTR_INDEX,i);
OutU8(VGA_ATTR_DATA_WRITE,i);
}
OutU8(VGA_ATTR_INDEX,0x20);
OutU8(VGA_ATTR_DATA_WRITE,0); //Dummy write
InU8(VGA_INPUT_STAT); //Rsts attr index/data
LBtr(&sys_semas[SYS_SEMA_VGA],0);
POPFD
}
public U0 SetVGAPaletteColor(I64 color_num,CBGR bgr)
{ //6-bits per r,dc and g
if (text_mode) return;
PUSHFD
CLI
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_WRITE,color_num);
OutU8(VGA_PALETTE_DATA,bgr.r>>2);
OutU8(VGA_PALETTE_DATA,bgr.g>>2);
OutU8(VGA_PALETTE_DATA,bgr.b>>2);
LBtr(&sys_semas[SYS_SEMA_VGA],0);
POPFD
}
public CBGR GetVGAPaletteColor(I64 color_num)
{ //6-bits per r,dc and g
CBGR result=0;
if (text_mode) return 0;
PUSHFD
CLI
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_READ,color_num);
result.r=InU8(VGA_PALETTE_DATA)<<2;
result.g=InU8(VGA_PALETTE_DATA)<<2;
result.b=InU8(VGA_PALETTE_DATA)<<2;
LBtr(&sys_semas[SYS_SEMA_VGA],0);
POPFD
return result;
}
public CBGR vga_palette4_std[16]={
0x000000,0x0000AA,0x00AA00,0x00AAAA,
0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,
0x555555,0x5555FF,0x55FF55,0x55FFFF,
0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF};
public CBGR vga_palette4_gray[16]={
0x000000,0x111111,0x222222,0x333333,
0x444444,0x555555,0x666666,0x777777,
0x888888,0x999999,0xAAAAAA,0xBBBBBB,
0xCCCCCC,0xDDDDDD,0xEEEEEE,0xFFFFFF};
public U0 GetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
bgr[i]=GetVGAPaletteColor(i);
}
public U0 SetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
SetVGAPaletteColor(i,bgr[i]);
}
public U0 SetStdPalette()
{
SetVGAPalette4(vga_palette4_std);
}
File diff suppressed because it is too large. Load diff
+450
View File
@@ -0,0 +1,450 @@
#help_index "Graphics/Screen"
U0 GrUpdateWins()
{ //Only called by WinMgr
I64 i;
CTask *task,*task1;
CD3I64 saved_scroll;
CDC *dc;
Preempt(OFF);
try {
refresh_ode_time=0;
if (Bt(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0))
WinZBufUpdate;
task1=task=sys_winmgr_task;
do {
if (!TaskValidate(task))
break;
sys_task_being_screen_updated=task;
Preempt(ON);
ODEsUpdate(task);
Preempt(OFF);
if (!TaskValidate(task))
break;
if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
Bt(gr_win_uncovered_bitmap,task->win_z_num))
try {
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
DrawTaskBorder(task);
WinTextFill(task->text_attr<<8,task);
Preempt(ON);
if (task==sys_winmgr_task) {
if (fp_wall_paper)
(*fp_wall_paper)(task);
} else {
if (!(task->win_inhibit&WIF_DOC))
DocUpdateTaskDocs(task);
}
if (TaskValidate(task)) {
if (task->draw_it) {
dc=DCAlias(gr_dc2,task);
(*task->draw_it)(task,dc);
DCDel(dc);
}
if (TaskValidate(task)) {
Preempt(OFF);
WinScrollNull(task,&saved_scroll);
DrawCtrls(task);
WinScrollRestore(task,&saved_scroll);
}
}
Preempt(OFF);
} catch {
if (task!=Fs && TaskValidate(task)) {
LBtr(&task->display_flags,DISPLAYf_SHOW);
"Exception in WinMgr: DrawIt\n";
PutExcept;
Sleep(3000);
VGAFlush;
}
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
for (i=1;i<mp_cnt;i++) {
task1=task=cpu_structs[i].seth_task;
do {
if (!TaskValidate(task))
break;
try {
sys_task_being_screen_updated=task;
Preempt(ON);
ODEsUpdate(task);
Preempt(OFF);
} catch {
LBts(&task->win_inhibit,WIf_ODE);
"Exception in WinMgr: ODE\n";
PutExcept;
Sleep(3000);
VGAFlush;
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
}
} catch {
PutExcept(FALSE);
Dbg("Exception in WinMgr");
}
last_refresh_ode_time=refresh_ode_time;
ode_allocated_factor=LowPass1(0.1,ode_allocated_factor,
Clamp(Gs->idle_factor-0.1,0.2,0.8),1/win_actual_refresh);
sys_task_being_screen_updated=NULL;
gr_refresh_time_stamps[gr_refresh_ts_ptr++&(GR_REFRESH_LOG_CNT-1)]=tS;
win_actual_refresh=(GR_REFRESH_LOG_CNT-1)/
(gr_refresh_time_stamps[(gr_refresh_ts_ptr-1)&(GR_REFRESH_LOG_CNT-1)]-
gr_refresh_time_stamps[gr_refresh_ts_ptr&(GR_REFRESH_LOG_CNT-1)]);
}
U0 GrFixZoomScale()
{
gr_screen_zoom=ClampI64(gr_screen_zoom,1,GR_MAX_SCREEN_ZOOM);
if (gr_screen_zoom==1) {
grsx=0;
grsy=0;
} else {
grsx=ClampI64(grsx,0,GR_WIDTH-GR_WIDTH/gr_screen_zoom)&~7;
grsy=ClampI64(grsy,0,GR_HEIGHT-GR_HEIGHT/gr_screen_zoom);
}
}
public U0 GrScaleZoom(F64 scale)
{
Bool old_preempt=Preempt(OFF);
F64 s=gr_screen_zoom;
gr_screen_zoom=gr_screen_zoom*scale;
GrFixZoomScale;
s/=gr_screen_zoom;
ipx_scale*=s;
ipy_scale*=s;
ipz_scale*=s;
ipx_offset=ipx-(ipx-ipx_offset)*s;
ipy_offset=ipy-(ipy-ipy_offset)*s;
ipz_offset=ipz-(ipz-ipz_offset)*s;
grsx=ipx-gr_zoomed_dc->width >>1/gr_screen_zoom;
grsy=ipy-gr_zoomed_dc->height>>1/gr_screen_zoom;
GrFixZoomScale;
Preempt(old_preempt);
}
U0 GrZoomInScreen()
{
GrFixZoomScale;
I64 plane,row,col,k,l,
d2=gr_zoomed_dc->width>>3/gr_screen_zoom,
d4=gr_zoomed_dc->width_internal>>3,
d5=d4-d2*gr_screen_zoom,
d3=gr_zoomed_dc->height/gr_screen_zoom,
d6=(gr_zoomed_dc->height-d3)*gr_dc1->width_internal>>3,
d7=gr_zoomed_dc->height%gr_screen_zoom*d4;
U8 *src,*src2,*dst,*src3,*map=gr_screen_zoom_tables[gr_screen_zoom];
src=gr_dc1->body+grsx>>3+grsy*gr_dc1->width_internal>>3;
dst=gr_zoomed_dc->body;
for (plane=1;plane<0x10;plane<<=1) {
row=d3;
while (row--) {
k=gr_screen_zoom;
while (k--) {
src2=src;
col=d2;
while (col--) {
src3=&map[*src2++];
l=gr_screen_zoom;
while (l--) {
*dst++=*src3;
src3+=256;
}
}
l=d5;
while (l--)
*dst++=0;
}
src+=d4;
}
l=d7;
while (l--)
*dst++=0;
src+=d6;
}
}
U0 GrUpdateBackgroundOfText()
{
I64 reg RSI *dst=gr_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_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_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 & (DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK && blink_flag)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
}
c=gr_1_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;
}
}
//$AN,"ExtScreenCodes",A="ExtScreenCodes"$
// Bits 0-7 ASCII (Screen Code)
// Bits 8-11 Foreground color
// Bits 12-15 Background color
// Bits 16-20 Signed X pos shift val
// Bits 21-25 Signed Y pos shift val
// Bit 28 Blink
// Bit 29 Inverted (Swap foreground and background)
// Bit 30 Selected (XOR colors with FF)
// Bit 31 Underline
U0 GrUpdateForegroundOfText()
{
U32 *src=gr_text_base;
I64 i,j,cur_ch,*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_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_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 & (DOCET_UNDERLINE | DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK && 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&(DOCET_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
} else
GrRopEquU8NoClipping(cur_ch&(DOCET_UNDERLINE+0xFFF),dst,w1);
dst(U8 *)+=8;
}
src+=w4;
dst(U8 *)+=w2;
}
}
U0 DCBlotColor8(CDC *dc,CDC *img)
{
U8 reg *src=img->body,*b0=dc->body;
I64 reg j,reg k,reg d0=img->width_internal*img->height;
for (k=0;k<d0;k++) {
j=*src++;
if (j!=COLOR_TRANSPARENT)
*b0++=j;
else
b0++;
}
}
U0 GrUpdateTextModeText()
{
U32 *src=gr_text_base;
I64 cur_ch,i,d0=TEXT_COLS*TEXT_ROWS;
U16 *dst=VGA_TEXT_MEM_BASE,*dst2=gr_vga_text_cache;
Bool blink_flag=Blink;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
cur_ch&=0x7FFF;
*dst++=*dst2++=cur_ch;
}
} else {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
cur_ch&=0x7FFF;
if (*dst2!=cur_ch)
*dst++=*dst2++=cur_ch;
else {
dst++;
dst2++;
}
}
}
}
U0 GrUpdateVGAGraphics()
{
I64 row,plane,d2=gr_zoomed_dc->width_internal>>5;
U32 *src,*dst,*dst2;
//Update Graphic Card
if (gr_screen_zoom==1)
src=gr_dc1->body;
else {
GrZoomInScreen;
src=gr_zoomed_dc->body;
}
dst2=gr_screen_image->body;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32FlushCache(&dst,&src,d2,&dst2);
}
} else {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32(&dst,&src,d2,&dst2);
}
}
}
U0 GrUpdateScreen()
{
CDC *dc;
Preempt(ON);
if (text_mode) //If 640x480 VGA is not available, falls back to text mode.
GrUpdateWins;
else {
GrUpdateBackgroundOfText;
GrUpdateForegroundOfText;
GrUpdateWins;
DCBlotColor8(gr_dc2,gr_dc);
}
Preempt(OFF);
dc=DCAlias(gr_dc2,Fs);
dc->flags|=DCF_ON_TOP;
if (fp_final_screen_update)
(*fp_final_screen_update)(dc);
DCDel(dc);
if (text_mode)
GrUpdateTextModeText;
else {
DCBlotColor4(gr_dc1->body,gr_dc2->body,gr_dc_cache->body,
gr_dc2->height*gr_dc2->width_internal>>3);
GrUpdateVGAGraphics;
}
}
+496
View File
@@ -0,0 +1,496 @@
#help_index "Graphics/Sprite"
/*
$LK,"CSprite",A="MN:CSprite"$s are stored as a sequence of var
length operations with a 1-byte type leading
each operation. The types available are lsted
here, $LK,"GRST_PT",A="MN:GRST_PT"$. They are stored, one after another,
in a chunk of memory terminated by a type $LK,"GRST_END",A="MN:GRST_END"$.
$LK,"Sprite3",A="MN:Sprite3"$() and $LK,"SpriteMain",A="MN:SpriteMain"$() shows how the
unions are used. It's kind-of a mess using a union.
$LK,"SpriteSize",A="MN:SpriteSize"$() will return the size of a single
operation, while $LK,"SpriteSize",A="MN:SpriteSize"$() with an 's' will
return the size of an entire lst. Look at
$LK,"sprite_base_size",A="MN:sprite_base_size"$.
To get familiar, type <CTRL-R> on sprite in
a document and select "Display as Text". It
will show the raw data for each CSprite. This
is how they are stored in files, as well.
See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$ for an example of
making CSprite by hand. Those are type
$LK,"GRST_MESH",A="MN:GRST_MESH"$, one of the most complicated.
*/
public U0 Sprite3(CDC *dc=gr_dc,I64 x,I64 y,I64 z,U8 *elems,Bool just_one=FALSE)
{//Plot a sprite into a CDC.
CSprite *tempg=elems-offset(CSprite.start);
I64 i,j,k,x1,y1,z1,x2,y2,
cur_sprite_elem_num=0,*old_r,*r2,
old_flags=dc->flags,
old_pen_width=dc->pen_width;
I32 *ptr;
CColorROPU32 old_color=dc->color;
CDC *img;
CD3I32 *p;
CGrSym old_sym;
MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
while (tempg->type) {
dc->cur_sprite_elem_num=cur_sprite_elem_num++;
switch (tempg->type) {
case GRST_COLOR8:
dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tempg->color8;
break;
case GRST_DITHER_COLOR8:
dc->color=dc->color&~COLORROP_COLORS_MASK|
tempg->dither_color8.u8[0]|
tempg->dither_color8.u8[1]<<COLORROP_BITS|ROPF_DITHER;
break;
case GRST_WIDTH:
dc->pen_width=tempg->width;
GrScalePenWidth(dc);
break;
case GRST_TRANSFORM_ON:
if (!(dc->flags&DCF_TRANSFORMATION)) {
x-=dc->x;
y-=dc->y;
z-=dc->z;
}
dc->flags|=DCF_TRANSFORMATION;
break;
case GRST_TRANSFORM_OFF:
if (dc->flags&DCF_TRANSFORMATION) {
x+=dc->x;
y+=dc->y;
z+=dc->z;
}
dc->flags&=~DCF_TRANSFORMATION;
break;
case GRST_PT:
GrPlot3(dc,tempg->x1+x,tempg->y1+y,z);
break;
case GRST_TEXT:
GrPrint3(dc,tempg->x1+x,tempg->y1+y,z,"%s",tempg->st);
break;
case GRST_TEXT_BOX:
GrTextBox3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_TEXT_DIAMOND:
GrTextDiamond3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_FLOOD_FILL:
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,FALSE);
break;
case GRST_FLOOD_FILL_NOT:
i=dc->color;
dc->color=dc->color.c0;
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,TRUE);
dc->color=i;
break;
case GRST_SHIFT:
x+=tempg->x1;
y+=tempg->y1;
break;
case GRST_LINE:
GrLine3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_ARROW:
GrArrow3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_PLANAR_SYMMETRY:
if (GrSetSymmetry3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z,tempg->x2+x,tempg->y2+y,z+1))
dc->flags|=DCF_SYMMETRY;
else
dc->flags&=~DCF_SYMMETRY;
break;
case GRST_BITMAP8:
img=CAlloc(sizeof(CDC));
img->width=tempg->width;
img->width_internal=(tempg->width+7)&~7;
img->height=tempg->height;
img->body_size=img->width_internal*img->height;
img->body=tempg(U8 *)+offset(CSprite.linespeed);
img->dc_signature=DCS_SIGNATURE_VAL;
GrBlot3(dc,tempg->x2+x,tempg->y2+y,z,img);
Free(img);
break;
case GRST_RECT:
GrRect3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
break;
case GRST_ROTATED_RECT:
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=z;
GrRot(dc->r,&x1,&y1,&z1);
old_r=dc->r;
dc->flags|=DCF_TRANSFORMATION;
r2=GrRotZNew(-tempg->rot_angle);
GrSetTranslation(r2,x1,y1,z1);
GrSetRotMat(dc,GrMulMat(old_r,r2));
GrRect3(dc,0,0,0,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
Free(dc->r);
Free(r2);
GrSetRotMat(dc,old_r);
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
break;
case GRST_CIRCLE:
GrCircle3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2);
break;
case GRST_ELLIPSE:
GrEllipse3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->rot_angle);
break;
case GRST_POLYGON:
GrRegPoly3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->sides,tempg->rot_angle);
break;
case GRST_POLYLINE:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
for (i=1;i<tempg->num;i++) {
x2=ptr[i<<1];
y2=ptr[i<<1+1];
GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);
x1=x2;y1=y2;
}
break;
case GRST_POLYPT:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
ptr+=2;
k=tempg->num*3;
GrPlot3(dc,x1+x,y1+y,z);
for (i=0;i<k;i+=3) {
j=BFieldExtU32(ptr,i,3);
x1+=gr_x_offsets[j];
y1+=gr_y_offsets[j];
GrPlot3(dc,x1+x,y1+y,z);
}
break;
sub_switch_start:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
case GRST_BSPLINE2:
Gr2BSpline3(dc,&tempg->y1,tempg->num,FALSE);
break;
case GRST_BSPLINE3:
Gr3BSpline3(dc,&tempg->y1,tempg->num,FALSE);
break;
case GRST_BSPLINE2_CLOSED:
Gr2BSpline3(dc,&tempg->y1,tempg->num,TRUE);
break;
case GRST_BSPLINE3_CLOSED:
Gr3BSpline3(dc,&tempg->y1,tempg->num,TRUE);
break;
sub_switch_end:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_MESH:
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3Mesh(dc,tempg->vertex_cnt,&tempg->x2,tempg->tri_cnt,(&tempg->x2)(U8 *)+sizeof(CD3I32)*tempg->vertex_cnt);
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_SHIFTABLE_MESH:
if (dc->flags&DCF_TRANSFORMATION) {
dc->x+=tempg->x1;
dc->y+=tempg->y1;
dc->z+=tempg->z1;
x1=x;
y1=y;
z1=z;
} else {
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=tempg->z1+z;
}
p=(&tempg->shiftable_tri_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x+=x1;
p->y+=y1;
p->z+=z1;
}
p=(&tempg->shiftable_tri_cnt)(U8 *)+sizeof(I32);
Gr3Mesh(dc,tempg->shiftable_vertex_cnt,p,tempg->shiftable_tri_cnt,p(U8 *)+sizeof(CD3I32)*tempg->shiftable_vertex_cnt);
p=(&tempg->shiftable_tri_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x-=x1;
p->y-=y1;
p->z-=z1;
}
if (dc->flags&DCF_TRANSFORMATION) {
dc->x-=tempg->x1;
dc->y-=tempg->y1;
dc->z-=tempg->z1;
}
break;
}
if (just_one) break;
tempg(U8 *)+=SpriteElemSize(tempg);
}
MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));
dc->color=old_color;
dc->pen_width=old_pen_width;
dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |
old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);
}
public U0 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 SpriteMat3B(CDC *dc=gr_dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
{//Plot rotated by matrix
I64 *old_r=dc->r,old_m[16],
old_flags=dc->flags&DCF_TRANSFORMATION;
MemCpy(old_m,m,16*sizeof(I64));
dc->flags|=DCF_TRANSFORMATION;
GrAddTranslation(m,x,y,z);
dc->r=GrMulMat(old_r,m);
Sprite3(dc,0,0,0,elems);
Free(dc->r);
dc->r=old_r;
MemCpy(m,old_m,16*sizeof(I64));
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
}
public U0 SpriteX3B(CDC *dc=gr_dc,I64 x,I64 y,I64 z,U8 *elems,F64 è=0)
{//Plot rotated around X axis
I64 *r=GrRotXNew(è);
SpriteMat3B(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpriteY3B(CDC *dc=gr_dc,I64 x,I64 y,I64 z,U8 *elems,F64 ê=0)
{//Plot rotated around Y axis
I64 *r=GrRotYNew(ê);
SpriteMat3B(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpriteZ3B(CDC *dc=gr_dc,I64 x,I64 y,I64 z,U8 *elems,F64 é=0)
{//Plot rotated around Z axis
I64 *r=GrRotZNew(é);
SpriteMat3B(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,
I64 *min_y=NULL,I64 *max_y=NULL)
{ //Ignores flood fills.
CDC *dc=DCNew(MAX_I32,MAX_I32,Fs,TRUE);
DCExtentsInit(dc);
Sprite3(dc,MAX_I32/2,MAX_I32/2,MAX_I32/2,elems);
if (dc->min_x<=dc->max_x) {
dc->min_x-=MAX_I32/2;
dc->max_x-=MAX_I32/2;
}
if (dc->min_y<=dc->max_y) {
dc->min_y-=MAX_I32/2;
dc->max_y-=MAX_I32/2;
}
if (min_x) *min_x=dc->min_x;
if (max_x) *max_x=dc->max_x;
if (min_y) *min_y=dc->min_y;
if (max_y) *max_y=dc->max_y;
DCDel(dc);
}
public CDC *Sprite2DC(U8 *elems)
{
CDC *result;
I64 min_x,max_x,min_y,max_y;
SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
result=DCNew(max_x-min_x+1,max_y-min_y+1);
Sprite3(result,-min_x,-min_y,0,elems);
return result;
}
public U8 *SpriteInterpolate(U8 *elems0,U8 *elems1,F64 t)
{
//The two CSprite should be identical
//except for points shifted around.
//t ranges from 0.0 to 1.0
I64 i,t1=gr_scale*t,t0=gr_scale-t1;
I32 *ptr0,*ptr1,*ptrr;
CD3I32 *p0,*p1,*pr;
U8 *result;
CSprite *tempg0=elems0-offset(CSprite.start),
*tempg1=elems1-offset(CSprite.start),*tempgr;
if (t<0.5) {
i=SpriteSize(elems0),
result=MAlloc(i);
MemCpy(result,elems0,i);
} else {
i=SpriteSize(elems1),
result=MAlloc(i);
MemCpy(result,elems1,i);
}
tempgr=result-offset(CSprite.start);
while (tempg0->type) {
if (tempg0->type!=tempg1->type)
throw('Graphics');
switch (tempg0->type) {
case GRST_ROTATED_RECT:
tempgr->rot_angle=(tempg0->rot_angle*t0+tempg1->rot_angle*t1)/gr_scale;
case GRST_RECT:
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_CIRCLE:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_ELLIPSE:
case GRST_POLYGON:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
tempgr->width=(tempg0->width*t0+tempg1->width*t1)>>32;
tempgr->height=(tempg0->height*t0+tempg1->height*t1)>>32;
break;
case GRST_BITMAP8:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
break;
case GRST_POLYLINE:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
for (i=0;i<tempg0->num;i++) {
ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;
ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;
}
break;
case GRST_POLYPT:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
ptrr[0]=(ptr0[0]*t0+ptr1[0]*t1)>>32;
ptrr[1]=(ptr0[1]*t0+ptr1[1]*t1)>>32;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
p0=&tempg0->y1;
p1=&tempg1->y1;
pr=&tempgr->y1;
for (i=0;i<tempg0->num;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
case GRST_MESH:
p0=&tempg0->x2;
p1=&tempg1->x2;
pr=&tempgr->x2;
for (i=0;i<tempg0->vertex_cnt;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
case GRST_SHIFTABLE_MESH:
p0=(&tempg0->shiftable_tri_cnt)(U8 *)+sizeof(I32);
p1=(&tempg1->shiftable_tri_cnt)(U8 *)+sizeof(I32);
pr=(&tempgr->shiftable_tri_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg0->shiftable_vertex_cnt;i++) {
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
}
break;
}
tempg0(U8 *)+=SpriteElemSize(tempg0);
tempg1(U8 *)+=SpriteElemSize(tempg1);
tempgr(U8 *)+=SpriteElemSize(tempgr);
}
return result;
}
#help_index "Graphics/Sprite;Doc/Output"
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,"Dollar",A="FI:::/Doc/Dollar.TXT"$ cmd with a %d for the bin_num.
I64 size;
U8 *st;
Bool unlock;
CDocEntry *doc_e;
CDocBin *tempb;
if (!doc && !(doc=DocPut)) return NULL;
unlock=DocLock(doc);
size=SpriteSize(elems);
tempb=CAlloc(sizeof(CDocBin),doc->mem_task);
tempb->size=size;
tempb->data=MAlloc(size,doc->mem_task);
MemCpy(tempb->data,elems,size);
tempb->num=doc->cur_bin_num;
tempb->use_cnt=1;
QueIns(tempb,doc->bin_root.last);
if (fmt)
st=MPrint(fmt,doc->cur_bin_num++);
else
st=MPrint("$$SP,\"\",BI=%d$$",doc->cur_bin_num++);
doc_e=DocPrint(doc,"%s",st);
Free(st);
doc_e->bin_data=tempb;
if (doc_e && doc_e->flags1&DOCEF1_TAG && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,doc->mem_task);
if (unlock)
DocUnlock(doc);
return doc_e;
}
public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)
{
//If you set fmt,
//then include dollarsigns ("$$SP ...$$")
//and leave a %d for the number.
CDoc *doc;
if (doc=DocPut)
return DocSprite(doc,elems,fmt);
return NULL;
}
+879
View File
@@ -0,0 +1,879 @@
#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)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
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 *GrRotXNew(F64 è,CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(è)*gr_scale,
my_sin=Sin(è)*gr_scale;
I64 *r=CAlloc(sizeof(I64)*16,mem_task);
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 r;
}
public I64 *GrRotYNew(F64 ê,CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(ê)*gr_scale,
my_sin=Sin(ê)*gr_scale;
I64 *r=CAlloc(sizeof(I64)*16,mem_task);
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 r;
}
public I64 *GrRotZNew(F64 é,CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(é)*gr_scale,
my_sin=Sin(é)*gr_scale;
I64 *r=CAlloc(sizeof(I64)*16,mem_task);
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 r;
}
public I64 *GrScaleNew(I64 *m1,F64 s,CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
I64 i,*r=CAlloc(sizeof(I64)*16,mem_task);
for (i=0;i<16;i++)
r[i]=m1[i]*s;
return r;
}
public I64 *GrMulMat(I64 *m1,I64 *m2,CTask *mem_task=NULL)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
//Conceptually, the transform m1 is applied after m2
I64 i,j,k,*r=CAlloc(sizeof(I64)*16,mem_task);
F64 d;
for (i=0;i<4;i++) {
for (j=0;j<4;j++) {
for (k=0;k<4;k++) {
d=m1[k+4*j];
d*=m2[i+4*k]; //TODO! Possible overflow if norm > one.
d/=gr_scale;
r[i+4*j]+=d;
}
}
}
return r;
}
public I64 *GrRotXEqu(I64 *m1,F64 è)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(è)*gr_scale,
my_sin=Sin(è)*gr_scale;
I64 r[16],*r2;
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;
r2=GrMulMat(r,m1);
MemCpy(m1,r2,sizeof(I64)*16);
Free(r2);
return m1;
}
public I64 *GrRotYEqu(I64 *m1,F64 ê)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(ê)*gr_scale,
my_sin=Sin(ê)*gr_scale;
I64 r[16],*r2;
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;
r2=GrMulMat(r,m1);
MemCpy(m1,r2,sizeof(I64)*16);
Free(r2);
return m1;
}
public I64 *GrRotZEqu(I64 *m1,F64 é)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
F64 my_cos=Cos(é)*gr_scale,
my_sin=Sin(é)*gr_scale;
I64 r[16],*r2;
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;
r2=GrMulMat(r,m1);
MemCpy(m1,r2,sizeof(I64)*16);
Free(r2);
return m1;
}
public I64 *GrScaleEqu(I64 *m1,F64 s)
{
I64 i;
for (i=0;i<16;i++)
m1[i]*=s;
return m1;
}
public U0 GrScalePenWidth(CDC *dc=gr_dc)
{
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 *GrSetTranslation(I64 r[4][4],I64 x,I64 y,I64 z)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
r[0][3]=x<<32;
r[1][3]=y<<32;
r[2][3]=z<<32;
r[3][3]=gr_scale;
return r;
}
public I64 *GrAddTranslation(I64 r[4][4],I64 x,I64 y,I64 z)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
r[0][3]+=x<<32;
r[1][3]+=y<<32;
r[2][3]+=z<<32;
r[3][3]=gr_scale;
return r;
}
public Bool GrSetSymmetry(CDC *dc=gr_dc,I64 x1,I64 y1,I64 x2,I64 y2)
{
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 GrSetSymmetry3(CDC *dc=gr_dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,I64 x3,I64 y3,I64 z3)
{
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 GrReflect(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
{
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
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 SCALE1 24
#define SCALE2 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*ã)
{
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<<SCALE1*Cos(t);
if (step<0) {
step=-step;
s2=1<<SCALE1*Sin(t);
s1=-s2;
} else {
s1=1<<SCALE1*Sin(t);
s2=-s1;
}
if (start_radians) {
x=radius*Cos(start_radians);
y=-radius*Sin(start_radians);
} else {
x=radius;
y=0;
}
x<<=SCALE2;
y<<=SCALE2;
for (i=0;i<=len;i+=step) {
if (!(*fp_plot)(aux_data,cx+x>>SCALE2,cy+y>>SCALE2,cz))
return FALSE;
for (j=0;j<step;j++) {
x1=(c*x+s1*y)>>SCALE1;
y1=(s2*x+c*y)>>SCALE1;
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*ã)
{
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<<SCALE1*Cos(t);
if (step<0) {
step=-step;
s2=1<<SCALE1*Sin(t);
s1=-s2;
} else {
s1=1<<SCALE1*Sin(t);
s2=-s1;
}
c2=1<<SCALE1*Cos(rot_angle);
s12=1<<SCALE1*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<<=SCALE2;
y<<=SCALE2;
x2=x;
y2=y;
y1=y2*y_radius/x_radius;
x=(c2*x2+s12*y1)>>SCALE1;
y=(s22*x2+c2*y1)>>SCALE1;
for (i=0;i<=len;i+=step) {
if ((x>>SCALE2!=_x || y>>SCALE2!=_y || first) &&
!(*fp_plot)(aux_data,cx+x>>SCALE2,cy+y>>SCALE2,cz))
return FALSE;
_x=x>>SCALE2; _y=y>>SCALE2; first=FALSE;
for (j=0;j<step;j++) {
x1=(c*x2+s1*y2)>>SCALE1;
y1=(s2*x2+c*y2)>>SCALE1;
x2=x1;
y2=y1;
y1=y1*y_radius/x_radius;
x=(c2*x1+s12*y1)>>SCALE1;
y=(s22*x1+c2*y1)>>SCALE1;
}
}
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*ã)
{
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<<SCALE1*Sin(angle_step);
s2=-s1;
c=1<<SCALE1*Cos(angle_step);
s12=1<<SCALE1*Sin(rot_angle);
s22=-s12;
c2=1<<SCALE1*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<<=SCALE2;
y<<=SCALE2;
x2=x;
y2=y;
y1=y2*y_radius/x_radius;
x=(c2*x2+s12*y1)>>SCALE1;
y=(s22*x2+c2*y1)>>SCALE1;
xx1=cx+x>>SCALE2;
yy1=cy+y>>SCALE2;
for (i=0;i<n;i++) {
x1=(c*x2+s1*y2)>>SCALE1;
y1=(s2*x2+c*y2)>>SCALE1;
x2=x1;
y2=y1;
y1=y1*y_radius/x_radius;
x=(c2*x1+s12*y1)>>SCALE1;
y=(s22*x1+c2*y1)>>SCALE1;
xx2=cx+x>>SCALE2;
yy2=cy+y>>SCALE2;
if (!Line(aux_data,xx1,yy1,cz,xx2,yy2,cz,fp_plot,step))
return FALSE;
xx1=xx2; yy1=yy2;
}
return TRUE;
}
#help_index "Graphics/CD3I32;Math/CD3I32"
public F64 D3I32Dist(CD3I32 *p1,CD3I32 *p2)
{
return Sqrt(SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z));
}
public I64 D3I32SqrDist(CD3I32 *p1,CD3I32 *p2)
{
return SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z);
}
public F64 D3I32Norm(CD3I32 *p)
{
return Sqrt(SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z));
}
public I64 D3I32SqrNorm(CD3I32 *p)
{
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)
{//2nd order
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)
{ //3rd order
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)
{ //2nd order
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)
{ //3rd order
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)
{
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;
}
}
}
+685
View File
@@ -0,0 +1,685 @@
#help_index "Graphics/Sprite"
#define GEBM_EXIT 0
#define GEBM_MAIN_MENU 1
#define GEBM_COLOR 2
#define GEBM_DITHER_COLOR 3
#define GEBM_WIDTH 4
#define GEBM_PT 5
#define GEBM_LINE 6
#define GEBM_ARROW 7
#define GEBM_RECT 8
#define GEBM_CIRCLE 9
#define GEBM_TEXT 10
#define GEBM_TEXT_BOX 11
#define GEBM_TEXT_DIAMOND 12
#define GEBM_FLOOD_FILL 13
#define GEBM_FLOOD_FILL_NOT 14
#define GEBM_POLYLINE 15
#define GEBM_POLYPT 16
#define GEBM_COPY 17
#define GEBM_DELETE 18
#define GEBM_PASTE 19
#define GEBM_PASTE_TRANSPARENT 20
#define GEBM_FIND_AND_REPLACE 21
#define GEBM_TRIM_TO_EXTENTS 22
#define GEBM_ADD_OUTLINE 23
#define GEBM_ETCH 24
#define GEBM_UNDO 25
#define GEBM_SAVE_BMP 26
#define GEBM_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 GRA\0");
}
GrInit4;
I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width)
{
I64 i;
U8 *st1,*st2,buf[136];
CDoc *doc=DocNew;
Color2Text(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.TXT.Z\"$$\n"
"\n$$LTBLUE$$$$MU-UL,\"Color %s\",LE=GEBM_COLOR$$\n"
"$$MU-UL,\"Dither Color %s\",LE=GEBM_DITHER_COLOR$$\n"
"$$MU-UL,\"Width %d\",LE=GEBM_WIDTH$$\n"
"$$MU-UL,\"Find & Replace Color\",LE=GEBM_FIND_AND_REPLACE$$\n"
"$$MU-UL,\"Trim to Extents\",LE=GEBM_TRIM_TO_EXTENTS$$\n"
"$$MU-UL,\"Add Outline\",LE=GEBM_ADD_OUTLINE$$\n"
"$$MU-UL,\"Etch\",LE=GEBM_ETCH$$\n"
"\n$$MU-UL,\"Point\",LE=GEBM_PT$$\n"
"$$MU-UL,\"Line\",LE=GEBM_LINE$$\n"
"$$MU-UL,\"Arrow\",LE=GEBM_ARROW$$\n"
"$$MU-UL,\"Rect\",LE=GEBM_RECT$$\n"
"$$MU-UL,\"Circle\",LE=GEBM_CIRCLE$$\n"
"$$MU-UL,\"Text\",LE=GEBM_TEXT$$\n"
"$$MU-UL,\"Text Box\",LE=GEBM_TEXT_BOX$$\n"
"$$MU-UL,\"Text Diamond\",LE=GEBM_TEXT_DIAMOND$$\n"
"$$MU-UL,\"Flood Fill\",LE=GEBM_FLOOD_FILL$$\n"
"$$MU-UL,\"Flood Fill Not Color\",LE=GEBM_FLOOD_FILL_NOT$$\n"
"$$MU-UL,\"PolyLine\",LE=GEBM_POLYLINE$$\n"
"$$MU-UL,\"PolyPoint\",LE=GEBM_POLYPT$$\n"
"\n$$MU-UL,\"Copy to Clipboard\",LE=GEBM_COPY$$\n"
"$$MU-UL,\"Delete to Clipboard\",LE=GEBM_DELETE$$\n"
"$$MU-UL,\"Paste Clipboard\",LE=GEBM_PASTE$$\n"
"$$MU-UL,\"Paste Transparent Clipboard\",LE=GEBM_PASTE_TRANSPARENT$$\n"
"\n$$MU-UL,\"Save BMP File\",LE=GEBM_SAVE_BMP$$\n"
"$$MU-UL,\"Save GRA File\",LE=GEBM_SAVE_GRA$$\n"
"\n$$MU-UL,\"Undo\",LE=GEBM_UNDO$$\n"
"\n$$PURPLE$$$$MU-UL,\"+] Sprite Main Menu\",LE=GEBM_MAIN_MENU$$$$LTBLUE$$\n"
"$$MU-UL,\"Exit Sprite\",LE=GEBM_EXIT$$\n"
"$$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$$\n",st1,st2,width);
DocPrint(doc,"\nRight-Click to get back to this menu.");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U0 GrBMEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
{
DCFill(dc);
GrBlot(dc,xx1,yy1,img);
}
U0 GrBMETrimToExtents(CDC **_img,I64 *_xx1,I64 *_yy1,I64 *_xx2,I64 *_yy2,CColorROPU32 bkcolor)
{
CDC *img=*_img;
I64 i,c,
x1=0,y1=0,x2=img->width-1,y2=img->height-1; //inclusive
while (y1<y2) {
for (i=x1;i<=x2;i++) {
c=GrPeek(img,i,y1);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_y2;
}
y1++;
}
tr_y2:
while (y1<y2) {
for (i=x1;i<=x2;i++) {
c=GrPeek(img,i,y2);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_x1;
}
y2--;
}
tr_x1:
while (x1<x2) {
for (i=y1;i<=y2;i++) {
c=GrPeek(img,x1,i);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_x2;
}
x1++;
}
tr_x2:
while (x1<x2) {
for (i=y1;i<=y2;i++) {
c=GrPeek(img,x2,i);
if (c!=bkcolor&&c!=COLOR_TRANSPARENT) goto tr_done;
}
x2--;
}
tr_done:
*_img=DCExtract(img,x1,y1,x2,y2);
*_xx1+=x1; *_yy1+=y1;
*_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
DCDel(img);
}
U0 GrBMEAddOutline(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=DCExtract(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 GrBMEEtch(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=DCExtract(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 SpriteBitMap(CDoc *,CDocEntry *doc_e,CDC *dc,I64 *_xx1,I64 *_yy1,I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor)
{
I64 i,j,mode=GEBM_LINE,color=BLACK,width=1,msg_code,p1,p2,x1,y1,x11,y11,x22,y22,
result,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2,
old_e_flags1=doc_e->flags1;
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->flags1|=DOCEF1_DONT_DRAW;
goto bm_menu;
while (TRUE) {
if (sys_cur_scan_code&SCF_CTRL)//grab scroll update?
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrLineRect4(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
while (msg_code=ScanMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_IP_L_UP|1<<MSG_IP_R_DOWN|
1<<MSG_IP_MOVE|1<<MSG_KEY_DOWN)) {
switch (msg_code) {
case MSG_KEY_DOWN:
if (p1==CH_SHIFT_ESC) {
result=GE_ABORT;
goto bm_key_up_done;
} else if (p1==CH_ESC) {
result=GE_CONT;
goto bm_key_up_done;
}
break;
case MSG_IP_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:
result=GE_ABORT;
goto bm_done;
case GEBM_EXIT:
result=GE_EXIT;
goto bm_done;
case GEBM_MAIN_MENU:
result=GE_CONT;
goto bm_done;
case GEBM_COLOR:
i=PopUpColor(,,FALSE);
if (i>=0) color=i;
goto bm_menu;
case GEBM_FIND_AND_REPLACE:
i=PopUpColor("Find Color\n",,FALSE);
if (i>=0) {
j=PopUpColor("Replace Color\n",,FALSE);
if (j>=0) {
DCColorChg(img,i,j);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
}
goto bm_menu;
case GEBM_TRIM_TO_EXTENTS:
GrBMETrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
goto bm_menu;
case GEBM_ADD_OUTLINE:
i=PopUpRangeI64(1,16,1,"Outline Width\n");
if (i>=0) {
GrBMEAddOutline(img,i,color,bkcolor);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
goto bm_menu;
case GEBM_ETCH:
i=PopUpRangeI64(1,16,1,"Etch Width\n");
if (i>=0) {
GrBMEEtch(img,i,bkcolor);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
goto bm_menu;
case GEBM_SAVE_BMP:
*filename.name=0;
if (DocFormDo(&filename) && *filename.name)
BMPFileWrite(filename.name,img);
goto bm_menu;
case GEBM_SAVE_GRA:
*filename.name=0;
if (DocFormDo(&filename) && *filename.name)
GRAWrite(filename.name,img);
goto bm_menu;
case GEBM_DITHER_COLOR:
i=PopUpColorDither;
if (i>=0) color=i;
goto bm_menu;
case GEBM_WIDTH:
i=PopUpRangeI64(1,16,1,"Pen Width\n");
if (i>=0) width=i;
goto bm_menu;
case GEBM_UNDO:
if (undo) {
Beep;
img->color=ROP_EQU;
GrBlot(img,0,0,undo);
DCDel(undo);
undo=NULL;
}
goto bm_menu;
case GEBM_PT:
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_FLOOD_FILL:
case GEBM_FLOOD_FILL_NOT:
case GEBM_POLYPT:
case GEBM_POLYLINE:
case GEBM_COPY:
case GEBM_DELETE:
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
mode=i;
break;
case GEBM_TEXT:
case GEBM_TEXT_BOX:
case GEBM_TEXT_DIAMOND:
Free(st);
st=PopUpMGetS("Enter text and press <ESC>.\n");
if (st && *st)
mode=i;
else
goto bm_menu;
break;
}
DCDel(undo);
undo=DCExtract(img,0,0,img->width-1,img->height-1);
undo->bkcolor=bkcolor;
WinMgrSync(2,TRUE); //Let popup close
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
down=FALSE;
break;
case MSG_IP_L_DOWN:
switch (mode) {
case GEBM_PT:
img->color=color;
img->pen_width=width;
GrPlot3(img,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_COPY:
case GEBM_DELETE:
if (down)
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
switch (mode) {
case GEBM_LINE:
GrLine3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_ARROW:
GrArrow3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_RECT:
GrRect(dc,x1,y1,1,1);
break;
case GEBM_CIRCLE:
GrCircle3(dc,x1,y1,0,1);
break;
case GEBM_COPY:
case GEBM_DELETE:
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x1,y1,x1,y1);
break;
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPrint(dc,p1,p2,"%s",st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_FLOOD_FILL:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_FLOOD_FILL_NOT:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1,TRUE);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_POLYLINE:
if (!down) {
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_POLYPT:
x1=p1; y1=p2;
down=TRUE;
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
}
break;
case MSG_IP_MOVE:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYLINE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(dc,x1,y1,0,p1,p2,0);
else
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_RECT:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=color;
GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
}
break;
case GEBM_COPY:
case GEBM_DELETE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x11,y11,x22,y22);
}
break;
case GEBM_CIRCLE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPrint(dc,p1,p2,"%s",st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_POLYPT:
if (down) {
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
}
break;
}
break;
case MSG_IP_L_UP:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYPT:
case GEBM_POLYLINE:
img->color=color;
img->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
else
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_POLYLINE) {
x1=p1; y1=p2;
} else
down=FALSE;
break;
case GEBM_RECT:
img->color=color;
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_COPY:
case GEBM_DELETE:
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
DCDel(clipboard);
clipboard=DCExtract(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
clipboard->bkcolor=bkcolor;
if (mode==GEBM_DELETE) {
img->color=bkcolor;
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
}
goto bm_menu;
case GEBM_CIRCLE:
img->color=color;
img->pen_width=width;
GrCircle3(img,x1-xx1,y1-yy1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(img,p1-xx1,p2-yy1,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(img,p1-xx1,p2-yy1,dc2);
DCDel(dc2);
}
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
break;
case GEBM_TEXT:
img->color=color;
GrPrint(img,p1-xx1,p2-yy1,"%s",st);
goto bm_menu;
case GEBM_TEXT_BOX:
img->color=color;
GrTextBox3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
case GEBM_TEXT_DIAMOND:
img->color=color;
GrTextDiamond3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
}
break;
}
}
WinMgrSync;
}
bm_key_up_done:
GetMsg(,,1<<MSG_KEY_UP);
bm_done:
DCDel(clipboard);
DCDel(undo);
Free(st);
DCFill(dc);
SettingsPop;
doc_e->flags1=old_e_flags1;
*_img=img;
*_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
return result;
}
+1252
View File
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
+175
View File
@@ -0,0 +1,175 @@
#help_index "Graphics/Sprite"
#help_file "::/Doc/Sprite"
I64 sprite_base_size[GRST_NUM_TYPES]=
{
offset(CSprite.x1)-offset(CSprite.start), //GRST_END
1+offset(CSprite.color8)-offset(CSprite.start), //GRST_COLOR8
2+offset(CSprite.dither_color8)-offset(CSprite.start), //GRST_DITHER_COLOR8
offset(CSprite.y1)-offset(CSprite.start), //GRST_WIDTH
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_PLANAR_SYMMETRY
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_ON
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_OFF
offset(CSprite.x2)-offset(CSprite.start), //GRST_SHIFT
offset(CSprite.x2)-offset(CSprite.start), //GRST_PT
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYPT
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_LINE
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYLINE
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_RECT
offset(CSprite.sides)-offset(CSprite.start), //GRST_ROTATED_RECT
offset(CSprite.y2)-offset(CSprite.start), //GRST_CIRCLE
offset(CSprite.sides)-offset(CSprite.start), //GRST_ELLIPSE
sizeof(CSprite)-offset(CSprite.start), //GRST_POLYGON
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2_CLOSED
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3_CLOSED
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL_NOT
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_BITMAP8
offset(CSprite.x2)-offset(CSprite.start), //GRST_MESH
offset(CSprite.shiftable_tri_cnt)+sizeof(I32)-offset(CSprite.start), //GRST_SHIFTABLE_MESH
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_ARROW
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_BOX
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_DIAMOND
};
I64 SpriteQuedBaseSize(I64 type)
{
return sprite_base_size[type]+offset(CSprite.start);
}
I64 SpriteElemSize(CSprite *tempg)
{
I64 i=sprite_base_size[tempg->type];
switch (tempg->type) {
case GRST_POLYLINE:
i+=tempg->num<<1*sizeof(I32);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
i+=StrLen(tempg->st)+1;
break;
case GRST_BITMAP8:
i+=((tempg->width+7)&~7)*tempg->height;
break;
case GRST_POLYPT:
i+=sizeof(I32)<<1+(tempg->num*3+7)>>3;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
i+=tempg->num*sizeof(CD3I32);
break;
case GRST_MESH:
i+=tempg->vertex_cnt*sizeof(CD3I32)+tempg->tri_cnt*sizeof(CMeshTri);
break;
case GRST_SHIFTABLE_MESH:
i+=tempg->shiftable_vertex_cnt*sizeof(CD3I32)+tempg->shiftable_tri_cnt*sizeof(CMeshTri);
break;
}
return i;
}
public I64 SpriteSize(U8 *elems)
{
CSprite *tempg=elems-offset(CSprite.start),*tempg1=tempg;
while (tempg->type)
tempg(U8 *)+=SpriteElemSize(tempg);
return tempg(U8 *)-tempg1(U8 *)+sprite_base_size[GRST_END];
}
I64 SpriteTypeMask(U8 *elems)
{
I64 result=0;
CSprite *tempg=elems-offset(CSprite.start);
while (tempg->type) {
if (tempg->type>=GRST_NUM_TYPES)
return 1<<GRST_NUM_TYPES;
Bts(&result,tempg->type);
tempg(U8 *)+=SpriteElemSize(tempg);
}
return result;
}
public U8 *DC2Sprite(CDC *tempb)
{
CSprite *tempg;
tempg=CAlloc(sprite_base_size[GRST_BITMAP8]+
tempb->width_internal*tempb->height+
sprite_base_size[GRST_END])
(U8 *)-offset(CSprite.start);
tempg->type=GRST_BITMAP8;
tempg->width=tempb->width;
tempg->height=tempb->height;
tempg->x2=0;
tempg->y2=0;
MemCpy(tempg(U8 *)+offset(CSprite.linespeed),tempb->body,
tempb->width_internal*tempb->height);
return tempg(U8 *)+offset(CSprite.start);
}
public U8 *Sprite2Text(CSprite *tempg)
{ //Study $LK,"::/Demo/Graphics/SpriteText.CPP"$.
U8 buf[256],buf2[136];
I32 *ptr;
SPrint(buf,"%Z",tempg->type,"ST_SPRITE_TYPES");
switch (tempg->type) {
case GRST_COLOR8:
CatPrint(buf," %s",Color2Text(buf2,tempg->color8));
break;
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
CatPrint(buf," %d,%d",tempg->x1,tempg->y1);
break;
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
case GRST_RECT:
case GRST_ROTATED_RECT:
CatPrint(buf," (%d,%d)-(%d,%d)",tempg->x1,tempg->y1,tempg->x2,tempg->y2);
break;
case GRST_CIRCLE:
CatPrint(buf," %d,%d:%dR",tempg->x1,tempg->y1,tempg->x2);
break;
case GRST_WIDTH:
CatPrint(buf," %d",tempg->width);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
CatPrint(buf," %d,%d:%-16tQ",tempg->x1,tempg->y1,tempg->st);
break;
case GRST_DITHER_COLOR8:
CatPrint(buf," %s",Color2Text(buf2,ROPF_DITHER|tempg->dither_color8.u8[0]|tempg->dither_color8.u8[1]<<COLORROP_BITS));
break;
case GRST_POLYLINE:
case GRST_POLYPT:
ptr=&tempg->y1;
CatPrint(buf," %d %d,%d",tempg->num,ptr[0],ptr[1]);
break;
case GRST_ELLIPSE:
case GRST_POLYGON:
case GRST_BITMAP8:
CatPrint(buf," %dW,%dH:%d,%d",tempg->width,tempg->height,tempg->x2,tempg->y2);
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
CatPrint(buf," %d",tempg->num);
break;
case GRST_MESH:
CatPrint(buf," %dV,%dT",tempg->vertex_cnt,tempg->tri_cnt);
break;
case GRST_SHIFTABLE_MESH:
CatPrint(buf," %dV,%dT",tempg->shiftable_vertex_cnt,tempg->shiftable_tri_cnt);
break;
}
return StrNew(buf);
}