;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ;³ C - B L A S T - by Wessko's Melodyes ³ ;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ;³(++about the name): You see, the palette is blue, gray and yellow and ³ ;³the effect is like explosion-that's why i named it "C-BLAST". ³ ;³(++about the code): Made:5.06.2000 compiled with TASM 3.1. Requires ³ ;³processor 286. Basically it introduces three effects: ³ ;³1. Blast/explosion/plasma/whatever. ³ ;³2. Fullscreen blur (standard matrix, not buffered). ³ ;³3. Changing-the-color balls. ³ ;³(++about the size): The first working one used FPU and was 210 bytes ³ ;³(with no palette initialising) and then 264 bytes (added palette&optimi-³ ;³sations). I assumed i won't be able to make it less than 256 bytes and ³ ;³so decided to make it 512 bytes and to add more effects. ³ ;³ However, the third effect took up more than 150 byte machine code ³ ;³and so the intro was 610 bytes. After making major optimisations (adding³ ;³cycles, testing, summing, getting nervous,making code hard-to-understand³ ;³and so...) it become 507 bytes. I added the string "Virus" in the ³ ;³beginning (recommend U to open blast.com with hex-editor :)). And it ³ ;³became 512 bytes :)). ³ ;³Size history: 210,240,270,264 // 610,604,600,582,520,508,507,512 ³ ;³optimisation (max)=610-507=103 bytes (16.8%). ³ ;³I know it could be optimised much more but that will make the code just ³ ;³bullshit. Even now i like more the 610 byte version,'coz it looks much ³ ;³better/simplier/undersandible. ³ ;³(++speed ): The intro should work fast enough on any machine-requires no³ ;³FPU. Even on my Pentium I 120 MHz the 'Blast' is still 'Blast' :) ³ ;³ Some info for those, who still haven't heard about me: ³ ;³Wessko's Melodyes' members: ³ ;³ Duke Nukem - code/gfx/whatever = vessko@gotmail.com ³ ;³Don't hesitate to email me if you want. ³ ;³ ³ ;³Now, here's the source (it's junked enough and that's why i ADDED ³ ;³comments in it:) ³ ;³ ³ ;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; IDEAL ;Compile with TASM MODEL Tiny ;...of course... P286N ;286 required (saves 5-6 bytes code) ;EQUATES eh equ 30 ;ball's diameter el equ 15 ;ball's radius _320eh equ 290 ;320-eh _200eh equ 170 ;200-eh DATASEG bobnum dw 2000 ;constant, should be about eh*eh*2 for the blast x1 dw 50 ;for the third effect-initial xcoord of the first ball x2 dw 270 ;xcoord of the second ball y1 dw 50 ;... y2 dw 30 x1inc dw 2 ;for each frame: x1:=x1+x1inc x2inc dw -1 ;x2:=x2+x2inc y1inc dw 1 ;y1:=y1+y1inc y2inc dw 2 ;y2:=y2+y2inc rseed dw ? ;random seed p db 768 DUP (?) ;palette table (256 colors * 3 bytes for color) CODESEG org 100h ;set origin for the .com file Start: jmp afterproc ;unconditional jump to main program db "(r)Virus(r)";open the file with text editor ;--------------------------------- ;PROC Random ;-gets the value in ax and returns ;-(in ax) number between 1 and ax ;-example: ;-mov ax,200 ;-call random ;-...ax will contain a number 1ö200 ; ;INPUT: ;AX=max output ; ;OUTPUT: ;AX=random number ; ;NOTE: rseed (word) should be in ;the dataseg. ;---------------------------------- PROC RANDOM push bx ;save some registers push ax in al,40h ;get the timer in ax mov ah,al mov bx,ax ;and in bx also mov ax,[rseed] ;rseed contains the previous random number add ax,5543 ;this is not kind a special number-i just put it for accurancy and true randomisation imul bx ;for example ax=A63C,bx=1C1C. Ax will become BE90h rcl ax,3 ;now ax is F485h mov [rseed],ax ;this random number is stored in rseed for next random pop bx ;bx=max output (see above) @arkanoid3d: cmp ax,bx ;while ax>bx jbe @pop3d sub ax,bx ;do ax=ax-bx jmp @arkanoid3d ;test agin @pop3d: pop bx ;random number 1ömaxoutput stored in ax ret ;work done ENDP Random ;----------------------------- ;PROC absax ;-gives ax it's absolute value ;-assumes ax is integer ; ;INPUT: ;ax -> -32768ö32767 ;OUTPUT: ;ax -> 0ö32767 ;------------------------------ PROC absax test ax,8000h ;is below zero? jz short @axend ;no-we won'e do anything. neg ax ;yes? let's change it's sign inc ax ;ax=-ax (standard algorithm <---) @axend: ret ;all work done ENDP absax ;---------------------------------------------- ;PROC Bobinc ;-increases the color in an area in ;-the Videomemory ;INPUT: ;ax=x (centre of the ball) ;bx=y (centre if the ball) ;NOTE: ; I used the following algorithm: ; color to increase=bobnum/((ax-cl)ý+(bx-ch)ý); ;---------------------------------------------- PROC Bobinc mov ch,eh ;ch=on which line we are xchg ax,bx ;ax=y;bx=x sub ax,el ;make initial offset for drawing sub bx,el ;in di (di=y*320+x) push bx ;bx=x;save x mov bx,320 ;prepare for multiply imul bx ;ax=y ==> ax=y*320 pop di ;di=x add di,ax ;and add the stuff;) @aloop: mov cl,eh ;prepare cycle @bloop: mov ax,el ;ax=el-cl(horizontal distance) push cx xor ch,ch sub ax,cx pop cx call absax ;ax=abs(ax) mov bx,ax ;bx=ax imul bx ;ax=axý mov dx,ax ;dx=ax mov ax,el ;ax=el-ch (vertical distance) push cx xor cl,cl xchg ch,cl sub ax,cx pop cx call absax ;ax=abx(ax) mov bx,ax ;bx=ax push dx ;during imul dx changes. And we need dx, so push it imul bx ;ax=axý pop bx ;what was in dx now is in bx (in dx was previous axý) add bx,ax ;(hr=horizontal dist.;vr=vertical d.) bx=hrý+vrý cmp bx,100 ;<== this is needed to make ja @vda ;the result of ax=bobnum/bx at most 20 mov bx,100 ;if we increase pixels with more than 20 @vda: ;we'll lost the cute effect mov ax,[bobnum] ;ax=bobnum/(hrý+vrý) div bx ;we're sure that bx is at least 100 add [byte es:di],al ;all this procedure for a single pixel!!!!! inc di ;next pixel dec cl ;if the resolution was greater, the intro would work jnz @bloop ;quite slower add di,_320eh ;change the row dec ch ;and decrease row pointer jnz @aloop ;while ch>0 do ... ret ;all done!!! ENDP Bobinc ;---------------------------- ;PROC CH(ange)Sign ;-changes the sign of a word ;-pointed by [ds:si+8] ;INPUT: ;-ds:si points a variable ;-ds:si+8 points a variable's ;incremental ;OUTPUT: ;-none ;---------------------------- PROC Chsign add si,8 ;why so? You'll see mov bx,[ds:si] ;simple algorythm: sub [ds:si],bx ;x-2x=-x sub [ds:si],bx ; sub si,8 ;reset si at input value ret ;the word in ds:si+8 is changed the sign ENDP Chsign afterproc: ;MAIN PROGRAM: mov ax,13h ;switch to videomode int 10h ;320x200x8-bit color in al,40h ;get timer for random seed mov ah,al mov [rseed],ax mov di,offset p ;ready to fill the palette table mov cx,768 ;768 bytes mov ax,0 ;filled with 0 cld ;clear dir flag rep stosb ;and fill the stuff lea di,[p+192] ;another pass mov cx,128 mov ax,0 @r20: stosb ;..are gradient black-yellow stosb test cx,1 ;if the number of color is even... jz @fm inc al ;...increase the Red&Green values @fm: inc di loop @r20 mov al,63 ;63 colours... mov cx,63 @r30: stosb ;gradient yellow-black stosb inc di dec al loop @r30 mov di,offset p ;one pass add di,2 ;for the blue values mov al,0 mov cx,63 ;63 colours-gradient black-blue @b10: stosb inc al add di,2 loop @b10 mov cx,128 ;and 128 colours-gradient blue-black @b20: mov ax,cx dec ax shr ax,1 stosb add di,2 loop @b20 mov dx,3c8h ;ready to initialise the palette xor al,al out dx,al inc dx mov cx,256 ;256 colours mov si,offset p ;stored in the table @initpalette: lodsb ;get Red value from table out dx,al ;send it to videocard lodsb ;get Green... out dx,al ;...put green lodsb ;get blue out dx,al ;...put blue loop @initpalette ;and so-256 times mov ax,0a000h ;load in es - videosegment mov es,ax @mainloop: mov ax,_200eh ;get random Y call random mov bx,el ;Should be >el and <200-el add bx,ax mov ax,_320eh ;get random X call random add ax,el ;Should be >el and <200-el call bobinc ;increase ball area, poited by ax&bx... mov ah,0bh ;DOS function:check keyboard state int 21h ;call DOS cmp al,0 ;is key pressed? je @mainloop ;no- doitagain mov ah,7 ;yes - read that key int 21h ;note: if we terminated the program here,the intro would be about 260 bytes mov cx,40 ;40 times.... xor bx,bx xor ax,ax @blloop: ;....blur the screen xor di,di push cx ;inline cycle - save cx mov cx,64000 ;screen is 64000 pixels @b1a: ;standard blur matrix: mov al,[es:di-1] ; ³ mov bl,[es:di+1] ; ÄÄ ÄÄ add ax,bx ; ³ mov bl,[es:di+320] ; add ax,bx ;(each point is the sum of it's neighbours divided mov bl,[es:di-320] ; by 4) add ax,bx shr ax,2 ;divide by 4 stosb ;and put it on screen loop @b1a ;and so 64000(!!) times pop cx ;the another cycle mov ah,0bh ;before cycling, check for keypress int 21h cmp al,0 ;if keypressed... jne @blured ;...jump to @blured xor ax,ax ;else : loop @blloop ;do it again @blured: cmp al,0 ;OK. Blur operation completed. But how? je @purged ;if not by user keypress-we're ready, jump there mov ah,7 ;else clear the keyboard buffer... int 21h ;...using DOS @purged: mov [bobnum],200 ;in this effect we'll increase 20 times slower mov ax,[x1] ;prepare the first ball mov bx,[y1] call bobinc ;and call the preocedure mov ax,[x2] mov bx,[y2] call bobinc mov si,offset x1 ;now - we should check mov cx,4 @wedc1: cmp [word ds:si],el jnb @wdone call chsign @wdone: add si,2 loop @wedc1 mov si,offset x1 mov cx,2 @xedc1: cmp [word ds:si],_320eh jna @e20 call chsign @e20: add si,2 loop @xedc1 mov cx,2 @xedc2: cmp [word ds:si],_200eh jna @e80 call chsign @e80: add si,2 loop @xedc2 mov cx,4 mov si,offset x1inc @e144: lodsw add [ds:si-10],ax loop @e144 mov ah,0bh int 21h cmp al,0 jne @ended jmp @purged @ended: mov ah,7 int 21h mov ax,3 int 10h mov ax,4c00h int 21h END Start