;/**************************************************************************** ;** 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