void DisplayList::UpdateButton(SObject* obj, int newState) // Add or remove child characters so that the button matches newState { SCharacter* ch = obj->character; if ( ch->type != buttonChar ) return; int oldState = obj->state; if ( oldState == newState ) return; U8 * cxData = ch->button.cxformData; ScriptPlayer* player = ch->player; for ( int pass = 0; pass < 2; pass++ ) { SParser parser; parser.Attach(ch->data, 0); if ( ch->tagCode == stagDefineButton2 ) parser.GetWord(); // skip the action offset SParser cxParser; if ( cxData ) cxParser.Attach(cxData, 0); for (;;) { U8 stateFlags = parser.GetByte(); if ( !stateFlags ) break; PlaceInfo info; info.flags = splaceCharacter|splaceMatrix|splaceColorTransform; U16 tag = parser.GetWord(); info.depth = obj->depth + parser.GetWord(); parser.GetMatrix(&info.mat); if ( ch->tagCode == stagDefineButton2 ) parser.GetColorTransform(&info.cxform, true); // new style button else if ( cxData ) cxParser.GetColorTransform(&info.cxform, false);// separate cxfrom data else info.cxform.Clear(); // no cxform data // Remove the objects first and then add in case we have conflicting layer/id combos BOOL newVis = stateFlags & btnStateMap[newState]; BOOL oldVis = stateFlags & btnStateMap[oldState]; if ( pass == 0 && !newVis && oldVis ) { // Remove the child RemoveObject(obj, info.depth); } if ( pass == 1 && newVis && !oldVis ) { // Add the child info.character = player->FindCharacter(tag); info.name = 0; if ( info.character ) PlaceObject(obj, &info); } } } obj->state = newState; }
void DisplayList::DoButtonAction(SObject* target, int transition) { SCharacter* ch = target->character; FLASHASSERT(ch->type == buttonChar); if ( ch->tagCode == stagDefineButton2 ) { // Handle the new style button SParser parser; parser.Attach(ch->data, 0); BOOL first = true; for (;;) { S32 link = parser.pos; int offset = parser.GetWord(); if ( !first ) { int code = parser.GetWord(); if ( code & (1<<transition) ) { PushAction(parser.script+parser.pos, target->thread); } } if ( !offset ) break; parser.pos = link + offset; first = false; } } else { // Handle the old style button if ( transition == bsOverDownToOverUp ) { // Do the button action on the mouse up in SParser parser; parser.Attach(ch->data, 0); // Skip over the child data for (;;) { U8 stateFlags = parser.GetByte(); if ( !stateFlags ) break; MATRIX m; parser.SkipBytes(4);//GetWord(); //parser.GetWord(); parser.GetMatrix(&m); } // Handle the action PushAction(parser.script+parser.pos, target->thread); } } #ifdef SOUND {// Play the sound int state = 0; switch ( transition ) { case bsIdleToOverDown: case bsIdleToOverUp: state = sbtnOverState; break; case bsOverUpToOverDown: state = sbtnDownState; break; case bsOverDownToOverUp: state = sbtnHitTestState; break; case bsOverUpToIdle: case bsOutDownToIdle: case bsOverDownToIdle: state = sbtnUpState; break; } if ( state && ch->button.soundData ) { SParser parser; parser.Attach(ch->button.soundData, 0); // Skip the sounds for ( int i = 1; i < state; i <<= 1 ) { U16 tag = parser.GetWord(); if ( tag ) parser.GetSoundInfo(0);// skip the data } // Get the sound we want U16 tag = parser.GetWord(); if ( tag ) { SCharacter* sound = ch->player->FindCharacter(tag); if ( !sound || sound->type != soundChar ) return; CSoundChannel* channel = new CSoundChannel(); if ( channel ) { channel->AddRef(); channel->sound = &sound->sound; channel->tag = (U32)this; parser.GetSoundInfo(channel); // set up envelope, inPoint, loops, etc... theSoundMix->AddSound(channel); channel->Release(); } } } } #endif }