Join Prime Video Channels Free Trial


ANGV Game Underground Page 2nd Edition

The page is in a sense continuation of the previous ANGV Undergroud Page. This one is however focused on internals of the release version of Austerlitz: Napoleon's Greatest Victory game created by Breakaway Games company.

InfoNews       What and why      Universal Patch       Fog Issue       Color Maps      Jump Maps      Links       



It is fun in itself afterall

Last Updated: Saturday, 16th of September 2002
This page is still in statu nascendi.

Having any remarks, questions, problems or insults you can contact me here:


Saturday, 16th of September 2002

Added information about JumpMap feature. Updated Universal Patch includes options allowing proper working of jump maps (both hand-made and simplified engine-drawn) in custom campaigns. Took me longer then expected - bottomline is: never trust a programmer - when he estimates something will take him say two days then all you can (usually) count on is that it will take no more then about twenty days :).
Next I plan to finish work promised for Peninsula Mod. It likely will take me more time then expected (:-) so next update of the page will be rather not soon. There is couple of possible improvements I'd like to make available in custom maps (for example making available more occupable flags/buildings, maybe also with ability to adjust their defensive morale bonus). Another thing I'm tempted to try is attempt to modify parts of battlefield simulation mechanics. The thing which could go over the top first is forcing routed units to loose stragglers/prisoners when pushed to move. Wouldn't be easy (don't have all parts of the puzzle right now) but what's the satisfaction if it would work! :-)

Friday, 6th of September 2002
Opening new page. Currently you can find on the page so-called Universal Patch, which offers a couple of options unavailable in original ANGV. Most important is, I think, that it tries to fix the problem with FOG initialisation and thus allows loading of custom campaign's maps without the crash. Beside the patch you may find there some info about FOG effect, color maps and in-game daylight conditions.

back to top of page

What and Why

Sorry, I'm not in the mood to explain it now. Maybe next time ;-).

back to top of page

Universal Patch

The name is certainly exaggerated. Anyway technique used is much more flexible then the methods I used previously (for the 1st Edition of the page :). So much that (I believe) it deserves some special name :). For these curious here is how it is supposed to work. First the seemingly normal patch procedure must be done. This time however patch program does not modify the code of ANGV program on file. Its task is to assure that once ANGV program is started it will first try to load special DLL library (it is named JPIEXAE.DLL in that case. A stands for Austerlitz; E for English version; EX means EXtension; JPI is just a prefix :). That DLL should be located in ANGV main directory. Once loaded DLL replaces the original WinMain procedure (program entry point) by its own version. That version calls of course the original WinMain but that call is bracketed by calls to two other procedures Init and Exit. First one is responsible for doing all the real program patching (note that it is done in-memory only - EXE file is not modified at the moment); second call is for doing any needed clean-up. This way is more flexible because I can now do more then just patch a couple of bytes. In theory it is now (relatively) easy to extend the original ANGV executable by pieces of code (written in C not assembelr!) contained in the DLL. It is also more convenient because after initial patch all what is needed to update the patch (correct bugs or add new functionality) is replacing the extension DLL by its new version.

Patch installation is to be done by hand. ZIP file contains two main files: UniPatch.exe and JPIEXAE.DLL. Extract them to game's main folder. Now is good time to backup your Austerlitz.EXE file. Next run UNIPATCH program (from Explorer window or DOS prompt) - be sure to do it from ANGV main folder. This is Win32 console program. It should do some sanity checks (including verifying ANGV executable CRC), make its own backup of original EXE, next do its main task (assuring that ANGV will load DLL at startup) and print a couple of diagnostic messages. Note that patched ANGV should be 8KB larger then original file. That's it - you do not need to do anything with DLL except assuring that it is present in ANGV folder. Note that if ANGV will for any reason fail to load extension DLL it should silently continue to load - in that case of course it will behave like original, non-patched version. Patch functionality is controlled by couple of home-invented properties. Some of them (global) are looked for in [extension] section of the Austerlitz.ini file, others (local to the given campaign) in the same section of the campaign's CONFIGnn.CFG file. Short description of available options is provided at the end of this section. Note that ZIP file contains two files which maybe be helpful as reference points Austerlitz.ini.example and config44.cfg.example.

Words of caution are in place here. If you decide to try it out you do it at your own risk. Read carefully the formal disclaimer above and remember that I'm not responsible for any problems or disasters you may experience. I can also not guarantee that the particular options will work as described nor even that the patch will work at all for you. I did my tests on Win95 machine (still... :). There is small but real possibility that - because of the technique used - it will not work at all on newer platforms. And of course there is host of other reasons why the patch may malfunction in your particular configuration.
It is needless to say that I'd like to hear about any successful and failed attempts. Feel free to mail me at the address provided above. If possible I will try to help in case of troubles - no guarantee of sucess however.

