Дополнительные возможности ввода/вывода в DirectInput.

Сразу оговорюсь, что этот типс был написан по принципу «давно уже ничего не писал, а написать хоть про что-то нужно». Не отчаивайтесь, о том какие статьи на подходе Вы сможет прочитать в разделе «Новости», а пока займемся DI.

Не смотря на то что мы в этом направлении сделали уже очень многое (укротили мышь и «клаву»), есть ещё один аспект ввода/вывода, с которым неплохо бы разделаться. Насколько мне помнится у меня в коде состояния клавиатуры и мыши мониторились каждый кадр. Сколько там времени уходит на отрисовку одного кадра? Где-то в районе 0.025с. А теперь представьте что вы вводите текст – нажимаете кнопку «А», программа рисует кадр, узнает кнопку, которую Вы нажали , записывает информацию об этом куда-то, затем снова узнает кнопку, которую Вы нажали... и так раз десять, до тех пор пока Вы не отпустите клавишу «А». В итоге получаем красивую такую строчку из 10 букв «А». Ах Вы хотели только одну "А" напечатать?!?! Ну тогда нажимаем клавишу «BackSpace» и все по-новой :) (у одного моего знакомого один раз запал «BackSpace»... IDE пожирающая программу – жуткое зрелище надо признаться). Выхода как всегда два – правильный и не очень. Тот что «не очень» заключается в том что бы жать на кнопку не дольше 0.025с. Всего делов! Уверен, что такой способ ввода текста Вам очень быстро надоест и Вы обратитесь к своим исходникам с намерением что-то подправить. Результатом таких «подправлений» может стать нижеследующий код:


bool			cKeyboard::GetKeyboardUpState( void ){
	if( !Buffer ){
		MessageBox( 0 , "Девайс не инициализирован!" , "Ошибка" , 0 );
		return( false );
	}
	if( !BackBuffer ){
		BackBuffer = new char[ 256 ];
		memset( BackBuffer , NULL , 256 );
	}

	memcpy( BackBuffer , Buffer , 256 );
	memset( Buffer , NULL , 256 );

	if( DIKeyboard->GetDeviceState( 256 , ( LPvoid ) Buffer ) != DI_OK ){
		MessageBox( 0 , "Ошибка чтения состояния клавиатуры." , "Ошибка" , 0 );
		return( false );
	}
	return( true );
}

void			cMouse::GetMouseUpState( void ){
	if( !DIMouse ){
        		MessageBox( 0 , "Девайс не инициализирован!" , "Ошибка" , 0 );
		exit( 0 );
	}
    
	memcpy( &BACK_DIMOUSEINPUT2 , &STD_DIMOUSEINPUT2 , sizeof( STD_DIMOUSEINPUT2 ) );
	memset( &STD_DIMOUSEINPUT2 , NULL , sizeof( STD_DIMOUSEINPUT2 ) );

	if( DIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ) , &STD_DIMOUSEINPUT2 ) != DI_OK ){
		MessageBox( 0 , "Ошибка чтения состояния мыши." , "Ошибка" , 0 );
		exit( 0 );
	}
}
Ну и соответственно обновленные функции для просмотра состояния конкретной кнопки.

bool			cMouse::GetButtonUpState( int mb ){

	if( !DIMouse ){
        		MessageBox( 0 , "Мышь не инициализирована." , "Ошибка" , 0 );
		exit( 0 );
	}

	return( ( ! ( STD_DIMOUSEINPUT2.rgbButtons[ mb ] & 0x80 ) ) && 
		( BACK_DIMOUSEINPUT2.rgbButtons[ mb ] & 0x80 ) );
}
Аналогично для клавиатуры

bool			cKeyboard::GetButtonUpState( char Button ){
	if( !Buffer || !BackBuffer ){
		MessageBox( 0 , "Клавиатура не инициализирована." , "Ошибка" , 0 );
		return( false );
	}

	return( ( !( Buffer[ Button ] & 0x80 ) ) && 
		( BackBuffer[ Button ] & 0x80 ) );
}
Как видно из кода у нас есть некий «задний буфер» в котором хранится состояние кнопок на ПРЕДУДУЩЕЙ итерации. Функции же GetButtonUpState возвращают true если мы отпустили кнопку (т.е. на предыдущей итерации она нажата, а на текущей уже нет).

Вот вроде и все хитрости... Если возникнут проблемы, то Вы знаете как со мной связаться.


Смежные вопросы:
Урок 10. Direct Input. Мышь.
Урок 11. Direct Input. Клавиатура.
Исходные коды.
© 2004-2005 Savardge.ru


Hosted by uCoz