Subversion Repositories Kolibri OS

Rev

Rev 7443 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7389 theonlymir 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
; Hot Angles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4
; Compile with FASM
7459 theonlymir 5
; Version 0.3.7: Oct 14, 2018
7389 theonlymir 6
 
7
; Copyright (c) 2018, Efremenkov Sergey aka TheOnlyMirage
8
; All rights reserved.
9
; Redistribution and use in source and binary forms, with or without modification,
10
; are permitted provided that the following conditions are met:
11
;    * Redistributions of source code must retain the above copyright notice, this
12
;    list of conditions and the following disclaimer.
13
;    * Redistributions in binary form must reproduce the above copyright  notice,
14
;    this list of conditions and the following disclaimer in the documentation and/or
15
;    other materials provided with the distribution.
16
;    * Neither the name of the  nor the names of its contributors may
17
;    be used to endorse or promote products derived from this software without
18
;    specific prior written permission.
19
 
20
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
; INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22
; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
; --------------------------------------------------------------------------------------
27
 
28
format binary as "" ;"kex"
29
use32
30
org 0x0    ; базовый адрес размещения кода, всегда 0x0
31
 
32
UNLOCKd = 0
7436 theonlymir 33
LOCKd   = 1
7459 theonlymir 34
SUPERLOCKd = 2
7389 theonlymir 35
 
36
; заголовок
37
db 'MENUET01'     ;магический идентификатор
38
dd 0x01           ;версия
7436 theonlymir 39
dd START_DEBUG    ;адрес точки старта программы
7389 theonlymir 40
dd I_END          ;адрес конца, по факту размер файла программы
41
dd 0x100000       ;требуемое кол-во памяти для загрузки программы
42
dd 0x7fff0        ;начальное значение регистра esp - адрес конца области стэка так как стэк растет в сторону меньших адресов
43
dd 0, 0           ;адрес строки параметров и адрес строки пути исполняемого файла
44
 
45
 
46
include '../../macros.inc'
47
 
48
START_DEBUG:
49
   call copyKill         ;простейшая защита от повторного запуска
50
   mcall  68, 11         ;инициализация кучи
51
   call loadConfig       ;загружаем конфигурацию приложения
7436 theonlymir 52
 
53
   cmp byte[mode], 0     ;функция отключена - выход
54
   jne @f
55
   mcall -1
56
@@:
7443 theonlymir 57
   ;режим жеста по горячей клавише?
58
   cmp byte[mode], 3 ;подписываемся на интересные нам события в зависимости от режима работы
59
   jne @f
60
   mov ebx, 00000100000000000000000000100010b    ;если да, то подписываемся на клавиши
61
   mcall 40
62
   jmp init03
63
@@:
7436 theonlymir 64
   ;режим активации горячей клавишей?
65
   cmp byte[mode], 2 ;подписываемся на интересные нам события в зависимости от режима работы
66
   jne @f
67
   mov ebx, 00000100000000000000000000100010b    ;если да, то подписываемся на клавиши
7389 theonlymir 68
   mcall 40
7436 theonlymir 69
   jmp init02
70
@@:
71
   ; во всех остальных случаях - классический режим работы
72
   ;mode=1 классический режим работы - реакция при наведении в угол
73
   mov byte[mode], 1
74
   mov ebx, 00000100000000000000000000100000b
75
   mcall 40
76
   jmp init01
7389 theonlymir 77
 
7436 theonlymir 78
 
79
 
80
init02:
81
   mov dword[backAdr], mode02
82
   call setHotKey
83
mode02:
84
   mcall 10
85
   cmp eax, 2     ;обработка нажатия клавиши
86
   je hotkey
87
 
88
   cmp byte[keyState], 0
89
   je mode02
90
   cmp   eax, 6   ;обработка перемещений и нажатия мыши
91
   je    mouse
92
 
93
   jmp mode02
94
 
95
 
96
setHotKey:    ;установить горячую клавишу
97
   push eax ebx ecx edx
98
   xor ecx, ecx
99
   mov cl, byte[keyActivate]  ;нажатие горячей клавиши
100
   mov edx, 0x000
101
   mcall 66, 4, ecx, edx
102
 
103
   ;mov cl, byte[keyActivate]
104
   add cl, 128              ;отпускание горячей клавиши
105
   ;mov edx, 0x000
106
   mcall 66, 4, ecx, edx
107
   pop edx ecx ebx eax
108
   ret
109
 
110
 
111
hotkey:
112
   mcall 2
113
   cmp eax, 1     ;буфер клавиш пуст?
