MappyDX - Release 11B documentation

Index:

  Welcome
  Disclaimer
  Requirements, how to use
  About the Mappy DLLs
  dxdemo1, the example
  dxdemo2, the example
  Using MappyDX with the CDX games library
  Blt, BltFast, Clippers etc...

Mappy API:
  Mappy API reference
  MapLoad (char * , LPDIRECTDRAW);
  MapDecode (unsigned char * , LPDIRECTDRAW);
  MapFreeMem (void);
  MapInitAnims (void);
  MapUpdateAnims (void);
  MapDraw functions
  MapDrawRow (LPDIRECTDRAWSURFACE, int, int, int, void (*cellcall) (int, int, int, int));
  MapRestore (void);
  MapGenerateYLookup (void);
  MapChangeLayer (int layernum);
  MapGetBlockID (int blid, int usernum);
  MapLoadMAR (char * filename, int layer);
  MapDecodeMAR (unsigned char * marmemory, int layer);
  MapGetBlock (int x, int y);
  MapSetBlock (int x, int y, int layer);
  MapGetXOffset (int x, int y);
  MapGetYOffset (int x, int y);
  MapCreateParallaxSurface (LPDIRECTDRAW);
  MapDrawParallax (LPDIRECTDRAWSURFACE, int, int);
  MapRestoreParallaxSurface (void *, int);
  MapReleaseParallaxSurface (void);

  Troubleshooting
  Hints and tips
  Version History


Welcome


  This code library provides functions to access and display FMP maps made by the Mappy tile map editor. Use of this library is free and you may modify it as you like, it would be nice to get a credit and link to the Mappy site if you use it in your game, but that is up to you. The previous version was tested with Visual C++ 4.0, Visual C++ 5.0 and Borland C++ 4.51 with various DirectX SDK, I have only been able to test this version with MingW32. If it doesn't work on your compiler and you think it should, let me know immediately and I'll fix it! For changes since release 2, see the version history.

  Please take the time to look at this documentation. If you want to contact me, please email me at mappy@tilemap.co.uk.

  Mappy homepage. The current Homepage for Mappy is: http://www.tilemap.co.uk or http://www.geocities.com/SiliconValley/Vista/7336/robmpy.htm or if all else fails: http://surf.to/mappy

(top of doc)


Disclaimer

  This software and associated files are provided 'as is' with no warranty or guarantees of any kind, you use them at your own risk and in doing so agree that the author is in no way liable and cannot be held responsible for any loss of time/data/hair or anything else that may occur either directly or indirectly from the use of this software or associated files.

  Sorry about that, but I don't think it's fair that I get sued for something I release for free, just remember to keep backups and you'll be fine. I have never lost any data or files or had Mappy screw anything up, just be aware that if it does I can't be held accountable :)

(top of doc)


Requirements, how to use

  You will need a PC with a C++ compiler that supports and has installed the DirectX SDK version 3 or later, you will also need this library and the Mappy editor (to make your FMP files). You will need to include the file 'mappydx.cpp' in the list of files that are in your project, and include the file 'mappydx.h' in any source files that need to call Mappy functions. Alternatively you can use the DLL (by using the file mpydll.h).

  Use of the library is through a simple API (see Mappy API reference), and the easiest way to see how it works is through the included example dxdemo1, as described in the next section...

  After you have initialised DirectDraw, you pass the DirectDraw object and the name of the map file to the Mappy function 'MapLoad', or the DD object and the memory address of the FMP data to 'MapDecode', if it is successful, you can then call MapInitAnims (); then go into your gameloop, inside which you can call MapUpdateAnims (); and the MapDraw functions. Should you lose your surfaces and need to restore them, call MapRestore (); When you've finished with the map, call MapFreeMem to remove it from memory. It's that easy.

(top of doc)


About the Mappy DLLs

  In response to requests to be able to use MappyDX from non-C++ languages I have put MappyDX in a DLL. To use it from C or C++ is fairly simple, just #include "mapdll1.h", make a .lib (from the .dll and .def) and use it normally. For other languages you should look for downloads from their pages, or make your own (I know there is one for DelphiX, for example).

  There are a few important differences between mappydx and mappydll. First, you must know which version of the DD interface your language is using. MappyDX1.dll uses interface 1, MappyDX4.dll uses interface 4, if you need a different one, let me know and I'll compile it. Second, the #defines in MappyDX are replaced by functions:

