;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; BOBS.ASM ; ; Shadebobs. ; FRiAR TuCK [PCi] ; ; This is how the "shadebobs" in a lot of demos are done. Many other effects ; use this type of technique, I figured it out while trying to duplicate the ; lines in the beginning of Renaissance's "Amnesia". ; ; Simple stuff.. Put together a palette with a fade in it, and then go around ; incrementing the value in the pixel. I use a block of BOBSIZE*BOBSIZE size. ; XMove and YMove are equates to move the block, but you can use a sine ; routine, anything.. All you do is put the X and Y coords for the block in ; [_x] and [_y], and then call _plotbob. Also you must call _init once in ; the beginning to set the screen and palette. Don't trust anything with ; these routines, because they're quick hacks. They destroy all registers, ; except the BP and SP regs. ; ; This is made into a .COM file, so all data work is in the same segment... ; For the uneducated, to create from this source: ; ; TASM bobs ; TLINK /t bobs ; ; Enjoy! ; -FT ; ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; mumbo jumbo DOSSEG .MODEL TINY .CODE .386 ORG 100h ASSUME CS:@CODE, DS:@CODE ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; GENERAL EQUATES ; ;============================================================================== ; Try different numbers here. BOBBER is the increment in color each time. BOBSIZE equ 51 XMOVE equ 19 YMOVE equ 12 BOBBER equ 4 ; Comment the next line for a neat effect. ; FULLSCRN equ 1 ; Lets make this a .COM file. START: jmp begin ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; GENERAL DATA VARS ; ;============================================================================== _x dw 0 _y dw 0 xm db XMOVE ym db YMOVE ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; PALETTE VALUES ; ;============================================================================== colors db 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0 db 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0 db 0, 8, 0, 0, 9, 0, 0,10, 0, 0,11, 0 db 0,12, 0, 0,13, 0, 0,14, 0, 0,15, 0 ; 16 db 0,16, 0, 0,17, 0, 0,18, 0, 0,19, 0 db 0,20, 0, 0,21, 0, 0,22, 0, 0,23, 0 db 0,24, 0, 0,25, 0, 0,26, 0, 0,27, 0 db 0,28, 0, 0,29, 0, 0,30, 0, 0,31, 0 ; 32 db 0,32, 0, 0,33, 0, 0,34, 0, 0,35, 0 db 0,36, 0, 0,37, 0, 0,38, 0, 0,39, 0 db 0,40, 0, 0,41, 0, 0,42, 0, 0,43, 0 db 0,44, 0, 0,45, 0, 0,46, 0, 0,47, 0 ; 48 db 0,48, 0, 0,49, 0, 0,50, 0, 0,51, 0 db 0,52, 0, 0,53, 0, 0,54, 0, 0,55, 0 db 0,56, 0, 0,57, 0, 0,58, 0, 0,59, 0 db 0,60, 0, 0,61, 0, 0,62, 0, 0,63, 0 ; 64 db 0,63, 0, 1,63, 1, 2,63, 2, 3,63, 3 db 4,63, 4, 5,63, 5, 6,63, 6, 7,63, 7 db 8,63, 8, 9,63, 9,10,63,10,11,63,11 db 12,63,12,13,63,13,14,63,14,15,63,15 ; 80 db 16,63,16,17,63,17,18,63,18,19,63,19 db 20,63,20,21,63,21,22,63,22,23,63,23 db 24,63,24,25,63,25,26,63,26,27,63,27 db 28,63,28,29,63,29,30,63,30,31,63,31 ; 96 db 32,63,32,33,63,33,34,63,34,35,63,35 db 36,63,36,37,63,37,38,63,38,39,63,39 db 40,63,40,41,63,41,42,63,42,43,63,43 db 44,63,44,45,63,45,46,63,46,47,63,47 ; 112 db 48,63,48,49,63,49,50,63,50,51,63,51 db 52,63,52,53,63,53,54,63,54,55,63,55 db 56,63,56,57,63,57,58,63,58,59,63,59 db 60,63,60,61,63,61,62,63,62,63,63,63 ; 128 ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; MACROS ; ; I use these macros because they make the code a little more readable. ; Nuthin' fancy, just nicer lookin'. ; ;============================================================================== ; @grmode = set 320x200x256c mode @grmode macro mov ax,0013h int 10h endm ; @textmode = set 80x25x16c mode @textmode macro mov ax,0003h int 10h endm ; @terminate = DOS Terminate. @terminate macro mov ax,4C00h int 21h endm ; @keypressed - check for keypress, zero flag set if yes. @keypressed macro mov ah,1 ;check to see if a key's been pressed int 16h endm ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; CODE BEGINS HERE ; ;============================================================================== ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; _INIT ; ; pops the screen into graphics mode, and writes the palette. ; ;============================================================================== _init proc near @grmode xor ax,ax mov dx,03C8h ; Tell the VGA card that the out dx,al ; Palette's comin'. mov dx,03C9h ; The values go here mov cx,384 ; 3*(128 colors) mov si,offset colors ; Point to the table cld in01: lodsb ; In out dx,al ; and Out dec cx ; NEXT! cmp cx,00h ; done? jne in01 ; nope ; std ; backwards dec si ; comment this line for green white and ; blue mov cx,384 ; in02: lodsb ; out dx,al ; dec cx ; cmp cx,00h ; jne in02 ; cld ; Forwards _init endp ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; _PLOTBOB ; ; Plots a square of [BOBSIZE x BOBSIZE], upper left at [_x,_y] ; ;============================================================================== _plotbob proc near mov di,word ptr [_x] ; DI = x mov cx,di ; CX = x jmp short pb07 ; compare and continue pb01: ; mov si,word ptr [_y] ; SI = y jmp short pb06 ; same thing pb02: ; mov ax,si ; AX = y ; ; This next stuff is conditional compile, if FULLSCRN is defined ; the bob will use the full screen, otherwise it clips ; ifdef fullscrn cmp ax,200 ; AX > 200? jl pb03 ; nope, skip this sub ax,200 ; AX = y - 200 endif pb03: mov dx,320 ; imul dx ; AX = (y|y-200) * 320 ifdef fullscrn cmp cx,320 ; CX > 320? jl pb05 ; nope, skip next line sub ax,320 ; AX = AX - 320 endif pb05: add ax,cx ; AX = (y*320)+x mov bx,ax ; ES:[AX] is illegal, so use BX mov dx,0A000h ; mov es,dx ; ES = segment 0A000 - the screen mem add byte ptr es:[bx],BOBBER ; PLOT THE POINT! inc si ; y = y + 1 pb06: mov ax,word ptr [_y] ; SI > y+BOBSIZE? add ax,BOBSIZE ; cmp ax,si jg short pb02 ; nope, NEXT! inc cx ; x = x + 1 pb07: mov ax,di ; add ax,BOBSIZE ; CX > x+BOBSIZE? cmp ax,cx ; jg short pb01 ; nope, next X. ret _plotbob endp ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ; ; PROGRAM ENTRY POINT ; ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° begin: call _init mov [_x],0 mov [_y],0 ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° bg01: add [_x],XMOVE ; Increment the X and Y locations add [_y],YMOVE ; ifdef fullscrn cmp [_x],320 ;====================================== jl bg02 ; sub [_x],320 ; This stuff is conditional assembled, bg02: cmp [_y],200 ; jl bg03 ; based on the existence of a FULLSCRN sub [_y],200 ; else ; equate. It clips the screenwork at a cmp [_x],320 - BOBSIZE ; jl bg02 ; MUCH smaller boundary. Looks cool if sub [_x],320 - BOBSIZE ; bg02: cmp [_y],200 - BOBSIZE ; you let it run a while. jl bg03 ; sub [_y],200 - BOBSIZE ;====================================== endif bg03: call _plotbob ; Plot it. @keypressed ; Press a key? jz bg01 ;nope, continue @textmode l8r: @terminate ;Terminate. END START ;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°