114
   je hotkey.end
115
 
116
   cmp al, 2      ;нас интересует только скан код горячей клавиши, иначе выходим
117
   jne hotkey.end
118
 
119
   cmp ah, byte[keyActivate]   ;если нажата наша горячая клавиша
120
   jne @f
7443 theonlymir 121
 
7459 theonlymir 122
   ;проверки для mode 3
123
   cmp byte[state], SUPERLOCKd
124
   je hotkey.end
7443 theonlymir 125
   cmp byte[keyState], 1
7459 theonlymir 126
   je hotkey.end
7443 theonlymir 127
 
128
   push eax ebx
129
   mcall 37, 0 ;запоминаем текущие(начальные) координаты мыши
130
   ;mov dword[o.x], eax
131
   mov word[o.y], ax
132
   shr eax, 16
133
   mov word[o.x], ax
134
   pop ebx eax
135
 
7436 theonlymir 136
   mov byte[keyState], 1
137
   mov byte[state], UNLOCKd
138
   jmp hotkey.end
139
@@:
140
   push edx
141
   xor edx, edx
142
   mov dl, byte[keyActivate]
143
   add dl, 128
144
   cmp ah, dl   ;если отпущена наша горячая клавиша
145
   jne @f       ;hotkey.end
7459 theonlymir 146
 
7436 theonlymir 147
   mov byte[keyState], 0
148
   mov byte[state], LOCKd
149
@@:
150
   pop edx
151
.end:
7443 theonlymir 152
   jmp dword[backAdr]
7436 theonlymir 153
 
154
 
155
init01:
156
   mov dword[backAdr], mode01
157
mode01:
7389 theonlymir 158
  mov     eax, 10                 ; function 10 : wait until event
159
  mcall                           ; event type is returned in eax
160
 
161
  cmp   eax, 6           ;обработка перемещений и нажатия мыши
162
  je    mouse
163
 
7436 theonlymir 164
  jmp mode01
7389 theonlymir 165
 
7436 theonlymir 166
 
7389 theonlymir 167
mouse:
7436 theonlymir 168
   push ebx
169
   mcall 37, 0   ;получаем текущие координаты мыши
170
   pop ebx
7389 theonlymir 171
 
172
  cmp eax, 0 ;левый верхний угол
173
  jne @f
174
  ; -- здесь вызываем соотв. вызов для левого верхнего угла  (X=0, Y=0)
175
  push ecx
176
  mov ecx, 0
177
  call run_command
178
  pop ecx
179
 
7436 theonlymir 180
  jmp dword[backAdr] ;finish
7389 theonlymir 181
@@:
182
  call get_screen_size ;иначе обновляем размеры экрана
183
 
184
  cmp ax, word[screen.height]    ;Ymouse = Yscreen ?
185
  je Ytrue
186
  ;если Y не равны, то нас интересует Y=0 и X=ScreenWidth (правый верхний угол)
187
 
188
  cmp ax, 0
189
  jne unlockend
190
  shr eax, 16
191
  cmp ax, word[screen.width]
192
  jne unlockend
193
  ; -- здесь вызываем для правого верхенего угла
194
  push ecx
195
  mov ecx, 2
196
  call run_command
197
  pop ecx
198
 
7436 theonlymir 199
  jmp dword[backAdr]
7389 theonlymir 200
Ytrue:
201
  ;если Y равны, то нас интересует X=0 (левый нижний угол) или X=ScreenWidth (правый нижний)
202
  shr eax, 16
203
  cmp ax, 0
204
  jne @f
205
  ; -- X=0, Y = Height  (левый нижний угол)
206
  push ecx
207
  mov ecx, 1
208
  call run_command
209
  pop ecx
7436 theonlymir 210
  jmp dword[backAdr]
7389 theonlymir 211
@@:
212
  cmp ax, word[screen.width]
213
  jne unlockend
214
  ; -- (правый нижний угол)
215
  push ecx
216
  mov ecx, 3
217
  call run_command
218
  pop ecx
219
 
7436 theonlymir 220
  jmp dword[backAdr]
7389 theonlymir 221
 
222
unlockend:
223
  mov byte[state], UNLOCKd
7436 theonlymir 224
  jmp dword[backAdr]
7389 theonlymir 225
 
226
 
7436 theonlymir 227
 
7389 theonlymir 228
;получить размер экрана
229
get_screen_size:
230
   push eax
231
   mcall 14
232
   ;теперь в eax = [xsize]*65536 + [ysize]
233
   ;mov dword[screen], eax
234
   mov word[screen.height], ax