List of available options

    In the Austerlitz.ini file, in its [extension] section following properties are recognized (note that values specified in the examples are defaults used when property is not defined explicitly):
  • EnableExtension=1 - if set to 0 all the extension functionality is disabled and all other properties ignored. Program should behave exactly like non-patched.
  • VideoIntroOff=0 - When set to 1 ANGV should skip the video intro replaying.
  • LoadPaintings=3 - if you created custom painting for loading screen and want ANGV to use them together with three original paintings, copy them to right place and set this property to the total number of paintings available.
  • LoadQuotes=25 - same as above but for quotes used in the loading screen.
  • GroundColorFix=0 - if set to 1 should fix the bug in the handling of the GroundColor.raw.
  • FogStart=0500
    FogEnd=0845 - defines the time limits for the FOG effect. Relevant only to Austerlitz campaign. Note that exact moment when fog vanishes may differ a bit from the FogEnd value. Don't set these two properties too close. You can read more about FOG effect below.
  • DayStart=0733
    DayEnd=1633 - Meaning is obvious. They are also used in implementation of the variable daylight conditions. Note that these values are default for Austerlitz campaign. For custom campaigns if that properties are not set here nor in the CONFIG file the values used are 0700 and 1900 respectively.
    Properties defined in the CONFIGnn.CFG file (in its [extension] section) have meaning for the given campaign only. Again values specified in examples below are defaults.
  • SwitchFogOff=0 - When set to 1 FOG effect should be disabled altogether.
  • FogStart=0500
    FogEnd=0845 - defines the FOG effect time limits for the given campaign. See remarks in the previous list.
  • DayStart=0700
    DayEnd=1900 - Meaning is obvious. If not set global settings (from Austerlitz.ini) are used. If these are also not set the defaults as given here are used. See also remarks on the previous list.
  • ColourMap=0 - if set to 1 engine will try to load single color map; if set to 2 will support variable daylight conditions by use of 24 color maps. You can read more about color maps and daylight conditions in section below.
  • ColourMapFile=Graphics\ColourMapC - this means that for ColourMap=1 engine will try to load color map from the ColourMapCnn.raw (where nn - is campaign's number); for ColourMap=2 engine will look for color maps in the set of 24 files named Graphics\ColourMapCnn_00hh.raw (nn - campaign's No., hh - color map number in range 00-23).
  • SwitchColourOn=0 - when set to 1 (assuming ColourMap=0) will fill the color map with single RGB color. See position below.
  • ColourR=255
    ColourB=255 - together define the RGB color to be used for filling the color map matrix. Values in range 0-255 are valid. Meaningful only if ColourOn=0 and SwitchColourOn=1.

