home *** CD-ROM | disk | FTP | other *** search
- ;=============================================================================
- ; lenz.asm - Lenz or Crystal Ball Demostration.
- ; File created: 10/18/93
- ; Copyright (c) 1993, Carlos Hasan Last modified: 11/16/93
- ;
- ; Description:
- ; This file implements a Lenz-like Crystall Ball effect using the
- ; VGA 320x200x256 graphics mode and a 320x200x256 picture.
- ;
- ; Portability:
- ; Requires Turbo Assembler 3.2 or better to be assembled.
- ; Dependent on the IBM PC 286 and the VGA graphics card.
- ;
- ; Modifications:
- ; 10/22/93 - Startup Code and Picture/Palette in .OBJ files.
- ; 11/01/93 - Fixed Vertical Strengh Amplification.
- ; 11/16/93 - Added EmBoss and Slide Effect.
- ;=============================================================================
-
- jumps
- .model small,pascal
- .286
-
- dosseg ; used to link like
- .stack 1024 ; an standalone program.
-
- global LenzDemo:proc
- global LenzPal:byte ; in LENZPAL.OBJ file.
- global LenzPic:byte ; in LENZRAW.OBJ file.
-
- ;========================= Demo equates ======================================
- ;
- ; Note: 1. Lenz strengh is computed like: Strengh = 256/Factor
- ; where Factor is the real amplification of the lenz.
- ;
- ; 2. I have used a picture with a gray scale palette at
- ; entries from 128 to 255. Emboss Bright, Depth, MinGray
- ; and MaxGray must be adjusted for others pictures.
- ;
-
- RADIUS equ 52 ; Lenz Radius in pixels.
- RADIUSI equ (15*RADIUS)/20 ; Internal Lenz Radius.
- STRENGH equ 155 ; Lenz Amplify (fixed 8.8).
- MAXWIDTH equ 320 ; VGA 320x200x256 dimensions.
- MAXHEIGHT equ 200
- SEED equ 286Ah ; Random seed for movement.
- BRIGHT equ 150 ; Emboss Bright Factor.
- DEPTH equ 12*256 ; Emboss Depth Factor (8.8).
- MINGRAY equ 128 ; Emboss Min/Max Gray
- MAXGRAY equ 255 ; Scale Range Values.
- TIMEOUT equ 70 * 6 ; at least 6 secs.
-
- ;======================== Demo data ==========================================
-
- .data
-
- LenzTable dw 4*RADIUS*RADIUS dup(?) ; Holds the transformation.
- LenzWidth dw 2*RADIUS dup(?) ; Scanline widths.
- RandSeed dw ? ; Random Seed.
- Timer dw ? ; Timer counter.
-
- ;======================== Demo Routines ======================================
-
- .code
-
- ;-----------------------------------------------------------------------------
- ; Random - Returns a random number of 16 bits, modified version of the
- ; ripped System unit random routine of the Borland Pascal 7.0.
- ; Out:
- ; AX - random value.
- ; Modified:
- ; AX, DX, Flags.
- ;-----------------------------------------------------------------------------
-
- Random proc near
-
- mov ax,[RandSeed]
- mov dx,8405h
- mul dx
- inc ax
- mov [RandSeed],ax
- ret
-
- Random endp
-
- ;-----------------------------------------------------------------------------
- ; WaitVRT - Waits the next VGA Vertical Retrace Period.
- ;-----------------------------------------------------------------------------
-
- WaitVRT proc near
-
- mov dx,3DAh
- WaitVR1: in al,dx
- test al,8
- jne WaitVR1
- WaitVR2: in al,dx
- test al,8
- je WaitVR2
- ret
-
- WaitVRT endp
-
- ;-----------------------------------------------------------------------------
- ; Delay - Sleeps during any amount of time. Uses the VGA Vertical retrace.
- ; In:
- ; CX - Number of ticks to speed (ticks at 70Hz).
- ;-----------------------------------------------------------------------------
-
- Delay proc near
-
- DelayLoop: call WaitVRT
- loop DelayLoop
- ret
-
- Delay endp
-
- ;-----------------------------------------------------------------------------
- ; SetPalette - Sets the VGA color palette.
- ; In:
- ; ES:SI - Palette segment address.
- ;-----------------------------------------------------------------------------
-
- SetPalette proc near
-
- push ds
- mov ax,es
- mov ds,ax
- mov dx,3C8h
- xor al,al
- out dx,al
- inc dx
- mov cx,768
- cld
- rep outsb
- pop ds
- ret
-
- SetPalette endp
-
- ;-----------------------------------------------------------------------------
- ; ShowSpray - Writes a picture on the scren using a Spray-like effect.
- ; In:
- ; DX - Picture source segment.
- ;-----------------------------------------------------------------------------
-
- ShowSpray proc near
-
- push ds
- push es
-
- mov ds,dx
- xor si,si
- mov ax,0A000h
- mov es,ax
-
- xor cx,cx
- SprayLoop: push cx
- xor bx,bx
- SprayLine: push bx
- mov ah,cs:[RandTable+bx]
- mov bx,cx
- mov al,cs:[RandTable+bx]
- mov bx,ax
- mov di,ax
- mov al,ds:[si+bx]
- mov es:[di],al
- pop bx
- inc cl
- inc bl
- jne SprayLine
- pop cx
- inc cl
- jne SprayLoop
-
- pop es
- pop ds
- ret
-
- RandTable label byte
- db 83, 8, 18, 177, 13, 241, 149, 157
- db 75, 248, 254, 23, 16, 66, 207, 31
- db 211, 183, 80, 242, 218, 27, 15, 128
- db 94, 98, 4, 36, 139, 110, 85, 230
- db 212, 26, 12, 249, 169, 233, 200, 150
- db 95, 114, 130, 167, 202, 187, 76, 145
- db 62, 117, 115, 190, 209, 42, 185, 224
- db 129, 104, 108, 192, 174, 137, 44, 41
- db 141, 53, 179, 81, 181, 57, 147, 210
- db 50, 134, 156, 125, 133, 126, 106, 162
- db 20, 59, 84, 0, 151, 143, 101, 215
- db 68, 246, 189, 197, 99, 213, 112, 144
- db 28, 235, 240, 90, 154, 56, 138, 165
- db 19, 166, 159, 92, 127, 208, 105, 118
- db 119, 153, 191, 184, 87, 70, 9, 164
- db 60, 252, 96, 3, 171, 38, 136, 14
- db 7, 160, 71, 146, 102, 229, 227, 43
- db 221, 182, 217, 30, 131, 219, 61, 180
- db 195, 245, 109, 203, 24, 49, 170, 247
- db 46, 148, 122, 250, 173, 107, 255, 194
- db 6, 37, 93, 22, 168, 97, 193, 5
- db 51, 223, 116, 86, 1, 89, 121, 243
- db 140, 220, 39, 222, 65, 55, 17, 54
- db 175, 206, 214, 155, 142, 163, 25, 188
- db 178, 11, 204, 135, 201, 238, 79, 132
- db 198, 40, 21, 45, 237, 253, 152, 74
- db 32, 111, 52, 47, 236, 2, 176, 239
- db 234, 58, 100, 91, 172, 73, 82, 205
- db 34, 88, 78, 231, 232, 225, 48, 251
- db 67, 123, 244, 29, 216, 64, 196, 69
- db 199, 33, 72, 35, 10, 63, 161, 228
- db 113, 158, 120, 103, 124, 186, 226, 77
-
- ShowSpray endp
-
- ;-----------------------------------------------------------------------------
- ; DoEmBoss - Do the EmBoss effect into a 320x200x256 picture.
- ; In:
- ; DX - Picture Source Segment.
- ;-----------------------------------------------------------------------------
-
- DoEmboss proc
-
- pusha
- push ds
-
- mov ds,dx ; DS:SI = source image.
- xor si,si
- xor cx,cx
- EmBossLine: push cx ; Y= 0..198
- xor bx,bx
- EmBossLoop: push bx ; X= 0..318
- add bx,cx
- xor dh,dh
- mov dl,[si+bx]
- mov ax,dx
- mov dl,[si+bx+MAXWIDTH+1]
- sub ax,dx
- mov dx,DEPTH ; EmBoss Depth Factor.
- imul dx
- mov al,ah
- mov ah,dl
- add ax,BRIGHT
- cmp ax,MINGRAY ; Check Color Range.
- jge EmbossHigh
- mov ax,MINGRAY
- EmbossHigh: cmp ax,MAXGRAY
- jle EmbossLow
- mov ax,MAXGRAY
- EmbossLow: mov [si+bx],al
- pop bx
- inc bx
- cmp bx,MAXWIDTH-2
- jbe EmbossLoop
- pop cx
- add cx,MAXWIDTH
- cmp cx,MAXWIDTH*(MAXHEIGHT-2)
- jbe EmbossLine
-
- pop ds
- popa
- ret
-
- DoEmboss endp
-
- ;-----------------------------------------------------------------------------
- ; ShowSlide - Shows a 320x200x256 picture using a Slide Effect.
- ; In:
- ; DX - Piccy Source Segment.
- ;-----------------------------------------------------------------------------
-
- ShowSlide proc
- local Level:word:MAXWIDTH,Weight:word:MAXWIDTH,\
- LevelPtr:word,WeightPtr:word
-
- pusha
- push ds
- push es
-
- mov ds,dx ; DS:SI = Source Picture.
- xor si,si
-
- mov ax,ss
- mov es,ax
-
- lea di,[Level] ; Clear Slide Row Levels.
- mov cx,MAXWIDTH
- cld
- xor ax,ax
- rep stosw
-
- lea di,[Weight] ; Clear Slide Row Weights.
- mov cx,MAXWIDTH
- cld
- xor ax,ax
- rep stosw
-
- mov ax,0A000h
- mov es,ax
-
- SlideLoop: call WaitVRT
- lea bx,[Level] ; Loads Level Pointer.
- mov [LevelPtr],bx
-
- lea bx,[Weight] ; Loads Weight Pointer.
- mov [WeightPtr],bx
-
- xor cx,cx ; For Each Column:
- xor dx,dx
-
- SlideInner: mov bx,[LevelPtr] ; Level[Col] < 320*200? Skip.
- mov ax,ss:[bx]
- cmp ax,MAXWIDTH*MAXHEIGHT
- jae SlideContinue
-
- inc dx ; Sets Flag.
-
- mov bx,[WeightPtr] ; Weight[Col] <> 0?
- mov ax,ss:[bx] ; Yes, Decrease.
- test ax,ax ; No, Slide Down Row.
- jz SlideDown
- dec ax
- mov ss:[bx],ax
- jmp SlideContinue
-
- SlideDown: mov bx,[LevelPtr] ; Level[Col] += 320
- mov ax,ss:[bx]
- add ax,MAXWIDTH
- mov ss:[bx],ax
- add ax,cx ; DI = Col + Level[Col]
- mov di,ax
- mov bx,di ; Sets New Row Weight:
- mov al,es:[di+MAXWIDTH] ; W=ABS(VMEM[DI+320]-VMEM[DI])
- sub al,es:[di]
- jge SlidePos
- neg al
- SlidePos: xor ah,ah
- mov bx,[WeightPtr]
- mov ss:[bx],ax
-
- mov bx,di ; Put Pixel at (Col,Level[Col])
- mov al,ds:[si+bx]
- mov es:[di],al
-
- SlideContinue: add [LevelPtr],2 ; Next Column.
- add [WeightPtr],2
- inc cx
- cmp cx,MAXWIDTH
- jb SlideInner
-
- test dx,dx ; Screen 100% filled?
- jnz SlideLoop ; No, Repeat.
-
- pop es
- pop ds
- popa
- ret
-
- ShowSlide endp
-
-
- ;-----------------------------------------------------------------------------
- ; GenLenz - Renders the Transformation matrix used during animation.
- ;
- ; Note: The square root is calculated using the Newton iteration
- ; aproximation algorithm:
- ; y² + (r² - x²)
- ; y² ≡ r² - x² ══ y ≈ ────────────────
- ; 2y
- ;
- ; We performs only one iteration using a initial «y» value
- ; near to the real square root wanted.
- ;-----------------------------------------------------------------------------
-
- GenLenz proc near
- local X:word,Y:word,R:word,Dist:Word,AddX:word,AddY:word
-
- mov ax,ds
- mov es,ax
- cld
-
- xor ax,ax ; Fills the whole rectangle
- lea di,[LenzTable] ; matrix with a linear
- mov cx,2*RADIUS ; transformation.
- MakLinLoop: push ax
- push cx
- mov cx,2*RADIUS
- MakLinRow: stosw
- inc ax
- loop MakLinRow
- pop cx
- pop ax
- add ax,MAXWIDTH
- loop MakLinLoop
-
- mov [X],RADIUS ; makes the scanlines
- mov [Y],0 ; widths of the lenz
- MakWidth: cmp [Y],RADIUS ; with radius RADIUS.
- jge MakXWidth
- mov ax,[X]
- mov bx,RADIUS ; LenzWidth[Radius+Y] = X
- add bx,[Y]
- shl bx,1
- mov [LenzWidth+bx],ax
- mov bx,RADIUS ; LenzWidth[Radius-Y-1] = X
- sub bx,[Y]
- dec bx
- shl bx,1
- mov [LenzWidth+bx],ax
- mov ax,[Y] ; X² = Radius² - Y²
- imul ax
- mov bx,ax
- mov ax,[X]
- imul ax
- sub ax,bx
- add ax,RADIUS*RADIUS
- sar ax,1
- cwd
- mov bx,[X]
- idiv bx
- mov [X],ax
- inc [Y] ; Y = Y+1
- jmp MakWidth
- MakXWidth:
-
-
- mov [X],RADIUSI ; Makes the transformation
- mov [Y],0 ; for the Lenz of radius
- MakLoop: cmp [Y],RADIUSI ; RADIUSY. Notice that
- jge MakExit ; this lets a border
- ; used for restoring the
- ; background while moving
- ; the lenz into the screen.
-
- mov ax,[X] ; compute the scanline
- mov dx,6 ; width adjusting with
- imul dx ; an aspect ratio of 6/5.
- mov bx,5
- idiv bx
- mov [R],ax
-
- mov [Dist],0
- mov [AddX],0
- mov [AddY],ax
-
- MakLine: mov ax,[R]
- cmp [AddX],ax
- jge MakLineBreak
-
- ; si = @LenzTable[0,RADIUS-Y-1]
-
- lea si,[LenzTable]
- mov ax,RADIUS
- sub ax,[Y]
- dec ax
- imul ax,2*RADIUS
- add si,ax
- shl si,1
-
- ; di = @LenzTable[0,RADIUS+Y]
-
- lea di,[LenzTable]
- mov ax,RADIUS
- add ax,[Y]
- imul ax,2*RADIUS
- add di,ax
- shl di,1
-
- ; Lenz[RADIUS+AddX,RADIUS-Y-1] = RADIUS+Hi(Dist) +
- ; MAXWIDTH * (RADIUS-1-STRENGH*Y)
-
- mov bx,RADIUS
- add bx,[AddX]
- shl bx,1
- mov ax,[Y]
- imul ax,STRENGH
- sar ax,8
- imul ax,MAXWIDTH
- neg ax
- add ax,RADIUS+MAXWIDTH*(RADIUS-1)
- mov dx,[Dist]
- shr dx,8
- add ax,dx
- mov [si+bx],ax
-
- ; Lenz[RADIUS-AddX-1,RADIUS-Y-1] = RADIUS-Hi(Dist)-1+
- ; MAXWIDTH * (RADIUS-1-STRENGH*Y)
-
- mov bx,RADIUS
- sub bx,[AddX]
- dec bx
- shl bx,1
- mov ax,[Y]
- imul ax,STRENGH
- sar ax,8
- imul ax,MAXWIDTH
- neg ax
- add ax,RADIUS+MAXWIDTH*(RADIUS-1)
- mov dx,[Dist]
- shr dx,8
- sub ax,dx
- dec ax
- mov [si+bx],ax
-
- ; LenzTable[RADIUS+AddX,RADIUS+Y] = RADIUS+Hi(Dist)+
- ; MAXWIDTH * (RADIUS + STRENGH*Y)
-
- mov bx,RADIUS
- add bx,[AddX]
- shl bx,1
- mov ax,[Y]
- imul ax,STRENGH
- sar ax,8
- imul ax,MAXWIDTH
- add ax,RADIUS+MAXWIDTH*RADIUS
- mov dx,[Dist]
- shr dx,8
- add ax,dx
- mov [di+bx],ax
-
- ; LenzTable[RADIUS-AddX-1,RADIUS+Y] = RADIUS-Hi(Dist)-1+
- ; MAXWIDTH * (RADIUS+STRENGH*Y)
-
- mov bx,RADIUS
- sub bx,[AddX]
- dec bx
- shl bx,1
- mov ax,[Y]
- imul ax,STRENGH
- sar ax,8
- imul ax,MAXWIDTH
- add ax,RADIUS+MAXWIDTH*RADIUS
- mov dx,[Dist]
- shr dx,8
- sub ax,dx
- dec ax
- mov [di+bx],ax
-
- ; Dist = Dist + (Strengh*Radius)/dY
-
- mov ax,STRENGH*RADIUS
- cwd
- mov bx,[AddY]
- idiv bx
- add [Dist],ax
-
- mov ax,[AddY] ; dY² = R² - dX²
- imul ax
- mov bx,ax
- mov ax,[AddX]
- imul ax
- sub bx,ax
- mov ax,[R]
- imul ax
- add ax,bx
- sar ax,1
- cwd
- mov bx,[AddY]
- idiv bx
- mov [AddY],ax
- inc [AddX] ; dX = dX+1
- jmp MakLine
-
- MakLineBreak: mov ax,[X] ; X² = Radius'² - Y²
- imul ax
- mov bx,ax
- mov ax,[Y]
- imul ax
- sub bx,ax
- mov ax,RADIUSI*RADIUSI
- add ax,bx
- sar ax,1
- cwd
- mov bx,[X]
- idiv bx
- mov [X],ax
- inc [Y] ; Y = Y+1
- jmp MakLoop
- MakExit: ret
-
- GenLenz endp
-
- ;-----------------------------------------------------------------------------
- ; WriteLenz - Writes the Lenz using the transformation matrix.
- ; In:
- ; DI - Starting offset location of the lenz.
- ; DX - Virtual picture used like background.
- ;-----------------------------------------------------------------------------
-
- WriteLenz proc near
-
- push bp
- mov ax,0A000h
- mov es,ax
- lea bx,[LenzTable]
- lea si,[LenzWidth]
- mov bp,di
- mov cx,2*RADIUS
- cld
- WriteLoop: push bx
- push cx
- push si
- push di
- cmp di,MAXWIDTH*MAXHEIGHT
- jae WriteBreak
- mov cx,[si] ; gets the scanline width.
- mov ax,RADIUS
- sub ax,cx
- add di,ax
- add bx,ax
- add bx,ax
- WriteLine: push es
- mov es,dx
- mov si,[bx]
- mov al,es:[bp+si]
- mov si,[bx+2]
- mov ah,es:[bp+si]
- add bx,4
- pop es
- stosw
- loop WriteLine
- WriteBreak: pop di
- pop si
- pop cx
- pop bx
- add bx,4*RADIUS
- add si,2
- add di,MAXWIDTH
- loop WriteLoop
- pop bp
- ret
-
- WriteLenz endp
-
-
- ;-----------------------------------------------------------------------------
- ; LenzDemo - Performs the demostration.
- ; In:
- ; DS - Data Segment.
- ; PicSeg - VGA 320x200x256 Picture used for Background.
- ; PalSeg - Color Palette of the Picture.
- ;-----------------------------------------------------------------------------
-
- LenzDemo proc PicSeg:word,PalSeg:dword
- local X:word,Y:word,AddX:word,AddY:word
-
- mov ax,13h ; sets 320x200x256 mode.
- int 10h
-
- call GenLenz ; creates the lenz matrix.
-
- mov cx,35 ; waits 0.5 seconds.
- call Delay
-
- les si,[PalSeg] ; sets the palette.
- call SetPalette
-
- mov dx,[PicSeg] ; writes the picture
- call ShowSpray ; to the screen.
-
- mov [RandSeed],SEED ; Randomize.
- mov [Timer],0
-
- mov [X],RADIUS
- mov [Y],RADIUS
- mov [AddX],3
- mov [AddY],2
-
- DemoLoop: call WaitVRT ; Waits VR period.
-
- mov ax,[Y] ; outputs the lenz
- sub ax,RADIUS ; crystall ball at
- mov dx,MAXWIDTH ; center coordinates (X,Y).
- mul dx
- add ax,[X]
- sub ax,RADIUS
- mov di,ax
- mov dx,[PicSeg]
- call WriteLenz
-
- AdjustX: mov ax,[X] ; adjust the X coord.
- add ax,[AddX]
- cmp ax,RADIUS
- jb ChangeX
- cmp ax,MAXWIDTH-RADIUS
- ja ChangeX
- mov [X],ax
- jmp AdjustY
- ChangeX: call Random
- shr ax,15
- inc ax
- cmp [AddX],0
- jl SetAddX
- neg ax
- SetAddX: mov [AddX],ax
-
- AdjustY: mov ax,[Y] ; adjust the Y coord.
- add ax,[AddY]
- cmp ax,RADIUSI
- jb ChangeY
- cmp ax,MAXHEIGHT-RADIUSI
- ja ChangeY
- mov [Y],ax
- jmp Continue
- ChangeY: call Random
- and ax,1
- inc ax
- cmp [AddY],0
- jl SetAddY
- neg ax
- SetAddY: mov [AddY],ax
-
- Continue: inc [Timer] ; timeout?
- cmp [Timer],TIMEOUT
- jae DemoExit
-
- mov ah,1 ; any key pressed?
- int 16h
- je DemoLoop
- mov ah,0 ; flush keyboard.
- int 16h
-
- DemoExit: mov dx,[PicSeg] ; EmBoss the Piccy.
- call DoEmboss
-
- mov dx,[PicSeg] ; SlideDown the Piccy.
- call ShowSlide
-
- mov cx,70 ; Sleep a while..
- call Delay
-
- mov es,[PicSeg] ; Blanks the picture.
- xor di,di
- mov cx,MAXWIDTH*MAXHEIGHT
- xor ax,ax
- cld
- rep stosb
-
- mov dx,[PicSeg] ; Clears the Screen.
- call ShowSpray
-
- mov cx,35 ; waits 0.5 seconds.
- call Delay
-
- mov ax,03h ; restores 80x25x16 mode.
- int 10h
- ret
-
- LenzDemo endp
-
-
- ;-----------------------------------------------------------------------------
- ; Start - Startup Code called from DOS.
- ; In:
- ; ES - Program Segment Prefix.
- ;-----------------------------------------------------------------------------
-
- Start proc
-
- mov ax,@Data
- mov ds,ax
- call LenzDemo,SEG LenzPic,SEG LenzPal,OFFSET LenzPal
- mov ax,4C00h
- int 21h
-
- Start endp
-
- end Start
-