text: // This file is part of Wintermute Engine
  // For conditions of distribution and use, see copyright notice in license.txt
  // http://dead-code.org/redir.php?target=wme
  
  
  #include "dcgf.h"
  #include "SXMath.h"
  
  //////////////////////////////////////////////////////////////////////
  // Construction/Destruction
  //////////////////////////////////////////////////////////////////////
  
  #define PI 3.141592653589793f
  
  
  IMPLEMENT_PERSISTENT(CSXMath, true);
  
  //////////////////////////////////////////////////////////////////////////
  CSXMath::CSXMath(CBGame* inGame):CBScriptable(inGame)
  {
  
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  CSXMath::~CSXMath()
  {
  
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  HRESULT CSXMath::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
  {
  	//////////////////////////////////////////////////////////////////////////
  	// Abs
  	//////////////////////////////////////////////////////////////////////////
  	if(strcmp(Name, "Abs")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(fabs(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Acos
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Acos")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(acos(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Asin
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Asin")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(asin(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Atan
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Atan")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(atan(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Atan2
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Atan2")==0){
  		Stack->CorrectParams(2);
  		double y = Stack->Pop()->GetFloat();
  		double x = Stack->Pop()->GetFloat();
  		Stack->PushFloat(atan2(y, x));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Ceil
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Ceil")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(ceil(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Cos
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Cos")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(cos(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Cosh
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Cosh")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(cosh(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Exp
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Exp")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(exp(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Floor
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Floor")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(floor(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Log
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Log")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(log(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Log10
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Log10")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(log10(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Pow
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Pow")==0){
  		Stack->CorrectParams(2);
  		double x = Stack->Pop()->GetFloat();
  		double y = Stack->Pop()->GetFloat();
  		
  		Stack->PushFloat(pow(x, y));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Sin
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Sin")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(sin(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Sinh
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Sinh")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(sinh(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Tan
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Tan")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(tan(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Tanh
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Tanh")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(tanh(DegreeToRadian(Stack->Pop()->GetFloat())));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// Sqrt
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "Sqrt")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(sqrt(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// DegToRad
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "DegToRad")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(DegreeToRadian(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// RadToDeg
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "RadToDeg")==0){
  		Stack->CorrectParams(1);
  		Stack->PushFloat(RadianToDegree(Stack->Pop()->GetFloat()));
  		return S_OK;
  	}
  
  	else return E_FAIL;
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  CScValue* CSXMath::ScGetProperty(char *Name)
  {
  	m_ScValue->SetNULL();
  
  	//////////////////////////////////////////////////////////////////////////
  	// Type
  	//////////////////////////////////////////////////////////////////////////
  	if(strcmp(Name, "Type")==0){
  		m_ScValue->SetString("math");
  		return m_ScValue;
  	}
  
  	//////////////////////////////////////////////////////////////////////////
  	// PI
  	//////////////////////////////////////////////////////////////////////////
  	else if(strcmp(Name, "PI")==0){
  		m_ScValue->SetFloat(PI);
  		return m_ScValue;
  	}
  	
  	else return m_ScValue;
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  double CSXMath::DegreeToRadian(double Value)
  {
  	return Value * (PI / 180.0f);
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  double CSXMath::RadianToDegree(double Value)
  {
  	return Value * (180.0f / PI);
  }
  
  
  //////////////////////////////////////////////////////////////////////////
  HRESULT CSXMath::Persist(CBPersistMgr* PersistMgr){
  
  	CBScriptable::Persist(PersistMgr);
  	return S_OK;
  }
  