home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
vr386
/
renderer
/
polyout.asm
< prev
next >
Wrap
Assembly Source File
|
1993-12-26
|
6KB
|
262 lines
TITLE POLYOUT - POST-PIPELINE POLY PROCESS IN ASSEMBLER
COMMENT $
// 26/12/93 by Dave Stampe
// All algorithms and code (c) 1993 by Dave Stampe
/*
This code is part of the REND386 project, created by Dave Stampe and
Bernie Roehl.
Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products! Usually there is no charge for under 50-100 items for
low-cost or shareware, and terms are reasonable. Any royalties are used
for development, so equipment is often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to REND386, Dave Stampe,
and Bernie Roehl in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling! No more
code ripoffs please.
CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
See the COPYRITE.H file for more information.
*/
This file unpacks polygons from the pipeline into an XY vertex
coordinate array. It also chacks the poly to see if a test-point
is inside of it.
/* Contact: dstampe@sunee.waterloo.edu */
$
.MODEL large
.386
.DATA
include 3dstruct.inc
include viewdata.inc
.CODE RENDERER
; /************ UNPACK VERTICES, CONVERT TO SCREEN COORDS *************/
; unpack poly's vertices to array, in X,Y pair order
; returns number of vertices unpacked
; vertices order can be reversed if screen, even if mirrored
;
;int unpack_poly_vertices(NPOLY *poly, int *vtxarray, int direction)
polyn equ DWORD PTR [bp+8] ; arguments
array equ DWORD PTR [bp+12]
direct equ WORD PTR [bp+16]
count equ WORD PTR [bp-2] ; locals
PUBLIC _unpack_poly_vertices
_unpack_poly_vertices proc far
.386
push ebp
mov ebp,esp
sub esp,8
push ds
push esi
push edi
push ecx
lds di,array ; MAKES ASSUMPTION THAT NPOLYS
; AND NVERTEX STRUCTS FOR REP
les si,polyn ; ARE IN SAME SEGMENT!
mov cx,WORD PTR es:[si].NP_npoints
mov count,cx
add si, SIZE NPOLY ; vertex pointer at END of structure
test direct,-1 ; forward or reverse?
jne reverse
copy_fwd:
mov bx,WORD PTR es:[si] ; ptr to vertex
mov ax,WORD PTR es:[bx].NV_xs ; convert X
add ax,2
shr ax,2
mov WORD PTR ds:[di],ax
mov ax,WORD PTR es:[bx].NV_ys ; convert Y
add ax,2
shr ax,2
mov WORD PTR ds:[di+2],ax
add di,4
add si,4
dec cx
jne copy_fwd
jmp end_copy
reverse:
add si,cx ; skip to end of vtx ptr table
add si,cx
add si,cx
add si,cx
copy_rev:
sub si,4
mov bx,WORD PTR es:[si] ; ptr to vertex
mov ax,WORD PTR es:[bx].NV_xs ; convert X
add ax,2
shr ax,2
mov WORD PTR ds:[di],ax
mov ax,WORD PTR es:[bx].NV_ys ; convert Y
add ax,2
shr ax,2
mov WORD PTR ds:[di+2],ax
add di,4
dec cx
jne copy_rev
end_copy:
mov ax,count ; return number of vertices copied
pop ecx
pop edi
pop esi
pop ds
mov esp,ebp
pop ebp
ret
_unpack_poly_vertices endp
;/******** TEST ROUTINE CALLED WITH SCREEN VERTEX ARRAY ********/
; given array of screen vertices (CCW)
; returns -1 for point not in poly, else 0
;
; int monitor_test_poly(int x, int y, int n, int *array)
x equ WORD PTR [bp+8] ; arguments
y equ WORD PTR [bp+10]
n equ WORD PTR [bp+12]
array equ DWORD PTR [bp+14]
have_left equ WORD PTR [bp-2] ; locals
have_right equ WORD PTR [bp-4]
result equ WORD PTR [bp-6]
PUBLIC _monitor_test_poly
_monitor_test_poly proc far
.386
push ebp
mov ebp,esp
sub esp,10
push esi
push edi
push ecx
mov have_left,0
mov have_right,0
mov result,-1 ; failure flag
mov cx,n ; number of edges to test
dec cx
les bx,array ; pointer to vertex array
mov si,bx
add si,4 ; "next" for edge
tedge: ; begin edge:
mov ax,y ; get test point
mov dx,x
cmp ax,[bx+2] ; check vertical
jle above1
cmp ax,[si+2]
jg notine ; not in edge: next slice
above1:
cmp ax,[bx+2] ; continue test
jge vertok
cmp ax,[si+2]
jl notine ; no vertical edge match
vertok:
cmp dx,[bx] ; have vertical, test for inside
jg rt1
cmp dx,[si]
jle left ; to left of edge
jmp allok
rt1:
cmp dx,[si]
jg right ; to right of edge
allok:
sub ax,[bx+2] ; y - y1 ; "within": compute intercept
mov dx,[si]
sub dx,[bx] ; x2 - x1
imul dx
mov di,[si+2]
sub di,[bx+2] ; y2 - y1
je pend ; horizontal edge: always succeeds
idiv di
add ax,[bx] ; find the x coord of y intercept
cmp ax,x
jle right ; to right of point
left:
inc WORD PTR have_left ; to left: found a matching edge yet?
test WORD PTR have_right,-1
jnz inpoly
jmp pend
right:
inc WORD PTR have_right ; same for left
test WORD PTR have_left,-1
jnz inpoly
notine: ; test of edge failed: next
pend:
add si,4
add bx,4
sub cx,1
jg tedge ; next edge
jl no_match ; done
mov si,WORD PTR array ; do last->first vertex edge
jmp tedge
inpoly: ; got it!
mov result,0 ; mark within poly
no_match:
mov ax,result
pop ecx
pop edi
pop esi
mov esp,ebp
pop ebp
ret
_monitor_test_poly endp
end