///////////////////////////////////////////////////// ///////////////////////////////////////////////////// // // MouseCursor // ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// #include "CKAll.h" CKObjectDeclaration *FillBehaviorMouseCursorDecl(); CKERROR CreateMouseCursorProto(CKBehaviorPrototype **); int MouseCursor(const CKBehaviorContext& behcontext); CKERROR MouseCursorCallbackDisp(const CKBehaviorContext& behcontext); void MouseCursorRender(CKRenderContext* dev, void *arg); CKObjectDeclaration *FillBehaviorMouseCursorDecl() { CKObjectDeclaration *od = CreateCKObjectDeclaration("Mouse Cursor"); od->SetDescription("Display a texture instead of the standard cursor."); /* rem: On: activates it.
Off: disables it.

Cursor Texture: texture to use to represent the mouse cursor.
Cursor Size: size in screen coordinates of the mouse cursor.
Cursor Color: color and transparency of the cursor.
Shadow: either to draw a shadow under the cursor.
Shadow Distance: distance of the shadow in screen coordinates.
Shadow Angle: angle of projection of the shadow.
Shadow Intensity: intensity of the shadow.
*/ od->SetType( CKDLL_BEHAVIORPROTOTYPE); od->SetGuid(CKGUID(0x140c3eac,0x6e502a81)); od->SetAuthorGuid(VIRTOOLS_GUID); od->SetAuthorName("Virtools"); od->SetVersion(0x00010000); od->SetCreationFunction(CreateMouseCursorProto); od->SetCompatibleClassId(CKCID_BEOBJECT); od->SetCategory("Interface/Screen"); return od; } CKERROR CreateMouseCursorProto(CKBehaviorPrototype **pproto) { CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Mouse Cursor"); if(!proto) return CKERR_OUTOFMEMORY; proto->DeclareInput("On"); proto->DeclareInput("Off"); proto->DeclareInParameter("Cursor Texture", CKPGUID_TEXTURE ); proto->DeclareInParameter("Cursor Size", CKPGUID_2DVECTOR,"32,32"); proto->DeclareInParameter("Cursor Color", CKPGUID_COLOR,"255,255,255,255"); proto->DeclareInParameter("Shadow", CKPGUID_BOOL); proto->DeclareInParameter("Shadow Distance", CKPGUID_FLOAT,"4.0"); proto->DeclareInParameter("Shadow Angle", CKPGUID_ANGLE,"0:120"); proto->DeclareInParameter("Shadow Intensity", CKPGUID_PERCENTAGE,"30"); // TODO : center - left - right // TODO : center - top - bottom // TODO : offset // TODO : setting = screen relative proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL); proto->SetFunction(MouseCursor); proto->SetBehaviorCallbackFct( MouseCursorCallbackDisp ); *pproto = proto; return CK_OK; } int MouseCursor(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; if( beh->IsInputActive(1) ){ // we enter by 'OFF' beh->ActivateInput(1, FALSE); beh->ActivateOutput(1); CKInputManager* im = (CKInputManager*) behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID); if(im){ im->ShowCursor(TRUE); } return CKBR_OK; } if( beh->IsInputActive(0) ){ // we enter by 'ON' beh->ActivateInput(0, FALSE); beh->ActivateOutput(0); CKInputManager* im = (CKInputManager*) behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID); if(im) im->ShowCursor(FALSE); } behcontext.CurrentRenderContext->AddPostSpriteRenderCallBack(MouseCursorRender,(void *)behcontext.Behavior->GetID(),TRUE); return CKBR_ACTIVATENEXTFRAME; } /*******************************************************/ /******************** INIT CALLBACK ********************/ CKERROR MouseCursorCallbackDisp(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; switch(behcontext.CallbackMessage) { case CKM_BEHAVIORPAUSE: case CKM_BEHAVIORDEACTIVATESCRIPT: { CKInputManager* im = (CKInputManager*) behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID); if(im) im->ShowCursor(TRUE); } break; case CKM_BEHAVIORNEWSCENE: case CKM_BEHAVIORRESUME: case CKM_BEHAVIORACTIVATESCRIPT: { // TODO : foire dans le load !!!!!!!!! if( beh->IsParentScriptActiveInScene(behcontext.CurrentScene)){ if(beh->IsActive()) { CKInputManager* im = (CKInputManager*) behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID); if(im) im->ShowCursor(FALSE); } } } break; } return CKBR_OK; } void MouseCursorRender(CKRenderContext* dev, void *arg) { CKBehavior* beh = (CKBehavior*)CKGetObject(dev->GetCKContext(),(CK_ID)arg); if (!beh) return; CKContext* ctx = beh->GetCKContext(); CKTexture* cursortex = (CKTexture*)beh->GetInputParameterObject(0); // extend the clipping VxRect oldclip; dev->GetViewRect(oldclip); VxRect clip = oldclip; dev->GetWindowRect(clip); clip.Translate(-clip.GetTopLeft()); dev->SetViewRect(clip); // SET STATES // we don't let write to the ZBuffer dev->SetTexture(cursortex); dev->SetTextureStageState(CKRST_TSS_TEXTUREMAPBLEND, VXTEXTUREBLEND_MODULATEALPHA); dev->SetState(VXRENDERSTATE_CULLMODE, VXCULL_NONE); dev->SetState(VXRENDERSTATE_SRCBLEND, VXBLEND_SRCALPHA); dev->SetState(VXRENDERSTATE_DESTBLEND, VXBLEND_INVSRCALPHA); dev->SetState(VXRENDERSTATE_ALPHABLENDENABLE, TRUE); dev->SetState(VXRENDERSTATE_ZENABLE , FALSE); dev->SetState(VXRENDERSTATE_ZWRITEENABLE , FALSE); dev->SetTextureStageState(CKRST_TSS_TEXTUREMAPBLEND,VXTEXTUREBLEND_MODULATEALPHA); dev->SetTextureStageState(CKRST_TSS_MAGFILTER , VXTEXTUREFILTER_NEAREST); dev->SetTextureStageState(CKRST_TSS_MINFILTER , VXTEXTUREFILTER_NEAREST); dev->SetState(VXRENDERSTATE_WRAP0 , 0); dev->SetTextureStageState(CKRST_TSS_STAGEBLEND,0,1); dev->SetTextureStageState(CKRST_TSS_TEXTURETRANSFORMFLAGS, 0); dev->SetTextureStageState(CKRST_TSS_TEXCOORDINDEX, 0); //prevents anti-aliasing artifacts : dev->SetTextureStageState(CKRST_TSS_ADDRESSU, VXTEXTURE_ADDRESSCLAMP); dev->SetTextureStageState(CKRST_TSS_ADDRESSV, VXTEXTURE_ADDRESSCLAMP); WORD indices[4]={0,1,2,3}; float vertices[16] = {0.0f,0.0f,0.5f,1.0f,640.0f,0.0f,0.5f,1.0f,0.0f,480.0f,0.5f,1.0f,640.0f,480.0f,0.5f,1.0f}; DWORD colors[4]; float uv[8]={0,0, 1,0, 1,1, 0,1}; VxDrawPrimitiveDataSimple data; data.VertexCount = 4; data.Flags = CKRST_DP_STAGES0; data.Positions.Set(vertices,sizeof(VxVector4)); data.Colors.Set(colors,sizeof(DWORD)); data.TexCoord.Set(uv,sizeof(VxUV)); // we get the input parameters Vx2DVector cursorsize; beh->GetInputParameterValue(1,&cursorsize); VxColor cursorcolor; beh->GetInputParameterValue(2,&cursorcolor); ///////////////////////////// // Mouse position Vx2DVector mousePos; CKInputManager *input = (CKInputManager*)ctx->GetManagerByGuid(INPUT_MANAGER_GUID); input->GetMousePosition(mousePos,FALSE); VxRect rect; rect.left = mousePos.x; rect.top = mousePos.y; rect.right = rect.left + cursorsize.x; rect.bottom = rect.top + cursorsize.y; /////////////////////////////// // Shadow CKBOOL shadow = FALSE; beh->GetInputParameterValue(3,&shadow); if(shadow) { float shadowdistance = 4.0f; beh->GetInputParameterValue(4,&shadowdistance); float shadowangle= 1.0f; beh->GetInputParameterValue(5,&shadowangle); float shadowintensity = 0.8f; beh->GetInputParameterValue(6,&shadowintensity); float offsetx = 4.0f; float offsety = 4.0f; offsetx = -shadowdistance*cosf(shadowangle); offsety = shadowdistance*sinf(shadowangle); data.Positions[0].Set(rect.left+offsetx , rect.top+offsety , 0.5f); data.Positions[1].Set(rect.right+offsetx , rect.top+offsety , 0.5f); data.Positions[2].Set(rect.right+offsetx , rect.bottom+offsety , 0.5f); data.Positions[3].Set(rect.left+offsetx , rect.bottom+offsety , 0.5f); for(int i=0;i<4;i++) { colors[i] = RGBAFTOCOLOR(0.0f,0.0f,0.0f,shadowintensity); } dev->DrawPrimitive(VX_TRIANGLEFAN,indices,4,(VxDrawPrimitiveData*)&data); } //////////////// // Cursor data.Positions[0].Set(rect.left , rect.top , 0.5f); data.Positions[1].Set(rect.right , rect.top , 0.5f); data.Positions[2].Set(rect.right , rect.bottom , 0.5f); data.Positions[3].Set(rect.left , rect.bottom , 0.5f); DWORD col = RGBAFTOCOLOR(&cursorcolor); for(int i=0;i<4;i++) { colors[i] = col; } dev->DrawPrimitive(VX_TRIANGLEFAN,indices,4,(VxDrawPrimitiveData*)&data); // restore clipping dev->SetViewRect(oldclip); }