ReC98/libs/master.lib/grcg_line.asm

319 lines
6.3 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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