Разработка программы рисования линий с помощью мыши

Примечаниеот редактора: только текстовые файлы
Загрузить архив:
Файл: ref-24059.zip (509kb [zip], Скачиваний: 24) скачать

ВВЕДЕНРР•

         Мой курсовой проект посвящается созданию программы, рисующей линии между контурными точками, расставляемыми в местах, где была нажата левая кнопка мыши. Это простейший пример, способный показать, что для демонстрации некоторых функций работы мыши актуальным является применение языка программирования «Ассемблер».

Мышь – устройство ввода, получившее очень большую популярность. Трудно представить себе современный компьютер без мыши или эквивалентного ей указывающего устройства. В качестве эквивалентного устройства может быть планшетка или разного рода сенсорные площадки, где управление осуществляется пластмассовым карандашом или непосредственно пальцем пользователя.


1 ОБЩРР™ РАЗДЕЛ

Устройство для ручного РІРІРѕРґР° графической информации РІ вычислительную машину, лишь РјРЅРѕРіРѕ позже получившее СЃРІРѕС‘ современное название, было придумано, сконструировано Рё запатентовано Дугласом Энгельбартом РёР· Стэнфордского университета РІ середине 60-ых РіРѕРґРѕРІ прошлого века. Энгельбарт, известный также как автор графического пользовательского интерфейса Рё РѕРґРёРЅ РёР· первых разработчиков гипертекстовой "РЅРёРІС‹", был пионером, так что дальше довольно РіСЂРѕРјРѕР·РґРєРѕРіРѕ Рё неудобного прототипа его мысль РЅРµ пошла. Честь превращения мыши РёР· РєРѕСЂРѕР±РєРё РЅР° РґРІСѓС… наружных колёсах РІ конструкцию, которую сегодня уже начинают забывать - коробочку СЃ шариком, также вращавшим пару роликов, РЅРѕ помещённых внутри - принадлежит работникам лаборатории Xerox PARC, сделавшим это РІ начале 70-ых РіРі. Наконец, облекли мышку РІ привлекательную внешне форму Рё выпустили РЅР° массовый рынок исследователи швейцарского РќРР СЃ труднопроизносимым названием (сокращаемым РґРѕ EPFL), работавшие РІ организованной РёРјРё Рё знакомой сегодня каждому компании Logitech.

 Шли годы, менялись внешний вид и количество кнопок (в конструкции Энгельбарта была только одна клавиша, и этот вариант был сравнительно популярен, в частности, на платформе Mac), а принцип работы манипулятора оставался прежним. Шарик собирал пыль, механическая конструкция была инерционной и неточной, и неудивительно, что в один прекрасный день в чью-то светлую голову пришла идея избавиться от механики, переложив задачу слежения за движениями руки пользователя на плечи электроники и оптики. Ранний период развития варианта мыши, получившей название оптической, связывают с именем неутомимого американского предпринимателя Стивена Кирша (известного, в частности, как основатель Infoseek Corp.). Это он придумал и запатентовал в начале 80-ых годов манипулятор, определявший направление движения с помощью простого оптического сенсора. Мышь Кирша могла работать только на специальном металлическом коврике, покрытом сеткой тёмных полос: она освещала коврик и следила за яркостью отражений, определяя траекторию по пересечениям полос.  

