<commit_before>#include "Condition.h"
#include "Instruction.h"

CCondition::CCondition(CGameState &_gameState, FCLInstructionVector _instructions, bool _isAnimator)
{
	gameState = &_gameState;
	instructions = _instructions;
	isAnimator = _isAnimator;
}

bool CCondition::statusOfConditional(FCLInstruction &conditional)	//CObject *obj,
{
	int32_t var1, var2;
	bool result = false;

	switch(conditional.getType())
	{
		default:
			std::cerr << "Unknown conditional" << &conditional;
		break;

		/*
			Collided, shot and activated all atomically test and reset object state bits;
			so they delegate determining the result to the object itself
		*/
//		case COLLIDEDQ:
//			Res = obj ? obj->GetCollided() : true;
//			if(obj) obj->SetCollided(false);
//		return Res;
//		case SHOTQ:
//			Res = obj ? obj->GetShot() : false;
//			if(obj) obj->SetShot(false);
//		return Res;
//		case ACTIVATEDQ:
//			Res = obj ? obj->GetActivated() : false;
//			obj->SetActivated(false);	// not sure about this
//		return Res;

		/*
			Visibility and, therefore, invisibility, depend on the scene's current state,
			and we want the scene graph to do the complicated maths anyway...
		*/
//		case VISQ:
//			Var2 = Parent->GetCurrentArea();
//			GetBinaryValues(Conditional, Var1, Var2);
//		return Parent->GetVis(Var1, Var2);
//		case INVISQ:
//			Var2 = Parent->GetCurrentArea();
//			GetBinaryValues(Conditional, Var1, Var2);
//		return !Parent->GetVis(Var1, Var2);

		/*
			Some easy ones — just compare one value to another
		*/
		case Token::VAREQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 == var2;

		case Token::VARNOTEQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 != var2;

		case Token::VARLQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 < var2;

		case Token::VARGQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 > var2;

		// bit not equal, which this code implements via the reserved word
		// bit!=?, is added to facilitate running of 8-bit games — syntax is
		// bit!=? (bit number, value), with the two things treated as Booleans
		case Token::BITNOTEQ:
			conditional.getValue(*gameState, var1, var2);
			bool B = gameState->getBit(var1);
		return B == (var2 ? true : false);

//		case TIMERQ:
//		return Parent->QueryTimerTicked();
//		case ADDVAR:
//			GetBinaryValues(Conditional, Var1, Var2);
//			Var2 += Var1;
//			if(Conditional->Data.BinaryOp.Dest.Type == VARIABLE)
//				Parent->SetVariable(Conditional->Data.BinaryOp.Dest.Data.Value, Var2);
//		return (Var2&Parent->GetVariableMask()) ? true : false;
//		case SUBVAR:
//			GetBinaryValues(Conditional, Var1, Var2);
//			Var2 -= Var1;
//			if(Conditional->Data.BinaryOp.Dest.Type == VARIABLE)
//				Parent->SetVariable(Conditional->Data.BinaryOp.Dest.Data.Value, Var2);
//		return (Var2&Parent->GetVariableMask()) ? true : false;
	}

	return result;
}

/*void CFreescapeGame::CCondition::SetLooping(bool c)
{
	Looping = c;
	if(!c && Active < 0) Active = 1;
}

const char *ConNames[] =
{
	"activated?", "addvar", "again", "and", "andv", "collided?", "delay", "destroy", "destroyed?", "else",
	"end", "endgame", "endif", "execute", "goto", "if", "invis", "invis?", "include", "loop", "mode",
	"move", "moveto", "notv", "or", "orv", "getxpos", "getypos", "getzpos", "print", "restart", "redraw",
	"remove", "sound", "setvar", "shot?", "start", "startanim", "stopanim", "subvar", "syncsnd", "then",
	"timer?", "togvis", "triganim", "updatei", "var=?", "var>?", "var<?", "vis?", "vis", "wait",
	"waittrig", ",", "(", ")", "constant", "variable", "literal", "???", "EOF", "setbit", "clrbit", "togbit",
	"swapjet", "bit!=?", "var!=?"
};

void CFreescapeGame::CCondition::ResetProg()
{
	if(Active > 0) Active--;
	if(!Active && Looping) Active = -1;
	ProgramStack[0] = Head;
	StackPtr = 0;
}

void CFreescapeGame::CCondition::Reset()
{
	Triggered = false;
	Active = (Animator || !Looping) ? 0 : -1;
	ResetProg();
	int c = MAX_OBJECTS_PER_AREA;
	while(c--)
		ObjFlags[c] = false;
}

void CFreescapeGame::CCondition::SetActive(bool s)	{ if(s && Active >= 0) Active++; if(!s) Active = 0;}
void CFreescapeGame::CCondition::Trigger()			{ Triggered = true; }

bool CFreescapeGame::CCondition::Execute(CObject *obj)
{
	Sint32 Var1, Var2, Var3, Mask;

	Mask = Parent->GetVariableMask();
	if(!Head || !Active) {return true;}
//	if(Animator) printf("anim %d\n", Active);

	// oh man!
	while(ProgramStack[StackPtr])
	{
		FCLInstruction *Instr = ProgramStack[StackPtr];
		ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;

		switch(Instr->Type)
		{
			default:
				printf("Unhandled FCLInstruction %s\n", ConNames[(int)Instr->Type]);
				ResetProg();
			return false;

			case IF:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = QueryCondition(obj, Conditional);
			}
			break;
			case AND:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = Status && QueryCondition(obj, Conditional);
			}
			break;
			case OR:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = Status || QueryCondition(obj, Conditional);
			}
			break;

			case THEN:
				if(Status && Instr->Data.Then.Passed)
				{
					// execute passed
					ProgramStack[StackPtr+1] = Instr->Data.Then.Passed;
					StackPtr++;
				}

				if(!Status && Instr->Data.Then.Failed)
				{
					// execute failed
					ProgramStack[StackPtr+1] = Instr->Data.Then.Failed;
					StackPtr++;
				}
			break;

			case ELSE:
			case ENDIF:
				if(StackPtr > 0)
					StackPtr--;
				else
					if(ProgramStack[StackPtr])
					{
						printf("too many ENDIFs\n");
						ResetProg();
						return false;
					}
			break;

			case EXECUTE:
				// execute someone else's script as though mine
				GetUnaryValue(Instr, Var1);
//				printf("execute %d\n", (int)Var1);
				CObject *NewObj = Parent->GetObject(Var1);
				ResetProg();
				if(NewObj)
				{
					CCondition *C = NewObj->GetCondition();
					if(C)
					{
						C->SetActive(true);
						return C->Execute(obj);
					}
					return true;
				}
				return false;
			break;
			case END:
				if(!Animator) ResetProg();
			return true;
			case WAIT:
			return true;

			case VIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, true);
			break;
			case INVIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, false);
			break;
			case DESTROY:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->Destroy(Var1, Var2);
			break;
			case GOTO:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->Goto(Var1, Var2);
			break;
			case TOGVIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, Parent->GetVis(Var1, Var2) ^ true);
			break;
			case STARTANIM:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetAnimatorActive(Var1, Var2, true);
//				printf("startanim %d, %d\n", (int)Var1, (int)Var2);
			break;
			case STOPANIM:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetAnimatorActive(Var1, Var2, false);
//				printf("stopanim %d, %d\n", (int)Var1, (int)Var2);
			break;
			case TRIGANIM:
				GetUnaryValue(Instr, Var1);
				Parent->TriggerAnimator(Var1);
//				printf("triganim %d\n",  (int)Var1);
			break;

			case CLEARBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, false);
			break;
			case SETBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, true);
			break;
			case TOGGLEBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, Parent->GetBit(Var1)^true);
			break;

			case SETVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var1);
			break;

			// addvar & subvar. Not sure if they really affect Status here
			case ADDVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Var2 += Var1;
				if(Instr->Data.BinaryOp.Dest.Type == VARIABLE)
					Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var2);
				Status = (Var2&Mask) ? true : false;
			break;
			case SUBVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Var2 -= Var1;
				if(Instr->Data.BinaryOp.Dest.Type == VARIABLE)
					Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var2);
				Status = (Var2&Mask) ? true : false;
			break;

			case WAITTRIG:
				if(Animator && !Triggered)
				{
					ProgramStack[StackPtr] = Instr;
					return true;
				}
				Triggered = false;
			break;

			//
			//	loops
			//
			case LOOP:
				GetUnaryValue(Instr, Var1);
				LoopPos = ProgramStack[StackPtr];
				LoopStackPtr = StackPtr;
				LoopCount = (int)Var1;
			break;
			case AGAIN:
				LoopCount--;
				if(LoopCount)	//seems to be the test, not > 0 as the documentation claims
				{
					StackPtr = LoopStackPtr;
					ProgramStack[StackPtr] = LoopPos;
				}
			return true;

			//
			//	Animator specific bits
			//
			case START:
				if(Animator)
				{
					StartPos = ProgramStack[StackPtr];
					StartStackPtr = StackPtr;
				}
			break;
			case RESTART:
				if(Animator)
				{
					StackPtr = StartStackPtr;
					ProgramStack[StackPtr] = StartPos;
					return true;	// I think?
				}
			break;
			case INCLUDE:
				if(Animator)
				{
					GetUnaryValue(Instr, Var1);
					ObjFlags[(int)Var1] = true;
				}
			break;
			case MOVETO:
				if(Animator)
				{
					GetTernaryValues(Instr, Var1, Var2, Var3);
					int c = 256;
					while(c--)
					{
						if(ObjFlags[c])
						{
							CObject *NewObj = Parent->GetObject(c);
							if(NewObj)
								NewObj->MoveTo(Var1, Var2, Var3);
						}
					}
				}
			return true;
			case MOVE:
				if(Animator)
				{
					GetTernaryValues(Instr, Var1, Var2, Var3);
					int c = 256;
					while(c--)
					{
						if(ObjFlags[c])
						{
							CObject *NewObj = Parent->GetObject(c);
							if(NewObj)
								NewObj->Move(Var1, Var2, Var3);
						}
					}
				}
			return true;

			case SOUND:
			case SYNCSND:
				GetUnaryValue(Instr, Var1);
				Parent->PlaySound(Var1-1); // should subtract 1?
//				printf("ignored sound\n");
			break;
			case UPDATEI:
//				printf("instrument update ignored\n");
			break;
			case REDRAW:	//always ignore redraw
			return true;
			case DELAY:		//always ignore delay - it's a bad solution
				GetUnaryValue(Instr, Var1);
				Parent->Delay(Var1);
			return true;
			case PRINT:		// ignore for now
				Parent->PrintMessage(Instr->Data.BinaryOp.Source.Data.String, 0);
//				printf("%s\n", Instr->Data.BinaryOp.Source.Data.String);
			break;
			case MODE:
				GetUnaryValue(Instr, Var1);
				Parent->SetMode(Var1);
			break;

			case ENDGAME:
				Parent->Reset();
			return true;
		}
	}

	// if we got to here then we reached the end of the program, so set things back to default for next time
	ResetProg();
	return true;
}*/
<commit_msg>Fixed an erroneous comment. Visibility is just a flag that lives on the object. It’s not line of sight.<commit_after>#include "Condition.h"
#include "Instruction.h"

CCondition::CCondition(CGameState &_gameState, FCLInstructionVector _instructions, bool _isAnimator)
{
	gameState = &_gameState;
	instructions = _instructions;
	isAnimator = _isAnimator;
}

