Another Macromedia Flash -> texture class

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Another Macromedia Flash -> texture class

Post by IPv6 »

Hello!

This is a snippet that can mirror swf file on texture. Based on FlashWidget from Popcap framework and quite straightforward.

header:

Code: Select all

#ifndef __NODEFLASH_H__
#define __NODEFLASH_H__

struct IOleObject;
struct IOleInPlaceObjectWindowless;

namespace ShockwaveFlashObjects
{
	struct IShockwaveFlash;
}

class FlashSink;
class ControlSite;

class FlashListener
{
public:
	virtual void			FlashAnimEnded(int theId) {}
	virtual void			FlashCommand(int theId, const _string& theCommand, const _string& theParam) {}
};

class CSpriteNode_Flash
{
public:
	enum
	{
		STATE_IDLE,
		STATE_PLAYING,
		STATE_STOPPED
	};

	enum
	{
		QUALITY_LOW,
		QUALITY_MEDIUM,
		QUALITY_HIGH
	};

public:
	s32						mWidth;
	s32						mHeight;
	int						mState;
	int						mId;
	FlashListener*			mFlashListener;
	HMODULE					mFlashLibHandle;		

	ControlSite*			mControlSite;
	FlashSink*				mFlashSink;
	ShockwaveFlashObjects::IShockwaveFlash* mFlashInterface;
	IOleObject*				mOleObject;
	IOleInPlaceObjectWindowless* mWindowlessObject;

	int						mCOMCount;
	int						mPauseCount;
	int						mHasLostFocus;

	_rcti					mDirtyRect;
	bool					mFlashDirty;
	_rcti					GetRect();

	bool					mAutoPause;
	SColor					mBkgColor;
	CSpriteNode*			targetNode;

public:
	BYTE*					bitmap_pData;
	BYTE*					bitmap_pData_Original;
	BITMAPINFO				bitmap_pbi;
	HBITMAP					bitmap;
	void					CleanupImages();
	void					RebuildImages();
	void					InitializeFlash();
public:
	CSpriteNode_Flash(int theId, FlashListener* theFlashListener, CSpriteNode* targetNode);
	~CSpriteNode_Flash();
	
	static double			GetFlashVersion();

	bool					StartAnimation(const _string& theFileName);	
	void					SetQuality(int theQuality);
	void					Pause();
	void					Unpause();
	bool					IsPlaying();	
	void					Rewind();
	void					Back();
	void					Forward();	
	void					GotoFrame(int theFrameNum);
	int						GetCurrentFrame();
	_string					GetCurrentLabel(const _string& theTimeline);
	void					CallFrame(const _string& theTimeline, int theFrameNum);
	void					CallLabel(const _string& theTimeline, const _string& theLabel);
	_string					GetVariable(const _string& theName);
	void					SetVariable(const _string& theName, const _string& theValue);
		
	virtual void			Resize(int theX, int theY, int theWidth, int theHeight);
	
	virtual void			Update();
	virtual void			Draw();

	virtual void			MouseDown(int x, int y, int theBtnNum, int theClickCount);		
	virtual void			MouseUp(int x, int y, int theBtnNum, int theClickCount);
	virtual void			MouseMove(int x, int y);
	virtual void			MouseDrag(int x, int y);
	
	virtual void			MouseLeave();

	virtual void			SysColorChanged();
	void					MarkDirty();
};

class CFlashAnimation:public INodeAnimator
{
public:
	CSpriteNode_Flash* flashCOM;
	CSpriteNode* targetNode;
	CString sPath;
	CFlashAnimation(CSpriteNode* _targetNode, const CString& _sPath);
	~CFlashAnimation();
	virtual void stepAnimation(CNodeBasement* node, u32 timeMs);
};
#endif //__NODEFLASH_H__
this is a rip from game frawork (over Irrlicht) so some classes that is used here are: CSpriteNode,CNodeBasement -> billboard, CString, string_ -> core::string.

Usage:

Code: Select all

sprite->addAnimator(new CFlashAnimation(sprite, sPathToFlashFile));
As long as this animator "animating" billboard, it will flush swf content into it first texture
GameRotor-Games and more...
Wiredplane-Shareware utilities...
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

source

Post by IPv6 »

Code: Select all

//////////////////////////////////////////////////////////////////////////
// Interfaces imported from flash.ocx
#include <comdef.h>
#include <ole2.h>

#include "Node_SpriteFlash.h"
//#pragma comment(lib, "comsuppw.lib")
RECT toRECT(const _rcti& rct)
{
	RECT res;
	res.left = rct.UpperLeftCorner.X;
	res.top = rct.UpperLeftCorner.Y;
	res.right = rct.LowerRightCorner.X;
	res.bottom = rct.LowerRightCorner.Y;
	return res;
}

#pragma pack(push, 8)