235
   shr eax, 16
236
   mov word[screen.width], ax
237
   pop eax
238
   ret
239
 
240
 
241
 
242
 
7436 theonlymir 243
 
7389 theonlymir 244
;запуск приложения: ecx - активный угол: lu=0, ld=1, ru=2, rd=3
245
run_command:
246
   cmp byte[state], UNLOCKd
247
   jne run_command.end
248
 
7436 theonlymir 249
   push eax ebx ecx
7389 theonlymir 250
 
251
   cmp ecx, 0
252
   jne @f
7459 theonlymir 253
   mov eax, apps.path1 ;dword[newData.lu]
254
   cmp byte[eax], 0 ;если по адресу пусто (или лежал символ '-'), то адрес 0
255
   je .set0
7389 theonlymir 256
   mov dword[struct70.path_adr], eax
7459 theonlymir 257
   mov eax, apps.param1
258
   mov dword[struct70.param_adr], eax
7389 theonlymir 259
   jmp .end_set_path
260
@@:
261
   cmp ecx, 1
262
   jne @f
7459 theonlymir 263
   mov eax, apps.path2 ;dword[newData.ld]
264
   cmp byte[eax], 0 ;если по адресу пусто (или лежал символ '-'), то адрес 0
265
   je .set0
7389 theonlymir 266
   mov dword[struct70.path_adr], eax
7459 theonlymir 267
   mov eax, apps.param2
268
   mov dword[struct70.param_adr], eax
7389 theonlymir 269
   jmp .end_set_path
270
@@:
271
   cmp ecx, 2
272
   jne @f
7459 theonlymir 273
   mov eax, apps.path3 ;dword[newData.ru]
274
   cmp byte[eax], 0 ;если по адресу пусто (или лежал символ '-'), то адрес 0
275
   je .set0
7389 theonlymir 276
   mov dword[struct70.path_adr], eax
7459 theonlymir 277
   mov eax, apps.param3
278
   mov dword[struct70.param_adr], eax
7389 theonlymir 279
   jmp .end_set_path
280
@@:
281
   cmp ecx, 3
7459 theonlymir 282
   jne .set0 ;.end_set_path
283
   mov eax, apps.path4 ;dword[newData.rd]
284
   cmp byte[eax], 0 ;если по адресу пусто (или лежал символ '-'), то адрес 0
285
   je .set0
7389 theonlymir 286
   mov dword[struct70.path_adr], eax
7459 theonlymir 287
   mov eax, apps.param4
288
   mov dword[struct70.param_adr], eax
7389 theonlymir 289
   jmp .end_set_path
7459 theonlymir 290
.set0:
291
   ;mov dword[struct70.path_adr], 0
292
   ;mov dword[struct70.param_adr], 0
293
   jmp @f
7389 theonlymir 294
.end_set_path:
295
   mcall 70, struct70
7416 theonlymir 296
@@:
7389 theonlymir 297
   mov byte[state], LOCKd
7436 theonlymir 298
   ;mov byte[keyState], 0
299
   pop ecx ebx eax
7389 theonlymir 300
.end:
301
   ret
302
 
303
struct70: ;Формат информационной структуры
304
  .func       dd 7 ; номер подфункции
305
  .mask       dd 0
306
  .param_adr  dd 0 ; указатель на ASCIIZ-строку с параметрами
307
  .other      dd 0, 0
7459 theonlymir 308
  .path       db 0
309
  .path_adr   dd 0 ; указатель на строку с путём
7389 theonlymir 310
 
311
;имя конфигурационного файла
7416 theonlymir 312
fileName: db 'SETTINGS/HOTANGLES.CFG', 0
7389 theonlymir 313
 
7459 theonlymir 314
 
315
;проходим до конца текущей строки
316
gotoEndString:
317
   cmp eax, edx  ;если файл закончился, то
318
   ja @f         ;выходим
319
   cmp byte[eax], 10
320
   je @f
321
   cmp byte[eax], 0
322
   je @f
323
   cmp byte[eax], 13
324
   je @f
325
   ;иначе переходим на следующий символ
326
   inc eax
327
   jmp gotoEndString
328
@@:
329
   ret
330
 
331
;пропускаем переносы в начале строки до первого адекватного символа
332
gotoStartString:
333
   cmp eax, edx  ;если файл закончился, то
334
   ja @f         ;выходим
335
   cmp byte[eax], 10
336
   je .next
337
   cmp byte[eax], 0
338
   je .next
339
   cmp byte[eax], 13
340
   je .next
341
   jmp @f ;если это другой символ, то выходим
