ReC98/libs/master.lib/grcg_line.asm

319 lines
6.3 KiB
NASM
Raw Normal View History

2014-08-31 09:30:26 +00:00
PAGE 98,120
; graphics - grcg - hline - PC98V
;
; DESCRIPTION:
; 直線の描画(青プレーンのみ)
;
; FUNCTION:
; void far _pascal grcg_line( int x1, int y1, int y1, int y2 ) ;
; PARAMETERS:
; int x1,y1 始点の座標
; int x1,y2 終点の座標
;
; BINDING TARGET:
; Microsoft-C / Turbo-C
;
; RUNNING TARGET:
; NEC PC-9801 Normal mode
;
; REQUIRING RESOURCES:
; CPU: V30
; GRAPHICS ACCELARATOR: GRAPHIC CHARGER
;
; COMPILER/ASSEMBLER:
; TASM 3.0
; OPTASM 1.6
;
; NOTES:
; ・グラフィック画面の青プレーンにのみ描画します。
; ・色をつけるには、グラフィックチャージャーを利用してください。
; ・grc_setclip()によるクリッピングに対応しています。
;
; AUTHOR:
; 恋塚昭彦
;
; 関連関数:
; grc_setclip()
; clipline
;
; HISTORY:
; 92/6/7 Initial
; 92/6/8 長さが1dotのときに/0を起こしていたのを訂正
; 変数を全てレジスタに割り当て
; 水平線を組み込み
; 92/6/9 クリッピングに不備。両方の点が外にあり、片方を
; 切断処理すると、長さが 1dotになってしまう場合、
; 残りの点を切断しようとするときに /0が発生!→訂正
; 92/6/9 ななめ45度ががあん〜〜〜〜→訂正
; 92/6/10 コードサイズの最適化
; 92/6/13 少々加速
; 92/6/14
; 92/6/16 TASM対応
; 92/6/22 45度を加速…
; 92/7/27 cutlineをcutline.asmに切り出し
ifndef X1280
XBYTES = 80
YSHIFT4 = 4
else
XBYTES = 160
YSHIFT4 = 5
endif
; カットカット〜〜〜(x1,y1)を切断により変更する
; in: BH:o2, BL:o1
; out: BH:o2, BL:o1, o1がzeroならば zflag=1
;
MRETURN macro
pop DI
pop SI
pop BP
ret 8
EVEN
endm
;-------------------------------------------------------------
; void far _pascal grcg_line( int x1, int y1, int x2, int y2 ) ;
;
func GRCG_LINE
push BP
push SI
push DI
CLI
; parameters
add SP,(RETSIZE+3)*2
pop BP ; y2
pop SI ; x2
pop DI ; y1
pop CX ; x1
sub SP,(RETSIZE+3+4)*2
STI
; クリッピング開始 =================================
; クリップ枠に合わせてy座標を変換
mov AX,ClipYT
sub DI,AX
sub BP,AX
mov AX,ClipXL
mov DX,ClipYH
mov BX,0505h ; outcode を全部左下に!!
GETOUTCODE BL,CX,DI,AX,ClipXR,DX
GETOUTCODE BH,SI,BP,AX,ClipXR,DX
test BH,BL
jnz short @@RETURN1 ; まず初期検査。クリップアウト〜
or BX,BX
jz short @@DRAW_START
call cutline ; 第1点のクリップ
jz short @@DRAW_START
xchg BH,BL
xchg CX,SI
xchg DI,BP
call cutline ; 第2点のクリップ
jnz short @@RETURN1
; +-----+-----+-----+-----+-----+-----+-----+
; !AH AL!DH DL!BH BL!CH CL! SI ! DI ! BP !
; ! ! ! ! x1 ! x2 ! y1 ! y2 !
; +-----+-----+-----+-----+-----+-----+-----+
; 描画開始 =================================
@@DRAW_START:
; セグメント設定
mov ES,ClipYT_seg
sub SI,CX ; SI = abs(x2-x1) : deltax
jnb short @@S400
add CX,SI ; CX = leftx
neg SI
xchg DI,BP
@@S400:
sub BP,DI ;
sbb DX,DX ;
mov BX,XBYTES ; BX(downf) = XBYTES ? -XBYTES
add BX,DX ; DX = abs(y2-y1) : deltay
xor BX,DX ;
add BP,DX ;
xor DX,BP ;
mov AX,DI ; DI *= 80
shl AX,2
add DI,AX
shl DI,YSHIFT4
mov AX,CX
shr AX,3
add DI,AX ; DI = start adr!
xor AX,AX
; +-----+-----+-----+-----+-----+-----+-----+
; !AH AL!DH DL!BH BL!CH CL! SI ! DI ! BP !
; ! 0 !delty!downf!leftx!deltx!sad b! !
; +-----+-----+-----+-----+-----+-----+-----+
; 縦長か横長かの判定
cmp SI,DX
jg short @@YOKO_DRAW
je short @@NANAME_DRAW
; 縦長の描画 =================================
@@TATE_DRAW:
dec BX ; BX = downf - 1
xchg DX,SI ; DX = deltax, SI = deltay
div SI
mov DX,8000h
mov BP,AX
and CL,07h
mov AL,DH ; 80h
shr AL,CL
lea CX,[SI+1] ; CX = deltay + 1
; 縦長のループ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
; +-----+-----+-----+-----+-----+-----+-----+
; !AH AL!DH DL!BH BL!CH CL! SI ! DI ! BP !
; ! bit!8000h!downf! len !deltx!gadr !dx/dy!
; +-----+-----+-----+-----+-----+-----+-----+
EVEN
@@TATELOOP:
stosb
add DX,BP
jc short @@TMIGI
add DI,BX
loop short @@TATELOOP
@@RETURN1:
MRETURN
@@TMIGI: ror AL,1
adc DI,BX
loop short @@TATELOOP
MRETURN
; ナナメ45度の描画 =================================
@@NANAME_DRAW:
dec BX ; BX = downf - 1
and CL,07h
mov AL,80h
shr AL,CL
lea CX,[SI+1] ; CX = deltay + 1
; 4個ずつループ展開… gr.lib 0.9のline.incでなされていた改変を
; こちらも追っ掛け(^^; 全く同じじゃ気に入らないから変えたけど…
shr CX,1
jnb short @@NANAME1
stosb
ror AL,1
adc DI,BX
@@NANAME1:
jcxz short @@NANAMERET
shr CX,1
jnb short @@NANAME2
stosb
ror AL,1
adc DI,BX
stosb
ror AL,1
adc DI,BX
@@NANAME2:
jcxz short @@NANAMERET
; ななめ45度のループ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
EVEN
@@NANAMELOOP:
stosb
ror AL,1
adc DI,BX
stosb
ror AL,1
adc DI,BX
stosb
ror AL,1
adc DI,BX
stosb
ror AL,1
adc DI,BX
loop short @@NANAMELOOP
@@NANAMERET:
MRETURN
; 横長の描画 =================================
@@YOKO_DRAW:
; +-----+-----+-----+-----+-----+-----+-----+
; !AH AL!DH DL!BH BL!CH CL! SI ! DI ! BP !
; ! 0 !delty!downf!leftx!deltx!sad b! !
; +-----+-----+-----+-----+-----+-----+-----+
and DI,0FFFEh
or DX,DX
jz short @@HLINE_DRAW
div SI
mov DX,8000h
mov BP,DX ; BP = 8000h(dd)
and CL,0Fh
shr DX,CL ; DX = bit
mov CX,SI ;
inc CX ; CX = deltax + 1
mov SI,AX ; SI = deltay / deltax
xor AX,AX ; AX = 0(wdata)
; 横長のループ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
EVEN
@@YOKOLOOP:
or AX,DX
ror DX,1
jc short @@S200
add BP,SI
jc short @@S300
loop @@YOKOLOOP
xchg AH,AL
stosw
MRETURN
@@S200: xchg AH,AL
stosw
xor AX,AX
add BP,SI
jc short @@S350
loop @@YOKOLOOP
MRETURN
@@S300: xchg AH,AL
mov ES:[DI],AX
xor AX,AX
@@S350: add DI,BX
loop @@YOKOLOOP
MRETURN
; 水平線の描画 ==============================
; +-----+-----+-----+-----+-----+-----+-----+
; !AH AL!DH DL!BH BL!CH CL! SI ! DI ! BP !
; ! 0 !delty!downf!leftx!deltx!gadr ! !
; +-----+-----+-----+-----+-----+-----+-----+
@@HLINE_DRAW:
mov BX,CX ; BX = leftx & 15
and BX,0Fh ;
lea CX,[BX+SI-10h] ; CX = deltax + BX - 16
shl BX,1
mov AX,[EDGES+BX] ; 左エッジ
not AX
mov BX,CX ;
and BX,0Fh
shl BX,1
sar CX,4
js short @@HL_LAST
stosw
mov AX,0FFFFh
rep stosw
@@HL_LAST:
and AX,[EDGES+2+BX] ; 右エッジ
stosw
MRETURN
endfunc