Article View: rec.games.programmer
Article #705fast VGA sprite routines
From: Brien Voorhees
Date: Thu, 13 Aug 1992 19:34
Date: Thu, 13 Aug 1992 19:34
96 lines
4255 bytes
4255 bytes
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.
Does anyone know techniques to speed up graphics routines? Here's an
overview of how my routines work :
During any given cycle, the following things happen :
The Master copy of the background (in a 64k buffer) is copied into the
work buffer (also 64k).
All sprites are written to the work buffer.
After all movement is done, the work buffer is copied into screen
memory
with a REP MOVSW. Predictably, this single instruction is where the vast
majority of the CPU's time is taken thanks to the slowness of video
memory.
The other (much less severe)bottleneck is the putimage routine. In my
putimg
routine, I grab each byte/pixel from the sprite image buffer and compare
it
against zero ( the background color). If it's a zero byte, I skip it and
go
to the next one, otherwise I write it to the WorkBuffer.
.............Here's the core of the CopyWorkToScreen
routine:...............
mov si,workoff // offset of workbuffer
mov ax,0a000h
mov es,ax
mov di,0
mov ax,workseg // segment of workbuffer
mov ds,ax
#ifdef CODE386 // tc++ inline asm doesn't seem to like 386 instructions
mov cx,03e80h
rep movsd
#else // so presently this (word) version is being used instead
mov cx,07d00h
rep movsw // copy all that crap to slow screen memory.
#endif
...................Here's my PutImage routine :.......................
void putframe(char *buffer,int x1, int y1, int xwidth, int ywidth)
{
int nextlineoffset,startaddr;
nextlineoffset=320-xwidth; // Amount to add to get to the correct
offset
// for the next line.
startaddr=320 * y1 + x1 + workoff; // workoff = address of the
workbuffer
asm{
push es
mov ax,workseg // Segment of (far char*) Work Buffer
mov es,ax
mov di,startaddr
mov si,buffer // (char*) buffer holds the sprite frame data
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
pop es
}
}
Is there any way at all to speed access to video memory? Perhaps
slowing the refresh rate would help? (if so, how do I?)
Also, are there any optimizations that can be made to my PutImage
routine?
I'm very new to assembly so, though I tried my best to optimize that
routine, I'm sure you graphics veterans c'n come up with a few tricks!
Any help would be enormously appreciated!!!
While I'm at it, does anyone have the specs to the .MOD music format?
Brien "I Link Therefore I Am" Voorhees
--
Brien Voorhees (bbs.brienv@tsoft.sf-bay.org)
Technical Details
Message-ID:
<RVmgPB1w165w@tsoft.sf-bay.org>Path:
arc1-ca.pugleaf.net!sparky!uunet!olivea!sgigate!sgiblab!tsoft!brienvShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!olivea!sgigate!sgiblab!tsoft!brienv From: bbs.brienv@tsoft.sf-bay.org (Brien Voorhees) Newsgroups: rec.games.programmer Subject: fast VGA sprite routines Message-ID: <RVmgPB1w165w@tsoft.sf-bay.org> Date: 13 Aug 92 19:34:14 GMT Sender: bbs@tsoft.sf-bay.org (BBS User) Organization: The TSoft BBS and Public Access Unix, +1 415 969 8238 Lines: 96