🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #934

Re: fast VGA sprite routines

#934
From: Harm Hanemaaijer
Date: Mon, 17 Aug 1992 12:36
92 lines
2986 bytes
In <1992Aug14.151042.23556@zooid.guild.org> Ross Ridge <ross@zooid.guild.org> writes:

>bbs.brienv@tsoft.sf-bay.org (Brien Voorhees) writes:
>>  I've been working on some graphics routines for VGA mode 13h to handle
>>animating sprites while retaining the background and have managed to get
>> 'em goin' pretty fast (about 25-35 fps on a 486) but that's without 
>>much other overhead.  Once I add collision detection, sound, music, etc.
>>I don't think I'm going to have enough cpu time to spare.
>
>>    mov   cx,ywidth  // Set outer loop to run <ywidth> times
>>rowloop:             // once per row (duh)
>>    push  cx         // save what row we're on
>>    mov   cx,xwidth  // Set inner loop to run for each pixel on this line
>>subloop:  // There are actually two loop instructions that goto this 
>>label
>>    lodsb            // grab a pixel
>>    cmp   al,0
>>    je short itsblank  // if it's 0, skip it
>>    stosb              // otherwise, write it
>>    loop  subloop
>>    jmp short endsubloop  // Jump outta' here. Don't wanna' fall thru to  
>>                          // the other subloop section!
>>itsblank:
>>    inc   di              // Keep the destination index in sync
>>    loop  subloop         // Ready for the next pixel
>> 
>>endsubloop:             
>>    add   di,nextlineoffset  // Set destination pointer to proper offset 
>>                             // for beginning of next image line
>>    pop   cx              // Where were we?
>>    loop  rowloop         // Ready for next line
>
>
>	mov dx,ywidth
>	mov bx,xwidth
>loop1:
>	mov cx,bx
>loop2:
>	lodsb
>	or al,al
>	je skip
>	mov [es:di],al
>skip:
>	inc di
>	dec cx
>	bne loop2
>	add di,nextlineoffset
>	dec dx
>	bne loop1
>
>It's probably faster on 8086's too if your sprites don't have many
>zero's in them.
>
>							Ross Ridge

This can be faster by using loop enrolling. It saves precious branch penalties,
and reduces the number of instructions executed. With loop enrolling it works
like this:

@@loop2:
	cmp cx,8
	jae @@loopenroll ; handle 8 pixels without checking 
        lodsb	
	or al,al
	je skip
	mov es:[di],al
@@skip: inc di
	dec cx
	bne loop2
        ...

@@loopenroll:
        mov al,[si]	
	or al,al
	je @@skip1 
        mov es:[di],al
@@skip1:
        mov al,[si+1]
	or al,al
	je @@skip2
	mov es:[di+1],al
@@skip2:
	...
	sub cx,8
	add si,8
	add di,8
	jmp @@loop2 
 
Loop enrolling can improve most code that involves small loops.

Harm Hanemaayer
hhanemaa@cs.ruu.nl
Technical Details
Message-ID: <1992Aug17.123659.24095@cs.ruu.nl>
Path: arc1-ca.pugleaf.net!sparky!uunet!mcsun!sun4nl!alchemy!hhanemaa
References: <RVmgPB1w165w@tsoft.sf-bay.org> <1992Aug14.151042.23556@zooid.guild.org>

Show Full Headers
Complete Article Headers
Newsgroups: comp.os.msdos.programmer
Path: arc1-ca.pugleaf.net!sparky!uunet!mcsun!sun4nl!alchemy!hhanemaa
From: hhanemaa@cs.ruu.nl (Harm Hanemaaijer)
Subject: Re: fast VGA sprite routines
Message-ID: <1992Aug17.123659.24095@cs.ruu.nl>
Date: Mon, 17 Aug 1992 12:36:59 GMT
References: <RVmgPB1w165w@tsoft.sf-bay.org> <1992Aug14.151042.23556@zooid.guild.org>
Organization: Utrecht University, Dept. of Computer Science
Lines: 92