some optimisation

git-svn-id: svn://kolibrios.org@1652 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Alexey Teplov ( 2010-10-11 10:31:26 +00:00
parent 93ace30f65
commit f999b6faa8
3 changed files with 159 additions and 97 deletions

View File

@ -103,9 +103,9 @@ macro edit_boxes_set_sys_color start,end,color_table
} }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Basic macros for use CheckBox ; ;Basic macros for use CheckBox ;
;Last change 03.10.2010 ;Last change 11.10.2010 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ch_struc_size=36 ;ðàçìåð ñòðóêòóðû ch_struc_size=32 ;đŕçěĺđ ńňđóęňóđű
ch_flag_en=10b ;флаг установленного чек бокса. ch_flag_en=10b ;флаг установленного чек бокса.
ch_left_s equ [ebp] ;кордината начала рисования по х ch_left_s equ [ebp] ;кордината начала рисования по х
@ -115,10 +115,9 @@ ch_color equ [ebp+12] ;
ch_border_color equ [ebp+16] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно ch_border_color equ [ebp+16] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно
ch_text_color equ [ebp+20] ;[edi+4] ;цвет текста ch_text_color equ [ebp+20] ;[edi+4] ;цвет текста
ch_text_ptr equ [ebp+24] ;указатель на начало текстовой строки ch_text_ptr equ [ebp+24] ;указатель на начало текстовой строки
ch_text_length equ [ebp+28] ;äëèííà ñòðîêè ch_flags equ [ebp+28] ;ôëŕăč
ch_flags equ [ebp+32] ;ôëàãè
struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,ch_text_length,flags struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,flags
{ ;структура параметров для чек бокса { ;структура параметров для чек бокса
.left_s: dd left_s ;+0 положение по х dw + размер dw .left_s: dd left_s ;+0 положение по х dw + размер dw
.top_s: dd top_s ;+4 положение по у dw + размер dw .top_s: dd top_s ;+4 положение по у dw + размер dw
@ -127,7 +126,6 @@ struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,c
.border_color: dd border_color ;цвет рамки .border_color: dd border_color ;цвет рамки
.text_color: dd text_color ;цвет надписи .text_color: dd text_color ;цвет надписи
.text: dd text ;адрес в коде программы где расположен текст .text: dd text ;адрес в коде программы где расположен текст
.ch_text_length: dd ch_text_length ;äëèííà ñòðîêè ñ ñèìâîëàìè
.flags: dd flags+0 ; флаги .flags: dd flags+0 ; флаги
} }

View File

@ -129,14 +129,14 @@ aCheck_box_draw db 'check_box_draw',0
aCheck_box_mouse db 'check_box_mouse',0 aCheck_box_mouse db 'check_box_mouse',0
aVersion_ch db 'version_ch',0 aVersion_ch db 'version_ch',0
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
check1 check_box (10 shr 16 + 12),(45 shr 16 + 12),6,0x80AABBCC,0,0,check_text,14,ch_flag_en check1 check_box (10 shr 16 + 12),(45 shr 16 + 12),6,0x80AABBCC,0,0,check_text,ch_flag_en
check2 check_box (10 shr 16 + 12),(60 shr 16 + 12),6,0x80AABBCC,0,0,check_text2,15 check2 check_box (10 shr 16 + 12),(60 shr 16 + 12),6,0x80AABBCC,0,0,check_text2
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
hed db 'CheckBox Exemples <Lrz> date 03.10.2010',0 hed db 'CheckBox Exemples <Lrz> date 03.10.2010',0
hed_end: hed_end:
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
check_text db 'First checkbox' check_text db 'First checkbox',0
check_text2 db 'Second checkbox' check_text2 db 'Second checkbox',0
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
MEM_END: MEM_END:
cur_dir_path rb 1024 cur_dir_path rb 1024

View File

