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