ReC98/libs/master.lib/grcg_circle.asm

279 lines
4.0 KiB
NASM

; master library - gc_poly - grcg - circle
;
; Description:
; 円描画
;
; Function/Procedures:
; void grcg_circle( int x, int y, unsigned r ) ;
;
; Parameters:
; x,y 中心座標
; r 半径 ( 1 以上 )
;
; Returns:
; none
;
; Binding Target:
; Microsoft-C / Turbo-C / Turbo Pascal
;
; Running Target:
; PC-9801V
;
; Requiring Resources:
; CPU: V30
; GRCG
;
; Notes:
; 半径が 0 ならば描画しません。
;
; Assembly Language Note:
;
;
; Compiler/Assembler:
; TASM 3.0
; OPTASM 1.6
;
; Author:
; 恋塚昭彦
;
; Revision History:
; 93/ 5/12 Initial:gc_circl.asm/master.lib 0.16
; 93/ 5/14 [M0.16] 加速
; 95/ 2/20 縦倍モード対応
; 95/ 3/25 [M0.22k] ゴミがでるバグ修正
MRETURN macro
pop DI
pop SI
pop BP
ret 6
EVEN
endm
retfunc GC_CIRCL_ALLIN
pop SI
pop BP
jmp GRCG_CIRCLE_X
GC_CIRCL_CLIPOUT:
pop SI
pop BP
ret 6
EVEN
endfunc
func GRCG_CIRCLE ; grcg_circle() {
push BP
mov BP,SP
push SI
; DIは下の方でpushしてる
; 引数
@@x = (RETSIZE+3)*2
@@y = (RETSIZE+2)*2
@@r = (RETSIZE+1)*2
mov SI,[BP+@@r] ; SI = 半径
xor CX,CX ; どこかクリップ枠にひっかかったら 0以外にー
; 大まかなクリッピング
mov AX,[BP+@@y]
sub AX,ClipYT
mov DX,AX ; DX = y
sub AX,SI
cmp AX,ClipYH
jg short GC_CIRCL_CLIPOUT
shl AX,1
rcl CX,1
mov AX,DX
add AX,SI
js short GC_CIRCL_CLIPOUT
cmp ClipYH,AX
rcl CX,1
mov AX,[BP+@@x]
mov BX,AX ; BX = x
sub AX,SI
cmp AX,ClipXR
jg short GC_CIRCL_CLIPOUT
sub AX,ClipXL
shl AX,1
rcl CX,1
mov AX,BX
add AX,SI
cmp AX,ClipXL
jl short GC_CIRCL_CLIPOUT
cmp ClipXR,AX
rcl CX,1
jcxz short GC_CIRCL_ALLIN
; 半径が 0 なら描画しない
or SI,SI
jz short GC_CIRCL_CLIPOUT
push DI
mov AL,byte ptr graph_VramZoom
mov CS:GC_CIRCL_VRAMZOOM1,AL
mov CS:GC_CIRCL_VRAMZOOM2,AL
mov ES,ClipYT_seg
mov AX,BX ; AX = x
mov gc_circl_cx_,AX
mov gc_circl_cy_,DX
xor DI,DI
mov BP,SI
EVEN
@@LOOPTOP:
call GC_CIRCL_PSET4
cmp SI,DI
je short @@SKIP
xchg SI,DI
call GC_CIRCL_PSET4
xchg SI,DI
@@SKIP:
stc ; BP -= DI*2+1;
sbb BP,DI ;
sub BP,DI ;
jns short @@LOOPCHECK
dec SI ; --SI;
add BP,SI ; BP += SI*2;
add BP,SI ;
@@LOOPCHECK:
inc DI ; ++DI;
cmp SI,DI
jge short @@LOOPTOP
MRETURN
endfunc ; }
; in:
; SI = dx
; DI = dy
; break:
; AX,BX,CX,DX
;
EVEN
GC_CIRCL_PSET4Q proc near
retn
EVEN
GC_CIRCL_PSET4Q endp
GC_CIRCL_PSET4 proc near
mov AX,gc_circl_cy_
mov BX,DI
shr BX,9 ; dummy
org $-1
GC_CIRCL_VRAMZOOM1 db ?
or BX,BX
jz short @@PS4
sub AX,BX
js short @@PS3
cmp AX,ClipYH
jg short GC_CIRCL_PSET4Q ; →描けるわけがない場合
; AX = (cy_ - DI)
; (cx_ + SI, AX)と (cx_ - SI, AX)に点を打つ
mov DX,AX
shl DX,2
add DX,AX
shl DX,4
mov AX,gc_circl_cx_
or SI,SI ; dxが 0 ならば 1 点のみ
je short @@PS2
sub AX,SI
cmp AX,ClipXL
jl short @@PS1
cmp AX,ClipXR
jg short GC_CIRCL_PSET4Q ; 左側の点が右端を越えているなら
; 右側の点は描けるわけがない
mov BX,AX
mov CX,AX
shr BX,3
add BX,DX
and CL,7
mov CH,80h
shr CH,CL
mov ES:[BX],CH
@@PS1:
mov AX,gc_circl_cx_
add AX,SI
@@PS2:
cmp AX,ClipXL
jl short @@PS3
cmp AX,ClipXR
jg short @@PS3
mov BX,AX
mov CX,BX
shr BX,3
add BX,DX
and CL,7
mov CH,80h
shr CH,CL
mov ES:[BX],CH
@@PS3:
mov AX,gc_circl_cy_
mov BX,DI
shr BX,9 ; dummy
org $-1
GC_CIRCL_VRAMZOOM2 db ?
add AX,BX
@@PS4:
cmp AX,ClipYH
jae short @@PSQ
; (cx_ + SI, AX)と (cx_ - SI, AX)に点を打つ
mov DX,AX
shl DX,2
add DX,AX
shl DX,4
mov AX,gc_circl_cx_
or SI,SI ; dxが 0 ならば 1 点のみ
je short @@PS6
sub AX,SI
cmp AX,ClipXL
jl short @@PS5
cmp AX,ClipXR
jg short @@PSQ ; 左側の点が右端を越えているなら
; 右側の点は描けるわけがない
mov BX,AX
mov CX,AX
shr BX,3
add BX,DX
and CL,7
mov CH,80h
shr CH,CL
mov ES:[BX],CH
@@PS5:
mov AX,gc_circl_cx_
add AX,SI
@@PS6:
cmp AX,ClipXL
jl short @@PSQ
cmp AX,ClipXR
jg short @@PSQ
mov BX,AX
mov CX,BX
shr BX,3
add BX,DX
and CL,7
mov CH,80h
shr CH,CL
mov ES:[BX],CH
@@PSQ:
ret
GC_CIRCL_PSET4 endp