void MapSetDrawArea (x, y, width, height); //Default is 0,0,640,480
void MapSetParaSize (width, height); //Width and height of parallax
void MapSetPalette (LPDIRECTDRAW, LPDIRECTDRAWSURFACE); // Sets palette in 8bit (after MapLoad)
void * MapGetPtr (int); //does nothing yet
int MapSetPtr (int, void *); //does nothing yet

int MapGetVal (int); // Use this to READ vars, see the MPY_ defines (1 to 17 only) in the .h files, example:
mymapwidth = MapGetVal (MPY_MAPWIDTH); // Get the mapwidth (after MapLoad)

int MapSetVal (int, int); // Use this to WRITE vars, these MPY_ vals only:
MapSetVal (MPY_BLTTYPE, 0=BltFast 1=Blt(default));
MapSetVal (MPY_MEMTYPE, 0=Vidmem then Sysmem (default) 1=Sysmem); // Before MapLoad
MapSetVal (MPY_8BITTOPINK, 0=No conversion 1=Convert (default)); // Before MapLoad

(top of doc)


dxdemo1, the example

  Don't be put off by the amount of code in dxdemo1.cpp (about 350 lines) as most of it is just setting up Windows and DirectDraw, there are only about 20 lines directly related to Mappy. First, note that mappydx.h is included:
#include "mappydx.h"
This is needed to access any of the Mappy functions. The next point of interest is line 366, the Mappy function 'MapLoad' is used to try to load the map, DirectDraw must have already been started, and if you are loading a high/true colour FMP onto an 8bit display you must have set the palette too. If you are using Visual C, be aware of the current directory, it may not be the same as the one with the executable in when you run it from DevStudio. At line 375, the Mappy structure mappept is used to set the palette, this is only valid for 8bit FMP files after they have been loaded. GameInit is called which calls MapInitAnims (); which resets the animations to their starting positions. In the main gameloop, simply call MapUpdateAnims (line 120) to advance the anims, then the MapDraw functions you want to use. If you want to draw sprites between the background and foreground, simply draw them between the calls to MapDrawBG and MapDrawFG. If you want to draw the background transparently, call MapDrawBGT instead of MapDrawBG.

  You will need to add mappydx.cpp to your project files, you will also need to adjust the defines in it if you don't want the defaults. This is particularly important if you are supporting more than one resolution. To do it, open mappydx.cpp and find near the top the small section of #defines that you can change. You can either change these to other fixed values, or to variables. The advantage of defining to variables is you can change things in runtime, example:
#define MSCRW screenw
#define MSCRH screenh
will make MappyDX use those variables instead of fixed values, you can then declare them as external (if you are keeping them in another source file):
extern int screenw;
extern int screenh;
This is exactly how I did it for the MappyWin32 editor where you could set your screenmode and load in a map with any sized tiles.

  To compile the example, make a new project and add the files dxdemo1.cpp, dxdemo1.rc, mappydx.cpp, and ddraw.lib. Make sure all those files are in the same directory along with mappydx.h, mylogo.bmp and myicon.ico and also the FMP file you are going to use. You should now be able to compile and run the example, if you can't, see the Troubleshooting section.

  I have now added parallax functions (release 5) and dxdemo1 has been altered to use them (fullscreen only).

(top of doc)


dxdemo2, the example

  Same as dxdemo1, but for Isometric, uses MapDrawRow, to depth sort everything. It uses the same BMP as demo1, so the title etc is wrong.
  To compile the example, make a new project and add the files dxdemo2.cpp, dxdemo1.rc, mappydx.cpp, and ddraw.lib. Make sure all those files are in the same directory along with mappydx.h, mylogo.bmp and myicon.ico and also the FMP file you are going to use.


Using MappyDX with the CDX games library

  Note: An add-on class called CDXMappy is available at the CDX site which should offer a more 'C++' way of displaying maps.

  I was asked to add support for CDX in MappyDX, and you can use it if you change some defines, but CDXMappy is much nicer to use.

  CDX's homepage is currently http://www.cdxlib.com
  CDXMappy is currently on the main mappy site

(top of doc)


Blt, BltFast, Clippers etc...

  One thing I didn't realise until recently was that BltFast (the method MappyDX used to use to draw the tiles to your surface) does NOT work when you have attached a DirectDraw clipper. Because of this, you can now tell MappyDX to use Blt or BltFast, this is a define in the user settings at the top of mappydx.cpp. Also, I have added the option for you to specify system memory instead of video memory for the tiles. This is achieved by changing the RBCAPS_TYPE define in mappydx.cpp, setting it to system memory also requires that you use Blt (BltFast only works on video memory). I would only recommend having tiles in system memory if you are rendering to a system memory surface, otherwise it will be a lot slower.

  In summary, leave it as default (using Blt and video memory) unless you know you need a different system.