Here is the Universal Patch version 1.01:
If you already patched ANGV then all you need to do is replace JPIEXAE.DLL in game's main folder by new version (well, if not counting setting values for new properties).
New properties available in version 1.01 (default values used when they apply):
    global, in Austerlitz.ini, in its [extension] section:
  • JumpMapFix=0 - when set to 1 enables whole JumpMap fix (easy! :).
    per-campaign, in CONFIGnn.CFG file, again in [extension] section:
  • JumpMapOffsetX= - offset in pixels along X-axis of actual JumpMap rectangle (its upper, left point) in whole JumpMap bitmap. Used for hand-made jump maps or when you use Canvas file (see one of options below)
  • JumpMapOffsetY= - as above but for Y-axis. Don't count here these 48 pixels of transparency!
  • JumpMapSizeX= - X-dimension in pixels of actual JumpMap rectangle (clikable area) in the whole JumpMap bitmap. Shouldn't be larger then 140 (and that's assuming unlikely case you set JumpMapOffsetX=0). Used for hand-made jump maps or when you use Canvas file.
  • JumpMapSizeY= - Y-dimension in pixels of actual JumpMap rectangle. Shouldn't be larger then 102 (and that's assuming unlikely case you set JumpMapOffsetY=0). Used for hand-made jump maps or when you use Canvas file.
  • JumpMapCanvasFile= - If specified then (assuming you don't provide hand-made jump map) defines Jump Map pane image used as a background for simplified, engine-drawn jump map.
    When JumpMapCanvasFile=Canvas.bmp engine will try to use image contained in GRAPHICS\Canvas.BM2 file. If you decide to use Canvas file then all the JumpMap{Offset,Size}{X,Y} properties must be also provided - just like for hand-made jump maps.

back to top of page

FOG feature and problems with custom campaigns

As already noticed by some modders there are problems with MultiCampaign in the ANGV release. Due to apparent bug in ANGV code the game is virtually guaranteed to crash when one tries to use its MultiCampaign feature. It is the case even when one prepares the CONFIG file such that it refers to original Austerlitz campaign MAPDATA assets. In fact it is the same problem which I encoutered some time ago during my experiments with ANGV Demo (you can read about it on the WaterlooAtANGV.html page. Particularly see the text under heading "First Blood - MultiCampaign is not easy").

On the page mentioned above I suggested that the problem has something to do with the initialisation of the FOG data. In that time I made a quick fix and skip over the issue. I suspected that the strange lighting conditions visible in the custom campaign maps may be a side effect of that dirty patch. It turned out however that it is not the case - the night-like conditions are the normal "feature" of the custom campaign maps (read more about it - and how to make things looking a bit better - in the topic below).

What is really wrong with the FOG initialisation? For Austerlitz campaign during the MAPDATA loading preparation phase one special procedure is called. It sets a couple of FOG related variables (FogStart, FogEnd variables amongst other) to the proper values. That procedure however is not called for the custom campaigns. This means that the related variables are left uninited which next leads quickly to the DIVIDE BY ZERO exception. In theory it should not be a problem when the FOG file fails to load as in that case a flag variable is set to prevent accessing of the FOG related code. Unfortunately one piece of code is not properly guarded by that flag. As a result no matter if one prepares fog file data or not the exception and program crash seems to be unavoidable.

Any solution? The ultimate one is of course the BAG patch. For the moment you may consider using my "Universal Patch" (see section above). It tries to fix the problems with the FOG code described above. By default it calls the forgotten procedure which inits the all-important variables and thus allows using the FOG feature in the custom campaigns. If you desire you can also explicitly disable the FOG mechanics for custom campaigns. In that case FOG related code will NOT be called after initialisation which should be another way to cure current vulnerability. To disable the FOG you should set the SwitchFogOff=1 property(default is 0 of course) in the [Extension] section of your campaign's CONFIGnn.CFG file. For more details see above and/or consult the example CONFIG file enclosed in the patch ZIP package.

On the previous edition of underground page I described a few facts and guesses about the FOG feature in general. Most of them I still consider to be correct. At least one thing however turned out to be more complicated then I expected. I suggested that the meaning of the single byte in the FOG file is very simple: 0 - no fog in square; 255 (FFh) - highest fog density. It is not so simple unfortunately. Here is how I think currently the FOG mechanics is working (of course that description can be still incomplete or plain wrong). The FOG display routine seems to except FOG intensity values in the range 0-10h. The initial intensity values for the squares are defined in the fog file but as all te players know FOG intensity is not constant - in the given square it gradually decreases until it vanish completely. At the initialisation decreasing time interval is calculated:

Fog appears on screen when the game clock reachs the FogStart value; from then on every time the interval calculated above expires the Fog intensities for the squares are decreased by 1 (if non zero). As an example: if the FogStart=0500 and FogEnd=0845 (which gives interval 14 minutes) the square for which the intensity defined in fog file is equal 1 should be free from fog at about 5:14am; in that for which initial intensity equals 14 (0Eh) fog should vanish completely at about 8:16am. (One last note: it looks like the fog file data defines intensities for the points of crossing the square borders, not for the center of the squares. The values in other points seem to be interpolation of the intensities from the 4 adjoining cross-points. That is however just an unverified conjecture currently).

What about preparing FOG effect for the custom campaign's map? The FOG file can be edited using any HEX editor. Creating this way FOG file adapted to the custom map is time-consuming but not impossible task. In future it seems to be possible to create little program which would generate FOG data automatically based on the Elevation (more fog in the valleys) and Terrain (more fog nearby the water - like streams and marsh terrain) files prepared previously for the given map (plus a couple of params). Of course the ultimate solution would be full-fledged map editor with the ability (amongst other) to edit visually the fog layer. But that seems to be rather the story of the far future...

In the paragraphs above I mentioned FogStart and FogEnd variables. Unfortunately their values are hardcoded into the game engine. However once you apply the "Universal Patch" you will be able to specify them both for the custom campaigns as well as for the Austerlitz one. For the Austerlitz campaign (Campaign=2) you should set that properties in the [Extension] section of the AUSTERLITZ.INI file. For custom campaigns the right place is the same section but located in the corresponding CONFIGnn.CFG file. The time values for both variables should be provided in the so-called military format - four digits without separator (otherwise they will be ignored and defaults will be used). Here is how it may look in the CONFIG file:
In that case fog effect is supposed to start at 5:00am and end about 8:45am. Incidentally that are the default values used if you don't specify your own times. A word of warning: it seems that when the difference between the start and end time is too small things may go a bit wild - for example fog may start to get more dense rather then vanish over time etc. I didn't test it exhaustively but it looks like the difference of 30 minutes or more is big enough.

back to top of page

Color Map feature and daylighting conditions

What is color map? Well, it seems to be one of these things which everybody see and enjoy but nobody notice - until it is missed. Once you apply the Universal Patch or in other way manage to load the map through MultiCampaign mechanism you will immediately notice its missing and likely start to appreciate the very feature. The fact is that all custom campaign's maps are displayed using night daylight conditions (hmm... sounds like oxymoron?:) with no single sunbeam touching the slopes of hills - monotonous dark green colour everywhere. It is not only a bit depressing but also makes virtually impossible feeling of the elevation differences without setting GRID option ON. With GRID ON battlefield looks much better - at least it should not hamper game playability.
So the main purpose of using color map is clear - visualisation of the battlefield's third dimension. It is achived by applying subtle variations of brightness. Carefully positioned stains of light are supossed to emphasize the sunny slopes of the hills; dark spots are to accentuate the valleys (and the opposite slopes). ANGV however extends that concept and uses color maps to implement the daylight conditions which are variable over time. That feature allows the simulation of dawn and dusk periods, wandering of the sun in the sky and even (potentially) some weather conditions (like cloudness of the sky). Nothing comes without the price however. WNLB needs only one color map - it is contained in the Graphics\TeenieMap.raw file; ANGV uses 24 color maps contained in Graphics\AuserMap_00nn.raw files (where nn is in range 00-23). Two other color map files available in ANGV (that is AusterMap.raw and TeenieMap.raw; the later seems to be just leftover from WNLB) are apparently not used. I thought initially that the numbers in the AusterMap file names correspond simply to the hours of the day. As usual reality turned out to be more complicated however.

So how really ANGV uses its 24 color maps? It is somewhat fancy but lets try to catch it. The engine checks which color map should be used every minute of the game time. The procedure called for that purpose uses two variables: DayStart, DayEnd and the current game time CurrentTime. First the DayStart is decremented by two hours and DayEnd incremented by the same interval. It is apparently done to take into account dawn and dusk conditions so lets call such modified variables DawnStart and DuskEnd. Then if...
CurrentTime < DawnStart => color map 00 will be used,
CurrentTime > DuskEnd   => color map 23 will be used,
DawnStart < CurrentTime < DuskEnd the color map number to be used is calculated by the following formula:

24 * ((CurrentTime - DawnStart)/(DuskEnd-DawnStart))
The result is of course rounded down to the nearest integer value. It is also needless to say that the color map is reloaded from corresponding file only if the calculated number differs from the result obtained a minute before. Lets see it on an example. Assume DayStart=0700 and DayEnd=1900 (these happen to be default values for the custom campaigns; for Austerlitz that values are 0733 and 1603 respectively). In that case game will use color map 00 until 5:40am, just in the moment of sunrise (7:00am) engine will switch to color map 03, (...) , at the sunset (7:00pm) it will go for color map 21 and finally starts to use the last map 23 at 8:20pm. Surely, not in every case calculations are going so smoothly nor are giving results aligned so well! :)

