268 lines
8.2 KiB
C++
268 lines
8.2 KiB
C++
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// 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:
|
|
<SPAN CLASS=in>On: </SPAN>activates it.<BR>
|
|
<SPAN CLASS=in>Off: </SPAN>disables it.<BR>
|
|
<BR>
|
|
<SPAN CLASS=in>Cursor Texture: </SPAN>texture to use to represent the mouse cursor.<BR>
|
|
<SPAN CLASS=in>Cursor Size: </SPAN>size in screen coordinates of the mouse cursor.<BR>
|
|
<SPAN CLASS=in>Cursor Color: </SPAN>color and transparency of the cursor.<BR>
|
|
<SPAN CLASS=in>Shadow: </SPAN>either to draw a shadow under the cursor.<BR>
|
|
<SPAN CLASS=in>Shadow Distance: </SPAN>distance of the shadow in screen coordinates.<BR>
|
|
<SPAN CLASS=in>Shadow Angle: </SPAN>angle of projection of the shadow.<BR>
|
|
<SPAN CLASS=in>Shadow Intensity: </SPAN>intensity of the shadow.<BR>
|
|
*/
|
|
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);
|
|
}
|