342
.next:   ;переходим на следующий символ
343
   inc eax
344
   jmp gotoStartString
345
@@:
346
   ret
347
 
348
 
349
sep: db '|' ;символ разделитель строки пути + параметры запуска
350
readPath:
351
   push ebx esi edi
352
   mov bh, 0 ; 0 -  знак того, что параметры ещё не встречались
353
   mov byte[esi], 0   ;проинициализируем буферы-строки пустотой (на всякий случай)
354
   mov byte[edi], 0
355
@@:
356
   cmp eax, edx  ;если файл закончился, то
357
   ja @f         ;выходим
358
   mov bl, byte[eax]
359
   ;если очередной символ не конец строки
360
   cmp bl, 10
361
   je @f  ;иначе выход
362
   cmp bl, 0
363
   je @f
364
   cmp bl, 13
365
   je @f
366
   ;и не начало параметров
367
   cmp bl, byte[sep]
368
   jne .read
369
   ;если sep уже встречали ранее, то
370
   cmp bh, 0
371
   jne .read ;просто продолжаем считывать параметры дальше  (в них может быть что угодно)
372
   ;иначе кладём завершающий 0 и переходим к буферу с параметрами
373
   mov byte[esi], 0
374
   call trim ;ещё не забудем убрать лишние табуляции и пробелы на конце нашей строки
375
   mov esi, edi
376
   mov bh, 1
377
   inc eax
378
   jmp @b
379
.read: ;то записываем символ в наш буфер и переходим на следующий символ
380
   mov byte[esi], bl
381
   inc esi
382
   inc eax
383
   jmp @b
384
@@:
385
   mov byte[esi], 0 ;кладём завершающий ноль
386
   pop edi esi ebx
387
   ret
388
 
389
trim:  ;esi - последний нулевой символ строки
390
   ;push esi
391
   mov byte[esi], 0
392
   dec esi
393
   cmp byte[esi], 8
394
   je trim
395
   cmp byte[esi], 32
396
   je trim
397
   inc esi
398
   ;pop esi
399
   ret
400
 
401
 
402
cfgFileAdr: dd 0     ;адрес конфигурационного файла в памяти
403
 
7389 theonlymir 404
loadConfig:
7416 theonlymir 405
   push eax ebx ecx edx
7389 theonlymir 406
   mcall 68, 27, fileName   ;загружаем конфигурационный файл в ОЗУ
7459 theonlymir 407
   mov dword[cfgFileAdr], eax
7389 theonlymir 408
   cmp eax, 0
409
   je loadConfig.exit       ;если файла конфигурации нет, то завершаем работу приложения
410
   ;иначе данные загружены в ОЗУ, размер в edx
411
   cmp edx, 0               ;если файл пуст, в нём нет данных, то завершаем работу
412
   je loadConfig.exit
413
 
414
   add edx, eax             ;иначе кладём в edx - адрес конца файла
415
 
7436 theonlymir 416
   mov byte[mode], 0
7459 theonlymir 417
   cmp byte[eax], '0'       ;если параметр активности приложения имеет статус: не активно
418
   je loadConfig.exit       ;то завершаем работу приложения
7436 theonlymir 419
   cmp byte[eax], 110 ;'n'
420
   je loadConfig.exit
7389 theonlymir 421
 
7436 theonlymir 422
   ;иначе выставляем режим
7459 theonlymir 423
   cmp byte[eax], 121 ;'y'  ;классический режим
424
   jne @f
425
   mov byte[mode], 1
426
   jmp loadConfig.modeEnd
427
@@:
428
   cmp byte[eax], '1'       ;классический режим
429
   jne @f
430
   mov byte[mode], 1
431
   jmp loadConfig.modeEnd
432
@@:
7436 theonlymir 433
   cmp byte[eax], '2'       ;режим активации по горячей клавише
434
   jne @f
435
   mov byte[mode], 2
436
   jmp loadConfig.modeEnd
437
@@:
438
   cmp byte[eax], '3'       ;режим жеста при зажатой клавише
439
   jne @f
440
   mov byte[mode], 3
441
   jmp loadConfig.modeEnd
442
@@:
7459 theonlymir 443
   mov byte[mode], 0        ;во всех остальных случаях - отключено
444
   jmp loadConfig.exit
7436 theonlymir 445
.modeEnd:
446
 
7459 theonlymir 447
   ;идём до конца этой строки
448
   call gotoEndString
449
   ;находим начало следующей строки
450
   call gotoStartString
7389 theonlymir 451
 
7459 theonlymir 452
   push esi edi
