632 lines
12 KiB
NASM
632 lines
12 KiB
NASM
;/****************************************************************************
|
|
;** MODULE: avid.asm
|
|
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
|
|
;** DOCUMENT: ?
|
|
;** VERSION: 1.0
|
|
;** REFERENCE: -
|
|
;** REVISED BY: -
|
|
;*****************************************************************************
|
|
;**
|
|
;** Assembler / Video (drawing, init...)
|
|
;**
|
|
;****************************************************************************/
|
|
|
|
include a.inc
|
|
|
|
asm_code SEGMENT para public use16 'CODE'
|
|
ASSUME cs:asm_code
|
|
|
|
framecounter dw 0
|
|
|
|
include avidm1.asm ;320x200x256 (tweak)
|
|
include avidm2.asm ;640x400x256 (tweak)
|
|
|
|
;entry: -
|
|
; exit: -
|
|
;descr: does nothing
|
|
emptyroutine PROC NEAR
|
|
ret
|
|
emptyroutine ENDP
|
|
|
|
;entry: -
|
|
; exit: -
|
|
;descr: executed before using graphics routines at entries.
|
|
; loads es => vram, and sets some VGA registers the
|
|
; way the gfx routines expect them to be.
|
|
vidstart PROC NEAR
|
|
mov es,ds:_vramseg
|
|
mov dx,3c4h
|
|
mov ax,0f02h
|
|
out dx,ax ;set the plane register ready (&enable all planes)
|
|
ret
|
|
vidstart ENDP
|
|
|
|
;entry: cx=rows to calc, dx=row length
|
|
setrows PROC NEAR
|
|
mov ds:_rowlen,dx
|
|
mov bx,OFFSET _rows
|
|
xor ax,ax
|
|
@@1: mov ds:[bx],ax
|
|
add ax,dx
|
|
add bx,2
|
|
loop @@1
|
|
ret
|
|
setrows ENDP
|
|
|
|
;±±±±±±±± _vid_cameraangle(angle a) ±±±±±±±±
|
|
;entry: (see above)
|
|
; exit: -
|
|
;descr: sets the vision angle (a=0..65535)
|
|
_vid_cameraangle PROC FAR
|
|
CBEG
|
|
mov eax,ds:_projclipx[CLIPMAX] ;right edge
|
|
sub eax,ds:_projaddx ;center X
|
|
;ax=width of half of screen
|
|
movpar bx,0
|
|
shr bx,1 ;divide by 2 for half of angle
|
|
cmp bx,8*64
|
|
jae @@2 ;about 3 degrees minimum
|
|
mov bx,8*64
|
|
@@2: cmp bx,16384
|
|
jb @@1
|
|
mov bx,16383 ;90 degrees maximum
|
|
@@1: shr bx,6-1
|
|
and bx,not 1
|
|
;bx=word index (0..255)*2
|
|
movzx ecx,word ptr ds:_avistan[bx]
|
|
mul ecx
|
|
shrd eax,edx,8
|
|
mov ds:_projmulx,eax
|
|
movzx ecx,word ptr ds:_projaspect
|
|
mul ecx
|
|
shrd eax,edx,8
|
|
mov ds:_projmuly,eax
|
|
CEND
|
|
_vid_cameraangle ENDP
|
|
|
|
;±±±±±±±± _vid_window(long x1,y1,x2,y2,z1,z2) ±±±±±±±±
|
|
;entry: (see above)
|
|
; exit: -
|
|
;descr: sets the video window (for clipping) and sets xadd/yadd to the
|
|
; center of the window
|
|
_vid_window PROC FAR
|
|
CBEG
|
|
movpar eax,0
|
|
mov edx,eax
|
|
mov ds:_projclipx[CLIPMIN],eax
|
|
movpar eax,2
|
|
add edx,eax
|
|
mov ds:_projclipx[CLIPMAX],eax
|
|
sar edx,1
|
|
mov ds:_projaddx,edx
|
|
movpar eax,4
|
|
mov edx,eax
|
|
mov ds:_projclipy[CLIPMIN],eax
|
|
movpar eax,6
|
|
add edx,eax
|
|
mov ds:_projclipy[CLIPMAX],eax
|
|
sar edx,1
|
|
mov ds:_projaddy,edx
|
|
movpar eax,8
|
|
mov ds:_projclipz[CLIPMIN],eax
|
|
movpar eax,10
|
|
mov ds:_projclipz[CLIPMAX],eax
|
|
CEND
|
|
_vid_window ENDP
|
|
|
|
;±±±±±±±± _vid_init(int mode) ±±±±±±±±
|
|
;entry: mode (see below)
|
|
; exit: -
|
|
;descr: initializes screen to graphics and sets up required variables
|
|
; NOTE: the screen / palette is left black.
|
|
;modes: 1=320x200x256 (tweak)
|
|
_vid_init PROC FAR
|
|
;CBEG (follows)
|
|
push bp
|
|
mov bp,sp
|
|
push si
|
|
push di
|
|
push ds
|
|
mov ax,ds
|
|
LOADDS
|
|
mov ds:_cdataseg,ax
|
|
movpar ax,0
|
|
cmp ax,1
|
|
jne @@1
|
|
call m1_init
|
|
@@1: cmp ax,11
|
|
jne @@11
|
|
call m11_init
|
|
@@11: cmp ax,2
|
|
jne @@2
|
|
call m2_init
|
|
@@2: cmp ax,3
|
|
jne @@3
|
|
call m1o_init
|
|
@@3: CEND
|
|
_vid_init ENDP
|
|
|
|
;±±±±±±±± _vid_deinit() ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: resets screen to text mode
|
|
_vid_deinit PROC FAR
|
|
CBEG
|
|
mov ax,3
|
|
int 10h
|
|
CEND
|
|
_vid_deinit ENDP
|
|
|
|
;±±±±±±±± _vid_setpal(char far *pal) ±±±±±±±±
|
|
;entry: pal=palette (768 bytes VGA RGB)
|
|
; exit: -
|
|
;descr: sets screen palette
|
|
_vid_setpal PROC FAR
|
|
CBEG
|
|
ldspar si,0
|
|
mov dx,3dah
|
|
@@1: in al,dx
|
|
test al,8
|
|
jnz @@1
|
|
@@2: in al,dx
|
|
test al,8
|
|
jz @@2
|
|
mov dx,3c8h
|
|
xor al,al
|
|
out dx,al
|
|
inc dx
|
|
mov cx,256
|
|
@@3: mov al,ds:[si+0]
|
|
out dx,al
|
|
mov al,ds:[si+1]
|
|
out dx,al
|
|
mov al,ds:[si+2]
|
|
out dx,al
|
|
add si,3
|
|
loop @@3
|
|
CEND
|
|
_vid_setpal ENDP
|
|
|
|
;±±±±±±±± _vid_drawdots(int count,pvlist *pv) ±±±±±±±±
|
|
;entry: count=number of points to draw
|
|
; pv=pointer to projected vertex list
|
|
; exit: -
|
|
;descr: plots vertices in list
|
|
_vid_drawdots PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
movpar cx,0
|
|
lfspar si,1
|
|
@@1: mov ax,fs:pvlist_vf[si]
|
|
or ax,ax
|
|
jnz @@2
|
|
mov dx,fs:pvlist_x[si]
|
|
mov bx,fs:pvlist_y[si]
|
|
mov ah,31
|
|
push cx
|
|
call ds:vr[PSET]
|
|
pop cx
|
|
@@2: add si,pvlist_size
|
|
loop @@1
|
|
CEND
|
|
_vid_drawdots ENDP
|
|
|
|
;±±±±±±±± _vid_dotdisplay_pvlist(int count,pvlist *list) ±±±±±±±±
|
|
;entry: count=number of elements in pvlist
|
|
; list=pointer to pvlist
|
|
; exit: -
|
|
;descr: TEST ROUTINE
|
|
; displays the projected vertices in the list as dots
|
|
_vid_dotdisplay_pvlist PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
lfspar si,1
|
|
movpar cx,0
|
|
@@1: push cx
|
|
mov ax,fs:[si+pvlist_vf]
|
|
or ax,ax
|
|
jnz @@2
|
|
mov dx,fs:[si+pvlist_x]
|
|
mov bx,fs:[si+pvlist_y]
|
|
mov ah,15 ;color
|
|
call ds:vr[PSET]
|
|
@@2: add si,pvlist_size
|
|
pop cx
|
|
loop @@1
|
|
CEND
|
|
_vid_dotdisplay_pvlist ENDP
|
|
|
|
;±±±±±±±± _vid_pset(int x,int y,int color) ±±±±±±±±
|
|
_vid_pset PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
movpar dx,0
|
|
movpar bx,1
|
|
movpar ah,2
|
|
call ds:vr[PSET]
|
|
CEND
|
|
_vid_pset ENDP
|
|
|
|
;±±±±±±±± _vid_dotdisplay_zcolor(int count,pvlist *list1,vlist *list2) ±±±±±±±±
|
|
;entry: count=number of elements in pvlist
|
|
; list1=pointer to pvlist
|
|
; list2=pointer to vlist (both lists should have same vertices!)
|
|
; exit: -
|
|
;descr: TEST ROUTINE
|
|
; displays the projected vertices in the list as dots colored
|
|
; according to depth
|
|
_vid_dotdisplay_zcolor PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
lfspar si,1
|
|
lgspar di,3
|
|
movpar cx,0
|
|
@@1: push cx
|
|
mov ax,fs:[si+pvlist_vf]
|
|
or ax,ax
|
|
jnz @@2
|
|
mov dx,fs:[si+pvlist_x]
|
|
mov bx,fs:[si+pvlist_y]
|
|
mov eax,gs:[di+vlist_z]
|
|
sar eax,11
|
|
cmp ax,1
|
|
jge @@3
|
|
mov ax,1
|
|
@@3: cmp ax,31
|
|
jle @@4
|
|
mov ax,31
|
|
@@4: mov ah,al
|
|
call ds:vr[PSET]
|
|
@@2: add si,pvlist_size
|
|
add di,vlist_size
|
|
pop cx
|
|
loop @@1
|
|
CEND
|
|
_vid_dotdisplay_zcolor ENDP
|
|
|
|
;±±±±±±±± _vid_clear(void) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Clears the current screen to black (color 0)
|
|
_vid_clear PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
mov ax,0 ;blackclear
|
|
call ds:vr[CLEAR]
|
|
CEND
|
|
_vid_clear ENDP
|
|
|
|
;±±±±±±±± _vid_clear255(void) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Clears the current screen to black (color 0)
|
|
_vid_clear255 PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
mov ax,9 ;255clear
|
|
call ds:vr[CLEAR]
|
|
CEND
|
|
_vid_clear255 ENDP
|
|
|
|
;±±±±±±±± _vid_clearbg(char *bg) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Copies the bg to screen
|
|
_vid_clearbg PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
mov ax,2 ;bgcopy
|
|
mov si,[bp+6]
|
|
mov fs,[bp+8]
|
|
call ds:vr[CLEAR]
|
|
CEND
|
|
_vid_clearbg ENDP
|
|
|
|
;±±±±±±±± _vid_switch(void) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Switch to the next screen page (_vid_waitb should be called after
|
|
; this)
|
|
_vid_switch PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
call ds:vr[SWITCH]
|
|
CEND
|
|
_vid_switch ENDP
|
|
|
|
;±±±±±±±± _vid_setswitch(int,int) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Forces a separate write/display switch
|
|
_vid_setswitch PROC FAR
|
|
CBEG
|
|
;call vidstart
|
|
movpar ax,0
|
|
cmp ax,-1
|
|
je @@1
|
|
shl ax,14-4
|
|
add ax,0a000h
|
|
mov ds:_vramseg,ax
|
|
@@1: movpar ax,1
|
|
cmp ax,-1
|
|
je @@2
|
|
shl ax,14
|
|
mov dx,3d4h
|
|
mov al,0ch
|
|
out dx,ax
|
|
@@2: CEND
|
|
_vid_setswitch ENDP
|
|
|
|
;±±±±±±±± _vid_waitb(void) ±±±±±±±±
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Waits for border (=retrace)
|
|
_vid_waitb PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
call ds:vr[WAITB]
|
|
CEND
|
|
_vid_waitb ENDP
|
|
|
|
;±±±±±±±± _vid_clear(char *sky) ±±±±±±±±
|
|
;entry: [sky]=pointer to sky data structure
|
|
; exit: -
|
|
;descr: Clears the current screen with a sky pattern according to [sky]
|
|
_vid_skyclear PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
lfspar si,0
|
|
mov ax,1 ;skyclear
|
|
call ds:vr[CLEAR]
|
|
CEND
|
|
_vid_skyclear ENDP
|
|
|
|
;##########################################################################
|
|
; 'Temporary' text routines
|
|
;##########################################################################
|
|
|
|
include atext.asm
|
|
|
|
;##########################################################################
|
|
; Common routines that work in all current screen modes
|
|
;##########################################################################
|
|
|
|
;entry: dx=x, bx=y, ax=width, cx=heigth
|
|
; exit:
|
|
;descr: calculates the 'good' copying sequence for the bitmap
|
|
ALIGN 2
|
|
bb_hidden dw 0
|
|
bb_yskip dw 0
|
|
bb_ycount dw 0
|
|
bb_xskip dw 0
|
|
bb_xcopy dw 0
|
|
;
|
|
bb_doskip dw 0,0,0,0 ;bytes
|
|
bb_doskip2 dw 0,0,0,0 ;pages 0..3
|
|
bb_doplane dw 0,0,0,0
|
|
bb_dodest dw 0,0,0,0
|
|
bb_docount dw 0,0,0,0
|
|
bitbltanalyze PROC NEAR
|
|
push si
|
|
push di
|
|
;clip up/down
|
|
mov cs:bb_xskip,0
|
|
mov cs:bb_yskip,0
|
|
mov si,word ptr ds:_projclipy[CLIPMAX]
|
|
cmp bx,si
|
|
jg @@out
|
|
mov si,word ptr ds:_projclipy[CLIPMIN]
|
|
cmp bx,si
|
|
jge @@1
|
|
sub si,bx
|
|
mov cs:bb_yskip,si
|
|
add bx,si
|
|
sub cx,si
|
|
@@1: mov si,word ptr ds:_projclipy[CLIPMAX]
|
|
sub si,bx
|
|
cmp cx,si
|
|
jle @@2
|
|
mov cx,si
|
|
inc cx
|
|
@@2: mov cs:bb_ycount,cx
|
|
mov si,bx
|
|
add si,cx
|
|
cmp si,word ptr ds:_projclipy[CLIPMIN]
|
|
jl @@out
|
|
;clip left/right
|
|
mov si,word ptr ds:_projclipx[CLIPMAX]
|
|
cmp dx,si
|
|
jg @@out
|
|
mov si,word ptr ds:_projclipx[CLIPMIN]
|
|
cmp dx,si
|
|
jge @@3
|
|
sub si,dx
|
|
mov cs:bb_xskip,si
|
|
add dx,si
|
|
sub ax,si
|
|
@@3: mov si,word ptr ds:_projclipx[CLIPMAX]
|
|
sub si,dx
|
|
cmp ax,si
|
|
jle @@4
|
|
mov ax,si
|
|
inc ax
|
|
@@4: mov cs:bb_xcopy,ax
|
|
mov si,dx
|
|
add si,ax
|
|
cmp si,word ptr ds:_projclipx[CLIPMIN]
|
|
jl @@out
|
|
;calc start address
|
|
shl bx,1
|
|
mov bx,ds:_rows[bx]
|
|
mov cx,dx
|
|
shr dx,2
|
|
add bx,dx
|
|
and cl,3
|
|
mov ax,1102h
|
|
rol ah,cl
|
|
mov dx,bx
|
|
mov si,cs:bb_xskip
|
|
mov di,cs:bb_xcopy
|
|
add di,3
|
|
xor bx,bx
|
|
REPT 4
|
|
local l1
|
|
push ax
|
|
mov cs:bb_doplane[bx],ax
|
|
mov cs:bb_dodest[bx],dx
|
|
mov ax,si
|
|
shr ax,2
|
|
mov cs:bb_doskip[bx],ax
|
|
mov ax,si
|
|
and ax,3
|
|
mov cs:bb_doskip2[bx],ax
|
|
mov ax,di
|
|
shr ax,2
|
|
mov cs:bb_docount[bx],ax
|
|
pop ax
|
|
rol ah,1
|
|
jnc l1
|
|
inc dx
|
|
l1: inc si
|
|
dec di
|
|
add bx,2
|
|
ENDM
|
|
mov cs:bb_hidden,0
|
|
pop di
|
|
pop si
|
|
ret
|
|
@@out: mov cs:bb_hidden,1
|
|
pop di
|
|
pop si
|
|
ret
|
|
bitbltanalyze ENDP
|
|
|
|
;±±±±±±±± _vid_pic320200(char *p,int x,int y) ±±±±±±±±
|
|
;entry: p=pointer to pic, x/y=screen position to write to
|
|
; exit: -
|
|
;descr: copies pic to screen. The pic format is {PIC64TW}
|
|
ALIGN 2
|
|
yrow dw 0
|
|
yrowlen dw 0
|
|
xm0 dw 0
|
|
xmstart dw 0
|
|
_vid_pic320200 PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
movpar dx,2
|
|
movpar bx,3
|
|
mov cx,200
|
|
mov ax,320
|
|
call bitbltanalyze
|
|
cmp cs:bb_hidden,0
|
|
jne @@0
|
|
mov ax,ds:_rowlen
|
|
mov cs:yrowlen,ax
|
|
ldspar si,0
|
|
xor bx,bx
|
|
mov cx,4
|
|
@@1: push cx
|
|
push bx
|
|
push si
|
|
push di
|
|
mov ax,320 ;line length in source buf
|
|
mul cs:bb_yskip
|
|
add si,ax
|
|
mov ax,80 ;lenght of single 'bit'plane
|
|
mul cs:bb_doskip2[bx]
|
|
add si,ax
|
|
add si,cs:bb_doskip[bx]
|
|
mov ax,cs:bb_doplane[bx]
|
|
mov dx,3c4h
|
|
out dx,ax
|
|
mov di,cs:bb_dodest[bx]
|
|
mov dx,cs:bb_docount[bx]
|
|
or dx,dx
|
|
jz @@20
|
|
mov cx,cs:bb_ycount
|
|
jcxz @@20
|
|
cmp cx,7
|
|
ja @@2
|
|
|
|
@@5: ;simplex nonaligned copy
|
|
push cx
|
|
push si
|
|
push di
|
|
mov cx,dx
|
|
shr cx,2
|
|
rep movsd ;copy dwords
|
|
mov cx,dx
|
|
and cx,3
|
|
rep movsb ;copy rest
|
|
pop di
|
|
pop si
|
|
pop cx
|
|
add di,cs:yrowlen
|
|
add si,320 ;line length in source buf
|
|
loop @@5
|
|
jmp @@20
|
|
|
|
@@2: ;aligned copy
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
mov cx,di
|
|
neg cx
|
|
and cx,3
|
|
sub dx,cx
|
|
rep movsb ;align
|
|
mov cx,dx
|
|
shr cx,2
|
|
rep movsd ;copy dwords
|
|
mov cx,dx
|
|
and cx,3
|
|
rep movsb ;copy rest
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
add di,cs:yrowlen
|
|
add si,320 ;line length in source buf
|
|
loop @@2
|
|
|
|
@@20: pop di
|
|
pop si
|
|
pop bx
|
|
pop cx
|
|
add bx,2
|
|
loop @@1
|
|
@@0: CEND
|
|
_vid_pic320200 ENDP
|
|
|
|
;±±±±±±±± _vid_drawsight(char *sight) ±±±±±±±±
|
|
;entry: [sight]=pointer to sight data
|
|
; exit: -
|
|
;descr: overlays a sight picture to the screen. The picture must be in
|
|
; sight format {SIGHT-DATA}
|
|
_vid_drawsight PROC FAR
|
|
CBEG
|
|
call vidstart
|
|
ldspar si,0
|
|
zzz=1
|
|
REPT 4
|
|
local l1
|
|
mov dx,3c5h
|
|
mov al,zzz
|
|
out dx,al
|
|
mov cx,ds:[si]
|
|
add si,2
|
|
mov al,127
|
|
l1: mov di,ds:[si]
|
|
add si,2
|
|
mov es:[di],al
|
|
loop l1
|
|
zzz=zzz*2
|
|
ENDM
|
|
CEND
|
|
_vid_drawsight ENDP
|
|
|
|
include avidfill.asm
|
|
|
|
asm_code ENDS
|
|
END
|