|
For squeezing the most speed out of your code,
the best optimizer is the one atop your shoulders. Visual
C++ does a reasonable job of optimizing C code, but because the
C language is not well suited for manipulating bits and bytes, it
often makes sense to write inner loop code in assembly language.
Microsoft has done a reasonable job with their support of inline
assembly in VC++. Shown below is a function which will draw
a character which unfortunately needs its colors translated pixel
by pixel. I've left the equivalent C code in place to demonstrate
what's going on in the assembly language. I've found the
following general rules apply when working with the inline assembler
in MSVC++:
1) Errors are off by one line - When an error
is found by the compiler, it erroneously reports it as being on
the next line (VC++ 5.0 & 6.0 behave this way).
2) Use EBP carefully - Since EBP points to the
local variable heap, you can modify it, but always restore it before
the end of your code block and while it is not pointing to the local
variables you will not be able to access any.
3) Using EBX,ESI,EDI - You are free to use these
registers, but they are used by the compiler for register vars.
If your ASM code is in the middle of code which uses register vars,
then these must be preserved, if not then don't worry about them.
4) Accessing structure variables - The compiler
does not allow accessing structure variables indirectly through
a pointer since it can't get to the pointer with an absolute address.
The solution is to put the value in a global or local var before
entering your routine so it can be accessed within the ASM code.
Here's the code:
iAddr - The emulated video offset (0-3ff)
cColorPROM - A 256 color translation table to turn the character
colors into palette colors
iPitch - Destination video buffer width in bytes
iChar - Character to draw
iColor - Color to draw the character
pCharData - Image data for characters, 8x8 bytes or 64 bytes per
character
void EMUDrawChar(int iAddr, unsigned char *cColorPROM,
int iPitch, int iChar, int iColor, unsigned char *pCharData)
{
int x, y;
unsigned char *s, *d;
x = iCharX[iAddr];
y = iCharY[iAddr];
if (x < 0 || y < 0)
return;
d = &pBitmap[y * iPitch + x];
s = &pCharData[iChar * 64];
#ifdef PORTABLE
for (y=0; y<8; y++)
for (x=0; x<8; x++)
d[y*iPitch+x] =
cColorPROM[iColor + *s++];
#else
iPitch -= 8;
_asm {
mov esi,s
mov edi,d
dec edi
mov edx,cColorPROM
add edx,iColor
mov ecx,iPitch
mov bl,8
xor eax,eax
drwc0: mov bh,8
drwc1: mov al,[esi]
inc edi
inc esi
mov al,[edx+eax]
dec bh
mov [edi],al
jnz drwc1
add edi,ecx
dec bl
jnz drwc0
}
#endif
}
Webdesign
by Deep Magic Studios
- HanaHo Games, Inc. Copyright © 2002 |