⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xrect.asm

📁 视频游戏开发C语言源程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;-----------------------------------------------------------------------
; MODULE XRECT
;
; Rectangle functions all MODE X 256 Color resolutions
;
; Compile with Tasm.
; C callable.
;
;
; ****** XLIB - Mode X graphics library                ****************
; ******                                               ****************
; ****** Written By Themie Gouthas                     ****************
;
; egg@dstos3.dsto.gov.au
; teg@bart.dsto.gov.au
;-----------------------------------------------------------------------


include xlib.inc
include xrect.inc


	.data
; Plane masks for clipping left and right edges of rectangle.
        LeftClipPlaneMask       db      00fh,00eh,00ch,008h
	RightClipPlaneMask      db      00fh,001h,003h,007h
	.code

;---------------------------------------------------------------------------
; Mode X (320x240, 256 colors) rectangle solid colour fill routine.
;
; Based on code originally published in DDJ Mag by M. Abrash
;
; with TASM 2. C near-callable as:
;
;    void x_rect_fill_clipped(int StartX, int StartY, int EndX, int EndY,
;       unsigned int PageBase, unsigne int color);
;
;


_x_rect_fill_clipped proc
ARG     StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word
	push bp              ;preserve caller's stack frame
	mov  bp,sp           ;point to local stack frame
	push si              ;preserve caller's register variables
	push di

	mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
	mov   cx,[_BottomClip]
	mov   ax,[StartY]
	mov   bx,[EndY]
        cmp   dx,ax
        jle   @@CheckBottomClip
	cmp   dx,bx
	jg    @@NotVisible
	mov   [StartY],dx

@@CheckBottomClip:
	cmp   cx,bx
	jg    @@CheckLeftClip
	cmp   cx,ax
	jl    @@NotVisible
	mov   [EndY],cx

@@CheckLeftClip:
	mov   dx,[_LeftClip]           ; Compare u.l. Y coord with Top
	mov   cx,[_RightClip]
	mov   ax,[StartX]
	mov   bx,[EndX]
	sal   dx,2
	sal   cx,2
	cmp   dx,ax
	jle   @@CheckRightClip
	cmp   dx,bx
	jg    @@NotVisible
	mov   [StartX],dx

@@CheckRightClip:
	cmp   cx,bx
	jg    RFClipDone
	cmp   cx,ax
	jl    @@NotVisible
	mov   [EndX],cx
	jmp   RFClipDone

@@NotVisible:
	mov   ax,1
	pop   di                          ; restore registers
	pop   si
	pop   bp
	ret
_x_rect_fill_clipped endp



;---------------------------------------------------------------------------
; Mode X (320x240, 256 colors) rectangle solid colour fill routine.
;
; Based on code originally published in DDJ Mag by M. Abrash
;
; with TASM 2. C near-callable as:
;
;    void x_rect_fill(int StartX, int StartY, int EndX, int EndY,
;       unsigned int PageBase, unsigne int color);
;
;


_x_rect_fill proc
ARG     StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word
	push bp              ;preserve caller's stack frame
	mov  bp,sp           ;point to local stack frame
	push si              ;preserve caller's register variables
	push di