What will happen if the color map prepared for Waterloo or Austerlitz battlefield will be applied to the custom campaign's map with different topography and (usually) different dimensions? Effect is easy to predict. The stains of light and dark will have no relation to the actual topography. That may look somewhat odd and misleading. Certainly it is rather matter of taste if this is more disturbing then monotonous darkness. Nevertheless BAG apparently decided that darkness is better and by design disabled loading of color map for custom campaigns. In that case the color of the square should be determined by the contents of the Graphics\GroundColor.raw file. That is only the theory - because of the apparent bug instead of the value defined in aforesaid file (almost) always the value of RGB=(0,0,0) is used. Lets defer the discussion about GroundColor mechanism details (including its file format and bug fix) to the later paragraph.
It is worth to note that behaviour of ANGV and WNLB differs here. ANGV (and French version of WNLB) don't use color maps in custom campaigns and as a result produce night-like effect (of course to see it in the ANGV you will have first to apply the Universal Patch to fix the FOG initialisation problem as described in the section above). US edition of WNLB however always attempts to load color map (TeenieMap.raw) and reverts to the ColorGround (with the same results) only if it fails to open the color map file.

What is the format of the color map files? Like fog file they are binary files; and like may other MAPDATA related files color map file is expected to be two dimentional matrix of values. Dimentions of the matrix are (of course) to be the same as dims of the given custom map and each value corresponds to the single map square. What is unique for color maps the single value is in that case three bytes long. That value is (you guessed :-)) just the color specifid in device independent RGB format (Red comes first in the file). Quite flexible solution, I think. One remark seems to be on place here. Though the colors in the file are specified in the 24-bit RGB form the graphics engine works internally with 16-bit '565' colors (or with 15-bit '555' form; it depends on device caps). So the RGB values have to be translated during loading process to the internal form. In practice it means that if you specify two similar R color values they may be translated into single R color value internally (more precisely lower three bits of every R, G, B byte are meaningless to the engine).