(top of doc)


  There are currently only a few functions in the Mappy API, but you can also access variables, they should be self explanatory, but see the Hints and tips section for a few hints. This release has full FMP1.0 support.

int MapLoad (char *, LPDIRECTDRAW);
  Loads the map with the path and name specified into memory so it can be used, this function or MapDecode must be used before calling other Mappy functions. Returns 0 on success, -1 on failure.

int MapDecode (unsigned char *, LPDIRECTDRAW);
  Same as MapLoad, but you pass the memory address of FMP data instead, this can be useful if you store the map in a compressed file, this function or MapLoad must be used before calling other Mappy functions. Returns 0 on success, -1 on failure.

void MapFreeMem (void);
  Frees the current map and all associated memory and surfaces Mappy is using.

void MapInitAnims (void);
  Resets animations to their initial values.

void MapUpdateAnims (void);
  Increments animations.

int MapDrawBG (LPDIRECTDRAWSURFACE, int xoff, int yoff);
int MapDrawBGT (LPDIRECTDRAWSURFACE, int xoff, int yoff);
int MapDrawFG (LPDIRECTDRAWSURFACE, int xoff, int yoff, int gfxlayer);
  These functions all draw to the surface specified, and at the x and y offset given, for example, if you call MapDrawBG (lpDDSBack, 1000, 2000); the area of the map 1000 pixels from the left edge and 2000 pixels from the top will be drawn to the lpDDSBack surface. The size and positioning of drawn area is dependant upon what MSCRW, MSCRH, MMOX and MMOY are defined as (alter these settings at the top of mappydx.cpp), if they are variables, make sure they are correct before calling these functions. Attempting to draw outside the surface, or an area outside the map will probably shutdown the program. So don't do it :) MapDrawBG draws the BG layer without transparency, so it will completely overwrite the specified area. MapDrawBGT draws the BG layer with transparency, any 'block 0' or pixels of the transparent colour won't overwrite the area you are drawing. MapDrawFG is the same as MapDrawBG except for FG layers, you specify 0, 1 or 2 as the last paramater for the FG layer.

int MapDrawRow (LPDIRECTDRAWSURFACE, int xoff, int yoff, int maprw, void (*cellcall) (int, int, int, int));
Same as MapDrawFG, except:
int maprw is the row to draw
cellcall is a callback function for each cell, pass NULL if you are doing your own depth sorting, or using another system. See dxdemo2.cpp for an example of this.

void MapRestore (void);
  If you lose your surfaces (for example if someone alt-tabs), you can call this function to restore them.

int MapGenerateYLookup (void);
  This is optional, call this after MapLoad or MapDecode (or variant) and it will generate a lookup table that _may_ slightly speed up the functions MapGetBlock and MapSetBlock, and allows you to use the maparraypt. If you use this, you _must_ use MapChangeLayer if you want to swap between layers. Another advantage is you can access block or anim offsets simply with:
maparraypt[y][x];
Where x is the offset from the left in _BLOCKS_, and y is the offset from the top in _BLOCKS_. Note you can get the actual block structure with the functions MapGetBlock and MapSetBlock.
  The memory allocated is freed when either MapFreeMem is called, or another map is loaded.

int MapChangeLayer (int layernumber);
  This changes to a different map layer, returns -1 if failed, or the new layer number (0 to 7) if successful.

int MapGetBlockID (int blid, int usernum);
*nbsp; returns the number of the first block that matches 'blid' in the field specified with usernum (1 to 7, user1 to user7). If no match, returns -1

int MapLoadMAR (char * filename, int layer);
int MapDecodeMAR (unsigned char * marmemory, int layer);
  Loads a .MAR file into a specified layer. Decode does it from memory, you can dealloc that memory afterwards. If you called MapGenerateYLookup, call it again after this function. Returns -1 on error, 0 on success.

BLKSTR * MapGetBlock (int x, int y);
  Returns a BLKSTR pointer, useful for collision detection and examining a blockstructure. Note: the x and y paramaters are the offset from the left and top of the map in _BLOCKS_ NOT pixels. Example:
BLKSTR * myblkstr;
myblkstr = MapGetBlock (xoffinblocks, yoffinblocks);
if (myblkstr->tl) { top left collision is set for this block }