RFClipDone:
	cld
	mov  ax,[_ScrnLogicalByteWidth]
	mul  [StartY]            ;offset in page of top rectangle scan line
	mov  di,[StartX]
	sar  di,2                ;X/4 = offset of first rectangle pixel in scan
	add  di,ax               ;offset of first rectangle pixel in page
	add  di,[PageBase]       ;offset of first rectangle pixel in
			         ; display memory
	mov  ax,SCREEN_SEG       ;point ES:DI to the first rectangle
	mov  es,ax               ; pixel's address
	mov  dx,SC_INDEX         ;set the Sequence Controller Index to
	mov  al,MAP_MASK         ; point to the Map Mask register
	out  dx,al
	inc  dx                  ;point DX to the SC Data register
	mov  si,[StartX]
	and  si,0003h                    ;look up left edge plane mask
	mov  bh,LeftClipPlaneMask[si]    ; to clip & put in BH
	mov  si,[EndX]
	and  si,0003h                    ;look up right edge plane
	mov  bl,RightClipPlaneMask[si]   ; mask to clip & put in BL

	mov  cx,[EndX]                   ;calculate # of addresses across rect
	mov  si,[StartX]
	cmp  cx,si
	jle  @@FillDone                  ;skip if 0 or negative width
	dec  cx
	and  si,not 011b
	sub  cx,si
	sar  cx,2                 ;# of addresses across rectangle to fill - 1
	jnz  @@MasksSet           ;there's more than one byte to draw
	and  bh,bl                ;there's only one byte, so combine the left
                                  ; and right edge clip masks
@@MasksSet:
	mov  si,[EndY]
	sub  si,[StartY]            ;BX = height of rectangle
	jle  @@FillDone             ;skip if 0 or negative height
	mov  ah,byte ptr [Color]    ;color with which to fill
	mov  bp,[_ScrnLogicalByteWidth]  ;stack frame isn't needed any more
	sub  bp,cx                  ;distance from end of one scan line to start
	dec  bp                     ; of next
@@FillRowsLoop:
	push cx                     ;remember width in addresses - 1
	mov  al,bh                  ;put left-edge clip mask in AL
	out  dx,al                  ;set the left-edge plane (clip) mask
	mov  al,ah                  ;put color in AL
	stosb                       ;draw the left edge
	dec  cx                     ;count off left edge byte
	js   @@FillLoopBottom       ;that's the only byte
	jz   @@DoRightEdge          ;there are only two bytes
	mov  al,00fh                ;middle addresses drawn 4 pixels at a pop
	out  dx,al                  ;set the middle pixel mask to no clip
	mov  al,ah                  ;put color in AL
	rep  stosb                  ;draw middle addresses four pixels apiece
@@DoRightEdge:
	mov  al,bl                  ;put right-edge clip mask in AL
	out  dx,al                  ;set the right-edge plane (clip) mask
	mov  al,ah                  ;put color in AL
        stosb                       ;draw the right edge
@@FillLoopBottom:
	add  di,bp                  ;point to start of the next scan line of
                                    ; the rectangle
	pop  cx                     ;retrieve width in addresses - 1
	dec  si                     ;count down scan lines
	jnz  @@FillRowsLoop
@@FillDone:
	pop  di                     ;restore caller's register variables
	pop  si
	pop  bp                     ;restore caller's stack frame
        ret
_x_rect_fill endp



;---------------------------------------------------------------------------
; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.
; Upper left corner of pattern is always aligned to a multiple-of-4
; row and column. Works on all VGAs. Uses approach of copying the
; pattern to off-screen display memory, then loading the latches with
; the pattern for each scan line and filling each scan line four
; pixels at a time. Fills up to but not including the column at EndX
; and the row at EndY. No clipping is performed. All ASM code tested
;
;
; Based on code originally published in DDJ Mag by M. Abrash
;
;
;  C near-callable as:
;
;    void x_rect_pattern_clipped(int StartX, int StartY, int EndX, int EndY,
;       unsigned int PageBase, char far * Pattern);
;
;

_x_rect_pattern_clipped proc
ARG     StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword
LOCAL   NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk
	push bp                       ;preserve caller's stack frame
	mov  bp,sp                    ;point to local stack frame
	sub  sp,LocalStk              ;allocate space for local vars
	push si                       ;preserve caller's register variables
	push di
	push ds

	mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
	mov   cx,[_BottomClip]
	mov   ax,[StartY]
	mov   bx,[EndY]
	cmp   dx,ax
	jle   @@CheckBottomClip
	cmp   dx,bx
	jg    @@NotVisible
	mov   [StartY],dx

@@CheckBottomClip:
	cmp   cx,bx
	jg    @@CheckLeftClip
	cmp   cx,ax
	jl    @@NotVisible
	mov   [EndY],cx

