00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "Hikari.h"
00037 #include "Ogre.h"
00038 #include "FlashControl.h"
00039 #include "impl/FlashSite.h"
00040 #include "impl/FlashHandler.h"
00041 #include "impl/RenderBuffer.h"
00042 #include "OgreViewportOverlay.h"
00043 #include "OgreBitwise.h"
00044
00045
00046 #include "../SCOLPack/SO3SCOL.h"
00047 #include "../SO3Renderer/SO3FlashControl.h"
00048 #include "../SO3Renderer/SO3Viewport.h"
00049 #include "../SO3Renderer/SO3Window.h"
00050 #include "../SO3Renderer/SO3Root.h"
00051 #include "../SO3SceneGraph/SO3Scene.h"
00052
00053 extern int SO3FLASHCONTROL;
00054
00055 using namespace Ogre;
00056
00057 extern HWND hwndScol;
00058 extern int FLASHCONTROL_CONTACTCB_TIME;
00059 extern int FLASHCONTROL_IS_INSIDE;
00060 extern int FLASHCONTROL_INSIDE_EVENT;
00061 extern int FLASHCONTROL_OUTSIDE_EVENT;
00062 extern int FLASHCONTROL_MOUSEDOWN_EVENT;
00063 extern int FLASHCONTROL_MOUSEUP_EVENT;
00064 extern int FLASHCONTROL_WHEEL_EVENT;
00065
00066 FlashControl::FlashControl(const string& _name, Viewport* viewport, int _width, int _height, const Hikari::Position& position, unsigned short zOrder) : IFlashControl()
00067 {
00068 name=_name;
00069 materialName = _name + "Material";
00070 textureName = _name + "Texture";
00071 site=0;
00072 handler=0;
00073 flashInterface=0;
00074 oleObject=0;
00075 windowlessObject=0;
00076 width=_width;
00077 height=_height;
00078 comCount=0;
00079 mainContext=0;
00080 mainBitmap=0;
00081 mainBuffer=0;
00082 altContext=0;
00083 altBitmap=0;
00084 altBuffer=0;
00085 renderBuffer=0;
00086 usingAlphaHack=false;
00087 onMaterial = false;
00088 isFirstInside=false;
00089 isFirstOutside=false;
00090 isClean=true;
00091 isTotallyDirty=false;
00092 overlay=0;
00093 texWidth=_width;
00094 texHeight=_height;
00095 texDepth=0;
00096 texPitch=0;
00097
00098 compensateNPOT=false;
00099 Foreground = false;
00100 topOnFocus = false;
00101 keyBoardEnable = true;
00102 mouseEnable = true;
00103 isTransparent=false;
00104 okayToDelete=false;
00105 isDraggable=true;
00106 isOverlay = true;
00107 isIgnoringTransparent=true;
00108 transThreshold=0.04f;
00109 lastDirtyWidth = 0;
00110 lastDirtyHeight = 0;
00111 scolFlags |= SO3_FLASH_ENABLE_MOUSE;
00112 scolFlags |= SO3_FLASH_ENABLE_KEYBOARD;
00113 movieLoaded = false;
00114
00115 sBlend = SBF_ONE;
00116 dBlend = SBF_ZERO;
00117 originalDepthWritting = true;
00118
00119 _tec = -1;
00120 _pass = -1;
00121 _unit = -1;
00122 texUnit = NULL;
00123
00124 renderBuffer = new Hikari::Impl::RenderBuffer(_width, _height);
00125
00126 createControl();
00127 createMaterial();
00128
00129 overlay = new OgreViewportOverlay(name, viewport, width, height, position, materialName, zOrder);
00130 if(compensateNPOT)
00131 overlay->getPanel()->setUV(0, 0, (Real)width/(Real)texWidth, (Real)height/(Real)texHeight);
00132 }
00133
00134 FlashControl::FlashControl(const string& _name,SScene* scene,const string& _matName, int _width, int _height,int techID,int passID,int unitID) : IFlashControl()
00135 {
00136 name=_name;
00137 materialName = _matName;
00138 textureName = _name + "Texture";
00139 currentScene = scene;
00140 width= _width;
00141 height = _height;
00142 site = 0;
00143 handler = 0;
00144 flashInterface = 0;
00145 oleObject = 0; windowlessObject = 0;
00146 comCount = 0;
00147 mainContext = 0; mainBitmap = 0; mainBuffer = 0;
00148 altContext = 0; altBitmap = 0; altBuffer = 0;
00149 renderBuffer = 0;
00150 usingAlphaHack=false;
00151 isFirstInside=false;
00152 isFirstOutside=false;
00153 onMaterial = true;
00154 keyBoardEnable = false;
00155 mouseEnable = false;
00156 isOverlay = false;
00157 isClean=true;
00158 isTotallyDirty=false;
00159 overlay = 0;
00160 texDepth = 0;
00161 texPitch = 0;
00162
00163 sBlend = SBF_ONE;
00164 dBlend = SBF_ZERO;
00165 originalDepthWritting = true;
00166 _tec = -1;
00167 _pass = -1;
00168 _unit = -1;
00169 texUnit = NULL;
00170
00171 compensateNPOT=false;
00172 isTransparent=false;
00173 okayToDelete=false;
00174 isIgnoringTransparent=false;
00175 transThreshold=0;
00176 scolFlags |= SO3_FLASH_ENABLE_MOUSE;
00177 scolFlags |= SO3_FLASH_ENABLE_KEYBOARD;
00178 movieLoaded = false;
00179
00180 renderBuffer = new Hikari::Impl::RenderBuffer(width, height);
00181 createControl();
00182 applyTexture(_matName,techID,passID,unitID);
00183 }
00184
00185 FlashControl::~FlashControl()
00186 {
00187 if(overlay)
00188 SAFE_DELETE(overlay);
00189 if(!onMaterial)
00190 {
00191 MaterialManager::getSingletonPtr()->remove(materialName);
00192 texture.setNull();
00193 TextureManager::getSingletonPtr()->remove(textureName);
00194 }
00195 else
00196 {
00197
00198 restoreMaterial();
00199 }
00200
00201 if(windowlessObject) windowlessObject->Release();
00202 if(flashInterface) flashInterface->Release();
00203 if(handler)
00204 {
00205 handler->Shutdown();
00206 handler->Release();
00207 }
00208
00209 if(oleObject)
00210 {
00211 oleObject->Close(OLECLOSE_NOSAVE);
00212 oleObject->Release();
00213 }
00214
00215 if(site)
00216 site->Release();
00217
00218 if(comCount)
00219 LogManager::getSingleton().logMessage("WARNING: Hikari::FlashControl is leaking COM objects!");
00220
00221 if(mainContext) ::DeleteDC(mainContext);
00222 if(mainBitmap) ::DeleteObject(mainBitmap);
00223 if(altContext) ::DeleteDC(altContext);
00224 if(altBitmap) ::DeleteObject(altBitmap);
00225 if(renderBuffer)
00226 SAFE_DELETE(renderBuffer);
00227 }
00228
00229 void FlashControl::restoreMaterial()
00230 {
00231 MaterialPtr material = (MaterialPtr)MaterialManager::getSingleton().getByName(materialName);
00232 if(!material.isNull() && ( _tec != -1) && (_pass != -1) && (_unit != -1))
00233 {
00234 Pass * matPass = material->getTechnique(_tec)->getPass(_pass);
00235 matPass->setDepthWriteEnabled(originalDepthWritting);
00236
00237
00238
00239 matPass->setSceneBlending(sBlend,dBlend);
00240
00241 if((matPass->getNumTextureUnitStates() >= _unit+1) && !oldTex.isNull())
00242 {
00243 texUnit = matPass->getTextureUnitState(_unit);
00244 texUnit->setTextureName(oldTex->getName());
00245 }
00246 }
00247
00248 texture.setNull();
00249 TextureManager::getSingletonPtr()->remove(textureName);
00250 }
00251
00252 typedef HRESULT (__stdcall *GetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
00253
00254 void FlashControl::createControl()
00255 {
00256 site = new Hikari::Impl::FlashSite();
00257 site->AddRef();
00258 site->Init(this, NULL);
00259
00260 HMODULE flashLib = Hikari::HikariManager::getSingleton().flashLib;
00261
00262
00263 if(flashLib)
00264 {
00265 IClassFactory* factory = 0;
00266 GetClassObject getClassFunc = (GetClassObject)GetProcAddress(flashLib, "DllGetClassObject");
00267 HRESULT result = getClassFunc(ShockwaveFlashObjects::CLSID_ShockwaveFlash, IID_IClassFactory, (void**)&factory);
00268 if(SUCCEEDED(result))
00269 {
00270 factory->CreateInstance(NULL, IID_IOleObject, (void**)&oleObject);
00271 factory->Release();
00272 }
00273 }
00274
00275
00276 if(!oleObject)
00277 {
00278 HRESULT result = CoCreateInstance(ShockwaveFlashObjects::CLSID_ShockwaveFlash, 0, CLSCTX_INPROC_SERVER, IID_IOleObject, (void**)&oleObject);
00279 if(FAILED(result))
00280 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Unable to load the Flash ActiveX control.", "FlashControl::createControl");
00281 }
00282
00283 IOleClientSite* clientSite = 0;
00284 site->QueryInterface(__uuidof(IOleClientSite), (void**)&clientSite);
00285 oleObject->SetClientSite(clientSite);
00286 clientSite->Release();
00287
00288 IOleInPlaceObject* inPlaceObject = 0;
00289 HRESULT result = oleObject->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*)&inPlaceObject);
00290 if(FAILED(result))
00291 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Unable to load the Flash ActiveX control.", "FlashControl::createControl");
00292
00293 if(inPlaceObject)
00294 {
00295 invalidateTotally();
00296
00297 inPlaceObject->SetObjectRects(&dirtyBounds, &dirtyBounds);
00298 inPlaceObject->Release();
00299 }
00300
00301 result = oleObject->QueryInterface(__uuidof(ShockwaveFlashObjects::IShockwaveFlash), (LPVOID*)&flashInterface);
00302 if(FAILED(result))
00303 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Unable to load the Flash ActiveX control.", "FlashControl::createControl");
00304
00305 flashInterface->PutWMode("opaque");
00306
00307 oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, clientSite, 0, 0, 0);
00308 clientSite->Release();
00309
00310 result = oleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (LPVOID*)&windowlessObject);
00311
00312 if(FAILED(result))
00313 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Unable to load the Flash ActiveX control.", "FlashControl::createControl");
00314
00315 handler = new Hikari::Impl::FlashHandler();
00316 handler->AddRef();
00317 handler->Init(this);
00318
00319 IViewObject* curView = 0;
00320 result = flashInterface->QueryInterface(IID_IViewObject, (void**)&curView);
00321
00322 if(FAILED(result))
00323 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Unable to load the Flash ActiveX control.", "FlashControl::createControl");
00324 }
00325
00326 void FlashControl::createMaterial()
00327 {
00328 MaterialManager::getSingletonPtr()->remove(materialName);
00329 texture.setNull();
00330 TextureManager::getSingletonPtr()->remove(textureName);
00331
00332 texWidth = width;
00333 texHeight = height;
00334
00335 _tec = 0;
00336 _pass = 0;
00337 _unit = 0;
00338
00339 if(!Bitwise::isPO2(width) || !Bitwise::isPO2(height))
00340 {
00341 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES))
00342 {
00343 if(Root::getSingleton().getRenderSystem()->getCapabilities()->getNonPOW2TexturesLimited())
00344 compensateNPOT = true;
00345 }
00346 else compensateNPOT = true;
00347
00348 if(compensateNPOT)
00349 {
00350 texWidth = Bitwise::firstPO2From(width);
00351 texHeight = Bitwise::firstPO2From(height);
00352 }
00353 }
00354
00355 texture = TextureManager::getSingletonPtr()->createManual(
00356 textureName,
00357 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
00358 TEX_TYPE_2D, (uint)texWidth,
00359 (uint)texHeight,
00360 0,
00361 isTransparent? PF_BYTE_BGRA : PF_BYTE_BGR,
00362 TU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
00363 this);
00364
00365 HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
00366
00367 pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
00368
00369 const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
00370
00371 texDepth = Ogre::PixelUtil::getNumElemBytes(pixelBox.format);
00372 texPitch = (pixelBox.rowPitch*texDepth);
00373
00374 uint8* pDest = static_cast<uint8*>(pixelBox.data);
00375
00376 memset(pDest, 128, texHeight*texPitch);
00377
00378 pixelBuffer->unlock();
00379
00380 MaterialPtr material = MaterialManager::getSingleton().create(materialName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00381 Pass* matPass = material->getTechnique(_tec)->getPass(_pass);
00382
00383 matPass->setSceneBlending(isTransparent? SBT_TRANSPARENT_ALPHA : SBT_REPLACE);
00384 matPass->setDepthWriteEnabled(isTransparent? false : true);
00385
00386 texUnit = matPass->createTextureUnitState(textureName);
00387 texUnit->setTextureFiltering(FO_NONE, FO_NONE, FO_NONE);
00388
00389 invalidateTotally();
00390
00391 if(overlay)
00392 {
00393 overlay->getPanel()->setMaterialName(materialName);
00394 if(compensateNPOT)
00395 overlay->getPanel()->setUV(0, 0, (Real)width/(Real)texWidth, (Real)height/(Real)texHeight);
00396 }
00397 }
00398
00399
00400
00401
00402 void FlashControl::updateTexture()
00403 {
00404 if(renderBuffer)
00405 SAFE_DELETE(renderBuffer);
00406
00407 restoreMaterial();
00408
00409 renderBuffer = new Hikari::Impl::RenderBuffer(width, height);
00410 texWidth = width;
00411 texHeight = height;
00412
00413 if(!Bitwise::isPO2(width) || !Bitwise::isPO2(height))
00414 {
00415 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES))
00416 {
00417 if(Root::getSingleton().getRenderSystem()->getCapabilities()->getNonPOW2TexturesLimited())
00418 compensateNPOT = true;
00419 }
00420 else compensateNPOT = true;
00421
00422 if(compensateNPOT)
00423 {
00424 texWidth = Bitwise::firstPO2From(width);
00425 texHeight = Bitwise::firstPO2From(height);
00426 }
00427 }
00428
00429 texture = TextureManager::getSingletonPtr()->createManual(
00430 textureName,
00431 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
00432 TEX_TYPE_2D,
00433 (uint)texWidth,
00434 (uint)texHeight,
00435 0,
00436 isTransparent? PF_BYTE_BGRA : PF_BYTE_BGR,
00437 TU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
00438 this);
00439
00440 HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
00441 pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
00442 const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
00443 texDepth = Ogre::PixelUtil::getNumElemBytes(pixelBox.format);
00444 texPitch = (pixelBox.rowPitch*texDepth);
00445
00446 uint8* pDest = static_cast<uint8*>(pixelBox.data);
00447
00448 memset(pDest, 128, texHeight*texPitch);
00449
00450 pixelBuffer->unlock();
00451
00452 MaterialPtr material = (MaterialPtr)MaterialManager::getSingleton().getByName(materialName);
00453 Pass* matPass;
00454 matPass = material->getTechnique(_tec)->getPass(_pass);
00455
00456 if (isTransparent && (_unit == 0))
00457 {
00458 matPass->setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
00459 matPass->setDepthWriteEnabled(false);
00460 }
00461
00462 texUnit = matPass->getTextureUnitState(_unit);
00463
00464 texUnit->setTextureName(textureName);
00465
00466 if (onMaterial)
00467 {
00468 texUnit->setTextureFiltering(FO_LINEAR , FO_LINEAR , FO_LINEAR);
00469 }
00470 else
00471 {
00472 texUnit->setTextureFiltering(FO_NONE, FO_NONE, FO_NONE);
00473 }
00474
00475 invalidateTotally();
00476 IOleInPlaceObject* inPlaceObject = 0;
00477 oleObject->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*)&inPlaceObject);
00478
00479 if(inPlaceObject)
00480 {
00481 inPlaceObject->SetObjectRects(&dirtyBounds, &dirtyBounds);
00482 inPlaceObject->Release();
00483 }
00484
00485 if(overlay)
00486 {
00487 if(compensateNPOT)
00488 overlay->getPanel()->setUV(0, 0, (Real)width/(Real)texWidth, (Real)height/(Real)texHeight);
00489 overlay->resize(width, height);
00490 }
00491 }
00492
00493
00494
00495 void FlashControl::applyTexture(string matname, int techidx, int passidx,int unitidx)
00496 {
00497 if(renderBuffer)
00498 SAFE_DELETE(renderBuffer);
00499
00500 restoreMaterial();
00501
00502 renderBuffer = new Hikari::Impl::RenderBuffer(width, height);
00503
00504 texWidth = width;
00505 texHeight = height;
00506 _tec = techidx;
00507 _pass = passidx;
00508 _unit = unitidx;
00509
00510 materialName = matname;
00511 if(!Bitwise::isPO2(width) || !Bitwise::isPO2(height))
00512 {
00513 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES))
00514 {
00515 if(Root::getSingleton().getRenderSystem()->getCapabilities()->getNonPOW2TexturesLimited())
00516 compensateNPOT = true;
00517 }
00518 else compensateNPOT = true;
00519
00520 if(compensateNPOT)
00521 {
00522 texWidth = Bitwise::firstPO2From(width);
00523 texHeight = Bitwise::firstPO2From(height);
00524 }
00525 }
00526 Ogre::NameValuePairList viewConfig;
00527 viewConfig["textureFlash"] = "1";
00528
00529 texture = TextureManager::getSingletonPtr()->createManual(
00530 textureName,
00531 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
00532 TEX_TYPE_2D,
00533 (uint)texWidth,
00534 (uint)texHeight,
00535 0,
00536 isTransparent? PF_BYTE_BGRA : PF_BYTE_BGR, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
00537 this);
00538
00539 HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
00540 pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
00541
00542 const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
00543 texDepth = Ogre::PixelUtil::getNumElemBytes(pixelBox.format);
00544 texPitch = (pixelBox.rowPitch*texDepth);
00545
00546 uint8* pDest = static_cast<uint8*>(pixelBox.data);
00547
00548 memset(pDest, 128, texHeight*texPitch);
00549
00550 pixelBuffer->unlock();
00551
00552 MaterialPtr material = (MaterialPtr)MaterialManager::getSingleton().getByName(matname);
00553 Pass* matPass = material->getTechnique(techidx)->getPass(passidx);
00554
00555 if(matPass->getNumTextureUnitStates()>= (unitidx+1))
00556 {
00557
00558 bool finded = false;
00559
00560 SFlashControlMap::iterator iFlashControlSearched = currentScene->listOfFlashControl.find(material->getName());
00561 if(iFlashControlSearched != currentScene->listOfFlashControl.end())
00562 {
00563 oldTex = iFlashControlSearched->second->oldTex;
00564 finded = true;
00565 }
00566
00567 if(!finded)
00568 oldTex = matPass->getTextureUnitState(unitidx)->_getTexturePtr();
00569 }
00570
00571 originalDepthWritting = matPass->getDepthWriteEnabled();
00572
00573 sBlend = matPass->getSourceBlendFactor();
00574 dBlend = matPass->getDestBlendFactor();
00575
00576
00577 if ((_unit == 0) && isTransparent)
00578 {
00579 matPass->setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
00580 matPass->setDepthWriteEnabled(false);
00581 };
00582
00583 texUnit = matPass->getTextureUnitState(_unit);
00584 texUnit->setTextureName(textureName);
00585
00586
00587 texUnit->setTextureFiltering(FO_LINEAR , FO_LINEAR , FO_LINEAR);
00588
00589 invalidateTotally();
00590 IOleInPlaceObject* inPlaceObject = 0;
00591 oleObject->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*)&inPlaceObject);
00592
00593 if(inPlaceObject)
00594 {
00595 inPlaceObject->SetObjectRects(&dirtyBounds, &dirtyBounds);
00596 inPlaceObject->Release();
00597 }
00598
00599 if(overlay)
00600 {
00601 if(compensateNPOT)
00602 overlay->getPanel()->setUV(0, 0, (Real)width/(Real)texWidth, (Real)height/(Real)texHeight);
00603 overlay->resize(width, height);
00604 }
00605 }
00606
00607
00608 void FlashControl::load(const Ogre::String& movieFilename, Hikari::HikariManager* hikariMgr, int type )
00609 {
00610
00611 if(type == SO3_FLASH_FILE)
00612 {
00613
00614
00615
00616
00617 FILE* file = fopen((char*)(movieFilename.c_str()), "r");
00618 if(file)
00619 {
00620 fclose(file);
00621 flashInterface->PutMovie((char*)(movieFilename.c_str()));
00622 movieLoaded = true;
00623 }
00624 else
00625 {
00626 OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND, "Could not load '" + movieFilename + "', the file was not found.", "FlashControl::load");
00627 }
00628 }
00629 else
00630 {
00631 flashInterface->PutMovie(movieFilename.c_str());
00632 movieLoaded = true;
00633 }
00634 }
00635
00636 void FlashControl::play()
00637 {
00638 flashInterface->Play();
00639 }
00640
00641 void FlashControl::stop()
00642 {
00643 flashInterface->Stop();
00644 }
00645
00646 void FlashControl::rewind()
00647 {
00648 flashInterface->Rewind();
00649 }
00650
00651 void FlashControl::gotoFrame(long frameNum)
00652 {
00653 flashInterface->raw_GotoFrame(frameNum);
00654 }
00655
00656 void FlashControl::setLoop(bool shouldLoop)
00657 {
00658 flashInterface->PutLoop(shouldLoop);
00659 }
00660
00661 void FlashControl::setTransparent(bool isTransparent, bool useAlphaHack)
00662 {
00663 this->isTransparent = isTransparent;
00664
00665
00666 if(isTransparent)
00667 {
00668 flashInterface->PutWMode("transparent");
00669 usingAlphaHack = useAlphaHack;
00670 }
00671 else
00672 {
00673 flashInterface->PutWMode("opaque");
00674 usingAlphaHack = false;
00675 }
00676
00677 updateTexture();
00678 }
00679
00680 void FlashControl::setQuality(short renderQuality)
00681 {
00682 switch(renderQuality)
00683 {
00684 case Hikari::RQ_LOW:
00685 flashInterface->PutQuality2("low");
00686 break;
00687 case Hikari::RQ_MEDIUM:
00688 flashInterface->PutQuality2("medium");
00689 break;
00690 case Hikari::RQ_HIGH:
00691 flashInterface->PutQuality2("high");
00692 break;
00693 case Hikari::RQ_BEST:
00694 flashInterface->PutQuality2("best");
00695 break;
00696 case Hikari::RQ_AUTOLOW:
00697 flashInterface->PutQuality2("autolow");
00698 break;
00699 case Hikari::RQ_AUTOHIGH:
00700 flashInterface->PutQuality2("autohigh");
00701 break;
00702 }
00703 }
00704
00705 void FlashControl::setScaleMode(short scaleMode)
00706 {
00707 flashInterface->PutScaleMode(scaleMode);
00708 updateTexture();
00709 }
00710
00711 void FlashControl::setDraggable(bool isDraggable)
00712 {
00713 this->isDraggable = isDraggable;
00714 }
00715
00716 void FlashControl::setIgnoreTransparentPixels(bool shouldIgnore, Ogre::Real threshold)
00717 {
00718 isIgnoringTransparent = shouldIgnore;
00719 transThreshold = threshold;
00720 }
00721
00722 const Ogre::String & FlashControl::getName() const
00723 {
00724 return name;
00725 }
00726
00727 const Ogre::String & FlashControl::getMaterialName() const
00728 {
00729 return materialName;
00730 }
00731
00732 void FlashControl::bind(const std::wstring& funcName, const Hikari::FlashDelegate& callback)
00733 {
00734 if(funcName.empty() || callback.empty())
00735 return;
00736
00737 delegateMap[funcName] = callback;
00738 }
00739
00740 void FlashControl::unbind(const std::wstring& funcName)
00741 {
00742 DelegateIter i = delegateMap.find(funcName);
00743 if(i != delegateMap.end())
00744 delegateMap.erase(i);
00745 }
00746
00747 Hikari::FlashValue FlashControl::callFunction(const std::wstring& funcName, const Hikari::Arguments& args)
00748 {
00749 BSTR returnVal = 0;
00750 HRESULT result = flashInterface->raw_CallFunction(_bstr_t(Hikari::Impl::serializeInvocation(funcName, args).c_str()), &returnVal);
00751 if(FAILED(result))
00752 {
00753 OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED,
00754 "Failed to call ActionScript function '" + funcName + "' from FlashControl '" + name + "'",
00755 "FlashControl::callFunction");
00756 }
00757 return Hikari::Impl::deserializeValue((wchar_t*)returnVal);
00758 }
00759
00760 void FlashControl::hide()
00761 {
00762 if(overlay)
00763 overlay->hide();
00764 }
00765 void FlashControl::show()
00766 {
00767 if(overlay)
00768 overlay->show();
00769 }
00770 bool FlashControl::getVisibility() const
00771 {
00772 if(overlay)
00773 return overlay->isVisible;
00774 else
00775 return false;
00776 }
00777 void FlashControl::setOpacity(Ogre::Real opacity)
00778 {
00779 if(texUnit)
00780 texUnit->setAlphaOperation(LBX_MODULATE, LBS_TEXTURE, LBS_MANUAL, 1, opacity);
00781 }
00782
00783 void FlashControl::focus()
00784 {
00785
00786 Hikari::HikariManager::getSingleton().focusControl(0, 0, this);
00787 }
00788
00789 void FlashControl::updateZOrder()
00790 {
00791 std::vector<IFlashControl*> sortedControls;
00792 std::map<string, IFlashControl*>::iterator iter;
00793
00794 unsigned short highestZ = 0;
00795 for(iter = scolRoot->O3HikariManager->controls.begin(); iter != scolRoot->O3HikariManager->controls.end(); iter++)
00796 if(iter->second)
00797 sortedControls.push_back(iter->second);
00798 struct compare { bool operator()(IFlashControl* a, IFlashControl* b){ return(a->getZOrder() > b->getZOrder()); }};
00799 std::sort(sortedControls.begin(), sortedControls.end(), compare());
00800
00801 std::vector<int> myZOrder;
00802 for(unsigned int i = 0; i < sortedControls.size(); i++)
00803 {
00804 myZOrder.push_back(sortedControls.at(i)->initialZOrder);
00805 }
00806 struct compareZOrder { bool operator()(int a, int b){ return(a > b); }};
00807 std::sort(myZOrder.begin(), myZOrder.end(), compareZOrder());
00808
00809
00810 std::vector<IFlashControl*> sortedControlsNoForeground;
00811 for(iter = scolRoot->O3HikariManager->controls.begin(); iter != scolRoot->O3HikariManager->controls.end(); iter++)
00812 {
00813 if(iter->second)
00814 {
00815 if(!iter->second->Foreground)
00816 {
00817 sortedControlsNoForeground.push_back(iter->second);
00818 }
00819 }
00820 }
00821 std::sort(sortedControlsNoForeground.begin(), sortedControlsNoForeground.end(), compare());
00822
00823 std::vector<IFlashControl*> sortedControlsForeground;
00824 for(iter = scolRoot->O3HikariManager->controls.begin(); iter != scolRoot->O3HikariManager->controls.end(); iter++)
00825 {
00826 if(iter->second)
00827 {
00828 if(iter->second->Foreground)
00829 {
00830 sortedControlsForeground.push_back(iter->second);
00831 }
00832 }
00833 }
00834 std::sort(sortedControlsForeground.begin(), sortedControlsForeground.end(), compare());
00835
00836
00837
00838 for(int i = sortedControlsNoForeground.size()-1;i>1; i--)
00839 {
00840 if(sortedControlsNoForeground.at(i)->getZOrder()==sortedControlsNoForeground.at(i-1)->getZOrder())
00841 {
00842 if(sortedControlsNoForeground.at(i)->initialZOrder>sortedControlsNoForeground.at(i-1)->initialZOrder)
00843 {
00844 IFlashControl * tmpCtrl;
00845 tmpCtrl = sortedControlsNoForeground.at(i);
00846 sortedControlsNoForeground.at(i) = sortedControlsNoForeground.at(i-1);
00847 sortedControlsNoForeground.at(i-1) = tmpCtrl;
00848 }
00849 }
00850 }
00851
00852
00853 for(int i = sortedControlsForeground.size()-1;i>1; i--)
00854 {
00855 if(sortedControlsForeground.at(i)->getZOrder()==sortedControlsForeground.at(i-1)->getZOrder())
00856 {
00857 if(sortedControlsForeground.at(i)->initialZOrder>sortedControlsForeground.at(i-1)->initialZOrder)
00858 {
00859 IFlashControl * tmpCtrl;
00860 tmpCtrl = sortedControlsForeground.at(i);
00861 sortedControlsForeground.at(i) = sortedControlsForeground.at(i-1);
00862 sortedControlsForeground.at(i-1) = tmpCtrl;
00863 }
00864 }
00865 }
00866 for(unsigned int i = 0; i < sortedControlsForeground.size(); i++) sortedControls.at(i) = sortedControlsForeground.at(i);
00867 for(unsigned int i = sortedControlsForeground.size(); i < sortedControls.size(); i++) sortedControls.at(i) = sortedControlsNoForeground.at(i-sortedControlsForeground.size());
00868 for(unsigned int i = 0; i < sortedControls.size(); i++) sortedControls.at(i)->setZOrder(myZOrder.at(i));
00869 std::sort(sortedControls.begin(), sortedControls.end(), compare());
00870 }
00871
00872 void FlashControl::move(int deltaX, int deltaY)
00873 {
00874 if(overlay)
00875 overlay->move(deltaX, deltaY);
00876 }
00877
00878 void FlashControl::getExtents(unsigned short &width, unsigned short &height) const
00879 {
00880 width = this->width;
00881 height = this->height;
00882 }
00883
00884 void FlashControl::getUVScale(Ogre::Real &uScale, Ogre::Real &vScale) const
00885 {
00886 uScale = vScale = 1;
00887
00888 if(compensateNPOT)
00889 {
00890 uScale = (Real)width/(Real)texWidth;
00891 vScale = (Real)height/(Real)texHeight;
00892 }
00893 }
00894
00895 void FlashControl::injectMouseMove(int xPos, int yPos, int btn)
00896 {
00897 LRESULT result;
00898 MMOUSE* mFlashResult = new MMOUSE();
00899 if(this->isPointOverMe(xPos-(this->getRelativeX(0)),yPos-(this->getRelativeY(0))))
00900 {
00901 mFlashResult->x = xPos;
00902 mFlashResult->y = yPos;
00903 if(this->mouseEnable)
00904 SendMessage( hwndScol, FLASHCONTROL_IS_INSIDE, (int)this,(LPARAM)mFlashResult);
00905 }
00906 if(this->mouseEnable)
00907 {
00908 int but = 0;
00909 if(btn&1)
00910 {
00911 but |= MK_LBUTTON;
00912 }
00913 if(btn&2)
00914 {
00915 but |= MK_RBUTTON;
00916 }
00917 if(btn&16)
00918 {
00919 but |= MK_MBUTTON;
00920 }
00921 windowlessObject->OnWindowMessage(WM_MOUSEMOVE, but, MAKELPARAM(xPos, yPos), &result);
00922 }
00923 SAFE_DELETE(mFlashResult);
00924 }
00925
00926 void FlashControl::injectMouseDown(int xPos, int yPos, int index)
00927 {
00928 LRESULT result;
00929 MMOUSE* mFlashResult = new MMOUSE();
00930 mFlashResult->x = xPos;
00931 mFlashResult->y = yPos;
00932 mFlashResult->index = index;
00933 MMechostr(1,"index button down : %i\n",index);
00934 scolRoot->O3HikariManager->defocusAll();
00935 this->focus();
00936 if(!this->onMaterial)
00937 this->currentViewport->currentWindow->lastOne = this;
00938 if(this->mouseEnable)
00939 {
00940 SendMessage( hwndScol, FLASHCONTROL_MOUSEDOWN_EVENT, (int)this,(LPARAM)mFlashResult);
00941 int but = 0;
00942 int msg = 0;
00943 switch(index)
00944 {
00945 case 1:
00946 {
00947 but = MK_LBUTTON;
00948 msg = WM_LBUTTONDOWN;
00949 break;
00950 }
00951 case 2:
00952 {
00953 but = MK_RBUTTON;
00954 msg = WM_RBUTTONDOWN;
00955 break;
00956 }
00957 case 16:
00958 {
00959 but = MK_MBUTTON;
00960 msg = WM_MBUTTONDOWN;
00961 break;
00962 }
00963 }
00964 windowlessObject->OnWindowMessage(msg, but, MAKELPARAM(xPos, yPos), &result);
00965 }
00966 SAFE_DELETE(mFlashResult);
00967 }
00968
00969 void FlashControl::injectMouseUp(int xPos, int yPos, int index)
00970 {
00971 LRESULT result;
00972 MMOUSE* mFlashResult = new MMOUSE();
00973 mFlashResult->x = xPos;
00974 mFlashResult->y = yPos;
00975 mFlashResult->index = index;
00976 MMechostr(1,"index button up : %i\n",index);
00977 if(this->mouseEnable)
00978 {
00979 SendMessage( hwndScol, FLASHCONTROL_MOUSEUP_EVENT, (int)this,(LPARAM)mFlashResult);
00980 int but = 0;
00981 int msg = 0;
00982 switch(index)
00983 {
00984 case 1:
00985 {
00986 but = MK_LBUTTON;
00987 msg = WM_LBUTTONUP;
00988 break;
00989 }
00990 case 2:
00991 {
00992 but = MK_RBUTTON;
00993 msg = WM_RBUTTONUP;
00994 break;
00995 }
00996 case 16:
00997 {
00998 but = MK_MBUTTON;
00999 msg = WM_MBUTTONUP;
01000 break;
01001 }
01002 }
01003 windowlessObject->OnWindowMessage(msg, but, MAKELPARAM(xPos, yPos), &result);
01004 }
01005 SAFE_DELETE(mFlashResult);
01006 }
01007
01008 #ifndef WM_MOUSEWHEEL
01009 # define WM_MOUSEWHEEL 0x020A
01010 #endif
01011
01012 void FlashControl::injectMouseWheel(int relScroll, int xPos, int yPos)
01013 {
01014 LRESULT result;
01015 MMOUSE* mFlashResult = new MMOUSE();
01016 mFlashResult->x = xPos;
01017 mFlashResult->y = yPos;
01018 mFlashResult->scroll = relScroll;
01019 if(this->mouseEnable)
01020 {
01021 SendMessage( hwndScol, FLASHCONTROL_WHEEL_EVENT, (int)this,(LPARAM)mFlashResult);
01022 windowlessObject->OnWindowMessage(WM_MOUSEWHEEL, MAKEWPARAM(0, relScroll), MAKELPARAM(xPos, yPos), &result);
01023 }
01024 SAFE_DELETE(mFlashResult);
01025 }
01026
01027 bool FlashControl::isPointOverMe(int screenX, int screenY)
01028 {
01029 if(!overlay)
01030 {
01031 this->isFirstInside = false;
01032 return false;
01033 }
01034
01035 if(!overlay->isVisible)
01036 {
01037 this->isFirstInside = false;
01038 return false;
01039 }
01040 if(overlay->isWithinBounds(screenX, screenY))
01041 {
01042 if(isTransparent && isIgnoringTransparent)
01043 {
01044 bool res = false;
01045 res = renderBuffer->getBuffer()[overlay->getRelativeY(screenY)*renderBuffer->rowSpan+overlay->getRelativeX(screenX)*4+3] > transThreshold * 255;
01046 if(res && !this->isFirstInside)
01047 {
01048 this->isFirstInside = true;
01049 SendMessage( hwndScol, FLASHCONTROL_INSIDE_EVENT, (int)this,NULL);
01050
01051 }
01052 else if(!res && this->isFirstInside)
01053 {
01054 this->isFirstInside = false;
01055 SendMessage( hwndScol, FLASHCONTROL_OUTSIDE_EVENT, (int)this,NULL);
01056
01057 }
01058 return res;
01059 }
01060 else
01061 {
01062 if(!this->isFirstInside)
01063 {
01064 this->isFirstInside = true;
01065 SendMessage( hwndScol, FLASHCONTROL_INSIDE_EVENT, (int)this,NULL);
01066 }
01067 return true;
01068 }
01069 }
01070 else if(this->isFirstInside)
01071 {
01072 this->isFirstInside = false;
01073 SendMessage( hwndScol, FLASHCONTROL_OUTSIDE_EVENT, (int)this,NULL);
01074 }
01075 return false;
01076 }
01077
01078 void FlashControl::invalidateTotally()
01079 {
01080 isClean = false;
01081 isTotallyDirty = true;
01082 dirtyBounds.left = 0;
01083 dirtyBounds.top = 0;
01084 dirtyBounds.right = width;
01085 dirtyBounds.bottom = height;
01086 }
01087
01088 void FlashControl::handleKeyEvent(UINT msg, WPARAM wParam, LPARAM lParam)
01089 {
01090 LRESULT aResult;
01091 windowlessObject->OnWindowMessage(msg, wParam, lParam, &aResult);
01092 }
01093
01094 void FlashControl::handleFlashCall(const std::wstring& xmlString)
01095 {
01096 std::wstring funcName;
01097 string invokeName;
01098 Hikari::Arguments args;
01099 Ogre::StringVector argstr;
01100 if(!Hikari::Impl::deserializeInvocation(xmlString, funcName, args))
01101 return;
01102 DelegateIter i = delegateMap.find(funcName);
01103 if(i != delegateMap.end())
01104 {
01105 Hikari::FlashValue retval = i->second(this, args);
01106 flashInterface->SetReturnValue(Hikari::Impl::serializeValue(retval).c_str());
01107 }
01108 invokeName.resize(funcName.size());
01109 wcstombs(&invokeName[0], &funcName[0], funcName.size());
01110 MFLASH* mFlashResult = new MFLASH();
01111 mFlashResult->invoke = invokeName.c_str();
01112 mFlashResult->flArgs = args;
01113 SendMessage( hwndScol, FLASHCONTROL_CONTACTCB_TIME, (int)this,(LPARAM)mFlashResult);
01114 }
01115
01116 void FlashControl::update()
01117 {
01118 if(isClean)
01119 return;
01120
01121 if(overlay)
01122 if(!overlay->isVisible)
01123 return;
01124
01125 int dirtyWidth = dirtyBounds.right - dirtyBounds.left;
01126 int dirtyHeight = dirtyBounds.bottom - dirtyBounds.top;
01127 int dirtyBufSize = dirtyWidth * dirtyHeight * 4;
01128
01129 IViewObject* curView = 0;
01130 flashInterface->QueryInterface(IID_IViewObject, (void**)&curView);
01131
01132 if(!oleObject || !curView)
01133 return;
01134
01135 if(!mainContext || dirtyWidth != lastDirtyWidth || dirtyHeight != lastDirtyHeight)
01136 {
01137 if(mainContext)
01138 {
01139 DeleteDC(mainContext);
01140 mainContext = 0;
01141 }
01142 if(mainBitmap)
01143 {
01144 DeleteObject(mainBitmap);
01145 mainBitmap = 0;
01146 }
01147
01148 lastDirtyWidth = dirtyWidth;
01149 lastDirtyHeight = dirtyHeight;
01150
01151 HDC hdc = GetDC(NULL);
01152 BITMAPINFOHEADER bih = {0};
01153 bih.biSize = sizeof(BITMAPINFOHEADER);
01154 bih.biBitCount = 32;
01155 bih.biCompression = BI_RGB;
01156 bih.biPlanes = 1;
01157 bih.biWidth = dirtyWidth;
01158 bih.biHeight = -dirtyHeight;
01159 mainContext = CreateCompatibleDC(hdc);
01160 mainBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&mainBuffer, 0, 0);
01161 SelectObject(mainContext, mainBitmap);
01162
01163 if(usingAlphaHack)
01164 {
01165 if(altContext)
01166 {
01167 DeleteDC(altContext);
01168 altContext = 0;
01169 }
01170 if(altBitmap)
01171 {
01172 DeleteObject(altBitmap);
01173 altBitmap = 0;
01174 }
01175
01176 altContext = CreateCompatibleDC(hdc);
01177 altBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&altBuffer, 0, 0);
01178 SelectObject(altContext, altBitmap);
01179 }
01180
01181 ReleaseDC(0, hdc);
01182 }
01183
01184 RECT local;
01185 local.left = -dirtyBounds.left;
01186 local.top = -dirtyBounds.top;
01187 local.right = local.left + dirtyBounds.right;
01188 local.bottom = local.top + dirtyBounds.bottom;
01189
01190 if(!usingAlphaHack)
01191 {
01192
01193 memset(mainBuffer, 0, dirtyBufSize);
01194
01195 HRESULT hr = OleDraw(curView, DVASPECT_TRANSPARENT, mainContext, &local);
01196 }
01197 else
01198 {
01199 memset(mainBuffer, 0, dirtyBufSize);
01200 memset(altBuffer, 255, dirtyBufSize);
01201
01202 OleDraw(curView, DVASPECT_TRANSPARENT, mainContext, &local);
01203 OleDraw(curView, DVASPECT_TRANSPARENT, altContext, &local);
01204
01205
01206
01207
01208 BYTE *blackBuffer, *whiteBuffer;
01209 blackBuffer = mainBuffer;
01210 whiteBuffer = altBuffer;
01211 BYTE blackRed, whiteRed;
01212 int size = dirtyWidth * dirtyHeight;
01213 for(int i = 0; i < size; i++)
01214 {
01215 blackRed = *blackBuffer;
01216 whiteRed = *whiteBuffer;
01217 blackBuffer += 3;
01218 whiteBuffer += 4;
01219 *blackBuffer++ = 255 - (whiteRed - blackRed);
01220 }
01221 }
01222
01223 renderBuffer->copyArea(dirtyBounds, mainBuffer, dirtyWidth * 4);
01224
01225 HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
01226 pixelBuffer->lock(HardwareBuffer::HBL_DISCARD);
01227 const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
01228
01229 uint8* destBuffer = static_cast<uint8*>(pixelBox.data);
01230
01231 renderBuffer->blitBGR(destBuffer, (int)texPitch, (int)texDepth);
01232
01233 pixelBuffer->unlock();
01234
01235 isClean = true;
01236 isTotallyDirty = false;
01237 }
01238
01239 void FlashControl::loadResource(Ogre::Resource* resource)
01240 {
01241 Texture *tex = static_cast<Texture*>(resource);
01242
01243 tex->setTextureType(TEX_TYPE_2D);
01244 tex->setWidth(texWidth);
01245 tex->setHeight(texHeight);
01246 tex->setNumMipmaps(0);
01247 tex->setFormat(isTransparent? PF_BYTE_BGRA : PF_BYTE_BGR);
01248 tex->setUsage(TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
01249 tex->createInternalResources();
01250
01251 invalidateTotally();
01252 }
01253
01254 bool FlashControl::isLoaded()
01255 {
01256 return movieLoaded;
01257 }