@ -6,71 +6,88 @@
macro use_checkbox_draw macro use_checkbox_draw
{ {
check_box_draw: check_box_draw:
pusha ;сохраним все регистры pushad ;сохраним все регистры
; mov edi,dword [esp+36] mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
; mov ebx,ch_left_s ; mov ebx,ch_left_s
; mov ecx,ch_top_s ; mov ecx,ch_top_s
; mov edx,dword ch_border_color ; mov edx,dword ch_border_color
; mov eax,13 ; mov eax,13
; mcall ;рисуем рамку ; mcall ;рисуем рамку
mcall 13,ch_left_s,ch_top_s,ch_border_color mcall 13,ch_left_s,ch_top_s,ch_border_color ;рисуем рамку чек бокса, фактически рисуем прямоугольник и закрашиваем фон внутри цветом рамки бокса
mov edx,dword ch_color mov edx,dword ch_color ;загружаем цвет фона
add ebx,1 shl 16 - 2 add ebx,1 shl 16 - 2
add ecx,1 shl 16 - 2 add ecx,1 shl 16 - 2
mcall ;закрашиваем внутренности чекбокса mcall ;закрашиваем внутренности чекбокса фоном
test dword ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF test dword ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF
jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@ jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@
call check_box_draw_ch ;нарисовать включенный чек бокс call check_box_draw_ch ;нарисовать включенный чек бокс
@@: @@:
;---------------------------- ;----------------------------
;расчет куда будет произведен вывод текста ;расчет куда будет произведен вывод текста
;---------------------------- ;----------------------------
mov ebx,ch_left ;загрузить значение х для чек бокса ; mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
add ebx,dword ch_size ; add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
add ebx,dword ch_text_margin ;добавить размер стороны и расстояние на котором начнется вывод текста ; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) ; add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
mov bx,word ch_top ;загрузим значение по y
add ebx,ch_size
mov ecx,dword ch_text_color ;загрузим цвет надписи + flags
sub ebx,7 ;добавим значение длины стороны -9+2
; mov eax,word ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса
; shl eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y
; Оптимизация для ЦП
mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
mov eax,dword ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса
add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
shl eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y
add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
shr eax,16 ;для y поместим в младшую часть
mov bx,ax ;внесем смещение для y
mov ecx,dword ch_text_color ;загрузим цвет надписи + flags
mov edx,dword ch_text_ptr ;укажем адрес от куда нужно выводить строку mov edx,dword ch_text_ptr ;укажем адрес от куда нужно выводить строку
mov esi,dword ch_text_length
mov eax,4 ;внесем в eax значение вывода надписи на канву mov eax,4 ;внесем в eax значение вывода надписи на канву
mcall ;Вывод mcall ;Вывод
popa ;восстановить значения регистров из стека popad ;восстановить значения регистров из стека
ret 4 ;выйдем из процедуры ret 4 ;выйдем из процедуры и удалим из стека указатель на структуру (4 байта)
check_box_clear_ch: ;очистка чек бокса check_box_clear_ch: ;очистка чек бокса
mov edx,dword ch_color ;цвет внутри чек бокса mov edx,dword ch_color ;цвет внутри чек бокса
jmp @f ;безусловный прыжок на нижнюю метку @@ jmp @f ;безусловный прыжок на нижнюю метку @@
check_box_draw_ch: ;нарисовать включенный чек бокс check_box_draw_ch: ;нарисовать включенный чек бокс
mov edx,dword ch_border_color ;загрузить цвет mov edx,dword ch_border_color ;загрузить цвет
@@: @@:
movzx ebx,word ch_left ;загрузить координату по х ; movzx ebx,word ch_left ;загрузить координату по х
mov eax,dword ch_size ; mov eax,dword ch_size
mov di,ax ; mov di,ax
shr eax,2 ; shr eax,2
push ax ; push ax
;
; push ax
; add ebx,eax
; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; pop ax
; lea eax,[eax*2]
; sub bp,ax ;сохраним регистр bx в регистре указателя базы
; mov bx,bp
push ax ; movzx ecx,word ch_top ;загрузить координату по у
add ebx,eax ; pop ax
shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) ; add cx,ax
pop ax ; shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
lea eax,[eax*2] ; mov cx,bp ;загрузим значения регистра указателя базы в cx
sub bp,ax ;сохраним регистр bx в регистре указателя базы ; mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс
mov bx,bp ; mcall ;вывод
movzx ecx,word ch_top ;загрузить координату по у mov ebx,dword ch_left_s
pop ax mov ecx,dword ch_top_s
add cx,ax add ebx,1 shl 16 - 4
shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) add ecx,1 shl 16 - 4
mov cx,bp ;загрузим значения регистра указателя базы в cx mcall 13
mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс ret
mcall ;вывод
ret ;выйти из процедуры
} }
@ -79,58 +96,105 @@ macro use_checkbox_mouse
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Обработчик mouse ;Обработчик mouse
; При попадании мышки + нажата клавиша в область checkbox состояние бокса должно менятся активный - не активный.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
check_box_mouse: ;обработка мыши check_box_mouse: ;обработка мыши
pusha pushad
mov edi,dword [esp+36] mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
mov eax,37 ;будем что то делать если у нас что - нить нажато mcall 37,2 ;проверяем состояние клавиш мышки. Было ли событие нажатая клавиша на мышке.
mov ebx,2 ;внести в регистр значение 2 test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем
mcall ;проверка не нажал ли пользователь кнопку мышки jnz @f ;перейти на нижнюю метку @@, если в eax не 0.
test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем ; and dword ch_flags,eax ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
jnz @f ;перейти на нижнюю метку @@ jmp .check_box_mouse_end ;обработка закончилась
btr dword ch_flags,2 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. ; Да событие: нажатие клавиши мышки произошло.
jmp check_box_mouse_end
@@: @@:
bts dword ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено mcall 37,1 ;получить координаты курсора относительно окна
jc check_box_mouse_end ;если CF=1 то перейти в конец т.е. это выход ;на выходе в eax x shl 16 + y
mov esi,dword ch_text_length ;загрузить кол-во символов в текстовой строке ;сравнение верхней точки по Y
mov ecx,dword ch_top_s ;y shl 16 +длинна по y
mov ebx,ecx
shr ebx,16 ;bx = координата по y
cmp ax,bx
jb .check_box_mouse_end ;указатель мышки меньше начальной координаты по y чем координата по Y у бокса
;сравнение нижней точки по Y
add cx,bx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y
cmp ax,cx
ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса
;сравнение по начальной точке Х
mov ecx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
mov ebx,ecx
shr ebx,16 ;bx = координата по X
cmp ax,bx
jb .check_box_mouse_end ;указатель мышки меньше начальной координаты по X чем координата по X у бокса
;сравнение конечной точки по X
add bx,cx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y
add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
mov ecx,dword ch_text_ptr ;укажем адрес строки с терминируещим 0
push eax
;подсчет длинны строки и увеличение прямогольника в котором срабатывает щелчок мышки
lodsb
test al,al
jz .ex_loop
@@:
add bx,6 ;ширина символа
lodsb
test al,al
jnz @b
.ex_loop:
pop eax
cmp ax,bx
ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса
;если все проверки были успешно пройдены мы обязаны поменять состояние бокса
btc dword ch_flags,2 ;перенос 2-го бита в cf и инверсия его
jc .enable_box ;если CF=1 то отобразим включенный бокс и выйдем
push dword .check_box_mouse_end ;фокус -покус, вернемся после вызова check_box_clear_ch на метку check_box_mouse_end
jmp check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
.enable_box:
call check_box_draw_ch ;отобразить включенный чек бокс
; bts dword ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено
; jc check_box_mouse_end ;если CF=1 то перейти в конец т.е. это выход
; mov esi,dword ch_text_length ;загрузить кол-во символов в текстовой строке
;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea
lea esi,[eax*3] ; lea esi,[eax*3]
shl esi,1 ; shl esi,1
; imul esi,6 ; или можно и так умножить на 6 ; imul esi,6 ; или можно и так умножить на 6
add esi,dword ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи ; add esi,dword ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи
mov eax,37 ;получим координаты мышки ; mov eax,37 ;получим координаты мышки
mov ebx,1 ;добавить 1 ; mov ebx,1 ;добавить 1
mcall ;получить координаты курсора относительно окна ; mcall ;получить координаты курсора относительно окна
movzx ebx,word ch_top ;загрузить в bx значение координаты у ; movzx ebx,word ch_top ;загрузить в bx значение координаты у
cmp ax,bx ;сравнить с с координатой курсора ; cmp ax,bx ;сравнить с с координатой курсора
jl check_box_mouse_end ;SF <> OF если меньше ; jl check_box_mouse_end ;SF <> OF если меньше
add ebx,dword ch_size ;добавить размер ; add ebx,dword ch_size ;добавить размер
cmp ax,bx ;сравнить ; cmp ax,bx ;сравнить
jg check_box_mouse_end ;ZF = 0 и SF = OF если больше ; jg check_box_mouse_end ;ZF = 0 и SF = OF если больше
shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений ; shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений
movzx ebx,word ch_left ;произведем аналогичное сравнение ; movzx ebx,word ch_left ;произведем аналогичное сравнение
cmp ax,bx ;сравнить регистры ; cmp ax,bx ;сравнить регистры
jl check_box_mouse_end ;если меньше ; jl check_box_mouse_end ;если меньше
add ebx,dword ch_size ;добавить длину стороны прямоугольника ; add ebx,dword ch_size ;добавить длину стороны прямоугольника
add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу ; add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу
cmp ax,bx ;стравнить регистры ; cmp ax,bx ;стравнить регистры
jg check_box_mouse_end ;если больше ; jg check_box_mouse_end ;если больше
bts dword ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1. ; bts dword ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1.
jc @f ;CF=1 то перейти на нижнюю @@ ; jc @f ;CF=1 то перейти на нижнюю @@
call check_box_draw_ch ;отобразить включенный чек бокс ; call check_box_draw_ch ;отобразить включенный чек бокс
; mov dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0 ; mov dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0
jmp check_box_mouse_end ;выйти ; jmp check_box_mouse_end ;выйти
@@: ;@@:
btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. ; btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
call check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона. ; call check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
check_box_mouse_end: .check_box_mouse_end:
popa ;восстановить регистры из стека popad ;восстановить регистры из стека
ret 4 ;выйти ret 4 ;выйти
} }