7389 theonlymir 453
 
7459 theonlymir 454
   ;считываем путь для левого верхнего угла
455
   mov esi, apps.path1
456
   mov edi, apps.param1
457
   call readPath
458
   call gotoStartString  ;находим начало следующей строки
7389 theonlymir 459
 
7459 theonlymir 460
   ;считываем путь для левого нижнего угла
461
   mov esi, apps.path2
462
   mov edi, apps.param2
463
   call readPath
464
   call gotoStartString
7416 theonlymir 465
 
7459 theonlymir 466
   ;считываем путь для правого верхнего угла
467
   mov esi, apps.path3
468
   mov edi, apps.param3
469
   call readPath
470
   call gotoStartString
7389 theonlymir 471
 
7459 theonlymir 472
   ;считываем путь для правого нижнего угла
473
   mov esi, apps.path4
474
   mov edi, apps.param4
475
   call readPath
476
   call gotoStartString
7389 theonlymir 477
 
7459 theonlymir 478
   ;call checkAdr ;проверим строки на '-' и пустоту и выставим битовую маску
479
   call checkPathAdr
7389 theonlymir 480
 
7459 theonlymir 481
   pop edi esi
482
 
483
   ;пропускаем строку с именем клавиши
484
   call gotoEndString
485
   call gotoStartString
486
 
487
   ;считываем сканкод активационной клавиши
488
   ;call readKey
489
   ;call gotoEndString
490
   push esi edi ecx
491
   mov esi, keystr
492
   mov edi, keystr
493
   call readPath
494
   ;преобразуем строку в число
495
   mov esi, keystr
496
   call strToInteger
497
   mov byte[keyActivate], cl
498
   pop ecx edi esi
499
   call gotoStartString
500
 
501
   ;считываем радиус
502
   push esi edi ecx
503
   mov esi, radstr
504
   mov edi, radstr
505
   call readPath
506
   ;преобразуем строку в число
507
   mov esi, radstr
508
   call strToInteger
509
   ;теперь ecx - значение радиуса
510
   ;!!! добавить проверку, чтобы число не было больше области экрана
511
   ;нас интересует квадрат числа
512
   push eax edx
513
   mov eax, ecx ;dword[radius2]
514
   mul ecx
515
   mov dword[radius2], eax
516
   pop edx eax
517
 
518
   pop ecx edi esi
519
 
520
   ;считывать размер элементов интерфейса нам не нужно (пока что этот параметр только для конфига)
521
   jmp .end
7389 theonlymir 522
.exit:
7416 theonlymir 523
   pop edx ecx ebx eax
7389 theonlymir 524
   mcall -1 ;закрыть эту программу
525
.end:
7459 theonlymir 526
   mov ecx, dword[cfgFileAdr]    ;если файл был загружен, то
527
   cmp ecx, 0
528
   je @f
529
   mcall 68, 13, ecx  ;выгружаем файл из памяти
530
@@:
7416 theonlymir 531
   pop edx ecx ebx eax
7389 theonlymir 532
   ret
533
 
534
 
7459 theonlymir 535
;readKey:
536
   ;читаем клавишу и выходим
537
;   cmp dword[eax], 'Ctrl'
538
;   jne .notCtrl
539
;   mov byte[keyActivate], 3
540
;   jmp .end
541
;.notCtrl:
542
;   cmp dword[eax], 'Shif'
543
;   jne .notShift
544
;   mov byte[keyActivate], 2
545
;   jmp .end
546
;.notShift:
547
;   cmp dword[eax], 'Spac'
548
;   jne .notSpace
549
;   mov byte[keyActivate], 32
550
;   jmp .end
551
;.notSpace:
552
;   cmp word[eax], 'Al'
553
;   jne .notAlt
554
;   mov byte[keyActivate], 1
555
;   jmp .end
556
;.notAlt:
557
   ;убедимся, что там 1 символ, а не строка
558
;   cmp byte[eax+1], 10
559
;   je .oneSymb
560
;   cmp byte[eax+1], 0
561
;   je .oneSymb
562
;   cmp byte[eax+1], 13
563
;   je .oneSymb
564
;   jmp .default    ;в любом другом случае ошибка конфига - выход
565
;.oneSymb:
566
   ;проверяем, что символ разрешённый  !!!  доделать
7389 theonlymir 567
 
7459 theonlymir 568
   ;добавляем символ как есть
569
;   push ebx
570
;   ;xor ebx, ebx
571
;   mov bl, byte[eax]
572
;   mov byte[keyActivate], bl
573
;   pop ebx
7389 theonlymir 574
 
