home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga ACS 1998 #6
/
amigaacscoverdisc1998-061998.iso
/
games
/
descent
/
source
/
3d
/
rod.asm
< prev
next >
Wrap
Assembly Source File
|
1998-06-08
|
10KB
|
431 lines
;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
;
; $Source: f:/miner/source/3d/rcs/rod.asm $
; $Revision: 1.22 $
; $Author: matt $
; $Date: 1995/02/09 22:00:51 $
;
; Code to draw rods (facing bitmaps).
;
; $Log: rod.asm $
; Revision 1.22 1995/02/09 22:00:51 matt
; Removed dependence on divide overflow handler; we now check for overflow
; before dividing. This fixed problems on some TI chips.
;
; Revision 1.21 1994/11/27 12:55:14 matt
; Tooks out some unused code
;
; Revision 1.20 1994/09/01 15:34:49 matt
; Fixed stack mess-up when rod projection overflows
;
; Revision 1.19 1994/09/01 10:41:46 matt
; Blob routine, renamed g3_draw_bitmap(), now takes seperate 3d width & height.
;
; Revision 1.18 1994/08/01 17:23:27 matt
; Check for overflow after project in blob code
;
; Revision 1.17 1994/07/25 15:47:13 matt
; Cleaned up code, and made long-broken flat-shaded rods work.
;
; Revision 1.16 1994/07/25 00:00:05 matt
; Made 3d no longer deal with point numbers, but only with pointers.
;
; Revision 1.15 1994/07/22 17:58:01 matt
; Changed the name of the rod functions, and took out some debugging code
;
; Revision 1.14 1994/07/21 12:49:41 mike
; Create _blob_vertices so powerups can be outlined when selected in editor.
;
; Revision 1.13 1994/06/16 09:07:29 matt
; Move in UV values for rods to prevent the texture mapper from reading
; past the edges of the bitmaps.
;
; Revision 1.12 1994/05/31 18:35:29 matt
; Added light value to g3_draw_facing_bitmap()
;
; Revision 1.11 1994/05/19 23:11:54 matt
; Support new uvl value ranges
;
; Revision 1.10 1994/05/13 10:18:07 matt
; Fixed bug introduced last time
;
; Revision 1.9 1994/05/11 10:10:35 matt
; Changed a little code in attempt to avoid overflows
;
; Revision 1.8 1994/05/07 16:43:26 matt
; Made rods work right, maybe.
;
; Revision 1.7 1994/03/23 10:25:04 matt
; Fixed stack messup with blob overflow, and removed debug_brk
;
; Revision 1.6 1994/03/15 21:22:11 matt
; Put in check for div overflow in blob code
;
; Revision 1.5 1994/02/21 11:04:15 matt
; Added check for zero-length vector
;
; Revision 1.4 1994/02/15 17:37:23 matt
; New function, g3_draw_blob()
;
; Revision 1.3 1994/02/11 20:15:04 matt
; Fixed matrix scale problem, removed unneeded debug_brk
;
; Revision 1.2 1994/02/09 11:49:32 matt
; Added code for texture-mapped and flat-shaded rods
;
; Revision 1.1 1994/02/02 11:27:21 matt
; Initial revision
;
;
ALWAYS_USE_SCALER = 0 ;if true, use scaler even when banked
.386
option oldstructs
.nolist
include types.inc
include psmacros.inc
include gr.inc
include 3d.inc
.list
assume cs:_TEXT, ds:_DATA
public _blob_vertices
_DATA segment dword public USE32 'DATA'
rcsid db "$Id: rod.asm 1.22 1995/02/09 22:00:51 matt Exp $"
align 4
bot_width fix ?
top_width fix ?
rod_points db 4*size g3s_point dup (?)
delta_x fix ?
delta_y fix ?
edge_vec_x fix ?
edge_vec_y fix ?
vertbuf fix 4 dup (?,?)
_blob_vertices fix 4 dup (?,?)
bitmap_ptr dd ?
delta_vec vms_vector <>
rod_norm vms_vector <>
temp_vec vms_vector <>
top_pnt dd ?
bot_pnt dd ?
rod_point_list dd rod_points
dd rod_points+(size g3s_point)
dd rod_points+(size g3s_point)*2
dd rod_points+(size g3s_point)*3
;values here are set to be half a pixel in from the edges so the texture
;mapper doesn't read past the bitmap
uvl_list fix 200h,200h,0
fix 0fe00h,200h,0
fix 0fe00h,0fe00h,0
fix 200h,0fe00h,0
;;uvl_list fix 0,0,0
;; fix 10000h,0,0
;; fix 10000h,10000h,0
;; fix 0,10000h,0
_DATA ends
_TEXT segment dword public USE32 'CODE'
extn scale_bitmap_
;draws a polygon that's always facing the viewer
;takes esi,edi=bottom & top points (g3s_point *), eax,edx=3d width at bottom,top
g3_draw_rod_flat: pushm eax,ebx,ecx,edx,esi,edi
call calc_rod_corners
or cl,cl ;check codes
jnz no_draw
mov ecx,4 ;4 corners
lea esi,rod_point_list
call g3_draw_poly
popm eax,ebx,ecx,edx,esi,edi
ret
;draws bitmap that's always facing the viewer
;takes esi,edi=bottom & top points (g3s_point *), eax,edx=3d width at bottom,top
;ebx = bitmap
;points must be rotated
g3_draw_rod_tmap:
pushm eax,ebx,ecx,edx,esi,edi
mov bitmap_ptr,ebx
;save lighting values
mov uvl_list+8,ecx
mov uvl_list+20,ecx
mov uvl_list+32,ecx
mov uvl_list+44,ecx
call calc_rod_corners
or cl,cl ;check codes
jnz no_draw
mov ecx,4
lea esi,rod_point_list
lea ebx,uvl_list
mov edx,bitmap_ptr
call g3_draw_tmap
jmp no_draw
;;@@;can use use scaler?
;;@@if not ALWAYS_USE_SCALER
;;@@ mov eax,vertbuf+4 ;point 0 y
;;@@ cmp eax,vertbuf+12 ;point 1 y
;;@@ jne must_roll
;;@@;use the scaler!
;;@@endif
;;@@ mov eax,bitmap_ptr
;;@@ lea edx,vertbuf
;;@@ call scale_bitmap_
;;@@ jmp no_draw
;;@@
;;@@;can't call the scaler
;;@@must_roll: mov eax,bitmap_ptr
;;@@ lea edx,vertbuf
;;@@ mov ebx,15 ;light value
;;@@ call rotate_bitmap_
no_draw:
popm eax,ebx,ecx,edx,esi,edi
ret
;draws a bitmap with the specified 3d width & height
;takes esi=position, ebx=width, ecx=height, eax=bitmap
;modifies eax,esi,ecx
g3_draw_bitmap: pushm edx,edi
mov bitmap_ptr,eax ;save bitmap
push ebx ;save width
lea edi,rod_points ;get dest point
call g3_rotate_point
or bl,bl ;off screen?
pop ebx ;restore width
js blob_off_screen
;we should check if off screen based on rad
mov esi,edi
call g3_project_point
test [esi].p3_flags,PF_OVERFLOW
jnz blob_off_screen
;get 2d width & height
mov eax,ebx ;get width
imul Canv_w2
blob_div0: divcheck [esi].z,blob_overflow_handler
idiv [esi].z ;width3d*canv_w/z
fixmul Matrix_scale.x ;*scale
mov edi,eax ;save width
mov eax,ecx ;get height
imul Canv_h2
blob_div1: divcheck [esi].z,blob_overflow_handler
idiv [esi].z ;height3d*canv_h/z
fixmul Matrix_scale.y ;*scale
mov ecx,eax ;save height
;copy 2d points into buffer
lea edx,_blob_vertices
mov eax,[esi].p3_sx
sub eax,edi ;- width
mov [edx],eax ;p0.x
lea eax,[eax+edi*2] ;+ 2*width
mov 8[edx],eax ;p1.x
mov 16[edx],eax ;p2.x
mov eax,[esi].p3_sy
sub eax,ecx ;- height
mov 4[edx],eax ;p0.y
mov 12[edx],eax ;p1.y
lea eax,[eax+ecx*2] ;+ 2*height
mov 20[edx],eax ;p2.y
;now draw
mov eax,bitmap_ptr ;get bitmap ptr
call scale_bitmap_ ;vertbuf in edx
blob_off_screen: popm edx,edi
ret
blob_overflow_handler:
;debug_brk "blob overflow - get Matt"
jmp blob_off_screen
;compute the corners of a rod. fills in vertbuf. ret codes in al.
;points in esi,edi, widths in eax,edx
;trashes piles of registers
calc_rod_corners:
mov bot_width,eax
mov top_width,edx
mov bot_pnt,esi
mov top_pnt,edi
;compute vector from one point to other, do cross product with vector
;from eye to get perpendiclar
lea eax,delta_vec
call vm_vec_sub
;unscale for aspect
mov eax,delta_vec.x
fixdiv matrix_scale.x
mov delta_vec.x,eax
mov eax,delta_vec.y
fixdiv matrix_scale.y
mov delta_vec.y,eax
;calc perp vector
;do lots of normalizing to prevent overflowing. When this code works,
;it should be optimized
lea esi,delta_vec
call vm_vec_normalize
vm_copy temp_vec,edi
mov edi,esi
lea esi,temp_vec
call vm_vec_normalize
xchg esi,edi
lea eax,rod_norm
call vm_vec_crossprod
mov esi,eax
call vm_vec_normalize
;scale for aspect
mov eax,rod_norm.x
fixmul matrix_scale.x
mov rod_norm.x,eax
mov eax,rod_norm.y
fixmul matrix_scale.y
mov rod_norm.y,eax
;now we have the usable edge. generate four points
mov cl,0ffh ;codes and
push ebp
lea ebp,rod_points
;top points
lea edi,temp_vec
lea ebx,rod_norm
mov ecx,top_width
call vm_vec_copy_scale
mov temp_vec.z,0
mov eax,ebp
mov esi,top_pnt ;temp vec in edi
call vm_vec_add
add eax,size g3s_point
call vm_vec_sub
lea ebp,size g3s_point[eax]
;bot points
lea edi,temp_vec
lea ebx,rod_norm
mov ecx,bot_width
call vm_vec_copy_scale
mov temp_vec.z,0
mov eax,ebp
mov esi,bot_pnt ;temp vec in edi
call vm_vec_sub
add eax,size g3s_point
call vm_vec_add
pop ebp
;now code the four points
mov cl,0ffh ;codes and
lea eax,rod_points
call code_point
and cl,bl
add eax,size g3s_point
call code_point
and cl,bl
add eax,size g3s_point
call code_point
and cl,bl
add eax,size g3s_point
call code_point
and cl,bl
jnz new_new_off_screen
push ecx ;save codes
;clear flags for new points (not projected)
lea esi,rod_points
mov [esi].p3_flags,0
mov [esi+size g3s_point].p3_flags,0
mov [esi+(size g3s_point)*2].p3_flags,0
mov [esi+(size g3s_point)*3].p3_flags,0
pop ecx ;restore codes
ret
new_new_off_screen:
ret
_TEXT ends
end