Ранняя эта конструкция так и не получила массового признания. Потребовались ещё почти двадцать лет развития электроники, для того чтобы оптические мыши смогли составить конкуренцию своим механическим предкам. Впрочем, современные оптические мыши устроены во многом схоже с киршевской. Они включают три основных элемента: светодиод, освещающий рабочую площадку, оптический сенсор в виде простейшей матрицы светочувствительных элементов (похожей на матрицу в цифровых фотоаппаратах, но значительно меньшего разрешения - примерно 16 х 16 пикселей), и сигнальный микропроцессор (DSP), умеющий распознавать образы. "Фотографируя" поверхность под собой полторы тысячи раз в секунду, оптическая мышь с помощью чипа DSP улавливает смещения картинки и подаёт соответствующие сигналы компьютеру. Работают такие мыши практически на любой поверхности, исключая лишь зеркальные, полированные и поверхности с крупноволокнистой фактурой. Точность позиционирования, почти нулевая инерционность, отсутствие необходимости в чистке - всё это помогло оптическим мышам вытеснить своих предшественниц с рабочих столов.  Рздесь мы подходим к тому, с чего всё собственно и началось. Уже знакомая вам компания Logitech представила на минувшей неделе компьютерную мышь новой конструкции. Строго говоря, Logitech MX1000 Laser Cordless Mouse относится к оптическому племени, но вместо светодиода в ней установлен миниатюрный полупроводниковый лазер, улучшена разрешающая способность фотосенсора. Принцип действия остался прежним, так что посвящать ему отдельный абзац нет необходимости. Чем лазерная мышь лучше оптической? Абсолютной неприхотливостью: она способна работать даже на зеркале благодаря свойствам лазерного излучения и новой оптической системе. Тем же самым она обязана и непревзойдённой точности: MX1000 различает в 20 раз больше деталей, чем обычная оптическая мышь. Стоит такая машинка почти 80 долларов. Вопрос в том, считать ли лазерную мышь Logitech новой ветвью на эволюционном древе (авторитет компании - аргумент в пользу) или это обычный маркетинговый ход с добавлением никому не нужной функции, для того чтобы выделиться средь толпы производителей? В самом деле, зачем вам двадцатикратное улучшение и без того более чем приемлемой точности?

В В В В В В В В 


2 РћРџРРЎРђРќРР• УСТРОЙСТВА

2.1 РћРџРРЎРђРќРР• МЫШР

         Популярность мышек заставила производителей серьезно задуматься о модернизации своих продуктов. В результате мы получили несколько типов мышек: механических, оптических, беспроводных оптических, беспроводных механических. В механических мышках для определения расстояния, на которое она переместилась, используются механические системы оповещения, в которых механическое вращение вертикальной, горизонтальной и диагональной осей преобразуются в сигналы, передаваемые на контроллер. В оптических мышках используются мощный светодиод, по отражению луча которого от поверхности, на которой находится мышка рассчитывается расстояния, на которое она переместилась,. Наличием колесика прокрутки уже трудно кого-либо удивить, зато в списках рейтингов можно увидеть мультимедийные мышки, сочетающие в себе все приемущества передовых разработок. При использовании такой мышки каждый палец задействован в работе для ее удобства и ускорения. Теперь без лишних движений мыши вы можете сворачивать, разворачивать, закрывать окна, управлять проигрывателем музыки или видео. При просмотре изображений вы можете без затруднения пролистывать их, изменять размеры и т. п.

Мышь состоит из 3-х частей: внешней оболочки (обычно пластмассовой, в области которой находятся кнопки и колесики прокрутки), блока микросхем (имеет прямое подключение к порту компьютера, передает сигналы от мыши), механической или оптической части (служит для определения расстояния, на которое мышь переместилась).

         Современная мышь смогла избавить нас от рутинной работы, лишних движений и таких неприятных вещей как чистка механических элементов от накопившейся грязи…

В В В В В В В В  РќРµ трудно догадаться, что для такого набора функций понадобятся нестандартные драйверы, (система может установить СЃРІРѕРё версии, РЅРѕ РѕРЅРё предназначены для использования лишь стандартных функций. РџРѕ-умолчанию (РІ самых последних версиях операционных систем, таких как WindowsXP, WindowsLonghorn) эти драйверы РјРѕРіСѓС‚ использовать левую, правую РєРЅРѕРїРєРё, колесико прокрутки Рё РґРѕ РґРІСѓС… РєРЅРѕРїРѕРє навигации для упрощения работы РІ сети Рнтернет.). РС… можно найти РІ РєРѕСЂРѕР±РєРµ СЃ устройством. Эти драйверы позволяют мышку работать корректно Рё использовать полный спектр функций, предусмотренных производителем. Р’ панели управления РЅР° вкладке «Мышь» становятся доступными настройки новых функций.

