home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / asm / retvec10 / retvect.asm next >
Encoding:
Assembly Source File  |  1993-08-20  |  34.8 KB  |  1,412 lines

  1. ; **************************************************************************
  2. ; 3D FixedPoint (8.8)  Retarded vectors - I got the idea from the PANIC demo
  3. ;                   Jon Beltran de Heredia, Aug'93
  4. ;   This will work under any PC with a VGA card. Learn all .386'ers!
  5. ; Version 1.0: Vectors fade out rotating palette, & there's objs morphing
  6. ;      Ah! And in the last moment, I made it 'explode' in the end
  7. ;      Originally inspired on code by Bios/<ode∩aτion 1993 Mar-93
  8. ; **************************************************************************
  9.  
  10.     .MODEL    SMALL
  11.     .STACK
  12. ; --------------------------------------------------------------------------
  13. ; Here we have global data
  14. ; --------------------------------------------------------------------------
  15.     .DATA
  16.  
  17. ; Limit for the number of vectors of the object
  18. MAX_LINES EQU 20d    ; Maximum number of lines that form one object
  19. MAX_POINTS EQU 20d    ; Maximum number of points that form one object
  20.  
  21. ; These values setup the projection environment
  22. HAng    DW 0        ; Spin of the object (rotation around its vert. axis)
  23. VAng    DW 0        ; The objects 'leans' down this angle
  24. deltaX    DW 0        ; \
  25. deltaY    DW 0        ; | The object translates after rotation
  26. deltaZ    DW 200d        ; /
  27. dPP    DW 200d        ; Distance from the viewpoint to the projection plane
  28.  
  29. ; ===========================================================================
  30. ; These variables describe the shape of the current object
  31. NPoints        DW 8    ; # of points that form the CURRENT object
  32. NLines        DW 12    ; # of lines that form the CURRENT object
  33. LPointsPtr    DW ?    ; OFFSET in DS of the local coors. of the points, in 3D
  34. ObjLines    DW 0,1    ; Pairs of vertex-indices that determine the edges
  35.         DW 1,2    ;  (or, in demo-slang, the 'vectors')
  36.         DW 2,3
  37.         DW 3,0
  38.         DW 4,5
  39.         DW 5,6
  40.         DW 6,7
  41.         DW 7,4
  42.         DW 0,4
  43.         DW 1,5
  44.         DW 2,6
  45.         DW 3,7
  46. ; ===========================================================================
  47. ; This table describes the set of objects
  48. NObjects    DW 6
  49. ObjDefs        DW OFFSET Obj0Pts, OFFSET Obj1Pts, OFFSET Obj2Pts
  50.         DW OFFSET Obj3Pts, OFFSET Obj4Pts, OFFSET Obj5Pts
  51. ; ---------------------------------------------------------------------------
  52. ; These values model the shape of the objects. The only difference betwen them
  53. ;  is the coors. of the vertices, being the lines all the same.
  54. ; ---------------------------------------------------------------------------
  55. Obj0Pts    DW 8 DUP (0,0,0)
  56.  
  57. Obj1Pts    DW  00,-50, 00
  58.     DW  00,-50, 00
  59.     DW  00,-50, 00
  60.     DW  00,-50, 00
  61.     DW  00, 50, 00
  62.     DW  00, 50, 00
  63.     DW  00, 50, 00
  64.     DW  00, 50, 00
  65.  
  66. Obj2Pts    DW -50,-50,-50
  67.     DW  50,-50,-50
  68.     DW  50,-50, 50
  69.     DW -50,-50, 50
  70.     DW  00, 50, 00
  71.     DW  00, 50, 00
  72.     DW  00, 50, 00
  73.     DW  00, 50, 00
  74.  
  75. Obj3Pts    DW -50,-50,-50
  76.     DW  50,-50,-50
  77.     DW  50,-50, 50
  78.     DW -50,-50, 50
  79.     DW -50, 50,-50
  80.     DW  50, 50,-50
  81.     DW  50, 50, 50
  82.     DW -50, 50, 50
  83.  
  84. Obj4Pts    DW  50,-50,-50
  85.     DW  50,-50, 50
  86.     DW -50,-50, 50
  87.     DW -50,-50,-50
  88.     DW -50, 50,-50
  89.     DW  50, 50,-50
  90.     DW  50, 50, 50
  91.     DW -50, 50, 50
  92.  
  93. Obj5Pts    DW -50,-50,-50
  94.     DW  50,-50,-50
  95.     DW  50,-50, 50
  96.     DW -50,-50, 50
  97.     DW -50, 50,-50
  98.     DW  50, 50,-50
  99.     DW  50, 50, 50
  100.     DW -50, 50, 50
  101.  
  102. ; ---------------------------------------------------------------------------
  103.  
  104. ; These coordinates are calculated by ProjectPoints, via F3Dto2D:
  105. ; ---
  106. ;  Points that compose the current object, as from the observer coordinate
  107. ;  system. We store the projected X and Y coordinates only.
  108.    ScrPoints    DW MAX_POINTS DUP (0,0)
  109. ; ---
  110.  
  111. ; Nice ( :-? ) goodbye message (well, not so nice as those from Iguana)
  112. ByeText LABEL BYTE
  113.  DB '3D FixedPoint Retarded-Vectors...', 0Dh, 0Ah
  114.  DB 'Coded by Jon Beltran de Heredia - Aug93', 0Dh, 0Ah
  115.  DB 'Got the idea from the PANIC demo', 0Dh, 0Ah
  116.  DB 'We gonna beat the Finnish & the Swedish out of the PC scene!! ;-)',0Dh,0Ah
  117.  DB 'Original inspiration from code by Bios/<ode∩aτion',0Dh,0Ah
  118.  DB 'Credits go to:', 0Dh, 0Ah
  119.  DB '  * Jare/Iguana for the line drawing code', 0Dh, 0Ah
  120.  DB '  * Draeden/VLA for the starfield idea', 0Dh, 0Ah
  121.  DB '  * Bios/<ode∩aτion for the original 3D engine design', 0Dh, 0Ah
  122.  DB 'Greetings to all you guys in the Spanish PC Scene!', 0Dh, 0Ah
  123.  DB 'Very Special Greetings go to:', 0Dh, 0Ah
  124.  DB '  * Jare/Iguana (I really liked your Inconexia!)', 0Dh, 0Ah
  125.  DB '  * Bios/<ode∩aτion (we are dying to see your demo)',0Dh,0Ah
  126.  DB '  * Aitor Garay (what are you waiting for to start coding demos?)', 0Dh, 0Ah
  127.  DB '  * & to everyone in Fido conferences PROASM_E and R34.DEMOS... keep on it!!!'
  128.  DB '$'
  129.  
  130. ;SinTable created by Jon Beltran de Heredia
  131. ;Sines are in 8.8 fixedpoint, from 0 degree to 360+90 degree (in order to
  132. ; calculate the cosines with the same table)
  133. SinTbl    LABEL    WORD
  134. dw 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
  135. dw 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
  136. dw 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
  137. dw 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
  138. dw 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
  139. dw 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256
  140. dw 256,256,256,256,255,255,255,254,254,253,252,251,250,249,248
  141. dw 247,246,245,243,242,241,239,237,236,234,232,230,228,226,224
  142. dw 222,219,217,215,212,210,207,204,202,199,196,193,190,187,184
  143. dw 181,178,175,171,168,165,161,158,154,150,147,143,139,136,132
  144. dw 128,124,120,116,112,108,104,100,96,92,88,83,79,75,71
  145. dw 66,62,58,53,49,44,40,36,31,27,22,18,13,9,4
  146. dw 0,-4,-9,-13,-18,-22,-27,-31,-36,-40,-44,-49,-53,-58,-62
  147. dw -66,-71,-75,-79,-83,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
  148. dw -128,-132,-136,-139,-143,-147,-150,-154,-158,-161,-165,-168,-171,-175,-178
  149. dw -181,-184,-187,-190,-193,-196,-199,-202,-204,-207,-210,-212,-215,-217,-219
  150. dw -222,-224,-226,-228,-230,-232,-234,-236,-237,-239,-241,-242,-243,-245,-246
  151. dw -247,-248,-249,-250,-251,-252,-253,-254,-254,-255,-255,-255,-256,-256,-256
  152. dw -256,-256,-256,-256,-255,-255,-255,-254,-254,-253,-252,-251,-250,-249,-248
  153. dw -247,-246,-245,-243,-242,-241,-239,-237,-236,-234,-232,-230,-228,-226,-224
  154. dw -222,-219,-217,-215,-212,-210,-207,-204,-202,-199,-196,-193,-190,-187,-184
  155. dw -181,-178,-175,-171,-168,-165,-161,-158,-154,-150,-147,-143,-139,-136,-132
  156. dw -128,-124,-120,-116,-112,-108,-104,-100,-96,-92,-88,-83,-79,-75,-71
  157. dw -66,-62,-58,-53,-49,-44,-40,-36,-31,-27,-22,-18,-13,-9,-4
  158. dw 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
  159. dw 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
  160. dw 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
  161. dw 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
  162. dw 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
  163. dw 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256,256
  164.  
  165. ; --------------------------------------------------------------------------
  166. ; Macros to profile the minidemo
  167. ; --------------------------------------------------------------------------
  168. SetBorder2    MACRO Color
  169.         push    ax
  170.         push    dx
  171.         cli            ; So that the flip-flop isn't
  172.                     ; uninit-ed by some IRQ...
  173.         mov    dx,3DAh
  174.         in    al,dx        ; Init the flip-flop for the
  175.                     ; attribute controller
  176.         mov    dx,3C0h        ; Attribute controller port
  177.         mov    al,31h        ; Overscan reg, don't switch ray off
  178.         out    dx,al        ; Write Register #
  179.         mov    al,Color
  180.         out    dx,al        ; Write Border Color
  181.         sti
  182.         pop    dx
  183.         pop    ax
  184.         ENDM
  185.     
  186. SetBorder    MACRO Color        ; To profile
  187.         ;SetBorder2 Color
  188.         ENDM
  189.  
  190. ; **************************************************************************
  191. ; Beginning of the code for the minidemo, functions...
  192. ; **************************************************************************
  193. ; --------------------------------------------------------------------------
  194. ; Function to calculate the values for the rotation 3*3 matrix from the
  195. ; current values of HAng and VAng. Uses sine table.
  196. ; --------------------------------------------------------------------------
  197. .DATA
  198. ; Sine and cosine of HAng and VAng, and their products
  199. _sh    DW ?
  200. _sv    DW ?
  201. _ch    DW ?
  202. _cv    DW ?
  203. _shsv    DW ?
  204. _chcv    DW ?
  205. _shcv    DW ?
  206. _chsv    DW ?
  207.  
  208. .CODE
  209. Calc    PROC
  210.     mov    bx,HAng
  211.     shl    bx,1
  212.     mov    ax,SinTbl[bx]
  213.     mov    _sh,ax
  214.     mov    ax,SinTbl[bx+180]    ; cos(alfa) = sin(alfa+90)
  215.     mov    _ch,ax
  216.     mov    bx,VAng
  217.     shl    bx,1
  218.     mov    ax,SinTbl[bx]
  219.     mov    _sv,ax
  220.     mov    ax,SinTbl[bx+180]
  221.     mov    _cv,ax
  222.     imul    _ch    
  223.     mov    byte ptr _chcv,ah
  224.     mov    byte ptr _chcv+1,dl
  225.     mov    ax,_sh
  226.     imul    _sv
  227.     mov    byte ptr _shsv,ah
  228.     mov    byte ptr _shsv+1,dl
  229.     mov    ax,_sh
  230.     imul    _cv
  231.     mov    byte ptr _shcv,ah
  232.     mov    byte ptr _shcv+1,dl
  233.     mov    ax,_sv
  234.     imul    _ch
  235.     mov    byte ptr _chsv,ah
  236.     mov    byte ptr _chsv+1,dl
  237.     ret
  238. Calc    ENDP
  239.  
  240. ; --------------------------------------------------------------------------
  241. ; Function to project a triad of words, representing the local coordinates
  242. ; of a vertex of the object, to obtain the 2D screen coords, using the
  243. ; values for the rotation matrix calculated by the 'Calc' function.
  244. ; --------------------------------------------------------------------------
  245. ; Transformation used:
  246. ;
  247. ;        [ x']   ( ch   -sh*sv -sh*cv )   [ x ]
  248. ;        [ y'] = ( 0      cv     -sv  ) * [ y ]
  249. ;        [ z']   ( sh    ch*sv  ch*cv )   [ z ]
  250. ;
  251. ; Where 'ch','sh', 'cv' and 'sv' stand for the sines and cosines of HAng & VAng
  252. ; --------------------------------------------------------------------------
  253. .CODE
  254. F3Dto2D    PROC    ; takes word ptr [si],[si+2] and [si+4] as 3D coords, projects
  255.         ; 'em and stores 2D projected coords in word ptr [di],[di+2]
  256.     lodsw
  257.     imul    _ch
  258.     mov    bx,ax
  259.     lodsw
  260.     neg    ax
  261.     imul    _shsv
  262.     add    bx,ax
  263.     lodsw
  264.     neg    ax
  265.     imul    _shcv
  266.     add    bx,ax
  267.     mov    cl,8
  268.     sar    bx,cl    ; must be 'sar' and not 'shr', 'cos it might be neg...
  269.     sub    si,4    ; starting with the 'y' coordinate
  270.     lodsw
  271.     imul    _cv
  272.     mov    bp,ax
  273.     lodsw
  274.     neg    ax
  275.     imul    _sv
  276.     add    bp,ax
  277.     mov    cl,8
  278.     sar    bp,cl
  279.     sub    si,6
  280.     lodsw
  281.     imul    _sh
  282.     mov    cx,ax
  283.     lodsw
  284.     imul    _chsv
  285.     add    cx,ax
  286.     lodsw
  287.     imul    _chcv
  288.     add    cx,ax
  289.     mov    cl,8
  290.     sar    cx,cl
  291.     add    cx,deltaZ
  292.     mov    ax,bx
  293.     add    ax,deltaX
  294.     imul    dPP
  295.     idiv    cx
  296.     add    ax,160d        ; center in screen
  297.     stosw
  298.  
  299.     mov    ax,bp
  300.     add    ax,deltaY
  301.     imul    dPP    
  302.     idiv    cx
  303.     neg    ax
  304.     add    ax,100d        ; center in screen
  305.     stosw
  306.     ret
  307. F3Dto2D    ENDP
  308.  
  309. ; --------------------------------------------------------------------------
  310. ; Function to project the vertices of the object, using the current values
  311. ; of HAng and VAng, and store them in OPoints
  312. ; --------------------------------------------------------------------------
  313. ProjectPoints PROC
  314.     call    Calc            ; Calculate the sines and cosines
  315.     mov    si,LPointsPtr
  316.     mov    di,OFFSET ScrPoints
  317.     mov    cx,NPoints
  318. L0:    push    cx
  319.     call    F3Dto2D
  320.     pop    cx
  321.     loop    L0            ; Loop to project all points
  322.     ret
  323. ProjectPoints ENDP
  324.  
  325. ; --------------------------------------------------------------------------
  326. ; Function to draw the lines specified in OPoints.
  327. ; Buffers the vectors, for later fadin'-out
  328. ; --------------------------------------------------------------------------
  329. .DATA
  330. ; Number of retarded vectors
  331. N_RETARD EQU 7        ; Number of vectors drawn in different shades of red
  332. ; Buffers to store the retarded vectors for later erasing after fade-out
  333. ;  First, BYTE stores the color in which it was drawn
  334. OldLines0 DB 0
  335.       DW MAX_LINES DUP (0,0,0,0)
  336. OldLines1 DB 0
  337.       DW MAX_LINES DUP (0,0,0,0)
  338. OldLines2 DB 0
  339.       DW MAX_LINES DUP (0,0,0,0)
  340. OldLines3 DB 0
  341.       DW MAX_LINES DUP (0,0,0,0)
  342. OldLines4 DB 0
  343.       DW MAX_LINES DUP (0,0,0,0)
  344. OldLines5 DB 0
  345.       DW MAX_LINES DUP (0,0,0,0)
  346. OldLines6 DB 0
  347.       DW MAX_LINES DUP (0,0,0,0)
  348. OldLinesBuffers    DW OFFSET OldLines0, OFFSET OldLines1
  349.         DW OFFSET OldLines2, OFFSET OldLines3
  350.         DW OFFSET OldLines4, OFFSET OldLines5
  351.         DW OFFSET OldLines6
  352.  
  353. MaxRed        DB ?    ; Maximum intensity red
  354. NextFreeBuffer    DW 0    ; In the beginning, there're no occupied buffers
  355. FlagEraseLines    DW 0    ; Don't erase lines - will get nonzero when all bufs
  356.             ;  are filled
  357.  
  358. .CODE
  359. DrawLines PROC
  360.     mov    di,NextFreeBuffer
  361.     shl    di,1
  362.     mov    di,OldLinesBuffers[di]    ; Pointer to buffer for the new vectors
  363.     mov    al,[MaxRed]
  364.     stosb                ; Store the color in which we'll draw
  365.     mov    cx,NLines        ; Number of vectors to store and draw
  366.     mov    si,OFFSET ObjLines    ; Pointer to vector array
  367. DL2:    push    cx
  368.     lodsw                ; Number of first vertex of line...
  369.     shl    ax,1
  370.     shl    ax,1
  371.     mov    bx,ax
  372.     mov    ax,ScrPoints[bx]    ; Load its X coordinate
  373.     stosw                ; Store in the buffer
  374.     mov    x1,ax            ; Store for the line-drawing function
  375.     mov    ax,ScrPoints[bx+2]    ; Load its Y coordinate
  376.     stosw                ; Store in the buffer
  377.     mov    y1,ax            ; Store for the line-drawing function
  378.     lodsw                ; Num of second vertex of this line...
  379.     shl    ax,1
  380.     shl    ax,1    
  381.     mov    bx,ax
  382.     mov    ax,ScrPoints[bx]    ; Load its X coordinate
  383.     stosw                ; Store in the buffer
  384.     mov    x2,ax            ; Store for the line-drawing function
  385.     mov    ax,ScrPoints[bx+2]    ; Load its Y coordinate
  386.     stosw                ; Store in the buffer
  387.     mov    y2,ax            ; Store for the line-drawing function
  388.     mov    ah,[MaxRed]        ; Maximum intensity red
  389.     push    bx            ; Preserve pointer to line array
  390.     call    Line            ; Draw the vector
  391.     pop    bx            ; Restore ptr to line array
  392.     pop    cx            ; Restore vector counter
  393.     loop    DL2
  394.     mov    ax,[NextFreeBuffer]    ; Calc. index (0-6) of next free buf
  395.     inc    ax
  396.     sub    ax,7
  397.     jnz    DL3
  398.     mov    [FlagEraseLines],1    ; From now on, there're lines to erase
  399.     mov    [NextFreeBuffer],ax
  400.     ret
  401.    DL3:    add    ax,7
  402.     mov    [NextFreeBuffer],ax
  403.     ret
  404. DrawLines ENDP
  405.  
  406. EraseLines PROC
  407.     mov    ax,[FlagEraseLines]
  408.     or    ax,ax
  409.     jz    ELSExit
  410.     mov    si,[NextFreeBuffer]    ; NextFreeBuffer is the buf with the
  411.                     ;  oldest vectors
  412.     shl    si,1
  413.     mov    si,OldLinesBuffers[si]    ; Address of the buffer
  414.     lodsb                ; Get the color of the vectors to erase
  415.     mov    bl,al            ; Keep it in bl
  416.     mov    cx,NLines        ; Use NLines as a counter
  417. L2:    push    cx
  418.     lodsw                ; Get X1 coordinate...
  419.     mov    x1,ax
  420.     lodsw                ; Get Y1 coordinate...
  421.     mov    y1,ax    
  422.     lodsw                ; Get X2 coordinate...
  423.     mov    x2,ax
  424.     lodsw                ; Get Y2 coordinate...
  425.     mov    y2,ax    
  426.     mov    ah,bl            ; Get red shade to erase
  427.     mov    al,0            ; Erase with black
  428.     push    bx            ; Preserve vectors color
  429.     call    ELine            ; Erase the vector
  430.     pop    bx
  431.     pop    cx            ; Restore vector counter
  432.     loop    L2
  433. ELSExit:
  434.     ret
  435. EraseLines ENDP    
  436.  
  437. ; --------------------------------------------------------------------------
  438. ; Line drawing based upon code by Javier Arevalo (Jare/Iguana)
  439. ; --------------------------------------------------------------------------
  440. ; Input: AH is the color, coors are in the following vars
  441. .DATA
  442. MulBy320 LABEL WORD
  443. I = 0
  444. REPT 200d
  445.  DW I*320d
  446.  I = I + 1
  447. ENDM
  448. x1    DW ?
  449. x2    DW ?
  450. y1    DW ?
  451. y2    DW ?
  452. LVar1   DW 0        ; Increment for DI when there is overflow
  453. LVar2   DW 0        ; Inc. for DI when there isn't overflow
  454. AdjDown    DW ?        ; Lookup Bresenham's algorithm
  455.     DW 0        ; There isn't AdjDown w/o overflow
  456.  
  457. VGASeg    DW 0A000h
  458. .CODE
  459. Line    PROC
  460.         mov    BYTE PTR cs:[ColorByte],ah
  461.         push    es
  462.     push    bp
  463.         push    cx
  464.         push    si
  465.     push    di
  466.         mov     ax,[y1]
  467.         mov     bx,[y2]
  468.         mov     cx,[x1]
  469.         mov     si,[x2]
  470.         cmp     ax,bx
  471.         jc      SHORT LL1
  472.         xchg   cx,si
  473.         xchg   ax,bx
  474.   LL1:
  475.     ; (cx,ax) = upper point
  476.     ; (si,bx) = the other one
  477.     sub     bx,ax            ; deltaY
  478.     mov     di,ax
  479.     add    di,di
  480.     mov     di,MulBy320[di]
  481.     add     di,cx
  482.     sub     si,cx
  483.     mov     ax,1
  484.     jnc    SHORT LL2
  485.     neg    ax
  486.     neg    si
  487.   LL2:    cmp    si,bx            ; cmp deltaX,deltaY
  488.     jnc    short LL3
  489.     ; so deltaX < deltaY
  490.     mov    dx,si
  491.     mov    si,ax            ; Minor inc.
  492.     mov    ax,320            ; Major inc.
  493.     jmp    SHORT LL4
  494.   LL3:    ; so deltaX > deltaY
  495.     mov    dx,bx
  496.     mov    bx,si
  497.     mov    si,320            ; Minor inc.
  498.   LL4:     mov    cx,bx
  499.         or    cx,cx
  500.     jnz    SHORT LL5
  501.     jmp    LExit
  502.   LL5:    ; Now: AX == Major displacement (every pixel does this).
  503.     ;      SI == Minor (only done when decimal part overflows).
  504.     add    si,ax
  505.     mov    [LVar1],si
  506.     mov    si,OFFSET LVar2
  507.         mov     [si],ax
  508.     ; Now:  ax == nothing
  509.     ;       bx == major axis width
  510.     ;       cx == major axis width
  511.     ;       dx == minor axis width
  512.     ;       si == OFFSET LVar2
  513.     ;    di == ScreenPtr
  514.     ;       bp == nothing
  515.     mov    bp,bx
  516.     neg    bp            ; bp == -major axis width (to round)
  517.     mov    ax,bp            ; ax == -major a.w.
  518.     add    ax,ax            ; ax *= 2
  519.     mov    AdjDown,ax
  520.     add    dx,dx            ; dx == 2*minor a. w. (AdjUp)
  521.     mov     es,[VGASeg]
  522.     inc    cx            ; To draw all the pixels
  523.     mov     bx,cx
  524.         mov    ax,cx
  525.     add    ax,0Fh
  526.     mov    cl,4
  527.     shr    ax,cl
  528.     mov    cx,ax            ; cx = # of complete 16 pel groups + 1
  529.     and    bx,00001111b        ; cx = # of ungrouped pixels
  530.     shl    bx,1
  531.     mov    al,0FFh
  532.     ColorByte = $-1
  533.     jmp    WORD PTR LineJmpTbl[bx]
  534.  
  535. LineDumpPixel MACRO p
  536. LineLoop&p:
  537.     mov    BYTE PTR es:[di],al
  538.     add    bp,dx
  539.     sbb    bx,bx
  540.     add    bx,bx
  541.     add    di,[si+bx]
  542.     add    bp,[si + bx + OFFSET AdjDown + 2 - OFFSET LVar2]
  543.     ENDM
  544.  
  545. LineLoop:
  546.     I = 0
  547.     REPT 16
  548.     LineDumpPixel %I
  549.     I = I + 1
  550.     ENDM
  551.     dec    cx
  552.     jz    SHORT LExit
  553.     jmp    LineLoop
  554.  LExit:    pop    di
  555.     pop    si
  556.     pop    cx
  557.     pop    bp
  558.     pop    es
  559.     ret
  560. Line    ENDP
  561.  
  562. .DATA
  563. LineJmpTbl LABEL WORD
  564. LineDumpLabel MACRO p
  565.     DW LineLoop&p
  566. ENDM
  567.     DW LineLoop0
  568.     I = 15
  569.     REPT 15
  570.     LineDumpLabel %I
  571.     I = I - 1
  572.     ENDM
  573.  
  574.  
  575. ; --------------------------------------------------------------------------
  576. ; Line erasing based upon code by Javier Arevalo (Jare/Iguana)
  577. ; --------------------------------------------------------------------------
  578. ; Input: AH is the color to erase, coors are in the x1,x2,y1,y2 vars
  579. ;        AL is the color with which to erase
  580. ; All data is stored in the variables of the previous routine
  581. .CODE
  582. ELine    PROC
  583.         mov    BYTE PTR cs:[CompColorByte],ah
  584.     mov    BYTE PTR cs:[EraseColorByte],al
  585.         push    es
  586.     push    bp
  587.         push    cx
  588.         push    si
  589.     push    di
  590.         mov     ax,[y1]
  591.         mov     bx,[y2]
  592.         mov     cx,[x1]
  593.         mov     si,[x2]
  594.         cmp     ax,bx
  595.         jc      SHORT EL1
  596.         xchg   cx,si
  597.         xchg   ax,bx
  598.   EL1:
  599.     ; (cx,ax) = upper point
  600.     ; (si,bx) = the other one
  601.     sub     bx,ax            ; deltaY
  602.     mov     di,ax
  603.     add    di,di
  604.     mov     di,MulBy320[di]
  605.     add     di,cx
  606.     sub     si,cx
  607.     mov     ax,1
  608.     jnc    SHORT EL2
  609.     neg    ax
  610.     neg    si
  611.   EL2:    cmp    si,bx            ; cmp deltaX,deltaY
  612.     jnc    short EL3
  613.     ; so deltaX < deltaY
  614.     mov    dx,si
  615.     mov    si,ax            ; Minor inc.
  616.     mov    ax,320            ; Major inc.
  617.     jmp    SHORT EL4
  618.   EL3:    ; so deltaX > deltaY
  619.     mov    dx,bx
  620.     mov    bx,si
  621.     mov    si,320            ; Minor inc.
  622.   EL4:    mov    cx,bx
  623.         or    cx,cx
  624.     jnz    SHORT EL5
  625.     jmp    LExit
  626.   EL5:    ; Now: AX == Major displacement (every pixel does this).
  627.     ;      SI == Minor (only done when decimal part overflows).
  628.     add    si,ax
  629.     mov    [LVar1],si
  630.     mov    si,OFFSET LVar2
  631.         mov     [si],ax
  632.     ; Now:  ax == nothing
  633.     ;       bx == major axis width
  634.     ;       cx == major axis width
  635.     ;       dx == minor axis width
  636.     ;       si == OFFSET LVar2
  637.     ;    di == ScreenPtr
  638.     ;       bp == nothing
  639.     mov    bp,bx
  640.     neg    bp            ; bp == -major axis width (to round)
  641.     mov    ax,bp            ; ax == -major a.w.
  642.     add    ax,ax            ; ax *= 2
  643.     mov    AdjDown,ax
  644.     add    dx,dx            ; dx == 2*minor a. w. (AdjUp)
  645.     mov     es,[VGASeg]
  646.     inc    cx
  647.     mov     bx,cx
  648.         mov    ax,cx
  649.     add    ax,0Fh
  650.     mov    cl,4
  651.     shr    ax,cl
  652.     mov    cx,ax            ; cx = # of complete 16 pel groups + 1
  653.     and    bx,00001111b        ; cx = # of ungrouped pixels
  654.     shl    bx,1
  655.     mov    ah,0FFh
  656.     CompColorByte = $-1
  657.     mov    al,0
  658.     EraseColorByte = $ - 1
  659.     jmp    WORD PTR ELineJmpTbl[bx]
  660.  
  661. ELineDumpPixel MACRO p
  662. LOCAL @@1
  663. ELineLoop&p:
  664.     cmp    BYTE PTR es:[di],ah
  665.     jne    @@1
  666.     mov    BYTE PTR es:[di],al
  667.    @@1:    add    bp,dx
  668.     sbb    bx,bx
  669.     add    bx,bx
  670.     add    di,[si+bx]
  671.     add    bp,[si + bx + OFFSET AdjDown + 2 - OFFSET LVar2]
  672.     ENDM
  673.  
  674. ELineLoop:
  675.     I = 0
  676.     REPT 16
  677.     ELineDumpPixel %I
  678.     I = I + 1
  679.     ENDM
  680.     dec    cx
  681.     jz    SHORT ELExit
  682.     jmp    ELineLoop
  683. ELExit:    pop    di
  684.     pop    si
  685.     pop    cx
  686.     pop    bp
  687.     pop    es
  688.     ret
  689. ELine    ENDP
  690.  
  691. .DATA
  692. ELineJmpTbl    LABEL WORD
  693. ELineDumpLabel    MACRO p
  694.         DW ELineLoop&p
  695. ENDM
  696.     DW ELineLoop0
  697.     I = 15
  698.     REPT 15
  699.     ELineDumpLabel %I
  700.     I = I - 1
  701.     ENDM
  702.  
  703. ; ---------------------------------------------------------------------------
  704. ; Function to set the DAC palette RGB values, to put the hi-est red in MaxRed
  705. ; ---------------------------------------------------------------------------
  706. .DATA
  707. Palette    LABEL BYTE
  708.     I = 0
  709.     REPT N_RETARD        ;  Shades of red, from 1 to N_RETARD
  710.      I = I + (63/(N_RETARD-1) - 1)
  711.      DB I,0,0
  712.     ENDM
  713.     I = 0            ; Repeat the same values
  714.     REPT N_RETARD        ;  Shades of red, from 1 to N_RETARD
  715.      I = I + (63/(N_RETARD-1) - 1)
  716.      DB I,0,0
  717.     ENDM
  718.  
  719. .CODE
  720. SetPal PROC
  721.     cli
  722.     mov    dx,3C8h        ; DAC palette port
  723.     mov    al,1        ; Start writing RGBs from color index 1
  724.     out    dx,al
  725.     inc    dx        ; To write the color data (RGBs)
  726.     mov    si,OFFSET Palette
  727.     mov    bx,7
  728.     sub    bl,[MaxRed]
  729.     add    si,bx
  730.     add    si,bx
  731.     add    si,bx    
  732.     mov    cx,N_RETARD    ; Number of colors
  733.     L4:    lodsb            ; Get red component
  734.         out    dx,al        ; Send it to the DAC
  735.     lodsb            ; Get green component
  736.     out    dx,al        ; Send it to the DAC
  737.     lodsb            ; Get blue component
  738.     out    dx,al        ; Send it to the DAC
  739.     loop    L4        ; Do it for the N_RETARD shades
  740.     sti
  741.     ret
  742. SetPal    ENDP
  743.  
  744. ; --------------------------------------------------------------------------
  745. ; Function to rotate the palette, to fade out the vectors
  746. ; ---------------------------------------------------------------------------
  747. RotatePal PROC
  748.     mov    al,MaxRed
  749.     inc    al
  750.     cmp    al,8
  751.     je    WrapPal
  752.     mov    MaxRed,al
  753.     call    SetPal
  754.     ret
  755.  WrapPal:
  756.      mov    MaxRed,1
  757.     call    SetPal
  758.     ret
  759. RotatePal ENDP
  760.  
  761. ; --------------------------------------------------------------------------
  762. ; Function to setup object data, morphing them with linear interpolation
  763. ; ---------------------------------------------------------------------------
  764. ; Input:
  765. ;  To force morphing: AX == object # (0 to NObjects-1)
  766. ;  To keep on: AX == -1
  767. .DATA
  768.  MORPHING   EQU 1
  769.  DO_NOTHING EQU 0
  770.  State        DB 0
  771.  CurrentObject    DW 0
  772.  DestObject    DW 0
  773.  MorphingCoors    DW 8 DUP (?,?,?)
  774.  Increments    DW 8 DUP (?,?,?)
  775.  MorphCount    DW ?
  776.  
  777. .CODE
  778. SetupObject PROC
  779.     inc    ax
  780.     jz    KeepOn
  781.     dec    ax
  782.     mov    [State],MORPHING
  783.     mov    [MorphCount],10h    ; Intermediate steps
  784.     mov    [DestObject],ax        ; Object to which to morph
  785.     mov    [LPointsPtr],OFFSET MorphingCoors
  786.     mov    [DestObject],ax
  787.     mov    ax,ds
  788.     mov    es,ax
  789.     mov    si,[CurrentObject]
  790.     add    si,si
  791.     mov    si,ObjDefs[si]
  792.     mov    di,OFFSET MorphingCoors
  793.     mov    cx,[NPoints]
  794.     mov    dx,cx
  795.     add    cx,cx
  796.     add    cx,dx
  797.     rep    movsw            ; Morphing coors start thus
  798.     mov    si,[DestObject]
  799.     add    si,si
  800.     mov    si,ObjDefs[si]        ; Where're the coors for the obj?
  801.     mov    bx,[CurrentObject]
  802.     add    bx,bx
  803.     mov    bx,ObjDefs[bx]
  804.     mov    di,OFFSET Increments
  805.     ; Now, si -> Increments; bx -> current coors; di -> increments
  806.     mov    bp,[NPoints]
  807.     mov    cl,4            ; For the sar
  808.    SO1:    lodsw
  809.     sub    ax,[bx]
  810.     add    ax,8
  811.     sar    ax,cl
  812.     stosw
  813.     lodsw
  814.     add    ax,8
  815.     sub    ax,[bx+2]
  816.     sar    ax,cl
  817.     stosw
  818.     lodsw
  819.     add    ax,8
  820.     sub    ax,[bx+4]
  821.     sar    ax,cl
  822.     stosw
  823.     add    bx,6
  824.     dec    bp
  825.     jnz    SO1
  826.     ret
  827.  KeepOn:mov    al,[State]
  828.     cmp    al,MORPHING
  829.     jne    SOExit
  830.     mov    ax,[MorphCount]
  831.     or    ax,ax
  832.     jnz    SO2
  833.     mov    [State],DO_NOTHING
  834.     mov    bx,[DestObject]
  835.     mov    [CurrentObject],bx
  836.     add    bx,bx
  837.     mov    bx,ObjDefs[bx]
  838.     mov    [LPointsPtr],bx
  839.     ret
  840.    SO2:    mov    si,OFFSET Increments
  841.     mov    di,OFFSET MorphingCoors
  842.     mov    cx,[NPoints]
  843.    SO3:    lodsw                ; Load increment
  844.     add    [di],ax
  845.     lodsw
  846.     add    [di+2],ax
  847.     lodsw
  848.     add    [di+4],ax
  849.     add    di,6
  850.     loop    SO3
  851.     dec    MorphCount
  852. SOExit:    ret
  853. SetupObject ENDP
  854. ; ===========================================================================
  855. ; Note: the code for the starfield and the palette managing for the explosion
  856. ;  is quite messy, as I did it in 2 or 3 hours. I won't bother commenting it
  857. ;  'cuz I assume it's quite easy to understand. Forgive me for being lazy!
  858. ; ===========================================================================
  859.  
  860. ; ---------------------------------------------------------------------------
  861. ; Functions to keep a starfield in the background while we do the ret-vect
  862. ; ---------------------------------------------------------------------------
  863. NUM_STARS = 200h
  864. Z_SPEED = 25
  865. FAR_Z = 1000h
  866. .DATA
  867. StarsPalette LABEL BYTE
  868.     I = 63
  869.     REPT 16
  870.     DB 3 DUP (I)
  871.     I = I - 4
  872.     ENDM
  873.     DB 0,0,0
  874. EVEN
  875. RndNum LABEL WORD
  876. dw -206, -27, 117, 202,-197, 158,  96, 118,-164,  92
  877. dw  126,-174,-194,-184,-144, 141,  75, -12,  56, 201
  878. dw  -94, -95, -54, 153,-149, 191, 205,  88, 123,  52
  879. dw -103, -10,-138, -61, 197, 111, 180, 199,  94,-145
  880. dw  181, -85,-143, 172,-172,  50,-136,  69, -45,-101
  881. dw   33,-148, 113, -38, -55,  37,  64, 157,-117,  98
  882. dw  127, -22, -33, -88,-205, -80, 154,  43, 121,-104
  883. dw   34,  39,  31,-201,-175,  76,  79,-102,-162, 135
  884. dw   73, 138, 174, 165,  29,-116, -18,-153, -74, 177
  885. dw -189, 194,-180,-169,  77, 128, -44,-156,  80, 130
  886. dw  -92,-125,-187, 106, -31,-105, -37, 124, -97,-130
  887. dw -168, 195,-154,-163,-106, 173,  48,  27,-142, 163
  888. dw -185, 119, -83, 136,-203, 132, 107, 186, -35,  14
  889. dw -161,-110, 114, -53, -58, -15,-124,  26,  97,  25
  890. dw -122,  10, 155, -41, -68, -76, 208, 169, 206,-140
  891. dw  -72,  38, 204, -14,  23,  99,-190,-118, -62, -60
  892. dw  -24,  22, -21, 188,  47, 167,  15,-112,  83, 185
  893. dw -198,-178, 189,  78,-182, 148,-159,  17, 145,-133
  894. dw   57,-209,  12,  44, -81,-195, -40, -17,-188, -69
  895. dw   11,-192,-171, 187, -78,-114,-176,-207,  24, 108
  896. dw  -89, 116,-179,  82, 149, 160, 104,-127, -25, 151
  897. dw -141, -43, -51,  46, 200,  20, 171,-119,-107,-193
  898. dw  -66,  86,-181, -77,  32,-158, -71,-139, 147, -28
  899. dw  -34,  61,-177, 120,  36, 137, 159,  41, -57, -46
  900. dw   71,-186,-135, -50, -47, 178, 133, -42, -99,  58
  901. dw -157, 152, 190,  95,-137, -67, 110,-210,-146, -19
  902. dw  -32, 183,  21,-196, 125,  45,  60,  90,-132,-111
  903. dw  -64,  28,-123,  30, -96, -29, -91,-113, 166,  74
  904. dw  -73, 156, -59,-200, -63, 193, 140,-151,  66, 115
  905. dw   62,  59,-191,-160,  54,  35,  67, -48,-126, 131
  906. dw  161,-155,  81, -16, 192, 168, -86,-109,  40, 203
  907. dw   49, 139, 175,-129, 112, 134,-208, 122, -20,  63
  908. dw  198,-165, -49, -90,  18,  13,-152, -13, 150,  87
  909. dw -167, 196,  70,  51, -65,-121, 184,-147,  42, 100
  910. dw  129, -98, 144,-128, -75, 182, 109, -79,  93,  65
  911. dw  -23,  55,  68, -70, 164, -26, 207,-150, -52,-134
  912. dw  101, 102,-166, -30, -56, -87,-108, 142,-100, 105
  913. dw  -82, -93,-199,  85, 143, 209, 176, -11,  72,-120
  914. dw   84,-173, 146,-115,  53, 170, 103,-183,  89,  16
  915. dw -202, -84, -39,-170,  19,-204,-131, 162,  91, -36
  916.  
  917. XRndIndex    DW 0
  918. YRndIndex    DW 30h    ; Arbitrary
  919. StarsX        DW NUM_STARS DUP (0)
  920. StarsY        DW NUM_STARS DUP (0)
  921. StarsZ        DW NUM_STARS DUP (0)
  922. StarsDI        DW NUM_STARS DUP (0)
  923. NumCurrentStars    DW 0
  924. ErrorMsg    DB 'There has been an internal error. Please report!', '$'
  925.  
  926. .CODE
  927. InitStars PROC
  928.     cli
  929.     mov    dx,3C8h        ; DAC palette port
  930.     mov    al,10h        ; Start writing RGBs from color index 16d
  931.     out    dx,al
  932.     inc    dx        ; To write the color data (RGBs)
  933.     mov    si,OFFSET StarsPalette
  934.     mov    cx,11h        ; Number of colors
  935.     L5:    lodsb            ; Get red component
  936.         out    dx,al        ; Send it to the DAC
  937.     lodsb            ; Get green component
  938.     out    dx,al        ; Send it to the DAC
  939.     lodsb            ; Get blue component
  940.     out    dx,al        ; Send it to the DAC
  941.     loop    L5        ; Do it for the 11h shades
  942.     sti
  943.     ret
  944. InitStars ENDP
  945.  
  946. AddStar    PROC
  947.     mov    ax,[NumCurrentStars]
  948.     cmp    ax,NUM_STARS
  949.     jne    DoAdd
  950.     jmp    DontAdd
  951. DoAdd:
  952.     mov    ax,ds
  953.     mov    es,ax
  954.     mov    di,OFFSET StarsZ
  955.     mov    cx,NUM_STARS
  956.     xor    ax,ax
  957.     repne    scasw
  958.     je    NotInternalError
  959.     mov    ax,0003
  960.     int    10h
  961.     mov    dx,OFFSET ErrorMsg
  962.     mov    ah,9
  963.     int    21h
  964.     mov    ax,4CFFh
  965.     int    21h
  966. NotInternalError:
  967.     mov    cl,3
  968.     mov    bx,di
  969.     sub    bx,2 + OFFSET StarsZ
  970.     mov    [WORD PTR di-2],FAR_Z
  971.     mov    si,[XRndIndex]
  972.     mov    ax,RndNum[si]
  973.     shl    ax,cl
  974.     mov    StarsX[bx],ax
  975.     mov    si,[YRndIndex]
  976.     mov    ax,RndNum[si]
  977.     shl    ax,cl
  978.     mov    StarsY[bx],ax
  979.     mov    ax,[XRndIndex]
  980.     mov    bx,[YRndIndex]
  981.     add    ax,2
  982.     cmp    ax,400d
  983.     jne    DontWrapXRnd
  984.     mov    ax,0
  985. DontWrapXRnd:
  986.     add    bx,2
  987.     cmp    bx,400d
  988.     jne    DontWrapYRnd
  989.     mov    bx,0
  990.     add    ax,2
  991.     cmp    ax,400d
  992.     jne    DontWrapXRnd2
  993.     mov    ax,0
  994. DontWrapXRnd2:
  995. DontWrapYRnd:
  996.     cmp    ax,bx
  997.     jne    XAndYNotEqual
  998.     add    ax,2
  999.     cmp    ax,400d
  1000.     jne    DontWrapXRnd3
  1001.     mov    ax,0
  1002. DontWrapXRnd3:
  1003. XAndYNotEqual:
  1004.     mov    [XRndIndex],ax
  1005.     mov    [YRndIndex],bx
  1006.     inc    [NumCurrentStars]
  1007. DontAdd:
  1008.     ret
  1009. AddStar    ENDP
  1010.  
  1011. DisplayStars PROC
  1012.     mov    di,OFFSET StarsZ
  1013.     mov    cx,NUM_STARS
  1014. DSOtherStar:
  1015.     mov    ax,ds
  1016.     mov    es,ax
  1017.     xor    ax,ax
  1018.     repe    scasw            ; Find first nonzero StarZ
  1019.     jne    DSDontExit
  1020.     jmp    DSExit
  1021. DSDontExit:
  1022.     push    di
  1023.     push    cx
  1024.     mov    bx,di
  1025.     sub    bx,2 + OFFSET StarsZ
  1026.     mov    ax,0A000h
  1027.     mov    es,ax
  1028.     mov    di,StarsDI[bx]
  1029.     cmp    BYTE PTR es:[di],10h
  1030.     jb    DontEraseStar
  1031.     mov    BYTE PTR es:[di],0
  1032. DontEraseStar:
  1033.     mov    cx,StarsZ[bx]        ; Get coor Z
  1034.     cmp    cx,1
  1035.     jne    DontTerminate
  1036.     mov    StarsZ[bx],0
  1037.     dec    [NumCurrentStars]
  1038.     jmp    DSContinue
  1039. DontTerminate:
  1040.     mov    ax,StarsX[bx]
  1041.     cwd
  1042.     mov    dl,ah
  1043.     mov    ah,al
  1044.     idiv    cx            ; Get screen coordinate X
  1045.     add    ax,160d            ; To center the stars
  1046.     cmp    ax,320d
  1047.     jl    DontKill1
  1048.     mov    StarsZ[bx],1
  1049.     jmp    DSContinue
  1050. DontKill1:
  1051.     cmp    ax,0
  1052.     jg    DontKill2
  1053.     mov    StarsZ[bx],1
  1054.     jmp    DSContinue
  1055. DontKill2:
  1056.     mov    si,ax
  1057.     mov    ax,StarsY[bx]
  1058.     cwd
  1059.     mov    dl,ah
  1060.     mov    ah,al
  1061.     idiv    cx            ; Get screen coor. Y
  1062.     add    ax,100d
  1063.     cmp    ax,200d
  1064.     jl    DontKill3
  1065.     mov    StarsZ[bx],1
  1066.     jmp    DSContinue
  1067. DontKill3:
  1068.     cmp    ax,0
  1069.     jg    DontKill4
  1070.     mov    StarsZ[bx],1
  1071.     jmp    DSContinue
  1072. DontKill4:    
  1073.     mov    di,ax
  1074.     add    di,di
  1075.     mov    ax,MulBy320[di]
  1076.     add    si,ax
  1077.     mov    StarsDI[bx],si
  1078.     cmp    BYTE PTR es:[si],0
  1079.     jne    DontDrawStar
  1080.     mov    al,ch            ; StarZ/100h
  1081.     add    al,10h
  1082.     mov    BYTE PTR es:[si],al
  1083. DontDrawStar:
  1084. DSContinue:
  1085.     pop    cx
  1086.     pop    di
  1087.     jmp    DSOtherStar
  1088. DSExit:
  1089.     ret
  1090. DisplayStars ENDP
  1091.  
  1092. AdvanceStars PROC
  1093.     mov    di,OFFSET StarsZ
  1094.     mov    cx,NUM_STARS
  1095. ASOtherStar:
  1096.     mov    ax,ds
  1097.     mov    es,ax
  1098.     xor    ax,ax
  1099.     repe    scasw            ; Find first nonzero StarZ
  1100.     je    ASExit
  1101.     push    di
  1102.     push    cx
  1103.     mov    bx,di
  1104.     sub    bx,2 + OFFSET StarsZ
  1105.     mov    ax,StarsZ[bx]
  1106.     sub    ax,Z_SPEED
  1107.     cmp    ax,2
  1108.     jge    DontKill5
  1109.     mov    StarsZ[bx],1
  1110.     jmp    ASContinue
  1111. DontKill5:
  1112.     mov    StarsZ[bx],ax
  1113. ASContinue:
  1114.     pop    cx
  1115.     pop    di
  1116.     jmp    ASOtherStar
  1117. ASExit:
  1118.     ret
  1119. AdvanceStars ENDP
  1120.  
  1121. ; --------------------------------------------------------------------------
  1122. ; Functions to fade palette to all 3Fhs, to simulate exploding
  1123. ; ---------------------------------------------------------------------------
  1124. .DATA
  1125. NextColor    LABEL BYTE
  1126.     I = 0
  1127.     REPT 3Ch
  1128.     DB I + 4
  1129.     I = I + 1
  1130.     ENDM
  1131.     DB 3Fh,3Fh,3Fh,3Fh
  1132. PrevColor    LABEL BYTE
  1133.     DB 0,0,0,0
  1134.     I = 0
  1135.     REPT 3Ch
  1136.     DB I
  1137.     I = I + 1
  1138.     ENDM
  1139. TempPalette    LABEL BYTE
  1140.     DB 0,0,0
  1141.     DB 7 DUP (3Fh,0,0)
  1142.     DB 8 DUP (0,0,0)
  1143.     I = 63
  1144.     REPT 16
  1145.      DB 3 DUP (I)
  1146.      I = I - 4
  1147.     ENDM
  1148.     DB 0,0,0
  1149. EndExplode    DB 0    
  1150. .CODE
  1151. AdvancePal PROC
  1152.     cli
  1153.     mov    ax,ds
  1154.     mov    es,ax
  1155.     mov    di,OFFSET TempPalette
  1156.     xor    bh,bh
  1157.     REPT 3 * 21h
  1158.     mov    bl,[di]
  1159.     mov    al,NextColor[bx]
  1160.     stosb
  1161.     ENDM
  1162.     mov    dx,3C8h
  1163.     xor    al,al
  1164.     out    dx,al
  1165.     inc    dx        ; To write the data
  1166.     mov    si,OFFSET TempPalette
  1167.     REPT 3 * 21h
  1168.     lodsb
  1169.     out    dx,al
  1170.     ENDM
  1171.     sti
  1172.     cmp    [TempPalette],3Fh
  1173.     jne    AP1
  1174.     mov    [EndExplode],1
  1175. AP1:
  1176.     ret
  1177. AdvancePal ENDP
  1178.  
  1179. DecreasePal PROC
  1180.     cli
  1181.     mov    ax,ds
  1182.     mov    es,ax
  1183.     mov    di,OFFSET TempPalette
  1184.     xor    bh,bh
  1185.     REPT 3 * 21h
  1186.     mov    bl,[di]
  1187.     mov    al,PrevColor[bx]
  1188.     stosb
  1189.     ENDM
  1190.     mov    dx,3C8h
  1191.     xor    al,al
  1192.     out    dx,al
  1193.     inc    dx        ; To write the data
  1194.     mov    si,OFFSET TempPalette
  1195.     REPT 3 * 21h
  1196.     lodsb
  1197.     out    dx,al
  1198.     ENDM
  1199.     sti
  1200.     ret
  1201. DecreasePal ENDP
  1202.  
  1203.  
  1204. ; **************************************************************************
  1205. ; **************************************************************************
  1206. ;  At last, here we have the main loop (looks like Pascal, doesn't it? 8-D).
  1207. ; **************************************************************************
  1208. ; **************************************************************************
  1209. .DATA
  1210. Phi    DW ?
  1211. RadiusX    DW 100d
  1212. RadiusY    DW 100d
  1213. RadiusZ    DW 200d
  1214. CenterX    DW 0
  1215. CenterY    DW 0
  1216. CenterZ    DW 600d
  1217.  
  1218. .CODE
  1219. Main    PROC
  1220.     cld
  1221.     mov    ax,@DATA
  1222.     mov    ds,ax
  1223.     mov    es,ax
  1224.     mov    ax,13h
  1225.     int    10h        ; Sets standard 320x200x256
  1226.     mov    MaxRed,7
  1227.     call    SetPal        ; Load values for the palette - red shades
  1228.     call    InitStars    ; Load values for the palette - white shades
  1229.     mov    ax,1
  1230. ObjLoop:push    ax        ; Loops for all objects
  1231.     call    SetupObject
  1232.     mov    cx,2        ; Numbwer of turns for each object
  1233. RotLoop:push    cx
  1234.     mov    ax,0        ; Obj starts with no angle (that is, far away)
  1235. PhiLoop:mov    [Phi],ax    ; Store NEW value of angle
  1236.     mov    bx,ax
  1237.     add    bx,bx
  1238.     mov    cx,[RadiusZ]
  1239.     mov    ax,SinTbl[bx+180d]    ; Get 100h * cos(Phi)
  1240.     imul    cx
  1241.     mov    al,ah
  1242.     mov    ah,dl
  1243.     add    ax,[CenterZ]
  1244.     mov    [deltaZ],ax
  1245.     mov    cx,[RadiusX]
  1246.         mov    ax,SinTbl[bx]    ; Get 100h * sin(phi)
  1247.     neg    ax
  1248.     imul    cx
  1249.     mov    al,ah
  1250.     mov    ah,dl
  1251.     add    ax,[CenterX]
  1252.     mov    [deltaX],ax
  1253.     mov    cx,[RadiusY]
  1254.     add    bx,bx
  1255.     sub    bx,720d
  1256.     jnc    M1
  1257.     add    bx,720d
  1258.     M1:    mov    ax,SinTbl[bx]    ; Get 100h * sin(phi)
  1259.     neg    ax
  1260.     imul    cx
  1261.     mov    al,ah
  1262.     mov    ah,dl
  1263.     add    ax,[CenterY]
  1264.     mov    [deltaY],ax
  1265.     mov    ax,[Phi]
  1266.     mov    [HAng],ax
  1267.     add    ax,ax
  1268.     sub    ax,360d
  1269.     jnc    M2
  1270.     add    ax,360d
  1271.     M2:    mov    [VAng],ax
  1272.     mov    ax,-1
  1273.     call    SetupObject    ; Performs morphing if necessary
  1274.     call    ProjectPoints    ; Calc new ScrPoints (projected coordinates)
  1275.     SetBorder 15
  1276.     call    DrawLines    ; Draws new lines
  1277.     SetBorder 13
  1278.     call    EraseLines    ; Erases lines from oldest buffer
  1279.     SetBorder 0
  1280.     mov    dx,3DAh
  1281. WaitVR1:in    al,dx
  1282.     and    al,8
  1283.     jz    WaitVR1        ; We wait till a vertical retrace
  1284. WaitDE:    in    al,dx
  1285.     and    al,1
  1286.     jnz    WaitDE        ; We wait till the vert. retr ends
  1287.     REPT 5
  1288.     call    AddStar
  1289.     ENDM
  1290.     call    DisplayStars
  1291.     call    AdvanceStars
  1292.     mov    dx,3DAh
  1293. WaitVR2:in    al,dx
  1294.     and    al,8
  1295.     jz    WaitVR2        ; Wait again till a vert. retr.
  1296.                 ; We animate every two frames (that's, at
  1297.                 ;  35 Hz) 'cos otherwise it's too fast!
  1298.     call    RotatePal    ; Rotate the palette, to fade out the vectors
  1299.     mov    ax,Phi
  1300.     add    ax,3
  1301.     cmp    ax,360d        ; Have we returned to the original spin?
  1302.     jae    ExitPhiLoop    ; If not, keep on the same way
  1303.     jmp    PhiLoop
  1304.   ExitPhiLoop:
  1305.     pop    cx
  1306.     dec    cx
  1307.     jz    ExitRotLoop
  1308.     jmp    RotLoop
  1309.   ExitRotLoop:
  1310.     pop    ax        ; Current obj number
  1311.     inc    ax
  1312.     cmp    ax,NObjects
  1313.     je    ExitObjLoop
  1314.     jmp    ObjLoop        ; Only 5 times to and fro
  1315.   ExitObjLoop:
  1316.     mov    ax,0
  1317.     call    SetupObject    ; Morph into nothing
  1318.     mov    ax,0        ; Obj starts with no angle (that is, far away)
  1319. PhiLoop2:mov    [Phi],ax    ; Store NEW value of angle
  1320.     mov    bx,ax
  1321.     add    bx,bx
  1322.     mov    cx,[RadiusZ]
  1323.     mov    ax,SinTbl[bx+180d]    ; Get 100h * cos(Phi)
  1324.     imul    cx
  1325.     mov    al,ah
  1326.     mov    ah,dl
  1327.     add    ax,[CenterZ]
  1328.     mov    [deltaZ],ax
  1329.     mov    cx,[RadiusX]
  1330.         mov    ax,SinTbl[bx]    ; Get 100h * sin(phi)
  1331.     neg    ax
  1332.     imul    cx
  1333.     mov    al,ah
  1334.     mov    ah,dl
  1335.     add    ax,[CenterX]
  1336.     mov    [deltaX],ax
  1337.     mov    cx,[RadiusY]
  1338.     add    bx,bx
  1339.     sub    bx,720d
  1340.     jnc    M3
  1341.     add    bx,720d
  1342.     M3:    mov    ax,SinTbl[bx]    ; Get 100h * sin(phi)
  1343.     neg    ax
  1344.     imul    cx
  1345.     mov    al,ah
  1346.     mov    ah,dl
  1347.     add    ax,[CenterY]
  1348.     mov    [deltaY],ax
  1349.     mov    ax,[Phi]
  1350.     mov    [HAng],ax
  1351.     add    ax,ax
  1352.     sub    ax,360d
  1353.     jnc    M4
  1354.     add    ax,360d
  1355.     M4:    mov    [VAng],ax
  1356.     mov    ax,-1
  1357.     call    SetupObject    ; Performs morphing if necessary
  1358.     call    ProjectPoints    ; Calc new ScrPoints (projected coordinates)
  1359.     SetBorder 15
  1360.     call    DrawLines    ; Draws new lines
  1361.     SetBorder 13
  1362.     call    EraseLines    ; Erases lines from oldest buffer
  1363.     SetBorder 0
  1364.     mov    dx,3DAh
  1365. WaitVR3:in    al,dx
  1366.     and    al,8
  1367.     jz    WaitVR3        ; We wait till a vertical retrace
  1368.     mov    dx,3DAh
  1369. WaitDE2:in    al,dx
  1370.     and    al,1
  1371.     jnz    WaitDE2        ; We wait till the vert. retr ends
  1372.     REPT 5
  1373.     call    AddStar
  1374.     ENDM
  1375.     call    DisplayStars
  1376.     call    AdvanceStars
  1377.     mov    dx,3DAh
  1378. WaitVR4:in    al,dx
  1379.     and    al,8
  1380.     jz    WaitVR4        ; Wait again till a vert. retr.
  1381.                 ; We animate every two frames (that's, at
  1382.                 ;  35 Hz) 'cos otherwise it's too fast!
  1383.     call    AdvancePal    ; To do the explosion
  1384.     cmp    [EndExplode],1
  1385.     je    ExitPhiLoop2    ; If not, keep on the same way
  1386.     mov    ax,[Phi]
  1387.     add    ax,3
  1388.     jmp    PhiLoop2
  1389.   ExitPhiLoop2:
  1390.     mov    cx,10h        ; Fade out palette in 10h frames
  1391. FadeOutLoop:
  1392.     push    cx
  1393.     mov    dx,3DAh
  1394. WaitNVR:in    al,dx
  1395.     test    al,1
  1396.     jnz    WaitNVR
  1397. WaitVR5:in    al,dx
  1398.     test    al,8
  1399.     jz    WaitVr5
  1400.     call    DecreasePal
  1401.     pop    cx
  1402.     loop    FadeOutLoop
  1403.     mov    ax,3
  1404.     int    10h        ; Set a wildly unknow video mode
  1405.     mov    ah,9
  1406.     mov    dx,offset ByeText
  1407.     int    21h        ; Use undoc. DOS function to print string
  1408.     mov    ax,4C00h
  1409.     int    21h        ; Exit to MeSsy-DOS
  1410. Main    ENDP
  1411.  
  1412.     END    Main