namespace ShockwaveFlashObjects 
{

//
// Forward references and typedefs
//

struct __declspec(uuid("d27cdb6b-ae6d-11cf-96b8-444553540000"))
/* LIBID */ __ShockwaveFlashObjects;
struct __declspec(uuid("d27cdb6c-ae6d-11cf-96b8-444553540000"))
/* dual interface */ IShockwaveFlash;
struct __declspec(uuid("d27cdb6d-ae6d-11cf-96b8-444553540000"))
/* dispinterface */ _IShockwaveFlashEvents;
struct /* coclass */ ShockwaveFlash;
struct /* coclass */ FlashProp;
struct __declspec(uuid("d27cdb70-ae6d-11cf-96b8-444553540000"))
/* interface */ IFlashFactory;
struct __declspec(uuid("d27cdb72-ae6d-11cf-96b8-444553540000"))
/* interface */ IFlashObjectInterface;
struct __declspec(uuid("a6ef9860-c720-11d0-9337-00a0c90dcaa9"))
/* interface */ IDispatchEx;
struct /* coclass */ FlashObjectInterface;

//
// Smart pointer typedef declarations
//

_COM_SMARTPTR_TYPEDEF(IShockwaveFlash, __uuidof(IShockwaveFlash));
_COM_SMARTPTR_TYPEDEF(_IShockwaveFlashEvents, __uuidof(_IShockwaveFlashEvents));
_COM_SMARTPTR_TYPEDEF(IFlashFactory, __uuidof(IFlashFactory));
_COM_SMARTPTR_TYPEDEF(IDispatchEx, __uuidof(IDispatchEx));
_COM_SMARTPTR_TYPEDEF(IFlashObjectInterface, __uuidof(IFlashObjectInterface));

//
// Type library items
//

struct __declspec(uuid("d27cdb6c-ae6d-11cf-96b8-444553540000"))
IShockwaveFlash : IDispatch
{
    //
    // Property data
    //

    __declspec(property(get=GetStacking,put=PutStacking))
    _bstr_t Stacking;
    __declspec(property(get=GetWMode,put=PutWMode))
    _bstr_t WMode;
    __declspec(property(get=GetMovie,put=PutMovie))
    _bstr_t Movie;
    __declspec(property(get=GetSAlign,put=PutSAlign))
    _bstr_t SAlign;
    __declspec(property(get=GetMenu,put=PutMenu))
    VARIANT_BOOL Menu;
    __declspec(property(get=GetQuality,put=PutQuality))
    int Quality;
    __declspec(property(get=GetLoop,put=PutLoop))
    VARIANT_BOOL Loop;
    __declspec(property(get=GetFrameNum,put=PutFrameNum))
    long FrameNum;
    __declspec(property(get=GetBase,put=PutBase))
    _bstr_t Base;
    __declspec(property(get=Getscale,put=Putscale))
    _bstr_t scale;
    __declspec(property(get=GetDeviceFont,put=PutDeviceFont))
    VARIANT_BOOL DeviceFont;
    __declspec(property(get=GetEmbedMovie,put=PutEmbedMovie))
    VARIANT_BOOL EmbedMovie;
    __declspec(property(get=GetBGColor,put=PutBGColor))
    _bstr_t BGColor;
    __declspec(property(get=GetQuality2,put=PutQuality2))
    _bstr_t Quality2;
    __declspec(property(get=GetReadyState))
    long ReadyState;
    __declspec(property(get=GetScaleMode,put=PutScaleMode))
    int ScaleMode;
    __declspec(property(get=GetAlignMode,put=PutAlignMode))
    int AlignMode;
    __declspec(property(get=GetBackgroundColor,put=PutBackgroundColor))
    long BackgroundColor;
    __declspec(property(get=GetTotalFrames))
    long TotalFrames;
    __declspec(property(get=GetPlaying,put=PutPlaying))
    VARIANT_BOOL Playing;
    __declspec(property(get=GetSWRemote,put=PutSWRemote))
    _bstr_t SWRemote;

    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall get_ReadyState (
        /*[out,retval]*/ long * thestate ) = 0;
      virtual HRESULT __stdcall get_TotalFrames (
        /*[out,retval]*/ long * numframes ) = 0;
      virtual HRESULT __stdcall get_Playing (
        /*[out,retval]*/ VARIANT_BOOL * Playing ) = 0;
      virtual HRESULT __stdcall put_Playing (
        /*[in]*/ VARIANT_BOOL Playing ) = 0;
      virtual HRESULT __stdcall get_Quality (
        /*[out,retval]*/ int * Quality ) = 0;
      virtual HRESULT __stdcall put_Quality (
        /*[in]*/ int Quality ) = 0;
      virtual HRESULT __stdcall get_ScaleMode (
        /*[out,retval]*/ int * scale ) = 0;
      virtual HRESULT __stdcall put_ScaleMode (
        /*[in]*/ int scale ) = 0;
      virtual HRESULT __stdcall get_AlignMode (
        /*[out,retval]*/ int * align ) = 0;
      virtual HRESULT __stdcall put_AlignMode (
        /*[in]*/ int align ) = 0;
      virtual HRESULT __stdcall get_BackgroundColor (
        /*[out,retval]*/ long * color ) = 0;
      virtual HRESULT __stdcall put_BackgroundColor (
        /*[in]*/ long color ) = 0;
      virtual HRESULT __stdcall get_Loop (
        /*[out,retval]*/ VARIANT_BOOL * Loop ) = 0;
      virtual HRESULT __stdcall put_Loop (
        /*[in]*/ VARIANT_BOOL Loop ) = 0;
      virtual HRESULT __stdcall get_Movie (
        /*[out,retval]*/ BSTR * path ) = 0;
      virtual HRESULT __stdcall put_Movie (
        /*[in]*/ BSTR path ) = 0;
      virtual HRESULT __stdcall get_FrameNum (
        /*[out,retval]*/ long * FrameNum ) = 0;
      virtual HRESULT __stdcall put_FrameNum (
        /*[in]*/ long FrameNum ) = 0;
      virtual HRESULT __stdcall SetZoomRect (
        /*[in]*/ long left,
        /*[in]*/ long top,
        /*[in]*/ long right,
        /*[in]*/ long bottom ) = 0;
      virtual HRESULT __stdcall Zoom (
        /*[in]*/ int factor ) = 0;
      virtual HRESULT __stdcall Pan (
        /*[in]*/ long x,
        /*[in]*/ long y,
        /*[in]*/ int mode ) = 0;
      virtual HRESULT __stdcall Play ( ) = 0;
      virtual HRESULT __stdcall Stop ( ) = 0;
      virtual HRESULT __stdcall Back ( ) = 0;
      virtual HRESULT __stdcall Forward ( ) = 0;
      virtual HRESULT __stdcall Rewind ( ) = 0;
      virtual HRESULT __stdcall StopPlay ( ) = 0;
      virtual HRESULT __stdcall GotoFrame (
        /*[in]*/ long FrameNum ) = 0;
      virtual HRESULT __stdcall CurrentFrame (
        /*[out,retval]*/ long * FrameNum ) = 0;
      virtual HRESULT __stdcall IsPlaying (
        /*[out,retval]*/ VARIANT_BOOL * Playing ) = 0;
      virtual HRESULT __stdcall PercentLoaded (
        /*[out,retval]*/ long * __MIDL_0011 ) = 0;
      virtual HRESULT __stdcall FrameLoaded (
        /*[in]*/ long FrameNum,
        /*[out,retval]*/ VARIANT_BOOL * loaded ) = 0;
      virtual HRESULT __stdcall FlashVersion (
        /*[out,retval]*/ long * version ) = 0;
      virtual HRESULT __stdcall get_WMode (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_WMode (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_SAlign (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_SAlign (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_Menu (
        /*[out,retval]*/ VARIANT_BOOL * pVal ) = 0;
      virtual HRESULT __stdcall put_Menu (
        /*[in]*/ VARIANT_BOOL pVal ) = 0;
      virtual HRESULT __stdcall get_Base (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_Base (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_scale (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_scale (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_DeviceFont (
        /*[out,retval]*/ VARIANT_BOOL * pVal ) = 0;
      virtual HRESULT __stdcall put_DeviceFont (
        /*[in]*/ VARIANT_BOOL pVal ) = 0;
      virtual HRESULT __stdcall get_EmbedMovie (
        /*[out,retval]*/ VARIANT_BOOL * pVal ) = 0;
      virtual HRESULT __stdcall put_EmbedMovie (
        /*[in]*/ VARIANT_BOOL pVal ) = 0;
      virtual HRESULT __stdcall get_BGColor (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_BGColor (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_Quality2 (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_Quality2 (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall LoadMovie (
        /*[in]*/ int layer,
        /*[in]*/ BSTR url ) = 0;
      virtual HRESULT __stdcall TGotoFrame (
        /*[in]*/ BSTR target,
        /*[in]*/ long FrameNum ) = 0;
      virtual HRESULT __stdcall TGotoLabel (
        /*[in]*/ BSTR target,
        /*[in]*/ BSTR label ) = 0;
      virtual HRESULT __stdcall TCurrentFrame (
        /*[in]*/ BSTR target,
        /*[out,retval]*/ long * FrameNum ) = 0;
      virtual HRESULT __stdcall TCurrentLabel (
        /*[in]*/ BSTR target,
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall TPlay (
        /*[in]*/ BSTR target ) = 0;
      virtual HRESULT __stdcall TStopPlay (
        /*[in]*/ BSTR target ) = 0;
      virtual HRESULT __stdcall SetVariable (
        /*[in]*/ BSTR name,
        /*[in]*/ BSTR value ) = 0;
      virtual HRESULT __stdcall GetVariable (
        /*[in]*/ BSTR name,
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall TSetProperty (
        /*[in]*/ BSTR target,
        /*[in]*/ int property,
        /*[in]*/ BSTR value ) = 0;
      virtual HRESULT __stdcall TGetProperty (
        /*[in]*/ BSTR target,
        /*[in]*/ int property,
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall TCallFrame (
        /*[in]*/ BSTR target,
        /*[in]*/ int FrameNum ) = 0;
      virtual HRESULT __stdcall TCallLabel (
        /*[in]*/ BSTR target,
        /*[in]*/ BSTR label ) = 0;
      virtual HRESULT __stdcall TSetPropertyNum (
        /*[in]*/ BSTR target,
        /*[in]*/ int property,
        /*[in]*/ double value ) = 0;
      virtual HRESULT __stdcall TGetPropertyNum (
        /*[in]*/ BSTR target,
        /*[in]*/ int property,
        /*[out,retval]*/ double * pVal ) = 0;
      virtual HRESULT __stdcall get_SWRemote (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_SWRemote (
        /*[in]*/ BSTR pVal ) = 0;
      virtual HRESULT __stdcall get_Stacking (
        /*[out,retval]*/ BSTR * pVal ) = 0;
      virtual HRESULT __stdcall put_Stacking (
        /*[in]*/ BSTR pVal ) = 0;
};

struct __declspec(uuid("d27cdb6d-ae6d-11cf-96b8-444553540000"))
_IShockwaveFlashEvents : IDispatch
{
    //
    // Wrapper methods for error-handling
    //

    // Methods:
    HRESULT OnReadyStateChange (
        long newState );
    HRESULT OnProgress (
        long percentDone );
    HRESULT FSCommand (
        _bstr_t command,
        _bstr_t args );
};

struct __declspec(uuid("d27cdb6e-ae6d-11cf-96b8-444553540000"))
ShockwaveFlash;
    // [ default ] interface IShockwaveFlash
    // [ default, source ] dispinterface _IShockwaveFlashEvents

struct __declspec(uuid("1171a62f-05d2-11d1-83fc-00a0c9089c5a"))
FlashProp;
    // [ default ] interface IUnknown

struct __declspec(uuid("d27cdb70-ae6d-11cf-96b8-444553540000"))
IFlashFactory : IUnknown
{};

struct __declspec(uuid("a6ef9860-c720-11d0-9337-00a0c90dcaa9"))
IDispatchEx : IDispatch
{
    //
    // Wrapper methods for error-handling
    //

    HRESULT GetDispID (
        _bstr_t bstrName,
        unsigned long grfdex,
        long * pid );
    HRESULT RemoteInvokeEx (
        long id,
        unsigned long lcid,
        unsigned long dwFlags,
        struct DISPPARAMS * pdp,
        VARIANT * pvarRes,
        struct EXCEPINFO * pei,
        struct IServiceProvider * pspCaller,
        unsigned int cvarRefArg,
        unsigned int * rgiRefArg,
        VARIANT * rgvarRefArg );
    HRESULT DeleteMemberByName (
        _bstr_t bstrName,
        unsigned long grfdex );
    HRESULT DeleteMemberByDispID (
        long id );
    HRESULT GetMemberProperties (
        long id,
        unsigned long grfdexFetch,
        unsigned long * pgrfdex );
    HRESULT GetMemberName (
        long id,
        BSTR * pbstrName );
    HRESULT GetNextDispID (
        unsigned long grfdex,
        long id,
        long * pid );
    HRESULT GetNameSpaceParent (
        IUnknown * * ppunk );

    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall raw_GetDispID (
        /*[in]*/ BSTR bstrName,
        /*[in]*/ unsigned long grfdex,
        /*[out]*/ long * pid ) = 0;
      virtual HRESULT __stdcall raw_RemoteInvokeEx (
        /*[in]*/ long id,
        /*[in]*/ unsigned long lcid,
        /*[in]*/ unsigned long dwFlags,
        /*[in]*/ struct DISPPARAMS * pdp,
        /*[out]*/ VARIANT * pvarRes,
        /*[out]*/ struct EXCEPINFO * pei,
        /*[in]*/ struct IServiceProvider * pspCaller,
        /*[in]*/ unsigned int cvarRefArg,
        /*[in]*/ unsigned int * rgiRefArg,
        /*[in,out]*/ VARIANT * rgvarRefArg ) = 0;
      virtual HRESULT __stdcall raw_DeleteMemberByName (
        /*[in]*/ BSTR bstrName,
        /*[in]*/ unsigned long grfdex ) = 0;
      virtual HRESULT __stdcall raw_DeleteMemberByDispID (
        /*[in]*/ long id ) = 0;
      virtual HRESULT __stdcall raw_GetMemberProperties (
        /*[in]*/ long id,
        /*[in]*/ unsigned long grfdexFetch,
        /*[out]*/ unsigned long * pgrfdex ) = 0;
      virtual HRESULT __stdcall raw_GetMemberName (
        /*[in]*/ long id,
        /*[out]*/ BSTR * pbstrName ) = 0;
      virtual HRESULT __stdcall raw_GetNextDispID (
        /*[in]*/ unsigned long grfdex,
        /*[in]*/ long id,
        /*[out]*/ long * pid ) = 0;
      virtual HRESULT __stdcall raw_GetNameSpaceParent (
        /*[out]*/ IUnknown * * ppunk ) = 0;
};

struct __declspec(uuid("d27cdb72-ae6d-11cf-96b8-444553540000"))
IFlashObjectInterface : IDispatchEx
{};

struct __declspec(uuid("d27cdb71-ae6d-11cf-96b8-444553540000"))
FlashObjectInterface;
    // [ default ] interface IFlashObjectInterface

} // namespace ShockwaveFlashObjects

#pragma pack(pop)

//////////////////////////////////////////////////////////////////////////
// FlashSink - Receives flash events   

class FlashSink : public ShockwaveFlashObjects::_IShockwaveFlashEvents
{
public:	
	LPCONNECTIONPOINT		mConnectionPoint;	
	DWORD					mCookie;
	int						mRefCount;
	CSpriteNode_Flash*			mCSpriteNode_Flash;

public:
	FlashSink()
	{		
		mCookie = 0;
		mConnectionPoint = NULL;
		mRefCount = 0;
		mCSpriteNode_Flash = NULL;		
	}

	virtual ~FlashSink()
	{
		mCSpriteNode_Flash->mCOMCount--;
	}

	HRESULT Init(CSpriteNode_Flash* theCSpriteNode_Flash)
	{
		mCSpriteNode_Flash = theCSpriteNode_Flash;
		mCSpriteNode_Flash->mCOMCount++;

		HRESULT aResult = NOERROR;
		LPCONNECTIONPOINTCONTAINER aConnectionPoint = NULL;
						
		if ((mCSpriteNode_Flash->mFlashInterface->QueryInterface(IID_IConnectionPointContainer, (void**) &aConnectionPoint) == S_OK) &&
			(aConnectionPoint->FindConnectionPoint(__uuidof(ShockwaveFlashObjects::_IShockwaveFlashEvents), &mConnectionPoint) == S_OK))			
		{
			IDispatch* aDispatch = NULL;
			QueryInterface(__uuidof(IDispatch), (void**) &aDispatch);
			if (aDispatch != NULL)
			{
				aResult = mConnectionPoint->Advise((LPUNKNOWN)aDispatch, &mCookie);
				aDispatch->Release();
			}
		}
				
		if (aConnectionPoint != NULL) 
			aConnectionPoint->Release();

		return aResult;
	}

	HRESULT Shutdown()
	{
		HRESULT aResult = S_OK;

		if (mConnectionPoint)
		{
			if (mCookie)
			{
				aResult = mConnectionPoint->Unadvise(mCookie);
				mCookie = 0;
			}

			mConnectionPoint->Release();
			mConnectionPoint = NULL;
		}

		return aResult;
	}
 
	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv)
	{
		*ppv = NULL;

		if (riid == IID_IUnknown)
		{
			*ppv = (LPUNKNOWN)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IDispatch)
		{
			*ppv = (IDispatch*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == __uuidof(ShockwaveFlashObjects::_IShockwaveFlashEvents))
		{
			*ppv = (ShockwaveFlashObjects::_IShockwaveFlashEvents*) this;
			AddRef();
			return S_OK;
		}
		else
		{   
			return E_NOTIMPL;
		}
	}

	ULONG STDMETHODCALLTYPE AddRef()
	{  
		return ++mRefCount;
	}

	ULONG STDMETHODCALLTYPE Release()
	{  
		int aRefCount = --mRefCount;
		if (aRefCount == 0)		
			delete this;		

		return aRefCount;
	}

 // IDispatch method
  virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo)
   { return E_NOTIMPL; }

	virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
	{
		return E_NOTIMPL; 
	}

	virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
		UINT cNames, LCID lcid,DISPID* rgDispId)
	{
		return E_NOTIMPL; 
	}

	virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
		WORD wFlags, ::DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult,
		::EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr)
	{
		switch(dispIdMember)
		{
		case 0x7a6:			
			break;
		case 0x96:			
			if ((pDispParams->cArgs == 2) &&
				(pDispParams->rgvarg[0].vt == VT_BSTR) &&
				(pDispParams->rgvarg[1].vt == VT_BSTR))
			{
				FSCommand(pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].bstrVal);
			}
			break;
		case DISPID_READYSTATECHANGE:					
			break;
		default:			
			return DISP_E_MEMBERNOTFOUND;
		} 
		
		return NOERROR;
	}

	HRESULT OnReadyStateChange (long newState)
	{	
		return S_OK;
	}
    
	HRESULT OnProgress(long percentDone )
	{		
		return S_OK;
	}

	HRESULT FSCommand (_bstr_t command, _bstr_t args)
	{
		if (mCSpriteNode_Flash->mFlashListener != NULL)
			mCSpriteNode_Flash->mFlashListener->FlashCommand(mCSpriteNode_Flash->mId, (char*) command, (char*) args);
		return S_OK;
	}	
};


using namespace ShockwaveFlashObjects;

//////////////////////////////////////////////////////////////////////////
// ControlSite - container that holds the flash control

class ControlSite : 	
	public IOleInPlaceSiteWindowless, 
	public IOleClientSite	
{
public:
	int						mRefCount;
	CSpriteNode_Flash*		mCSpriteNode_Flash;

public:
	ControlSite()
	{		
		mRefCount = 0;		
		mCSpriteNode_Flash = NULL;
	}	

	virtual ~ControlSite()
	{
		if (mCSpriteNode_Flash != NULL)
			mCSpriteNode_Flash->mCOMCount--;
	}

	void Init(CSpriteNode_Flash* theCSpriteNode_Flash)
	{
		mCSpriteNode_Flash = theCSpriteNode_Flash;
		mCSpriteNode_Flash->mCOMCount++;
	}

	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv)
	{
		*ppv = NULL;

		if (riid == IID_IUnknown)
		{
			*ppv = (IUnknown*) (IOleWindow*) this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleWindow)
		{
			*ppv = (IOleWindow*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSite)
		{
			*ppv = (IOleInPlaceSite*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSiteEx)
		{
			*ppv = (IOleInPlaceSiteEx*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSiteWindowless)
		{
			*ppv = (IOleInPlaceSiteWindowless*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleClientSite)
		{
			*ppv = (IOleClientSite*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == __uuidof(ShockwaveFlashObjects::_IShockwaveFlashEvents))
		{
			*ppv = (ShockwaveFlashObjects::_IShockwaveFlashEvents*) this;
			AddRef();
			return S_OK;
		}
		else
		{   
			return E_NOTIMPL;
		}
	}

	ULONG STDMETHODCALLTYPE AddRef()
	{  
		return ++mRefCount;
	}

	ULONG STDMETHODCALLTYPE Release()
	{ 
		int aRefCount = --mRefCount;
		if (aRefCount == 0)		
			delete this;		

		return aRefCount;
	}

	//////////////////////////////////////////////////////////////////////////	

	virtual HRESULT  STDMETHODCALLTYPE SaveObject(void)
	{
		return S_OK;
	}

	virtual HRESULT  STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,IMoniker** ppmk )
	{
		*ppmk = NULL;
		return E_NOTIMPL;
	}

	virtual HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer ** theContainerP)
	{
		//return QueryInterface(__uuidof(IOleContainer), (void**) theContainerP);				
		return E_NOINTERFACE;
	}


	virtual HRESULT  STDMETHODCALLTYPE ShowObject(void)
	{
		return E_NOTIMPL;
	}

	virtual HRESULT  STDMETHODCALLTYPE OnShowWindow(BOOL)
	{
		return E_NOTIMPL;
	}

	virtual HRESULT  STDMETHODCALLTYPE RequestNewObjectLayout(void)
	{
		return E_NOTIMPL;
	}
		//		
	

	HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(/* [in] */ BOOL fEnterMode)
	{
	    return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetWindow(/* [out] */ HWND __RPC_FAR* theWnndow)
	{
		return E_FAIL;

	    //*theWnndow = NULL;
		//*theWnndow = gSexyAppBase->mHWnd;
		//return S_OK;
	}

	HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void)
	{
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void)
	{		
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnUIActivate(void)
	{		
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE GetWindowContext(/* [out] */ IOleInPlaceFrame __RPC_FAR *__RPC_FAR *ppFrame, /* [out] */ IOleInPlaceUIWindow __RPC_FAR *__RPC_FAR *ppDoc, /* [out] */ LPRECT lprcPosRect, /* [out] */ LPRECT lprcClipRect, /* [out][in] */ LPOLEINPLACEFRAMEINFO lpFrameInfo)
	{
		_rcti aRect = mCSpriteNode_Flash->GetRect();

		*lprcPosRect = toRECT(aRect);
		*lprcClipRect = toRECT(aRect);
		
		*ppFrame = NULL;
		QueryInterface(__uuidof(IOleInPlaceFrame), (void**) ppFrame);		
		*ppDoc = NULL;

		lpFrameInfo->fMDIApp = FALSE;
		lpFrameInfo->hwndFrame = NULL;
		lpFrameInfo->haccel = NULL;
		lpFrameInfo->cAccelEntries = 0;
		
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE Scroll(/* [in] */ SIZE scrollExtant)
	{
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnUIDeactivate(/* [in] */ BOOL fUndoable)
	{		
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void)
	{	
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE DiscardUndoState(void)
	{
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void)
	{
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnPosRectChange(/* [in] */ LPCRECT lprcPosRect)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(/* [out] */ BOOL __RPC_FAR *pfNoRedraw, /* [in] */ DWORD dwFlags)
	{
		if(pfNoRedraw){
			*pfNoRedraw = TRUE;
		}
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(/* [in] */ BOOL fNoRedraw)
	{		
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE RequestUIActivate(void)
	{
		return S_FALSE;
	}


	HRESULT STDMETHODCALLTYPE CanWindowlessActivate(void)
	{
		// Allow windowless activation?
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE GetCapture(void)
	{
		// TODO capture the mouse for the object
		return S_FALSE;
	}


	HRESULT STDMETHODCALLTYPE SetCapture(/* [in] */ BOOL fCapture)
	{
		// TODO capture the mouse for the object
		return S_FALSE;
	}


	HRESULT STDMETHODCALLTYPE GetFocus(void)
	{
		return S_OK;
	}


	HRESULT STDMETHODCALLTYPE SetFocus(/* [in] */ BOOL fFocus)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetDC(/* [in] */ LPCRECT pRect, /* [in] */ DWORD grfFlags, /* [out] */ HDC __RPC_FAR *phDC)
	{		
		return E_INVALIDARG;		
	}


	HRESULT STDMETHODCALLTYPE ReleaseDC(/* [in] */ HDC hDC)
	{
		return E_INVALIDARG;
	}


	HRESULT STDMETHODCALLTYPE InvalidateRect(/* [in] */ LPCRECT pRect, /* [in] */ BOOL fErase)
	{	
		if (pRect == NULL)
		{
			mCSpriteNode_Flash->mDirtyRect = mCSpriteNode_Flash->GetRect();
			mCSpriteNode_Flash->mFlashDirty = true;
		}
		else if (!mCSpriteNode_Flash->mFlashDirty)
		{
			mCSpriteNode_Flash->mDirtyRect = _rcti(_p2i(pRect->left, pRect->top), _d2i(pRect->right - pRect->left, pRect->bottom - pRect->top));
			mCSpriteNode_Flash->mFlashDirty = true;
		}
		else
		{			
			mCSpriteNode_Flash->mDirtyRect.addInternalPoint(_p2i(pRect->left, pRect->top));
			mCSpriteNode_Flash->mDirtyRect.addInternalPoint(_p2i(pRect->right, pRect->bottom));
		}		
		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE InvalidateRgn(/* [in] */ HRGN hRGN, /* [in] */ BOOL fErase)
	{	
		mCSpriteNode_Flash->mDirtyRect = mCSpriteNode_Flash->GetRect();
		mCSpriteNode_Flash->mFlashDirty = true;
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE ScrollRect(/* [in] */ INT dx, /* [in] */ INT dy, /* [in] */ LPCRECT pRectScroll, /* [in] */ LPCRECT pRectClip)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE AdjustRect(/* [out][in] */ LPRECT prc)
	{
		if (prc == NULL)
		{
			return E_INVALIDARG;
		}
		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnDefWindowMessage(/* [in] */ UINT msg, /* [in] */ WPARAM wParam, /* [in] */ LPARAM lParam, /* [out] */ LRESULT __RPC_FAR *plResult)
	{
		return S_FALSE;
	}
};


//////////////////////////////////////////////////////////////////////////

const CLSID CLSID_ShockwaveFlash =
  { 0xD27CDB6E, 0xAE6D, 0x11cf, {0x96, 0xB8, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };

typedef HRESULT (__stdcall *DllGetClassObjectFunc)(REFCLSID rclsid, REFIID riid, LPVOID * ppv); 

CSpriteNode_Flash::CSpriteNode_Flash(int theId, FlashListener* theFlashListener,CSpriteNode* _targetNode)
{
	bitmap=0;
	bitmap_pData=0;
	bitmap_pData_Original=0;
	targetNode=_targetNode;
	mState = STATE_IDLE;

	mCOMCount = 0;
	mPauseCount = 0;
	mAutoPause = false;
	mHasLostFocus = getWindowActive();
	mFlashDirty = true;	

	mBkgColor = SColor();
	mId = theId;
	mFlashListener = theFlashListener;	

	mFlashSink = NULL;
	
	mFlashInterface = NULL;
	mOleObject = NULL;
	mWindowlessObject = NULL;

	mFlashLibHandle = NULL;

	CoInitialize(NULL);

	mFlashLibHandle = LoadLibraryA(GetAppDir()+"gr_mm.dll");
	if(!mFlashLibHandle){
		mFlashLibHandle = LoadLibraryA("flash.ocx");
	}
	//InitializeFlash();!!!-not here
}

void CSpriteNode_Flash::InitializeFlash()
{
	HRESULT aResult;
	mControlSite = new ControlSite();
	mControlSite->AddRef();	
	mControlSite->Init(this);
	if (mFlashLibHandle != NULL)
	{
		IClassFactory* aClassFactory = NULL;
		DllGetClassObjectFunc aDllGetClassObjectFunc = (DllGetClassObjectFunc) GetProcAddress(mFlashLibHandle, "DllGetClassObject");
		aResult = aDllGetClassObjectFunc(CLSID_ShockwaveFlash, IID_IClassFactory, (void**)&aClassFactory);
		aClassFactory->CreateInstance(NULL, IID_IOleObject, (void**)&mOleObject);
		aClassFactory->Release();	
	}
	else
	{
		CoCreateInstance(CLSID_ShockwaveFlash, NULL, 
			CLSCTX_INPROC_SERVER,
			IID_IOleObject,
			(void**)&mOleObject);
	}

	IOleClientSite* aClientSite = NULL;
	mControlSite->QueryInterface(__uuidof(IOleClientSite), (void**) &aClientSite);
	mOleObject->SetClientSite(aClientSite);	

	mOleObject->QueryInterface(__uuidof(IShockwaveFlash), (LPVOID*) &mFlashInterface);

	// Set up the flash presentation parameters
	mFlashInterface->put_BackgroundColor(0x00000000); // makes 
	mFlashInterface->put_EmbedMovie(FALSE);
	//mFlashInterface->put_Scale(L"showAll");
	//mFlashInterface->put_AllowScriptAccess(L"always");
	//if (m_bWindowless)
	mFlashInterface->put_WMode(L"transparent");//mFlashInterface->PutWMode(L"windowed");
	//if (!m_bLocalSecurityDisabled)
	//try {mFlashInterface->DisableLocalSecurity();m_bLocalSecurityDisabled = TRUE;}catch (...){ }

	RECT aRect = toRECT(GetRect());
	aResult = mOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, aClientSite, 0, NULL, &aRect);
  	//aResult = mOleObject->DoVerb(OLEIVERB_SHOW, NULL, aClientSite, 0, NULL, &aRect);
	aClientSite->Release();	
		
	mOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (LPVOID*) &mWindowlessObject);
			
	mFlashSink = new FlashSink();
	mFlashSink->AddRef();	
	mFlashSink->Init(this);
	RebuildImages();
}

CSpriteNode_Flash::~CSpriteNode_Flash()
{
	CleanupImages();
		
	if (mWindowlessObject != NULL)
		mWindowlessObject->Release();
	if (mFlashInterface != NULL)
		mFlashInterface->Release();	

	if (mFlashSink != NULL)
	{
		mFlashSink->Shutdown();
		mFlashSink->Release();
	}

	mOleObject->Close(OLECLOSE_NOSAVE);
		
	if (mOleObject != NULL)
		mOleObject->Release();	

	if (mControlSite != NULL)
		mControlSite->Release();

	// Make sure all our COM objects were actually destroyed
	DEBUG_ASSERT(mCOMCount == 0,"Flash COMErr!");

	if (mFlashLibHandle != NULL)
		FreeLibrary(mFlashLibHandle);	
}

double CSpriteNode_Flash::GetFlashVersion()
{
	CoInitialize(NULL);

	IOleObject* anOleObject = NULL;
	if (FAILED(CoCreateInstance(CLSID_ShockwaveFlash, NULL, 
		CLSCTX_INPROC_SERVER,
		IID_IOleObject,
		(void**) &anOleObject)))
		return 0.0;	

	IShockwaveFlash* aFlashInterface = NULL;
	if (FAILED(anOleObject->QueryInterface(__uuidof(IShockwaveFlash), (LPVOID*) &aFlashInterface)))
		return 0.0;
	
	long aVersion = 0;
	aFlashInterface->FlashVersion(&aVersion);

	aFlashInterface->Release();
	anOleObject->Release();

	return aVersion / 65536.0;
}

void CSpriteNode_Flash::CleanupImages()
{
	if(bitmap_pData){
		delete bitmap_pData;
		bitmap_pData=0;
	}
	if(bitmap_pData_Original){
		delete bitmap_pData_Original;
		bitmap_pData_Original=0;
	}
	DeleteObject(bitmap);
	bitmap=0;
}

bool CSpriteNode_Flash::StartAnimation(const _string& theFileName)
{
	CString aFullPath = getDataPath(theFileName.c_str());
	
	_bstr_t bstr((char*) aFullPath.c_str());
	HRESULT hr = S_OK;
	hr = mFlashInterface->put_Movie(bstr); // you have to change the path here	
	hr = mFlashInterface->put_BackgroundColor(0xFFFFFFFF);
	if ((mPauseCount == 0) && (mFlashInterface->Play() != S_OK))
		return false;	

	mState = STATE_PLAYING;	
	return true;
}

void CSpriteNode_Flash::SetQuality(int theQuality)
{
	static char* aQualityNames[3] = {"Low", "Medium", "High"};
	
	_bstr_t aNewStr = aQualityNames[theQuality];
	mFlashInterface->put_Quality2(aNewStr);
}

void CSpriteNode_Flash::Pause()
{
	mPauseCount++;

	if (mState != STATE_STOPPED)
		mState = STATE_IDLE;

	if ((mPauseCount == 1) && (mFlashInterface != NULL) && (mState != STATE_STOPPED))
		mFlashInterface->StopPlay();
}

void CSpriteNode_Flash::Unpause()
{
	mPauseCount--;
	if ((mPauseCount == 0) && (mFlashInterface != NULL) && (mState != STATE_STOPPED))
	{
		mState = STATE_PLAYING;
		mFlashInterface->Play();
	}
}

void CSpriteNode_Flash::Rewind()
{
	if (mFlashInterface != NULL)
	{
		mFlashInterface->Rewind();
		mFlashInterface->Play();
	}
}

void CSpriteNode_Flash::GotoFrame(int theFrameNum)
{
	if (mFlashInterface != NULL)
	{
		mFlashInterface->GotoFrame(theFrameNum);
		mFlashInterface->Play();
	}
}

void CSpriteNode_Flash::Back()
{
	if (mFlashInterface != NULL)
	{
		mFlashInterface->Back();
		mFlashInterface->Play();
	}
}

void CSpriteNode_Flash::Forward()
{
	if (mFlashInterface != NULL)
	{
		mFlashInterface->Forward();
		mFlashInterface->Play();
	}
}

bool CSpriteNode_Flash::IsPlaying()
{
	VARIANT_BOOL aBool = 0;
	if (mFlashInterface != NULL)
		mFlashInterface->IsPlaying(&aBool);
	return aBool != 0;
}

int CSpriteNode_Flash::GetCurrentFrame()
{	
	long aCurrentFrame = -1;
	if (mFlashInterface != NULL)
		mFlashInterface->CurrentFrame(&aCurrentFrame);
	return aCurrentFrame;
}

_string CSpriteNode_Flash::GetCurrentLabel(const _string& theTimeline)
{
	BSTR aBStr = L"";
	if (mFlashInterface != NULL)
		mFlashInterface->TCurrentLabel(_bstr_t(theTimeline.c_str()), &aBStr);
	return (const char*) _bstr_t(aBStr);
}

void CSpriteNode_Flash::CallFrame(const _string& theTimeline, int theFrameNum)
{
	if (mFlashInterface != NULL)
		mFlashInterface->TCallFrame(_bstr_t(theTimeline.c_str()), theFrameNum);
}

void CSpriteNode_Flash::CallLabel(const _string& theTimeline, const _string& theLabel)
{
	if (mFlashInterface != NULL)
		mFlashInterface->TCallLabel(_bstr_t(theTimeline.c_str()), _bstr_t(theLabel.c_str()));
}

_string CSpriteNode_Flash::GetVariable(const _string& theName)
{
	BSTR aBStr = L"";
	if (mFlashInterface != NULL)
		mFlashInterface->GetVariable(_bstr_t(theName.c_str()), &aBStr);
	return (const char*) _bstr_t(aBStr);
}

void CSpriteNode_Flash::SetVariable(const _string& theName, const _string& theValue)
{
	if (mFlashInterface != NULL)
		mFlashInterface->SetVariable(_bstr_t(theName.c_str()), _bstr_t(theValue.c_str()));
}

void CSpriteNode_Flash::Resize(int theX, int theY, int theWidth, int theHeight)
{
	mDirtyRect = _rcti(theX, theY, theWidth, theHeight);	
	IOleInPlaceObject* anInPlaceObject = NULL;	
	mOleObject->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*) &anInPlaceObject);			

	if (anInPlaceObject != NULL)
	{
		RECT aRect = toRECT(GetRect());
		anInPlaceObject->SetObjectRects(&(aRect), &(aRect));
		anInPlaceObject->Release();
	}
}

void CSpriteNode_Flash::Update()
{
	if (mAutoPause)
	{
		if (!getWindowActive())
		{
			if (!mHasLostFocus)
			{
				if (mAutoPause)
					Pause();
				mHasLostFocus = true;
			}

			return;
		}
		else
		{
			if (mHasLostFocus)
			{
				if (mAutoPause)
					Unpause();
				mHasLostFocus = false;
			}
		}
	}

	if (mState == STATE_PLAYING)
	{
		VARIANT_BOOL isPlaying = 0;
		mFlashInterface->IsPlaying(&isPlaying);	
		if (!isPlaying)
		{
			mState = STATE_STOPPED;
			if ((mFlashListener != NULL) && (mPauseCount == 0))
				mFlashListener->FlashAnimEnded(mId);
		}
	}
}

void CSpriteNode_Flash::Draw()
{	
	if (mFlashDirty)
	{
		HRESULT hr=S_OK;
		HDC hDC = ::CreateCompatibleDC(NULL);
		HBITMAP hbmold = (HBITMAP)::SelectObject(hDC, bitmap);
		RECT aRect = {0, 0, mWidth, mHeight};
		IViewObject* aViewObject = NULL;
		mFlashInterface->QueryInterface(IID_IViewObject, (LPVOID*) &aViewObject);
		if (aViewObject != NULL)
		{
			{// Dirty strategy...
				::FillRect(hDC,&aRect,CreateSolidBrush(0));
				/*
				_v2i anAbsPos(0,0);
				HRGN aRgn = CreateRectRgn(mDirtyRect.UpperLeftCorner.X - anAbsPos.X, mDirtyRect.UpperLeftCorner.Y - anAbsPos.Y, 
				mDirtyRect.UpperLeftCorner.X + mWidth - anAbsPos.X, 
				mDirtyRect.UpperLeftCorner.Y + mHeight - anAbsPos.Y);
				SelectClipRgn(hDC, aRgn);
				DeleteObject(aRgn);
				*/
			}
			RECTL aRectL = {aRect.left,aRect.top,aRect.right,aRect.bottom};
			hr=aViewObject->Draw(DVASPECT_CONTENT, 1, NULL, NULL, hDC, hDC, &aRectL, &aRectL, 0, 0);//&aRect //DVASPECT_OPAQUE, and DVASPECT_TRANSPARENT//aViewObject->SetExtent(DVASPECT_CONTENT,&aspSize);SIZE aspSize;aspSize.cx=mWidth;	aspSize.cy=mHeight;
			aViewObject->Release();
		}
		::SelectObject(hDC, hbmold);//Deselecting BEFORE GetDIBits! MSDN
		int iRes = ::GetDIBits(hDC, bitmap, 0, mHeight, bitmap_pData, &bitmap_pbi, DIB_RGB_COLORS);
		LPVOID targetPizels = targetNode->getMaterial(0).TextureLayer[0].Texture->lock();
		if(bitmap_pData_Original){
			memcpy(targetPizels,bitmap_pData_Original,mWidth*mHeight*4);
		}
		memcpy(targetPizels,bitmap_pData,mWidth*mHeight*4);
		targetNode->getMaterial(0).TextureLayer[0].Texture->unlock();
		::DeleteDC(hDC);
		mFlashDirty = false;
	}
}

void PrepareRGBBitmapInfo(BITMAPINFO* pRes, WORD wWidth, WORD wHeight)
{
	::ZeroMemory(pRes, sizeof(BITMAPINFO));
	pRes->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pRes->bmiHeader.biWidth = wWidth;
	pRes->bmiHeader.biHeight = -wHeight;
	pRes->bmiHeader.biCompression = BI_RGB; 
	pRes->bmiHeader.biPlanes = 1;
	//pRes->bmiHeader.biBitCount = 24;
	pRes->bmiHeader.biBitCount = 32;
    pRes->bmiHeader.biSizeImage = ((pRes->bmiHeader.biWidth * pRes->bmiHeader.biBitCount +31) & ~31) /8 * pRes->bmiHeader.biHeight;
	pRes->bmiHeader.biClrImportant = 0; 
	return;
}

void CSpriteNode_Flash::RebuildImages()
{
	CleanupImages();
	_d2i resolution = targetNode->getMaterial(0).TextureLayer[0].Texture->getSize();
	mWidth=resolution.Width;
	mHeight=resolution.Height;
	HDC hDC = ::GetDC(NULL);
	bitmap = ::CreateCompatibleBitmap(hDC, mWidth, mHeight);
	BITMAP bmpInfo;
	::GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
	::ReleaseDC(NULL, hDC);
	PrepareRGBBitmapInfo(&bitmap_pbi, (WORD)mWidth, (WORD)mHeight);
	bool bHasMips=targetNode->getMaterial(0).TextureLayer[0].Texture->hasMipMaps();
	DEBUG_ASSERT(bHasMips==false,"Bad tex for flash! (mips)");
	ECOLOR_FORMAT cf=targetNode->getMaterial(0).TextureLayer[0].Texture->getColorFormat();
	DEBUG_ASSERT(cf==ECF_A8R8G8B8,"Bad tex for flash! (cf)");
	long imageSize = mWidth*mHeight*4+1024;
	bitmap_pData = new BYTE[imageSize];
	memset(bitmap_pData,0,imageSize);
	/*
	LPVOID targetPizels = targetNode->getMaterial(0).TextureLayer[0].Texture->lock();
	bitmap_pData_Original = new BYTE[imageSize];
	memset(bitmap_pData_Original,0,imageSize);
	memcpy(bitmap_pData_Original,targetPizels,mWidth*mHeight*4);
	targetNode->getMaterial(0).TextureLayer[0].Texture->unlock();
	*/
	Resize(0,0,mWidth,mHeight);
}

void CSpriteNode_Flash::MouseMove(int x, int y)
{	
	/*
	Widget::MouseMove(x, y);

	LRESULT aResult;
	Point anAbsPos = GetAbsPos();
	mWindowlessObject->OnWindowMessage(WM_MOUSEMOVE, 0, MAKELPARAM(x + anAbsPos.X, y + anAbsPos.y), &aResult);

	if (mIsOver)
		CheckCursor();
	*/ //???
}

void CSpriteNode_Flash::MouseDown(int x, int y, int theBtnNum, int theClickCount)
{
	/* if (theBtnNum == 0)
	{
		LRESULT aResult;
		Point anAbsPos = GetAbsPos();
		mWindowlessObject->OnWindowMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x + anAbsPos.X, y + anAbsPos.y), &aResult);
		CheckCursor();
	}
	*/ //???
}

void CSpriteNode_Flash::MouseUp(int x, int y, int theBtnNum, int theClickCount)
{
	/*if (theBtnNum == 0)
	{
		LRESULT aResult;
		Point anAbsPos = GetAbsPos();
		mWindowlessObject->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(x + anAbsPos.X, y + anAbsPos.y), &aResult);
		CheckCursor();
	}
	*/ //???
}

void CSpriteNode_Flash::MouseDrag(int x, int y)
{
	/*if (mWidgetManager->IsLeftButtonDown())
	{
		LRESULT aResult;
		Point anAbsPos = GetAbsPos();
		mWindowlessObject->OnWindowMessage(WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(x + anAbsPos.X, y + anAbsPos.y), &aResult);
		CheckCursor();
	}
	*/ //???
}

void CSpriteNode_Flash::MouseLeave()
{
/*
	Widget::MouseLeave();

	// To prevent Flash control from setting our cursor if it thinks 
	// our mouse is still over something
	MouseMove(-1, -1);

	gSexyAppBase->mOverrideCursor = NULL;
	gSexyAppBase->SetCursor(CURSOR_POINTER);	
*/ //???
}

void CSpriteNode_Flash::MarkDirty()
{
	mFlashDirty = true;
}

void CSpriteNode_Flash::SysColorChanged()
{
	MarkDirty();
}

_rcti CSpriteNode_Flash::GetRect()
{
	return _rcti(0,0,mWidth,mHeight);
}

CFlashAnimation::CFlashAnimation(CSpriteNode* _targetNode, const CString& _sPath)
{
	flashCOM=0;
	sPath=_sPath;
	targetNode=_targetNode;
}

CFlashAnimation::~CFlashAnimation()
{
	if(flashCOM){
		delete flashCOM;
	}
}

void CFlashAnimation::stepAnimation(CNodeBasement* node, u32 timeMs)
{
	if(!flashCOM || flashCOM->bitmap==0){
		flashCOM=new CSpriteNode_Flash(0,0,targetNode);
		flashCOM->InitializeFlash();
		flashCOM->StartAnimation(sPath.GetBuffer(0));
	}
	flashCOM->MarkDirty();
	flashCOM->Update();
	flashCOM->Draw();
	flashCOM->Unpause();
}

GameRotor-Games and more...
Wiredplane-Shareware utilities...
happilylazy
Posts: 53
Joined: Sun Aug 31, 2008 3:16 pm
Location: Split, Croatia

Post by happilylazy »

Could be useful for some games that embed puzzles in Flash format.
Great.
What now??? =_=''
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Post by IPv6 »

yes, we also use flash for animated comixes, intros and tutorials. It is quite easy to made complex animation in flash
GameRotor-Games and more...
Wiredplane-Shareware utilities...
happilylazy
Posts: 53
Joined: Sun Aug 31, 2008 3:16 pm
Location: Split, Croatia

Post by happilylazy »

Yea, I'm doing the Flash programming also, very powerful tool.
So now I see this thread for Flash integration, and another for IrrLicht in browser integration. I think this is going for a small revolution/evolution in online gaming.
What now??? =_=''
Arcoroc
Posts: 51
Joined: Wed Oct 01, 2008 11:40 pm
Location: Canada

Post by Arcoroc »

Thanks IPv6 for sharing, looks interesting.

I am trying to integrate into irrlicht 1.42, and got reasonably close to get it working.

I made a few assumptions, from your description and reading the code, that may or may not be correct - so here they are:

- Type casting into irrlicht constructs:

Code: Select all

#define _string core::stringc
#define CString core::stringc
#define _rcti core::rect<s32>
#define CSpriteNode scene::IBillboardSceneNode
#define CNodeBasement scene::IBillboardSceneNode
#define INodeAnimator scene::ISceneNodeAnimator
#define _d2i core::dimension2d<s32>
#define _p2i core::position2d<s32>
- added void animateNode(ISceneNode* node, u32 timeMs) function into CFlashAnimation class, mapping a call to stepAnimation(CNodeBasement* node, u32 timeMs):

Code: Select all

class CFlashAnimation:public INodeAnimator 
{ 
public: 
   CSpriteNode_Flash* flashCOM; 
   CSpriteNode* targetNode; 
   CString sPath; 
   CFlashAnimation(CSpriteNode* _targetNode, const CString& _sPath); 
   ~CFlashAnimation(); 
   virtual void stepAnimation(CNodeBasement* node, u32 timeMs); 
   virtual void animateNode(ISceneNode* node, u32 timeMs) { stepAnimation((scene::IBillboardSceneNode*)node,timeMs) ; }

}; 
- used flash9f.ocx as dll, which was installed on my system

- wrote the following calling code, with 'RenderMan' being my wrapper of irrlicht:

Code: Select all

scene::IBillboardSceneNode* node = RenderMan::SceneManager()->addBillboardSceneNode(0, core::dimension2d<f32>(800, 600)); 
node->addAnimator(new CFlashAnimation(node, "flashlib\\imageloader.swf")); 
From there, it compiles ok.

Runtime fails (asserts) in void CSpriteNode_Flash::RebuildImages() on two lines of code, in function CSpriteNode_Flash::RebuildImages() :

Code: Select all

void CSpriteNode_Flash::RebuildImages() 
{ 
   CleanupImages(); 
   _d2i resolution = targetNode->getMaterial(0).TextureLayer[0].Texture->getSize(); 
   
   mWidth=resolution.Width; 
   mHeight=resolution.Height; 
   HDC hDC = ::GetDC(NULL); 
   bitmap = ::CreateCompatibleBitmap(hDC, mWidth, mHeight); 
   BITMAP bmpInfo; 
   ::GetObject(bitmap, sizeof(bmpInfo), &bmpInfo); 
   ::ReleaseDC(NULL, hDC); 
   PrepareRGBBitmapInfo(&bitmap_pbi, (WORD)mWidth, (WORD)mHeight); 

   bool bHasMips=targetNode->getMaterial(0).TextureLayer[0].Texture->hasMipMaps(); 
   if(bHasMips==false) printf("error SWFTexturePlayer.cpp: Bad tex for flash! (mips)") ; 

   ECOLOR_FORMAT cf=targetNode->getMaterial(0).TextureLayer[0].Texture->getColorFormat(); 
    if(cf==ECF_A8R8G8B8) printf("error SWFTexturePlayer.cpp: Bad tex for flash! (cf)") ; 

   long imageSize = mWidth*mHeight*4+1024; 
   bitmap_pData = new BYTE[imageSize]; 
   memset(bitmap_pData,0,imageSize); 
   /* 
   LPVOID targetPizels = targetNode->getMaterial(0).TextureLayer[0].Texture->lock(); 
   bitmap_pData_Original = new BYTE[imageSize]; 
   memset(bitmap_pData_Original,0,imageSize); 
   memcpy(bitmap_pData_Original,targetPizels,mWidth*mHeight*4); 
   targetNode->getMaterial(0).TextureLayer[0].Texture->unlock(); 
   */ 
   Resize(0,0,mWidth,mHeight); 
} 
Those two lines assert:

Code: Select all

   bool bHasMips=targetNode->getMaterial(0).TextureLayer[0].Texture->hasMipMaps(); 
   if(bHasMips==false) printf("error SWFTexturePlayer.cpp: Bad tex for flash! (mips)") ; 

   ECOLOR_FORMAT cf=targetNode->getMaterial(0).TextureLayer[0].Texture->getColorFormat(); 
    if(cf==ECF_A8R8G8B8) printf("error SWFTexturePlayer.cpp: Bad tex for flash! (cf)") ; 
About color format, i am using this call to initialize the texture - however the video driver creates a ARGB texture anyway:

Code: Select all

	scene::IBillboardSceneNode* node = RenderMan::SceneManager()->addBillboardSceneNode(0, core::dimension2d<f32>(800, 600)); 
				node->setMaterialFlag(video::EMF_LIGHTING, false);
				node->setMaterialType(video::EMT_SOLID);
				ITexture* tex = RenderMan::Driver()->addTexture(core::dimension2d<s32>(800, 600),"swf",video::ECF_R5G6B5) ;
			    ECOLOR_FORMAT cf1=tex->getColorFormat(); 
Here a breakpoint on cf1 reveals the texture has been created as ARGB.

Also, the code seems to require mipmaps to be created. Here i must be doing something naive, which does not work either:

Code: Select all

		tex->regenerateMipMapLevels() ;
				node->setMaterialTexture(0, tex );
				
I am somehow assuming regenerateMipmaplevels() would procedurally create mipmaps, but that seems a bit too magical, and 'tex' is not created with mipmaps.

Can you spot what i am doing wrong?

Thanks much.
Arcoroc
Posts: 51
Joined: Wed Oct 01, 2008 11:40 pm
Location: Canada

Post by Arcoroc »

Update, never mind the mipmaps generation issue - solved. Had unexpectedly disabled mipmapping in earlier function call.

Still stands the color format issue, which always creates ARGB on AddTexture().

Btw, what color format should be set for rendering flash to texture?

Over and out.
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

it would be an advantage for irrlicht if this is part of the core, imo. good job!
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Post by IPv6 »

It works only with ECF_A8R8G8B8, sorry :( the main reason it that Flash providing it`s "video state" in this format. And, as we need to copy-paste it`s content to texture as fast as possible, no retranslation from one color format to another is really possible, or you will suffer awful fps. So we need to keep texture in the same format as Flash internally using

And for the sake of clearness, the line
DEBUG_ASSERT(bHasMips==false,"Bad tex for flash! (mips)");
means that there is an error when bHasMips!=false. (bHasMips==false) - is good situation and (bHasMips!=false) is not. but mipmaps are not preventing code from working at all (but flash content will be put into first mipmap always, i assume)

Sorry for not mentioning this earlier :(
GameRotor-Games and more...
Wiredplane-Shareware utilities...
Arcoroc
Posts: 51
Joined: Wed Oct 01, 2008 11:40 pm
Location: Canada

Post by Arcoroc »

Thanks much for the clarification, i will try again with these perls of knowledge.

So far i managed to display a.. black screen :P

thanks for the base class IPv6, will post an update.
Frank Chendra
Posts: 1
Joined: Thu Apr 30, 2009 9:42 am

Source please?

Post by Frank Chendra »

Hi,

could anyone here (either Arcoroc or IPv6) please post the adapted files in order to compile the flash support into Irrlicht?

I would be grateful for this, as I am trying to get it to work and the compiler keeps complaining. I am lacking the C++ skills to get it to work, sorry.

But i am very interested in this.

Any help would be much appreciated.
Scarabol
Posts: 167
Joined: Sat Jan 03, 2009 5:26 pm
Location: Aachen, Germany

Post by Scarabol »

Im very interested, too.

Does anybody has a running version of this?

MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Scarabol
Posts: 167
Joined: Sat Jan 03, 2009 5:26 pm
Location: Aachen, Germany

Post by Scarabol »

Does anybody know how it works?

Does it use ActiveX Control?

MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Scarabol
Posts: 167
Joined: Sat Jan 03, 2009 5:26 pm
Location: Aachen, Germany

Post by Scarabol »

OMG IT WORKS!!!

If anybody is interested in it, tell me.

MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Brainsaw
Posts: 1183
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Post by Brainsaw »

I am not really (not yet) interested in a Flash to texture class, but I think you should put it online nevertheless, so that the current version can be found easily.
Dustbin::Games on the web: https://www.dustbin-online.de/

Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Post Reply