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