Esempio n. 1
0
BOOL CBitBuffer::CreateScreenBits( NativePlayerWnd* native, SRECT* frame)
{
	FLASHASSERT( ( frame->xmax - frame->xmin ) > 0 );
	FLASHASSERT( ( frame->ymax - frame->ymin ) > 0 );
	FreeBits();
	SColorTable* table = 0;

	int depth;

	// Pick a format for the offscreen bitmap
	depth = NativeDisplayTester::CurrentScreenBitDepth();

	if ( screenDepth != depth ) {
		if ( screenDepth > 0 )
		{
			delete m_cinfo;
			m_cinfo = 0;
		}

		// We need to profile the device
		screenDepth = depth;

		NativeDisplayTester tester;

		tester.TestDepth( screenDepth );
		screenFormat = tester.BestDetectedFormat();
		screenInverted = tester.BestDetectedInvert();
	}

	m_inverted = screenInverted;
	m_xorg = 0;

	if ( screenFormat <= pix8 ) 
	{
		if ( m_cinfo )
		{
			delete m_cinfo;
			m_cinfo = 0;
		}

		SColorTable ctab;

		NativePalette::GetScreenPalette( &ctab );
		m_cinfo = CreateColorInfo( &ctab );

		if ( !m_cinfo ) return false;
		AttachColorInfo(m_cinfo);
		table = &m_cinfo->ctab;
	}

	bitmap = new NativeBitmap(	native, 
								table,
								frame->xmax - frame->xmin,
								frame->ymax - frame->ymin,
								screenDepth,
								screenFormat
						     );
	return ( bitmap->ScanLine() != 0 );
}
Esempio n. 2
0
void ReleaseColorInfo(SColorInfo* cinfo)
{
	if ( !cinfo ) return;
	FLASHASSERT( cinfo->refCount );
	if ( --cinfo->refCount == 0 ) {
		SColorInfo** link = &firstColorInfo;
		if(*link)
		{
			while ( *link ) {
				if ( *link == cinfo ) {
					*link = cinfo->next;

					cinfo->DestroyOSPalette();
					memset( cinfo, 0, sizeof( SColorInfo ) );
					delete cinfo;
					return;
				}
				link = &cinfo->next;
			}
		}
		else
		{
			cinfo->DestroyOSPalette();
			delete cinfo;
			return;
		}
	}
}
Esempio n. 3
0
void DisplayList::RemoveThread(ScriptThread* thread)
{
	// Clear any pending actions on a thread that is going away
	actionList.RemoveThread(thread);

	// If we are inside a DoActions, remove pending actions on
	// the action context stack
	ActionContext* actionContext = actionCallStack;
	for (int i=0; i<actionCallStackTop; i++) {
		if (actionContext->targetThread == thread) {
			actionContext->targetThread = 0;
			actionContext->useTarget = false;
		}
		actionContext->actionList->RemoveThread(thread);
		actionContext++;
	}

	// Remove the thread from the list
	ScriptThread** link = &threads;
	while ( *link ) {
		if ( *link == thread ) {
			*link = thread->next;
			return;
		}
		link = &(*link)->next;
	}
	FLASHASSERT(false);
}
Esempio n. 4
0
BOOL NativePlayerWnd::StartTimer( int playTimerInterval, int cursorTimerInterval )
{
    if ( !loaded )
        return false;

    FLASHASSERT( playTimerInterval );
    FLASHASSERT( cursorTimerInterval );

    flash->cursorTimeInterval=cursorTimerInterval;
    flash->cursorTime=GetTickCount();
    playTimer = flash->timer(playTimerInterval);
    //SetTimer( hwnd, TIMER_PLAY, playTimerInterval, 0 );
    //cursorTimer = SetTimer( hwnd, TIMER_CURSOR, cursorTimerInterval, 0 );

    return true;
}
Esempio n. 5
0
void DecomposeRect(SRECT* r1, SRECT* r2)
// Restructure two overlaping rectangles to eliminate the intersecting area
//	while still covering the same area and perhaps more area
{
	FLASHASSERT(RectTestOverlap(r1, r2));

	// Build the 3 rect slabs on y-axis
	SRECT r[3];
	if ( r1->ymin < r2->ymin ) {
		r[0].ymin = r1->ymin;
		r[0].ymax = r2->ymin;
		r[0].xmin = r1->xmin;
		r[0].xmax = r1->xmax;
	} else {
		r[0].ymin = r2->ymin;
		r[0].ymax = r1->ymin;
		r[0].xmin = r2->xmin;
		r[0].xmax = r2->xmax;
	}
	if ( r1->ymax < r2->ymax ) {
		r[2].ymin = r1->ymax;
		r[2].ymax = r2->ymax;
		r[2].xmin = r2->xmin;
		r[2].xmax = r2->xmax;
	} else {
		r[2].ymin = r2->ymax;
		r[2].ymax = r1->ymax;
		r[2].xmin = r1->xmin;
		r[2].xmax = r1->xmax;
	}
	r[1].ymin = r[0].ymax;
	r[1].ymax = r[2].ymin;
	r[1].xmin = Min(r1->xmin, r2->xmin);
	r[1].xmax = Max(r1->xmax, r2->xmax);

	// Combine the middle slab with the slab that will generate the smallest area
	S32 a[3];
	for ( int i = 0; i < 3; i++ )
		a[i] = RectArea(r+i);

	SRECT u1, u2;
	RectUnion(&r[0], &r[1], &u1);
	RectUnion(&r[1], &r[2], &u2);

	S32 delta0 = a[0] + a[1] - RectArea(&u1);
	S32 delta1 = a[1] + a[2] - RectArea(&u2);

	if ( delta0 > delta1 ) {
		*r1 = u1;
		*r2 = r[2];
	} else {
		*r1 = r[0];
		*r2 = u2;
	}
}
Esempio n. 6
0
void DisplayList::DoButtonStateTransition(SObject* newButton, int transition)
{
	FLASHASSERT(newButton);
	switch ( transition ) {
		case bsIdleToOverUp:
		case bsOverDownToOverUp:
			buttonState = bsOverUp;
			break;
		case bsOverUpToIdle:
		case bsOutDownToIdle:
		case bsOverDownToIdle:
			buttonState = bsIdle;
			break;
		case bsOverUpToOverDown:
		case bsOutDownToOverDown:
		case bsIdleToOverDown:
			buttonState = bsOverDown;
			break;
		case bsOverDownToOutDown:
			buttonState = bsOutDown;
			break;
		default:
			FLASHASSERT(false);
	}

	UpdateButton(newButton, buttonState);
	DoButtonAction(newButton, transition);

	if ( buttonState == bsIdle ) {
		button = 0;
		buttonParent = 0;
		buttonCharacter = 0;
		buttonDepth = 0;
		buttonRatio = 0;
	} else {
		button = newButton;
		buttonParent = newButton->parent;
		buttonCharacter = newButton->character;
		buttonDepth = newButton->depth;
		buttonRatio = newButton->ratio;
	}
}
Esempio n. 7
0
SObject* DisplayList::MoveObject(SObject* parent, PlaceInfo* info)
{
	// See if there is already an object at this depth or find the insertion point
	SObject* obj = parent->bottomChild;
	while ( obj ) {
	 	if ( obj->depth >= info->depth ) 
			break;
		obj = obj->above;
	}

	if ( obj ) {
		// We found an object at this depth
		if ( obj->depth != info->depth ) {
			FLASHASSERT(false);
			return 0;		// don't move the wrong object
		}

        if (obj->puppet)
            return 0;       // don't move the object if it's puppeted

		// Move the proper fields of the object
		obj->Modify();
		if ( info->flags & splaceCharacter ) {
			// The type of sprite or button objects must never change
			if ( obj->character->type != info->character->type && 
				 (obj->character->type == spriteChar || info->character->type == spriteChar ||
				  obj->character->type == buttonChar || info->character->type == buttonChar) ) {
				FLASHASSERT(false);		// this should never happen, there was a beta build where we did export like this, so prevent the crash
			} else {
				obj->character = info->character;
			}
		}
		if ( info->flags & splaceMatrix )
			obj->xform.mat = info->mat;
		if ( info->flags & splaceColorTransform )
			obj->xform.cxform = info->cxform;
		if ( info->flags & splaceRatio )
			obj->ratio = info->ratio;
	}
	return obj;
}
Esempio n. 8
0
void NativeSoundMix::BuildAndWrite( WaveHeader* wave, BOOL silence )
{
	int i = wave->bufferId;
	WAVEHDR* hdr = &waveHDR[i];

	// Clean up the header
	int res = waveOutUnprepareHeader(hWaveOut, hdr, sizeof(WAVEHDR));
	FLASHASSERT(res == MMSYSERR_NOERROR);

	// Generate the sound info
	if ( silence ) {
		memset(buffer[i], mixFormat.Is8Bit() ? 0x80 : 0, bufferBytes);
	} else {
		BuildBuffer( i );
	}

	res = waveOutPrepareHeader(hWaveOut, hdr, sizeof(WAVEHDR));
	FLASHASSERT(res == MMSYSERR_NOERROR);
	res = waveOutWrite(hWaveOut, hdr, sizeof(WAVEHDR)); 
	FLASHASSERT(res == MMSYSERR_NOERROR);
}
Esempio n. 9
0
void NativeSoundMix::CloseNativeDevice()
{
	if ( !isOpen ) return;

	SetEvent(playEvent);	// signal the thread to quit

	EnterCritical(); // do this after we kill the timer proc to prevent a deadlock

	if ( !isOpen ) {
		LeaveCritical();
		return;	// It is possible for timeKillEvent to call CloseDevice
	}
	isOpen = false;
	
	HWAVEOUT hW = hWaveOut;
	hWaveOut = 0;	// flag that we are shutting down so PollSound will bail

	int res = waveOutReset(hW);
	FLASHASSERT(res == MMSYSERR_NOERROR);

	for ( int i = 0; i < nBuffers; i++ ) {
		int limit = 50;
		while ( limit-- ) {
			int res = waveOutUnprepareHeader(hW, waveHDR+i, sizeof(WAVEHDR));
			if ( res != WAVERR_STILLPLAYING ) {
				FLASHASSERT(res == MMSYSERR_NOERROR);
				break;
			}
			Sleep(1);
		}
	}

	res = waveOutClose(hW);
	FLASHASSERT(res == MMSYSERR_NOERROR);

	CloseHandle(playThread);
	playThread = 0;
	LeaveCritical();
}
Esempio n. 10
0
int NativeDisplayTester::DepthToSimplestPixelFormat( int depth )
{	
	int pixelFormat;

	switch ( depth ) 
	{
		case 1:		pixelFormat = pix1;  break;
		case 4:		pixelFormat = pix4;  break;
		case 8:		pixelFormat = pix8;  break;
		case 16:	pixelFormat = pix16; break;
		case 24:	pixelFormat = pix24; break;
		case 32:	pixelFormat = pix32; break;
		default:
			FLASHASSERT(false);
	}
	return pixelFormat;
}
Esempio n. 11
0
void DisplayList::DoRemove(SObject** link)
{
	SObject* obj = *link;
	FLASHASSERT(obj);

	// Remove the contents of the old object
	if ( obj->drawn )
		InvalidateRect(&obj->devBounds);

	obj->FreeChildren();
	obj->Free();

	
	// Remove from list
	if ( obj == button )
		button = 0;
	*link = obj->above;
	FreeObject(obj);
}
Esempio n. 12
0
SColorInfo* GetColorInfo(SColorTable* ctab)
{
	// Find an existing color table
	SColorInfo* cinfo = firstColorInfo;
	while ( cinfo ) {
		FLASHASSERT( cinfo->refCount );
		if ( ColorTableEqual(ctab, &cinfo->ctab) ) {
			cinfo->refCount++;
			return cinfo;
		}
		cinfo = cinfo->next;
	}

	// Create a new inverse table
	cinfo = CreateColorInfo(ctab);
	if ( !cinfo ) return 0;
	cinfo->next = firstColorInfo;
	firstColorInfo = cinfo;
	return cinfo;
}
Esempio n. 13
0
void DisplayList::InvalidateRect(SRECT* r)
{
	SRECT rect;
	rect.xmin = r->xmin;
	rect.xmax = r->xmax;
	rect.ymin = r->ymin;
	rect.ymax = r->ymax;

	RectInset(antialias ? -8 : -2, &rect);
	if ( RectTestIntersect(&devViewRect, &rect) ) {
		FLASHASSERT(nDirty < maxDirtyAreas);
		// Add to the list
		RectIntersect(&devViewRect, &rect, &devDirtyRect[nDirty]);
		RectUnion(&devDirtyRgn, &devDirtyRect[nDirty], &devDirtyRgn);	// add to the dirty region
		devDirtyArea[nDirty] = RectArea(devDirtyRect+nDirty);	// add to the list
		nDirty++;

		MergeDirtyList(nDirty == maxDirtyAreas);
	}
}
Esempio n. 14
0
void DisplayList::SetCamera(SRECT* frame, SRECT* viewRct, BOOL smooth, int scaleMode)
{
	// Set up the camera
	SRECT viewPort = *viewRct;
	if ( smooth ) {
	 	viewPort.xmin *= 4;
	 	viewPort.ymin *= 4;
	 	viewPort.xmax *= 4;
	 	viewPort.ymax *= 4;
	}

	// Calculate the mapping
	//	src = frame
	//	dst = viewPort
	MATRIX newMat;
	#define minMapSize 0x10L
	FLASHASSERT(!RectIsEmpty(&viewPort) && !RectIsEmpty(frame));
	newMat.a = FixedDiv(FixedMax(RectWidth(&viewPort), minMapSize), FixedMax(RectWidth(frame), minMapSize));
	newMat.d = FixedDiv(FixedMax(RectHeight(&viewPort), minMapSize), FixedMax(RectHeight(frame), minMapSize));
	newMat.b = newMat.c = 0;

	// Adjust the scaling to maintain the aspect ratio
	switch ( scaleMode & scaleMask ) {
		case showAll:
			newMat.a = newMat.d = FixedMin(newMat.a, newMat.d);
			break;
		case noBorder:
			newMat.a = newMat.d = FixedMax(newMat.a, newMat.d);
			break;
		case exactFit:
			//MatrixMap(frame, &viewPort, &newMat);
			break;
		case noScale:
			newMat.a = newMat.d = smooth ? 4*fixed_1/20 : fixed_1/20;
			break;
	}

	// Pick the alignment point
	SPOINT srcRef, dstRef;
	if ( scaleMode & alignLeft ) {
		srcRef.x = frame->xmin;
		dstRef.x = viewPort.xmin;
	} else if ( scaleMode & alignRight ) {
		srcRef.x = frame->xmax;
		dstRef.x = viewPort.xmax;
	} else {
		srcRef.x = FixedAverage(frame->xmin, frame->xmax);
		dstRef.x = FixedAverage(viewPort.xmin, viewPort.xmax);
	}
	if ( scaleMode & alignTop ) {
		srcRef.y = frame->ymin;
		dstRef.y = viewPort.ymin;
	} else if ( scaleMode & alignBottom ) {
		srcRef.y = frame->ymax;
		dstRef.y = viewPort.ymax;
	} else {
		srcRef.y = FixedAverage(frame->ymin, frame->ymax);
		dstRef.y = FixedAverage(viewPort.ymin, viewPort.ymax);
	}

	// Calculate the translation based on the alignment
	newMat.tx = dstRef.x - FixedMul(srcRef.x, newMat.a);
	newMat.ty = dstRef.y - FixedMul(srcRef.y, newMat.d);

	// Don't invalidate unless there was a change
	BOOL smoothBits = smooth && !faster;
	if ( newMat.a  != camera.mat.a  || newMat.b  != camera.mat.b ||
		 newMat.c  != camera.mat.c  || newMat.d  != camera.mat.d ||
		 newMat.tx != camera.mat.tx || newMat.ty != camera.mat.ty ||
		 antialias != smooth || raster.smoothBitmaps != smoothBits ) {
		antialias = smooth;
		camera.mat = newMat;
		raster.smoothBitmaps = smoothBits;
		raster.bitmapDither = antialias ? errorDiffusionDither : orderedDither;
		ModifyCamera();
	}
}
Esempio n. 15
0
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
}
Esempio n. 16
0
void DisplayList::AddThread(ScriptThread* thread) 
{
	FLASHASSERT(!thread->next); 
	thread->next = threads; 
	threads = thread; 
}
Esempio n. 17
0
BOOL DisplayList::SetButton(SObject* newButton, BOOL mouseIsDown)
{
	FLASHASSERT(!newButton || newButton->character->type == buttonChar);

	if ( !button ) {				// just in case the button was removed
		buttonState = bsIdle;
		buttonParent = 0;
		buttonCharacter = 0;
		buttonDepth = 0;
		buttonRatio = 0;
	}

	BOOL changed = false;
	switch ( buttonState ) {
		case bsIdle: {
			FLASHASSERT(!button);
			if ( newButton ) {
				if ( !mouseIsDown ) {
					// The mouse has come over the button
					DoButtonStateTransition(newButton, bsIdleToOverUp);
					changed = true;
				} else if ( newButton->character->button.trackAsMenu ) {
					// Enter a button while the mouse is down
					DoButtonStateTransition(newButton, bsIdleToOverDown);
					changed = true;
				}
			}
		} break;

		case bsOverUp: {
			FLASHASSERT(button);
			if ( button == newButton ) {
				if ( mouseIsDown ) {
					// The mouse clicked on the button
					DoButtonStateTransition(button, bsOverUpToOverDown);
					changed = true;
				}
			} else {
				// The mouse is over a different button
				DoButtonStateTransition(button, bsOverUpToIdle);
				changed = true;
			}
		} break;

		case bsOverDown: {
			FLASHASSERT(button);
			if ( button == newButton ) {
				if ( !mouseIsDown ) {
					// The mouse was released over the button
					DoButtonStateTransition(button, bsOverDownToOverUp);
					changed = true;
				}
			} else {
				if ( button->character->button.trackAsMenu ) {
					// Exit the button
					DoButtonStateTransition(button, bsOverDownToIdle);
					changed = true;
				} else {
					// The mouse is over a different button
					DoButtonStateTransition(button, bsOverDownToOutDown);
					changed = true;
				}
			}
		} break;

		case bsOutDown: {
			FLASHASSERT(button);
			if ( button == newButton ) {
				// The mouse went back over the button
				DoButtonStateTransition(button, bsOutDownToOverDown);
				changed = true;
			} else if ( !mouseIsDown ) {
				// The mouse was released outside the button
				DoButtonStateTransition(button, bsOutDownToIdle);
				changed = true;
			}
		} break;
	}

	// If we deactivated a button, we may need to activate a new button
	if ( changed && !button && newButton )
		SetButton(newButton, mouseIsDown);	// call again 

	return changed;
}
Esempio n. 18
0
void DisplayList::FinishHold()
// Compare the old and the new list
// If an old object matches a new object, replace the new object with the old object
{
	FLASHASSERT(holdParent);

	SObject** oldLink = &holdList;
	SObject** newLink = &holdParent->bottomChild;

    for (;;) {
		SObject* oldObj = *oldLink;
		SObject* newObj = *newLink;

		if ( !oldObj )
			break;	// we are done

		if ( !newObj || oldObj->depth < newObj->depth ) {
			if ( oldObj->depth >= 0x4000 ) {
				// This is a cloned object, it always gets copied to the new list
				FLASHASSERT(!newObj);	// none of the new obj's should have a depth > 4000
				*oldLink = oldObj->above;	// remove from old list
				oldObj->above = *newLink;	// place on new list
				*newLink = oldObj;

			} else {
				// Get rid of the old object
				DoRemove(oldLink);
			}

		} else if ( oldObj->depth == newObj->depth ) {
			// Compare these objects
            BOOL remove = true;
			if (oldObj->character == newObj->character && oldObj->ratio == newObj->ratio && oldObj->clipDepth == newObj->clipDepth) 
            {
				// Check the matrix and cxform and ratio
				BOOL moved = !Equal(&oldObj->xform, &newObj->xform);
				if (!moved || oldObj->character->type == spriteChar) 
                {
					if ( moved && !oldObj->puppet) 
                    {
						oldObj->Modify();
						oldObj->xform = newObj->xform;
						//oldObj->ratio = newObj->ratio;
					}

					if ( button == newObj ) 
                    { 
						FLASHASSERT(oldObj->state == buttonState);
						button = oldObj;
						//UpdateButton(obj, state);
					}
                    remove = false;
				}
			}
            else if (
                oldObj->ratio == newObj->ratio && 
                (oldObj->character->type == spriteExternalChar || oldObj->character->type == spriteChar) && 
                (newObj->character->type == spriteChar || newObj->character->type == spriteExternalChar))
            {
                // we are dealing with externally loaded sprite
                // or an empty placeholder. It inherits the 
                // sprite ratio of the sprite we are replacing. 
                // This means that it goes away when the same 
                // time the replaced sprite should have gone away
				
                if (!Equal(&oldObj->xform, &newObj->xform))
                {
                        if (!oldObj->puppet)
                        {
						    oldObj->Modify();
						    oldObj->xform = newObj->xform;
                        }
			    }
                remove = false;
            }
            
            if (!remove)
            {
				DoRemove(newLink);			// delete the new obj
				*oldLink = oldObj->above;	// remove from old list
				oldObj->above = *newLink;	// place on new list
				*newLink = oldObj;
				continue;
            }
			
			newLink = &newObj->above;
			DoRemove(oldLink);

		} else {
			// Just look at the next new object
			FLASHASSERT(oldObj->depth > newObj->depth);
			newLink = &newObj->above;
		}
	}

#ifdef EDITTEXT
	// Update edit texts on hold list
	SObject* obj = holdParent->bottomChild;
	while (obj) {
		if (obj->character && obj->character->type == editTextChar) {
			obj->editText->UpdateFromVariable();
		}
		obj = obj->above;
	}
#endif

    holdParent = 0;
}
Esempio n. 19
0
SObject* DisplayList::PlaceObject(SObject* parent, PlaceInfo* info)
{
	// Find the insertion point
	SObject** link = &parent->bottomChild;
	for (;;) {
		SObject* obj = *link;
		if ( !obj ) break;
	 	if ( obj->depth >= info->depth ) {
			FLASHASSERT(obj->depth != info->depth);
			break;
		}
		link = &obj->above;
	}

	// Create a new object
	SObject* obj = CreateObject();
	if ( !obj ) return 0;

	// Add to list
	obj->parent = parent;
	obj->above = *link;
	*link = obj;

	// Set up object
	obj->character = info->character;
	obj->xform = *info;
	obj->depth = info->depth;
	obj->ratio = info->ratio;
    obj->puppet = info->puppet;
	obj->drawn = false;
    obj->visible = true;
	obj->dragCenter = false;
	RectSetEmpty(&obj->dragConstraint);
	obj->dropTarget = NULL;
	obj->display = this;
	obj->bottomChild = 0;
	obj->edges = 0;
	obj->colors = 0;
	obj->state = 0;
#ifdef EDITTEXT
	obj->editText = 0;
#endif

	// If this is a movie clip and it has no name,
	// generate a default name
	if (obj->character->type == spriteChar && !info->name) {
		URLBuilder ub;
		ub.AppendString("instance");
		ub.AppendInt(++instanceNameCount);
		obj->name = CreateStr(ub.buf);
	} else {
		// Regular processing: copy name if present
		obj->name = CreateStr(info->name);
	}
	obj->thread = parent ? parent->thread : 0;
	obj->clipDepth = info->flags & splaceDefineClip ? info->clipDepth : 0;//(info->flags & splaceDefineClip) != 0;
	obj->Modify();

	switch ( obj->character->type ) {
		case buttonChar: {
			// Set up the button state
			int state = bsIdle;
			if ( obj->depth == buttonDepth && obj->parent == buttonParent && 
				 buttonCharacter == obj->character && obj->ratio == buttonRatio ) {
				// The button is currently being tracked
				FLASHASSERT(obj->character->type == buttonChar);
				button = obj;
				state = buttonState;
			}
			UpdateButton(obj, state);
		} break;

#ifdef EDITTEXT
		case editTextChar:
			{
				obj->editText = new EditText(obj);
				if (holdParent != obj->parent) {
					// Not doing a hold... update value immediately
					obj->editText->UpdateFromVariable();
				}
				// If there is a holdParent, the edit text's value will
				// be updated later.
			}
			break;
#endif

		case spriteExternalChar:
        {
			ScriptThread    *thread = 0;
            ScriptPlayer    *player = obj->character->player;
            int             startPos = 0;
            int             len = 0;
            int             numFrames = 0;

            if (info->flags & splaceCloneExternalSprite)
            {
                // means we are cloning an existing
                // external sprite
                if (player->len >= player->scriptLen)
                {
                    // we only clone the external
                    // sprite if it has been completely loaded
                    // allocate full player instead of thread
                    // it is easier to delete the external
                    // sprite if it has its own player
                    thread = new ScriptPlayer;
                    startPos = player->startPos;
                    len = player->len;
                    numFrames = player->numFrames;
                    thread->script = player->script;
                    ((ScriptPlayer *) thread)->numFramesComplete = player->numFramesComplete;
                    player = (ScriptPlayer *) thread;
                    player->gotHeader = true;
                    
                    // add a ref count to the script
                    // we don't want to duplicate it
                    // so we want to make sure it's
                    // protected from deletion for
                    // cloned external sprites
                    player->scriptRefCount = obj->character->player->scriptRefCount;
                    player->ScriptAddRefCount();
                }
            }
            else
            {
                // note that it's ok to have some of the
                // initial values of the len, etc. set
                // to zero. they will be set during pushdata
                thread = player;

                // add a ref count to the script
                // we don't want to duplicate it
                // so we want to make sure it's
                // protected from deletion for
                // cloned external sprites
                player->ScriptAddRefCount();
            }
			
            if ( thread ) 
            {
				thread->ClearState();
				obj->thread = thread;
				thread->player = player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->player->script, startPos);
				thread->len = len;
				thread->startPos = startPos;
				thread->numFrames = numFrames;
                
                // for non cloned sprite this won't draw the frame
                // untill we push data into the script (this is ok)
				thread->DrawFrame(0, false);
			}
		} break;

  		case spriteChar: {
			// Create a sprite thread
			ScriptThread* thread = new ScriptThread();
			if ( thread ) {
				thread->ClearState();
				obj->thread = thread;
				thread->player = obj->character->player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->data, 0);
				thread->len = obj->character->sprite.length;
				thread->startPos = 0;
				thread->numFrames = obj->character->sprite.numFrames;
				thread->DrawFrame(0, false);
			}
		} break;
	}

	return obj;
}
Esempio n. 20
0
NativeBitmap::NativeBitmap( NativePlayerWnd* native,
							const SColorTable* table, 
							int _width, 
							int _height, 
							int _depth, 
							int _pixelFormat )
{
	U32 nColors;	
	LOGPALETTE256 logpal = { 0x300, 256	};

	FLASHOUTPUT( "NativeBitmap created\n" );

	width = ( _width + 3 ) & ( ~0x03 );	// increase the width to be byte-aligned
	height = _height;
	depth = _depth;
	format = _pixelFormat;
	nColors = NativeDisplayTester::CurrentScreenColors();

	bytesPerLine = ( width * depth + 7 ) / 8;

	if ( depth < 8 )
	{
		FLASHASSERT( 0 );	// not supported in this version....
	}
	else if ( depth == 8 )
	{
		for ( U32 i=0; i<nColors; i++ )
		{
			logpal.palEntry[i].peRed    = info.bmiColors[i].rgbRed   = table->colors[i].red;
			logpal.palEntry[i].peGreen  = info.bmiColors[i].rgbGreen = table->colors[i].green;
			logpal.palEntry[i].peBlue   = info.bmiColors[i].rgbBlue  = table->colors[i].blue;
										  
			info.bmiColors[i].rgbReserved = 0;
			
			if ( i >= 10 && i < 246 )
				logpal.palEntry[i].peFlags  = PC_NOCOLLAPSE;
			else
				logpal.palEntry[i].peFlags  = 0;
		}

		// Create a Palette object
		palette = ::CreatePalette((LOGPALETTE *)&logpal);
	}
	else
	{
		nColors = 0;
		palette = 0;
	}	
	
	memset( &info.bmiHeader, 0, sizeof( BITMAPINFOHEADER ) );
	info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); // + nColors * sizeof( RGBQUAD );
	info.bmiHeader.biWidth = width;
	info.bmiHeader.biHeight = height;
	info.bmiHeader.biPlanes = 1;		// Must be 1. Thank you windows.
	info.bmiHeader.biBitCount = depth;	
	info.bmiHeader.biCompression = BI_RGB;	
	info.bmiHeader.biSizeImage = height * bytesPerLine;	
	info.bmiHeader.biClrUsed = nColors;	
	info.bmiHeader.biClrImportant = nColors;	
	
	HDC hdc = native->GetNWindowDC();

	hBitmap = CreateDIBSection( hdc, (BITMAPINFO*) &info, DIB_RGB_COLORS, (void**) &bits, 0, 0);
//  	HBITMAP hbmOld = (HBITMAP)::SelectObject(hdc, hBitmap);

	
	native->ReleaseWindowDC();

	FLASHASSERT( hBitmap );
}