I started taking a look at how to implement the idea I was describing back in September, of taking a chunk of an image file and displaying it to replace other terrain images. Once I started digging around in the code, I found what I think is probably the best way to do it, which runs as follows: * Extend the current "subimages" concept in the image-family system. You can already specify special types of images, namely "tile", "border", "connection", and "transition", and you can specify (for regular images, which could be cell terrain or units) multiple "subimages". I propose to add a new special type of image called "hexgrid". When you specify a "hexgrid" image, you specify a subrectangle of an image as you normally do with other images, and you also specify a number of rows and columns (of hexagonal cells). Hexagonal chunks are automatically clipped out of the source image starting from your specified coordinates, to make up a number of "subimages" for the image family. * Add data structures to the map to store, for each cell and cell terrain type, pointers to image families and subimage numbers for "override" images. * Change interfaces so that when they go looking for a cell terrain image for a given cell, if there is an applicable override image at that cell, they use it instead. I'm hoping to keep the amount of per-interface code for this as small as possible; that should be reasonably easy to do, because it's mostly just a matter of extending the call interfaces make to say "Hey, what's the image for this terrain type?" to be "Hey, what's the image for this terrain type *at these cell coordinates*?" * Add appropriate forms to GDL to allow setting the override information. I decided to try implementing these ideas, but I wanted to do it in such a way that I could test each step and see that it was working before moving on to the next one, so as a very first step, I wrote a simple game module which would trigger the "subimage" code, figuring that next I could move on to making it clip out the subimages in a hex grid instead of the existing one-dimensional linear offset. The results are at these URLs: http://ansuz.sooke.bc.ca/temporary/maptest.g http://ansuz.sooke.bc.ca/temporary/override.gif Those are supposed to work with the existing code base; the "forest" cells on the map are supposed to be filled with a random mixture of five different hexagonal chunks taken out of override.gif (which, you will note, contains a chunk of the existing map with the colours modified and some minor edits so that I'll be able to see when it's correctly spliced in). In testing that, I discovered a bunch of issues with existing code, with my test files (I haven't touched the code to actually modify it yet at all), or issues that will come up soon: * It doesn't work in the TCL interface except on the highest magnification. At other magnifications, the affected cells are just black. As far as I can tell, for some reason the automatic scale-down code isn't running. Isn't it supposed to? I thought the idea was you could specify just one resolution of an image and any others would be automatically generated if necessary; that certainly works for units, but at least in this case it doesn't seem to work for terrain. * It doesn't seem to work in the SDL interface at all - I get a segfault, see attached backtrace. I haven't tested this extensively at all, so it's possible it may be unrelated, but the same build of the SDL interface seems at least sort of stable with other modules, so I suspect it's something to do with the same issue as in the TCL interface - I didn't specify more than one resolution for the terrain images, and there are issues with generating the other sizes automatically. This could be a problem because someone who's doing this clip-and-insert thing will only naturally have one resolution for the image, and it seems like a bad thing to force the designer to provide multiple sizes of the same image from outside the game; the resize code really should work. * It seems like a shame that images can only have 256 colours, and this'll be a bigger issue when we have image chunks of serious size, where all the hexes in the chunk have to share the same palette. Ideally I think this would be fixed by making XConq capable of loading PNGs, but it looks like there are 8-bit assumptions built into a lot of code, and at this point I don't want to try to change them when that's not my main goal. * It seems like maybe (I'm not quite clear on this) when there are a bunch of subimages in an image, the GIF file is being re-read for each one. That could already be a performance issue for border/connection terrain; but with satellite images there could be hundreds, or thousands, of subimages from the same image, and it would really suck to have to spend the time to load the GIF a thousand times over. Better to cache it somehow; but maybe that's already being done, since border/connection terrain *doesn't* seem to create a huge loading-time problem, and is already loading 63 subimages per terrain type. * There is simply a lot of data involved in covering a whole map with custom images. There's not really any way around that. I think it could be a problem because there are some warnings I don't understand in the code (imf.c lines 88-90 and uses of the flag defined there) about some Windows interfaces having limits on "GDI memory", and there are measures taken to cut features to save on the amount of imagery loaded. For instance, if the flag that says "we have to conserve GDI memory" is set, then when you specify a lot of alternate images (like in my example file, which specifies five) only the first three are used. Well, with a patch of satellite data you pretty much have to load all the subimages - but if there are hundreds of them, and you can't afford to load a lot of images in general, that's going to be a problem. I don't think there's really much way to avoid this, short of simply disabling the image-override mechanism entirely when the "must not load too many images" flag is set. No matter what scheme we use, those images have to be loaded if we're going to use them. Maybe someone who knows more about Windows and what that flag is actually for could shed some light on this issue. * Minor thing, but something I'll include in my patch for sure: the (x n x y) property for image families doesn't seem to permit negative x/y values, and I think you'd be likely to want to use those far more often than you'd want to define both of them to be non-zero, which is behaviour it does permit. Easy to change, just by changing ">0" to "!=0". I'm also not convinced that this parameter is really 100% correctly implemented in general, but that's not really my problem and it obviously does at least sort of work because the terrain in the existing "advanced" game uses it. I became interested in this bit of code because it's closely related to the code I want to add for hex-grid clipping. * If I clip chunks out of an image on a hexagonal grid, what I will get will be overlapping rectangular images (88x96 or similar) without the hex masks that I think the current system might produce. I'm not sure how interfaces use images or whether that's likely to be a problem; I suspect it isn't a problem because of the success of my test files with the current code, but if it turns out to be, then I guess I'll have to write some code to generate a hexagonal clipping mask for the images. The issue is that the interface asks for an image for terrain for a given cell, the imf code hands back an image, but that is a rectangle that covers the bounding rectangle of the cell and includes pixels outside the bounds of the cell, because there's not a hex mask to clip it to the cell... Will the interface do the clipping? Or do I have to generate a mask to go with the image? I guess I'll find that out by experiment later. It seems like something that the interface probably already has to do anyway, so it's probably not a problem I need to solve; and if I did need to solve it, I could, so it's no biggie. -- Matthew Skala mskala@ansuz.sooke.bc.ca Embrace and defend. http://ansuz.sooke.bc.ca/