7459 theonlymir 575
;   jmp .end
576
;.default:
577
;   mcall -1
578
;   ;mov byte[keyActivate], 2
579
;.end:
580
;   ret
581
 
582
 
583
checkPathAdr:
584
   push eax ebx
585
   xor eax, eax
586
 
587
   mov ebx, apps.path1
588
   cmp byte[ebx], '-'
589
   jne @f
590
   ;cmp byte[ebx+1], 0
591
   ;jne @f
592
   mov byte[ebx], 0
593
@@:
594
   mov ebx, apps.path2
595
   cmp byte[ebx], '-'
596
   jne @f
597
   ;cmp byte[ebx+1], 0
598
   ;jne @f
599
   mov byte[ebx], 0
600
@@:
601
   mov ebx, apps.path3
602
   cmp byte[ebx], '-'
603
   jne @f
604
   ;cmp byte[ebx+1], 0
605
   ;jne @f
606
   mov byte[ebx], 0
607
@@:
608
   mov ebx, apps.path4
609
   cmp byte[ebx], '-'
610
   jne @f
611
   ;cmp byte[ebx+1], 0
612
   ;jne @f
613
   mov byte[ebx], 0
614
@@:
615
   pop ebx eax
616
   ret
617
 
618
 
619
checkAdr:
620
   push eax ebx
621
   xor eax, eax
622
 
623
   mov ebx, apps.path1
624
   cmp byte[ebx], '-'
625
   jne @f
626
   inc eax
627
@@:
628
   mov ebx, apps.path2
629
   cmp byte[ebx], '-'
630
   jne @f
631
   add eax, 2
632
@@:
633
   mov ebx, apps.path3
634
   cmp byte[ebx], '-'
635
   jne @f
636
   add eax, 4
637
@@:
638
   mov ebx, apps.path4
639
   cmp byte[ebx], '-'
640
   jne @f
641
   add eax, 8
642
@@:
643
 
644
   mov ebx, apps.param1
645
   cmp byte[ebx], '-'
646
   jne @f
647
   add eax, 16
648
@@:
649
   mov ebx, apps.param2
650
   cmp byte[ebx], '-'
651
   jne @f
652
   add eax, 32
653
@@:
654
   mov ebx, apps.param3
655
   cmp byte[ebx], '-'
656
   jne @f
657
   add eax, 64
658
@@:
659
   mov ebx, apps.param4
660
   cmp byte[ebx], '-'
661
   jne @f
662
   add eax, 128
663
@@:
664
 
665
   mov byte[apps.bits], al
666
   pop ebx eax
667
   ret
668
 
669
 
670
 
671
;преобразование строки в целое число
672
strToInteger: ;вход: esi - указатель на строку с десятичной записью числа, выход: eсx - число
673
   push eax ebx edx edi
674
   xor eax, eax  ;обнуляем eax
675
   xor ecx, ecx
676
   mov edi, esi
677
.get_last_symbol:
678
   ;читаем очередной символ
679
   mov al, byte[edi]
680
 
681
   ;если это ноль, то строка закончилась
682
   cmp al, 0
683
   je @f
684
 
685
   ;иначе переходим на следующий символ
686
   inc edi
687
   jmp .get_last_symbol
688
@@:   ;дошли до последнего символа и кладём адрес на него в edi
689
   dec edi
690
 
691
   cmp edi, esi    ;адрес последнего символа должен быть дальше адреса первого символа
692
   jae @f
693
   jmp .error  ;иначе ошибка
694
@@:
695
   ;теперь в edi последний символ, а esi указывает на начало строки (на первй символ строки)
696
   mov cl, byte[edi]
697
   sub cl, 48 ;0x30 ;'0'
698
   dec edi         ;переходим на след символ от конца
699
   mov ebx, 10     ;множитель степени
700
.tranform_cicle:
701
   cmp edi, esi        ;если больше нет символов строке, то число преобразовали - выходим
702
   jb .end
703
 
704
   mov eax, 0
705
   mov al, byte[edi]
706
   sub al, 48 ;'0'
707
   cmp al, 9 ;0x39           ;если число больше 9, то видимо в строке было что-то не так
708
   ja .error
709
   cmp al, 0 ;0x30           ;если число меньше 0, то видимо в строке было что-то не так
710
   jb .error
711
   mov edx, 0
712
   mul ebx
713
 
714
   add ecx, eax
715
 
716
   dec edi
717
   mov edx, 0
718
   mov eax, 10
719
   mul ebx
720
   mov ebx, eax
721
   jmp .tranform_cicle
