home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 3d / interp.asm < prev    next >
Assembly Source File  |  1998-06-08  |  21KB  |  999 lines

  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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/3d/rcs/interp.asm $
  13. ; $Revision: 1.21 $
  14. ; $Author: john $
  15. ; $Date: 1994/10/26 23:57:49 $
  16. ; Polygon object interpreter
  17. ; $Log: interp.asm $
  18. ; Revision 1.21  1994/10/26  23:57:49  john
  19. ; Took out gr_inverse_table
  20. ; Revision 1.20  1994/09/26  14:43:31  matt
  21. ; Put in checks for faces with fewer than 3 vertices
  22. ; Revision 1.19  1994/09/09  14:24:14  matt
  23. ; Added support for glowing textures, to add engine glow to Descent.
  24. ; Revision 1.18  1994/08/26  16:42:03  matt
  25. ; Added check for how many textures used in an object
  26. ; Revision 1.17  1994/07/29  18:29:17  matt
  27. ; Use instance-by-angles code, instead of building matrix here
  28. ; Revision 1.16  1994/07/25  10:58:28  matt
  29. ; Fixed morph effect for new 3d point handling
  30. ; Revision 1.15  1994/07/25  00:00:07  matt
  31. ; Made 3d no longer deal with point numbers, but only with pointers.
  32. ; Revision 1.14  1994/07/22  17:57:59  matt
  33. ; Changed the name of the rod functions, and took out some debugging code
  34. ; Revision 1.13  1994/06/07  16:49:36  matt
  35. ; Made interpreter take lighting value as parm, rather than in global var
  36. ; Revision 1.12  1994/05/31  22:11:52  matt
  37. ; Fixed morphing object lighting
  38. ; Revision 1.11  1994/05/31  18:35:52  matt
  39. ; Added lighting back to polygon objects
  40. ; Revision 1.10  1994/05/31  16:03:55  matt
  41. ; Made uvls right for triangulated faces in morphing objects
  42. ; Revision 1.9  1994/05/30  22:48:34  matt
  43. ; Added support for morph effect
  44. ; Revision 1.8  1994/05/19  23:12:04  matt
  45. ; Support new uvl value ranges
  46. ; Revision 1.7  1994/04/29  15:39:46  matt
  47. ; Use ebx in one place because the assembler seemed to be using it anyway
  48. ; even though I typed just bx.
  49. ; Revision 1.6  1994/04/19  17:02:32  matt
  50. ; Made g3d_interp_outline var accessible by C
  51. ; Revision 1.5  1994/03/30  10:22:40  matt
  52. ; Added outline option for polygon models
  53. ; Revision 1.4  1994/03/25  18:23:51  matt
  54. ; Fixed a couple of subobject problems, and made g3_draw_polygon_model
  55. ; take a pointer to a list of angvecs for subobj animation.
  56. ; Revision 1.3  1994/03/18  16:07:57  matt
  57. ; Added subobject and rod bitmap opcodes
  58. ; Revision 1.2  1994/03/15  21:23:04  matt
  59. ; Added code
  60. ; Revision 1.1  1994/03/14  21:26:56  matt
  61. ; Initial revision
  62.  
  63.  
  64.  
  65. .386
  66.     option    oldstructs
  67.  
  68.     .nolist
  69.     include    types.inc
  70.     include    psmacros.inc
  71.     include    gr.inc
  72.     include    3d.inc
  73.     .list
  74.  
  75.     assume    cs:_TEXT, ds:_DATA
  76.  
  77. _DATA    segment    dword public USE32 'DATA'
  78.  
  79. rcsid    db    "$Id: interp.asm 1.21 1994/10/26 23:57:49 john Exp $"
  80.     align    4
  81.  
  82. ;table with address for each opcode
  83. opcode_table    dd    op_eof    ;0 = eof
  84.     dd    op_defpoints    ;1 = defpoints
  85.     dd    op_flatpoly    ;2 = flat-shaded polygon
  86.     dd    op_tmappoly    ;3 = texture-mapped polygon
  87.     dd    op_sortnorm    ;4 = sort by normal
  88.     dd    op_rodbm    ;5 = rod bitmap
  89.     dd    op_subcall    ;6 = call a subobject
  90.     dd    op_defp_start    ;7 = defpoints with start
  91.     dd    op_glow    ;8 = glow value for next poly
  92. n_opcodes = ($-opcode_table)/4
  93.  
  94. bitmap_ptr    dd    ?
  95. anim_angles    dd    ?    ;pointer to angle data
  96.  
  97. morph_points    dd    ?    ;alternate points for morph
  98.  
  99. ;light value for the next tmap
  100. glow_num    dd    -1    ;-1 means off
  101. glow_values    dd    ?    ;ptr to array of values
  102.  
  103.     public    _highest_texture_num
  104. _highest_texture_num dw    0
  105.  
  106. zero_angles    fixang    0,0,0    ;vms_angvec <0,0,0>    ;for if no angles specified
  107.  
  108. rod_top_p    g3s_point <>
  109. rod_bot_p    g3s_point <>
  110.  
  111.     ifndef    NDEBUG
  112.     public    g3d_interp_outline,_g3d_interp_outline
  113. _g3d_interp_outline label    dword
  114. g3d_interp_outline    dd    0
  115.     endif
  116.  
  117. morph_pointlist    dd    ?,?,?
  118.  
  119. morph_uvls    fix    3 dup (?,?,?)
  120.  
  121. ;the light for the current model
  122. model_light    fix    ?
  123.  
  124. ;ptr to array of points
  125. Interp_point_list    dd    ?
  126.  
  127. MAX_POINTS_PER_POLY = 25
  128.  
  129. point_list    dd    MAX_POINTS_PER_POLY dup (?)
  130.  
  131. _DATA    ends
  132.  
  133.  
  134.  
  135. _TEXT    segment    dword public USE32 'CODE'
  136.  
  137. ;get and jump to next opcode
  138. next    macro
  139.     xor    ebx,ebx
  140.     mov    bx,[ebp]
  141.     ifndef    NDEBUG
  142.      cmp    ebx,n_opcodes
  143.      break_if    ge,'Invalid opcode'
  144.     endif
  145.     mov    ebx,opcode_table[ebx*4]
  146.     jmp    ebx
  147.     endm
  148.  
  149. ;get and call the next opcode
  150. call_next    macro    
  151.     xor    ebx,ebx
  152.     mov    bx,[ebp]
  153.     ifndef    NDEBUG
  154.      cmp    ebx,n_opcodes
  155.      break_if    ge,'Invalid opcode'
  156.     endif
  157.     mov    ebx,opcode_table[ebx*4]
  158.     call    ebx
  159.     endm
  160.  
  161. ;give the interpreter an array of points to use
  162. g3_set_interp_points:
  163.     mov    Interp_point_list,eax
  164.     ret
  165.  
  166. ;interpreter to draw polygon model
  167. ;takes esi=ptr to object, edi=ptr to array of bitmap pointers, 
  168. ;eax=ptr to anim angles, edx=light value, ebx=ptr to array of glow values
  169. g3_draw_polygon_model:
  170.     pushm    eax,ebx,ecx,edx,esi,edi,ebp
  171.  
  172.     mov    ebp,esi    ;ebp = interp ptr
  173.  
  174.     mov    bitmap_ptr,edi    ;save ptr to bitmap array
  175.     mov    anim_angles,eax
  176.     mov    model_light,edx
  177.     mov    glow_values,ebx
  178.  
  179.     mov    glow_num,-1
  180.  
  181. ;;@@ mov depth,0
  182.  
  183.     call_next
  184.  
  185.     popm    eax,ebx,ecx,edx,esi,edi,ebp
  186.     ret
  187.  
  188. ;handlers for opcodes
  189.  
  190. ;end of a model or sub-rountine
  191. op_eof:    ret
  192.  
  193. ;define a list of points
  194. op_defpoints:    xor    ecx,ecx
  195.     mov    cx,2[ebp]    ;num points
  196.     mov    edi,Interp_point_list
  197.     lea    esi,4[ebp]
  198. rotate_loop:    call    g3_rotate_point
  199.     add    edi,size g3s_point
  200.     add    esi,size vms_vector
  201.     dec    ecx
  202.     jnz    rotate_loop
  203.     mov    ebp,esi
  204.     next
  205.  
  206. ;define a list of points, with starting point num specified
  207. op_defp_start:    xor    ecx,ecx
  208.     xor    eax,eax
  209.     mov    ax,w 4[ebp]    ;starting point num
  210.     imulc    eax,size(g3s_point) ;get ofs of point
  211.     ;changed the above line from "size g3s_point" to "size(g3s_point)" to make the compiler happy -KRB
  212.     
  213.     add    eax,Interp_point_list
  214.     mov    edi,eax
  215.     mov    cx,2[ebp]    ;num points
  216.     lea    esi,8[ebp]
  217.     jmp    rotate_loop
  218.     next
  219.  
  220. ;draw a flat-shaded polygon
  221. op_flatpoly:    xor    ecx,ecx
  222.     mov    cx,2[ebp]    ;num verts
  223.     lea    esi,4[ebp]    ;point
  224.     lea    edi,16[ebp]    ;vector
  225.     call    g3_check_normal_facing
  226.     jng    flat_not_facing
  227.  
  228. ;polygon is facing, so draw it
  229.  
  230.     xor    eax,eax
  231.     mov    ax,28[ebp]            ;get color
  232.     call    gr_setcolor_            ;set it
  233.  
  234.     lea    esi,30[ebp]    ;point number list
  235.  
  236.     ;make list of point pointers
  237.  
  238.     ifndef    NDEBUG
  239.      cmp    ecx,MAX_POINTS_PER_POLY
  240.      break_if    ge,'Too many points in interp poly'
  241.     endif
  242.  
  243.     lea    edi,point_list
  244.     xor    ebx,ebx
  245. copy_loop:    xor    eax,eax
  246.     mov    ax,w [esi+ebx*2]    ;get point number
  247.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  248.     add    eax,Interp_point_list
  249.     mov    [edi+ebx*4],eax
  250.     inc    ebx
  251.     cmp    ebx,ecx
  252.     jne    copy_loop
  253.     mov    esi,edi
  254.  
  255.     call    g3_draw_poly
  256.     xor    ecx,ecx
  257.     mov    cx,2[ebp]    ;restore count
  258.  
  259.     ifndef    NDEBUG
  260.     test    g3d_interp_outline,-1
  261.     jz    no_outline
  262.     pushm    ecx,esi
  263.     lea    esi,30[ebp]
  264.     call    draw_outline
  265.     popm    ecx,esi
  266. no_outline:
  267.     endif    
  268.  
  269. ;polygon is not facing (or we've plotted it). jump to next opcode
  270. flat_not_facing:    and    ecx,0fffffffeh
  271.     inc    ecx    ;adjust for pad
  272.     lea    ebp,30[ebp+ecx*2]
  273.     next
  274.  
  275. ;set the glow value for the next tmap
  276. op_glow:    test    glow_values,-1
  277.     jz    skip_glow
  278.     xor    eax,eax
  279.     mov    ax,2[ebp]
  280.     mov    glow_num,eax
  281. skip_glow:    add    ebp,4
  282.     next
  283.  
  284.  
  285. ;draw a texture map
  286. op_tmappoly:    xor    ecx,ecx
  287.     mov    cx,2[ebp]    ;num verts
  288.     lea    esi,4[ebp]    ;point
  289.     lea    edi,16[ebp]    ;normal
  290.     call    g3_check_normal_facing
  291.     jng    tmap_not_facing
  292.  
  293. ;polygon is facing, so draw it
  294.  
  295.     xor    edx,edx
  296.     mov    dx,28[ebp]    ;get bitmap number
  297.     mov    eax,bitmap_ptr
  298.     mov    edx,[eax+edx*4]
  299.  
  300.     lea    esi,30[ebp]    ;point number list
  301.     mov    eax,ecx
  302.     and    eax,0fffffffeh
  303.     inc    eax
  304.     lea    ebx,30[ebp+eax*2]    ;get uvl list
  305.  
  306. ;calculate light from surface normal
  307.     push    esi
  308.  
  309.     test    glow_num,-1    ;glow override?
  310.     js    no_glow
  311. ;special glow lighting, which doesn't care about surface normal
  312.     mov    eax,glow_num
  313.     mov    esi,glow_values
  314.     mov    eax,[esi+eax*4]
  315.     mov    glow_num,-1
  316.     jmp    got_light_value
  317. no_glow:
  318.     lea    esi,View_matrix.fvec
  319.     lea    edi,16[ebp]    ;normal
  320.     call    vm_vec_dotprod
  321.     neg    eax
  322. ;scale light by model light
  323.     push    edx
  324.     mov    edx,eax
  325.     add    eax,eax
  326.     add    eax,edx    ;eax *= 3
  327.     sar    eax,2    ;eax *= 3/4
  328.     add    eax,f1_0/4    ;eax = 1/4 + eax * 3/4
  329.     fixmul    model_light
  330.     pop    edx
  331. ;now poke light into l values
  332. got_light_value:    pushm    ecx,ebx
  333. l_loop:    mov    8[ebx],eax
  334.     add    ebx,12
  335.     dec    ecx
  336.     jnz    l_loop
  337.     popm    ecx,ebx
  338.     pop    esi
  339.  
  340. ;now draw it
  341.     ;make list of point pointers
  342.  
  343.     ifndef    NDEBUG
  344.      cmp    ecx,MAX_POINTS_PER_POLY
  345.      break_if    ge,'Too many points in interp poly'
  346.     endif
  347.  
  348.     push    ebx
  349.     lea    edi,point_list
  350.     xor    ebx,ebx
  351. copy_loop2:    xor    eax,eax
  352.     mov    ax,w [esi+ebx*2]    ;get point number
  353.     imulc    eax,size(g3s_point);;Modified to add Parentheses -KRB
  354.     add    eax,Interp_point_list
  355.     mov    [edi+ebx*4],eax
  356.     inc    ebx
  357.     cmp    ebx,ecx
  358.     jne    copy_loop2
  359.     mov    esi,edi
  360.     pop    ebx
  361.  
  362.     call    g3_draw_tmap
  363.     xor    ecx,ecx
  364.     mov    cx,2[ebp]    ;restore count
  365.  
  366.     ifndef    NDEBUG
  367.     test    g3d_interp_outline,-1
  368.     jz    no_outline2
  369.     pushm    ecx,esi
  370.     lea    esi,30[ebp]
  371.     call    draw_outline
  372.     popm    ecx,esi
  373. no_outline2:
  374.     endif    
  375.  
  376. ;polygon is not facing (or we've plotted it). jump to next opcode
  377. tmap_not_facing:    mov    ebx,ecx
  378.     and    ebx,0fffffffeh
  379.     inc    ebx    ;adjust for pad
  380.     lea    ebp,30[ebp+ebx*2]
  381.  
  382.     mov    eax,ecx
  383.     sal    ecx,1
  384.     add    ecx,eax
  385.     sal    ecx,2    ;ecx=ecx*12
  386.     add    ebp,ecx    ;point past uvls
  387.  
  388.     next
  389.  
  390. ;sort based on surface normal
  391. op_sortnorm:    lea    esi,16[ebp]    ;point
  392.     lea    edi,4[ebp]    ;vector
  393.     call    g3_check_normal_facing
  394.     jng    sortnorm_not_facing
  395.  
  396. ;is facing.  draw back then front
  397.  
  398.     push    ebp
  399.     xor    eax,eax
  400.     mov    ax,30[ebp]    ;get back offset
  401.     add    ebp,eax
  402.     call_next
  403.     mov    ebp,[esp]    ;get ebp
  404.     xor    eax,eax
  405.     mov    ax,28[ebp]    ;get front offset
  406.     add    ebp,eax
  407.     call_next
  408.     pop    ebp
  409.  
  410.     lea    ebp,32[ebp]
  411.     next
  412.  
  413. ;is not facing.  draw front then back
  414.  
  415. sortnorm_not_facing:
  416.     push    ebp
  417.     xor    eax,eax
  418.     mov    ax,28[ebp]    ;get back offset
  419.     add    ebp,eax
  420.     call_next
  421.     mov    ebp,[esp]    ;get ebp
  422.     xor    eax,eax
  423.     mov    ax,30[ebp]    ;get front offset
  424.     add    ebp,eax
  425.     call_next
  426.     pop    ebp
  427.  
  428.     lea    ebp,32[ebp]
  429.     next
  430.  
  431. ;draw a rod bitmap 
  432. op_rodbm:    lea    esi,20[ebp]    ;bot point
  433.     lea    edi,rod_bot_p
  434.     call    g3_rotate_point
  435.  
  436.     lea    esi,4[ebp]    ;top point
  437.     lea    edi,rod_top_p
  438.     call    g3_rotate_point
  439.  
  440.     lea    esi,rod_bot_p    ;esi=bot, edi=top
  441.     mov    eax,16[ebp]    ;bot width
  442.     mov    edx,32[ebp]    ;top width
  443.  
  444.     xor    ebx,ebx
  445.     mov    bx,2[ebp]    ;get bitmap number
  446.     mov    ecx,bitmap_ptr
  447.     mov    ebx,[ecx+ebx*4]
  448.  
  449.     call    g3_draw_rod_tmap
  450.  
  451.     lea    ebp,36[ebp]
  452.     next
  453.  
  454.  
  455. ;draw a subobject
  456. op_subcall:    xor    eax,eax
  457.     mov    ax,2[ebp]    ;get object number
  458.  
  459. ;get ptr to angles
  460.     mov    edi,anim_angles
  461.     or    edi,edi
  462.     jnz    angles_not_null
  463. ;angles not specified.  Use zero angles
  464.     lea    edi,zero_angles
  465.     jmp    got_angles
  466. angles_not_null:
  467.     imulc    eax,size(vms_angvec);Modified to add Parentheses -KRB
  468.     add    edi,eax
  469. got_angles:
  470.     ;angles in edi
  471.  
  472.     lea    esi,4[ebp]    ;get position
  473.     call    g3_start_instance_angles
  474.  
  475.     push    ebp
  476.     xor    eax,eax
  477.     mov    ax,16[ebp]
  478.     add    ebp,eax    ;offset of subobject
  479.     call_next        ;draw the subobject
  480.     pop    ebp
  481.  
  482.     call    g3_done_instance
  483.  
  484.     lea    ebp,20[ebp]
  485.     next
  486.  
  487.  
  488. ;initialize a polygon object
  489. ;translate colors, scale UV values
  490. ;takes esi=ptr to model
  491. g3_init_polygon_model:
  492.     mov    _highest_texture_num,-1
  493.  
  494.     pushm    eax,ebx,ecx,edx,esi,edi
  495.     call    init_loop
  496.     popm    eax,ebx,ecx,edx,esi,edi
  497.     ret
  498.  
  499.  
  500. init_loop:    mov    ax,[esi]    ;get opcode
  501.     cmp    ax,0    ;eof
  502.     jne    not_eof
  503.     ret
  504. not_eof:
  505.  
  506. ;defpoints
  507.     cmp    ax,1    ;defpoints
  508.     jne    not_defpoints
  509.     xor    eax,eax
  510.     mov    ax,2[esi]    ;get count
  511.     sal    eax,1
  512.     add    ax,2[esi]    ;*3
  513.     lea    esi,4[esi+eax*4]
  514.     jmp    init_loop
  515. not_defpoints:
  516.  
  517. ;flat polygon
  518.     cmp    ax,2
  519.     jne    not_flatpoly
  520.     ifndef    NDEBUG
  521.     cmp     w 2[esi],3
  522.     break_if    l,'face must have 3 or more points'
  523.     endif
  524.     ;NO_INVERSE_TABLE xor    ebx,ebx
  525.     ;NO_INVERSE_TABLE mov    bx,28[esi]        ;get color
  526.     ;NO_INVERSE_TABLE xor    eax,eax
  527.     ;NO_INVERSE_TABLE mov    al,gr_inverse_table[ebx]    ;xlate it
  528.     ; The following 3 lines replace the above
  529.     xor    eax, eax
  530.     mov    ax,28[esi]        ;get color
  531.     call    gr_find_closest_color_15bpp_
  532.  
  533.     mov    28[esi],ax        ;store new color
  534.  
  535.     xor    ecx,ecx
  536.     mov    cx,2[esi]    ;get nverts
  537.     and    ecx,0fffffffeh
  538.     inc    ecx    ;adjust for pad
  539.     lea    esi,30[esi+ecx*2]
  540.     jmp    init_loop
  541. not_flatpoly:
  542.  
  543. ;tmap polygon
  544.     cmp    ax,3
  545.     jne    not_tmappoly
  546.     ifndef    NDEBUG
  547.     cmp     w 2[esi],3
  548.     break_if    l,'face must have 3 or more points'
  549.     endif
  550.     mov    ax,28[esi]    ;get bitmap number
  551.     cmp    ax,_highest_texture_num
  552.     jle    not_new
  553.     mov    _highest_texture_num,ax
  554. not_new:    xor    ecx,ecx
  555.     mov    cx,2[esi]    ;get nverts
  556.     mov    ebx,ecx
  557.     and    ebx,0fffffffeh
  558.     inc    ebx    ;adjust for pad
  559.     lea    esi,30[esi+ebx*2]    ;point at uvls
  560.  
  561.     imul    ecx,12    ;size of uvls
  562.     add    esi,ecx    ;skip them
  563.     jmp    init_loop
  564.  
  565. ;;@@init_uv_loop:    mov    eax,[esi]    ;get u
  566. ;;@@    imul    eax,64    ;times bitmap w
  567. ;;@@    mov    [esi],eax
  568. ;;@@    mov    eax,4[esi]    ;get v
  569. ;;@@    imul    eax,64    ;times bitmap h
  570. ;;@@    mov    4[esi],eax
  571. ;;@@    add    esi,12    ;point at next
  572. ;;@@    dec    ecx
  573. ;;@@    jnz    init_uv_loop
  574. ;;@@    jmp    init_loop
  575. not_tmappoly:
  576.  
  577. ;sort
  578.     cmp    ax,4    ;sortnorm
  579.     jne    not_sortnorm
  580.  
  581.     push    esi
  582.     xor    eax,eax
  583.     mov    ax,28[esi]    ;get front offset
  584.     add    esi,eax
  585.     call    init_loop
  586.     mov    esi,[esp]
  587.     xor    eax,eax
  588.     mov    ax,30[esi]    ;get front offset
  589.     add    esi,eax
  590.     call    init_loop
  591.     pop    esi
  592.     lea    esi,32[esi]
  593.  
  594.     jmp    init_loop
  595. not_sortnorm:
  596.     cmp    ax,5
  597.     jne    not_rodbm
  598.  
  599.     add    esi,36
  600.     jmp    init_loop
  601.  
  602. not_rodbm:
  603.     cmp    ax,6
  604.     jne    not_subcall
  605.  
  606.  
  607.     push    esi
  608.     xor    eax,eax
  609.     mov    ax,16[esi]    ;get subobj offset
  610.     add    esi,eax
  611.     call    init_loop
  612.     pop    esi
  613.  
  614.     add    esi,20
  615.     jmp    init_loop
  616. not_subcall:
  617.     cmp    ax,7    ;defpoints
  618.     jne    not_defpoints_st
  619.     xor    eax,eax
  620.     mov    ax,2[esi]    ;get count
  621.     sal    eax,1
  622.     add    ax,2[esi]    ;*3
  623.     lea    esi,8[esi+eax*4]
  624.     jmp    init_loop
  625. not_defpoints_st:
  626.     cmp    ax,8
  627.     jne    not_glow
  628.     add    esi,4
  629.     jmp    init_loop
  630. not_glow:
  631.  
  632.     debug_brk    "Invalid opcode"
  633.  
  634.     jmp    init_loop
  635.  
  636.  
  637. ;takes ecx=count, esi=ptr to point list
  638. draw_outline:    pushm    eax,ebx,ecx,edx,esi,edi
  639.  
  640.     ;NO_INVERSE_TABLE xor    eax,eax
  641.     ;NO_INVERSE_TABLE mov    al,gr_inverse_table[7fffh]    ;white 
  642.     mov    eax, 255    ; bright white
  643.     call    gr_setcolor_
  644.  
  645.     mov    ebx,esi
  646.  
  647.     xor    eax,eax
  648.     mov    ax,[ebx]    ;get first point
  649.     push    eax    ;save it
  650.  
  651. outline_loop:    xor    esi,esi
  652.     xor    edi,edi
  653.     mov    si,[ebx]
  654.     dec    ecx
  655.     jz    done_loop
  656.     mov    di,2[ebx]
  657.     push    ebx
  658.  
  659.     imul    esi,size g3s_point
  660.     add    esi,Interp_point_list
  661.     imul    edi,size g3s_point
  662.     add    edi,Interp_point_list
  663.  
  664.     call    g3_draw_line
  665.     pop    ebx
  666.  
  667.     add    ebx,2
  668.     jmp    outline_loop
  669.  
  670. done_loop:    pop    edi    ;get first point back
  671.  
  672.     imul    esi,size g3s_point
  673.     add    esi,Interp_point_list
  674.     imul    edi,size g3s_point
  675.     add    edi,Interp_point_list
  676.  
  677.     call    g3_draw_line
  678.  
  679.     popm    eax,ebx,ecx,edx,esi,edi
  680.     ret
  681.  
  682. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  683.  
  684. ;Special code to draw morphing objects
  685.  
  686. ;define a list of points
  687. morph_defpoints:    xor    ecx,ecx
  688.     mov    cx,2[ebp]    ;num points
  689.     mov    edi,Interp_point_list
  690.     lea    esi,4[ebp]
  691. morph_rotate_list:    lea    eax,[ecx*2+ecx]    ;eax=npoint * 3
  692.     lea    esi,[esi+eax*4]    ;point past points
  693.     push    esi
  694.     mov    esi,morph_points    ;get alternate points
  695. morph_rotate_loop:    call    g3_rotate_point
  696.     add    edi,size g3s_point
  697.     add    esi,size vms_vector
  698.     dec    ecx
  699.     jnz    morph_rotate_loop
  700.     pop    esi    ;restore pointer
  701.     mov    ebp,esi
  702.     next
  703.  
  704. ;define a list of points, with starting point num specified
  705. morph_defp_start:    xor    ecx,ecx
  706.     xor    eax,eax
  707.     mov    ax,w 4[ebp]    ;starting point num
  708.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB ;get ofs of point
  709.     add    eax,Interp_point_list
  710.     mov    edi,eax
  711.     mov    cx,2[ebp]    ;num points
  712.     lea    esi,8[ebp]
  713.     jmp    morph_rotate_list
  714.  
  715. ;draw a flat-shaded polygon
  716. morph_flatpoly:    xor    ecx,ecx
  717.     mov    cx,2[ebp]    ;num verts
  718.     lea    esi,4[ebp]    ;point
  719.     lea    edi,16[ebp]    ;vector
  720.  
  721. ;set color
  722.     xor    eax,eax
  723.     mov    ax,28[ebp]            ;get color
  724.     call    gr_setcolor_            ;set it
  725.  
  726. ;check and draw
  727.     lea    esi,30[ebp]    ;point number list
  728.  
  729.     xor    eax,eax
  730.     lodsw
  731.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  732.     add    eax,Interp_point_list
  733.     mov    morph_pointlist,eax
  734.     xor    eax,eax
  735.     lodsw
  736.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  737.     add    eax,Interp_point_list
  738.     mov    morph_pointlist+4,eax
  739.     xor    eax,eax
  740.     lodsw
  741.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  742.     add    eax,Interp_point_list
  743.     mov    morph_pointlist+8,eax
  744.  
  745.     cmp    ecx,3    ;3 points is good!
  746.     je    flat_got3
  747.     sub    ecx,2    ;tri count
  748.  
  749. flat_tri_loop:    xor    edi,edi    ;no normal, must compute
  750.     pushm    ecx,esi
  751.     mov    ecx,3    ;always draw triangle
  752.     lea    esi,morph_pointlist
  753.     call    g3_check_and_draw_poly
  754.     popm    ecx,esi
  755.  
  756.     mov    eax,morph_pointlist+8
  757.     mov    morph_pointlist+4,eax
  758.     xor    eax,eax
  759.     lodsw
  760.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  761.     add    eax,Interp_point_list
  762.     mov    morph_pointlist+8,eax
  763.  
  764.     dec    ecx
  765.     jnz    flat_tri_loop
  766.     jmp    flat_done_draw
  767.     
  768. flat_got3:
  769.     lea    esi,morph_pointlist
  770.     xor    edi,edi    ;no normal, must compute
  771.     call    g3_check_and_draw_poly
  772.  
  773. flat_done_draw:    xor    ecx,ecx
  774.     mov    cx,2[ebp]    ;restore count
  775.  
  776.     and    ecx,0fffffffeh
  777.     inc    ecx    ;adjust for pad
  778.     lea    ebp,30[ebp+ecx*2]
  779.     next
  780.  
  781. ;draw a texture map
  782. morph_tmappoly:    xor    ecx,ecx
  783.     mov    cx,2[ebp]    ;num verts
  784.     lea    esi,4[ebp]    ;point
  785.     lea    edi,16[ebp]    ;normal
  786.  
  787. ;get bitmap
  788.     xor    edx,edx
  789.     mov    dx,28[ebp]    ;get bitmap number
  790.     mov    eax,bitmap_ptr
  791.     mov    edx,[eax+edx*4]
  792.  
  793.     lea    esi,30[ebp]    ;point number list
  794.     mov    eax,ecx
  795.     and    eax,0fffffffeh
  796.     inc    eax
  797.     lea    ebx,30[ebp+eax*2]    ;get uvl list
  798. ;calculate light from surface normal
  799.     push    esi
  800.     lea    esi,View_matrix.fvec
  801.     lea    edi,16[ebp]    ;normal
  802.     call    vm_vec_dotprod
  803.     neg    eax
  804. ;scale light by model light
  805.     push    edx
  806.     mov    edx,eax
  807.     add    eax,eax
  808.     add    eax,edx    ;eax *= 3
  809.     sar    eax,2    ;eax *= 3/4
  810.     add    eax,f1_0/4    ;eax = 1/4 + eax * 3/4
  811.     fixmul    model_light
  812.  
  813.     or    eax,eax
  814.     jge    not_zero
  815.     xor    eax,eax
  816. not_zero:
  817.     pop    edx
  818.     pop    esi
  819.  
  820. ;now eax=plane light value
  821.  
  822.     mov    morph_uvls+8,eax
  823.     mov    morph_uvls+20,eax
  824.     mov    morph_uvls+32,eax
  825.  
  826.     xor    eax,eax
  827.     lodsw
  828.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  829.     add    eax,Interp_point_list
  830.     mov    morph_pointlist,eax
  831.     xor    eax,eax
  832.     lodsw
  833.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  834.     add    eax,Interp_point_list
  835.     mov    morph_pointlist+4,eax
  836.     xor    eax,eax
  837.     lodsw
  838.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  839.     add    eax,Interp_point_list
  840.     mov    morph_pointlist+8,eax
  841.  
  842.     cmp    ecx,3    ;3 points is good!
  843.     jl    tmap_done_draw    ;something is bad, abort
  844.     je    tmap_got3
  845.     sub    ecx,2    ;tri count
  846.  
  847.     push    edx
  848.  
  849.     mov    edx,[ebx]
  850.     mov    morph_uvls,edx
  851.     mov    edx,4[ebx]
  852.     mov    morph_uvls+4,edx
  853.  
  854.     mov    edx,12[ebx]
  855.     mov    morph_uvls+12,edx
  856.     mov    edx,16[ebx]
  857.     mov    morph_uvls+16,edx
  858.  
  859.     mov    edx,24[ebx]
  860.     mov    morph_uvls+24,edx
  861.     mov    edx,28[ebx]
  862.     mov    morph_uvls+28,edx
  863.  
  864.     add    ebx,3*12
  865.  
  866.     pop    edx
  867.  
  868.  
  869. tmap_tri_loop:    xor    edi,edi    ;no normal, must compute
  870.     pushm    ebx,edx,ecx,esi
  871.     mov    ecx,3    ;always draw triangle
  872.     lea    esi,morph_pointlist
  873.     lea    ebx,morph_uvls
  874.     call    g3_check_and_draw_tmap
  875.     popm    ebx,edx,ecx,esi
  876.  
  877.     mov    eax,morph_pointlist+8
  878.     mov    morph_pointlist+4,eax
  879.     xor    eax,eax
  880.     lodsw
  881.     imulc    eax,size(g3s_point);Modified to add Parentheses -KRB
  882.     add    eax,Interp_point_list
  883.     mov    morph_pointlist+8,eax
  884.  
  885.     push    edx
  886.     mov    edx,morph_uvls+24
  887.     mov    morph_uvls+12,edx
  888.     mov    edx,morph_uvls+28
  889.     mov    morph_uvls+16,edx
  890.  
  891.     mov    edx,[ebx]
  892.     mov    morph_uvls+24,edx
  893.     mov    edx,4[ebx]
  894.     mov    morph_uvls+28,edx
  895.     add    ebx,12
  896.     pop    edx
  897.  
  898.     dec    ecx
  899.     jnz    tmap_tri_loop
  900.     jmp    tmap_done_draw
  901.     
  902. tmap_got3:
  903. ;poke in light values
  904.     pusha
  905. tmap_l_loop:    mov    8[ebx],eax
  906.     add    ebx,12
  907.     dec    ecx
  908.     jnz    tmap_l_loop
  909.     popa
  910.  
  911.     lea    esi,morph_pointlist
  912.  
  913.     xor    edi,edi    ;no normal
  914.     call    g3_check_and_draw_tmap
  915.  
  916. tmap_done_draw:    xor    ecx,ecx
  917.     mov    cx,2[ebp]    ;restore count
  918.  
  919. ;jump to next opcode
  920.     mov    ebx,ecx
  921.     and    ebx,0fffffffeh
  922.     inc    ebx    ;adjust for pad
  923.     lea    ebp,30[ebp+ebx*2]
  924.  
  925.     mov    eax,ecx
  926.     sal    ecx,1
  927.     add    ecx,eax
  928.     sal    ecx,2    ;ecx=ecx*12
  929.     add    ebp,ecx    ;point past uvls
  930.  
  931.     next
  932.  
  933.  
  934. ;interpreter to draw polygon model
  935. ;takes esi=ptr to object, edi=ptr to array of bitmap pointers, 
  936. ;eax=ptr to anim angles, ebx=alternate points, edx=light value
  937.  
  938. g3_draw_morphing_model:
  939.     pushm    eax,ebx,ecx,edx,esi,edi,ebp
  940.  
  941.     mov    bitmap_ptr,edi    ;save ptr to bitmap array
  942.     mov    anim_angles,eax
  943.     mov    morph_points,ebx
  944.     mov    model_light,edx
  945.  
  946.     mov    ebp,esi    ;ebp = interp ptr
  947.  
  948.     ;set alternate opcode pointers
  949.  
  950.     push    opcode_table[1*4]    ;defpoints
  951.     push    opcode_table[2*4]    ;flatpoly
  952.     push    opcode_table[3*4]    ;tmappoly
  953.     push    opcode_table[7*4]    ;defp_start
  954.  
  955.     mov    opcode_table[1*4],offset morph_defpoints
  956.     mov    opcode_table[2*4],offset morph_flatpoly
  957.     mov    opcode_table[3*4],offset morph_tmappoly
  958.     mov    opcode_table[7*4],offset morph_defp_start
  959.  
  960.     call_next
  961.  
  962.     pop    opcode_table[7*4]    ;defp_start
  963.     pop    opcode_table[3*4]    ;tmappoly
  964.     pop    opcode_table[2*4]    ;flatpoly
  965.     pop    opcode_table[1*4]    ;defpoints
  966.  
  967.     popm    eax,ebx,ecx,edx,esi,edi,ebp
  968.     ret
  969.  
  970. _TEXT    ends
  971.  
  972.     end
  973.  
  974. 
  975.