Subversion Repositories Kolibri OS

Rev

Rev 1754 | Rev 2618 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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