There is one essensial side effect of the color map loading process which may be very important for people trying to prepare custom maps for WNLB (US version). As said above for the map of the X*Y size the color map file is expected to contains 3*X*Y bytes. If the program fails to open the file (likely because it does not exist) it will revert to use the GroudColor/darkness lighting conditions. If the file exists however then - because of the details of color map loading - if the file size is lower then expected (like in the case of custom map BIGGER then standard Waterloo 145*100 map AND standard Waterloo TeenieMap.raw file) the program crash during the initialisation phase is virtually inevitable. To avoid that you should extend the size of your color map file to be at least the mentioned 3*X*Y bytes. For the biggest WNLB map (255x255) the TeenieMap.raw extended to the size of 196608 bytes should be enough. One way to extend the file is by using the HEX editor. If this is not feasible at the moment you can try following quick and dirty appoarch: open your command shell (DOSBox window), go to the GRAPHICS directory of your WNLB game, and being there type the following commands (backup original TeenieMap first!):
copy /B TeenieMap.raw+TeenieMap.raw Temp.raw
del TeenieMap.raw
ren Temp.raw TeenieMap.raw

These three commands should double the size of color map file. Repeat as many times as needed :). Surely it's far from perfect but at least it should let you avoid crashing when loading large custom maps in WNLB. Note that once you apply Universal Patch to the ANGV you will have the chance to use existing (or create own) color map(s) for the custom campaign's maps. If you decide to use that option that paragrapth will apply to you too.

What if one wants something more however? How to create color map which will correctly express topography of the custom campaign's map? Doing it by hand - using HEX editor - looks like a never-ending job even if one decides to limit himself to only one color map (remember that to provide variable daylight conditions one needs to create 24 maps! :-/)
Like in case of FOG file the fully-fledged map editor would be the ultimate, as yet remote solution. And like for FOG it seems to be possible to write simpler program which would generate color map(s) based on the Elevation data and couple of aditional params like campaign date, latitude of the battlefield location, maybe also some weather info. Any volunteers? (:-) Well, once you read about GroundColor Fix in paragraphs below you may come to the conclusion that this issue is not so urgent... Still I think it would be good to have such mechanism available.

