DinkSmallwoodHD/source/Component/DragControlComponent.cpp
seth d4f66a5d2e Initial commit of Dink Smallwood HD source. See the "Programmer readme.txt" for information on how to set it up.
git-svn-id: svn://rtsoft.com/rtsvn/projects/RTDink@1469 353e56fe-9613-0410-8469-b96ad8e6f29c
2017-09-12 04:57:47 +00:00

332 lines
No EOL
8.2 KiB
C++

#include "PlatformPrecomp.h"
#include "DragControlComponent.h"
#include "util/GLESUtils.h"
#include "Entity/EntityUtils.h"
#include "BaseApp.h"
#include "Entity/ArcadeInputComponent.h"
#include "GUI/GameMenu.h"
DragControlComponent::DragControlComponent()
{
SetName("DragControl");
SAMPLE_COUNT = 8; //unused
LENGTH_REQUIRED_FOR_MOVE = 16;
if (IsIphoneSize || IsIphone4Size) LENGTH_REQUIRED_FOR_MOVE = 32; //the screen is tiny, need a few more pixels
if (IsIphone4Size)
{
LENGTH_REQUIRED_FOR_MOVE *= 2;
}
}
DragControlComponent::~DragControlComponent()
{
}
void DragControlComponent::OnAdd(Entity *pEnt)
{
EntityComponent::OnAdd(pEnt);
m_pPos2d = &GetParent()->GetVar("pos2d")->GetVector2();
m_pSize2d = &GetParent()->GetVar("size2d")->GetVector2();
if (IsIPAD())
{
*m_pPos2d =(CL_Vec2f(0,29));
} else
{
*m_pPos2d = (iPhoneMap(0,29));
}
//fit the active area to match the active dink screen layout
if (g_dglo.GetActiveView() != DinkGlobals::VIEW_ZOOMED && IsDrawingDinkStatusBar())
{
if (IsIPAD())
{
*m_pSize2d = CL_Vec2f(865, 584);
} else
{
*m_pSize2d = iPhoneMap(380, 237);
}
} else
{
if (IsIPAD())
{
*m_pSize2d = CL_Vec2f(866, 715);
} else
{
*m_pSize2d = iPhoneMap(380, 286);
}
}
if (GetApp()->GetIconsOnLeft())
{
m_pPos2d->x += GetScreenSizeXf()-m_pSize2d->x;
}
m_lastTouch = CL_Vec2f(0,0);
/*
m_pScale = &GetParent()->GetShared()->GetVarWithDefault("scale", Variant(1.0f))->GetFloat();
m_pRotation = &GetParent()->GetVar("rotation")->GetFloat(); //in degrees
m_pColor = &GetParent()->GetShared()->GetVarWithDefault("color", Variant(MAKE_RGBA(255,255,255,255)))->GetUINT32();
m_pColorMod = &GetParent()->GetShared()->GetVarWithDefault("colorMod", Variant(MAKE_RGBA(255,255,255,255)))->GetUINT32();
m_pAlpha = &GetParent()->GetShared()->GetVarWithDefault("alpha", Variant(1.0f))->GetFloat();
m_pAlignment = &GetParent()->GetVar("alignment")->GetUINT32();
*/
//register ourselves to render if the parent does
//GetParent()->GetFunction("OnRender")->sig_function.connect(1, boost::bind(&DragControlComponent::OnRender, this, _1));
GetParent()->GetFunction("OnUpdate")->sig_function.connect(1, boost::bind(&DragControlComponent::OnUpdate, this, _1));
GetBaseApp()->m_sig_arcade_input.connect(1, boost::bind(&DragControlComponent::OnArcadeInput, this, _1));
GetParent()->GetVar("ignoreTouchesOutsideRect")->Set(uint32(1));
EntityComponent *pTouch = GetParent()->AddComponent(new TouchHandlerComponent);
//movement arrows
//for speed, we've disabled movement message handling in App.cpp, but we actually want them just here, so we'll hardwire it
AddInputMovementFocusIfNeeded(GetParent());
GetParent()->GetFunction("OnOverStart")->sig_function.connect(1, boost::bind(&DragControlComponent::OnOverStart, this, _1));
GetParent()->GetFunction("OnOverEnd")->sig_function.connect(1, boost::bind(&DragControlComponent::OnOverEnd, this, _1));
GetParent()->GetFunction("OnOverMove")->sig_function.connect(1, boost::bind(&DragControlComponent::OnOverMove, this, _1));
GetParent()->GetParent()->GetFunction("OnKillingControls")->sig_function.connect(1, boost::bind(&DragControlComponent::OnKillingControls, this, _1));
/*
EntityComponent *pFilter = m_pArrowEnt->AddComponent(new FilterInputComponent);
pFilter->GetVar("mode")->Set(uint32(FilterInputComponent::MODE_CLIP_INPUT_TO_ABSOLUTE_CLIP_RECT_AND_DISABLE_INPUT_CHILDREN));
pFilter->GetVar("clipRect")->Set(CL_Rectf(0,43,397, GetScreenSizeY()));
m_timeOfLastTouch = GetTick(TIMER_SYSTEM);
SetAlignmentEntity(m_pArrowEnt, ALIGNMENT_CENTER);
m_pArrowEnt->GetVar("pos2d")->Set(CL_Vec2f(80, 240));
m_vArrowImageSizeOver2 = m_pArrowEnt->GetVar("size2d")->GetVector2()/2;
*/
VariantList vTemp;
OnOverEnd(&vTemp);
}
void DragControlComponent::OnRemove()
{
EntityComponent::OnRemove();
}
void DragControlComponent::SendKey(eDinkInput key, bool bIsDown)
{
if (bIsDown)
{
g_dglo.m_dirInput[key] = true;
g_dglo.m_dirInputFinished[key] = false; //make sure it wasn't scheduled to stop pressing
} else
{
g_dglo.m_dirInputFinished[key] = true;
}
}
void DragControlComponent::OnKillingControls(VariantList *pVList)
{
RemoveFocusIfNeeded(GetParent());
}
void DragControlComponent::AddSample(DragUnit v)
{
if (DinkIsDoingScreenTransition()) return;
m_samples.push_back(v);
/*
if (m_samples.size() > SAMPLE_COUNT)
{
m_samples.pop_front();
}
*/
}
void DragControlComponent::OnOverStart(VariantList *pVList)
{
m_samples.clear();
m_lastTouch = pVList->Get(0).GetVector2();
}
void DragControlComponent::OnOverEnd(VariantList *pVList)
{
// CL_Vec2f vPos = pVList->Get(0).GetVector2();
// LogMsg("Got over end: %s", PrintVector2(vPos).c_str());
m_samples.clear();
m_lastTouch = CL_Vec2f(0,0);
ClearKeyInput();
}
void DragControlComponent::OnOverMove(VariantList *pVList)
{
AddSample( DragUnit(pVList->Get(0).GetVector2() - m_lastTouch, GetTick(TIMER_GAME)));
//SetPosition(pVList->Get(0).GetVector2());
m_lastTouch = pVList->Get(0).GetVector2();
}
void DragControlComponent::ClearKeyInput()
{
SendKey(DINK_INPUT_UP, false);
SendKey(DINK_INPUT_DOWN, false);
SendKey(DINK_INPUT_LEFT, false);
SendKey(DINK_INPUT_RIGHT, false);
}
void DragControlComponent::OnRender(VariantList *pVList)
{
CL_Vec2f vFinalPos = pVList->m_variant[0].GetVector2()+*m_pPos2d;
}
void DragControlComponent::ProcessLastJoystickReading()
{
if (m_samples.size() == 0) return;
//first, lets figure out what direction we want
CL_Vec2f vDir = CL_Vec2f(0,0);
std::deque< DragUnit> sampleTemp;
for (int i=m_samples.size()-1; i >= 0;)
{
//if (m_samples.size() < SAMPLE_COUNT) break;
/*
if (1)
//if (m_samples.at(i).m_timeMade+100 < GetTick(TIMER_GAME))
{
vDir = CL_Vec2f(0,0);
//would removing this stop us from moving?
for (int h=1; h < m_samples.size();h++)
{
vDir += m_samples[h].m_vPos;
}
if (vDir.length() < LENGTH_REQUIRED_FOR_MOVE)
{
//yes it would. Just let it be, for now.
//break;
} else
{
//it's not needed
}
m_samples.erase(m_samples.begin()+i);
continue;
} else
{
break;
}
*/
vDir += m_samples[i].m_vPos;
sampleTemp.push_front( m_samples[i]);
if (vDir.length() >= LENGTH_REQUIRED_FOR_MOVE)
{
//all done
break;
}
i--;
}
m_samples = sampleTemp;
//vDir = CL_Vec2f(0,0);
/*
for (unsigned int i=0; i < m_samples.size();i++)
{
vDir += m_samples[i].m_vPos;
}
*/
ClearKeyInput();
//LogMsg("vDir length is %.2f", vDir.length());
if (vDir.length() < LENGTH_REQUIRED_FOR_MOVE) return;
vDir.normalize();
//recalculate the points
sampleTemp.clear();
//sampleTemp.push_front(m_samples[m_samples.size()-1]);
sampleTemp.push_front(DragUnit( (vDir*LENGTH_REQUIRED_FOR_MOVE)*1.1, 0));
m_samples = sampleTemp;
#ifdef _DEBUG
//LogMsg("Dir is %s (%d samples)", PrintVector2(vDir).c_str(), m_samples.size());
#endif
//convert to 360 degrees
int dir = (int(RAD2DEG(atan2(vDir.y, vDir.x))+(90)));
const int maxDirections = 8;
int finaldir = mod(dir+ (360/ (maxDirections*2)), 360)/ (360/maxDirections);
//nah, let's do 8 actually
//LogMsg("Pressing %s, which is dir %d (final: %d)", PrintVector2(m_lastTouchDir).c_str(), dir, finaldir);
switch (finaldir)
{
case 0: SendKey(DINK_INPUT_UP, true); break;
case 1: SendKey(DINK_INPUT_RIGHT, true); SendKey(DINK_INPUT_UP, true); break;
case 2: SendKey(DINK_INPUT_RIGHT, true); break;
case 3: SendKey(DINK_INPUT_RIGHT, true); SendKey(DINK_INPUT_DOWN, true); break;
case 4: SendKey(DINK_INPUT_DOWN, true); break;
case 5: SendKey(DINK_INPUT_DOWN, true); SendKey(DINK_INPUT_LEFT, true); break;
case 6: SendKey(DINK_INPUT_LEFT, true); break;
case 7: SendKey(DINK_INPUT_LEFT, true); SendKey(DINK_INPUT_UP, true); break;
}
}
void DragControlComponent::OnArcadeInput(VariantList *pVList)
{
int vKey = pVList->Get(0).GetUINT32();
bool bIsDown = pVList->Get(1).GetUINT32() != 0;
//LogMsg("Key %d, down is %d", vKey, int(bIsDown));
switch (vKey)
{
case VIRTUAL_KEY_DIR_LEFT:
SendKey(DINK_INPUT_LEFT, bIsDown);
break;
case VIRTUAL_KEY_DIR_RIGHT:
SendKey(DINK_INPUT_RIGHT, bIsDown);
break;
case VIRTUAL_KEY_DIR_UP:
SendKey(DINK_INPUT_UP, bIsDown);
break;
case VIRTUAL_KEY_DIR_DOWN:
SendKey(DINK_INPUT_DOWN, bIsDown);
break;
}
}
void DragControlComponent::OnUpdate(VariantList *pVList)
{
ProcessLastJoystickReading();
}