2.2 ПРОГРАММНАЯ МОДЕЛЬ МЫШР

      Все общение с мышью в DOS выполняется через прерывание ЗЗh,обработчик которого устанавливает драйвер мыши, загружаемый обычно при запуске сис­темы. Современные драйверы поддерживают около 60 функций, позволяющих настраивать разрешение мыши, профили ускорений, виртуальные координаты, дополнительные обработчики событий и т. п. Большинство этих функций требу­ются редко, сейчас рассмотрим основные.

INT33h, РђРҐ=0: Рнициализация мыши Р’С…РѕРґ:В В В В  РђРҐ = OOOOhВыход:В В  РђРҐ = OOOOh, если мышь или драйвер мыши РЅРµ установлены

АХ = OFFFFh, если драйвер и мышь установлены

ВХ = число кнопок:

2 или OFFFFh - две

3 - три

0000 - другое количество Выполняется аппаратный и программный сброс мыши и драйвера.

INT33h, AX=1: Показать курсор Вход:     АХ - 000 lh

INT33h, AX= 2: Спрятать курсор Вход:     АХ = 0002h

Драйвер мыши поддерживает внутренний счетчик, управляющий видимостью курсора мыши. Функция 2 уменьшает значение счетчика на единицу, а функция 1 увеличивает его, но только до значения 0. Если значение счетчика - отрицатель­ное число, он спрятан, если ноль - показан. Это позволяет процедурам, использу­ющим прямой вывод в видеопамять, вызывать функцию 2 в самом начале и 1 в са­мом конце, не заботясь о том, в каком состоянии был курсор мыши у вызвавшей эту процедуру программы.

INT33h, AX= 3: Определить состояние мыши Вход:     АХ - ОООЗhВыход:   ВХ - состояние кнопок:

бит 0. нажата левая кнопка

бит 1: нажата правая кнопка

бит 2: нажата средняя кнопка

РЎРҐ

DX

Х-координата

Y-координата

Возвращаемые координаты совпадают с координатами пикселов соответству­ющей точки на экране в большинстве графических режимов, «роме 04, 05, ODh, 13h, где Х-координату мыши нужно разделить на 2, чтобы получить номер стол­бца соответствующей точки на экране. В текстовых режимах oбе координаты надо разделить на 8 для получения номера строки и столбца соответственно.

В большинстве случаев эта функция не используется в npoграммах, так как для того, чтобы реагировать на нажатие кнопки или перемещение мыши в заданную область, требуется вызывать это прерывание постоянно, что приводит к трате процессорного времени. Функции 5 (определить положение курсора при после­днем нажатии кнопки), 6 (определить положение курсора при последнем отпус­кании кнопки) и OBh (определить расстояние, пройденное мшью) могут помочь оптимизировать работу программы, самостоятельно «следящей» за всеми пере­движениями мыши, но гораздо эффективнее указать драйверу контролировать ее передвижения (чем он, собственно, и занимается постоянно) и передавать управ­ление в программу, как только выполнится заранее определенное условие, напри­мер пользователь нажмет на левую кнопку мыши. Такой сервис обеспечивает функция 0Сh- установить обработчик событий.

INT 33h, AX= 0Сh: Установить обработчик событий Вход:      АХ = 000Ch

ES:DX = адрес обработчика СХ = условие вызова

бит 0: любое перемещение мыши

бит 1: нажатие левой кнопки

бит 2: отпускание левой кнопки

бит 3: нажатие правой кнопки

бит 4: отпускание правой кнопки

бит 5: нажатие средней кнопки

бит 6: отпускание средней кнопки СХ = 0000h - отменить обработчик

Обработчик событий должен быть оформлен, как дальняя процедура (то есть завершаться командой RETF). На входе в процедуру обработчика АХ содержит условие вызова, ВХ - состояние кнопок, СХ, DX - Х- и У-координаты курсора, SI, DI - счетчики последнего перемещения по горизонтали и Вертикали (едини­цы измерения для этих счетчиков - мики, 1/200 дюйма), DS - сегмент данных драйвера мыши. Перед завершением программы установленный обработчик со­бытий должен быть обязательно удален (вызов функции 0Сhс СХ= 0). так как иначе при первом же выполнении условия управление будет передано по адресу в памяти, с которого начинался обработчик.