bool CCondition::statusOfConditional(FCLInstruction &conditional)	//CObject *obj,
{
	int32_t var1, var2;
	bool result = false;

	switch(conditional.getType())
	{
		default:
			std::cerr << "Unknown conditional" << &conditional;
		break;

		/*
			Collided, shot and activated all atomically test and reset object state bits;
			so they delegate determining the result to the object itself
		*/
//		case COLLIDEDQ:
//			Res = obj ? obj->GetCollided() : true;
//			if(obj) obj->SetCollided(false);
//		return Res;
//		case SHOTQ:
//			Res = obj ? obj->GetShot() : false;
//			if(obj) obj->SetShot(false);
//		return Res;
//		case ACTIVATEDQ:
//			Res = obj ? obj->GetActivated() : false;
//			obj->SetActivated(false);	// not sure about this
//		return Res;

		/*
			Visibility and invisibility need working objects ...
		*/
//		case VISQ:
//			Var2 = Parent->GetCurrentArea();
//			GetBinaryValues(Conditional, Var1, Var2);
//		return Parent->GetVis(Var1, Var2);
//		case INVISQ:
//			Var2 = Parent->GetCurrentArea();
//			GetBinaryValues(Conditional, Var1, Var2);
//		return !Parent->GetVis(Var1, Var2);

		/*
			Some easy ones — just compare one value to another
		*/
		case Token::VAREQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 == var2;

		case Token::VARNOTEQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 != var2;

		case Token::VARLQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 < var2;

		case Token::VARGQ:
			conditional.getValue(*gameState, var1, var2);
		return var1 > var2;

		// bit not equal, which this code implements via the reserved word
		// bit!=?, is added to facilitate running of 8-bit games — syntax is
		// bit!=? (bit number, value), with the two things treated as Booleans
		case Token::BITNOTEQ:
			conditional.getValue(*gameState, var1, var2);
			bool B = gameState->getBit(var1);
		return B == (var2 ? true : false);

//		case TIMERQ:
//		return Parent->QueryTimerTicked();
//		case ADDVAR:
//			GetBinaryValues(Conditional, Var1, Var2);
//			Var2 += Var1;
//			if(Conditional->Data.BinaryOp.Dest.Type == VARIABLE)
//				Parent->SetVariable(Conditional->Data.BinaryOp.Dest.Data.Value, Var2);
//		return (Var2&Parent->GetVariableMask()) ? true : false;
//		case SUBVAR:
//			GetBinaryValues(Conditional, Var1, Var2);
//			Var2 -= Var1;
//			if(Conditional->Data.BinaryOp.Dest.Type == VARIABLE)
//				Parent->SetVariable(Conditional->Data.BinaryOp.Dest.Data.Value, Var2);
//		return (Var2&Parent->GetVariableMask()) ? true : false;
	}

	return result;
}

/*void CFreescapeGame::CCondition::SetLooping(bool c)
{
	Looping = c;
	if(!c && Active < 0) Active = 1;
}

const char *ConNames[] =
{
	"activated?", "addvar", "again", "and", "andv", "collided?", "delay", "destroy", "destroyed?", "else",
	"end", "endgame", "endif", "execute", "goto", "if", "invis", "invis?", "include", "loop", "mode",
	"move", "moveto", "notv", "or", "orv", "getxpos", "getypos", "getzpos", "print", "restart", "redraw",
	"remove", "sound", "setvar", "shot?", "start", "startanim", "stopanim", "subvar", "syncsnd", "then",
	"timer?", "togvis", "triganim", "updatei", "var=?", "var>?", "var<?", "vis?", "vis", "wait",
	"waittrig", ",", "(", ")", "constant", "variable", "literal", "???", "EOF", "setbit", "clrbit", "togbit",
	"swapjet", "bit!=?", "var!=?"
};

void CFreescapeGame::CCondition::ResetProg()
{
	if(Active > 0) Active--;
	if(!Active && Looping) Active = -1;
	ProgramStack[0] = Head;
	StackPtr = 0;
}

void CFreescapeGame::CCondition::Reset()
{
	Triggered = false;
	Active = (Animator || !Looping) ? 0 : -1;
	ResetProg();
	int c = MAX_OBJECTS_PER_AREA;
	while(c--)
		ObjFlags[c] = false;
}

void CFreescapeGame::CCondition::SetActive(bool s)	{ if(s && Active >= 0) Active++; if(!s) Active = 0;}
void CFreescapeGame::CCondition::Trigger()			{ Triggered = true; }

bool CFreescapeGame::CCondition::Execute(CObject *obj)
{
	Sint32 Var1, Var2, Var3, Mask;

	Mask = Parent->GetVariableMask();
	if(!Head || !Active) {return true;}
//	if(Animator) printf("anim %d\n", Active);

	// oh man!
	while(ProgramStack[StackPtr])
	{
		FCLInstruction *Instr = ProgramStack[StackPtr];
		ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;

		switch(Instr->Type)
		{
			default:
				printf("Unhandled FCLInstruction %s\n", ConNames[(int)Instr->Type]);
				ResetProg();
			return false;

			case IF:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = QueryCondition(obj, Conditional);
			}
			break;
			case AND:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = Status && QueryCondition(obj, Conditional);
			}
			break;
			case OR:
			{
				FCLInstruction *Conditional = ProgramStack[StackPtr];
				ProgramStack[StackPtr] = ProgramStack[StackPtr]->Next;
				Status = Status || QueryCondition(obj, Conditional);
			}
			break;

			case THEN:
				if(Status && Instr->Data.Then.Passed)
				{
					// execute passed
					ProgramStack[StackPtr+1] = Instr->Data.Then.Passed;
					StackPtr++;
				}

				if(!Status && Instr->Data.Then.Failed)
				{
					// execute failed
					ProgramStack[StackPtr+1] = Instr->Data.Then.Failed;
					StackPtr++;
				}
			break;

			case ELSE:
			case ENDIF:
				if(StackPtr > 0)
					StackPtr--;
				else
					if(ProgramStack[StackPtr])
					{
						printf("too many ENDIFs\n");
						ResetProg();
						return false;
					}
			break;

			case EXECUTE:
				// execute someone else's script as though mine
				GetUnaryValue(Instr, Var1);
//				printf("execute %d\n", (int)Var1);
				CObject *NewObj = Parent->GetObject(Var1);
				ResetProg();
				if(NewObj)
				{
					CCondition *C = NewObj->GetCondition();
					if(C)
					{
						C->SetActive(true);
						return C->Execute(obj);
					}
					return true;
				}
				return false;
			break;
			case END:
				if(!Animator) ResetProg();
			return true;
			case WAIT:
			return true;

			case VIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, true);
			break;
			case INVIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, false);
			break;
			case DESTROY:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->Destroy(Var1, Var2);
			break;
			case GOTO:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->Goto(Var1, Var2);
			break;
			case TOGVIS:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVis(Var1, Var2, Parent->GetVis(Var1, Var2) ^ true);
			break;
			case STARTANIM:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetAnimatorActive(Var1, Var2, true);
//				printf("startanim %d, %d\n", (int)Var1, (int)Var2);
			break;
			case STOPANIM:
				Var2 = Parent->GetCurrentArea();
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetAnimatorActive(Var1, Var2, false);
//				printf("stopanim %d, %d\n", (int)Var1, (int)Var2);
			break;
			case TRIGANIM:
				GetUnaryValue(Instr, Var1);
				Parent->TriggerAnimator(Var1);
//				printf("triganim %d\n",  (int)Var1);
			break;

			case CLEARBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, false);
			break;
			case SETBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, true);
			break;
			case TOGGLEBIT:
				GetUnaryValue(Instr, Var1);
				Parent->SetBit(Var1, Parent->GetBit(Var1)^true);
			break;

			case SETVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var1);
			break;

			// addvar & subvar. Not sure if they really affect Status here
			case ADDVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Var2 += Var1;
				if(Instr->Data.BinaryOp.Dest.Type == VARIABLE)
					Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var2);
				Status = (Var2&Mask) ? true : false;
			break;
			case SUBVAR:
				GetBinaryValues(Instr, Var1, Var2);
				Var2 -= Var1;
				if(Instr->Data.BinaryOp.Dest.Type == VARIABLE)
					Parent->SetVariable(Instr->Data.BinaryOp.Dest.Data.Value, Var2);
				Status = (Var2&Mask) ? true : false;
			break;

			case WAITTRIG:
				if(Animator && !Triggered)
				{
					ProgramStack[StackPtr] = Instr;
					return true;
				}
				Triggered = false;
			break;

			//
			//	loops
			//
			case LOOP:
				GetUnaryValue(Instr, Var1);
				LoopPos = ProgramStack[StackPtr];
				LoopStackPtr = StackPtr;
				LoopCount = (int)Var1;
			break;
			case AGAIN:
				LoopCount--;
				if(LoopCount)	//seems to be the test, not > 0 as the documentation claims
				{
					StackPtr = LoopStackPtr;
					ProgramStack[StackPtr] = LoopPos;
				}
			return true;

			//
			//	Animator specific bits
			//
			case START:
				if(Animator)
				{
					StartPos = ProgramStack[StackPtr];
					StartStackPtr = StackPtr;
				}
			break;
			case RESTART:
				if(Animator)
				{
					StackPtr = StartStackPtr;
					ProgramStack[StackPtr] = StartPos;
					return true;	// I think?
				}
			break;
			case INCLUDE:
				if(Animator)
				{
					GetUnaryValue(Instr, Var1);
					ObjFlags[(int)Var1] = true;
				}
			break;
			case MOVETO:
				if(Animator)
				{
					GetTernaryValues(Instr, Var1, Var2, Var3);
					int c = 256;
					while(c--)
					{
						if(ObjFlags[c])
						{
							CObject *NewObj = Parent->GetObject(c);
							if(NewObj)
								NewObj->MoveTo(Var1, Var2, Var3);
						}
					}
				}
			return true;
			case MOVE:
				if(Animator)
				{
					GetTernaryValues(Instr, Var1, Var2, Var3);
					int c = 256;
					while(c--)
					{
						if(ObjFlags[c])
						{
							CObject *NewObj = Parent->GetObject(c);
							if(NewObj)
								NewObj->Move(Var1, Var2, Var3);
						}
					}
				}
			return true;

			case SOUND:
			case SYNCSND:
				GetUnaryValue(Instr, Var1);
				Parent->PlaySound(Var1-1); // should subtract 1?
//				printf("ignored sound\n");
			break;
			case UPDATEI:
//				printf("instrument update ignored\n");
			break;
			case REDRAW:	//always ignore redraw
			return true;
			case DELAY:		//always ignore delay - it's a bad solution
				GetUnaryValue(Instr, Var1);
				Parent->Delay(Var1);
			return true;
			case PRINT:		// ignore for now
				Parent->PrintMessage(Instr->Data.BinaryOp.Source.Data.String, 0);
//				printf("%s\n", Instr->Data.BinaryOp.Source.Data.String);
			break;
			case MODE:
				GetUnaryValue(Instr, Var1);
				Parent->SetMode(Var1);
			break;

			case ENDGAME:
				Parent->Reset();
			return true;
		}
	}

	// if we got to here then we reached the end of the program, so set things back to default for next time
	ResetProg();
	return true;
}*/
<|endoftext|>


<commit_before>#include "moses/FF/Factory.h"
#include "moses/StaticData.h"

#include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryOnDisk.h"
#include "moses/TranslationModel/PhraseDictionaryMemory.h"
#include "moses/TranslationModel/CompactPT/PhraseDictionaryCompact.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModel.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModelCounts.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryALSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryDynSuffixArray.h"

#include "moses/FF/LexicalReordering/LexicalReordering.h"

