Advertisement

I need suggestions on optimizing my game code

Started by February 16, 2000 01:06 AM
5 comments, last by arrow62 24 years, 6 months ago
I am making a basic DirectX tile game engine and would like some suggestions on the best way to optimize my graphics code. My approach is to load a bmp file containing all the 48x48 terrain tiles and then every frame I loop through the map array which is an array of structures containing the information for each layer of that map cell and get the current tile number. I use the current tile number to determine the correct rcRect.left and rcRect.top coordinates in the tile bitmap. Once I have the correct coordinates for rcRect I use BltFast to place the 48x48 tile on the screen. I am only looping through the mapStruct that is visible. Is it efficient to use the rcRect to get each tile for each cell as I need it from the tile bitmap every frame or is there a better approach? I''m also wondering where pointers might help speed things up. I seem to be getting a decent frame rate at this time but I''m wondering how much it could be improved with some optimization. I''m getting around 59 fps at 1024x768 and 83 fps at 800x600 in fullscreen mode on my PII 350 with a voodoo2 card and it doesnt seem to slow down much as I add layers and pieces to the function. Any comments or suggestions would be appreciated. See example below. simpified example: rcRect.left = mapStruct[j].layer1*tileWidth; rcRect.top = mapStruct[j].layer1*tileHeight; rcRect.right=rcRect.left+tileWidth; rcRect.bottom=rcRect.top+tileHeight; while (1) { ddrval = lpDDSBack->BltFast(x, y,lpDDSMap, &rcRect, DDBLTFAST_SRCCOLORKEY); } Thanks, Arrow </i>
I don''t think you can get it much faster by changing the code you have supplied.
When optimizing you should always concentrate on the code that runs the largest fraction of the time it takes to process each frame.
In this case it probably is the rendering process that you are already trying to optimize, however I believe that although BltFast uses the hardware it still takes up a much largest fraction of time than your handling of rcRect.
Advertisement
The 59 fps and the 83 fps for your 1024x786 and 800x600 screensizes are tied to your Monitors refresh rate. I bet your at 60mhz and 85 mhz respectively for those modes. Thats why you don''t see slow downs, since your "true" fps is actually higher, prob. much higher.

As for optimizations, you have to ask your self some questions....
How many DIFFERENT tiles are you going to display on the screen at once?
How can you arrange those tile groups according to your answer above?
How many layers of tiles/objects do you plan to blit?
What is your low end target platform (P166/200/300 etc)?
What is the min video memory your engine can tolerate?

Then adjust your engine accordingly. There''s lots of answers here.

One thing to remember: The more locking of a surface that occurs the slower your engine will be, try to limit views of objects/tiles as much as possible.

On that note I''m willing to release the source code of my engine/map, to help anyone out. I can send it to you via email, or if I see enough response here, I''ll just post it on the web site.

For starters, you could precalculate a static array
of RECTs, one for each of the tiles you are going to
use.

Then the 8 lines of code you show simplify to

ddrval = lpDDSBack->BltFast( x, y, lpDDSMap,
&tile_array[tile_num], DDBLTFAST_SRCCOLORKEY );


You''ll need to calculate tile_num - I''m not sure
exactly how your mapStruct is set up.

Second, are your tiles transparent? If not, use
DDBLTFAST_NOCOLORKEY.

Third, how much does your screen scroll around?
If it''s not much (say on the order of an RTS game)
it may be worthwhile to create a scratch surface for
drawing your terrain tiles into and keeping an extra
array that records what tile is drawn at each location
in your scratch surface. Then each time through your
drawing loop you can just check against the cache
array, update on those tiles that are different, and
once you are done, blit the whole scratch surface into
the right place on the back buffer.

1) I use the same method as you but I put into the mapcell structure an actual RECT that I fill at the start

struct mapinfo
{
int BaseTileNumber;
int PathTileNumber;
RECT rcBaseTileSource;
RECT rcPathTileSource;
} Map[60][70];
calculate the RECTs when you load the map file (watch the memory though)

LordFoul''s suggestion of having a separate backgound is excellent. I use it for the background tiles that never change and that''s just one big blt for all that. When you scroll the map you would cut and paste a large section of the map and fill in the lagging files. The array mentioned by him allows you to test for sprites that have disturbed the map background.
Everytime you place a tile you would calculate at each corner of the sprite the Map[x][y] co-ords that you have disturbed. In a separate array of chars (CheckingArray[60][70]) you change the [x][y] to 1 from 0;
When you go to refreah the frame, just loop through the CheckingArray[60][70]checking for disturbed tiles.
There''s the time lost going through the CheckingArray but it would cut out most of the cost of Blitting _everything_

ZoomBoy
A 2D RPG with skills, weapons, and adventure.
See my character editor, Tile editor and diary at
http://www.geocities.com/Area51/Atlantis/7739/
When reading Tips of the Windows Game Programming Gurus, LaMonthe said that processors don''t exactly like complicated commands all at once. So , I suggest, to optimize this, do the following:


int left = magStruct[j].layer1*tileWidth;
int top = magStruct[j].layer1*tileHeight;
int right = rcRect.left+tileWidth;
int bottom = rcRect.top+tileHeight;

rcRect.left = left;
rcRect.top = top;
rcRect.right= right;
rcRect.bottom= bottom;

while (1)
{
ddrval = lpDDSBack->BltFast(x, y,lpDDSMap, &rcRect, DDBLTFAST_SRCCOLORKEY);
}


Or you could create some sort of lookup table for
magstruct[j]. Well, good luck!<br> </i>
D:
Advertisement
quote: Original post by PsYcHoPrOg

When reading Tips of the Windows Game Programming Gurus, LaMonthe said that processors don't exactly like complicated commands all at once. So , I suggest, to optimize this, do the following:

int left = magStruct[j].layer1*tileWidth;int top  = magStruct[j].layer1*tileHeight;int right = rcRect.left+tileWidth;int bottom = rcRect.top+tileHeight;rcRect.left = left;rcRect.top = top;rcRect.right= right;rcRect.bottom= bottom;



I doubt that this will do you any good. Although LaMothe is probably right this is something that the compiler takes care of. If it is needed the compiler will do this optimization (unless it's a really bad compiler )


Edited by - Spellbound on 2/24/00 12:34:53 PM

This topic is closed to new replies.

Advertisement