Platform SDK: DirectX

Step 5: Create the Primary Segments

[Visual Basic]

This tutorial pertains only to applications written in C++. See DirectMusic Visual Basic Tutorials.

[C++]

The one-time initialization of DirectMusic in the DMDonuts sample application is now complete. Further initialization is done in the setup_game function each time the game is started or the player advances to the next level.

The setup_game function first calls another function called ComposeNewSegments, which selects a style and chordmap based on the current game level, releases any previously created segments, and then composes two new segments based on the templates previously loaded from file. One of these segments is an introductory theme that plays until a donut has been hit; the other plays from that point until the player beats the level. The snSubLevel variable tracks which part of the level we are in and is used elsewhere to determine which segment should be played when music is toggled on with the F7 key.

snSubLevel = 1;
snLastTempo = 0;
gnLastStyle = gnCurrentStyle;
gnLastChordMap = gnCurrentChordMap;
gnCurrentStyle = level % NUM_STYLES;
gnCurrentChordMap = ((level - 1) / 2) % NUM_CHORDMAP;
HRESULT hr = S_OK;
MUSIC_TIME mtSegmentLength;
if (gapSegment[SEGMENT_1])
{
    gapSegment[SEGMENT_1]->Release();
}
hr = gpComposer->ComposeSegmentFromTemplate(
        gapStyle[gnCurrentStyle],
        gpIntroTemplate, 0, 
        gapChordMap[gnCurrentStyle][gnCurrentChordMap],
        &gapSegment[SEGMENT_1]
);
if (!SUCCEEDED(hr))
{
    CleanupAndExit("Segment 1 composition failed");
}
 

We happen to know that the template has a signpost on the last measure that matches the signpost on the first measure, for graceful looping. Once the segment is composed, the last measure is lopped off. Note that the value of MEASURE_LENGTH was calculated in Step 1: Defines and Globals as (DMUS_PPQ * 4)—that is, four quarter-notes of music time. This is valid because the time signature is 4/4.

gapSegment[SEGMENT_1]->GetLength(&mtSegmentLength);
gapSegment[SEGMENT_1]->SetLength(
        mtSegmentLength - MEASURE_LENGTH);
 

Finally, the segment is set to loop repeatedly.

gapSegment[SEGMENT_1]->SetRepeats(999);
 

The second segment, based on gpGameTemplate, is composed and set up the same way.

Next: Step 6: Play a Primary Segment