#include "moses/FF/BleuScoreFeature.h"
#include "moses/FF/TargetWordInsertionFeature.h"
#include "moses/FF/SourceWordDeletionFeature.h"
#include "moses/FF/GlobalLexicalModel.h"
#include "moses/FF/GlobalLexicalModelUnlimited.h"
#include "moses/FF/UnknownWordPenaltyProducer.h"
#include "moses/FF/WordTranslationFeature.h"
#include "moses/FF/TargetBigramFeature.h"
#include "moses/FF/TargetNgramFeature.h"
#include "moses/FF/PhraseBoundaryFeature.h"
#include "moses/FF/PhrasePairFeature.h"
#include "moses/FF/PhraseLengthFeature.h"
#include "moses/FF/DistortionScoreProducer.h"
#include "moses/FF/WordPenaltyProducer.h"
#include "moses/FF/InputFeature.h"
#include "moses/FF/PhrasePenalty.h"
#include "moses/FF/OSM-Feature/OpSequenceModel.h"
#include "moses/FF/ControlRecombination.h"
#include "moses/FF/ExternalFeature.h"
#include "moses/FF/ConstrainedDecoding.h"

#include "moses/FF/SkeletonStatelessFF.h"
#include "moses/FF/SkeletonStatefulFF.h"

#include "moses/LM/Ken.h"
#ifdef LM_IRST
#include "moses/LM/IRST.h"
#endif

#ifdef LM_SRI
#include "moses/LM/SRI.h"
#endif

#ifdef LM_RAND
#include "moses/LM/Rand.h"
#endif

#ifdef HAVE_SYNLM
#include "moses/SyntacticLanguageModel.h"
#endif

#include "util/exception.hh"

#include <vector>

namespace Moses
{

class FeatureFactory
{
public:
  virtual ~FeatureFactory() {}

  virtual void Create(const std::string &line) = 0;

protected:
  template <class F> static void DefaultSetup(F *feature);

  FeatureFactory() {}
};

template <class F> void FeatureFactory::DefaultSetup(F *feature)
{
  StaticData &static_data = StaticData::InstanceNonConst();
  std::vector<float> &weights = static_data.GetParameter()->GetWeights(feature->GetScoreProducerDescription());

  if (feature->IsTuneable() || weights.size()) {
    // if it's tuneable, ini file MUST have weights
    // even it it's not tuneable, people can still set the weights in the ini file
    static_data.SetWeights(feature, weights);
  } else {
    std::vector<float> defaultWeights = feature->DefaultWeights();
    static_data.SetWeights(feature, defaultWeights);
  }
}

namespace
{

template <class F> class DefaultFeatureFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(new F(line));
  }
};

class KenFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(ConstructKenLM(line));
  }
};

} // namespace

FeatureRegistry::FeatureRegistry()
{
// Feature with same name as class
#define MOSES_FNAME(name) Add(#name, new DefaultFeatureFactory< name >());
// Feature with different name than class.
#define MOSES_FNAME2(name, type) Add(name, new DefaultFeatureFactory< type >());
  MOSES_FNAME(GlobalLexicalModel);
  //MOSES_FNAME(GlobalLexicalModelUnlimited); This was commented out in the original
  MOSES_FNAME(SourceWordDeletionFeature);
  MOSES_FNAME(TargetWordInsertionFeature);
  MOSES_FNAME(PhraseBoundaryFeature);
  MOSES_FNAME(PhraseLengthFeature);
  MOSES_FNAME(WordTranslationFeature);
  MOSES_FNAME(TargetBigramFeature);
  MOSES_FNAME(TargetNgramFeature);
  MOSES_FNAME(PhrasePairFeature);
  MOSES_FNAME(LexicalReordering);
  MOSES_FNAME2("Generation", GenerationDictionary);
  MOSES_FNAME(BleuScoreFeature);
  MOSES_FNAME2("Distortion", DistortionScoreProducer);
  MOSES_FNAME2("WordPenalty", WordPenaltyProducer);
  MOSES_FNAME(InputFeature);
  MOSES_FNAME2("PhraseDictionaryBinary", PhraseDictionaryTreeAdaptor);
  MOSES_FNAME(PhraseDictionaryOnDisk);
  MOSES_FNAME(PhraseDictionaryMemory);
  MOSES_FNAME(PhraseDictionaryCompact);
  MOSES_FNAME(PhraseDictionaryMultiModel);
  MOSES_FNAME(PhraseDictionaryMultiModelCounts);
  MOSES_FNAME(PhraseDictionaryALSuffixArray);
  MOSES_FNAME(PhraseDictionaryDynSuffixArray);
  MOSES_FNAME(OpSequenceModel);
  MOSES_FNAME(PhrasePenalty);
  MOSES_FNAME2("UnknownWordPenalty", UnknownWordPenaltyProducer);
  MOSES_FNAME(ControlRecombination);
  MOSES_FNAME(ConstrainedDecoding);
  MOSES_FNAME(ExternalFeature);

  MOSES_FNAME(SkeletonStatelessFF);
  MOSES_FNAME(SkeletonStatefulFF);

#ifdef HAVE_SYNLM
  MOSES_FNAME(SyntacticLanguageModel);
#endif
#ifdef LM_IRST
  MOSES_FNAME2("IRSTLM", LanguageModelIRST);
#endif
#ifdef LM_SRI
  MOSES_FNAME2("SRILM", LanguageModelSRI);
#endif
#ifdef LM_RAND
  MOSES_FNAME2("RANDLM", LanguageModelRandLM);
#endif
  Add("KENLM", new KenFactory());
}

FeatureRegistry::~FeatureRegistry() {}

void FeatureRegistry::Add(const std::string &name, FeatureFactory *factory)
{
  std::pair<std::string, boost::shared_ptr<FeatureFactory> > to_ins(name, boost::shared_ptr<FeatureFactory>(factory));
  UTIL_THROW_IF(!registry_.insert(to_ins).second, util::Exception, "Duplicate feature name " << name);
}

namespace
{
class UnknownFeatureException : public util::Exception {};
}

void FeatureRegistry::Construct(const std::string &name, const std::string &line)
{
  Map::iterator i = registry_.find(name);
  UTIL_THROW_IF(i == registry_.end(), UnknownFeatureException, "Feature name " << name << " is not registered.");
  i->second->Create(line);
}

} // namespace Moses
<commit_msg>oops. forgot to check in new FF<commit_after>#include "moses/FF/Factory.h"
#include "moses/StaticData.h"

#include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryOnDisk.h"
#include "moses/TranslationModel/PhraseDictionaryMemory.h"
#include "moses/TranslationModel/CompactPT/PhraseDictionaryCompact.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModel.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModelCounts.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryALSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryDynSuffixArray.h"

#include "moses/FF/LexicalReordering/LexicalReordering.h"

#include "moses/FF/BleuScoreFeature.h"
#include "moses/FF/TargetWordInsertionFeature.h"
#include "moses/FF/SourceWordDeletionFeature.h"
#include "moses/FF/GlobalLexicalModel.h"
#include "moses/FF/GlobalLexicalModelUnlimited.h"
#include "moses/FF/UnknownWordPenaltyProducer.h"
#include "moses/FF/WordTranslationFeature.h"
#include "moses/FF/TargetBigramFeature.h"
#include "moses/FF/TargetNgramFeature.h"
#include "moses/FF/PhraseBoundaryFeature.h"
#include "moses/FF/PhrasePairFeature.h"
#include "moses/FF/PhraseLengthFeature.h"
#include "moses/FF/DistortionScoreProducer.h"
#include "moses/FF/WordPenaltyProducer.h"
#include "moses/FF/InputFeature.h"
#include "moses/FF/PhrasePenalty.h"
#include "moses/FF/OSM-Feature/OpSequenceModel.h"
#include "moses/FF/ControlRecombination.h"
#include "moses/FF/ExternalFeature.h"
//#include "moses/FF/ConstrainedDecoding.h"

#include "moses/FF/SkeletonStatelessFF.h"
#include "moses/FF/SkeletonStatefulFF.h"

#include "moses/LM/Ken.h"
#ifdef LM_IRST
#include "moses/LM/IRST.h"
#endif

#ifdef LM_SRI
#include "moses/LM/SRI.h"
#endif

#ifdef LM_RAND
#include "moses/LM/Rand.h"
#endif

#ifdef HAVE_SYNLM
#include "moses/SyntacticLanguageModel.h"
#endif

#include "util/exception.hh"

#include <vector>

namespace Moses
{

class FeatureFactory
{
public:
  virtual ~FeatureFactory() {}

  virtual void Create(const std::string &line) = 0;

protected:
  template <class F> static void DefaultSetup(F *feature);

  FeatureFactory() {}
};

template <class F> void FeatureFactory::DefaultSetup(F *feature)
{
  StaticData &static_data = StaticData::InstanceNonConst();
  std::vector<float> &weights = static_data.GetParameter()->GetWeights(feature->GetScoreProducerDescription());

  if (feature->IsTuneable() || weights.size()) {
    // if it's tuneable, ini file MUST have weights
    // even it it's not tuneable, people can still set the weights in the ini file
    static_data.SetWeights(feature, weights);
  } else {
    std::vector<float> defaultWeights = feature->DefaultWeights();
    static_data.SetWeights(feature, defaultWeights);
  }
}

namespace
{

template <class F> class DefaultFeatureFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(new F(line));
  }
};

class KenFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(ConstructKenLM(line));
  }
};

} // namespace

FeatureRegistry::FeatureRegistry()
{
// Feature with same name as class
#define MOSES_FNAME(name) Add(#name, new DefaultFeatureFactory< name >());
// Feature with different name than class.
#define MOSES_FNAME2(name, type) Add(name, new DefaultFeatureFactory< type >());
  MOSES_FNAME(GlobalLexicalModel);
  //MOSES_FNAME(GlobalLexicalModelUnlimited); This was commented out in the original
  MOSES_FNAME(SourceWordDeletionFeature);
  MOSES_FNAME(TargetWordInsertionFeature);
  MOSES_FNAME(PhraseBoundaryFeature);
  MOSES_FNAME(PhraseLengthFeature);
  MOSES_FNAME(WordTranslationFeature);
  MOSES_FNAME(TargetBigramFeature);
  MOSES_FNAME(TargetNgramFeature);
  MOSES_FNAME(PhrasePairFeature);
  MOSES_FNAME(LexicalReordering);
  MOSES_FNAME2("Generation", GenerationDictionary);
  MOSES_FNAME(BleuScoreFeature);
  MOSES_FNAME2("Distortion", DistortionScoreProducer);
  MOSES_FNAME2("WordPenalty", WordPenaltyProducer);
  MOSES_FNAME(InputFeature);
  MOSES_FNAME2("PhraseDictionaryBinary", PhraseDictionaryTreeAdaptor);
  MOSES_FNAME(PhraseDictionaryOnDisk);
  MOSES_FNAME(PhraseDictionaryMemory);
  MOSES_FNAME(PhraseDictionaryCompact);
  MOSES_FNAME(PhraseDictionaryMultiModel);
  MOSES_FNAME(PhraseDictionaryMultiModelCounts);
  MOSES_FNAME(PhraseDictionaryALSuffixArray);
  MOSES_FNAME(PhraseDictionaryDynSuffixArray);
  MOSES_FNAME(OpSequenceModel);
  MOSES_FNAME(PhrasePenalty);
  MOSES_FNAME2("UnknownWordPenalty", UnknownWordPenaltyProducer);
  MOSES_FNAME(ControlRecombination);
//  MOSES_FNAME(ConstrainedDecoding);
  MOSES_FNAME(ExternalFeature);

  MOSES_FNAME(SkeletonStatelessFF);
  MOSES_FNAME(SkeletonStatefulFF);

#ifdef HAVE_SYNLM
  MOSES_FNAME(SyntacticLanguageModel);
#endif
#ifdef LM_IRST
  MOSES_FNAME2("IRSTLM", LanguageModelIRST);
#endif
#ifdef LM_SRI
  MOSES_FNAME2("SRILM", LanguageModelSRI);
#endif
#ifdef LM_RAND
  MOSES_FNAME2("RANDLM", LanguageModelRandLM);
#endif
  Add("KENLM", new KenFactory());
}

