Example #1
0
ogl::aabb ogl::node::view(int id, const vec4 *V, int n)
{
    if (!ubiquitous)
    {
        // Get the cached culler hint.

        int bit, hint = get_oct(hint_cache, id);

        // Test the bounding box and set the visibility bit.

        if (V == 0 || my_aabb.test(V, n, M, hint))
            test_cache = set_bit(test_cache, id, (bit = 1));
        else
            test_cache = set_bit(test_cache, id, (bit = 0));

        // Set the cached culler hint.

        hint_cache = set_oct(hint_cache, id, hint);

        // If this node is visible, return the world-space AABB.

        if (bit && V)
            return ogl::aabb(my_aabb, M);
    }
    return ogl::aabb();
}
void GetRegister(const char const* *m_str, PASM_REG m_reg)
{
	const char *m_ptr = *m_str;
	ASM_REG reg = *m_reg;
	int thirdc;
	const char *m_ch;
	
	// 중요 : 이 함수는 다음과 같은 구문은 처리하지 못합니다.
	//	[<num2> + <reg> * <num1>]
	//	[<num1> * <reg> + <num2>]
	//	[<num2>	+ <num1> * <reg>]
	//	[<num1> * <reg>]
	//	[<num1> + <reg>]

	if (reg.isprocess)
		return;
	reg.isprocess = true;
	reg.error = SYNTAX_ERROR::_Not_Found_Error;
	
	//	[<reg> * <num1> + <num2>] 형식일 경우 이 플래그는 활성화됨
	thirdc = FALSE;

	//	상수식 분석
	if ( isdigit(*m_ptr)  ||
	  // isxdigit(*m_ptr) ||
		 *m_ptr == '-'    ||
		 *m_ptr == '+'       )
	{
		const char *foresee = m_ptr + 1;
		int get;
		int radix = 0;

		reg.type = REG_TYPE::_Reg_Numberic;
		
		//	맨 끝의 문자를 확인하기 위해 포인터를 옮김
	 // SkipFunc(&foresee, isspace);
		SkipFunc(&foresee, isxdigit);
	 // SkipFunc(&foresee, isspace);

		if (*foresee == 'o')
			get = get_oct(m_ptr);
		else if (*foresee == 'x')
			get = get_hex(m_ptr);
		else
			get = get_dec(m_ptr);

		reg.first = get;

		m_ptr = foresee + 1;
		goto PROC_END;
	}
	
	//
	//	rxx, exx와 참조형 오퍼랜드를 분석함
	//	디폴트 값은 16bit형 오퍼랜드임
	//
RE:	switch(tolower(*m_ptr))
	{
	case '[':
		reg.type = REG_TYPE::_Reg_Reference;
		SkipWS(&m_ptr);
		m_ptr++;
		goto RE;
	{ case 'e': reg.bit = 32; goto SET; }
 // { case 'r': bit = 64; goto SET; }
	{ default:  reg.bit = 16; break; }
SET:
		if (reg.type != REG_TYPE::_Reg_Reference)
			reg.type = REG_TYPE::_Reg_Normal;
		m_ptr++;
	}
	
	//
	//	exx에서 e을 넘긴 레지스터를 분석함
	//	형식은 모두 16bit로 통일
	//
	switch(tolower(*((m_ch = m_ptr + 1) - 1)))
	{
	case 'a': 
		if      (*m_ch == 'x') reg.first = AX;
		else if (*m_ch == 'l') reg.first = AL;
		else if (*m_ch == 'h') reg.first = AH;
		break;
	case 'b':
		if      (*m_ch == 'p') reg.first = BP;
		else if (*m_ch == 'x') reg.first = BX;
		else if (*m_ch == 'l') reg.first = BL;
		else if (*m_ch == 'h') reg.first = BH;
		break;
	case 'c':
		if      (*m_ch == 'x') reg.first = CX;
		else if (*m_ch == 'l') reg.first = CL;
		else if (*m_ch == 'h') reg.first = CH;
		break;
	case 'd':
		if      (*m_ch == 'i') reg.first = DI;
		else if (*m_ch == 'x') reg.first = DX;
		else if (*m_ch == 'l') reg.first = DL;
		else if (*m_ch == 'h') reg.first = DH;
		break;
	case 's':
		if      (*m_ch == 'p') reg.first = SP;
		else if (*m_ch == 'i') reg.first = SI;
		break;
	}
	
	//
	//	분석했던 레지스터의 총 길이가 2이므로
	//
	m_ptr += 2;
	SkipWS(&m_ptr);

	//
	//	일반 레지스터 형식이면 더 이상 분석할 필요없으니
	//	그냥 끝냄
	//
	if (reg.type == REG_TYPE::_Reg_Normal)
		goto PROC_END;

	//
	//	일반 참조형 레지스터 형식
	//
	if (*m_ptr == ']') {
		reg.type = REG_TYPE::_Reg_SingleReference;
		goto PROC_END;
	}
	
	//
	//	']'를 만나지 않으면 뭔가 더 있는 것임으로
	//
	if (*m_ptr == '+')
		reg.sign = REG_SIGN::_Sign_Plus;
	else if (*m_ptr == '-')
		reg.sign = REG_SIGN::_Sign_Minus;
	else if (*m_ptr == '*')
		reg.sign = REG_SIGN::_Sign_Multiple;
	SkipWS(&m_ptr);

	m_ptr++;

	//
	//	16진수의 문자열일 경우 ffh나, a2h같은 문자가 먼저 나와있을 수 있는데
	//	이 경우엔 분석을 막아 변수로 취급한다. 그로 인해 16진수의 경우엔 
	//	0ffh, 0a2h와 같이 나타내어야 한다.
	//
	if(isdigit(*m_ptr))
	{
		const char * t = m_ptr;
		int get;
		for (; *t != ']' && *t; t++)
			if (*t == '-' || *t == '+') {

				//
				//	[<reg> * <num1> + <num2>] 형식임이 확증됨
				//
				thirdc = TRUE;
				break;
			}

		//
		//	*t == NULL이면 열린 괄호가 닫히지 않았으므로 당연한 오류
		//
		if (!*t--) {
			reg.error = SYNTAX_ERROR::_Not_Find_Comma;
			goto PROC_END;
		}

		//
		//	']'가 나오기 전에 공백이 포함되어있을 수 있으므로
		//
		for (; isspace(*t); t--)
			;

		if (*t == 'o')
			get = get_oct(m_ptr);
		else if (*t == 'h')
			get = get_hex(m_ptr);
		else
			get = get_dec(m_ptr);

		reg.second = get;
		reg.type = REG_TYPE::_Reg_Reference;
		m_ptr = t + 1;

		if (thirdc == TRUE) {
			//
			//	이 코드구역은 상기구역과 동일함
			//
			const char * ptr = t+1;
			int get;
			SkipWS(&m_ptr);

			if (*ptr == '+')
				reg.sign = REG_SIGN::_Sign_Multiple_Plus;
			else if (*ptr == '-')
				reg.sign = REG_SIGN::_Sign_Multiple_Minus;
			SkipWS(&m_ptr);

			for (; *t != ']' && *t; t++)
				;
			
			if (!*t--) {
				reg.error = SYNTAX_ERROR::_Not_Find_Comma;
				goto PROC_END;
			}

			for (; isspace(*t); t--)
				;
			
			if (*t == 'o')
				get = get_oct(m_ptr);
			else if (*t == 'h')
				get = get_hex(m_ptr);
			else
				get = get_dec(m_ptr);

			reg.third = get;
			m_ptr = ptr + 1;
		}
	}

PROC_END:
	*m_reg = reg;
	*m_str = m_ptr;
}