Функция 0Сh используется так часто, что у нее появилось несколько модифи­каций - функция 14h, дающая возможность установить одновременно три обра­ботчика с разными условиями, и функция 18h, также позволяющая установить


3 РАЗРАБОТКА АЛГОРРРўРњРђ УПРАВЛЕНРРЇ МЫШЬЮ

         Схема обработки прерываний:

Внешнее устройство

Процессор

Контроллер прерываний

Шина данных

Внешнее устройство

Внешнее устройство

Внешнее устройство

NMI

INTA

INTR


         Обработка прерываний осуществляется с помощью специального процессора, производящего предварительную обработку запросов на прерывания. Выбирается запрос с наибольшим приоритетом, а затем уже обращается к процессору, т.е. на выходе INTRподключен контроллер прерываний, а к нему уже подключается внешнее устройство. Немаскируемое прерывание связано с процессором. Таймер обращается к процессору напрямую. Запрос на прерывание внешнее устройство посылает на контроллер прерываний , который затем посылает запрос по линии INTRна процессор, анализирующий флаг прерывания, если он равен 1, то по линии INTAидет подтверждение готовности обработать запрос. После этого через шину данных контроллер прерываний формирует команду INTс соответствующим номером прерывания. Далее процессор обрабатывает эту команду и передает управление на обработчик прерывания, который взаимодействует с устройством, вызвавшим это прерывание через шину данных и адреса, а также через порты, к которым подсоединено устройство и его контроллер.


4 РАЗРАБОТКА РРЕАЛРР—РђР¦РРЇ ПРОГРАММНОГО ОБЕСПЕЧЕНРРЇ

       Для работы моей программы требуется IBM совместимый компьютер на базе процессора Intel и любая возможная техническая конфигурация для запуска операционной системы DOS. Программа занимает не более 500 байт оперативной памяти. Также потребуется предварительно откомпилированный исполняемый файл программы. Пользователю нужно запустить программу и нажать левую кнопку мышки в разных местах экрана для проверки работоспособности программы. Если между точками в которых были произведены нажатия рисуются лини, то программа работает корректно.

В В В В В В  Рсходный РєРѕРґ программы представлен РІ приложении Рђ.

       Блок-схема представлена в приложении Б.

В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В В 


5 ОТЛАДКА Р РСПЫТАНРР• ПРОГРАММЫ

         Перед запуском программы следует убедиться в том, что к компьютеру подсоединена мышь, включить компьютер, запустить программу в 16-битной среде, нажать левую кнопку мыши в разных местах экрана. Программа может работать некорректно при условии несоблюдения вышеуказанных условий.

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


ЗАКЛЮЧЕНРР•

         В процессе выполнения данного курсового проекта я ознакомился с устройствами разных типов мышек, с их программными моделями. Научился писать простейшее программное обеспечение, использующее некоторые функции мыши. Разработал алгоритм управления устройством, написал, отладил и экспериментально проверил функциональность программы.


Р›РТЕРАТУРА

1.         Абель П. и программирования/ Пер. с англ. Ю. В. Сальникова.- М.: Высш. Шк. 1992г. – 447с.: ил.

2.А. Жуков, А. Авдохин «Assembler».-Спб: БХВ – Петербург, 2002..

3. Архитектура РІРІРѕРґР°-вывода персональных Р­Р’Рњ IBM PC РџРѕРґ pедакцией Р®. РЎ. Лукача (C) РнженеpРЅРѕ-техническое Р±СЋpРѕ, 1990

4. В. Юров «Assembler» Практикум.-Спб.:Питер, 2001.

5. В. Юров «Assembler» Учебник.-Спб.:Питер, 2001.

6. РСЂРІРёРЅ, РљРёРї. Язык Ассемблера для процессоров Intel, 3-Рµ издание: Пер. СЃ англ. - Рњ.: Рздательский РґРѕРј «Вильямс», 2002.-616СЃ.: РёР». - Парал. РўРёС‚. РђРЅРіР».

7.Рспользование Turbo Assembler РїСЂРё разработке программ / РЎРѕСЃС‚. Рђ. Рђ. Чекатков.-Киев:Диалектика,1995.-228СЃ

