home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / fakesrc.zip / PART4 / LENZ.ASM next >
Assembly Source File  |  1993-11-16  |  27KB  |  768 lines

  1. ;=============================================================================
  2. ; lenz.asm - Lenz or Crystal Ball Demostration.
  3. ;                                                    File created: 10/18/93
  4. ; Copyright (c) 1993, Carlos Hasan                  Last modified: 11/16/93
  5. ;
  6. ; Description:
  7. ;   This file implements a Lenz-like Crystall Ball effect using the
  8. ;   VGA 320x200x256 graphics mode and a 320x200x256 picture.
  9. ;
  10. ; Portability:
  11. ;  Requires Turbo Assembler 3.2 or better to be assembled.
  12. ;  Dependent on the IBM PC 286 and the VGA graphics card.
  13. ;
  14. ; Modifications:
  15. ;  10/22/93 - Startup Code and Picture/Palette in .OBJ files.
  16. ;  11/01/93 - Fixed Vertical Strengh Amplification.
  17. ;  11/16/93 - Added EmBoss and Slide Effect.
  18. ;=============================================================================
  19.  
  20.                 jumps
  21.                 .model  small,pascal
  22.                 .286
  23.  
  24.                 dosseg                          ; used to link like
  25.                 .stack  1024                    ; an standalone program.
  26.  
  27.                 global  LenzDemo:proc
  28.                 global  LenzPal:byte            ; in LENZPAL.OBJ file.
  29.                 global  LenzPic:byte            ; in LENZRAW.OBJ file.
  30.  
  31. ;========================= Demo equates ======================================
  32. ;
  33. ; Note: 1. Lenz strengh is computed like:  Strengh = 256/Factor
  34. ;          where Factor is the real amplification of the lenz.
  35. ;
  36. ;       2. I have used a picture with a gray scale palette at
  37. ;          entries from 128 to 255. Emboss Bright, Depth, MinGray
  38. ;          and MaxGray must be adjusted for others pictures.
  39. ;
  40.  
  41. RADIUS          equ     52                      ; Lenz Radius in pixels.
  42. RADIUSI         equ     (15*RADIUS)/20          ; Internal Lenz Radius.
  43. STRENGH         equ     155                     ; Lenz Amplify (fixed 8.8).
  44. MAXWIDTH        equ     320                     ; VGA 320x200x256 dimensions.
  45. MAXHEIGHT       equ     200
  46. SEED            equ     286Ah                   ; Random seed for movement.
  47. BRIGHT          equ     150                     ; Emboss Bright Factor.
  48. DEPTH           equ     12*256                  ; Emboss Depth Factor (8.8).
  49. MINGRAY         equ     128                     ; Emboss Min/Max Gray
  50. MAXGRAY         equ     255                     ; Scale Range Values.
  51. TIMEOUT         equ     70 * 6                  ; at least 6 secs.
  52.  
  53. ;======================== Demo data ==========================================
  54.  
  55.                 .data
  56.  
  57. LenzTable       dw      4*RADIUS*RADIUS dup(?)  ; Holds the transformation.
  58. LenzWidth       dw      2*RADIUS dup(?)         ; Scanline widths.
  59. RandSeed        dw      ?                       ; Random Seed.
  60. Timer           dw      ?                       ; Timer counter.
  61.  
  62. ;======================== Demo Routines ======================================
  63.  
  64.                 .code
  65.  
  66. ;-----------------------------------------------------------------------------
  67. ; Random - Returns a random number of 16 bits, modified version of the
  68. ;  ripped System unit random routine of the Borland Pascal 7.0.
  69. ; Out:
  70. ;  AX - random value.
  71. ; Modified:
  72. ;  AX, DX, Flags.
  73. ;-----------------------------------------------------------------------------
  74.  
  75. Random          proc near
  76.  
  77.                 mov     ax,[RandSeed]
  78.                 mov     dx,8405h
  79.                 mul     dx
  80.                 inc     ax
  81.                 mov     [RandSeed],ax
  82.                 ret
  83.  
  84. Random          endp
  85.  
  86. ;-----------------------------------------------------------------------------
  87. ; WaitVRT - Waits the next VGA Vertical Retrace Period.
  88. ;-----------------------------------------------------------------------------
  89.  
  90. WaitVRT         proc near
  91.  
  92.                 mov     dx,3DAh
  93. WaitVR1:        in      al,dx
  94.                 test    al,8
  95.                 jne     WaitVR1
  96. WaitVR2:        in      al,dx
  97.                 test    al,8
  98.                 je      WaitVR2
  99.                 ret
  100.  
  101. WaitVRT         endp
  102.  
  103. ;-----------------------------------------------------------------------------
  104. ; Delay - Sleeps during any amount of time. Uses the VGA Vertical retrace.
  105. ; In:
  106. ;   CX - Number of ticks to speed (ticks at 70Hz).
  107. ;-----------------------------------------------------------------------------
  108.  
  109. Delay           proc near
  110.  
  111. DelayLoop:      call    WaitVRT
  112.                 loop    DelayLoop
  113.                 ret
  114.  
  115. Delay           endp
  116.  
  117. ;-----------------------------------------------------------------------------
  118. ; SetPalette - Sets the VGA color palette.
  119. ; In:
  120. ;   ES:SI - Palette segment address.
  121. ;-----------------------------------------------------------------------------
  122.  
  123. SetPalette      proc near
  124.  
  125.                 push    ds
  126.                 mov     ax,es
  127.                 mov     ds,ax
  128.                 mov     dx,3C8h
  129.                 xor     al,al
  130.                 out     dx,al
  131.                 inc     dx
  132.                 mov     cx,768
  133.                 cld
  134.                 rep     outsb
  135.                 pop     ds
  136.                 ret
  137.  
  138. SetPalette      endp
  139.  
  140. ;-----------------------------------------------------------------------------
  141. ; ShowSpray - Writes a picture on the scren using a Spray-like effect.
  142. ; In:
  143. ;   DX - Picture source segment.
  144. ;-----------------------------------------------------------------------------
  145.  
  146. ShowSpray       proc near
  147.  
  148.                 push    ds
  149.                 push    es
  150.  
  151.                 mov     ds,dx
  152.                 xor     si,si
  153.                 mov     ax,0A000h
  154.                 mov     es,ax
  155.  
  156.                 xor     cx,cx
  157. SprayLoop:      push    cx
  158.                 xor     bx,bx
  159. SprayLine:      push    bx
  160.                 mov     ah,cs:[RandTable+bx]
  161.                 mov     bx,cx
  162.                 mov     al,cs:[RandTable+bx]
  163.                 mov     bx,ax
  164.                 mov     di,ax
  165.                 mov     al,ds:[si+bx]
  166.                 mov     es:[di],al
  167.                 pop     bx
  168.                 inc     cl
  169.                 inc     bl
  170.                 jne     SprayLine
  171.                 pop     cx
  172.                 inc     cl
  173.                 jne     SprayLoop
  174.  
  175.                 pop     es
  176.                 pop     ds
  177.                 ret
  178.  
  179. RandTable label byte
  180.       db   83,   8,  18, 177,  13, 241, 149, 157
  181.       db   75, 248, 254,  23,  16,  66, 207,  31
  182.       db  211, 183,  80, 242, 218,  27,  15, 128
  183.       db   94,  98,   4,  36, 139, 110,  85, 230
  184.       db  212,  26,  12, 249, 169, 233, 200, 150
  185.       db   95, 114, 130, 167, 202, 187,  76, 145
  186.       db   62, 117, 115, 190, 209,  42, 185, 224
  187.       db  129, 104, 108, 192, 174, 137,  44,  41
  188.       db  141,  53, 179,  81, 181,  57, 147, 210
  189.       db   50, 134, 156, 125, 133, 126, 106, 162
  190.       db   20,  59,  84,   0, 151, 143, 101, 215
  191.       db   68, 246, 189, 197,  99, 213, 112, 144
  192.       db   28, 235, 240,  90, 154,  56, 138, 165
  193.       db   19, 166, 159,  92, 127, 208, 105, 118
  194.       db  119, 153, 191, 184,  87,  70,   9, 164
  195.       db   60, 252,  96,   3, 171,  38, 136,  14
  196.       db    7, 160,  71, 146, 102, 229, 227,  43
  197.       db  221, 182, 217,  30, 131, 219,  61, 180
  198.       db  195, 245, 109, 203,  24,  49, 170, 247
  199.       db   46, 148, 122, 250, 173, 107, 255, 194
  200.       db    6,  37,  93,  22, 168,  97, 193,   5
  201.       db   51, 223, 116,  86,   1,  89, 121, 243
  202.       db  140, 220,  39, 222,  65,  55,  17,  54
  203.       db  175, 206, 214, 155, 142, 163,  25, 188
  204.       db  178,  11, 204, 135, 201, 238,  79, 132
  205.       db  198,  40,  21,  45, 237, 253, 152,  74
  206.       db   32, 111,  52,  47, 236,   2, 176, 239
  207.       db  234,  58, 100,  91, 172,  73,  82, 205
  208.       db   34,  88,  78, 231, 232, 225,  48, 251
  209.       db   67, 123, 244,  29, 216,  64, 196,  69
  210.       db  199,  33,  72,  35,  10,  63, 161, 228
  211.       db  113, 158, 120, 103, 124, 186, 226,  77
  212.  
  213. ShowSpray     endp
  214.  
  215. ;-----------------------------------------------------------------------------
  216. ; DoEmBoss - Do the EmBoss effect into a 320x200x256 picture.
  217. ; In:
  218. ;  DX - Picture Source Segment.
  219. ;-----------------------------------------------------------------------------
  220.  
  221. DoEmboss        proc
  222.  
  223.                 pusha
  224.                 push    ds
  225.  
  226.                 mov     ds,dx                   ; DS:SI = source image.
  227.                 xor     si,si
  228.                 xor     cx,cx
  229. EmBossLine:     push    cx                      ; Y= 0..198
  230.                 xor     bx,bx
  231. EmBossLoop:     push    bx                      ; X= 0..318
  232.                 add     bx,cx
  233.                 xor     dh,dh
  234.                 mov     dl,[si+bx]
  235.                 mov     ax,dx
  236.                 mov     dl,[si+bx+MAXWIDTH+1]
  237.                 sub     ax,dx
  238.                 mov     dx,DEPTH                ; EmBoss Depth Factor.
  239.                 imul    dx
  240.                 mov     al,ah
  241.                 mov     ah,dl
  242.                 add     ax,BRIGHT
  243.                 cmp     ax,MINGRAY              ; Check Color Range.
  244.                 jge     EmbossHigh
  245.                 mov     ax,MINGRAY
  246. EmbossHigh:     cmp     ax,MAXGRAY
  247.                 jle     EmbossLow
  248.                 mov     ax,MAXGRAY
  249. EmbossLow:      mov     [si+bx],al
  250.                 pop     bx
  251.                 inc     bx
  252.                 cmp     bx,MAXWIDTH-2
  253.                 jbe     EmbossLoop
  254.                 pop     cx
  255.                 add     cx,MAXWIDTH
  256.                 cmp     cx,MAXWIDTH*(MAXHEIGHT-2)
  257.                 jbe     EmbossLine
  258.  
  259.                 pop     ds
  260.                 popa
  261.                 ret
  262.  
  263. DoEmboss        endp
  264.  
  265. ;-----------------------------------------------------------------------------
  266. ; ShowSlide - Shows a 320x200x256 picture using a Slide Effect.
  267. ; In:
  268. ;  DX - Piccy Source Segment.
  269. ;-----------------------------------------------------------------------------
  270.  
  271. ShowSlide       proc
  272.                 local    Level:word:MAXWIDTH,Weight:word:MAXWIDTH,\
  273.                    LevelPtr:word,WeightPtr:word
  274.  
  275.                 pusha
  276.                 push    ds
  277.                 push    es
  278.  
  279.                 mov     ds,dx           ; DS:SI = Source Picture.
  280.                 xor     si,si
  281.  
  282.                 mov     ax,ss
  283.                 mov     es,ax
  284.  
  285.                 lea     di,[Level]      ; Clear Slide Row Levels.
  286.                 mov     cx,MAXWIDTH
  287.                 cld
  288.                 xor     ax,ax
  289.                 rep     stosw
  290.  
  291.                 lea     di,[Weight]     ; Clear Slide Row Weights.
  292.                 mov     cx,MAXWIDTH
  293.                 cld
  294.                 xor     ax,ax
  295.                 rep     stosw
  296.  
  297.                 mov     ax,0A000h
  298.                 mov     es,ax
  299.  
  300. SlideLoop:      call    WaitVRT
  301.                 lea     bx,[Level]      ; Loads Level Pointer.
  302.                 mov     [LevelPtr],bx
  303.  
  304.                 lea     bx,[Weight]     ; Loads Weight Pointer.
  305.                 mov     [WeightPtr],bx
  306.  
  307.                 xor     cx,cx           ; For Each Column:
  308.                 xor     dx,dx
  309.  
  310. SlideInner:     mov     bx,[LevelPtr]   ; Level[Col] < 320*200? Skip.
  311.                 mov     ax,ss:[bx]
  312.                 cmp     ax,MAXWIDTH*MAXHEIGHT
  313.                 jae     SlideContinue
  314.  
  315.                 inc     dx              ; Sets Flag.
  316.  
  317.                 mov     bx,[WeightPtr]  ; Weight[Col] <> 0?
  318.                 mov     ax,ss:[bx]      ; Yes, Decrease.
  319.                 test    ax,ax           ; No, Slide Down Row.
  320.                 jz      SlideDown
  321.                 dec     ax
  322.                 mov     ss:[bx],ax
  323.                 jmp     SlideContinue
  324.  
  325. SlideDown:      mov     bx,[LevelPtr]   ; Level[Col] += 320
  326.                 mov     ax,ss:[bx]
  327.                 add     ax,MAXWIDTH
  328.                 mov     ss:[bx],ax
  329.                 add     ax,cx           ; DI = Col + Level[Col]
  330.                 mov     di,ax
  331.                 mov     bx,di           ; Sets New Row Weight:
  332.                 mov     al,es:[di+MAXWIDTH] ; W=ABS(VMEM[DI+320]-VMEM[DI])
  333.                 sub     al,es:[di]
  334.                 jge     SlidePos
  335.                 neg     al
  336. SlidePos:       xor     ah,ah
  337.                 mov     bx,[WeightPtr]
  338.                 mov     ss:[bx],ax
  339.  
  340.                 mov     bx,di           ; Put Pixel at (Col,Level[Col])
  341.                 mov     al,ds:[si+bx]
  342.                 mov     es:[di],al
  343.  
  344. SlideContinue:  add     [LevelPtr],2    ; Next Column.
  345.                 add     [WeightPtr],2
  346.                 inc     cx
  347.                 cmp     cx,MAXWIDTH
  348.                 jb      SlideInner
  349.  
  350.                 test    dx,dx           ; Screen 100% filled?
  351.                 jnz     SlideLoop       ; No, Repeat.
  352.  
  353.                 pop     es
  354.                 pop     ds
  355.                 popa
  356.                 ret
  357.  
  358. ShowSlide       endp
  359.  
  360.  
  361. ;-----------------------------------------------------------------------------
  362. ; GenLenz - Renders the Transformation matrix used during animation.
  363. ;
  364. ; Note: The square root is calculated using the Newton iteration
  365. ;       aproximation algorithm:
  366. ;                                        y² + (r² - x²)
  367. ;               y² ≡ r² - x²  ══   y ≈ ────────────────
  368. ;                                             2y
  369. ;
  370. ;       We performs only one iteration using a initial «y» value
  371. ;       near to the real square root wanted.
  372. ;-----------------------------------------------------------------------------
  373.  
  374. GenLenz         proc near
  375.                 local    X:word,Y:word,R:word,Dist:Word,AddX:word,AddY:word
  376.  
  377.                 mov      ax,ds
  378.                 mov      es,ax
  379.                 cld
  380.  
  381.                 xor      ax,ax                  ; Fills the whole rectangle
  382.                 lea      di,[LenzTable]         ; matrix with a linear
  383.                 mov      cx,2*RADIUS            ; transformation.
  384. MakLinLoop:     push     ax
  385.                 push     cx
  386.                 mov      cx,2*RADIUS
  387. MakLinRow:      stosw
  388.                 inc      ax
  389.                 loop     MakLinRow
  390.                 pop      cx
  391.                 pop      ax
  392.                 add      ax,MAXWIDTH
  393.                 loop     MakLinLoop
  394.  
  395.                 mov      [X],RADIUS             ; makes the scanlines
  396.                 mov      [Y],0                  ; widths of the lenz
  397. MakWidth:       cmp      [Y],RADIUS             ; with radius RADIUS.
  398.                 jge      MakXWidth
  399.                 mov      ax,[X]
  400.                 mov      bx,RADIUS              ; LenzWidth[Radius+Y] = X
  401.                 add      bx,[Y]
  402.                 shl      bx,1
  403.                 mov      [LenzWidth+bx],ax
  404.                 mov      bx,RADIUS              ; LenzWidth[Radius-Y-1] = X
  405.                 sub      bx,[Y]
  406.                 dec      bx
  407.                 shl      bx,1
  408.                 mov      [LenzWidth+bx],ax
  409.                 mov      ax,[Y]                 ; X² = Radius² - Y²
  410.                 imul     ax
  411.                 mov      bx,ax
  412.                 mov      ax,[X]
  413.                 imul     ax
  414.                 sub      ax,bx
  415.                 add      ax,RADIUS*RADIUS
  416.                 sar      ax,1
  417.                 cwd
  418.                 mov      bx,[X]
  419.                 idiv     bx
  420.                 mov      [X],ax
  421.                 inc      [Y]                    ; Y = Y+1
  422.                 jmp      MakWidth
  423. MakXWidth:
  424.  
  425.  
  426.                 mov     [X],RADIUSI             ; Makes the transformation
  427.                 mov     [Y],0                   ; for the Lenz of radius
  428. MakLoop:        cmp     [Y],RADIUSI             ; RADIUSY. Notice that
  429.                 jge     MakExit                 ; this lets a border
  430.                                                 ; used for restoring the
  431.                                                 ; background while moving
  432.                                                 ; the lenz into the screen.
  433.  
  434.                 mov     ax,[X]                  ; compute the scanline
  435.                 mov     dx,6                    ; width adjusting with
  436.                 imul    dx                      ; an aspect ratio of 6/5.
  437.                 mov     bx,5
  438.                 idiv    bx
  439.                 mov     [R],ax
  440.  
  441.                 mov     [Dist],0
  442.                 mov     [AddX],0
  443.                 mov     [AddY],ax
  444.  
  445. MakLine:        mov     ax,[R]
  446.                 cmp     [AddX],ax
  447.                 jge     MakLineBreak
  448.  
  449.                 ; si = @LenzTable[0,RADIUS-Y-1]
  450.  
  451.                 lea     si,[LenzTable]
  452.                 mov     ax,RADIUS
  453.                 sub     ax,[Y]
  454.                 dec     ax
  455.                 imul    ax,2*RADIUS
  456.                 add     si,ax
  457.                 shl     si,1
  458.  
  459.                 ; di = @LenzTable[0,RADIUS+Y]
  460.  
  461.                 lea     di,[LenzTable]
  462.                 mov     ax,RADIUS
  463.                 add     ax,[Y]
  464.                 imul    ax,2*RADIUS
  465.                 add     di,ax
  466.                 shl     di,1
  467.  
  468.                 ; Lenz[RADIUS+AddX,RADIUS-Y-1] = RADIUS+Hi(Dist) +
  469.                 ;     MAXWIDTH * (RADIUS-1-STRENGH*Y)
  470.  
  471.                 mov     bx,RADIUS
  472.                 add     bx,[AddX]
  473.                 shl     bx,1
  474.                 mov     ax,[Y]
  475.                 imul    ax,STRENGH
  476.                 sar     ax,8
  477.                 imul    ax,MAXWIDTH
  478.                 neg     ax
  479.                 add     ax,RADIUS+MAXWIDTH*(RADIUS-1)
  480.                 mov     dx,[Dist]
  481.                 shr     dx,8
  482.                 add     ax,dx
  483.                 mov     [si+bx],ax
  484.  
  485.                 ; Lenz[RADIUS-AddX-1,RADIUS-Y-1] = RADIUS-Hi(Dist)-1+
  486.                 ;     MAXWIDTH * (RADIUS-1-STRENGH*Y)
  487.  
  488.                 mov     bx,RADIUS
  489.                 sub     bx,[AddX]
  490.                 dec     bx
  491.                 shl     bx,1
  492.                 mov     ax,[Y]
  493.                 imul    ax,STRENGH
  494.                 sar     ax,8
  495.                 imul    ax,MAXWIDTH
  496.                 neg     ax
  497.                 add     ax,RADIUS+MAXWIDTH*(RADIUS-1)
  498.                 mov     dx,[Dist]
  499.                 shr     dx,8
  500.                 sub     ax,dx
  501.                 dec     ax
  502.                 mov     [si+bx],ax
  503.  
  504.                 ; LenzTable[RADIUS+AddX,RADIUS+Y] = RADIUS+Hi(Dist)+
  505.                 ;    MAXWIDTH * (RADIUS + STRENGH*Y)
  506.  
  507.                 mov     bx,RADIUS
  508.                 add     bx,[AddX]
  509.                 shl     bx,1
  510.                 mov     ax,[Y]
  511.                 imul    ax,STRENGH
  512.                 sar     ax,8
  513.                 imul    ax,MAXWIDTH
  514.                 add     ax,RADIUS+MAXWIDTH*RADIUS
  515.                 mov     dx,[Dist]
  516.                 shr     dx,8
  517.                 add     ax,dx
  518.                 mov     [di+bx],ax
  519.  
  520.                 ; LenzTable[RADIUS-AddX-1,RADIUS+Y] = RADIUS-Hi(Dist)-1+
  521.                 ;    MAXWIDTH * (RADIUS+STRENGH*Y)
  522.  
  523.                 mov     bx,RADIUS
  524.                 sub     bx,[AddX]
  525.                 dec     bx
  526.                 shl     bx,1
  527.                 mov     ax,[Y]
  528.                 imul    ax,STRENGH
  529.                 sar     ax,8
  530.                 imul    ax,MAXWIDTH
  531.                 add     ax,RADIUS+MAXWIDTH*RADIUS
  532.                 mov     dx,[Dist]
  533.                 shr     dx,8
  534.                 sub     ax,dx
  535.                 dec     ax
  536.                 mov     [di+bx],ax
  537.  
  538.                 ; Dist = Dist + (Strengh*Radius)/dY
  539.  
  540.                 mov     ax,STRENGH*RADIUS
  541.                 cwd
  542.                 mov     bx,[AddY]
  543.                 idiv    bx
  544.                 add     [Dist],ax
  545.  
  546.                 mov     ax,[AddY]               ; dY² = R² - dX²
  547.                 imul    ax
  548.                 mov     bx,ax
  549.                 mov     ax,[AddX]
  550.                 imul    ax
  551.                 sub     bx,ax
  552.                 mov     ax,[R]
  553.                 imul    ax
  554.                 add     ax,bx
  555.                 sar     ax,1
  556.                 cwd
  557.                 mov     bx,[AddY]
  558.                 idiv    bx
  559.                 mov     [AddY],ax
  560.                 inc     [AddX]                  ; dX = dX+1
  561.                 jmp     MakLine
  562.  
  563. MakLineBreak:   mov     ax,[X]                  ; X² = Radius'² - Y²
  564.                 imul    ax
  565.                 mov     bx,ax
  566.                 mov     ax,[Y]
  567.                 imul    ax
  568.                 sub     bx,ax
  569.                 mov     ax,RADIUSI*RADIUSI
  570.                 add     ax,bx
  571.                 sar     ax,1
  572.                 cwd
  573.                 mov     bx,[X]
  574.                 idiv    bx
  575.                 mov     [X],ax
  576.                 inc     [Y]                     ; Y = Y+1
  577.                 jmp     MakLoop
  578. MakExit:        ret
  579.  
  580. GenLenz         endp
  581.  
  582. ;-----------------------------------------------------------------------------
  583. ; WriteLenz - Writes the Lenz using the transformation matrix.
  584. ; In:
  585. ;  DI  - Starting offset location of the lenz.
  586. ;  DX  - Virtual picture used like background.
  587. ;-----------------------------------------------------------------------------
  588.  
  589. WriteLenz       proc near
  590.  
  591.                 push    bp
  592.                 mov     ax,0A000h
  593.                 mov     es,ax
  594.                 lea     bx,[LenzTable]
  595.                 lea     si,[LenzWidth]
  596.                 mov     bp,di
  597.                 mov     cx,2*RADIUS
  598.                 cld
  599. WriteLoop:      push    bx
  600.                 push    cx
  601.                 push    si
  602.                 push    di
  603.                 cmp     di,MAXWIDTH*MAXHEIGHT
  604.                 jae     WriteBreak
  605.                 mov     cx,[si]                 ; gets the scanline width.
  606.                 mov     ax,RADIUS
  607.                 sub     ax,cx
  608.                 add     di,ax
  609.                 add     bx,ax
  610.                 add     bx,ax
  611. WriteLine:      push    es
  612.                 mov     es,dx
  613.                 mov     si,[bx]
  614.                 mov     al,es:[bp+si]
  615.                 mov     si,[bx+2]
  616.                 mov     ah,es:[bp+si]
  617.                 add     bx,4
  618.                 pop     es
  619.                 stosw
  620.                 loop    WriteLine
  621. WriteBreak:     pop     di
  622.                 pop     si
  623.                 pop     cx
  624.                 pop     bx
  625.                 add     bx,4*RADIUS
  626.                 add     si,2
  627.                 add     di,MAXWIDTH
  628.                 loop    WriteLoop
  629.                 pop     bp
  630.                 ret
  631.  
  632. WriteLenz       endp
  633.  
  634.  
  635. ;-----------------------------------------------------------------------------
  636. ; LenzDemo - Performs the demostration.
  637. ; In:
  638. ;   DS      - Data Segment.
  639. ;   PicSeg  - VGA 320x200x256 Picture used for Background.
  640. ;   PalSeg  - Color Palette of the Picture.
  641. ;-----------------------------------------------------------------------------
  642.  
  643. LenzDemo        proc  PicSeg:word,PalSeg:dword
  644.                 local   X:word,Y:word,AddX:word,AddY:word
  645.  
  646.                 mov     ax,13h                  ; sets 320x200x256 mode.
  647.                 int     10h
  648.  
  649.                 call    GenLenz                 ; creates the lenz matrix.
  650.  
  651.                 mov     cx,35                   ; waits 0.5 seconds.
  652.                 call    Delay
  653.  
  654.                 les     si,[PalSeg]             ; sets the palette.
  655.                 call    SetPalette
  656.  
  657.                 mov     dx,[PicSeg]             ; writes the picture
  658.                 call    ShowSpray               ; to the screen.
  659.  
  660.                 mov     [RandSeed],SEED         ; Randomize.
  661.                 mov     [Timer],0
  662.  
  663.                 mov     [X],RADIUS
  664.                 mov     [Y],RADIUS
  665.                 mov     [AddX],3
  666.                 mov     [AddY],2
  667.  
  668. DemoLoop:       call    WaitVRT                 ; Waits VR period.
  669.  
  670.                 mov     ax,[Y]                  ; outputs the lenz
  671.                 sub     ax,RADIUS               ; crystall ball at
  672.                 mov     dx,MAXWIDTH             ; center coordinates (X,Y).
  673.                 mul     dx
  674.                 add     ax,[X]
  675.                 sub     ax,RADIUS
  676.                 mov     di,ax
  677.                 mov     dx,[PicSeg]
  678.                 call    WriteLenz
  679.  
  680. AdjustX:        mov     ax,[X]                  ; adjust the X coord.
  681.                 add     ax,[AddX]
  682.                 cmp     ax,RADIUS
  683.                 jb      ChangeX
  684.                 cmp     ax,MAXWIDTH-RADIUS
  685.                 ja      ChangeX
  686.                 mov     [X],ax
  687.                 jmp     AdjustY
  688. ChangeX:        call    Random
  689.                 shr     ax,15
  690.                 inc     ax
  691.                 cmp     [AddX],0
  692.                 jl      SetAddX
  693.                 neg     ax
  694. SetAddX:        mov     [AddX],ax
  695.  
  696. AdjustY:        mov     ax,[Y]                  ; adjust the Y coord.
  697.                 add     ax,[AddY]
  698.                 cmp     ax,RADIUSI
  699.                 jb      ChangeY
  700.                 cmp     ax,MAXHEIGHT-RADIUSI
  701.                 ja      ChangeY
  702.                 mov     [Y],ax
  703.                 jmp     Continue
  704. ChangeY:        call    Random
  705.                 and     ax,1
  706.                 inc     ax
  707.                 cmp     [AddY],0
  708.                 jl      SetAddY
  709.                 neg     ax
  710. SetAddY:        mov     [AddY],ax
  711.  
  712. Continue:       inc     [Timer]                 ; timeout?
  713.                 cmp     [Timer],TIMEOUT
  714.                 jae     DemoExit
  715.  
  716.                 mov     ah,1                    ; any key pressed?
  717.                 int     16h
  718.                 je      DemoLoop
  719.                 mov     ah,0                    ; flush keyboard.
  720.                 int     16h
  721.                 
  722. DemoExit:       mov     dx,[PicSeg]             ; EmBoss the Piccy.
  723.                 call    DoEmboss
  724.  
  725.                 mov     dx,[PicSeg]             ; SlideDown the Piccy.
  726.                 call    ShowSlide
  727.  
  728.                 mov     cx,70                   ; Sleep a while..
  729.                 call    Delay
  730.  
  731.                 mov     es,[PicSeg]             ; Blanks the picture.
  732.                 xor     di,di
  733.                 mov     cx,MAXWIDTH*MAXHEIGHT
  734.                 xor     ax,ax
  735.                 cld
  736.                 rep     stosb
  737.  
  738.                 mov     dx,[PicSeg]             ; Clears the Screen.
  739.                 call    ShowSpray
  740.  
  741.                 mov     cx,35                   ; waits 0.5 seconds.
  742.                 call    Delay
  743.  
  744.                 mov     ax,03h                  ; restores 80x25x16 mode.
  745.                 int     10h
  746.                 ret
  747.  
  748. LenzDemo        endp
  749.  
  750.  
  751. ;-----------------------------------------------------------------------------
  752. ; Start - Startup Code called from DOS.
  753. ; In:
  754. ;   ES - Program Segment Prefix.
  755. ;-----------------------------------------------------------------------------
  756.  
  757. Start           proc
  758.  
  759.                 mov     ax,@Data
  760.                 mov     ds,ax
  761.                 call    LenzDemo,SEG LenzPic,SEG LenzPal,OFFSET LenzPal
  762.                 mov     ax,4C00h
  763.                 int     21h
  764.  
  765. Start           endp
  766.  
  767.                 end     Start
  768.