722
.error:
723
   mov ecx, 0
724
.end:
725
   pop edi edx ebx eax
726
   ret
727
 
728
 
7389 theonlymir 729
;Вынести код ниже в отдельный общий модуль
730
selfName db '@HOTANGLES',0
731
selfNameSize = 10 ;до 11 byte
732
;
733
compareBytes:
734
   push edi esi ecx ebx
7436 theonlymir 735
   xor eax, eax
7389 theonlymir 736
   mov ecx, selfNameSize    ;max размер строк 11
737
@@:
738
   mov bl, byte[edi]
739
   cmp bl, byte[esi]
740
   jne compareBytes.no
741
   inc edi
742
   inc esi
743
   cmp ecx, 0
744
   je @f
745
   dec ecx
746
   jmp @b
747
.no:
748
   mov eax, 1
749
@@:
750
   pop ebx ecx esi edi
751
   ret
752
;
753
copyKill:
754
   push eax ebx ecx esi edi
755
 
756
   ;сперва прочтём свою информацию
757
   mcall 9, buf, -1
758
   mov eax, dword[buf+30]
759
   mov dword[selfPID], eax
760
 
761
   ;указатели, которые никогда не меняются:
762
   mov esi, selfName       ;первая строка - имя текущего приложения
763
   mov edi, buf            ;вторая строка - имя текущего слота
764
   add edi, 10
765
 
766
   mov ecx, 1
767
@@:
768
   mcall 9, buf, ecx
769
   mov dword[slotMax], eax
770
 
771
   ;если это мы сами, то пропускаем проверку
772
   mov eax, dword[buf+30]
773
   cmp eax, dword[selfPID]
774
   je copyKill.propusk
775
 
776
   call compareBytes   ;сравниваем 11 байт строк, результат в eax
777
 
778
   cmp eax, 0
779
   je copyKill.selfKill
780
 
781
.propusk:
782
   inc ecx
783
   cmp ecx, dword[slotMax]
784
   ja @f
785
   jmp @b
786
 
787
.selfKill:
788
   pop edi esi ecx ebx eax
789
   mcall -1
790
   ret
791
@@:
792
   pop edi esi ecx ebx eax
793
   ret
794
 
795
 
7443 theonlymir 796
;MODE 3
797
init03:
7459 theonlymir 798
   ;mov dword[radius2], 100; 10*10
7443 theonlymir 799
   mov dword[backAdr], mode03
800
   call setHotKey
801
mode03:
802
   mcall 10
803
   cmp eax, 2     ;обработка нажатия клавиши
804
   je hotkey
805
 
806
   ;cmp byte[keyState], 0
807
   ;je mode03
808
   cmp   eax, 6   ;обработка перемещений и нажатия мыши
809
   je    mouse03
810
 
811
   jmp mode03
812
 
813
mouse03:
814
   cmp byte[keyState], 0     ;если клавиша не зажата, то обновим начальные координаты
815
   je mouse03.updateCoord
816
 
817
   cmp byte[state], LOCKd    ;если угол заблокирован, то обновим начальные координаты
818
   je mouse03.updateCoord
819
 
7459 theonlymir 820
   cmp byte[state], SUPERLOCKd  ;если действие было выполнено и получили блокировку, то ждём отпускания клавиши активации
821
   je @f
822
 
7443 theonlymir 823
   call checkPointInCircle   ;иначе если преодолели радиус активации, то вызываем действие нужного угла
824
   jmp @f
825
.updateCoord:
826
   push eax ebx
827
   mcall 37, 0 ;запоминаем текущие(начальные) координаты мыши
828
   ;mov dword[o.x], eax
829
   mov word[o.y], ax
830
   shr eax, 16
831
   mov word[o.x], ax
832
   pop ebx eax
833
@@:
834
   jmp dword[backAdr]
835
 
836
 
837
radius2 dd 0  ;квадрат радиуса для mode 3
838
o:            ;координаты начальной и текущей точки
839
 .x:   dw 0
840
 .y:   dw 0
841
 .cx:  dw 0
842
 .cy:  dw 0
843
 
844
;проверка выхода за пределы круга
845
; sqrt( (x2-x1)^2 + (y2-y1)^2 ) <= radius
846
; (x2-x1)^2 + (y2-y1)^2 <= radius^2
847
checkPointInCircle:
848
   push eax ebx ecx edx
849
   mcall 37, 0 ;получаем текущие координаты мыши
850
   ;mov dword[o.cx], eax
851
   mov word[o.cy], ax
852
   shr eax, 16