FeatureRegistry::~FeatureRegistry() {}

void FeatureRegistry::Add(const std::string &name, FeatureFactory *factory)
{
  std::pair<std::string, boost::shared_ptr<FeatureFactory> > to_ins(name, boost::shared_ptr<FeatureFactory>(factory));
  UTIL_THROW_IF(!registry_.insert(to_ins).second, util::Exception, "Duplicate feature name " << name);
}

namespace
{
class UnknownFeatureException : public util::Exception {};
}

void FeatureRegistry::Construct(const std::string &name, const std::string &line)
{
  Map::iterator i = registry_.find(name);
  UTIL_THROW_IF(i == registry_.end(), UnknownFeatureException, "Feature name " << name << " is not registered.");
  i->second->Create(line);
}

} // namespace Moses
<|endoftext|>


<commit_before>#include <SCD/CD/CD_Pair.h>
#include <SCD/CD/CD_Simplex.h>
#include <SCD/CD/CD_SimplexEnhanced.h>
#ifdef WITH_OPENGL
#include <GL/glut.h>
#endif
#include <iostream>

//#ifndef NOGLUT
//#define SHOW_LAST_SIMLPEX
//#endif
//#define COUNTER
//#define SAFE_VERSION
#define PENETRATION_DEPTH

#define _EPSILON_ 1e-24
#define _PRECISION_ 1e-6

using namespace SCD;

inline Vector3 LinearSystem(Matrix3x3& A, Vector3& y)
{
	Matrix3x3 B;
	A.Inversion(B);
	return (B*y);
}

CD_Pair::CD_Pair(S_Object *obj1, S_Object *obj2):sObj1_(obj1),sObj2_(obj2),lastDirection_(1.0,0.0,0.0),
lastFeature1_(-1),lastFeature2_(-1),distance_(0),
stamp1_(sObj1_->checkStamp()),stamp2_(sObj2_->checkStamp()),precision_(_PRECISION_),
epsilon_(_EPSILON_),witPointsAreComputed_(false),s1_(Point3()),s2_(Point3()),s_(Point3()),sp_(Point3()),depthPair(obj1,obj2)
{
	--stamp1_;
	--stamp2_;

	depthPair.setRelativePrecision(_PRECISION_);
	depthPair.setEpsilon(_EPSILON_);

}

CD_Pair::~CD_Pair(void)
{
}

Scalar CD_Pair::getDistance()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		return distance_;
	}
	else
	{
		stamp1_=sObj1_->checkStamp();
		stamp2_=sObj2_->checkStamp();
		GJK();
		penetrationDepth();
		return distance_;
	}

}

Scalar CD_Pair::getDistanceWithoutPenetrationDepth()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		if (distance_ > 0)
			return distance_;
		return 0;
	}
	else
	{
		GJK();
		if (collision_)
			return 0;
		return distance_;
	}

}

Scalar CD_Pair::reComputeClosestPoints(Point3& p1,Point3& p2)
{
	stamp1_=sObj1_->checkStamp();
	stamp2_=sObj2_->checkStamp();
	GJK();
	penetrationDepth();
	witPoints(p1,p2);
	return distance_;

}

void CD_Pair::setRelativePrecision(Scalar s)
{
	precision_=s*s;
	depthPair.setRelativePrecision(s);
}

void CD_Pair::setEpsilon(Scalar s)
{
	epsilon_=s;
	depthPair.setEpsilon(s);
}

Scalar CD_Pair::getClosestPoints(Point3 &p1, Point3 &p2)
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		if (!witPointsAreComputed_)
		{
			witPointsAreComputed_=true;
			witPoints(p1,p2);
		}
		p1=p1_;
		p2=p2_;
		return distance_;
	}
	else
	{

		stamp1_=sObj1_->checkStamp();
		stamp2_=sObj2_->checkStamp();
		GJK();
		penetrationDepth();
		witPoints(p1,p2);
		witPointsAreComputed_=true;
		return distance_;

	}

}

Scalar CD_Pair::penetrationDepth()
{
#ifdef PENETRATION_DEPTH
	if (collision_)//Objects are in collision
	{
		distance_=-depthPair.getPenetrationDepth(lastDirection_,p1_,p2_,sp_,s1_,s2_);
		if (distance_<0)
		{
			lastDirection_.Set(0,1,0);
		}

		return distance_;
	}
	else
	{
		return distance_;
	}
#else
	return distance_;
#endif
}

Scalar CD_Pair::GJK()
{
	Vector3& v=lastDirection_;

	witPointsAreComputed_=false;

	int& lf1=lastFeature1_;
	int& lf2=lastFeature2_;

	Point3 sup1=sObj1_->support(v,lf1);
	Point3 sup2=sObj2_->support(-v,lf2);

	Point3 sup(sup1);

	sup-=sup2;

	s1_=sup1;
	s2_=sup2;
	s_=sup;

	sp_=sup;

	CD_SimplexKeptPoints k;

	projectionComputed_=false;

	bool cont=true;

	Point3 proj;

	Vector3 S01;
	Vector3 S02;

	Scalar a1,a2,a3,a4,a5,a6;

#ifdef COUNTER

	int	cnt=0;
#endif

	while (cont)
	{

#ifdef COUNTER

		cnt++;
#endif
		switch (s_.getType())
		{

		case CD_Triangle:
			{
				S01=s_[1];
				S01-=s_[2];
				S02=s_[0];
				S02-=s_[2];
				a1=S01*s_[0],a2=S01*s_[1],a3=S01*s_[2],a4=S02*s_[0],a5=S02*s_[1],a6=S02*s_[2];

				lambda0_=a2*a6-a3*a5;
				lambda1_=a3*a4-a1*a6;
				lambda2_=a1*a5-a2*a4;
				det_=1/(lambda0_+lambda1_+lambda2_);
				lambda0_*=det_;
				lambda1_*=det_;
				lambda2_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_+s_[2]*lambda2_;
				v=-proj;
				break;
			}

		case CD_Segment:
			{
				S01=s_[1];
				S01-=s_[0];

				lambda0_=S01*s_[1];
				lambda1_=-(S01*s_[0]);
				det_=1/(lambda0_+lambda1_);
				lambda0_*=det_;
				lambda1_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_;
				v=-proj;
				break;
			}
		default:
			{
				proj=s_[0];
				v=-proj;
			}

		}
		if ((distance_=v.normsquared())<=sp_.farthestPointDistance()*epsilon_)//v is considered zero
		{
			collision_=true;
			cont=false;
		}
		else
		{
			sup1=sObj1_->support(v,lf1);
			sup2=sObj2_->support(-v,lf2);
			sup=sup1;
			sup-=sup2;

			if ((distance_-proj*sup)<(precision_*distance_))//precision reached
			{
				collision_=false;
				cont=false;
				projectionComputed_=true;
			}
			else
			{
				sp_+=sup;
				sp_.updateVectors();
#ifndef SAFE_VERSION
				if (sp_.isAffinelyDependent())
				{
					cont=false;
					collision_=false;
					projectionComputed_=true;
				}
				else
#endif
				{
					sp_.getClosestSubSimplexGJK(k);
					sp_.filter(k);
					s1_+=sup1;
					s2_+=sup2;

					if (sp_.getType()==CD_Tetrahedron)
					{
						cont=false;
						s1_+=sup1;
						s2_+=sup2;
						collision_=true;
					}
					else
					{
						s_=sp_;
						s1_.filter(k);
						s2_.filter(k);
					}
				}
			}
		}
	}

#ifdef COUNTER

	std::cout<<"F "<<cnt<<" ; ";
#endif

	return distance_;

}

void CD_Pair::setVector(const Vector3 &v)
{
	lastDirection_=v;
}

void CD_Pair::witPoints(Point3 &p1, Point3 &p2)
{
	Point3 proj;
	Vector3& v=lastDirection_;

	if (collision_)
	{
		p1=p1_;
		p2=p2_;
		return;

	}

	switch (s_.getType())
	{

	case CD_Triangle:
		{

			{
				if (!projectionComputed_)
				{
					Vector3 S01(s_[1]-s_[2]), S02(s_[0]-s_[2]);

					Scalar a1=S01*s_[0],a2=S01*s_[1],a3=S01*s_[2],a4=S02*s_[0],a5=S02*s_[1],a6=S02*s_[2];

					lambda0_=a2*a6-a3*a5;
					lambda1_=a3*a4-a1*a6;
					lambda2_=a1*a5-a2*a4;
					det_=1/(lambda0_+lambda1_+lambda2_);

					lambda0_*=det_;
					lambda1_*=det_;
					lambda2_*=det_;

					proj=s_[0]*lambda0_+s_[1]*lambda1_+s_[2]*lambda2_;

					v=-proj;

				}

				p1_=p1=s1_[0]*lambda0_+s1_[1]*lambda1_+s1_[2]*lambda2_;
				p2_=p2=s2_[0]*lambda0_+s2_[1]*lambda1_+s2_[2]*lambda2_;

			}

#ifdef WITH_OPENGL
#ifdef SHOW_LAST_SIMLPEX
			glDisable(GL_DEPTH_TEST);
			glColor4d(0,0.5,1,0.5);
			glBegin(GL_TRIANGLES);
			glVertex3d(s1_[0][0],s1_[0][1],s1_[0][2]);
			glVertex3d(s1_[1][0],s1_[1][1],s1_[1][2]);
			glVertex3d(s1_[2][0],s1_[2][1],s1_[2][2]);

			glVertex3d(s2_[0][0],s2_[0][1],s2_[0][2]);
			glVertex3d(s2_[1][0],s2_[1][1],s2_[1][2]);
			glVertex3d(s2_[2][0],s2_[2][1],s2_[2][2]);

			glEnd();

			glEnable(GL_DEPTH_TEST);
#endif
#endif // WITH_OPENGL

			return;

		}

	case CD_Segment:
		{
			if (!projectionComputed_)
			{

				Vector3 S01(s_[1]-s_[0]);

				lambda1_=-(S01*s_[0]);
				lambda0_=S01*s_[1];

				det_=1/(lambda0_+lambda1_);

				lambda0_*=det_;
				lambda1_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_;

				v=-proj;

			}

			p1_=p1=s1_[0]*lambda0_+s1_[1]*lambda1_;
			p2_=p2=s2_[0]*lambda0_+s2_[1]*lambda1_;

#ifdef WITH_OPENGL
#ifdef SHOW_LAST_SIMLPEX

			glDisable(GL_DEPTH_TEST);
			glColor4d(0,0.5,1,0.5);
			glBegin(GL_LINES);
			glVertex3d(s1_[0][0],s1_[0][1],s1_[0][2]);
			glVertex3d(s1_[1][0],s1_[1][1],s1_[1][2]);

			glVertex3d(s2_[0][0],s2_[0][1],s2_[0][2]);
			glVertex3d(s2_[1][0],s2_[1][1],s2_[1][2]);

			glEnd();

			glEnable(GL_DEPTH_TEST);

#endif
#endif // WITH_OPENGL
			return ;
		}
	default:
		{
			p1_=p1=s1_[0];
			p2_=p2=s2_[0];

			return ;
		}

	}
}

bool CD_Pair::isInCollision()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		return collision_;
	}
	else
	{
		Scalar prec=precision_;
		precision_=1;
		GJK();
		precision_=prec;
		return collision_;
	}
}