Приложение А

; mousedr.asm

; Рисует на экране прямые линии с концами в позициях, указываемых мышью

В В В В В В В В  .modelВ В В В В В В  tiny

В В В В В В В В  .code

start:

В В В В В В В В  movВ  ax,12h

         int     10h             ; видеорежим 640x480

         mov  ax,0            ; инициализировать мышь

В В В В В В В В  intВ В В В  33h

         mov  ax,1            ; показать курсор мыши

В В В В В В В В  intВ В В В  33h

         mov  ax,000Ch   ; установить обработчик событий мыши

         mov  cx,0002h    ; событие - нажатие левой кнопки

         mov  dx,offset handler ; ES:DX - адресобработчика

В В В В В В В В  intВ В В В  33h

         mov  ah,0            ; ожидание нажатия любой клавиши

В В В В В В В В  intВ В В В  16h

В В В В В В В В  movВ  ax,000Ch

         mov  cx,0000h    ; удалить обработчик событий мыши

В В В В В В В В  intВ В В В  33h

         mov  ax,3            ; текстовый режим

В В В В В В В В  intВ В В В  10h

         ret                        ; конец программы

; Обработчик событий мыши: при первом нажатии выводит точку на экран,

; при каждом дальнейшем вызове проводит прямую линию от предыдущей точки к

; текущей

handler:

В В В В В В В В  pushВ  0A000h

         pop   es                ; ES - начало видеопамяти

В В В В В В В В  pushВ  cs

         pop   ds               ; DS - сегмент кода и данных этой программы

         push  cx               ; CX (X-координата) и

         push  dx               ; DX (Y-координата) потребуются в конце

         mov  ax,2            ; спрятать курсор мыши перед выводом на экран

В В В В В В В В  intВ В В В  33h

         cmp   word ptr previous_X,-1         ; если это первый вызов,

         je       first_point           ; только вывести точку,

         call    line_bresenham             ; иначе - провести прямую

exit_handler:

         pop   dx                        ; восстановить CX и DX

В В В В В В В В  popВ В  cx

         mov  previous_X,cx              ; и запомнить их как предыдущие

         mov  previous_Y,dx              ; координаты

         mov  ax,1            ; показать курсор мыши

В В В В В В В В  intВ В В В  33h

         retf                       ; выход из обработчика - команда RETF

first_point:

         call    putpixel1b  ; вывод одной точки (при первом вызове)

В В В В В В В В  jmp short exit_handler

; Процедура рисования прямой линии с использованием алгоритма Брезенхама

; Ввод: CX,DX - X, Y конечной точки

; previous_X,previous_Y - X, Y начальнойточки

В 

line_bresenham:

В В В В В В В В  movВ  ax,cx

         sub    ax,previous_X     ; AX = длина проекциипрямойнаось X

         jns     dx_pos                          ; если AX отрицательный -

         neg    ax                                  ; сменить его знак, причем

         mov  word ptr X_increment,1         ; координата X при выводе

         jmp short dx_neg                   ; прямой будет расти,

dx_pos:      mov  wordptrX_increment,-1 ; а иначе - уменьшаться

dx_neg:В В В В В  movВ  bx,dx

         sub    bx,previous_Y     ; BX = длина проекции прямой на ось Y

         jns     dy_pos                          ; если BX отрицательный -

         neg    bx                                  ; сменить его знак, причем

         mov  word ptr Y_increment,1         ; координата Y при выводе

         jmp short dy_neg                   ; прямой будет расти,

dy_pos:      mov  word ptr Y_increment,-1        ; а иначе - уменьшаться