MapSetBlock (int x, int y, int strvalue);
  The x and y paramaters are the offset from the left and top of the map in _BLOCKS_ NOT pixels. If strvalue is positive, the cell is set to that block structure. If strvalue is negative the cell is set to that anim structure-1 (ie if you want to put anim 3 in, strvalue would be -4).

int MapGetXOffset (int x, int y);
int MapGetYOffset (int x, int y);
  Returns the X or Y offset in blocks of the specified pixel coordinates. This is very useful on maps with non-rectangular blocks as it is pixel perfect.

MapCreateParallaxSurface (LPDIRECTDRAW);
  Creates a surface for the parallax graphic of the size PARAW*PARAH. These are defined in mappydx.cpp, you must call this before using the other parallax functions. Remember to draw the graphics afterwards using MapRestoreParallaxSurface. Note that the surface is freed on a call to MapLoad, MapDecode or MapFreeMem.

MapDrawParallax (LPDIRECTDRAWSURFACE, int, int);
  Efficiently draws to areas that will not be obscured by layers above it (minimal overdraw). The x and y coords passed should be the SAME as to MapDrawBGT etc, these are automatically halved. The parallax surface will be tiled over the surface. Remember to use MapDrawBGT instead of MapDrawBG if using this function. Be sure your map has the transparency bit set for any blocks with transparent pixels in them (especially block 0). This only works with rectangular tiles.

MapRestoreParallaxSurface (void *, int);
  Call this after calling MapCreateParallaxSurface to render the parallax graphics, also call if MapDrawParallax returns -1. If you pass NULL as the source, it's assumed you have blitted the parallax bitmap to lpDDSParallax.

void MapReleaseParallaxSurface (void);
  Frees the parallax surface, you shouldn't normally need to call this as it is called by MapFreeMem.

(top of doc)


Troubleshooting

  Don't worry if you get messages like 'may lose significant digits', when compiling mappydx, that's normal.

  If you get messages like 'unknown type _LPDIRECTDRAW' you haven't got your DirectX SDK setup properly on your compiler, make sure ddraw.lib is in your project files.

  If you keep getting 'can't load map' messages on the demo, ensure you have a compatible FMP file in the same directory as you are running from, and it has the same name as needed in dxdemo1.cpp

  If your programme exits or crashes when you try and draw a map, make sure you have changed the defines at the top of mappydx.cpp

  If you are loading an 8bit map onto a high colour screen, make sure the transparency colour is defined correctly, see hints and tips below for a useful idea

(top of doc)


Hints and tips

  Although you can still change the map array layer by doing:
mappt = mapmappt[layer]; where layer is a VALID layer number.
There is now a function called MapChangeLayer which you should use instead, in fact you must use MapChangeLayer if you have called GenerateYLookup

  If you are loading an 8bit map to a high or truecolour screen, the transparency index will be changed to the truecolour value. If you don't want this behaviour, change the RB8BITTOPINK define in mappydx.cpp or change the 24bit colourkey to 000000 in MappyWin32.

  A collision detection example is now given in MapGetBlock

(top of doc)


Version History

Release 11B:

  Fixed error in MapDecode

Release 11:

  Fixed incredibly insignificant accuracy error in 15bit loader (no noticeable effect)
  New map for dxdemo1 (TEST2.FMP, better size blocks)

Release 10:

  Small fixes and tweaks
  Examples show windowed mode
  You can specify the left or right side of a pillar with bits 2 and 3 in 'others'

Release 9:

  Small fixes and tweaks
  Mappy in a DLL!

Release 8:

  MapDrawRow function and dxdemo2 example

Release 7:

  Many many changes inc:
  Full FMP1.0 support
  100% accurate 15/16bit to other conversion (no more 0xF800F8 :)
  Non-square tile support (Iso, hex etc)

Release 6:

  You can specify where to store the tiles (system or video memory)
  You can use Blt instead of Bltfast if you want

Release 5:

  Added 4 efficient (minimal overdraw) parallax functions

Release 4:

  Fixed function MapDecode (wasn't working before)
  Added MapGenerateYLookup, MapChangeLayer, MapGetBlock and MapSetBlock functions
  Added #defines to mappydx.cpp to allow specifying a version of a DirectX interface
  Added support header and example for CDX

Release 3:

  Much faster loading of graphics to surfaces
  Can now use tiles whose widths are different to height
  All colourdepth conversion
  General tidying up
  Decent documentation

Release 2:

  structsize fix for Visual C compilers

Release 1:

  Original version, pretty good for a first release

(top of doc)


This documentation is for MappyDX Release 11B by Robin Burrows 7/5/2002.

Homepage 1 - Homepage 2