DMDX Help.


How DMDX works


    In the interests of enabling people to write better scripts here are some of the details of the way in which DMDX gets things done.

Preprocessing.

    Before the tachistoscopic routines are fired up DMDX performs a certain amount of text file manipulation. DMDX first parses the rich text item file to a new temporary file called rtfparsed.txt, parsing out all RTF control codes not between quotes. Next if the item file calls for scrambling the scrambling routines produce another file scrambled.itm. DMDX reads whatever the final result of that process is, be it the original ascii item file (if it did not use scrambling) or rtfparsed.itm (if RTF and no scrambling) or scrambled.itm.

    Following file parsing the various processes that make up DMDX proper are begun.
    First DirectX is instructed to switch the screen to whatever display mode has been requested in the item file. That mode must have been setup with TimeDX beforehand as DMDX reads various values relevant to keeping track of the retrace from the registry that TimeDX puts there. It also requests that as many screen buffers as can be contained in video memory be created, these are called DirectDraw Surfaces. Beside the primary surface that is always displayed there can be a large number of these back surfaces that DMDX uses for buffering, up to 24 of them on a 8M video card at 640x480 8 bits per pixel (bpp).
    Then the millisecond callback from the OS is initiated. I recommend you read all of
TimeDX's help file if you want a full understanding of what's going on, here I will simply mention that timing under Win32 is a bitch. On a perfect machine DMDX will get control once every millisecond and indeed on fast XP machines this is almost always the case, slower 9x machines vary substantially from one machine to the next however.
    A thread is created to keep track of the retrace. A thread is another task running in parallel with the original program (itself just another thread). The retrace thread spends most of it's time sleeping (ie, letting the other threads execute). Once each retrace period it wakes up and waits for a number of milliseconds until it either finds the retrace or it decides that it has missed it, in either event counters are updated and DMDX gets to decide what should happen. In most cases if a retrace is missed it is no big deal, what DMDX requires is done by the hardware at the
next retrace anyway, so as long as DMDX gets control back before the next retrace things are fine. Unfortunately this is not always the case, see TimeDX's help file for myriad details.
    A thread is also created for each input device requested in the item file or just the keyboard if no requests were made. Threads for keyboards and mice and any other interrupt driven devices (
TimeDX will tell you whether a device is interrupt driven or not) lie in wait for input data, all other polled devices have threads that are woken up periodically by the millisecond callback to go and check if a key is being pressed (and therefore represent a greater load on the system).
    Another thread can exist to handle requests to play sound files, however this thread is not created until DMDX finds a request to play a sound. At that time the sound system as a whole is initiated and the sound thread created. The thread creation is not likely to take much time, however setting the sound system going could take quite a number of milliseconds. Also once the sound system is initiated it is running
all the time till that item file finishes, meaning the machine is pumping 22050 16 bit samples per second in stereo (so times 2) to the sound card -- which is why it's not done unless it's needed. Not that this represents a significant load to a Pentium running at 133 Mhz, it's just another load and the less of load the better. If DMDX is going to be used primarily to present audio stimuli the priority of the audio thread can be bumped up.
   

Per-item processing.

    Prior to the request beginning any given item DMDX performs all disk related tasks. This means that for request scheduled displays and low value D parameters care must be taken to ensure that unrealistic timing requests are not made. In DMTG (and DM I suppose, although most of it's processing was so trivial that I don't think anyone that ever used it had much concern) you had to ascertain just how fast you could go by attempting to go faster than possible and backing off, DMDX on the other hand provides the time taken to prepare items in it's Preparation A and B times, A being disk stuff and B being drawing stuff (see Errors you might encounter. below).
    Disk related tasks include writing diagnostics to disk, writing result files to disk, reading the item to be displayed (although this is likely to have been buffered in memory as DMDX uses file mapping), and reading the bitmaps and sound files used in the item and preparing their in-memory analogues. If a sound file is used for the first time this is when the sound system is initiated.

    Once the request has been received DMDX prepares each individual frame in a separate main memory (as opposed to screen memory) DirectDraw surface, then it ascertains which screen surface that frame will be displayed in and what in that screen surface from a previous item's display needs to be overwritten or erased. Having done that it creates a surface (that will be destroyed at the item's completion) just big enough to contain the region that will change on the screen surface and copies the corresponding region of the memory surface to this new temporary surface.

    Once everything is drawn DMDX schedules the frames for display and adds them to the display queue.

Per-frame processing.

    DMDX's main thread watches the display queue to see if any of the screen surfaces become empty (or are already empty at the item's commencement) and moves the display queue surfaces onto the screen surfaces a portion at a time -- it moves only portions because the process of moving data to the video display memory usually locks out all other threads, a bad thing.

    The retrace thread decides when screen surfaces should be flipped, when sounds should be commenced, when output bytes should be output, when the clock should be turned on and so forth. These requests are calculated ahead of time, usually only a portion of a retrace interval but sometimes in the case of a sound quite some time earlier, and passed off to the millisecond callback with the exception of flip requests that are given directly to DirectDraw.

    The millisecond callback then has this list of things that should be done at various times and it dispatches them as needed.





DMDX Index.