#undef SHOW_LAST_SIMLPEX
#undef COUNTER
<commit_msg>Add verbose mode to the algorithm<commit_after>#include <SCD/CD/CD_Pair.h>
#include <SCD/CD/CD_Simplex.h>
#include <SCD/CD/CD_SimplexEnhanced.h>
#ifdef WITH_OPENGL
#include <GL/glut.h>
#endif
#include <iostream>

//#ifndef NOGLUT
//#define SHOW_LAST_SIMLPEX
//#endif
//#define COUNTER
//#define SAFE_VERSION //use when the scalar has a perfect precision
#define PENETRATION_DEPTH
//#define CD_PAIR_VERBOUS_MODE

#define _EPSILON_ 1e-24
#define _PRECISION_ 1e-6

using namespace SCD;

inline Vector3 LinearSystem(Matrix3x3& A, Vector3& y)
{
	Matrix3x3 B;
	A.Inversion(B);
	return (B*y);
}

CD_Pair::CD_Pair(S_Object *obj1, S_Object *obj2):sObj1_(obj1),sObj2_(obj2),lastDirection_(1.0,0.0,0.0),
lastFeature1_(-1),lastFeature2_(-1),distance_(0),
stamp1_(sObj1_->checkStamp()),stamp2_(sObj2_->checkStamp()),precision_(_PRECISION_),
epsilon_(_EPSILON_),witPointsAreComputed_(false),s1_(Point3()),s2_(Point3()),s_(Point3()),sp_(Point3()),depthPair(obj1,obj2)
{
	--stamp1_;
	--stamp2_;

	depthPair.setRelativePrecision(_PRECISION_);
	depthPair.setEpsilon(_EPSILON_);

}

CD_Pair::~CD_Pair(void)
{
}

Scalar CD_Pair::getDistance()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		return distance_;
	}
	else
	{
		stamp1_=sObj1_->checkStamp();
		stamp2_=sObj2_->checkStamp();
		GJK();
		penetrationDepth();
		return distance_;
	}

}

Scalar CD_Pair::getDistanceWithoutPenetrationDepth()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		if (distance_ > 0)
			return distance_;
		return 0;
	}
	else
	{
		GJK();
		if (collision_)
			return 0;
		return distance_;
	}

}

Scalar CD_Pair::reComputeClosestPoints(Point3& p1,Point3& p2)
{
	stamp1_=sObj1_->checkStamp();
	stamp2_=sObj2_->checkStamp();
	GJK();
	penetrationDepth();
	witPoints(p1,p2);
	return distance_;

}

void CD_Pair::setRelativePrecision(Scalar s)
{
	precision_=s*s;
	depthPair.setRelativePrecision(s);
}

void CD_Pair::setEpsilon(Scalar s)
{
	epsilon_=s;
	depthPair.setEpsilon(s);
}

Scalar CD_Pair::getClosestPoints(Point3 &p1, Point3 &p2)
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		if (!witPointsAreComputed_)
		{
			witPointsAreComputed_=true;
			witPoints(p1,p2);
		}
		p1=p1_;
		p2=p2_;
		return distance_;
	}
	else
	{

		stamp1_=sObj1_->checkStamp();
		stamp2_=sObj2_->checkStamp();
		GJK();
		penetrationDepth();
		witPoints(p1,p2);
		witPointsAreComputed_=true;
		return distance_;

	}

}

Scalar CD_Pair::penetrationDepth()
{
#ifdef PENETRATION_DEPTH
	if (collision_)//Objects are in collision
	{
		distance_=-depthPair.getPenetrationDepth(lastDirection_,p1_,p2_,sp_,s1_,s2_);
		if (distance_<0)
		{
			lastDirection_.Set(0,1,0);
		}

		return distance_;
	}
	else
	{
		return distance_;
	}
#else
	return distance_;
#endif
}

Scalar CD_Pair::GJK()
{
	Vector3& v=lastDirection_;

#ifdef CD_PAIR_VERBOUS_MODE
	std::cout<<"#####GJK START######"<<std::endl;
#endif

	witPointsAreComputed_=false;

	int& lf1=lastFeature1_;
	int& lf2=lastFeature2_;

	Point3 sup1=sObj1_->support(v,lf1);
	Point3 sup2=sObj2_->support(-v,lf2);

#ifdef CD_PAIR_VERBOUS_MODE
	std::cout<<"Last features"<<lf1<<" "<<lf2<<std::endl;
#endif

	Point3 sup(sup1);

	sup-=sup2;

	s1_=sup1;
	s2_=sup2;
	s_=sup;

	sp_=sup;

	CD_SimplexKeptPoints k;

	projectionComputed_=false;

	bool cont=true;

	Point3 proj;

	Vector3 S01;
	Vector3 S02;

	Scalar a1,a2,a3,a4,a5,a6;

#ifdef COUNTER

	int	cnt=0;
#endif

	while (cont)
	{

#ifdef COUNTER

		cnt++;
#endif
		switch (s_.getType())
		{

		case CD_Triangle:
			{
				S01=s_[1];
				S01-=s_[2];
				S02=s_[0];
				S02-=s_[2];
				a1=S01*s_[0],a2=S01*s_[1],a3=S01*s_[2],a4=S02*s_[0],a5=S02*s_[1],a6=S02*s_[2];

				lambda0_=a2*a6-a3*a5;
				lambda1_=a3*a4-a1*a6;
				lambda2_=a1*a5-a2*a4;
				det_=1/(lambda0_+lambda1_+lambda2_);
				lambda0_*=det_;
				lambda1_*=det_;
				lambda2_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_+s_[2]*lambda2_;
				v=-proj;
				break;
			}

		case CD_Segment:
			{
				S01=s_[1];
				S01-=s_[0];

				lambda0_=S01*s_[1];
				lambda1_=-(S01*s_[0]);
				det_=1/(lambda0_+lambda1_);
				lambda0_*=det_;
				lambda1_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_;
				v=-proj;
				break;
			}
		default:
			{
				proj=s_[0];
				v=-proj;
			}

		}
		if ((distance_=v.normsquared())<=sp_.farthestPointDistance()*epsilon_)//v is considered zero
		{
			collision_=true;
			cont=false;
		}
		else
		{
			sup1=sObj1_->support(v,lf1);
			sup2=sObj2_->support(-v,lf2);

#ifdef CD_PAIR_VERBOUS_MODE
			std::cout<<"Last features"<<lf1<<" "<<lf2<<std::endl;
			std::cout<<"supports"<<sup1<<" "<<sup2<<std::endl;
#endif

			sup=sup1;
			sup-=sup2;

			if ((distance_-proj*sup)<(precision_*distance_))//precision reached
			{
				collision_=false;
				cont=false;
				projectionComputed_=true;
			}
			else
			{
				sp_+=sup;
				sp_.updateVectors();
#ifndef SAFE_VERSION
				if (sp_.isAffinelyDependent())
				{
					cont=false;
					collision_=false;
					projectionComputed_=true;
				}
				else
#endif
				{
					sp_.getClosestSubSimplexGJK(k);
					sp_.filter(k);
					s1_+=sup1;
					s2_+=sup2;

					if (sp_.getType()==CD_Tetrahedron)
					{
						cont=false;
						s1_+=sup1;
						s2_+=sup2;
						collision_=true;
					}
					else
					{
						s_=sp_;
						s1_.filter(k);
						s2_.filter(k);
					}
				}
			}
		}
	}

#ifdef COUNTER

	std::cout<<"F "<<cnt<<" ; ";
#endif

#ifdef CD_PAIR_VERBOUS_MODE
	std::cout<<"#####GJK END######"<<std::endl;
#endif

	return distance_;

}

void CD_Pair::setVector(const Vector3 &v)
{
	lastDirection_=v;
}

void CD_Pair::witPoints(Point3 &p1, Point3 &p2)
{
	Point3 proj;
	Vector3& v=lastDirection_;

	if (collision_)
	{
		p1=p1_;
		p2=p2_;
		return;

	}

	switch (s_.getType())
	{

	case CD_Triangle:
		{

			{
				if (!projectionComputed_)
				{
					Vector3 S01(s_[1]-s_[2]), S02(s_[0]-s_[2]);

					Scalar a1=S01*s_[0],a2=S01*s_[1],a3=S01*s_[2],a4=S02*s_[0],a5=S02*s_[1],a6=S02*s_[2];

					lambda0_=a2*a6-a3*a5;
					lambda1_=a3*a4-a1*a6;
					lambda2_=a1*a5-a2*a4;
					det_=1/(lambda0_+lambda1_+lambda2_);

					lambda0_*=det_;
					lambda1_*=det_;
					lambda2_*=det_;

					proj=s_[0]*lambda0_+s_[1]*lambda1_+s_[2]*lambda2_;

					v=-proj;

				}

				p1_=p1=s1_[0]*lambda0_+s1_[1]*lambda1_+s1_[2]*lambda2_;
				p2_=p2=s2_[0]*lambda0_+s2_[1]*lambda1_+s2_[2]*lambda2_;

			}

#ifdef WITH_OPENGL
#ifdef SHOW_LAST_SIMLPEX
			glDisable(GL_DEPTH_TEST);
			glColor4d(0,0.5,1,0.5);
			glBegin(GL_TRIANGLES);
			glVertex3d(s1_[0][0],s1_[0][1],s1_[0][2]);
			glVertex3d(s1_[1][0],s1_[1][1],s1_[1][2]);
			glVertex3d(s1_[2][0],s1_[2][1],s1_[2][2]);

			glVertex3d(s2_[0][0],s2_[0][1],s2_[0][2]);
			glVertex3d(s2_[1][0],s2_[1][1],s2_[1][2]);
			glVertex3d(s2_[2][0],s2_[2][1],s2_[2][2]);

			glEnd();

			glEnable(GL_DEPTH_TEST);
#endif
#endif // WITH_OPENGL

			return;

		}

	case CD_Segment:
		{
			if (!projectionComputed_)
			{

				Vector3 S01(s_[1]-s_[0]);

				lambda1_=-(S01*s_[0]);
				lambda0_=S01*s_[1];

				det_=1/(lambda0_+lambda1_);

				lambda0_*=det_;
				lambda1_*=det_;

				proj=s_[0]*lambda0_+s_[1]*lambda1_;

				v=-proj;

			}

			p1_=p1=s1_[0]*lambda0_+s1_[1]*lambda1_;
			p2_=p2=s2_[0]*lambda0_+s2_[1]*lambda1_;

#ifdef WITH_OPENGL
#ifdef SHOW_LAST_SIMLPEX

			glDisable(GL_DEPTH_TEST);
			glColor4d(0,0.5,1,0.5);
			glBegin(GL_LINES);
			glVertex3d(s1_[0][0],s1_[0][1],s1_[0][2]);
			glVertex3d(s1_[1][0],s1_[1][1],s1_[1][2]);

			glVertex3d(s2_[0][0],s2_[0][1],s2_[0][2]);
			glVertex3d(s2_[1][0],s2_[1][1],s2_[1][2]);

			glEnd();

			glEnable(GL_DEPTH_TEST);

#endif
#endif // WITH_OPENGL
			return ;
		}
	default:
		{
			p1_=p1=s1_[0];
			p2_=p2=s2_[0];

			return ;
		}

	}
}

bool CD_Pair::isInCollision()
{
	if ((stamp1_==sObj1_->checkStamp())&&(stamp2_==sObj2_->checkStamp()))
	{
		return collision_;
	}
	else
	{
		Scalar prec=precision_;
		precision_=1;
		GJK();
		precision_=prec;
		return collision_;
	}
}