@@CheckLeftClip:
	mov   dx,[_LeftClip]           ; Compare u.l. Y coord with Top
	mov   cx,[_RightClip]
	mov   ax,[StartX]
	mov   bx,[EndX]
	sal   dx,2
	sal   cx,2
	cmp   dx,ax
	jle   @@CheckRightClip
	cmp   dx,bx
	jg    @@NotVisible
	mov   [StartX],dx

@@CheckRightClip:
	cmp   cx,bx
	jg    RPClipDone
	cmp   cx,ax
	jl    @@NotVisible
	mov   [EndX],cx
	jmp   RPClipDone

@@NotVisible:
	mov   ax,1
	pop   ds
	pop   di                          ; restore registers
	pop   si
	mov   sp,bp
	pop   bp
	ret

_x_rect_pattern_clipped endp

;---------------------------------------------------------------------------
; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.
; Upper left corner of pattern is always aligned to a multiple-of-4
; row and column. Works on all VGAs. Uses approach of copying the
; pattern to off-screen display memory, then loading the latches with
; the pattern for each scan line and filling each scan line four
; pixels at a time. Fills up to but not including the column at EndX
; and the row at EndY. No clipping is performed. All ASM code tested
;
;
; Based on code originally published in DDJ Mag by M. Abrash
;
;
;  C near-callable as:
;
;    void x_rect_pattern(int StartX, int StartY, int EndX, int EndY,
;       unsigned int PageBase, char far * Pattern);



_x_rect_pattern proc
ARG     StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword
LOCAL   NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk
	push bp                       ;preserve caller's stack frame
	mov  bp,sp                    ;point to local stack frame
	sub  sp,LocalStk              ;allocate space for local vars
	push si                       ;preserve caller's register variables
	push di
	push ds

RPClipDone:
	cld
	mov  ax,SCREEN_SEG            ;point ES to display memory
	mov  es,ax
				      ;copy pattern to display memory buffer
	lds  si,dword ptr [Pattern]   ;point to pattern to fill with
	mov  di,PATTERN_BUFFER        ;point ES:DI to pattern buffer
	mov  dx,SC_INDEX              ;point Sequence Controller Index to
	mov  al,MAP_MASK              ; Map Mask
	out  dx,al
	inc  dx                       ;point to SC Data register
	mov  cx,4                     ;4 pixel quadruplets in pattern
@@DownloadPatternLoop:
	mov  al,1                     ;
	out  dx,al                    ;select plane 0 for writes
        movsb                         ;copy over next plane 0 pattern pixel
	dec  di                       ;stay at same address for next plane
	mov  al,2                     ;
	out  dx,al                    ;select plane 1 for writes
	movsb                         ;copy over next plane 1 pattern pixel
	dec  di                       ;stay at same address for next plane
	mov  al,4                     ;
	out  dx,al                    ;select plane 2 for writes
        movsb                         ;copy over next plane 2 pattern pixel
	dec  di                       ;stay at same address for next plane
	mov  al,8                     ;
	out  dx,al                    ;select plane 3 for writes
        movsb                         ;copy over next plane 3 pattern pixel
                                      ; and advance address
        loop @@DownloadPatternLoop
        pop  ds

	mov  dx,GC_INDEX              ;set the bit mask to select all bits
	mov  ax,00000h+BIT_MASK       ; from the latches and none from
	out  dx,ax                    ; the CPU, so that we can write the
                                      ; latch contents directly to memory
	mov  ax,[StartY]              ;top rectangle scan line
	mov  si,ax
	and  si,011b                  ;top rect scan line modulo 4
	add  si,PATTERN_BUFFER        ;point to pattern scan line that
				      ; maps to top line of rect to draw
	mov  dx,[_ScrnLogicalByteWidth]
	mul  dx                       ;offset in page of top rect scan line
	mov  di,[StartX]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -