home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ;+ Mode 13h animation test program. Rotates a golden cross above a complex +
- ;+ background using logical operations to manipulate the bitmaps +
- ;+**************************************************************************+
- ;+ developed on: 4-8-91 +
- ;+ last update : 4-12-91 +
- ;+ developed by: Chris Lampton +
- ;+ Mark Betz +
- ;+ caller: Turbo Pascal +
- ;+**************************************************************************+
- ;+ This source code is copyrighted 1991 by the Gamers Programming Workshop +
- ;+ which is a function of the GAMERS forum, Compuserve. Limited license +
- ;+ is granted for distribution and copying provided that this notice is +
- ;+ left intact on all versions. Use of these routines is permitted without +
- ;+ license or fee. No price may be charged beyond disk costs for this code + +
- ;+**************************************************************************+
-
- TITLE GPWAnim
-
- .MODEL TPascal
- .DATA
- ; constants
- ; not all of these are being used
-
- V_Seg equ 0A000H ; video segment
- GC_Index_reg equ 003CEH ; port address of GC index register
- StatReg1 equ 003DAH ; port address of VGA status register
- VSMask equ 00008H ; mask for bit 4, vsynch signal
- SeqIReg equ 003C4H ; port address of Sequencer Index Reg
- SeqDReg equ 003C5H ; port address of Sequencer Data Reg
- DEMask equ 00020H ; mask for bit 5, Refresh enable
-
- ; variables
-
- x1 DW ? ; current top left x display coord
- y1 DW ? ; current top left y display coord
- ox1 DW ? ; old top left x display coord
- oy1 DW ? ; old top left y display coord
- DeltaX1 DW ? ; x incremental change per iteration
- DeltaY1 DW ? ; y incremental change per iteration
- FrameCnt DB ? ; number of current frame
- SvFrm1 DB 2600 DUP (?) ; background save array
- OldVofs DW ? ; hold precalculated offsets into
- NewVofs DW ? ; the video buffer
-
- ; variables and structures declared in Turbo Pascal calling module
-
- ;******************************************************************************
- ; PROGRAMMER'S NOTE:
- ; This module is written to accept Pascal calling conventions. This basically
- ; means it expects parameters pushed on the stack in order of left-right
- ; occurence in the function definition. Also, the called routine is expected
- ; to clean up passed parameters and restore the stack before returning. I
- ; don't believe converting it to be called by C++ would be much of a chore.
- ;******************************************************************************
-
- ;******************************************************************************
- ; EXTERNAL VARIABLE DECLARATION NOTES
- ;
- ; Calling programs must declare the following variables:
- ;
- ; FRMBuff : pointer to buffer containing the primary image frames
- ; SvFrm1 : array containing saved background image data
- ; FrameWid : word containing frame width in bytes
- ; FrameDep : word containing frame depth in lines
- ; FrameSize : word containing frame size in bytes
- ; TopFrame : byte containing number of last frame in buffer
- ;******************************************************************************
-
- EXTRN FRMBuff:DWORD ; pointer to frame image buffer
- EXTRN PcxBuff:DWORD ; pointer to background image
- EXTRN FrameWid:WORD ; global frame width in pixels
- EXTRN FrameDep:WORD ; global frame depth in lines
- EXTRN FrameSize:WORD ; global frame size variable
- EXTRN TopFrame:BYTE ; global top frame number
-
- DATA ENDS
- .CODE
- assume cs:CODE
-
- PUBLIC _Animate
-
- ;******************************************************************************
- ; Procedure _CalcVOffset. Calculate the offset for the new video frame based
- ; on the current values of x1, and y1. Stores result in NewVofs. Swaps the
- ; old value of NewVOfs into OldVofs
- ;
- ;
- ; call: nothing
- ; destroys: ax,bx,dx
- ;*****************************************************************************
-
- _CalcVOffset PROC NEAR
- ; calculate the offset into the video buffer by the formula
- ; ((y-1)*320)+x = offset
-
- mov ax,NewVofs ; mov current frame ofs to OldVofs
- mov OldVofs,ax
- mov ax,y1
- mov bx,x1
- sub ax,1 ; subtract 1 from the y coord
- push bx ; save the x coord
- mov bx,320 ; move the bytes per line value to bx
- mul bx ; multiply ax by bx, result in ax
- pop bx ; restore the x coordinate
- add ax,bx ; add the x coordinate to mul result
- mov NewVofs,ax ; new offset value in ax
- ret
- _CalcVOffset ENDP
-
- ;*****************************************************************************
- ; Procedure _GetBKGRND. Grabs a background frame at the current offset into
- ; video ram. Works in mode 13h ONLY.
- ;
- ; call: with frame depth in lines in cx, frame width in bytes in dx, pointer
- ; to frame buffer in es:di
- ;
- ; destroys: ax, cx, es, di, si
- ;*****************************************************************************
-
- _GetBKGRND PROC NEAR
- push ds
- mov si,NewVOfs ; put vram offset in si
- mov ax,WORD PTR PcxBuff+2 ; get the image segment into
- mov ds,ax ; the ds register
- cld
- gbgloop:
- push cx ; save the line counter
- mov cx,dx ; initialize byte counter
- rep movsb ; move bytes from ds:si to es:di
- pop cx ; restore line counter
- add si,320 ; move to next line
- sub si,dx ; need to subtract frame width
- loop gbgloop ; do the next line
- pop ds
- ret
- _GetBKGRND ENDP
-
- ;*****************************************************************************
- ; Procedure _PutBKGRND. Displays a background frame at the passed x,y coord-
- ; inate pair. Works in mode 13h ONLY. Only non-zero bytes are displayed.
- ;
- ; call: with frame depth in lines in cx, frame width in bytes in dx, pointer
- ; to frame buffer in ds:si
- ;
- ; destroys: ax, cx, es, di, si
- ;*****************************************************************************
-
- _PutBKGRND PROC NEAR
- mov di,OldVofs ; put vram offset in ax
- mov ax, WORD PTR PcxBuff+2 ; get the video segment into
- mov es,ax ; the es register
- cld
- pbgloop:
- push cx ; save the line counter
- mov cx,dx ; initialize byte counter
- rep movsb ; move bytes from ds:si to es:di
- pop cx ; restore line counter
- add di,320 ; move to next line
- sub di,dx ; need to subtract frame width
- loop pbgloop ; do the next line
- ret
- _PutBKGRND ENDP
-
- ;*****************************************************************************
- ; Procedure _PutFrame. Displays a frame from the frame buffer. Works in mode
- ; 13h ONLY. Only non-zero bytes are displayed.
- ;
- ; call: with frame depth in lines in cx, frame width in bytes in dx, pointer
- ; to frame buffer in ds:si
- ;
- ; destroys: ax, bx, cx, es, di, si
- ;*****************************************************************************
-
- _PutFrame PROC NEAR
- mov di,NewVofs ; put offset into vram in di
- mov ax, WORD PTR PcxBuff+2 ; get the video segment into
- mov es,ax ; the es register
- xor bx,bx ; this is a counter
-
- PFrmLoop:
- cmp BYTE PTR [si+bx],0 ; is the next byte in the frame 0
- je nodisp2 ; if yes don't display
- mov al,[si+bx] ; display the image byte
- mov es:[di+bx],al
- nodisp2:
- inc bx ; increment the counter
- cmp bx,dx ; at the end of the line?
- jb PFrmLoop
- add si,dx ; point to next line in frame buff
- add di,320 ; point to next line in vram
- xor bx,bx ; re-zero the byte counter
- loop PFrmLoop ; go process the next line
- ret
- _PutFrame ENDP
-
- ;*****************************************************************************
- ; Procedure _CheckKey. Returns a 1 in ax if there was a key in the buffer
- ; else it returns a 0 in ax. The key is removed from the buffer.
- ;
- ; call: nothing
- ; destroys: ax
- ;*****************************************************************************
-
- _CheckKey PROC NEAR
- mov ah, 01h ; function 01h: check for key
- int 016h
- jz NoKey ; if zf not set then no key ready
- mov ah,0h ; function 0h, read key from buffer
- int 016h
- mov ax,1 ; return a 1 in ax
- jmp kend
- NoKey:
- mov ax,0 ; return a 0 in ax
- kend:
- ret
- _CheckKey ENDP
-
- ;*****************************************************************************
- ; Procedure _Wait. Waits in a null loop.
- ; call: nothing
- ; destroys: nothing
- ;*****************************************************************************
-
- _Wait PROC NEAR
- push cx
- mov cx,63000
- waitloop:
- loop waitloop
- pop cx
- ret
- _Wait ENDP
-
- ;*****************************************************************************
- ; Procedure _AdjCoords. Increments the x and y position, checks for coll-
- ; ision with the edge of the screen, and flips the sign of DeltaX1 or
- ; DeltaY1 if a collisions is detected. It also saves the last x,y pair in
- ; ox1, and oy1.
- ;
- ; call: nothing
- ; destroys: ax
- ;*****************************************************************************
-
- _AdjCoords PROC NEAR
- mov ax, x1 ; move the current x value to ox1
- mov ox1,ax
- mov ax, y1 ; move the current y value to oy1
- mov oy1,ax
-
- mov ax,x1
- add ax,DeltaX1 ; increment x1
- mov x1,ax
- cmp x1,270 ; x1 greater than 265?
- jb testx1low ; if so then check low
- neg DeltaX1 ; else flip DeltaX1's sign
- jmp x1okay ; and skip the low check
- testx1low:
- cmp x1,2 ; is it greater than 10?
- ja x1okay ; if so then no action
- neg DeltaX1 ; else flip DeltaX1's sign
- x1okay:
- mov ax,y1
- add ax,DeltaY1 ; do the same for y1
- mov y1,ax
- cmp y1,146
- jb testy1low
- neg DeltaY1
- jmp y1okay
- testy1low:
- cmp y1,2
- ja y1okay
- neg DeltaY1
- y1okay:
- ret
- _AdjCoords ENDP
-
- ;*****************************************************************************
- ; Procedure _Animate handles the animation of the rotating cross. It expects
- ; the starting x,y coordinate pair to be on the stack when it is called.
- ; The calling program must also have declared variables as described above,
- ; and must have loaded the frame data into the buffers.
- ;
- ; call: push x, then y
- ;
- ; destroys: nothing
- ;*****************************************************************************
-
- _Animate PROC NEAR
- push bp
- mov bp, sp ; set up stack frame
- push ds ; save the registers
- push es
- push ss
- push di
- push si
- push ax
- push bx
- push cx
- push dx
-
- mov ax, [bp+6] ; get the starting x,y coords
- mov x1, ax
- mov ax, [bp+4]
- mov y1, ax
- mov FrameCnt,0 ; zero out the frame counter
- mov DeltaX1,1 ; start with delta values of 1
- mov DeltaY1,1
-
-
- CALL _CalcVOffset ; sets up the offsets into vram
- mov ax,NewVofs ; first time through we want these
- mov OldVofs,ax ; pointing the same place
- mov ax,ds ; set up for _GetBKGRND call
- mov es,ax
- mov di,OFFSET SvFrm1
- mov cx,FrameDep ; frame depth in cx
- mov dx,FrameWid ; frame width in dx
- CALL _GetBKGRND ; get the background at OldVofs
-
- mov si,WORD PTR FRMBuff ; put offset to first frame in si
- push si ; save it on the stack
- mov cx,FrameDep ; frame depth in cx
- CALL _PutFrame ; blit the first frame at NewVofs
- pop si
-
- MainAnimLoop:
- CALL _AdjCoords ; increment coordinates
- CALL _CalcVOffset ; get the video offset into ax
- add si,FrameSize ; increment pointer into frame buffer
- push si ; save si (offset into frame buffer)
-
- mov cx,FrameDep ; do part of set-up for _PutBKGRND
- mov si, OFFSET SvFrm1
- mov dx,FrameWid ; frame width in bytes in dx
- CALL _PutBKGRND ; restore the background
-
- mov cx,FrameDep ; set up for call to _GetBKGRND
- mov ax,@DATA
- mov es,ax
- mov di,OFFSET SvFrm1
- CALL _GetBKGRND ; restore the background
-
- pop si ; restore frame buffer offset
- push si ; and save it again
- mov cx,FrameDep ; see _PutFrame for details on call
- CALL _PutFrame
-
- mov cx,64000 ; size of mode 13h screen
- mov ax,0A000h ; get video segment into es
- mov es,ax
- xor di,di ; offset 0
- push ds ; save data segment
- mov bx,WORD PTR PcxBuff+2 ; get image buffer segment
- mov si,WORD PTR PcxBuff ; offset of image buffer
- mov ds,bx ; set up ds to image segment
- rep movsw ; move 64000 bytes
- pop ds ; restore data segment
- pop si ; restore frame buffer offset
-
- inc FrameCnt ; increment FrameCnt and check it
- mov al,FrameCnt
- cmp al,TopFrame ; against TopFrame
- jb MainAnimLoop
- CALL _CheckKey ; check for a key
- cmp ax,1 ; see if one was ready
- je alldone ; if so all done
- mov FrameCnt,0 ; reset to first frame
- mov si,WORD PTR FRMBuff ; set offset to first frame
- jmp MainAnimLoop ; start sequence again
- alldone:
- pop dx ; restore the registers
- pop cx
- pop bx
- pop ax
- pop si
- pop di
- pop ss
- pop es
- pop ds
- mov sp,bp ; and the stack
- pop bp
- ret 4
- _Animate ENDP
- CODE ENDS
- END
-