#undef SHOW_LAST_SIMLPEX
#undef COUNTER
<|endoftext|>


<commit_before>#include <CImageDraw.h>
#include <CImageGC.h>
#include <CMathRound.h>

#include <CLine2D.h>
#include <CBresenham.h>

CImageDraw::
CImageDraw(CImagePtr image) :
 image_(image), compose_(false)
{
}

void
CImageDraw::
setImage(CImagePtr image)
{
  image_ = image;
}

void
CImageDraw::
clear(const CImageGC &gc)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getBackground(color_ind);

    image_->setColorIndexData(color_ind);
  }
  else {
    CRGBA rgba;

    gc.getBackground(rgba);

    image_->setRGBAData(rgba);
  }
}

void
CImageDraw::
fill(const CImageGC &gc)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    image_->setColorIndexData(color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    image_->setRGBAData(rgba);
  }
}

void
CImageDraw::
drawImage(const CImageGC &, int x, int y, CImagePtr image)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int iwidth1  = image->getWidth ();
  int iheight1 = image->getHeight();

  int x1 = x;
  int x2 = std::min(x + iwidth1  - 1, iwidth  - 1);
  int y1 = y;
  int y2 = std::min(y + iheight1 - 1, iheight - 1);

  if (image_->hasColormap()) {
    int color_ind;

    for (int y = y1; y <= y2; ++y)
      for (int x = x1; x <= x2; ++x) {
        color_ind = image->getColorIndexPixel(x - x1, y - y1);

        image_->drawColorIndexPoint(x, y, color_ind);
      }
  }
  else {
    CRGBA rgba;

    for (int y = y1; y <= y2; ++y)
      for (int x = x1; x <= x2; ++x) {
        image->getRGBAPixel(x - x1, y - y1, rgba);

        image_->drawRGBAPoint(x, y, rgba);
      }
  }
}

void
CImageDraw::
drawPolygon(const CImageGC &gc, int *x, int *y, int num_xy)
{
  int i1 = num_xy - 1;
  int i2 = 0;

  for ( ; i2 < num_xy; i1 = i2, ++i2)
    drawLine(gc, x[i1], y[i1], x[i2], y[i2]);
}

void
CImageDraw::
fillPolygon(const CImageGC &gc, int *x, int *y, int num_xy)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int ymin = iheight;
  int ymax = -1;

  for (int i1 = 0; i1 < num_xy; ++i1) {
    ymin = std::min(ymin, y[i1]);
    ymax = std::max(ymax, y[i1]);
  }

  ymin = std::max(ymin, 0);
  ymax = std::min(ymax, iheight - 1);

  for (int yy = ymin; yy <= ymax; ++yy) {
    int xmin = iwidth;
    int xmax = -1;

    for (int i1 = num_xy - 1, i2 = 0; i2 < num_xy; i1 = i2, ++i2) {
      if ((y[i1] < yy && y[i2] < yy) ||
          (y[i1] > yy && y[i2] > yy) ||
          y[i1] == y[i2])
        continue;

      double factor = double(x[i2] - x[i1])/double(y[i2] - y[i1]);

      int xx = CMathRound::Round((yy - y[i1])*factor + x[i1]);

      xmin = std::min(xmin, xx);
      xmax = std::max(xmax, xx);
    }

    xmin = std::max(xmin, 0);
    xmax = std::min(xmax, iwidth - 1);

    if (xmin > xmax)
      continue;

    drawLine(gc, xmin, yy, xmax, yy);
  }
}

void
CImageDraw::
drawRectangle(const CImageGC &gc, int x, int y, int width, int height)
{
  int x1 = x + width  - 1;
  int y1 = y + height - 1;

  drawLine(gc, x , y , x1, y );
  drawLine(gc, x1, y , x1, y1);
  drawLine(gc, x1, y1, x , y1);
  drawLine(gc, x , y1, x , y );
}

void
CImageDraw::
fillRectangle(const CImageGC &gc, int x, int y, int width, int height)
{
  if (compose_) {
    int iwidth  = image_->getWidth ();
    int iheight = image_->getHeight();

    int x1 = x;
    int x2 = std::min(x + width  - 1, iwidth  - 1);
    int y1 = y;
    int y2 = std::min(y + height - 1, iheight - 1);

    if (image_->hasColormap()) {
      int color_ind;

      gc.getForeground(color_ind);

      for (int y = y1; y <= y2; ++y)
        for (int x = x1; x <= x2; ++x)
          image_->drawColorIndexPoint(x, y, color_ind);
    }
    else {
      CRGBA rgba;

      gc.getForeground(rgba);

      for (int y = y1; y <= y2; ++y)
        for (int x = x1; x <= x2; ++x)
          image_->drawRGBAPoint(x, y, rgba);
    }
  }
  else {
    int x2 = x + width  - 1;
    int y2 = y + height - 1;

    if (image_->hasColormap()) {
      int color_ind;

      gc.getForeground(color_ind);

      image_->fillColorIndexRectangle(x, y, x2, y2, color_ind);
    }
    else {
      CRGBA rgba;

      gc.getForeground(rgba);

      image_->fillRGBARectangle(x, y, x2, y2, rgba);
    }
  }
}

void
CImageDraw::
drawButton(const CImageGC &gc, int x, int y, int width, int height,
           int thickness)
{
  if (image_->hasColormap())
    return;

  CRGBA rgba;

  gc.getForeground(rgba);

  CRGBA rgba1 = rgba;
  CRGBA rgba2 = rgba;

  rgba1.scaleAlpha(0.4);
  rgba2.scaleAlpha(0.8);

  // top

  {
    int x1 = x;
    int x2 = x + width - 2;
    int y1 = y;

    for (int i = 0; i < thickness; ++i, x1++, x2--)
      drawRGBAHLine(x1, y1 + i, x2 - x1 + 1, rgba1);
  }

  // left

  {
    int x1 = x;
    int y1 = y + 1;
    int y2 = y + height - 2;

    for (int i = 0; i < thickness; ++i, y1++, y2--)
      drawRGBAVLine(x1 + i, y1, y2 - y1 + 1, rgba1);
  }

  // bottom

  {
    int x1 = x;
    int y1 = y + height - 1;
    int x2 = x + width - 1;

    for (int i = 0; i < thickness; ++i, x1++, x2--)
      drawRGBAHLine(x1, y1 - i, x2 - x1 + 1, rgba2);
  }

  // right

  {
    int x1 = x + width - 1;
    int y1 = y;
    int y2 = y + height - 2;

    for (int i = 0; i < thickness; ++i, y1++, y2--)
      drawRGBAVLine(x1 - i, y1, y2 - y1 + 1, rgba2);
  }

  fillRectangle(gc, x + thickness, y + thickness,
                width - 2*thickness, height - 2*thickness);
}

void
CImageDraw::
drawHLine(const CImageGC &gc, int x, int y, int length)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    drawColorIndexHLine(x, y, length, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    drawRGBAHLine(x, y, length, rgba);
  }
}

void
CImageDraw::
drawColorIndexHLine(int x, int y, int length, int color_ind)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int x1 = x;
  int x2 = std::min(x + length - 1, iwidth - 1);

  if (y < 0 || y >= iheight)
    return;

  for (int x = x1; x <= x2; ++x)
    image_->drawColorIndexPoint(x, y, color_ind);
}

void
CImageDraw::
drawRGBAHLine(int x, int y, int length, const CRGBA &rgba)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int x1 = x;
  int x2 = std::min(x + length - 1, iwidth - 1);

  if (y < 0 || y >= iheight)
    return;

  for (int x = x1; x <= x2; ++x)
    image_->drawRGBAPoint(x, y, rgba);
}

void
CImageDraw::
drawVLine(const CImageGC &gc, int x, int y, int length)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    drawColorIndexVLine(x, y, length, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    drawRGBAVLine(x, y, length, rgba);
  }
}

void
CImageDraw::
drawColorIndexVLine(int x, int y, int length, int color_ind)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int y1 = y;
  int y2 = std::min(y + length - 1, iheight - 1);

  if (x < 0 || x >= iwidth)
    return;

  for (int y = y1; y <= y2; ++y)
    image_->drawColorIndexPoint(x, y, color_ind);
}

void
CImageDraw::
drawRGBAVLine(int x, int y, int length, const CRGBA &rgba)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int y1 = y;
  int y2 = std::min(y + length - 1, iheight - 1);

  if (x < 0 || x >= iwidth)
    return;

  for (int y = y1; y <= y2; ++y)
    image_->drawRGBAPoint(x, y, rgba);
}

void
CImageDraw::
drawDLine(const CImageGC &gc, int x1, int y1, int x2, int y2)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  if (x1 < 0 || x1 >= iwidth  || x2 < 0 || x2 >= iwidth  ||
      y1 < 0 || y1 >= iheight || y2 < 0 || y2 >= iheight)
    return;

  int dx = (x2 > x1 ? 1 : -1);
  int dy = (y2 > y1 ? 1 : -1);

  int x = x1;
  int y = y1;

  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    while (true) {
      if      (dx ==  1 && x > x2) break;
      else if (dx == -1 && x < x2) break;
      if      (dy ==  1 && y > y2) break;
      else if (dy == -1 && y < y2) break;

      image_->drawColorIndexPoint(x, y, color_ind);

      x += dx;
      y += dy;
    }
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    while (true) {
      if      (dx ==  1 && x > x2) break;
      else if (dx == -1 && x < x2) break;
      if      (dy ==  1 && y > y2) break;
      else if (dy == -1 && y < y2) break;

      image_->drawRGBAPoint(x, y, rgba);

      x += dx;
      y += dy;
    }
  }
}

void
CImageDraw::
drawLine(const CImageGC &gc, int x1, int y1, int x2, int y2)
{
  class CImageDrawBresenham : public CBresenham {
   public:
    CImageDrawBresenham(CImageDraw *draw, const CImageGC *gc) :
     draw_(draw), gc_(gc) {
    }

    void drawPoint(int x, int y) {
      draw_->drawPoint(*gc_, x, y);
    }

   private:
    CImageDraw     *draw_;
    const CImageGC *gc_;
  };

  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  CLine2D line(x1, y1, x2, y2);
  CBBox2D bbox(0, 0, iwidth - 1, iheight - 1);

  CLine2D cline;

  if (! line.clip(bbox, cline))
    return;

  CImageDrawBresenham bresenham(this, &gc);

  bresenham.drawLine(cline.start().x, cline.start().y,
                     cline.end  ().x, cline.end  ().y);
}

void
CImageDraw::
drawPoint(const CImageGC &gc, int x, int y)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  if (x < 0 || x >= iwidth  ||
      y < 0 || y >= iheight)
    return;

  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    image_->drawColorIndexPoint(x, y, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    image_->drawRGBAPoint(x, y, rgba);
  }
}
<commit_msg>new files<commit_after>#include <CImageDraw.h>
#include <CImageGC.h>
#include <CMathRound.h>

#include <CLine2D.h>
#include <CBresenham.h>

CImageDraw::
CImageDraw(CImagePtr image) :
 image_(image), compose_(false)
{
}

void
CImageDraw::
setImage(CImagePtr image)
{
  image_ = image;
}

void
CImageDraw::
clear(const CImageGC &gc)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getBackground(color_ind);

    image_->setColorIndexData(color_ind);
  }
  else {
    CRGBA rgba;

    gc.getBackground(rgba);

    image_->setRGBAData(rgba);
  }
}

void
CImageDraw::
fill(const CImageGC &gc)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    image_->setColorIndexData(color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    image_->setRGBAData(rgba);
  }
}