dy_neg:

         shl     ax,1            ; удвоить значения проекций,

         shl     bx,1            ; чтобы избежать работы с полуцелыми числами

         call    putpixel1b  ; вывести первую точку (прямая рисуется от

; CX,DX Рє previous_X,previous_Y

         cmp   ax,bx          ; если проекция на ось X больше, чем на Y:

В В В В В В В В  jnaВ В В В  dx_le_dy

         mov  di,ax           ; DI будет указывать, в какую сторону мы

         shr    di,1             ; отклонились от идеальной прямой

         neg    di                ; оптимальное начальное значение DI:

В В В В В В В В  addВ В В  di,bxВ В В В В В В В В В  ; DI = 2 * dy - dx.

cycle:

         cmp   cx,word ptr previous_X         ; основнойциклвыполняется,

         je       exit_bres              ; пока X не станет равно previous_X

         cmp   di,0                                ; если DI > 0,

В В В В В В В В  jlВ В В В В В  fractlt0

         add    dx,word ptr Y_increment       ; перейтикследующему Y

         sub    di,ax                              ; и уменьшить DI на 2 * dx

fractlt0:

         add    cx,word ptr X_increment       ; следующий X (на каждом шаге)

         add    di,bx                    ; увеличить DI на 2 * dy

         call    putpixel1b           ; вывести точку

         jmp short cycle             ; продолжить цикл

dx_le_dy:                      ; если проекция на ось Y больше, чем на X

В В В В В В В В  movВ  di,bx

В В В В В В В В  shrВ В В  di,1

         neg    di                ; оптимальное начальное значение DI:

В В В В В В В В  addВ В В  di,axВ В В В В В В В В В  ; DI = 2 * dx - dy

cycle2:

         cmp   dx,word ptr previous_Y        ; основнойциклвыполняется,

         je       exit_bres              ; пока Y нестанетравным previous_Y,

         cmp   di,0                                ; если DI > 0

В В В В В В В В  jlВ В В В В В  fractlt02

         add    cx,word ptr X_increment       ; перейтикследующему X

         sub    di,bx                              ; и уменьшить DI на 2 * dy

fractlt02:

         add    dx,word ptr Y_increment       ; следующий Y (на каждом шаге)

         add    di,ax                    ; увеличить DI на 2 * dy

         call    putpix ось Y больше, чем на X

В В В В В В В В  movВ  di,bx

В В В В В В В В  shrВ В В  di,1

         neg    di                ; оптимальное начальное значение DI:

В В В В В В В В  addВ В В  di,axВ В В В В В В В В В  ; DI = 2 * dx - dy

cycle2:

         cmp   dx,word ptr previous_Y        ; основнойциклвыполняется,

         je       exit_bres              ; пока Y нестанетравным previous_Y,

         cmp   di,0                                ; если DI > 0

В В В В В В В В  jlВ В В В В В  fractlt02

         add    cx,word ptr X_increment       ; перейтикследующему X

         sub    di,bx                              ; и уменьшить DI на 2 * dy

fractlt02:

         add    dx,word ptr Y_increment       ; следующий Y (на каждом шаге)

         add    di,ax                     ; увеличить DI на 2 * dy

         call    putpixi,ax            ; поместить его в SI и DI для команд

         mov  si,di            ; строковой обработки

         pop   cx               ; CX снова содержит номер столбца

В В В В В В В В  movВ  bx,0080h

         and    cx,07h        ; последние три бита CX =

; остаток от деления на 8 =

; номер бита в байте, считая справа налево

         shr    bx,cl           ; теперь в BL установлен в 1 нужный бит

         lods   es:byte ptr some_label  ; AL = байт из видеопамяти

         or      ax,bx          ; установить выводимый бит в 1

; чтобы стереть пиксель с экрана, эту команду OR можно заменить на

; notbx

; andax,bx

; или лучше инициализировать BX не числом 0080h, а числом FF7Fh и ; использовать только and

         stosb                    ; и вернем байт на место

         popa                    ; восстановим регистры

         ret                        ; конец

previous_X          dw     -1      ; предыдущая X-координата

previous_Y          dw     -1      ; предыдущая Y-координата

Y_increment        dw     -1      ; направление изменения Y

X_increment        dw     -1      ; направление изменения X

some_label:                            ; метка, используемая для переопределения

; сегмента-источника для lods с DS на ES

В В В В В В В В  endВ В В  start

Приложение Б

Начало

Точка входа

Переключение видеорежима

Рнициализация мыши

Конец

Установка обработчика событий мыши

Рисование

В РїСЂСЏРјРѕР№

Блок-схема: