12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013 |
- ; 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 1.27 1996/01/08 14:59:12 matt 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
|