void
CImageDraw::
drawImage(const CImageGC &, int x, int y, CImagePtr image)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int iwidth1  = image->getWidth ();
  int iheight1 = image->getHeight();

  int x1 = x;
  int x2 = std::min(x + iwidth1  - 1, iwidth  - 1);
  int y1 = y;
  int y2 = std::min(y + iheight1 - 1, iheight - 1);

  if (image_->hasColormap()) {
    int color_ind;

    for (int yy = y1; yy <= y2; ++yy)
      for (int xx = x1; xx <= x2; ++xx) {
        color_ind = image->getColorIndexPixel(xx - x1, yy - y1);

        image_->drawColorIndexPoint(xx, yy, color_ind);
      }
  }
  else {
    CRGBA rgba;

    for (int yy = y1; yy <= y2; ++yy)
      for (int xx = x1; xx <= x2; ++xx) {
        image->getRGBAPixel(xx - x1, yy - y1, rgba);

        image_->drawRGBAPoint(xx, yy, rgba);
      }
  }
}

void
CImageDraw::
drawPolygon(const CImageGC &gc, int *x, int *y, int num_xy)
{
  int i1 = num_xy - 1;
  int i2 = 0;

  for ( ; i2 < num_xy; i1 = i2, ++i2)
    drawLine(gc, x[i1], y[i1], x[i2], y[i2]);
}

void
CImageDraw::
fillPolygon(const CImageGC &gc, int *x, int *y, int num_xy)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int ymin = iheight;
  int ymax = -1;

  for (int i1 = 0; i1 < num_xy; ++i1) {
    ymin = std::min(ymin, y[i1]);
    ymax = std::max(ymax, y[i1]);
  }

  ymin = std::max(ymin, 0);
  ymax = std::min(ymax, iheight - 1);

  for (int yy = ymin; yy <= ymax; ++yy) {
    int xmin = iwidth;
    int xmax = -1;

    for (int i1 = num_xy - 1, i2 = 0; i2 < num_xy; i1 = i2, ++i2) {
      if ((y[i1] < yy && y[i2] < yy) ||
          (y[i1] > yy && y[i2] > yy) ||
          y[i1] == y[i2])
        continue;

      double factor = double(x[i2] - x[i1])/double(y[i2] - y[i1]);

      int xx = CMathRound::Round((yy - y[i1])*factor + x[i1]);

      xmin = std::min(xmin, xx);
      xmax = std::max(xmax, xx);
    }

    xmin = std::max(xmin, 0);
    xmax = std::min(xmax, iwidth - 1);

    if (xmin > xmax)
      continue;

    drawLine(gc, xmin, yy, xmax, yy);
  }
}

void
CImageDraw::
drawRectangle(const CImageGC &gc, int x, int y, int width, int height)
{
  int x1 = x + width  - 1;
  int y1 = y + height - 1;

  drawLine(gc, x , y , x1, y );
  drawLine(gc, x1, y , x1, y1);
  drawLine(gc, x1, y1, x , y1);
  drawLine(gc, x , y1, x , y );
}

void
CImageDraw::
fillRectangle(const CImageGC &gc, int x, int y, int width, int height)
{
  if (compose_) {
    int iwidth  = image_->getWidth ();
    int iheight = image_->getHeight();

    int x1 = x;
    int x2 = std::min(x + width  - 1, iwidth  - 1);
    int y1 = y;
    int y2 = std::min(y + height - 1, iheight - 1);

    if (image_->hasColormap()) {
      int color_ind;

      gc.getForeground(color_ind);

      for (int yy = y1; yy <= y2; ++yy)
        for (int xx = x1; xx <= x2; ++xx)
          image_->drawColorIndexPoint(xx, yy, color_ind);
    }
    else {
      CRGBA rgba;

      gc.getForeground(rgba);

      for (int yy = y1; yy <= y2; ++yy)
        for (int xx = x1; xx <= x2; ++xx)
          image_->drawRGBAPoint(xx, yy, rgba);
    }
  }
  else {
    int x2 = x + width  - 1;
    int y2 = y + height - 1;

    if (image_->hasColormap()) {
      int color_ind;

      gc.getForeground(color_ind);

      image_->fillColorIndexRectangle(x, y, x2, y2, color_ind);
    }
    else {
      CRGBA rgba;

      gc.getForeground(rgba);

      image_->fillRGBARectangle(x, y, x2, y2, rgba);
    }
  }
}

void
CImageDraw::
drawButton(const CImageGC &gc, int x, int y, int width, int height,
           int thickness)
{
  if (image_->hasColormap())
    return;

  CRGBA rgba;

  gc.getForeground(rgba);

  CRGBA rgba1 = rgba;
  CRGBA rgba2 = rgba;

  rgba1.scaleAlpha(0.4);
  rgba2.scaleAlpha(0.8);

  // top

  {
    int x1 = x;
    int x2 = x + width - 2;
    int y1 = y;

    for (int i = 0; i < thickness; ++i, x1++, x2--)
      drawRGBAHLine(x1, y1 + i, x2 - x1 + 1, rgba1);
  }

  // left

  {
    int x1 = x;
    int y1 = y + 1;
    int y2 = y + height - 2;

    for (int i = 0; i < thickness; ++i, y1++, y2--)
      drawRGBAVLine(x1 + i, y1, y2 - y1 + 1, rgba1);
  }

  // bottom

  {
    int x1 = x;
    int y1 = y + height - 1;
    int x2 = x + width - 1;

    for (int i = 0; i < thickness; ++i, x1++, x2--)
      drawRGBAHLine(x1, y1 - i, x2 - x1 + 1, rgba2);
  }

  // right

  {
    int x1 = x + width - 1;
    int y1 = y;
    int y2 = y + height - 2;

    for (int i = 0; i < thickness; ++i, y1++, y2--)
      drawRGBAVLine(x1 - i, y1, y2 - y1 + 1, rgba2);
  }

  fillRectangle(gc, x + thickness, y + thickness,
                width - 2*thickness, height - 2*thickness);
}

void
CImageDraw::
drawHLine(const CImageGC &gc, int x, int y, int length)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    drawColorIndexHLine(x, y, length, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    drawRGBAHLine(x, y, length, rgba);
  }
}

void
CImageDraw::
drawColorIndexHLine(int x, int y, int length, int color_ind)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int x1 = x;
  int x2 = std::min(x + length - 1, iwidth - 1);

  if (y < 0 || y >= iheight)
    return;

  for (int xx = x1; xx <= x2; ++xx)
    image_->drawColorIndexPoint(xx, y, color_ind);
}

void
CImageDraw::
drawRGBAHLine(int x, int y, int length, const CRGBA &rgba)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int x1 = x;
  int x2 = std::min(x + length - 1, iwidth - 1);

  if (y < 0 || y >= iheight)
    return;

  for (int xx = x1; xx <= x2; ++xx)
    image_->drawRGBAPoint(xx, y, rgba);
}

void
CImageDraw::
drawVLine(const CImageGC &gc, int x, int y, int length)
{
  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    drawColorIndexVLine(x, y, length, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    drawRGBAVLine(x, y, length, rgba);
  }
}

void
CImageDraw::
drawColorIndexVLine(int x, int y, int length, int color_ind)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int y1 = y;
  int y2 = std::min(y + length - 1, iheight - 1);

  if (x < 0 || x >= iwidth)
    return;

  for (int yy = y1; yy <= y2; ++yy)
    image_->drawColorIndexPoint(x, yy, color_ind);
}

void
CImageDraw::
drawRGBAVLine(int x, int y, int length, const CRGBA &rgba)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  int y1 = y;
  int y2 = std::min(y + length - 1, iheight - 1);

  if (x < 0 || x >= iwidth)
    return;

  for (int yy = y1; yy <= y2; ++yy)
    image_->drawRGBAPoint(x, yy, rgba);
}

void
CImageDraw::
drawDLine(const CImageGC &gc, int x1, int y1, int x2, int y2)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  if (x1 < 0 || x1 >= iwidth  || x2 < 0 || x2 >= iwidth  ||
      y1 < 0 || y1 >= iheight || y2 < 0 || y2 >= iheight)
    return;

  int dx = (x2 > x1 ? 1 : -1);
  int dy = (y2 > y1 ? 1 : -1);

  int x = x1;
  int y = y1;

  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    while (true) {
      if      (dx ==  1 && x > x2) break;
      else if (dx == -1 && x < x2) break;
      if      (dy ==  1 && y > y2) break;
      else if (dy == -1 && y < y2) break;

      image_->drawColorIndexPoint(x, y, color_ind);

      x += dx;
      y += dy;
    }
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    while (true) {
      if      (dx ==  1 && x > x2) break;
      else if (dx == -1 && x < x2) break;
      if      (dy ==  1 && y > y2) break;
      else if (dy == -1 && y < y2) break;

      image_->drawRGBAPoint(x, y, rgba);

      x += dx;
      y += dy;
    }
  }
}

void
CImageDraw::
drawLine(const CImageGC &gc, int x1, int y1, int x2, int y2)
{
  class CImageDrawBresenham : public CBresenham {
   public:
    CImageDrawBresenham(CImageDraw *draw, const CImageGC *gc) :
     draw_(draw), gc_(gc) {
    }

    void drawPoint(int x, int y) {
      draw_->drawPoint(*gc_, x, y);
    }

   private:
    CImageDraw     *draw_;
    const CImageGC *gc_;
  };

  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  CLine2D line(x1, y1, x2, y2);
  CBBox2D bbox(0, 0, iwidth - 1, iheight - 1);

  CLine2D cline;

  if (! line.clip(bbox, cline))
    return;

  CImageDrawBresenham bresenham(this, &gc);

  bresenham.drawLine(cline.start().x, cline.start().y,
                     cline.end  ().x, cline.end  ().y);
}

void
CImageDraw::
drawPoint(const CImageGC &gc, int x, int y)
{
  int iwidth  = image_->getWidth ();
  int iheight = image_->getHeight();

  if (x < 0 || x >= iwidth  ||
      y < 0 || y >= iheight)
    return;

  if (image_->hasColormap()) {
    int color_ind;

    gc.getForeground(color_ind);

    image_->drawColorIndexPoint(x, y, color_ind);
  }
  else {
    CRGBA rgba;

    gc.getForeground(rgba);

    image_->drawRGBAPoint(x, y, rgba);
  }
}
<|endoftext|>


