Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;******************************************************************************
  2. ;   MAIN MENU by lisovin@26.ru
  3. ;   Some parts of code rewritten by Ivan Poddubny <ivan-yar@bk.ru>
  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 <ah> times; <ah> = button_id
  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:
  582.