853
   mov word[o.cx], ax
854
 
855
   xor eax, eax
856
   xor edx, edx
857
   mov ax, word[o.x]
858
   mov dx, word[o.cx]
859
   cmp dx, ax
860
   jae @f
861
   sub ax, dx
862
   mov dx, ax
863
   jmp .xend
864
@@:
865
   sub dx, ax
866
.xend:
867
   mov eax, edx
868
   mul dx
869
 
870
   mov ebx, eax
871
 
872
   xor eax, eax
873
   xor edx, edx
874
   mov ax, word[o.y]
875
   mov dx, word[o.cy]
876
   cmp dx, ax
877
   jae @f
878
   sub ax, dx
879
   mov dx, ax
880
   jmp .yend
881
@@:
882
   sub dx, ax
883
.yend:
884
   mov eax, edx
885
   mul dx
886
 
887
   add ebx, eax
888
 
889
   cmp ebx, dword[radius2]
890
   jbe @f
891
   call activateCorner ;иначе активируем нужный угол
892
 @@:
893
   pop edx ecx ebx eax
894
   ret
895
 
896
;выяснить в сторону какого угла ушли и активировать его
897
activateCorner:
898
   push eax ecx
899
   xor eax, eax
900
 
901
   mov ax, word[o.cx]
902
   cmp ax, word[o.x]
903
   je activateCorner.end       ;если координата равна, то выходим (такого быть не должно)
904
   ja activateCorner.right
905
 
906
   ;иначе левая сторона
907
   mov ax, word[o.cy]
908
   cmp ax, word[o.y]
909
   je activateCorner.end       ;если координата равна, то выходим (такого быть не должно)
910
   jb activateCorner.leftup
911
 
912
   ;иначе левый нижний угол
913
   mov ecx, 1
914
   call run_command
915
   mov byte[keyState], 0
7459 theonlymir 916
   mov byte[state], SUPERLOCKd
7443 theonlymir 917
   jmp activateCorner.end
918
 
919
.leftup:
920
   ;левый верхний угол
921
   mov ecx, 0
922
   call run_command
923
   mov byte[keyState], 0
7459 theonlymir 924
   mov byte[state], SUPERLOCKd
7443 theonlymir 925
   jmp activateCorner.end
926
 
927
.right: ;правая сторона экрана
928
   mov ax, word[o.cy]
929
   cmp ax, word[o.y]
930
   je activateCorner.end       ;если координата равна, то выходим (такого быть не должно)
931
   jb activateCorner.rightup
932
 
933
   ;иначе правый нижний угол
934
   mov ecx, 3
935
   call run_command
936
   mov byte[keyState], 0
7459 theonlymir 937
   mov byte[state], SUPERLOCKd
7443 theonlymir 938
   jmp activateCorner.end
939
 
940
.rightup:
941
   ;правый верхний угол
942
   mov ecx, 2
943
   call run_command
944
   mov byte[keyState], 0
7459 theonlymir 945
   mov byte[state], SUPERLOCKd
7443 theonlymir 946
   jmp activateCorner.end
947
 
948
.end:
949
   pop ecx eax
950
   ret
951
 
952
 
953
 
7436 theonlymir 954
keyActivate db 41 ;16 ;'Q' ;клавиша активации
7443 theonlymir 955
keyState    db 0  ;0-клавиша не активна, 1 - клавиша активна
7389 theonlymir 956
 
7443 theonlymir 957
backAdr rd 1      ;адрес для возврата из проверки мыши
7436 theonlymir 958
slotMax rd 1
959
selfPID rd 1
960
buf rb 1024
961
 
962
;структурка данных для хранения параметров экрана
963
screen:
7443 theonlymir 964
  .width  rw 1
965
  .height rw 1
7436 theonlymir 966
 
7459 theonlymir 967
state: rb 1  ;состояние: 0=unlock, 1=lock, 2=superlock for mode 3
7436 theonlymir 968
mode:  rb 1  ;режим работы приложения: 0=не работает, 1=классический, 2=по горячей клавише
969
 
970
 
7459 theonlymir 971
keystr: rb 4 ;строка со значением сканкода активационной клавиши
972
radstr: rb 5 ;строка со значением радиуса
973
apps:
974
 .bits: rb 1
975
 .path1: rb 512
976
 .path2: rb 512
977
 .path3: rb 512
978
 .path4: rb 512
979
 .param1: rb 512
980
 .param2: rb 512
981
 .param3: rb 512
982
 .param4: rb 512
983
appsEnd:
984
 
985
 
7389 theonlymir 986
I_END: