DMDX Help.

Bitmap notes.

    A rather cool thing is the ability to make the background of a bitmap transparent using a feature of DirectX called Color Keying. A graphic frame with the <ColorKey> switch set will examine the color of the top left pixel of the bitmap and when adding that graphic to the displayed frame all pixels of that color will not be copied. Especially handy if you have changed the background color or your bitmaps do not have a white background.

    If you are importing large numbers of .IMG files from DMTG using IMG2BMP.EXE you will not need to stretch the images using some other image manipulation program, DMDX can do it with the
<DefaultBMPMultipliers> switch, typical values for stretching EGA images being <dbm 1.0,1.371>.

Stretch Blt modes.

    For the longest time whenever you wanted to scale a bitmap smaller with the bitmap multipliers you could get some fairly ugly artifacts until I stumbled across the win32 SetStrechBltMode function and nowadays you put something like <dbm 1 HALFTONE> in your item file and down scaled bitmaps are just fine.  Up scaled bitmaps have always been more or less fine (beyond the obvious fuzziness issues that are inherent in magnifying data).  Why is this important?  If you want to build an item file that runs on a number of machines that uses bitmaps and you want a fairly consistent experience from one machine to the next you'll want to provide higher resolution bitmaps that you scale down using a fraction of the screen's dimensions otherwise depending on the screen resolution on the machine the sizes of the bitmaps will change (assuming you're using <vm desktop> and these days you really should be using it, the days of being able to run everything at a fixed display resolution are all but past).

    Speaking of making an item file running on multiple machines with scaling bitmaps you'd probably also want to know the aspect ratio of the screen your item file is running.  Maybe you can get away with assuming a 16:9 widescreen device regardless of it's resolution and scale those bitmaps down to a fraction of the screen width nicely but if not in the past you'd have been stymied pretty good, however these days you can actually detect the aspect ratio using the expression tokens VideoModeX and VideoModeY (see the <SetCounter> help).  You've got two choices here, one (as long as the aspect ratio of all your images is the same, if not see the second option) is to detect the aspect ratio like the <Instruction> help does and then passing one of two macros (one for 4:3 screens and another for 16:9) to all your <bmp> keywords that determines the upper left and lower right corners for your bitmaps.  The other option involves knowing the size of each bitmap which is perhaps more labor intensive (unless of course they're all the same) but is less prone to accidentally distorting an image as it involves using the bitmap multipliers that carefully preserve image aspect ratios.  Here you'd have to use a two items per presentation, one to set up a couple of macros that have the scaling factor for that that image and because DMDX has no floating point stuff available we'll fudge it with with 4 digit fixed point calculations using the fixed point set option FXPSET in the macro keyword and one more to display it using the macro in a <bm> keyword.  In the following example the bitmap being displayed is 2048 pixels high and we're aiming to display it as half the screen height:

~1 <macro fxpset 4 f = (videomodey * 10000 / 2048) / 2>;
+101 <bm ~f halftone> <bmp> "image" * ;

    Both this method and an older one not using FXPSET are demoed in the graphics portion of the features test demo FEATURES.RTF in this archive:

    With the addition of relativeclicklogging in the <2Did> keyword a good opportunity arose to demo scaled bitmaps and the ability to click on a specific region, or at least to ask a subject to do so and see if they got it right.  Because we're using the normalizedata <2Did> option this item file works across multiple display sizes (essential if you're going to be using it for remote testing).  The bitmaps here are found in the demos archive mentioned above.  The key thing about this demo is using <sc> to store the coordinates that the bitmap was rendered to and then using <sbr> to set the rectangle for the button defined in the <2Did> statement to those stored coordinates so different aspect ratio bitmaps will all be handled correctly -- however in order to do that we have to actually display the text before we can change the button rect.  Unlike other uses of <sc> and <sbr> (say <expireif>) we can't just present the bitmap in the same color as the background before testing the subject as bitmaps aren't (easily) obscured (you could present a white rectangle over it I suppose) we just present it for two ticks beforehand gathering the coordinates of it's display and then present the item that gathers the response click making sure that it doesn't erase the preceding display of the bitmap with <noerase>.  Other interesting points here include the fact that bitmaps are smaller than the requested display size (a third of the width of the screen) in most cases so we're scaling them up (most of the time anyway) with the halftone scaling method.  Also of interest is presenting them with an <inst> keyword with the explicatory text in the right half of the screen:

<fd 30> <cr> <id #keyboard> <!ntl> <t 100000> <nfb>
<2Did mouse relativeclicklogging,100
<xyjustification framebyframe> <inst hardmargin>

~1 ml++ mt++ mr++ mb++ <mpr +bitmap>;

~1 <macro fxpset 4 f = (videomodex * 10000 / 350) / 3> <! GOLFTP is 350 px wide>;
1 <xyjustification center> <xy .25,.5> <dbm ~f halftone STAT> <bmp> "GOLFTP" <sc l, t, r, b>;
+101 <delay 2> <inst .5,.3,.9> <sbr bitmap,~l, ~t, ~r, ~b> <noerase> <xyjustification leftbottom>
"In ", "this ", "experiment ", "click ", "on ", "the ", "flag ", "in ", "the ", "image ", "on ", "the ", "left" * ;

~1 <macro fxpset 4 f = (videomodex * 10000 / 320) / 3> <! WINLOGO is 320 px wide>;
1 <xyjustification center> <xy .25,.5> <dbm ~f halftone STAT> <bmp> "WINLOGO" <sc l, t, r, b>;
+102 <delay 2> <inst .5,.3,.9> <sbr bitmap,~l, ~t, ~r, ~b> <noerase> <xyjustification leftbottom>
"In ", "this ", "experiment ", "click ", "on ", "the ", "flag ", "in ", "the ", "image ", "on ", "the ", "left" * ;

0 "Done";

    If we use clicklogging instead relativeclicklogging we can use the data logging macros and add a line after items 101 and 102 to display a character over where they clicked:

0 ! "X" <xyjustification center> <xy ~.dataloggingx.,~.dataloggingy.>;

Alpha Blending.

    Another cool thing is the ability to alpha blend two (or more) frames together -- although this looks busted these days and is explicitly unavailable when using the Direct3D renderer. An alpha blend adds two frames together as transparencies, a succession of frames with alpha values changing from 1.0 to 0.0 in small increments will fade from one frame to the next. As with all DMDX color things a 16 bpp (bit per pixel, 65535) color mode is nearly essential. It works with all types of frames with the likely exception of Digital Video frames regardless of how many colors or what was used to make the frame. It is fairly CPU intensive to prepare (I have not written a very efficient algorithm, it does however work with everything), check your preparation times if you intend to use REQSHED or the D parameter. To blend from the word "first" to the word "second" in 6 steps the following item would be used:

0 "first" <as> / <ab .8> "second" / <ab .6> "second" / <ab .4> "second" / <ab .2> "second" / "second";

    The first frame's switch <as> (or <AlphaSource> if you like) causes it to be stored as the alpha source for all following blends in that item, after that it is discarded, you can't blend across items. The next four frames will be a combination of the words first and second and the last frame is only the word second, <ab 0> being equivalent to no blending. Each frame is generated in the normal fashion and then blended with the surface that was stored with the most recent <as> switch -- they are not blended with the previous frame (and if you put non-erase switches in very odd things would happen). An interesting thing to note with only four steps in the blend is that this could be displayed by a 256 color display as the default windows palette contains four shades of gray -- however four steps is a pretty crude blend, a much better instance that requires a 16 bpp display is:

0 "first" <as> / <ab .95> "second" / <ab .9> "second" / <ab .85> "second" / <ab .8> "second" / <ab .75> "second" / <ab .7> "second" / <ab .65> "second" / <ab .6> "second" / <ab .55> "second" / <ab .5> "second" / <ab .45> "second" / <ab .4> "second" / <ab .35> "second" / <ab .3> "second" / <ab .25> "second" / <ab .2> "second" / <ab .15> "second" / <ab .1> "second" / <ab .05> "second" / "second";

    An interesting thing to note is that you can store a new alpha source in any frame leading to the ability to blend a bit to one word and then change to a new word (whether anyone would ever want to do this is another thing).

Image Loading time issues.

    If people require the fastest possible loading of bitmap displays for low ISIs (usually because they are using continuous running with an FMRI image sequence) they should convert their bitmaps to 256 color .BMP files, however they should still use a 16 bit display, or possibly a 24 bit display. Because the image is displayed on an RGB surface the fact that it's encoded as a 256 color palletized surface doesn't matter, no changing of colors to match a system palette occurs (some changing does occur as a 16 bit surface is 5 bits of red, 6 of green and 5 of blue whereas a 256 color palette has 6 of everything but that's trivial or if it does matter use a 24 bit display mode) and because each image is encoded separately the palette for the image can be super fudged by the conversion program to match the colors in the image and it's impressive what a bit of dithering will achieve. 800x600 8 bit .BMPs load in 50ms on my test bed (preparation A times) vs. 150ms for 24 bit .BMPs vs. 300ms to 600ms for .JPGs. All have a preparation B time of about 40ms (the time to make a DMDX frame out of them once loaded into memory).

DMDX Index.