#1
31 декабря 2007 в 13:33
Без библиотеки DirectInput:<br /><br />http://msdn2.microsoft.com/en-us/library/bb206183(VS.85).aspx<br /><br />Как плюс такой реализации - непосредственное чтение событий от мышиного драйвера, исключение дополнительной библиотеки и дополнительного программного потока, выполняющегося параллельно с основной программой.<br />Смысл DirectInput в чтении событий WM_INPUT, т.е. работает через механизм описанный выше, на самом деле.<br /><br />Так что у кого там лаги с мышкой были? ;) Ну же, Barnes, Берсеркер - бонусы-то серьёзные, а совместимость 100%-я! Реализация строчек десять, больше кода вырезается чем вставляется. А самое клёвое, что не нужно каждый кадр опрашивать состояние мыши - мышь сама сообщит об изменениях! Задержки соответсвенно около нуля, как в дос играх :D.
#3
03 января 2008 в 05:07
Че то не компилицо, ни метод WM_INPUT, ни через DirectInput :(
#4
17 октября 2008 в 14:08
Имеет ли вообще какой-либо смысл ускорение мыши (m_accel)? т.е. умножение дельты смещения мышки на некую величину, зависящую от этого самого смещения?<br /><br />Точности это не прибавляет, совершенно точно. На малых смещениях с мышью низкого разрешения ещё что-то, но при больших смещениях точности никакой. Уж лучше пусть выдаёт лесенку. Я хочу высказать мнение что единственное, что имеет смысл, это раздельный скаляр для X и Y смещений. Если мышь выдаёт лесенку, то это повод её сменить на более точную но никак не говорит о том, что алгоритм баллистики плохой. Это значит у вас мышь худая. Дешёвая офисная мышь за 200 рублей имеет разрешение 400dpi, у меня дома один лишь десктоп требует 2000dpi. Стратегии тоже 2000dpi. В играх от первого лица, где требуется вращать камеру использую все 2500dpi на которые способна мышь. Сколько раз я ни переделывал обработчик мыши, каждый раз останавливался на самом простом варианте:<br /><br />
<br />void IN_MouseMove (usercmd_t *cmd)<br />{<br /> if (!mouseactive) return;<br /> cl.viewangles[YAW] -= m_yaw->value * mouse_x;<br /> mouse_x = 0;<br /> cl.viewangles[PITCH] += m_pitch->value * mouse_y;<br /> mouse_y = 0;<br />}<br />
<br /><br />m_filter, m_accel, sensitivity не имеют никакого значения кроме как искажения так называемого RAW потока событий от мышки.
#5
17 октября 2008 в 20:01
я так и не понял в свое время смысла фильтра мыши... <br />а про разрешение мыши я по скромнее) 1600 достаточно<br />да и восьмисот тоже. А я всеж рисую на работе на техже 400 ;)<br />и ниче, кроме глюкофф самой мыши все ок ;)
#6
17 октября 2008 в 21:04
Судя по реализации, фильтр мыши (m_filter) уменьшает вдвое ступенчатость баллистической траектории, хотя и это я поставил бы под большое сомнение, но абсолютно чётко на примерно половину кадра снижает чувствительность мыши. Это просто недопустимо. У меня всё время витают идеи как бы использовать повышенную частоту опроса состояния мыши, теоретически это даст лучшую управляемость, но для этого надо отвязать физику от рендера, пустить их параллельными потоками. Скажем, рендер на сколько тянет монитор, физику и HID на 200 полных циклов в секунду, звук на примерно 20 полных циклов в секунду. Нужно понимать, что всякая подсистема в конечном счёте привязана к конкретной железке у которой своё время регенерации. Так, звук привязан к размеру буфера звуковухи, изображение к развёртке монитора, физика - если подумать, физика привязана к устройствам ввода. Тупо прогонять единый регенерирующий цикл имеет смысл примерно при 20 fps, это было нормой во времена первого софт-quake, далее гораздо выгоднее разъединять подсистемы. Разгонять звук и видео нет никакого смысла, нагрузки колоссальные а эффект минимальный, опять же про-геймеры разгоняя устройства ввода до 200 fps вынуждены тянуть за собой разгон прочих подсистем квейка до аналогичной скорости :o. Это всё равно как разгонять поезд толкая его сзади, толкая и вагоны и локомотив.<br /><br />Требование к разрешению мыши растёт с увеличением разрешения монитора, у меня 1920х1200, 800 dpi никак не тянет, все настройки увеличения чувствительности на максимуме и после всех этих алгоритмов компенсации недостачи dpi мышь становится тягучая-тягучая, курсор как на резиновой нити бегает. То, что это терпимо, это исключительно самовнушение, мне тоже было жалко мою logitech mx310, удобней её я не встречал, тактильно приятная, но вдвое более дешёвая китайская народная a4tech XL-750BF с лёгкостью уделала бренд без всяких оговорок.
#7
17 октября 2008 в 22:27
willow пишет:<br />
Судя по реализации, фильтр мыши (m_filter) уменьшает вдвое ступенчатость баллистической траекторииm_filter включает интерполяцию движения мыши, то есть курсор не обновляется в новую позицию каждую секунду, а как бы движется в направлении этой новой позиции. Отсюда и эффект "отставания". В некоторых играх кстати он вполне терпим.<br /><br />
Имеет ли вообще какой-либо смысл ускорение мыши (m_accel)? т.е. умножение дельты смещения мышки на некую величину, зависящую от этого самого смещения? Точности это не прибавляет, совершенно точно.<br />А и не должно, акселерация мыши сделана чтобы уменьшить количество движения рукой для радикального перемещения курсора из одной позиции экрана в другую. Если говорить о "лесенке" то m_accel по теории этот эффект должен усугублять. Ускорение мыши в винде включено по умолчанию.<br /><br />
Скажем, рендер на сколько тянет монитор, физику и HID на 200 полных циклов в секунду, звук на примерно 20 полных циклов в секундуQuakeWorld, Ку2 и все более поздние движки уже давно этот велосипед используют. В ку2 физика идет на постоянном фреймрейте в 20 FPS.
#8
17 октября 2008 в 22:39
q2world ща испльзует асинхрон что позволяет при 60 фпс исп физику как на 120 фпс<br />
#9
19 октября 2008 в 19:53
Значит так, провёл некоторое время над изучением вопроса. Начнём с понимания того, что событие WM_MOUSEMOVE имеет строгое ограничение для использования исключительно в 2D окнах. Если вы заметили, то возвращаются абсолютные координаты, ибо только они и имеют смысл. MS чётко указывает, что скорость движения мыши никак не соотносится с тем, с какой скоростью вы двигаете мышь. Используется баллистика курсора применительно к рабочему столу!! Даже берсовский m_xpfix = 1 на самом деле пшик и реально делает мало, напротив, это подрывная работа по перенастройке рабочего стола, линейная скорость мыши же по-прежнему не гарантируется. Также не гарантируются получение полных DPI самой мыши, т.к. разрешение мыши масштабируются под рабочий стол. Если вы не любитель приключений, то для вас уже давно создано событие WM_INPUT, которое возвращает непосредственно значения смещений, рапортуемые мышью. Я офигиваю, товарищи, как мы любим создавать сами себе проблемы и потом винить во всех проблемах бесконечно икающего Билла. Нужно исправляться, лучше поздно чем никогда.<br /><br />Вот мой код (на примере Berserker@Quake2)<br /><br />Инициализация:<br />
<br /> #ifndef HID_USAGE_PAGE_GENERIC<br /> #define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)<br /> #endif<br /> #ifndef HID_USAGE_GENERIC_MOUSE<br /> #define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)<br /> #endif<br /><br /> RAWINPUTDEVICE Rid[1];<br /> Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;<br /> Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;<br /> Rid[0].dwFlags = RIDEV_INPUTSINK;<br /> Rid[0].hwndTarget = cl_hwnd; //hWnd главного окна<br /> RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));<br />
<br /><br />Этот фрагмент кода разрешает передачу RAW событий от мыши, а именно WM_INPUT. Как следствие, пересоздавая окно, необходимо разрешать приём RAW событий от мыши.<br /><br />Стандартный обработчик событий для главного окна (MainWndProc):<br /><br /> case WM_INPUT: <br /> {<br /> UINT dwSize = 40;<br /> static BYTE lpb[40];<br /> <br /> GetRawInputData((HRAWINPUT)lParam, RID_INPUT, <br /> lpb, &dwSize, sizeof(RAWINPUTHEADER));<br /> <br /> RAWINPUT* raw = (RAWINPUT*)lpb;<br /> <br /> if (raw->header.dwType == RIM_TYPEMOUSE) <br /> {<br /> mousex += raw->data.mouse.lLastX;<br /> mousey += raw->data.mouse.lLastY;<br /> } <br /> break;<br /> }<br />
<br /><br />А теперь, собственно, обработка мыши, весь бред убран ибо является чушью с точки зрения про-игрока, остался только регулятор чувствительности мыши и новая переменная для инверсии мыши по оси Y, специально для тех, кто переиграл в авиасимуляторы. Это как левши и права меньшинств всё-таки надо уважать.<br /><br />void IN_MouseMove (usercmd_t *cmd)<br />{<br /> if (mouseactive)<br /> {<br /> cl.viewangles[YAW] -= sensitivity->value * mouse_x;<br /> mouse_x = 0;<br /> if (m_inversion->value)<br /> cl.viewangles[PITCH] -= sensitivity->value * mouse_y;<br /> else<br /> cl.viewangles[PITCH] += sensitivity->value * mouse_y;<br /> mouse_y = 0;<br /> }<br />}<br />
<br /><br />Что я могу сказать, теперь Bers@Q2 по части мыши рулит, по крайней мере для меня 8).
#10
20 октября 2008 в 03:34
Похоже придется выпустить апдейт за номером 1.09 ;)