<commit_before>/*
    aimbuddylist.cpp - The Less Crappy AIM Buddy List Implementation (TM)

    Copyright (c) 2003 by Nick Betcher <nbetcher@kde.org>
    with copyrighted ideas stolen from Neil Stevens

    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "aimbuddylist.h"

// Project includes
#include "aim.h"

// KDE Includes
#include <kdebug.h>

AIMBuddyList::AIMBuddyList()
	: QObject()
{

}

AIMBuddyList *AIMBuddyList::operator+= (AIMBuddyList &original)
{
	for (int i = 0; i != original.mBuddiesDeny.count(); ++i)
		mBuddiesDeny.append(original.mBuddiesDeny.at(i));

	for (int i = 0; i != original.mBuddiesPermit.count(); ++i)
		mBuddiesPermit.append(original.mBuddiesPermit.at(i));

	for (QMap<QString, AIMBuddy * >::Iterator it = original.mBuddyNameMap.begin(); it != original.mBuddyNameMap.end(); ++it)
	{
		if ((*it))
			if (mBuddyNameMap.find((*it)->screenname()) != mBuddyNameMap.end())
				continue; //already have this in our list

		mBuddyNameMap.insert((*it)->screenname(), (*it));
	}

	for (QMap<int, AIMGroup * >::Iterator it = original.mGroupMap.begin(); it != original.mGroupMap.end(); ++it)
	{
		if ((*it))
			if (mGroupMap.find((*it)->ID()) != mGroupMap.end())
				continue; //already have this in our list

		mGroupMap.insert((*it)->ID(), (*it));
		if (!(*it)->name().isNull())
			mGroupNameMap.insert((*it)->name(), (*it));
	}
	return this;
}

void AIMBuddyList::addBuddy(AIMBuddy *buddy)
{
	mBuddyNameMap.insert(tocNormalize(buddy->screenname()), buddy);
}

void AIMBuddyList::removeBuddy(AIMBuddy *buddy)
{
	mBuddyNameMap.remove(tocNormalize(buddy->screenname()));
	QMap<int, AIMGroup * >::Iterator group = mGroupMap.find(buddy->groupID());
	if (group == mGroupMap.end())
		return;
	(*group)->removeBuddy(buddy);
}

void AIMBuddyList::moveBuddy(AIMBuddy *buddy, AIMGroup *from, AIMGroup *to)
{
	from->removeBuddy(buddy);
	buddy->setGroupID(to->ID());
	to->addBuddy(buddy);
}

AIMBuddy *AIMBuddyList::findBuddy(const QString &name)
{
	QMap<QString, AIMBuddy * >::Iterator it = mBuddyNameMap.find(tocNormalize(name));
	if (it != mBuddyNameMap.end() && (*it))
		return (*it);
	return 0L;
}

AIMGroup *AIMBuddyList::addGroup(const int id, const QString &name)
{
	AIMGroup *group = new AIMGroup(id);
	if (name != QString::null)
	{
		group->setName(name);
		mGroupNameMap.insert(name, group);
	}
	mGroupMap.insert(group->ID(), group);
	emit groupAdded(group);
	return group;
}

void AIMBuddyList::removeGroup(const int id)
{
	AIMGroup *group = mGroupMap[id];
	if (!group) return;
	mGroupNameMap.remove(group->name());
	delete group; // also deletes the buddies in that group too
	mGroupMap.remove(id);
}

AIMGroup *AIMBuddyList::findGroup(const int id)
{
	QMap<int, AIMGroup * >::Iterator it = mGroupMap.find(id);
	if (it != mGroupMap.end() && (*it))
		return (*it);
	return 0L;
}

AIMGroup *AIMBuddyList::findGroup(const QString &name)
{
	QMap<QString, AIMGroup * >::Iterator it = mGroupNameMap.find(name);
	if (it != mGroupNameMap.end() && (*it))
		return (*it);
	return 0L;
}

bool AIMBuddyList::setGroupName(AIMGroup *group, const QString &name)
{
	QMap<QString, AIMGroup * >::Iterator oldgroup = mGroupNameMap.find(name);
	if (oldgroup == mGroupNameMap.end())
	{
		group->setName(name);
		return true;
	}
	return false;
}

void AIMBuddyList::addBuddyPermit(AIMBuddy *buddy)
{
	mBuddiesPermit.insert(buddy->ID(), buddy);
}

void AIMBuddyList::removeBuddyPermit(AIMBuddy *buddy)
{
	mBuddiesPermit.remove(buddy->ID());
}

void AIMBuddyList::addBuddyDeny(AIMBuddy *buddy)
{
	mBuddiesDeny.insert(buddy->ID(), buddy);
}

void AIMBuddyList::removeBuddyDeny(AIMBuddy *buddy)
{
	mBuddiesDeny.remove(buddy->ID());
}

AIMGroup::AIMGroup(const int id)
{
	mGroupID = id;
}

void AIMGroup::removeBuddy(AIMBuddy *buddy)
{
	mBuddies.remove(buddy);
}

bool AIMGroup::addBuddy(AIMBuddy *buddy)
{
	if (buddy->groupID() == mGroupID)
	{
		mBuddies.insert(mGroupID, buddy);
		return true;
	}
	return false;
}

AIMBuddy::AIMBuddy(const int buddyID, const int groupID, const QString &screenName)
{
	mBuddyID = buddyID;
	mGroupID = groupID;
	mScreenName = screenName;
}

AIMBuddyCaps::AIMBuddyCaps()
{
	buddyicon = false;
	voice = false;
	imimage = false;
	chat = false;
	getfile = false;
	sendfile = false;
	games = false;
	savestocks = false;
	sendbuddylist = false;
	games2 = false;
	icq = false;
	apinfo = false;
	icqrtf = false;
	empty = false;
	icqserverrelay = false;
	icqunknown = false;
	trilliancrypt = false;
	last = false;
}

#include "aimbuddylist.moc"
<commit_msg>New buddies now set their initial state to offline via the getOnlineStatus method in oscarprotocol<commit_after>/*
    aimbuddylist.cpp - The Less Crappy AIM Buddy List Implementation (TM)

    Copyright (c) 2003 by Nick Betcher <nbetcher@kde.org>
    with copyrighted ideas stolen from Neil Stevens

    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "aimbuddylist.h"
#include "oscarprotocol.h"

// Project includes
#include "aim.h"

// KDE Includes
#include <kdebug.h>

AIMBuddyList::AIMBuddyList()
	: QObject()
{

}

AIMBuddyList *AIMBuddyList::operator+= (AIMBuddyList &original)
{
	for (int i = 0; i != original.mBuddiesDeny.count(); ++i)
		mBuddiesDeny.append(original.mBuddiesDeny.at(i));

	for (int i = 0; i != original.mBuddiesPermit.count(); ++i)
		mBuddiesPermit.append(original.mBuddiesPermit.at(i));

	for (QMap<QString, AIMBuddy * >::Iterator it = original.mBuddyNameMap.begin(); it != original.mBuddyNameMap.end(); ++it)
	{
		if ((*it))
			if (mBuddyNameMap.find((*it)->screenname()) != mBuddyNameMap.end())
				continue; //already have this in our list

		mBuddyNameMap.insert((*it)->screenname(), (*it));
	}

	for (QMap<int, AIMGroup * >::Iterator it = original.mGroupMap.begin(); it != original.mGroupMap.end(); ++it)
	{
		if ((*it))
			if (mGroupMap.find((*it)->ID()) != mGroupMap.end())
				continue; //already have this in our list

		mGroupMap.insert((*it)->ID(), (*it));
		if (!(*it)->name().isNull())
			mGroupNameMap.insert((*it)->name(), (*it));
	}
	return this;
}

void AIMBuddyList::addBuddy(AIMBuddy *buddy)
{
	mBuddyNameMap.insert(tocNormalize(buddy->screenname()), buddy);
}

void AIMBuddyList::removeBuddy(AIMBuddy *buddy)
{
	mBuddyNameMap.remove(tocNormalize(buddy->screenname()));
	QMap<int, AIMGroup * >::Iterator group = mGroupMap.find(buddy->groupID());
	if (group == mGroupMap.end())
		return;
	(*group)->removeBuddy(buddy);
}

void AIMBuddyList::moveBuddy(AIMBuddy *buddy, AIMGroup *from, AIMGroup *to)
{
	from->removeBuddy(buddy);
	buddy->setGroupID(to->ID());
	to->addBuddy(buddy);
}

AIMBuddy *AIMBuddyList::findBuddy(const QString &name)
{
	QMap<QString, AIMBuddy * >::Iterator it = mBuddyNameMap.find(tocNormalize(name));
	if (it != mBuddyNameMap.end() && (*it))
		return (*it);
	return 0L;
}

AIMGroup *AIMBuddyList::addGroup(const int id, const QString &name)
{
	AIMGroup *group = new AIMGroup(id);
	if (name != QString::null)
	{
		group->setName(name);
		mGroupNameMap.insert(name, group);
	}
	mGroupMap.insert(group->ID(), group);
	emit groupAdded(group);
	return group;
}

void AIMBuddyList::removeGroup(const int id)
{
	AIMGroup *group = mGroupMap[id];
	if (!group) return;
	mGroupNameMap.remove(group->name());
	delete group; // also deletes the buddies in that group too
	mGroupMap.remove(id);
}

AIMGroup *AIMBuddyList::findGroup(const int id)
{
	QMap<int, AIMGroup * >::Iterator it = mGroupMap.find(id);
	if (it != mGroupMap.end() && (*it))
		return (*it);
	return 0L;
}

AIMGroup *AIMBuddyList::findGroup(const QString &name)
{
	QMap<QString, AIMGroup * >::Iterator it = mGroupNameMap.find(name);
	if (it != mGroupNameMap.end() && (*it))
		return (*it);
	return 0L;
}

bool AIMBuddyList::setGroupName(AIMGroup *group, const QString &name)
{
	QMap<QString, AIMGroup * >::Iterator oldgroup = mGroupNameMap.find(name);
	if (oldgroup == mGroupNameMap.end())
	{
		group->setName(name);
		return true;
	}
	return false;
}

void AIMBuddyList::addBuddyPermit(AIMBuddy *buddy)
{
	mBuddiesPermit.insert(buddy->ID(), buddy);
}

void AIMBuddyList::removeBuddyPermit(AIMBuddy *buddy)
{
	mBuddiesPermit.remove(buddy->ID());
}

void AIMBuddyList::addBuddyDeny(AIMBuddy *buddy)
{
	mBuddiesDeny.insert(buddy->ID(), buddy);
}

void AIMBuddyList::removeBuddyDeny(AIMBuddy *buddy)
{
	mBuddiesDeny.remove(buddy->ID());
}

AIMGroup::AIMGroup(const int id)
{
	mGroupID = id;
}

void AIMGroup::removeBuddy(AIMBuddy *buddy)
{
	mBuddies.remove(buddy);
}

bool AIMGroup::addBuddy(AIMBuddy *buddy)
{
	if (buddy->groupID() == mGroupID)
	{
		mBuddies.insert(mGroupID, buddy);
		return true;
	}
	return false;
}

AIMBuddy::AIMBuddy(const int buddyID, const int groupID, const QString &screenName)
{
	mBuddyID = buddyID;
	mGroupID = groupID;
	mScreenName = screenName;
	// By default set it's status to offline
	mStatus = OscarProtocol::protocol()->getOnlineStatus(
	    OscarProtocol::OFFLINE);
}

AIMBuddyCaps::AIMBuddyCaps()
{
	buddyicon = false;
	voice = false;
	imimage = false;
	chat = false;
	getfile = false;
	sendfile = false;
	games = false;
	savestocks = false;
	sendbuddylist = false;
	games2 = false;
	icq = false;
	apinfo = false;
	icqrtf = false;
	empty = false;
	icqserverrelay = false;
	icqunknown = false;
	trilliancrypt = false;
	last = false;
}

#include "aimbuddylist.moc"
<|endoftext|>


<commit_before>#include "csound.hpp"
#include "csPerfThread.hpp"
#include "csPerfThread.cpp"

int useThreads = true;

int main(int argc, char *argv[])
{
    Csound csound;
    csound.Compile(argc,argv);
    csound.Start();
    if (useThreads) {
        CsoundPerformanceThread performanceThread(csound.GetCsound());
        performanceThread.Play();
        performanceThread.Join();
    } else {
        while (csound.PerformKsmps() == 0) {}
    }
 }
<commit_msg>Corrected example.<commit_after>#include "csound.hpp"
#include "csPerfThread.hpp"

int useThreads = true;

int main(int argc, char *argv[])
{
    Csound csound;
    csound.Compile(argc,argv);
    csound.Start();
    if (useThreads) {
        CsoundPerformanceThread performanceThread(csound.GetCsound());
        performanceThread.Play();
        performanceThread.Join();
    } else {
        while (csound.PerformKsmps() == 0) {}
    }
 }
<|endoftext|>


<commit_before><commit_msg>Integrate from upstream at revision 967b64beb4bf.<commit_after><|endoftext|>