Rev 529 | Rev 1754 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
31 | halyavin | 1 | ;****************************************************************************** |
2 | ; MAIN MENU by lisovin@26.ru |
||
3 | ; Some parts of code rewritten by Ivan Poddubny |
||
4 | ; |
||
5 | ; Compile with FASM for Menuet |
||
6 | ;****************************************************************************** |
||
7 | include "lang.inc" |
||
485 | heavyiron | 8 | include "..\..\..\macros.inc" |
31 | halyavin | 9 | |
10 | BTN_HEIGHT = 22 |
||
11 | TXT_Y = (BTN_HEIGHT)/2-5 |
||
12 | |||
13 | use32 |
||
97 | mario79 | 14 | org 0x0 |
15 | db 'MENUET01' ; 8 byte id |
||
16 | dd 0x01 ; header version |
||
17 | dd START ; start of code |
||
18 | dd I_END ; size of image |
||
19 | dd 0x20000 ; memory for app |
||
20 | dd 0x20000-1 ; esp |
||
21 | dd 0x0 , 0x0 ; I_Param , I_Icon |
||
31 | halyavin | 22 | ;****************************************************************************** |
23 | ;include "DEBUG.INC" ; debug macros |
||
97 | mario79 | 24 | START: ; start of execution |
31 | halyavin | 25 | |
97 | mario79 | 26 | mov eax, 48 ; load system colors |
31 | halyavin | 27 | mov ebx, 3 |
28 | mov ecx, sc |
||
29 | mov edx, sizeof.system_colors |
||
485 | heavyiron | 30 | mcall |
31 | halyavin | 31 | |
97 | mario79 | 32 | mov eax, 70 ; load MENU.DAT |
31 | halyavin | 33 | mov ebx, fileinfo |
485 | heavyiron | 34 | mcall |
97 | mario79 | 35 | test eax, eax ; error ? |
36 | jz @f |
||
37 | cmp eax,6 |
||
31 | halyavin | 38 | jnz close |
97 | mario79 | 39 | @@: |
40 | test ebx, ebx ; length = 0 ? |
||
31 | halyavin | 41 | jz close |
42 | mov ecx, ebx |
||
43 | mov edi, mem_end |
||
44 | newsearch: |
||
45 | mov al, '#' |
||
46 | cld |
||
47 | repne scasb |
||
97 | mario79 | 48 | test ecx, ecx ; if not found |
31 | halyavin | 49 | jz close |
50 | call get_number |
||
51 | test ebx, ebx |
||
52 | jnz .number |
||
53 | cmp al, '#' |
||
54 | je search_end |
||
55 | .number: |
||
56 | shl ebx, 4 |
||
97 | mario79 | 57 | add ebx, menu_data ; pointer to process table |
31 | halyavin | 58 | mov [ebx], edi |
59 | inc [processes] |
||
60 | jmp newsearch |
||
61 | search_end: |
||
62 | mov [end_pointer], edi |
||
63 | mov ebx, [processes] |
||
64 | dec ebx |
||
65 | shl ebx, 4 |
||
66 | add ebx, menu_data |
||
67 | newprocess: |
||
68 | xor edx, edx |
||
69 | mov ecx, edi |
||
70 | sub ecx, [ebx] |
||
71 | mov al, 10 |
||
72 | newsearch1: |
||
73 | std |
||
74 | repne scasb |
||
75 | test ecx, ecx |
||
76 | je endprocess |
||
77 | cmp [edi], byte 13 |
||
78 | jne newsearch1 |
||
79 | inc edx |
||
80 | jmp newsearch1 |
||
81 | endprocess: |
||
82 | mov esi, ebx |
||
83 | add esi, 4 |
||
84 | dec edx |
||
85 | mov [esi], dl |
||
86 | cmp ebx, menu_data |
||
87 | jbe search_end1 |
||
88 | sub ebx, 16 |
||
89 | jmp newprocess |
||
90 | search_end1: |
||
91 | mov eax, 14 |
||
485 | heavyiron | 92 | mcall |
31 | halyavin | 93 | sub ax, 20 |
97 | mario79 | 94 | mov [menu_data + y_end], ax |
31 | halyavin | 95 | mov [menu_data + x_start], 5 |
96 | mov al, [menu_data + rows] |
||
97 | mov [menu_data + cur_sel], al ; clear selection |
||
98 | mov [menu_data + prev_sel], al |
||
99 | |||
100 | mov [buffer], 0 |
||
101 | thread: |
||
97 | mario79 | 102 | mov eax, [buffer] ; identifier |
31 | halyavin | 103 | shl eax, 4 |
104 | add eax, menu_data |
||
105 | mov edi, eax |
||
106 | |||
97 | mario79 | 107 | mov eax, 40 ; set event mask |
108 | mov ebx, 100111b ; mouse + button + key + redraw |
||
485 | heavyiron | 109 | mcall |
31 | halyavin | 110 | |
111 | call draw_window |
||
112 | |||
113 | still: |
||
97 | mario79 | 114 | mov eax, 23 ; wait here for event |
31 | halyavin | 115 | mov ebx, 5 |
485 | heavyiron | 116 | mcall |
31 | halyavin | 117 | |
97 | mario79 | 118 | test [close_now], 1 ; is close flag set? |
31 | halyavin | 119 | jnz close |
120 | |||
97 | mario79 | 121 | cmp eax, 1 ; redraw request ? |
122 | je red |
||
123 | cmp eax, 2 ; key pressed ? |
||
124 | je key |
||
125 | cmp eax, 3 ; button in buffer ? |
||
126 | je button |
||
127 | cmp eax, 6 ; mouse event ? |
||
128 | je mouse |
||
31 | halyavin | 129 | |
130 | cmp edi, menu_data |
||
97 | mario79 | 131 | je still ; if main process-ignored |
31 | halyavin | 132 | |
133 | movzx ebx, [edi + parent] ; parent id |
||
134 | shl ebx, 4 |
||
97 | mario79 | 135 | add ebx, menu_data ; ebx = base of parent info |
136 | call backconvert ; get my id in al |
||
137 | cmp al, [ebx + child] ; if I'm not child of my parent, I shall die :) |
||
31 | halyavin | 138 | jne close |
139 | |||
140 | jmp still |
||
141 | |||
142 | |||
97 | mario79 | 143 | red: ; redraw |
31 | halyavin | 144 | call draw_window |
145 | jmp still |
||
146 | |||
147 | |||
148 | key: |
||
149 | ; mov eax, 2 |
||
485 | heavyiron | 150 | mcall |
31 | halyavin | 151 | |
97 | mario79 | 152 | mov al, [edi + rows] ; number of buttons |
31 | halyavin | 153 | |
97 | mario79 | 154 | cmp ah, 178 ; KEY_UP |
31 | halyavin | 155 | jne .noup |
156 | |||
157 | mov ah, [edi+cur_sel] |
||
158 | mov [edi+prev_sel], ah |
||
159 | dec byte [edi+cur_sel] |
||
160 | jnz redrawbut |
||
161 | mov [edi+cur_sel], al |
||
162 | jmp redrawbut |
||
163 | |||
164 | |||
165 | .noup: |
||
97 | mario79 | 166 | cmp ah, 177 ; KEY_DOWN |
31 | halyavin | 167 | jne .nodn |
168 | |||
169 | mov ah, [edi + cur_sel] |
||
170 | mov [edi + prev_sel], ah |
||
171 | inc [edi + cur_sel] |
||
172 | cmp [edi + cur_sel], al |
||
173 | jna redrawbut |
||
174 | mov [edi + cur_sel], 1 |
||
175 | jmp redrawbut |
||
176 | |||
177 | .nodn: |
||
97 | mario79 | 178 | cmp ah, 13 ; ENTER |
31 | halyavin | 179 | jne .noenter |
180 | mov ah, [edi + cur_sel] |
||
181 | jmp button1 |
||
182 | |||
183 | .noenter: |
||
97 | mario79 | 184 | cmp ah, 27 ; ESC |
31 | halyavin | 185 | jne still |
186 | jmp close |
||
187 | |||
188 | ; include "DEBUG.INC" |
||
189 | |||
97 | mario79 | 190 | button: ; BUTTON HANDLER |
191 | mov eax, 17 ; get id |
||
485 | heavyiron | 192 | mcall |
31 | halyavin | 193 | |
194 | button1: |
||
195 | mov esi, edi |
||
196 | push edi |
||
197 | mov edi, [edi + pointer] |
||
198 | |||
199 | ; print "hello" |
||
200 | mov al, [esi + cur_sel] |
||
201 | mov [esi + prev_sel], al |
||
202 | mov [esi + cur_sel], ah |
||
203 | pushad |
||
204 | mov edi, esi |
||
205 | ; dph eax |
||
206 | call draw_only_needed_buttons |
||
207 | popad |
||
208 | |||
209 | ; look for the next line |
||
210 | push eax |
||
211 | .next_string: |
||
212 | call searchstartstring |
||
213 | dec ah |
||
214 | jnz .next_string |
||
215 | pop eax |
||
216 | |||
217 | mov ecx, 40 |
||
218 | mov al, '/' |
||
219 | cld |
||
220 | repne scasb |
||
97 | mario79 | 221 | test ecx, ecx ; if '/' not found |
222 | je searchexit |
||
31 | halyavin | 223 | |
224 | cmp [edi], byte '@' ; check for submenu |
||
97 | mario79 | 225 | je runthread |
31 | halyavin | 226 | |
227 | dec edi |
||
97 | mario79 | 228 | push edi ; pointer to start of filename |
31 | halyavin | 229 | call searchstartstring ; search for next string |
97 | mario79 | 230 | sub edi, 2 ; to last byte of string |
31 | halyavin | 231 | |
232 | mov ecx, edi |
||
233 | pop esi |
||
234 | sub ecx, esi |
||
97 | mario79 | 235 | inc ecx ; length of filename |
31 | halyavin | 236 | mov edi, fileinfo_start.name |
97 | mario79 | 237 | rep movsb ; copy string |
238 | mov byte [edi], 0 ; store terminator |
||
239 | mov eax, 70 ; start program |
||
31 | halyavin | 240 | mov ebx, fileinfo_start |
485 | heavyiron | 241 | mcall |
97 | mario79 | 242 | ; mcall 5,100 |
243 | or [close_now], 1 ; set close flag |
||
31 | halyavin | 244 | pop edi |
245 | mov [mousemask], 0 |
||
246 | jmp close |
||
247 | |||
248 | searchexit: |
||
249 | pop edi |
||
250 | jmp still |
||
251 | |||
252 | |||
253 | runthread: |
||
254 | inc edi |
||
255 | |||
256 | push eax |
||
97 | mario79 | 257 | call get_number ; get number of this process |
31 | halyavin | 258 | pop eax |
259 | |||
97 | mario79 | 260 | test ebx, ebx ; returned zero - main menu or not number |
261 | jz searchexit |
||
31 | halyavin | 262 | |
263 | mov al, bl |
||
264 | |||
265 | mov ebx, [processes] |
||
266 | dec bl |
||
267 | cmp al, bl |
||
97 | mario79 | 268 | ja searchexit ; such process doesnt exist |
31 | halyavin | 269 | cmp al, [esi + child] |
97 | mario79 | 270 | je searchexit ; such process already exists |
31 | halyavin | 271 | |
272 | mov [esi + child], al ; this is my child |
||
273 | mov cx, [esi + x_start] |
||
97 | mario79 | 274 | add cx, 141 ; new x_start in cx |
31 | halyavin | 275 | movzx edx, al |
276 | shl edx, 4 |
||
277 | add edx, menu_data ; edx points to child's base address |
||
278 | mov [edx + x_start], cx ; xstart for new thread |
||
279 | mov cx, [esi + y_end] ; y_end in cx |
||
280 | mov bl, [esi + rows] ; number of buttons in bl |
||
97 | mario79 | 281 | sub bl, ah ; number of btn from bottom |
31 | halyavin | 282 | movzx eax, al |
97 | mario79 | 283 | mov [buffer], eax ; thread id in buffer |
31 | halyavin | 284 | movzx ebx, bl |
285 | push edx |
||
286 | mov eax, BTN_HEIGHT |
||
287 | mul ebx |
||
97 | mario79 | 288 | sub cx, ax ; new y_end for new thread |
31 | halyavin | 289 | pop edx |
290 | mov [edx + y_end], cx ; store y_end |
||
291 | mov edi, esi |
||
292 | call backconvert ; get number of this process (al) |
||
293 | mov [edx + parent], al ; store number of parent process |
||
294 | mov al, [edx + rows] |
||
295 | mov [edx + cur_sel], al ; clear current selected element |
||
296 | mov [edx + prev_sel], al ; clear previous selected element |
||
297 | mov [edx + child], 0 |
||
298 | |||
299 | cmp [thread_stack], 0x1e000 |
||
300 | jne thread_stack_not_full |
||
97 | mario79 | 301 | mov [thread_stack], 0xE000 |
31 | halyavin | 302 | |
303 | thread_stack_not_full: |
||
304 | add [thread_stack], 0x2000 ; start new thread |
||
305 | mov eax, 51 |
||
306 | mov ebx, 1 |
||
307 | mov ecx, thread |
||
308 | mov edx, [thread_stack] |
||
485 | heavyiron | 309 | mcall |
31 | halyavin | 310 | |
311 | jmp searchexit |
||
312 | |||
313 | |||
97 | mario79 | 314 | mouse: ; MOUSE EVENT HANDLER |
31 | halyavin | 315 | mov eax, 37 |
316 | mov ebx, 2 |
||
485 | heavyiron | 317 | mcall |
97 | mario79 | 318 | test eax, eax ; check buttons state |
31 | halyavin | 319 | jnz click |
320 | mov eax, 37 |
||
321 | mov ebx, 1 |
||
485 | heavyiron | 322 | mcall |
97 | mario79 | 323 | ror eax, 16 ; eax = [ Y | X ] relative to window |
324 | cmp ax, 140 ; pointer in window? |
||
325 | ja noinwindow |
||
31 | halyavin | 326 | ; in window |
327 | |||
97 | mario79 | 328 | shr eax, 16 ; eax = [ 0 | Y ] |
31 | halyavin | 329 | xor edx, edx |
330 | mov ebx, BTN_HEIGHT |
||
331 | div ebx |
||
97 | mario79 | 332 | inc eax ; number of "button" in eax |
31 | halyavin | 333 | movzx ebx, [edi + rows] ; total strings in ebx |
334 | cmp eax, ebx |
||
97 | mario79 | 335 | ja noinwindow |
31 | halyavin | 336 | cmp [edi + cur_sel], al |
97 | mario79 | 337 | je noredrawbut |
31 | halyavin | 338 | mov bl, [edi + cur_sel] |
339 | |||
340 | ;;;;;; |
||
341 | cmp [edi + child], 0 |
||
342 | jne noredrawbut |
||
343 | ;;;;;; |
||
344 | |||
345 | mov [edi + cur_sel], al |
||
346 | mov [edi + prev_sel], bl |
||
347 | redrawbut: |
||
348 | call draw_only_needed_buttons |
||
349 | noredrawbut: |
||
350 | call backconvert |
||
351 | bts [mousemask], eax |
||
352 | jmp still |
||
353 | noinwindow: |
||
354 | call backconvert |
||
355 | btr [mousemask], eax |
||
356 | jmp still |
||
357 | click: |
||
358 | cmp [mousemask], 0 ; not in a window (i.e. menu) |
||
97 | mario79 | 359 | je close |
31 | halyavin | 360 | jmp still |
361 | |||
362 | |||
363 | close: |
||
728 | diamond | 364 | movzx ebx, [edi+parent] ; parent id |
365 | shl ebx, 4 |
||
366 | add ebx, menu_data ; ebx = base of parent info |
||
367 | call backconvert |
||
368 | cmp [ebx + child], al ; if i am the child of my parent... |
||
369 | jnz @f |
||
370 | mov [ebx + child], -1 ; ...my parent now has no children |
||
371 | @@: |
||
372 | or eax, -1 ; close this thread |
||
373 | mov [edi + child], al ; my child is not mine |
||
374 | mcall |
||
31 | halyavin | 375 | |
97 | mario79 | 376 | backconvert: ; convert from pointer to process id |
31 | halyavin | 377 | mov eax, edi |
378 | sub eax, menu_data |
||
379 | shr eax, 4 |
||
380 | ret |
||
381 | |||
382 | |||
383 | ;================================== |
||
384 | ; get_number |
||
385 | ; load number from [edi] to ebx |
||
386 | ;================================== |
||
387 | get_number: |
||
388 | push edi |
||
389 | |||
390 | xor eax, eax |
||
391 | xor ebx, ebx |
||
392 | |||
393 | .get_next_char: |
||
394 | mov al, [edi] |
||
395 | inc edi |
||
396 | cmp al, '0' |
||
97 | mario79 | 397 | jb .finish |
31 | halyavin | 398 | cmp al, '9' |
97 | mario79 | 399 | ja .finish |
31 | halyavin | 400 | sub al, '0' |
401 | imul ebx, 10 |
||
402 | add ebx, eax |
||
403 | jmp .get_next_char |
||
404 | |||
405 | .finish: |
||
406 | pop edi |
||
407 | ret |
||
408 | |||
409 | |||
410 | ; ********************************************* |
||
411 | ; ******* WINDOW DEFINITIONS AND DRAW ******** |
||
412 | ; ********************************************* |
||
413 | |||
414 | |||
415 | draw_window: |
||
416 | |||
97 | mario79 | 417 | mov eax, 12 ; function 12:tell os about windowdraw |
418 | mov ebx, 1 ; 1, start of draw |
||
485 | heavyiron | 419 | mcall |
31 | halyavin | 420 | |
421 | movzx ebx, [edi + rows] |
||
97 | mario79 | 422 | imul eax, ebx, BTN_HEIGHT ; eax = height of window |
31 | halyavin | 423 | movzx ecx, [edi + y_end] |
97 | mario79 | 424 | sub ecx, eax ; ecx = Y_START |
31 | halyavin | 425 | shl ecx, 16 |
97 | mario79 | 426 | add ecx, eax ; ecx = [ Y_START | Y_SIZE ] |
31 | halyavin | 427 | dec ecx |
428 | movzx ebx, [edi + x_start] |
||
429 | shl ebx, 16 |
||
97 | mario79 | 430 | mov bx, 140 ; ebx = [ X_START | X_SIZE ] |
431 | xor eax, eax ; function 0 : define and draw window |
||
432 | mov edx, 0x01000000 ; color of work area RRGGBB,8->color gl |
||
433 | mov esi, edx ; unmovable window |
||
485 | heavyiron | 434 | mcall |
31 | halyavin | 435 | |
436 | call draw_all_buttons |
||
437 | |||
438 | mov eax,12 |
||
439 | mov ebx,2 |
||
485 | heavyiron | 440 | mcall |
31 | halyavin | 441 | |
442 | ret |
||
443 | |||
444 | |||
445 | draw_all_buttons: |
||
446 | xor edx, edx |
||
447 | .new_button: |
||
448 | call draw_one_button |
||
449 | inc edx |
||
450 | cmp dl, [edi + rows] |
||
97 | mario79 | 451 | jb .new_button |
31 | halyavin | 452 | |
453 | ret |
||
454 | |||
455 | |||
456 | draw_only_needed_buttons: |
||
457 | xor edx, edx |
||
458 | mov dl, [edi + cur_sel] |
||
459 | dec dl |
||
460 | call draw_one_button |
||
461 | mov dl, [edi + prev_sel] |
||
462 | dec dl |
||
463 | call draw_one_button |
||
464 | ret |
||
465 | |||
466 | |||
467 | draw_one_button: |
||
468 | ; receives number of button in dl |
||
469 | push edx;ad |
||
470 | |||
471 | mov eax, 8 |
||
472 | mov ebx, 140 |
||
473 | movzx ecx, dl |
||
474 | imul ecx, BTN_HEIGHT |
||
475 | shl ecx, 16 |
||
476 | add ecx, BTN_HEIGHT-1 |
||
477 | ; edx = button identifier |
||
195 | heavyiron | 478 | mov esi, [sc.work] |
318 | heavyiron | 479 | cmp esi, 0xdfdfdf |
480 | jb nocorrect |
||
481 | sub esi, 0x1b1b1b |
||
482 | nocorrect: |
||
31 | halyavin | 483 | inc dl |
484 | cmp [edi + cur_sel], dl |
||
485 | jne .nohighlight |
||
318 | heavyiron | 486 | add esi, 0x1a1a1a |
31 | halyavin | 487 | .nohighlight: |
97 | mario79 | 488 | or edx, 0x20000000 |
485 | heavyiron | 489 | mcall |
31 | halyavin | 490 | movzx edx, dl |
491 | |||
492 | dec dl |
||
493 | imul ebx, edx, BTN_HEIGHT |
||
494 | add ebx, (4 shl 16) + TXT_Y |
||
495 | |||
496 | movzx ecx, dl |
||
497 | inc ecx |
||
498 | mov edx, [edi + pointer] |
||
499 | .findline: |
||
500 | cmp byte [edx], 13 |
||
97 | mario79 | 501 | je .linefound |
31 | halyavin | 502 | inc edx |
503 | jmp .findline |
||
504 | .linefound: |
||
505 | inc edx |
||
506 | cmp byte [edx], 10 |
||
507 | jne .findline |
||
508 | dec ecx |
||
509 | jnz .findline |
||
510 | |||
195 | heavyiron | 511 | mov ecx, [sc.work_text] |
31 | halyavin | 512 | mov eax, 4 |
513 | mov esi, 21 |
||
485 | heavyiron | 514 | mcall |
31 | halyavin | 515 | |
516 | pop edx;ad |
||
517 | ret |
||
518 | |||
519 | |||
520 | searchstartstring: |
||
521 | mov ecx, 40 |
||
522 | mov al, 13 |
||
523 | cld |
||
524 | repne scasb |
||
525 | cmp byte [edi], 10 |
||
526 | jne searchstartstring |
||
527 | ret |
||
528 | |||
529 | |||
530 | ;*** DATA AREA **************************************************************** |
||
531 | |||
97 | mario79 | 532 | thread_stack dd 0xE000 |
31 | halyavin | 533 | processes dd 0 |
534 | |||
535 | fileinfo: |
||
97 | mario79 | 536 | .subfunction dd 0 ; 0=READ |
537 | .start dd 0 ; start byte |
||
538 | .size_high dd 0 ; rezerved |
||
539 | .size dd 0x10000-mem_end ; blocks to read |
||
540 | .return dd mem_end ; return data pointer |
||
31 | halyavin | 541 | .name: |
529 | spraid | 542 | db '/sys/MENU.DAT',0 ; ASCIIZ dir & filename |
31 | halyavin | 543 | |
544 | fileinfo_start: |
||
97 | mario79 | 545 | .subfunction dd 7 ; 7=START APPLICATION |
546 | .flags dd 0 ; flags |
||
547 | .params dd 0x0 ; nop |
||
548 | .rezerved dd 0x0 ; nop |
||
549 | .rezerved_1 dd 0x0 ; nop |
||
31 | halyavin | 550 | .name: |
551 | times 50 db ' ' |
||
552 | |||
553 | I_END: |
||
554 | |||
555 | close_now dd ? ; close all processes immediately |
||
556 | end_pointer dd ? |
||
97 | mario79 | 557 | buffer dd ? |
31 | halyavin | 558 | mousemask dd ? ; mask for mouse pointer location |
559 | |||
560 | sc system_colors |
||
561 | |||
562 | menu_data: |
||
563 | rb 0x4000 ;x10000 |
||
564 | |||
565 | virtual at 0 ; PROCESSES TABLE (located at menu_data) |
||
566 | pointer dd ? ; +0 pointer in file |
||
97 | mario79 | 567 | rows db ? ; +4 numer of strings |
31 | halyavin | 568 | x_start dw ? ; +5 x start |
569 | y_end dw ? ; +7 y end |
||
570 | child db ? ; +9 id of child menu |
||
571 | parent db ? ; +10 id of parent menu |
||
572 | cur_sel db ? ; +11 current selection |
||
573 | prev_sel db ? ; +12 previous selection |
||
574 | rb 16-$+1 ; [16 bytes per element] |
||
575 | end virtual |
||
576 | |||
577 | mem_end: |