I don't have a "slow" machine. I don't have the latest "bomb" either.
But I'm convinced of one thing: displaying 2-D data on today's machines should be near-instantaneous.
There are a lot of ways to speed this part.
First, whats the deal with 'tens of thousands" of bitmaps?
A typical dungeon has about 1000 squares. You mean you have to manipulate apprx 10 bitmaps per DUNGEON SQUARE? Are you telling me that you are actually computing from scratch everything from the BASE bitmaps? No wonder its so slow!
Ask yourself this: Just how many DIFFERENT bitmaps are displayed? Ask yourself how you could do the computing you're doing on your bitmaps ONCE PER DIFFERENT bitmap instead of "everytime". Divide and conquer! Separate the computing steps. Do you really need to do all the work from the unzoomed images? OFr could you first reduce each image you need, and only if they that wasn't already done before during this instanciation of the program, and THEN copy those "new source" images in the destination array?
Once you've computed ONE bitmap, just keep it's already-iconized-image around for all other instead of that bitmap will speed things up greatly. Then copying from a 4 times smaller image means not only 16 times less data to move around, but also less operations on the data, too (because it is ALREADY iconized and thus you don't need to recompute the zooming every time). A computer has only a VERY limited amount of regstry in CPU where it can put data, so the more you chew up the work out for it, the easier (i.e. faster) it runs.
Anyway, blitting zoomed bitmaps like this should be lightning fast. I did this programming optimization step once at work at it provided 100+ times faster ROTATIONS of objects. Now, with static, non-rotated bitmaps, this should really be a laugh.
Use the following method:
Determine current zoom factor for the various lements (for example, the floor bitmaps aren't necesseraly zoomed at the same factor as objects).
Now, determine the pixel skip value vector for each possible zoom levels. Since everything is square, this vector is the same for both horizontal and vertical.
PRECOMPUTE which columns/rows will be displayed for the maximum size bitmap. for example, for a zoom factor such that 32 pixels of bitmap will be displayed on screen using 6 pixels, then the zoom factor is 5.4, and my vector would look something like:
0,5,11,16,22,27,32,etc.
(i.e. 2nd position = 2 * 5.4 = 10.8 rounded to 11) in short, precomputing where each "closest pîxel" will fall in advance.
Then accessing each destination-color pixel is only a matter of finding the offset in the index vector to get the needed position in the bitmap.
I call a reduced bitmap its icon. But don't create separate images for all icons. This is because allocating a memnory, even a tny one, takes, relatively speaking a HUGE amount of time, CPU wise. Heck, creating your own heap is WAY faster than using the default rutines. And for "fixed size" elements like sets of bitmaps all of the same size, its definitely the way to go.
Instead draw directly all icons directly inside one HUGE IMAGE of standardized "multiple-of-two" width, keeping for each image its total byte offset in the big image. I call this big image (several in fact, one for each icon size) my "workbench". Such images can be pre-computed with a timestamp and saved in a file so that it doesn't have to be produced every time the editor is started.
Image operations should not be of the type:
For X=0 to Width
For Y = 0 to Height
Destination (X)(Y) = Source (X)(Y)
Next Y
Next X
This is very simple to code, easy to "rad and debug", but... it is a common programing technique mistake made by many programmers!
Use this instead:
(remember to put Y before X in vectoring matrix operations!)
Blitting a Width by Height rectangle from Source to Destination:
(Check cases if Width or Height are zero)
Pointer to First Source Pixel = S
Pointer to First Destination Pixel = D
SW = SourceTotalWidth
DW = DestinationTotalWidth
EndPointer = S + ( Height * SourceTotalWidth )
SourceSKip = SourceTotalWidth - Width
DestSKip = DestinationTotalWidth - Width
While S different than EndPointer
EndLinePointer = S + Width
While S different than EndLinePointer
Content of D++ = Content of S++
EndWhile
S += SourceSKip
D+= DestSkip
EndWhile
Note that even though the pointers seem to be able to attain values that ccould, if dereferenced, mean invalid memory access voilations, the while conditions means that the pointers are deferenced only when within valid image area.
This idea of minimizing the actual number of variables used, using extremely simple while logic conditions, precalcultating values OUTSIDE of loops, and working directly with pointers INSIDE the array rather than the array variable and dereferencing the X and Y corrdinates at each loop iteration is a common and very useful tool in programming and makes for INCREDIBLY fast code.
Ask yourself this: what is faster:
A) For X Y with Pixel = Image(Y)(X)
"Bob, go find where the house's entrance is. Then go to the first corridor, Then go to the first room in that corridor. Copy the paper there."
then
"Bob, go find where the house's entrance is. Then go to the first corridor, Then go to the second room in that corridor. Copy the paper there."
then
"Bob, go find where the house's entrance is. Then go to the first corridor, Then go to the third room in that corridor. Copy the paper there."
etc.
repeat until corridor Y / room X.
or
B) While P not at End loop with Pixel = Content of Pointer P++
"Bob, go find where the house's entrance is. Find the first corridor, find the first room."
"Go into the room in front of you. Copy The paper there. Move on to the next room"
then
"Go into the room in front of you. Copy The paper there. Move on to the next room"
then
"Go into the room in front of you. Copy The paper there. Move on to the next room"
etc.
repeat until you find the room number you're in front of is End.
A computer may work fast, but each operation takes time, even if a tiny bit. By giving the computer EFFICIENT sets of instructions, a program can go much faster, because it needs less commands to do the same job.
Now, its clear to have your image not in a window portable format but directly an array-in-memory is much faster. You'd be surprised how much FASTER direct memory manipulation is. Then, as a LAST step, bitblip your final image to screen.
Of course, drawing lines is similarly much faster if you use the Bresenham Line Algorithm directly into a memory buffer rsather than using the so-extremely-inefficient conventional drawing routines.
http://www.cs.helsinki.fi/group/goa/mal ... esenh.html
Tricks of the trade.
I can do it for you igf you like. In what language did you code?
patrick.rannou@sympatico.ca