home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Underground
/
UNDERGROUND.ISO
/
graphic
/
voxel.asm
< prev
next >
Wrap
Assembly Source File
|
1995-07-28
|
4KB
|
135 lines
data segment
extrn vscreen:dword ;pointer to landscape data
extrn x,y: word ;coordinates of trapezoid
extrn vpage:word ;current video page
data ends
code segment
assume cs:code,ds:data
;variables with fractional part (lower 8 bits):
offst dd 0 ;current offset
step dd 0 ;pixel size
row_start dd 0 ;beginning of current row
row_step dd 0 ;distance from next row
r_count dw 0 ;counter for depth
shrink dw 0 ;correction on lower screen border
row dd 0 ;current screen row number
vpage_cs dw 0 ;video page in the code segment
.386
public Draw_Voxel
Draw_Voxel proc pascal
;shows landscape on current video page
;reads data from vscreen starting from position (x/y)
mov ax,vpage ;note number of video page
mov vpage_cs,ax
push ds
mov ax,0a000h ;load destination segment
mov es,ax
mov ax,320 ;calculate offset in landscape
imul y
add ax,x
lds si,vscreen ;take data from vscreen
add si,ax ;add offset
shl esi,8 ;convert to fixed point number
mov offst,esi ;initial values for pixel ...
mov row_start,esi ;... and row
mov step,100h ;first scaling factor 1
mov row,100*256 ;begin in screen row 100
mov row_step,14040h ;distance of rows 320,25
mov shrink,0 ;first no correction
mov r_count,160 ;number of rows to calculate
next_y:
mov eax,row ;get current (screen) row number
mov ebx,eax ;store
shr eax,8 ;convert to whole number
add eax,50 ;50 pixels down
imul eax,80 ;convert to offset
mov di,ax ;store as destination pointer
cmp di,199*80 ;screen border exceeded ?
jb normal
mov di,199*80 ;yes, then position on last row
mov eax,row ;difference to bottom screen border
shr eax,8
sub eax,149
mov shrink,ax ;and note as correction
normal:
add di,vpage_cs ;add current video page
imul ebx,16500 ;multiply row number by 1,007
shr ebx,14 ;calculate * 16500 / 16384
mov row,ebx ;and store
mov bp,80 ;number of pixels per row
next_x:
mov esi,offst ;load current pixel offset
shr esi,8 ;convert to whole number
xor eax,eax
mov al,[si] ;load dot from landscape
mov cx,ax ;store
cmp cx,99 ;color (=height) < 100
ja fill_bar
mov ax,99 ;then set to 99
fill_bar:
shl ax,5 ;vanishing point projection: height * 32
xor dx,dx
push bp
mov bp,r_count ;divides by the distance
add bp,50
idiv bp
pop bp
sub ax,shrink ;perform correction
jbe continue ;if <= 0, don't even draw
push di
next_fill:
mov es:[di],cl ;enter color
sub di,80 ;address next highest row
dec al ;decrement counter
jne next_fill ;continue ?
pop di
continue:
inc di ;address next byte on the screen
mov esi,step ;get step
add esi,offst ;increment
mov offst,esi ;and rewrite
dec bp ;next dot
jne next_x
mov esi,row_step ;shift beginning of row
add esi,row_start
mov row_start,esi
mov offst,esi ;reload pixel offset also
dec step ;decrement scaling factor
dec r_count ;continue row counter
jne next_y
pop ds
ret
Draw_Voxel endp
code ends
end