For our tile-based engine, I load the tiles into the editor I've created and split the tiles based on the current tilesize. The tilesize must be a power of 2.
Then I go through the larger bitmap and extract the squares of tiles from it. This is done in GDI so it's hideous, but it's easier in DirectX or OpenGL since you have direct access to the surface.
Then I save the tiles into a proprietary format and load them into the texture resource manager and then load the corresponding map data into the map resource manager.
I'll post some code later after I leave work. No time right now.
Ok, now for some code. Work was fast eh. Actually about ten hours between first section and this section, but you'd never know it.
Ok I'm going to walk you through this conceptually first.
1. We have 1 large bitmap.
2. We want to create many smaller bitmaps from the 1 bitmap.
Immediately you will see that we need:
1. A desired cellsize for each smaller bitmap. You could use varying sizes, but that complicates the code enormously.
2. A way to extract square sections from a larger bitmap, or a larger square section.
I'll try to code this w/o using API specifics. For DirectX you would have to lock the surface of the large bitmap and the smaller bitmap and do a copy. For GDI you would need to create 2 DCs and do a whole bunch of other 'crap' to get it to work.
This is a function that will extract tiles of size cellsize from a larger image.
This 'should' work if I've coded everything correctly. It traverses the source bitmap and destination bitmap linearily using offsets. There are no multiplies used to figure out the current position in either of the bitmaps.
//Vector to stick 'tiles' into
std::vector<CTile *> vImages;
//Extract 1 tile starting at dwSourceOffset
//Create tile object
CTile *tile=new CTile;
//Get pointer to buffer
//Copy one DWORD from source to dest (movsd)
//Increment destination offset
//Increment source offset
//Increment destination column counter
//If column counter>dwCellSize
//Reset destination column counter and increment row count
//Move down one line in source, but move to start of line
} while (iRowCounter<dwDestHeight);
//Reset loop vars for next tile
//Save tile in vector
//Move over 1 block in source bitmap
//Check for end of source bitmap
//Move down dwCellSize*iSourceRowCounter pixels
//Set starting offset to dwStartSourceOffset
} while (iSourceRowCounter<dwSourceHeight);
This is a small BitBlt w/o transparency in assembly.
You may want to test this as I coded it sitting here and have not compiled it.
void BitBlt(DWORD dwX,DWORD dwY,DWORD *pSource,DWORD dwSrcWidth,DWORD *pDest,DWORD dwDestWidth,DWORD dwDestHeight)
//Move to dwX,dwY in source image
//Increment row counter
//Are we done?
//If above we are done
//Move down one line in source bitmap
//Move to start of line or left side of tile image by subtracting
//width of destination bitmap
//Here edi is at the right point
It looks strange because the compiler will not allow labels inside of _asm blocks and unfortunately in assembly there isn't any other way to do an a comparison (if) or break out of a loop w/o using them.
This will work provided the direction flag is correct, I prob should deliberately set it, and the coordinates given with the height and width given will not run off the edges of the source bitmap. I could adjust for this with a couple more lines of code, but chose not to.