dxx-rebirth/3d/interp.asm
Bradley Bell 9bd1ba7c47 This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
2001-01-19 03:30:16 +00:00

1013 lines
20 KiB
NASM

; 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-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
.386
option oldstructs
.nolist
include pstypes.inc
include psmacros.inc
include gr.inc
include 3d.inc
.list
assume cs:_TEXT, ds:_DATA
_DATA segment dword public USE32 'DATA'
rcsid db "$Id: interp.asm,v 1.1.1.1 2001-01-19 03:29:58 bradleyb Exp $"
align 4
;table with address for each opcode
opcode_table dd op_eof ;0 = eof
dd op_defpoints ;1 = defpoints
dd op_flatpoly ;2 = flat-shaded polygon
dd op_tmappoly ;3 = texture-mapped polygon
dd op_sortnorm ;4 = sort by normal
dd op_rodbm ;5 = rod bitmap
dd op_subcall ;6 = call a subobject
dd op_defp_start ;7 = defpoints with start
dd op_glow ;8 = glow value for next poly
n_opcodes = ($-opcode_table)/4
bitmap_ptr dd ?
anim_angles dd ? ;pointer to angle data
morph_points dd ? ;alternate points for morph
;light value for the next tmap
glow_num dd -1 ;-1 means off
glow_values dd ? ;ptr to array of values
public _highest_texture_num
_highest_texture_num dw 0
zero_angles fixang 0,0,0 ;vms_angvec <0,0,0> ;for if no angles specified
rod_top_p g3s_point <>
rod_bot_p g3s_point <>
public g3d_interp_outline,_g3d_interp_outline
_g3d_interp_outline label dword
g3d_interp_outline dd 0
morph_pointlist dd ?,?,?
morph_uvls fix 3 dup (?,?,?)
;the light for the current model
model_light fix ?
;ptr to array of points
Interp_point_list dd ?
MAX_POINTS_PER_POLY = 25
point_list dd MAX_POINTS_PER_POLY dup (?)
MAX_INTERP_COLORS = 100
;this is a table of mappings from RGB15 to palette colors
interp_color_table dw MAX_INTERP_COLORS dup (?,?)
n_interp_colors dd 0
uninit_flag dd 0
_DATA ends
_TEXT segment dword public USE32 'CODE'
;get and jump to next opcode
next macro
xor ebx,ebx
mov bx,[ebp]
ifndef NDEBUG
cmp ebx,n_opcodes
break_if ge,'Invalid opcode'
endif
mov ebx,opcode_table[ebx*4]
jmp ebx
endm
;get and call the next opcode
call_next macro
xor ebx,ebx
mov bx,[ebp]
ifndef NDEBUG
cmp ebx,n_opcodes
break_if ge,'Invalid opcode'
endif
mov ebx,opcode_table[ebx*4]
call ebx
endm
;give the interpreter an array of points to use
g3_set_interp_points:
mov Interp_point_list,eax
ret
;interpreter to draw polygon model
;takes esi=ptr to object, edi=ptr to array of bitmap pointers,
;eax=ptr to anim angles, edx=light value, ebx=ptr to array of glow values
g3_draw_polygon_model:
pushm eax,ebx,ecx,edx,esi,edi,ebp
mov ebp,esi ;ebp = interp ptr
mov bitmap_ptr,edi ;save ptr to bitmap array
mov anim_angles,eax
mov model_light,edx
mov glow_values,ebx
mov glow_num,-1
;;@@ mov depth,0
call_next
popm eax,ebx,ecx,edx,esi,edi,ebp
ret
;handlers for opcodes
;end of a model or sub-rountine
op_eof: ret
;define a list of points
op_defpoints: xor ecx,ecx
mov cx,2[ebp] ;num points
mov edi,Interp_point_list
lea esi,4[ebp]
rotate_loop: call g3_rotate_point
add edi,size g3s_point
add esi,size vms_vector
dec ecx
jnz rotate_loop
mov ebp,esi
next
;define a list of points, with starting point num specified
op_defp_start: xor ecx,ecx
xor eax,eax
mov ax,w 4[ebp] ;starting point num
imulc eax,size g3s_point ;get ofs of point
add eax,Interp_point_list
mov edi,eax
mov cx,2[ebp] ;num points
lea esi,8[ebp]
jmp rotate_loop
next
;draw a flat-shaded polygon
op_flatpoly: xor ecx,ecx
mov cx,2[ebp] ;num verts
lea esi,4[ebp] ;point
lea edi,16[ebp] ;vector
call g3_check_normal_facing
jng flat_not_facing
;polygon is facing, so draw it
;here the glow parameter is used for the player's headlight
test glow_num,-1 ;glow override?
js no_glow2
mov eax,glow_num
mov esi,glow_values
mov eax,[esi+eax*4]
mov glow_num,-1
cmp eax,-1 ;-1 means draw normal color
jne not_normal_color
;use the color specified, run through darkening table
xor ebx,ebx
mov eax,32 ;32 shades
imul model_light
sar eax,16
or eax,eax
jns no_sat1
xor eax,eax
no_sat1: cmp eax,32
jl no_sat2
mov eax,32
no_sat2: mov bh,al ;get lighting table
xor eax,eax
mov ax,28[ebp] ;get color index
mov ax,interp_color_table[eax*4]
mov bl,al
mov al,gr_fade_table[ebx]
jmp got_color_index
not_normal_color: cmp eax,-2 ;-2 means use white
jne not_white
mov eax,255 ;hack!
jmp got_color_index
not_white: cmp eax,-3 ;-3 means don't draw polygon
je flat_not_facing
no_glow2:
xor eax,eax
mov ax,28[ebp] ;get color index
mov ax,interp_color_table[eax*4]
got_color_index: call gr_setcolor_ ;set it
lea esi,30[ebp] ;point number list
;make list of point pointers
ifndef NDEBUG
cmp ecx,MAX_POINTS_PER_POLY
break_if ge,'Too many points in interp poly'
endif
lea edi,point_list
xor ebx,ebx
copy_loop: xor eax,eax
mov ax,w [esi+ebx*2] ;get point number
imulc eax,size g3s_point
add eax,Interp_point_list
mov [edi+ebx*4],eax
inc ebx
cmp ebx,ecx
jne copy_loop
mov esi,edi
call g3_draw_poly
xor ecx,ecx
mov cx,2[ebp] ;restore count
ifndef NDEBUG
test g3d_interp_outline,-1
jz no_outline
pushm ecx,esi
lea esi,30[ebp]
call draw_outline
popm ecx,esi
no_outline:
endif
;polygon is not facing (or we've plotted it). jump to next opcode
flat_not_facing: and ecx,0fffffffeh
inc ecx ;adjust for pad
lea ebp,30[ebp+ecx*2]
next
;set the glow value for the next tmap
op_glow: test glow_values,-1
jz skip_glow
xor eax,eax
mov ax,2[ebp]
mov glow_num,eax
skip_glow: add ebp,4
next
;draw a texture map
op_tmappoly: xor ecx,ecx
mov cx,2[ebp] ;num verts
lea esi,4[ebp] ;point
lea edi,16[ebp] ;normal
call g3_check_normal_facing
jng tmap_not_facing
;polygon is facing, so draw it
xor edx,edx
mov dx,28[ebp] ;get bitmap number
mov eax,bitmap_ptr
mov edx,[eax+edx*4]
lea esi,30[ebp] ;point number list
mov eax,ecx
and eax,0fffffffeh
inc eax
lea ebx,30[ebp+eax*2] ;get uvl list
;calculate light from surface normal
push esi
test glow_num,-1 ;glow override?
js no_glow
;special glow lighting, which doesn't care about surface normal
mov eax,glow_num
mov esi,glow_values
mov eax,[esi+eax*4]
mov glow_num,-1
jmp got_light_value
no_glow:
lea esi,View_matrix.fvec
lea edi,16[ebp] ;normal
call vm_vec_dotprod
neg eax
;scale light by model light
push edx
mov edx,eax
add eax,eax
add eax,edx ;eax *= 3
sar eax,2 ;eax *= 3/4
add eax,f1_0/4 ;eax = 1/4 + eax * 3/4
fixmul model_light
pop edx
;now poke light into l values
got_light_value: pushm ecx,ebx
l_loop: mov 8[ebx],eax
add ebx,12
dec ecx
jnz l_loop
popm ecx,ebx
pop esi
;now draw it
;make list of point pointers
ifndef NDEBUG
cmp ecx,MAX_POINTS_PER_POLY
break_if ge,'Too many points in interp poly'
endif
push ebx
lea edi,point_list
xor ebx,ebx
copy_loop2: xor eax,eax
mov ax,w [esi+ebx*2] ;get point number
imulc eax,size g3s_point
add eax,Interp_point_list
mov [edi+ebx*4],eax
inc ebx
cmp ebx,ecx
jne copy_loop2
mov esi,edi
pop ebx
call g3_draw_tmap
xor ecx,ecx
mov cx,2[ebp] ;restore count
ifndef NDEBUG
test g3d_interp_outline,-1
jz no_outline2
pushm ecx,esi
lea esi,30[ebp]
call draw_outline
popm ecx,esi
no_outline2:
endif
;polygon is not facing (or we've plotted it). jump to next opcode
tmap_not_facing: mov ebx,ecx
and ebx,0fffffffeh
inc ebx ;adjust for pad
lea ebp,30[ebp+ebx*2]
mov eax,ecx
sal ecx,1
add ecx,eax
sal ecx,2 ;ecx=ecx*12
add ebp,ecx ;point past uvls
next
;sort based on surface normal
op_sortnorm: lea esi,16[ebp] ;point
lea edi,4[ebp] ;vector
call g3_check_normal_facing
jng sortnorm_not_facing
;is facing. draw back then front
push ebp
xor eax,eax
mov ax,30[ebp] ;get back offset
add ebp,eax
call_next
mov ebp,[esp] ;get ebp
xor eax,eax
mov ax,28[ebp] ;get front offset
add ebp,eax
call_next
pop ebp
lea ebp,32[ebp]
next
;is not facing. draw front then back
sortnorm_not_facing:
push ebp
xor eax,eax
mov ax,28[ebp] ;get back offset
add ebp,eax
call_next
mov ebp,[esp] ;get ebp
xor eax,eax
mov ax,30[ebp] ;get front offset
add ebp,eax
call_next
pop ebp
lea ebp,32[ebp]
next
;draw a rod bitmap
op_rodbm: lea esi,20[ebp] ;bot point
lea edi,rod_bot_p
call g3_rotate_point
lea esi,4[ebp] ;top point
lea edi,rod_top_p
call g3_rotate_point
lea esi,rod_bot_p ;esi=bot, edi=top
mov eax,16[ebp] ;bot width
mov edx,32[ebp] ;top width
xor ebx,ebx
mov bx,2[ebp] ;get bitmap number
mov ecx,bitmap_ptr
mov ebx,[ecx+ebx*4]
call g3_draw_rod_tmap
lea ebp,36[ebp]
next
;draw a subobject
op_subcall: xor eax,eax
mov ax,2[ebp] ;get object number
;get ptr to angles
mov edi,anim_angles
or edi,edi
jnz angles_not_null
;angles not specified. Use zero angles
lea edi,zero_angles
jmp got_angles
angles_not_null:
imulc eax,size vms_angvec
add edi,eax
got_angles:
;angles in edi
lea esi,4[ebp] ;get position
call g3_start_instance_angles
push ebp
xor eax,eax
mov ax,16[ebp]
add ebp,eax ;offset of subobject
call_next ;draw the subobject
pop ebp
call g3_done_instance
lea ebp,20[ebp]
next
;takes ax, returns ax
find_color_index: push ebx
;first, see if color already in table
xor ebx,ebx ;counter
look_loop: cmp ebx,n_interp_colors
je must_add_color
cmp ax,interp_color_table+2[ebx*4]
je found_color
inc ebx
jmp look_loop
must_add_color: mov interp_color_table+2[ebx*4],ax ;save rgb15
call gr_find_closest_color_15bpp_
mov interp_color_table[ebx*4],ax ;save pal entry
inc n_interp_colors
found_color: mov eax,ebx ;return index
pop ebx
ret
;this remaps the 15bpp colors for the models into a new palette. It should
;be called whenever the palette changes
g3_remap_interp_colors:
pushm eax,ebx
xor ebx,ebx ;index
remap_loop: cmp ebx,n_interp_colors
je done_remap
xor eax,eax
mov ax,interp_color_table+2[ebx*4] ;get rgb15
call gr_find_closest_color_15bpp_
mov interp_color_table[ebx*4],ax ;store pal entry
inc ebx
jmp remap_loop
done_remap: popm eax,ebx
ret
;maps the colors back to RGB15
g3_uninit_polygon_model:
mov uninit_flag,1
;initialize a polygon object
;translate colors, scale UV values
;takes esi=ptr to model
g3_init_polygon_model:
mov _highest_texture_num,-1
pushm eax,ebx,ecx,edx,esi,edi
call init_loop
popm eax,ebx,ecx,edx,esi,edi
mov uninit_flag,0
ret
init_loop: mov ax,[esi] ;get opcode
cmp ax,0 ;eof
jne not_eof
ret
not_eof:
;defpoints
cmp ax,1 ;defpoints
jne not_defpoints
xor eax,eax
mov ax,2[esi] ;get count
sal eax,1
add ax,2[esi] ;*3
lea esi,4[esi+eax*4]
jmp init_loop
not_defpoints:
;flat polygon
cmp ax,2
jne not_flatpoly
ifndef NDEBUG
cmp w 2[esi],3
break_if l,'face must have 3 or more points'
endif
; The following 3 lines replace the above
xor eax, eax
mov ax,28[esi] ;get color
test uninit_flag,-1
jz not_uninit
;unitialize!
mov ax,interp_color_table+2[eax*4]
jmp cont1
not_uninit:
call find_color_index
cont1: mov 28[esi],ax ;store new color
xor ecx,ecx
mov cx,2[esi] ;get nverts
and ecx,0fffffffeh
inc ecx ;adjust for pad
lea esi,30[esi+ecx*2]
jmp init_loop
not_flatpoly:
;tmap polygon
cmp ax,3
jne not_tmappoly
ifndef NDEBUG
cmp w 2[esi],3
break_if l,'face must have 3 or more points'
endif
mov ax,28[esi] ;get bitmap number
cmp ax,_highest_texture_num
jle not_new
mov _highest_texture_num,ax
not_new: xor ecx,ecx
mov cx,2[esi] ;get nverts
mov ebx,ecx
and ebx,0fffffffeh
inc ebx ;adjust for pad
lea esi,30[esi+ebx*2] ;point at uvls
imul ecx,12 ;size of uvls
add esi,ecx ;skip them
jmp init_loop
;;@@init_uv_loop: mov eax,[esi] ;get u
;;@@ imul eax,64 ;times bitmap w
;;@@ mov [esi],eax
;;@@ mov eax,4[esi] ;get v
;;@@ imul eax,64 ;times bitmap h
;;@@ mov 4[esi],eax
;;@@ add esi,12 ;point at next
;;@@ dec ecx
;;@@ jnz init_uv_loop
;;@@ jmp init_loop
not_tmappoly:
;sort
cmp ax,4 ;sortnorm
jne not_sortnorm
push esi
xor eax,eax
mov ax,28[esi] ;get front offset
add esi,eax
call init_loop
mov esi,[esp]
xor eax,eax
mov ax,30[esi] ;get front offset
add esi,eax
call init_loop
pop esi
lea esi,32[esi]
jmp init_loop
not_sortnorm:
cmp ax,5
jne not_rodbm
add esi,36
jmp init_loop
not_rodbm:
cmp ax,6
jne not_subcall
push esi
xor eax,eax
mov ax,16[esi] ;get subobj offset
add esi,eax
call init_loop
pop esi
add esi,20
jmp init_loop
not_subcall:
cmp ax,7 ;defpoints
jne not_defpoints_st
xor eax,eax
mov ax,2[esi] ;get count
sal eax,1
add ax,2[esi] ;*3
lea esi,8[esi+eax*4]
jmp init_loop
not_defpoints_st:
cmp ax,8
jne not_glow
add esi,4
jmp init_loop
not_glow:
debug_brk "Invalid opcode"
jmp init_loop
;takes ecx=count, esi=ptr to point list
draw_outline: pushm eax,ebx,ecx,edx,esi,edi
;NO_INVERSE_TABLE xor eax,eax
;NO_INVERSE_TABLE mov al,gr_inverse_table[7fffh] ;white
mov eax, 255 ; bright white
call gr_setcolor_
mov ebx,esi
xor eax,eax
mov ax,[ebx] ;get first point
push eax ;save it
outline_loop: xor esi,esi
xor edi,edi
mov si,[ebx]
dec ecx
jz done_loop
mov di,2[ebx]
push ebx
imul esi,size g3s_point
add esi,Interp_point_list
imul edi,size g3s_point
add edi,Interp_point_list
call g3_draw_line
pop ebx
add ebx,2
jmp outline_loop
done_loop: pop edi ;get first point back
imul esi,size g3s_point
add esi,Interp_point_list
imul edi,size g3s_point
add edi,Interp_point_list
call g3_draw_line
popm eax,ebx,ecx,edx,esi,edi
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Special code to draw morphing objects
;define a list of points
morph_defpoints: xor ecx,ecx
mov cx,2[ebp] ;num points
mov edi,Interp_point_list
lea esi,4[ebp]
morph_rotate_list: lea eax,[ecx*2+ecx] ;eax=npoint * 3
lea esi,[esi+eax*4] ;point past points
push esi
mov esi,morph_points ;get alternate points
morph_rotate_loop: call g3_rotate_point
add edi,size g3s_point
add esi,size vms_vector
dec ecx
jnz morph_rotate_loop
pop esi ;restore pointer
mov ebp,esi
next
;define a list of points, with starting point num specified
morph_defp_start: xor ecx,ecx
xor eax,eax
mov ax,w 4[ebp] ;starting point num
imulc eax,size g3s_point ;get ofs of point
add eax,Interp_point_list
mov edi,eax
mov cx,2[ebp] ;num points
lea esi,8[ebp]
jmp morph_rotate_list
;draw a flat-shaded polygon
morph_flatpoly: xor ecx,ecx
mov cx,2[ebp] ;num verts
lea esi,4[ebp] ;point
lea edi,16[ebp] ;vector
;set color
xor eax,eax
mov ax,28[ebp] ;get color
mov ax,interp_color_table[eax*4]
call gr_setcolor_ ;set it
;check and draw
lea esi,30[ebp] ;point number list
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+4,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+8,eax
cmp ecx,3 ;3 points is good!
je flat_got3
sub ecx,2 ;tri count
flat_tri_loop: xor edi,edi ;no normal, must compute
pushm ecx,esi
mov ecx,3 ;always draw triangle
lea esi,morph_pointlist
call g3_check_and_draw_poly
popm ecx,esi
mov eax,morph_pointlist+8
mov morph_pointlist+4,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+8,eax
dec ecx
jnz flat_tri_loop
jmp flat_done_draw
flat_got3:
lea esi,morph_pointlist
xor edi,edi ;no normal, must compute
call g3_check_and_draw_poly
flat_done_draw: xor ecx,ecx
mov cx,2[ebp] ;restore count
and ecx,0fffffffeh
inc ecx ;adjust for pad
lea ebp,30[ebp+ecx*2]
next
;draw a texture map
morph_tmappoly: xor ecx,ecx
mov cx,2[ebp] ;num verts
lea esi,4[ebp] ;point
lea edi,16[ebp] ;normal
;get bitmap
xor edx,edx
mov dx,28[ebp] ;get bitmap number
mov eax,bitmap_ptr
mov edx,[eax+edx*4]
lea esi,30[ebp] ;point number list
mov eax,ecx
and eax,0fffffffeh
inc eax
lea ebx,30[ebp+eax*2] ;get uvl list
;calculate light from surface normal
push esi
lea esi,View_matrix.fvec
lea edi,16[ebp] ;normal
call vm_vec_dotprod
neg eax
;scale light by model light
push edx
mov edx,eax
add eax,eax
add eax,edx ;eax *= 3
sar eax,2 ;eax *= 3/4
add eax,f1_0/4 ;eax = 1/4 + eax * 3/4
fixmul model_light
or eax,eax
jge not_zero
xor eax,eax
not_zero:
pop edx
pop esi
;now eax=plane light value
mov morph_uvls+8,eax
mov morph_uvls+20,eax
mov morph_uvls+32,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+4,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+8,eax
cmp ecx,3 ;3 points is good!
jl tmap_done_draw ;something is bad, abort
je tmap_got3
sub ecx,2 ;tri count
push edx
mov edx,[ebx]
mov morph_uvls,edx
mov edx,4[ebx]
mov morph_uvls+4,edx
mov edx,12[ebx]
mov morph_uvls+12,edx
mov edx,16[ebx]
mov morph_uvls+16,edx
mov edx,24[ebx]
mov morph_uvls+24,edx
mov edx,28[ebx]
mov morph_uvls+28,edx
add ebx,3*12
pop edx
tmap_tri_loop: xor edi,edi ;no normal, must compute
pushm ebx,edx,ecx,esi
mov ecx,3 ;always draw triangle
lea esi,morph_pointlist
lea ebx,morph_uvls
call g3_check_and_draw_tmap
popm ebx,edx,ecx,esi
mov eax,morph_pointlist+8
mov morph_pointlist+4,eax
xor eax,eax
lodsw
imulc eax,size g3s_point
add eax,Interp_point_list
mov morph_pointlist+8,eax
push edx
mov edx,morph_uvls+24
mov morph_uvls+12,edx
mov edx,morph_uvls+28
mov morph_uvls+16,edx
mov edx,[ebx]
mov morph_uvls+24,edx
mov edx,4[ebx]
mov morph_uvls+28,edx
add ebx,12
pop edx
dec ecx
jnz tmap_tri_loop
jmp tmap_done_draw
tmap_got3:
;poke in light values
pusha
tmap_l_loop: mov 8[ebx],eax
add ebx,12
dec ecx
jnz tmap_l_loop
popa
lea esi,morph_pointlist
xor edi,edi ;no normal
call g3_check_and_draw_tmap
tmap_done_draw: xor ecx,ecx
mov cx,2[ebp] ;restore count
;jump to next opcode
mov ebx,ecx
and ebx,0fffffffeh
inc ebx ;adjust for pad
lea ebp,30[ebp+ebx*2]
mov eax,ecx
sal ecx,1
add ecx,eax
sal ecx,2 ;ecx=ecx*12
add ebp,ecx ;point past uvls
next
;interpreter to draw polygon model
;takes esi=ptr to object, edi=ptr to array of bitmap pointers,
;eax=ptr to anim angles, ebx=alternate points, edx=light value
g3_draw_morphing_model:
pushm eax,ebx,ecx,edx,esi,edi,ebp
mov bitmap_ptr,edi ;save ptr to bitmap array
mov anim_angles,eax
mov morph_points,ebx
mov model_light,edx
mov ebp,esi ;ebp = interp ptr
;set alternate opcode pointers
push opcode_table[1*4] ;defpoints
push opcode_table[2*4] ;flatpoly
push opcode_table[3*4] ;tmappoly
push opcode_table[7*4] ;defp_start
mov opcode_table[1*4],offset morph_defpoints
mov opcode_table[2*4],offset morph_flatpoly
mov opcode_table[3*4],offset morph_tmappoly
mov opcode_table[7*4],offset morph_defp_start
call_next
pop opcode_table[7*4] ;defp_start
pop opcode_table[3*4] ;tmappoly
pop opcode_table[2*4] ;flatpoly
pop opcode_table[1*4] ;defpoints
popm eax,ebx,ecx,edx,esi,edi,ebp
ret
_TEXT ends
end