As said above patched ANGV allows you to use the color maps(s) on the custom campaign's maps in the way similar to the standard Austerlitz campaign. To enable that feature you should set the ColourMap property in the [extension] section of campaign's CONFIGnn.CFG file. The default for that property is 0 (disabled). When ColourMap=1 ANGV engine should behave like WNLB (US ver.). That is it should try to load the single color map - the variable daylight feature is to be disabled. Default name of that file is Graphics\ColourMapCnn.raw (nn here are two digits of campaign number). You can change the name of the file by using ColourMapFile property. (Warning: when using that option don't specify the file extension! '.raw' extension is appended automatically)
Setting ColourMap=2 tells the engine to handle custom campaign's maps exactly like the standard one. That is it will use variable daylight mechanism and will need all 24 color maps for that purpose. By default the engine looks for the color maps in the files named Graphics\ColourMapCnn_00hh.raw. Here nn is campaign number and hh is the color map number (00-23). Again you can specify different name(s) using the ColourMapFile property. Please, note that in that case both file extension and the _00hh postfix are appended automatically. Don't specify them!. Couple of examples should makes things more clear:
When ColourMap=1 and ColourMapFile=Graphics\TeenieMap the engine will try to load standard Waterloo color map (installed by default in ANGV folder GRAPHICS). Note that in that case you will not be able to load map for which X*Y > 14500 - until you extend the original TeenieMap.raw file.
When ColourMap=2 and ColourMapFile=Graphics\AusterMap the engine will use standard set of 24 color maps prepared for Austerlitz battlefield. (Graphics\AusterMap_00hh.raw files). In that case the largest map is one for which X*Y <=18750 - again until you extend all the relevant files.
Finally when ColourMap=1 and ColourMapFile=Graphics\AusterMap the engine will try to load single color map AusterMap.raw. That file is also installed (but not used) by default in GRAPHICS directory. Usual limitation of X*Y <=18750 apply.
Normally when ColourMap=0 the engine falls back to the standard GroundColor/darkness behaviour. I provided a couple of experimental options (I don't think they will be usable for real map's development) which modify somewhat that behaviour. Setting the SwitchColourOn=1 property (default is 0) will let you specify the single color which will be used to init in-memory color map array. You specify that color using set of three properties Colour{R,G,B}. Allowed values are in the range 0-255. 255 means the highest intensity of the given color component and is default value.
And finally the all-important last pair of properties: DayStart and DayEnd properties. They should be provided using military time format (like 0700 or 1900 - no separator). They are used in the implementation of the variable daylight conditions as described above. Naturally they are also used to determine when the night condition is to be applied (which in turn infuences the battlefield visibility and some movement and combat penalties). That properties may be specified in the campaign's CONFIG file or globally (in the [extension] section of Austerlitz.ini file). The former takes the precedence over the later; the later (if specified) is also applied to the standard Austerlitz campaign. If none are specified the engine is using the hardcoded defaults (which are different for custom campaigns and Austerlitz one).

Time for couple of pictures to illustrate concepts described here. All pictures were made using one and the same campaign config file (config44.cfg). It is prepared so that it just loads the standard Austerlitz campaign's MAPDATA assets through MultiCampaign feature - so it is useful to verify the transparency of of the MultiCampaign mechanics. Note that these pictures suggest that there is something wrong with JumpMap displaying. But that's different story...

Going from upper left to lower right:

  1. Darkness: This picture was achieved after applying Universal Patch but with all related options switched off (ColourMap=0 and SwitchColourOn=0)
  2. This is similar picture but with ColourMap=2 and ColourMapFile=Graphics\AusterMap. In other words it uses color map from the standard set of 24 Austerlitz color maps. Which one exactly was used at the moment I can't really tell you because I don't remember what were values of DayStart and DayEnd properties when I snaped the picture (and anyway I'm relucant to make necessary calculations right now! :)
  3. That's really bloody one... Here ColourMap=0, SwitchColourOn=1, ColourR=255, Colour{G,B}=0. No color map file is used. Instead whole color map array was initted with one RGB color.
  4. This is similar situation. The only difference is that all Colour{R,G,B}=255. This shows how Austerlitz battlefield could look if the December 1805 was more snowly. (A bit different color could represent Egyptian deserts for example :).
  5. Here ColourMap=1 and ColourMapFile=Graphics\TeenieMap. So it loads the Waterloo TeenieMap.raw file. It visualizes the situation when color map is not prepared for the real map topography. Note also the darkness in the southern part of battlefield. It is because to use TeenieMap.raw with Austerlitz MAPDATA assets I had to extend color map file. I fill the additional space with zeros and these translate to the darkness near the south edge.
  6. Similar example: ColourMap=1 and ColourMapFile=Graphics\AusterMap. It uses the single AusterMap.raw file from GRAPHICS folder.
  7. How was this picture gathered? No, I didn't prepare special color map file to get such fancy picture (and it does not come from LANDSAT database either :). It is a riddle for you... If you don't know the answer (hey you shouldn't know it ! :) read on the paragraph below...
  8. This picture is also an illustration for the following paragraph. :)

Time to talk about GroundColor.raw file, its format, how it was supposed to work and (last but not least) promised Fix. As explained above GroundColor is used in case when either color map is not loaded by design (ANGV custom campaigns) or the color map file does not exist (may be the case for both ANGV and WNLB US ver.)
Lets start from the file format. It is small binary file (768 bytes) and is treated by the engine as an two-dimentional array of 16x16 entries. Each entry is 3 bytes wide and is obviously RGB color just like in the case of color maps (Red comes first). And like for color maps its value is translated to the 16-bit color space during loading. Apparently only first four rows (each with 16 RGB values - 48 bytes) are intended to be used. Other are reserved for future use. How that four rows are supposed to be used? When it comes to choose the color to be used for the given square the engine first selects one of the these rows. Decision is made based on the terrain features. Most importantly for open terrain the first row is selected. Other rows are used as a background color source for other terrain assets (for example woods seems to use background colors from the third row). I'm not ready currently to specify exactly which terrian types use which row - lets treat it as an excercise for the future :). But how engine decides which one from the 16 row's colors should be applied to the current square? (hint: take one more look at the 7th picture above :). Accidentaly sixteen is the number of elevation levels allowed in the game... Yup! Engine uses the elevation of the given square as the index in just selected color row. Pretty elegant solution! Looks also very simple and logical once I understood it... but it took me some time to understand it! :)
So easy-peasy, all is dancing and singing... but why the hell the custom maps are displayed all in dark! The first row in the ColorGround.raw contains various colors - none seems to be responsible for the darkness however. As mentioned above there is apparently a bug in the code which affects the all-important first row of colors. Due to the bug instead of taking colors from that row engine takes the color from some wild, unrelated location (which seems to be always equal to zero). Life is cruel... Patched ANGV provides the option to fix that problem. To do it you need to set GroundColorFix=1 property (default is 0). It is global property - to be set in the [extension] section of Austerlitz.ini file. Of course to see the GroundColour mechanism at work you need to switch off color map usage in your campaign CONFIG file - that means both ColourMap and SwitchColourOn should be set to zero (that is the default for both anyway).
Back to the pictures above: The 7th picture was snaped when using modified GroundColor.raw file - with colors choosen somewhat arbitrary for testing purposes. Next 8th picture uses the standard GroundColor.raw file as provided by BAG. It is not looking bad, I think. The question if it is better then color map version is (as usual) matter of taste. I personally would vote for fine tuned color maps. If only they were easier to prepare...

back to top of page

Jump Maps for custom campaigns

First time I managed to load scenario through MultiCampaign mechanism the thing which drew my attention (right after batlefield darkness) was strange apperance of Jump Map Frame. In fact this frame didn't appear at all. Frame area was completely transparent with the exception of menu buttons on the right side and groups of blue/red dots (representing units) spread in frame space (sometimes also outside of the frame - it depends on custom map size and units locations). Transparency in itself may be not bad thing - a bit more of main map is visible afterall. It is also easy to avoid by providing custom Jump Map bitmap in  GRAPHICS folder and specifying its name in JumpMapImage property (default is JumpMapNN.BM2; where NN is campaign number). However the real problem is that parts of the main map are unreachable by mouse clicking on the jump map area and that in cases where "jumping" mechanism works it often jumps to slightly (sometimes not so slightly) different parts of main map then expected.

What is source of problems? Proper working of Jump Map feature depends on consistent implementation of two fundamental transformations. One procedure is needed to transform main map coordinates (in squares) into jump map coordinates measured in pixels (and counted from the upper left of Jump Map bitmap). This is needed for displaying units (and VP locations) in right place on Jump Map bitmap. Second procedure is responsible for converting mouse click coords (in pixels) into main map coords (in squares). That is the essence of "jumping" functionality.
To do it properly code needs to know both X and Y dimensions of Jump Map (I mean here measured in pixels size of actual map rectangle on the Jump Map bitmap file) and its offset from the beginning of Jump Map bitmap (again in pixels). To understand better what that last thing means compare Jump Map bitmap for Waterloo battlefield with that for Austerlitz one. For first offset of map rectangle is 3 pixels down and 3 pixels right; for the second again 3 pels down but as many as 33 pels right (these numbers include 2 pels needed for the golden frame around Jump Map pane).
Program contains variables designed to hold that necessary parameters. They are inited to values which are proper for standard, Austerlitz campaign. Major problem is that there seems to be no way to specify different values for Jump Maps prepared for custom campaigns' maps. Together with something which looks like subtle bug in scaling calculations it leads to problems mentioned above.

Updated Universal Patch provides means to specify necessary values on per-campaign basis. So once you've prepared custom version of Jump Map for your campaign next - to get it working properly - you will have to specify four properties in [extension] section of campaign's  CONFIGnn.CFG. All four are numbers measured in pixels. First pair - JumpMapOffsetX and JumpMapOffsetY - defines place on JumpMap bitmap where actual map rectangle (its upper left point) begins. For JumpMapOffsetY please do NOT count upper 48 lines of transparent area which is necessary according to MAPCREATION.txt. Using again Waterloo JumpMap as an example proper setting here is JumpMapOffsetY=3 and NOT JumpMapOffsetY=51 (48+3).
Second pair of properties - JumpMapSizeX and JumpMapSizeY - is needed to provide dimensions of actual JumpMap rectangle. For example in case of Austerlitz standard JumpMap JumpMapSizeX=80 and JumpMapSizeY=95 should be right. As a designer of custom JumpMap you have to provide these four numbers to make the mechanism working correctly - chance that default values will be working for you is next to nil. Your freedom of choise is limited first of all by size of JumpMap pane (187x102 pixels not counting 48 upper lines which have to be transparent), next the fact that you will likely want to reserve couple of pixels for nice golden frame around the pane and last but not least the very fact that about 50 pixels on the right side of JumpMap pane will be anyway covered by Menu Buttons. Yet another limitation likely worth to comply with is preserving aspect ratio. If your main map is of size, lets say 150x200 squares (that means aspect ratio is 3:4) then preserving aspect ratio would mean that dimentions of JumpMap rectangle would be something like 72x96 pixels. Because you can specify JumpMapSizeX, JumpMapSizeY separately you do not have to obey aspect ratio limitation - you could decide to extend JumpMap picture in X axis and specify JumpMapSizeX=136 or whatever suits your desire. Still until you really think it looks better that way my advise would be to stick to aspect ratio defined by main map dimensions.

If you have read MAPCREATION.txt you would likely wonder how to get that simplistic version of Jump Map with main map's roads&pikes network indicated. Indeed it shows up in WNLB (assuming you did not prepare your own Jump Map of course). To achieve the same in unpatched ANGV it is enough to copy JumpMap01.BM2 into WaterMisc.BAG container. But even then it will suffer from the similar reasons like these described above: hardcoded mapping parameters. Still for some (main) map dimensions mechanism should work pretty well. Most likely for maps which dimensions are ALMOST equal but with Y dim slightly larger then X one. I suppose it may somewhat explain why the map dimesions of 145x150 are choosen at least for some battles of Peninsula Mod project.
Again Universal Patch attempts to correct scaling problems. By default engine displays simplified JumpMap in fixed place of the bitmap (corresponding to both JumpMapOffset{X,Y}=4) and calculates dimensions so that JumpMap rectangle uses largest possible part of bitmap but in the same time preserves aspect ratio of main map. This means that either JumpMapSizeX=136 or JumpMapSizeY=95 is choosen depending which better works with dimensions of campaign's main map.
Patched ANGV allows you also to customize that behaviour a bit. Namely you can specify bitmap which will be used as JumpMap pane background (lets call it canvas) - normaly engine fills the background with black color. The canvas will be used exactly like regular JumpMap bitmap except that you obviously should not put actual jump map picture on it - it will be drawn by engine itself. You can also make your canvas looking a bit more fancy (pictograms on JumpMap margins or something?) until you preserve JumpMap dimension requirements (and don't forget about that 48 lines of transparency too). You specify canvas file using JumpMapCanvasFile property in [extension] section of CONFIG file. For example if JumpMapCanvasFile=Canvas.bmp then engine will look for GRAPHICS\Canvas.BM2 file. If you specify canvas file then you are also responsible for providing yourself correct values for JumpMapOffset{X,Y} and JumpMapSize{X,Y} pairs. Engine will use them to position properly jump map drawn - this way you can avoid covering any special elements you put on your canvas. If you don't want any special graphics elements in JumpMap pane and don't mind black background then don't use JumpMapCanvasFile property - engine should take care about jump map position as described above. All that assuming of course that you don't want to hand-make your jump map picture.

Words of cautions: it has to be said that functionality described wasn't tested long enough to make me confident it will be working as expected in all possible combinations of conditions. Based on tests I made I still hope it will work correctly with your custom maps (assuming you provide correct values for properties described). In case of troubles I'd love to hear about them and will try to fix them as time allows me. In fact one of the problems with testing it was limited number of different test cases (different custom maps and jump map pictures). One another property which may be helpful in case of troubles is JumpMapFix. Setting this global property to zero disables JumpMap patch - so ANGV should handle JumpMap as original non-patched version. Note that it is default value and to get JumpMap feature (hopefully) fixed you need to put JumpMapFix=1 in [extension] section of Austerlitz.ini file.
One last remark... Part of JumpMap is white quadrilateral (well, more or less :) showing which part of main map is currently visible. Making it working properly meant replacing another set of hardcoded values by variables suited for given campaign's map. Sometimes this element is not displayed quite correctly (it is rare case; to replicate set the view direction to "North up" and click couple of times on jump map near to its south edge. Sooner or later you should notice that two longer sides of the figure are drawn crossed...). This little problem is present in unpatched ANGV and Austerlitz campaign and (I believe) it behaves exactly the same in patched ANGV with custom maps. As this is more like minor quirk then real problem and because it does not seems to be related to changes I've made I'm currently relucant to spend likely large amount of time to find out its source. Maybe in the future when there will be no more serious problems available to fix nor exciting features to implement... :)

back to top of page


   company's ANGV game page.
   company's Download page - AusterlitzDemo is available from here (about 36MB).
   company's Discussion Board for WNLB and ANGV games (amongst others). also covers WNLB and ANGV.
   THE ANGLE has its own discussion forum for WNLB and ANGV too.

     Shrapnel Games is the publisher of ANGV game.
   On the Shrapnel's ANGV Game Page you can order the game right now!
   (or you can go directly to their GamersFront on-line store page)

     Wargamer Austerlitz mini-site - couple of fine articles and more...

     Previous edition of Underground Page - based on Demo version.
   Still contains (I believe) some relevant info - and some misinterpretations! :)

back to top of page

Greatest Battles Main Page