INTERP.ASM 20 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. ; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  9. ; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  10. ; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  11. .386
  12. option oldstructs
  13. .nolist
  14. include pstypes.inc
  15. include psmacros.inc
  16. include gr.inc
  17. include 3d.inc
  18. .list
  19. assume cs:_TEXT, ds:_DATA
  20. _DATA segment dword public USE32 'DATA'
  21. rcsid db "$Id: interp.asm 1.27 1996/01/08 14:59:12 matt Exp $"
  22. align 4
  23. ;table with address for each opcode
  24. opcode_table dd op_eof ;0 = eof
  25. dd op_defpoints ;1 = defpoints
  26. dd op_flatpoly ;2 = flat-shaded polygon
  27. dd op_tmappoly ;3 = texture-mapped polygon
  28. dd op_sortnorm ;4 = sort by normal
  29. dd op_rodbm ;5 = rod bitmap
  30. dd op_subcall ;6 = call a subobject
  31. dd op_defp_start ;7 = defpoints with start
  32. dd op_glow ;8 = glow value for next poly
  33. n_opcodes = ($-opcode_table)/4
  34. bitmap_ptr dd ?
  35. anim_angles dd ? ;pointer to angle data
  36. morph_points dd ? ;alternate points for morph
  37. ;light value for the next tmap
  38. glow_num dd -1 ;-1 means off
  39. glow_values dd ? ;ptr to array of values
  40. public _highest_texture_num
  41. _highest_texture_num dw 0
  42. zero_angles fixang 0,0,0 ;vms_angvec <0,0,0> ;for if no angles specified
  43. rod_top_p g3s_point <>
  44. rod_bot_p g3s_point <>
  45. public g3d_interp_outline,_g3d_interp_outline
  46. _g3d_interp_outline label dword
  47. g3d_interp_outline dd 0
  48. morph_pointlist dd ?,?,?
  49. morph_uvls fix 3 dup (?,?,?)
  50. ;the light for the current model
  51. model_light fix ?
  52. ;ptr to array of points
  53. Interp_point_list dd ?
  54. MAX_POINTS_PER_POLY = 25
  55. point_list dd MAX_POINTS_PER_POLY dup (?)
  56. MAX_INTERP_COLORS = 100
  57. ;this is a table of mappings from RGB15 to palette colors
  58. interp_color_table dw MAX_INTERP_COLORS dup (?,?)
  59. n_interp_colors dd 0
  60. uninit_flag dd 0
  61. _DATA ends
  62. _TEXT segment dword public USE32 'CODE'
  63. ;get and jump to next opcode
  64. next macro
  65. xor ebx,ebx
  66. mov bx,[ebp]
  67. ifndef NDEBUG
  68. cmp ebx,n_opcodes
  69. break_if ge,'Invalid opcode'
  70. endif
  71. mov ebx,opcode_table[ebx*4]
  72. jmp ebx
  73. endm
  74. ;get and call the next opcode
  75. call_next macro
  76. xor ebx,ebx
  77. mov bx,[ebp]
  78. ifndef NDEBUG
  79. cmp ebx,n_opcodes
  80. break_if ge,'Invalid opcode'
  81. endif
  82. mov ebx,opcode_table[ebx*4]
  83. call ebx
  84. endm
  85. ;give the interpreter an array of points to use
  86. g3_set_interp_points:
  87. mov Interp_point_list,eax
  88. ret
  89. ;interpreter to draw polygon model
  90. ;takes esi=ptr to object, edi=ptr to array of bitmap pointers,
  91. ;eax=ptr to anim angles, edx=light value, ebx=ptr to array of glow values
  92. g3_draw_polygon_model:
  93. pushm eax,ebx,ecx,edx,esi,edi,ebp
  94. mov ebp,esi ;ebp = interp ptr
  95. mov bitmap_ptr,edi ;save ptr to bitmap array
  96. mov anim_angles,eax
  97. mov model_light,edx
  98. mov glow_values,ebx
  99. mov glow_num,-1
  100. ;;@@ mov depth,0
  101. call_next
  102. popm eax,ebx,ecx,edx,esi,edi,ebp
  103. ret
  104. ;handlers for opcodes
  105. ;end of a model or sub-rountine
  106. op_eof: ret
  107. ;define a list of points
  108. op_defpoints: xor ecx,ecx
  109. mov cx,2[ebp] ;num points
  110. mov edi,Interp_point_list
  111. lea esi,4[ebp]
  112. rotate_loop: call g3_rotate_point
  113. add edi,size g3s_point
  114. add esi,size vms_vector
  115. dec ecx
  116. jnz rotate_loop
  117. mov ebp,esi
  118. next
  119. ;define a list of points, with starting point num specified
  120. op_defp_start: xor ecx,ecx
  121. xor eax,eax
  122. mov ax,w 4[ebp] ;starting point num
  123. imulc eax,size g3s_point ;get ofs of point
  124. add eax,Interp_point_list
  125. mov edi,eax
  126. mov cx,2[ebp] ;num points
  127. lea esi,8[ebp]
  128. jmp rotate_loop
  129. next
  130. ;draw a flat-shaded polygon
  131. op_flatpoly: xor ecx,ecx
  132. mov cx,2[ebp] ;num verts
  133. lea esi,4[ebp] ;point
  134. lea edi,16[ebp] ;vector
  135. call g3_check_normal_facing
  136. jng flat_not_facing
  137. ;polygon is facing, so draw it
  138. ;here the glow parameter is used for the player's headlight
  139. test glow_num,-1 ;glow override?
  140. js no_glow2
  141. mov eax,glow_num
  142. mov esi,glow_values
  143. mov eax,[esi+eax*4]
  144. mov glow_num,-1
  145. cmp eax,-1 ;-1 means draw normal color
  146. jne not_normal_color
  147. ;use the color specified, run through darkening table
  148. xor ebx,ebx
  149. mov eax,32 ;32 shades
  150. imul model_light
  151. sar eax,16
  152. or eax,eax
  153. jns no_sat1
  154. xor eax,eax
  155. no_sat1: cmp eax,32
  156. jl no_sat2
  157. mov eax,32
  158. no_sat2: mov bh,al ;get lighting table
  159. xor eax,eax
  160. mov ax,28[ebp] ;get color index
  161. mov ax,interp_color_table[eax*4]
  162. mov bl,al
  163. mov al,gr_fade_table[ebx]
  164. jmp got_color_index
  165. not_normal_color: cmp eax,-2 ;-2 means use white
  166. jne not_white
  167. mov eax,255 ;hack!
  168. jmp got_color_index
  169. not_white: cmp eax,-3 ;-3 means don't draw polygon
  170. je flat_not_facing
  171. no_glow2:
  172. xor eax,eax
  173. mov ax,28[ebp] ;get color index
  174. mov ax,interp_color_table[eax*4]
  175. got_color_index: call gr_setcolor_ ;set it
  176. lea esi,30[ebp] ;point number list
  177. ;make list of point pointers
  178. ifndef NDEBUG
  179. cmp ecx,MAX_POINTS_PER_POLY
  180. break_if ge,'Too many points in interp poly'
  181. endif
  182. lea edi,point_list
  183. xor ebx,ebx
  184. copy_loop: xor eax,eax
  185. mov ax,w [esi+ebx*2] ;get point number
  186. imulc eax,size g3s_point
  187. add eax,Interp_point_list
  188. mov [edi+ebx*4],eax
  189. inc ebx
  190. cmp ebx,ecx
  191. jne copy_loop
  192. mov esi,edi
  193. call g3_draw_poly
  194. xor ecx,ecx
  195. mov cx,2[ebp] ;restore count
  196. ifndef NDEBUG
  197. test g3d_interp_outline,-1
  198. jz no_outline
  199. pushm ecx,esi
  200. lea esi,30[ebp]
  201. call draw_outline
  202. popm ecx,esi
  203. no_outline:
  204. endif
  205. ;polygon is not facing (or we've plotted it). jump to next opcode
  206. flat_not_facing: and ecx,0fffffffeh
  207. inc ecx ;adjust for pad
  208. lea ebp,30[ebp+ecx*2]
  209. next
  210. ;set the glow value for the next tmap
  211. op_glow: test glow_values,-1
  212. jz skip_glow
  213. xor eax,eax
  214. mov ax,2[ebp]
  215. mov glow_num,eax
  216. skip_glow: add ebp,4
  217. next
  218. ;draw a texture map
  219. op_tmappoly: xor ecx,ecx
  220. mov cx,2[ebp] ;num verts
  221. lea esi,4[ebp] ;point
  222. lea edi,16[ebp] ;normal
  223. call g3_check_normal_facing
  224. jng tmap_not_facing
  225. ;polygon is facing, so draw it
  226. xor edx,edx
  227. mov dx,28[ebp] ;get bitmap number
  228. mov eax,bitmap_ptr
  229. mov edx,[eax+edx*4]
  230. lea esi,30[ebp] ;point number list
  231. mov eax,ecx
  232. and eax,0fffffffeh
  233. inc eax
  234. lea ebx,30[ebp+eax*2] ;get uvl list
  235. ;calculate light from surface normal
  236. push esi
  237. test glow_num,-1 ;glow override?
  238. js no_glow
  239. ;special glow lighting, which doesn't care about surface normal
  240. mov eax,glow_num
  241. mov esi,glow_values
  242. mov eax,[esi+eax*4]
  243. mov glow_num,-1
  244. jmp got_light_value
  245. no_glow:
  246. lea esi,View_matrix.fvec
  247. lea edi,16[ebp] ;normal
  248. call vm_vec_dotprod
  249. neg eax
  250. ;scale light by model light
  251. push edx
  252. mov edx,eax
  253. add eax,eax
  254. add eax,edx ;eax *= 3
  255. sar eax,2 ;eax *= 3/4
  256. add eax,f1_0/4 ;eax = 1/4 + eax * 3/4
  257. fixmul model_light
  258. pop edx
  259. ;now poke light into l values
  260. got_light_value: pushm ecx,ebx
  261. l_loop: mov 8[ebx],eax
  262. add ebx,12
  263. dec ecx
  264. jnz l_loop
  265. popm ecx,ebx
  266. pop esi
  267. ;now draw it
  268. ;make list of point pointers
  269. ifndef NDEBUG
  270. cmp ecx,MAX_POINTS_PER_POLY
  271. break_if ge,'Too many points in interp poly'
  272. endif
  273. push ebx
  274. lea edi,point_list
  275. xor ebx,ebx
  276. copy_loop2: xor eax,eax
  277. mov ax,w [esi+ebx*2] ;get point number
  278. imulc eax,size g3s_point
  279. add eax,Interp_point_list
  280. mov [edi+ebx*4],eax
  281. inc ebx
  282. cmp ebx,ecx
  283. jne copy_loop2
  284. mov esi,edi
  285. pop ebx
  286. call g3_draw_tmap
  287. xor ecx,ecx
  288. mov cx,2[ebp] ;restore count
  289. ifndef NDEBUG
  290. test g3d_interp_outline,-1
  291. jz no_outline2
  292. pushm ecx,esi
  293. lea esi,30[ebp]
  294. call draw_outline
  295. popm ecx,esi
  296. no_outline2:
  297. endif
  298. ;polygon is not facing (or we've plotted it). jump to next opcode
  299. tmap_not_facing: mov ebx,ecx
  300. and ebx,0fffffffeh
  301. inc ebx ;adjust for pad
  302. lea ebp,30[ebp+ebx*2]
  303. mov eax,ecx
  304. sal ecx,1
  305. add ecx,eax
  306. sal ecx,2 ;ecx=ecx*12
  307. add ebp,ecx ;point past uvls
  308. next
  309. ;sort based on surface normal
  310. op_sortnorm: lea esi,16[ebp] ;point
  311. lea edi,4[ebp] ;vector
  312. call g3_check_normal_facing
  313. jng sortnorm_not_facing
  314. ;is facing. draw back then front
  315. push ebp
  316. xor eax,eax
  317. mov ax,30[ebp] ;get back offset
  318. add ebp,eax
  319. call_next
  320. mov ebp,[esp] ;get ebp
  321. xor eax,eax
  322. mov ax,28[ebp] ;get front offset
  323. add ebp,eax
  324. call_next
  325. pop ebp
  326. lea ebp,32[ebp]
  327. next
  328. ;is not facing. draw front then back
  329. sortnorm_not_facing:
  330. push ebp
  331. xor eax,eax
  332. mov ax,28[ebp] ;get back offset
  333. add ebp,eax
  334. call_next
  335. mov ebp,[esp] ;get ebp
  336. xor eax,eax
  337. mov ax,30[ebp] ;get front offset
  338. add ebp,eax
  339. call_next
  340. pop ebp
  341. lea ebp,32[ebp]
  342. next
  343. ;draw a rod bitmap
  344. op_rodbm: lea esi,20[ebp] ;bot point
  345. lea edi,rod_bot_p
  346. call g3_rotate_point
  347. lea esi,4[ebp] ;top point
  348. lea edi,rod_top_p
  349. call g3_rotate_point
  350. lea esi,rod_bot_p ;esi=bot, edi=top
  351. mov eax,16[ebp] ;bot width
  352. mov edx,32[ebp] ;top width
  353. xor ebx,ebx
  354. mov bx,2[ebp] ;get bitmap number
  355. mov ecx,bitmap_ptr
  356. mov ebx,[ecx+ebx*4]
  357. call g3_draw_rod_tmap
  358. lea ebp,36[ebp]
  359. next
  360. ;draw a subobject
  361. op_subcall: xor eax,eax
  362. mov ax,2[ebp] ;get object number
  363. ;get ptr to angles
  364. mov edi,anim_angles
  365. or edi,edi
  366. jnz angles_not_null
  367. ;angles not specified. Use zero angles
  368. lea edi,zero_angles
  369. jmp got_angles
  370. angles_not_null:
  371. imulc eax,size vms_angvec
  372. add edi,eax
  373. got_angles:
  374. ;angles in edi
  375. lea esi,4[ebp] ;get position
  376. call g3_start_instance_angles
  377. push ebp
  378. xor eax,eax
  379. mov ax,16[ebp]
  380. add ebp,eax ;offset of subobject
  381. call_next ;draw the subobject
  382. pop ebp
  383. call g3_done_instance
  384. lea ebp,20[ebp]
  385. next
  386. ;takes ax, returns ax
  387. find_color_index: push ebx
  388. ;first, see if color already in table
  389. xor ebx,ebx ;counter
  390. look_loop: cmp ebx,n_interp_colors
  391. je must_add_color
  392. cmp ax,interp_color_table+2[ebx*4]
  393. je found_color
  394. inc ebx
  395. jmp look_loop
  396. must_add_color: mov interp_color_table+2[ebx*4],ax ;save rgb15
  397. call gr_find_closest_color_15bpp_
  398. mov interp_color_table[ebx*4],ax ;save pal entry
  399. inc n_interp_colors
  400. found_color: mov eax,ebx ;return index
  401. pop ebx
  402. ret
  403. ;this remaps the 15bpp colors for the models into a new palette. It should
  404. ;be called whenever the palette changes
  405. g3_remap_interp_colors:
  406. pushm eax,ebx
  407. xor ebx,ebx ;index
  408. remap_loop: cmp ebx,n_interp_colors
  409. je done_remap
  410. xor eax,eax
  411. mov ax,interp_color_table+2[ebx*4] ;get rgb15
  412. call gr_find_closest_color_15bpp_
  413. mov interp_color_table[ebx*4],ax ;store pal entry
  414. inc ebx
  415. jmp remap_loop
  416. done_remap: popm eax,ebx
  417. ret
  418. ;maps the colors back to RGB15
  419. g3_uninit_polygon_model:
  420. mov uninit_flag,1
  421. ;initialize a polygon object
  422. ;translate colors, scale UV values
  423. ;takes esi=ptr to model
  424. g3_init_polygon_model:
  425. mov _highest_texture_num,-1
  426. pushm eax,ebx,ecx,edx,esi,edi
  427. call init_loop
  428. popm eax,ebx,ecx,edx,esi,edi
  429. mov uninit_flag,0
  430. ret
  431. init_loop: mov ax,[esi] ;get opcode
  432. cmp ax,0 ;eof
  433. jne not_eof
  434. ret
  435. not_eof:
  436. ;defpoints
  437. cmp ax,1 ;defpoints
  438. jne not_defpoints
  439. xor eax,eax
  440. mov ax,2[esi] ;get count
  441. sal eax,1
  442. add ax,2[esi] ;*3
  443. lea esi,4[esi+eax*4]
  444. jmp init_loop
  445. not_defpoints:
  446. ;flat polygon
  447. cmp ax,2
  448. jne not_flatpoly
  449. ifndef NDEBUG
  450. cmp w 2[esi],3
  451. break_if l,'face must have 3 or more points'
  452. endif
  453. ; The following 3 lines replace the above
  454. xor eax, eax
  455. mov ax,28[esi] ;get color
  456. test uninit_flag,-1
  457. jz not_uninit
  458. ;unitialize!
  459. mov ax,interp_color_table+2[eax*4]
  460. jmp cont1
  461. not_uninit:
  462. call find_color_index
  463. cont1: mov 28[esi],ax ;store new color
  464. xor ecx,ecx
  465. mov cx,2[esi] ;get nverts
  466. and ecx,0fffffffeh
  467. inc ecx ;adjust for pad
  468. lea esi,30[esi+ecx*2]
  469. jmp init_loop
  470. not_flatpoly:
  471. ;tmap polygon
  472. cmp ax,3
  473. jne not_tmappoly
  474. ifndef NDEBUG
  475. cmp w 2[esi],3
  476. break_if l,'face must have 3 or more points'
  477. endif
  478. mov ax,28[esi] ;get bitmap number
  479. cmp ax,_highest_texture_num
  480. jle not_new
  481. mov _highest_texture_num,ax
  482. not_new: xor ecx,ecx
  483. mov cx,2[esi] ;get nverts
  484. mov ebx,ecx
  485. and ebx,0fffffffeh
  486. inc ebx ;adjust for pad
  487. lea esi,30[esi+ebx*2] ;point at uvls
  488. imul ecx,12 ;size of uvls
  489. add esi,ecx ;skip them
  490. jmp init_loop
  491. ;;@@init_uv_loop: mov eax,[esi] ;get u
  492. ;;@@ imul eax,64 ;times bitmap w
  493. ;;@@ mov [esi],eax
  494. ;;@@ mov eax,4[esi] ;get v
  495. ;;@@ imul eax,64 ;times bitmap h
  496. ;;@@ mov 4[esi],eax
  497. ;;@@ add esi,12 ;point at next
  498. ;;@@ dec ecx
  499. ;;@@ jnz init_uv_loop
  500. ;;@@ jmp init_loop
  501. not_tmappoly:
  502. ;sort
  503. cmp ax,4 ;sortnorm
  504. jne not_sortnorm
  505. push esi
  506. xor eax,eax
  507. mov ax,28[esi] ;get front offset
  508. add esi,eax
  509. call init_loop
  510. mov esi,[esp]
  511. xor eax,eax
  512. mov ax,30[esi] ;get front offset
  513. add esi,eax
  514. call init_loop
  515. pop esi
  516. lea esi,32[esi]
  517. jmp init_loop
  518. not_sortnorm:
  519. cmp ax,5
  520. jne not_rodbm
  521. add esi,36
  522. jmp init_loop
  523. not_rodbm:
  524. cmp ax,6
  525. jne not_subcall
  526. push esi
  527. xor eax,eax
  528. mov ax,16[esi] ;get subobj offset
  529. add esi,eax
  530. call init_loop
  531. pop esi
  532. add esi,20
  533. jmp init_loop
  534. not_subcall:
  535. cmp ax,7 ;defpoints
  536. jne not_defpoints_st
  537. xor eax,eax
  538. mov ax,2[esi] ;get count
  539. sal eax,1
  540. add ax,2[esi] ;*3
  541. lea esi,8[esi+eax*4]
  542. jmp init_loop
  543. not_defpoints_st:
  544. cmp ax,8
  545. jne not_glow
  546. add esi,4
  547. jmp init_loop
  548. not_glow:
  549. debug_brk "Invalid opcode"
  550. jmp init_loop
  551. ;takes ecx=count, esi=ptr to point list
  552. draw_outline: pushm eax,ebx,ecx,edx,esi,edi
  553. ;NO_INVERSE_TABLE xor eax,eax
  554. ;NO_INVERSE_TABLE mov al,gr_inverse_table[7fffh] ;white
  555. mov eax, 255 ; bright white
  556. call gr_setcolor_
  557. mov ebx,esi
  558. xor eax,eax
  559. mov ax,[ebx] ;get first point
  560. push eax ;save it
  561. outline_loop: xor esi,esi
  562. xor edi,edi
  563. mov si,[ebx]
  564. dec ecx
  565. jz done_loop
  566. mov di,2[ebx]
  567. push ebx
  568. imul esi,size g3s_point
  569. add esi,Interp_point_list
  570. imul edi,size g3s_point
  571. add edi,Interp_point_list
  572. call g3_draw_line
  573. pop ebx
  574. add ebx,2
  575. jmp outline_loop
  576. done_loop: pop edi ;get first point back
  577. imul esi,size g3s_point
  578. add esi,Interp_point_list
  579. imul edi,size g3s_point
  580. add edi,Interp_point_list
  581. call g3_draw_line
  582. popm eax,ebx,ecx,edx,esi,edi
  583. ret
  584. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  585. ;Special code to draw morphing objects
  586. ;define a list of points
  587. morph_defpoints: xor ecx,ecx
  588. mov cx,2[ebp] ;num points
  589. mov edi,Interp_point_list
  590. lea esi,4[ebp]
  591. morph_rotate_list: lea eax,[ecx*2+ecx] ;eax=npoint * 3
  592. lea esi,[esi+eax*4] ;point past points
  593. push esi
  594. mov esi,morph_points ;get alternate points
  595. morph_rotate_loop: call g3_rotate_point
  596. add edi,size g3s_point
  597. add esi,size vms_vector
  598. dec ecx
  599. jnz morph_rotate_loop
  600. pop esi ;restore pointer
  601. mov ebp,esi
  602. next
  603. ;define a list of points, with starting point num specified
  604. morph_defp_start: xor ecx,ecx
  605. xor eax,eax
  606. mov ax,w 4[ebp] ;starting point num
  607. imulc eax,size g3s_point ;get ofs of point
  608. add eax,Interp_point_list
  609. mov edi,eax
  610. mov cx,2[ebp] ;num points
  611. lea esi,8[ebp]
  612. jmp morph_rotate_list
  613. ;draw a flat-shaded polygon
  614. morph_flatpoly: xor ecx,ecx
  615. mov cx,2[ebp] ;num verts
  616. lea esi,4[ebp] ;point
  617. lea edi,16[ebp] ;vector
  618. ;set color
  619. xor eax,eax
  620. mov ax,28[ebp] ;get color
  621. mov ax,interp_color_table[eax*4]
  622. call gr_setcolor_ ;set it
  623. ;check and draw
  624. lea esi,30[ebp] ;point number list
  625. xor eax,eax
  626. lodsw
  627. imulc eax,size g3s_point
  628. add eax,Interp_point_list
  629. mov morph_pointlist,eax
  630. xor eax,eax
  631. lodsw
  632. imulc eax,size g3s_point
  633. add eax,Interp_point_list
  634. mov morph_pointlist+4,eax
  635. xor eax,eax
  636. lodsw
  637. imulc eax,size g3s_point
  638. add eax,Interp_point_list
  639. mov morph_pointlist+8,eax
  640. cmp ecx,3 ;3 points is good!
  641. je flat_got3
  642. sub ecx,2 ;tri count
  643. flat_tri_loop: xor edi,edi ;no normal, must compute
  644. pushm ecx,esi
  645. mov ecx,3 ;always draw triangle
  646. lea esi,morph_pointlist
  647. call g3_check_and_draw_poly
  648. popm ecx,esi
  649. mov eax,morph_pointlist+8
  650. mov morph_pointlist+4,eax
  651. xor eax,eax
  652. lodsw
  653. imulc eax,size g3s_point
  654. add eax,Interp_point_list
  655. mov morph_pointlist+8,eax
  656. dec ecx
  657. jnz flat_tri_loop
  658. jmp flat_done_draw
  659. flat_got3:
  660. lea esi,morph_pointlist
  661. xor edi,edi ;no normal, must compute
  662. call g3_check_and_draw_poly
  663. flat_done_draw: xor ecx,ecx
  664. mov cx,2[ebp] ;restore count
  665. and ecx,0fffffffeh
  666. inc ecx ;adjust for pad
  667. lea ebp,30[ebp+ecx*2]
  668. next
  669. ;draw a texture map
  670. morph_tmappoly: xor ecx,ecx
  671. mov cx,2[ebp] ;num verts
  672. lea esi,4[ebp] ;point
  673. lea edi,16[ebp] ;normal
  674. ;get bitmap
  675. xor edx,edx
  676. mov dx,28[ebp] ;get bitmap number
  677. mov eax,bitmap_ptr
  678. mov edx,[eax+edx*4]
  679. lea esi,30[ebp] ;point number list
  680. mov eax,ecx
  681. and eax,0fffffffeh
  682. inc eax
  683. lea ebx,30[ebp+eax*2] ;get uvl list
  684. ;calculate light from surface normal
  685. push esi
  686. lea esi,View_matrix.fvec
  687. lea edi,16[ebp] ;normal
  688. call vm_vec_dotprod
  689. neg eax
  690. ;scale light by model light
  691. push edx
  692. mov edx,eax
  693. add eax,eax
  694. add eax,edx ;eax *= 3
  695. sar eax,2 ;eax *= 3/4
  696. add eax,f1_0/4 ;eax = 1/4 + eax * 3/4
  697. fixmul model_light
  698. or eax,eax
  699. jge not_zero
  700. xor eax,eax
  701. not_zero:
  702. pop edx
  703. pop esi
  704. ;now eax=plane light value
  705. mov morph_uvls+8,eax
  706. mov morph_uvls+20,eax
  707. mov morph_uvls+32,eax
  708. xor eax,eax
  709. lodsw
  710. imulc eax,size g3s_point
  711. add eax,Interp_point_list
  712. mov morph_pointlist,eax
  713. xor eax,eax
  714. lodsw
  715. imulc eax,size g3s_point
  716. add eax,Interp_point_list
  717. mov morph_pointlist+4,eax
  718. xor eax,eax
  719. lodsw
  720. imulc eax,size g3s_point
  721. add eax,Interp_point_list
  722. mov morph_pointlist+8,eax
  723. cmp ecx,3 ;3 points is good!
  724. jl tmap_done_draw ;something is bad, abort
  725. je tmap_got3
  726. sub ecx,2 ;tri count
  727. push edx
  728. mov edx,[ebx]
  729. mov morph_uvls,edx
  730. mov edx,4[ebx]
  731. mov morph_uvls+4,edx
  732. mov edx,12[ebx]
  733. mov morph_uvls+12,edx
  734. mov edx,16[ebx]
  735. mov morph_uvls+16,edx
  736. mov edx,24[ebx]
  737. mov morph_uvls+24,edx
  738. mov edx,28[ebx]
  739. mov morph_uvls+28,edx
  740. add ebx,3*12
  741. pop edx
  742. tmap_tri_loop: xor edi,edi ;no normal, must compute
  743. pushm ebx,edx,ecx,esi
  744. mov ecx,3 ;always draw triangle
  745. lea esi,morph_pointlist
  746. lea ebx,morph_uvls
  747. call g3_check_and_draw_tmap
  748. popm ebx,edx,ecx,esi
  749. mov eax,morph_pointlist+8
  750. mov morph_pointlist+4,eax
  751. xor eax,eax
  752. lodsw
  753. imulc eax,size g3s_point
  754. add eax,Interp_point_list
  755. mov morph_pointlist+8,eax
  756. push edx
  757. mov edx,morph_uvls+24
  758. mov morph_uvls+12,edx
  759. mov edx,morph_uvls+28
  760. mov morph_uvls+16,edx
  761. mov edx,[ebx]
  762. mov morph_uvls+24,edx
  763. mov edx,4[ebx]
  764. mov morph_uvls+28,edx
  765. add ebx,12
  766. pop edx
  767. dec ecx
  768. jnz tmap_tri_loop
  769. jmp tmap_done_draw
  770. tmap_got3:
  771. ;poke in light values
  772. pusha
  773. tmap_l_loop: mov 8[ebx],eax
  774. add ebx,12
  775. dec ecx
  776. jnz tmap_l_loop
  777. popa
  778. lea esi,morph_pointlist
  779. xor edi,edi ;no normal
  780. call g3_check_and_draw_tmap
  781. tmap_done_draw: xor ecx,ecx
  782. mov cx,2[ebp] ;restore count
  783. ;jump to next opcode
  784. mov ebx,ecx
  785. and ebx,0fffffffeh
  786. inc ebx ;adjust for pad
  787. lea ebp,30[ebp+ebx*2]
  788. mov eax,ecx
  789. sal ecx,1
  790. add ecx,eax
  791. sal ecx,2 ;ecx=ecx*12
  792. add ebp,ecx ;point past uvls
  793. next
  794. ;interpreter to draw polygon model
  795. ;takes esi=ptr to object, edi=ptr to array of bitmap pointers,
  796. ;eax=ptr to anim angles, ebx=alternate points, edx=light value
  797. g3_draw_morphing_model:
  798. pushm eax,ebx,ecx,edx,esi,edi,ebp
  799. mov bitmap_ptr,edi ;save ptr to bitmap array
  800. mov anim_angles,eax
  801. mov morph_points,ebx
  802. mov model_light,edx
  803. mov ebp,esi ;ebp = interp ptr
  804. ;set alternate opcode pointers
  805. push opcode_table[1*4] ;defpoints
  806. push opcode_table[2*4] ;flatpoly
  807. push opcode_table[3*4] ;tmappoly
  808. push opcode_table[7*4] ;defp_start
  809. mov opcode_table[1*4],offset morph_defpoints
  810. mov opcode_table[2*4],offset morph_flatpoly
  811. mov opcode_table[3*4],offset morph_tmappoly
  812. mov opcode_table[7*4],offset morph_defp_start
  813. call_next
  814. pop opcode_table[7*4] ;defp_start
  815. pop opcode_table[3*4] ;tmappoly
  816. pop opcode_table[2*4] ;flatpoly
  817. pop opcode_table[1*4] ;defpoints
  818. popm eax,ebx,ecx,edx,esi,edi,ebp
  819. ret
  820. _TEXT ends
  821. end