Subversion Repositories Kolibri OS

Rev

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

  1. #define MEMSIZE 4096 * 50
  2.  
  3. //===================================================//
  4. //                                                   //
  5. //                       LIB                         //
  6. //                                                   //
  7. //===================================================//
  8.  
  9. #include "../lib/fs.h"
  10. #include "../lib/list_box.h"
  11. #include "../lib/gui.h"
  12. #include "../lib/random.h"
  13. #include "../lib/kfont.h"
  14.  
  15. #include "../lib/obj/libio.h"
  16. #include "../lib/obj/libimg.h"
  17. #include "../lib/obj/libini.h"
  18. #include "../lib/obj/proc_lib.h"
  19. #include "../lib/obj/box_lib.h"
  20.  
  21. #include "../lib/patterns/simple_open_dialog.h"
  22.  
  23. //===================================================//
  24. //                                                   //
  25. //                       DATA                        //
  26. //                                                   //
  27. //===================================================//
  28.  
  29. //simple open dialog data
  30. char default_dir[] = "/rd/1";
  31. od_filter filter2 = { 15, "MP3\0WAV\0XM\0\0" };
  32.  
  33. #define ABOUT_MESSAGE "Pixie Player v2.81
  34.  
  35.      A tiny music folder player.
  36.      Supports MP3, WAV, XM audio file formats.
  37.  
  38. Hot keys:
  39.  Open file: O key
  40.  Play/Stop: Space or P key
  41.  Start playing selected file: Enter
  42.  Goto next/previous track: Ctrl + Left/Right
  43.  Change sound volume: Left/Right key
  44.  Remove from the list: Delete
  45.  Repeat: R
  46.  Shuffle: S
  47.  Mute: M
  48.  
  49. kolibri-n.org & aspero.pro"
  50.  
  51. scroll_bar scroll1 = { 5,200,398,44,0,2,115,15,0,0xeeeeee,0xBBBbbb,0xeeeeee,
  52.         0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
  53.  
  54. proc_info Form;
  55. llist list;
  56.  
  57. char pixie_ini_path[4096];
  58. char work_folder[4096];
  59. char current_filename[256];
  60.  
  61. enum {
  62.         BUTTON_WINDOW_CLOSE = 1,
  63.         BUTTON_WINDOW_MINIMIZE,
  64.         BUTTON_WINDOW_REDUCE,
  65.         BUTTON_PLAYBACK_PLAY_PAUSE = 10,
  66.         BUTTON_PLAYBACK_PREV,
  67.         BUTTON_PLAYBACK_NEXT,
  68.         BUTTON_REPEAT,
  69.         BUTTON_SHUFFLE,
  70.         BUTTON_OPEN_DIALOG,
  71.         BUTTON_SHOW_VOLUME
  72. };
  73.  
  74. int player_run_id;
  75. int notify_run_id;
  76.  
  77. bool repeat;
  78. bool shuffle;
  79.  
  80. int current_playing_file_n=0;
  81.  
  82. word win_x_normal, win_y_normal;
  83. word win_x_small, win_y_small;
  84.  
  85. byte window_mode;
  86. enum {
  87.         WINDOW_MODE_NORMAL,
  88.         WINDOW_MODE_SMALL
  89. };
  90.  
  91. byte playback_mode;
  92. enum {
  93.         PLAYBACK_MODE_STOPED,
  94.         PLAYBACK_MODE_PLAYING
  95. };
  96.  
  97. #define LAST_FOLDER_EXISTS 1
  98.  
  99. //===================================================//
  100. //                                                   //
  101. //                       CODE                        //
  102. //                                                   //
  103. //===================================================//
  104.  
  105. #include "get_files_list.h"
  106. #include "settings.h"
  107.  
  108. void LoadLibraries()
  109. {
  110.         load_dll(boxlib, #box_lib_init,0);
  111.         load_dll(libio, #libio_init,1);
  112.         load_dll(libimg, #libimg_init,1);
  113.         load_dll(libini, #lib_init,1);
  114.         load_dll(Proc_lib, #OpenDialog_init,0);
  115.         OpenDialog_init stdcall (#o_dialog);
  116. }
  117.  
  118. void main()
  119. {
  120.         list.SetFont(8, 16, 13);
  121.         LoadLibraries();
  122.         LoadIniConfig();
  123.         if (work_folder) param=LAST_FOLDER_EXISTS;
  124.         if (!param) notify("'Pixie Player\nPress O key to open MP3/WAV/XM file' -St");
  125.         kfont.init(DEFAULT_FONT);      
  126.         SetEventMask(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER);
  127.         loop()
  128.         {
  129.           WaitEventTimeout(10);
  130.           switch(EAX & 0xFF) {
  131.                 case evMouse:
  132.                         if (!CheckActiveProcess(Form.ID)) break;
  133.                         mouse.get();
  134.                         scrollbar_v_mouse (#scroll1);
  135.                         if (list.first != scroll1.position)
  136.                         {
  137.                                 list.first = scroll1.position;
  138.                                 DrawPlayList();
  139.                                 break;
  140.                         }
  141.                         if (list.MouseOver(mouse.x, mouse.y))
  142.                         {
  143.                                 if (mouse.vert) && (list.MouseScroll(mouse.vert)) DrawPlayList();
  144.                                 if (mouse.dblclick) EventStartPlayingSelectedItem();
  145.                                 if (mouse.down) && (mouse.key&MOUSE_LEFT)
  146.                                         && (list.ProcessMouse(mouse.x, mouse.y)) DrawPlayList();
  147.                                 if (mouse.down) && (mouse.key&MOUSE_RIGHT) EventShowAbout();
  148.                         }
  149.                         if(mouse.key&MOUSE_LEFT) && (mouse.x<14)
  150.                                 && (window_mode == WINDOW_MODE_SMALL) EventDragWindow();
  151.                         break;
  152.                 case evButton:
  153.                         switch(GetButtonID()) {
  154.                                 case BUTTON_WINDOW_CLOSE: EventExitApp(); break;
  155.                                 case BUTTON_WINDOW_MINIMIZE: MinimizeWindow(); break;
  156.                                 case BUTTON_WINDOW_REDUCE: EventChangeWindowMode(); break;
  157.                                 case BUTTON_PLAYBACK_PREV: EventPlaybackPrevious();     break;
  158.                                 case BUTTON_PLAYBACK_NEXT: EventPlaybackNext(); break;
  159.                                 case BUTTON_PLAYBACK_PLAY_PAUSE: EventPlayAndPause(); break;
  160.                                 case BUTTON_REPEAT: EventRepeatClick(); break;
  161.                                 case BUTTON_SHUFFLE: EventShuffleClick(); break;
  162.                                 case BUTTON_OPEN_DIALOG: EventFileDialogOpen(); break;
  163.                                 case BUTTON_SHOW_VOLUME: RunProgram("/sys/@VOLUME", NULL); break;
  164.                         }
  165.                         break;   
  166.                 case evKey:
  167.                         GetKeys();
  168.                         if (key_modifier&KEY_LCTRL) || (key_modifier&KEY_RCTRL) {
  169.                                 if (key_scancode==SCAN_CODE_LEFT) EventPlaybackPrevious();
  170.                                 if (key_scancode==SCAN_CODE_RIGHT) EventPlaybackNext();
  171.                                 break;
  172.                         }              
  173.                         if (key_scancode==SCAN_CODE_KEY_O) EventFileDialogOpen();
  174.                         if (key_scancode==SCAN_CODE_KEY_M) RunProgram("/sys/@VOLUME", "m");
  175.                         if (key_scancode==SCAN_CODE_KEY_R) EventRepeatClick();
  176.                         if (key_scancode==SCAN_CODE_KEY_S) EventShuffleClick();
  177.                         if (key_scancode==SCAN_CODE_RIGHT) RunProgram("/sys/@VOLUME", "+");
  178.                         if (key_scancode==SCAN_CODE_LEFT)  RunProgram("/sys/@VOLUME", "-");
  179.                         if (key_scancode==SCAN_CODE_ENTER) EventStartPlayingSelectedItem();
  180.                         if (key_scancode==SCAN_CODE_DEL) EventDeleteItem();
  181.                         if (key_scancode==SCAN_CODE_KEY_P)||(key_scancode==SCAN_CODE_SPACE) EventPlayAndPause();
  182.                         if (key_scancode==SCAN_CODE_F1) EventShowAbout();
  183.                         if (list.ProcessKey(key_scancode)) DrawPlayList();
  184.                         break;
  185.                 case evReDraw:
  186.                         if (window_mode == WINDOW_MODE_NORMAL)
  187.                                 DefineDragableWindow(win_x_normal, win_y_normal, skin.w - 1, skin.h + list.h-1);
  188.                         if (window_mode == WINDOW_MODE_SMALL)
  189.                                 DefineDragableWindow(win_x_small, win_y_small, WIN_W_SMALL, WIN_H_SMALL);
  190.                         draw_window();
  191.                         if (param[0]) {
  192.                                 if (param==LAST_FOLDER_EXISTS) EventOpenFolder(NULL);
  193.                                 else EventOpenFolder(#param);
  194.                                 param[0] = NULL;
  195.                         }
  196.                         break;
  197.                 default:
  198.                         EventCheckSongFinished();
  199.           }
  200.   }
  201. }
  202.  
  203.  
  204. void DrawPlayList()
  205. {
  206.         int i;
  207.         int yyy;
  208.         int kfont_width;
  209.         char temp_filename[4096];
  210.         dword text_color, bg_color;
  211.         for (i=0; i<list.visible; i++;)
  212.         {
  213.                 strcpy(#temp_filename, files_mas[i + list.first] * 304 + buf + 72);
  214.                 temp_filename[strrchr(#temp_filename, '.')-1] = '\0';
  215.                
  216.                 yyy = i*list.item_h+list.y;
  217.                
  218.                 //this is selected file
  219.                 if (list.cur_y - list.first == i)
  220.                 {
  221.                         if (i>=list.count) continue;
  222.                         bg_color = theme.color_list_active_bg;
  223.                         text_color = theme.color_list_text;
  224.                 }
  225.                 //this is not selected file
  226.                 else
  227.                 {
  228.                         if (i>=list.count) continue;
  229.                         bg_color = theme.color_list_bg;
  230.                         text_color = theme.color_list_text;
  231.                 }
  232.                 //this is cur_y playing file
  233.                 if (i + list.first == current_playing_file_n)
  234.                 && (playback_mode == PLAYBACK_MODE_PLAYING)
  235.                 {
  236.                         text_color = theme.color_list_active_text;
  237.                 }
  238.                 DrawBar(list.x, yyy, list.w, list.item_h, bg_color);
  239.                 kfont_width = kfont.WriteIntoWindow(6, yyy+list.text_y, bg_color,
  240.                         text_color, list.font_type, #temp_filename);
  241.                 if (kfont_width>skin.w-15) DrawBar(skin.w-1, yyy, 1, list.item_h, theme.color_list_border);
  242.         }
  243.         DrawBar(list.x,list.visible * list.item_h + list.y, list.w,
  244.                 -list.visible * list.item_h + list.h, theme.color_list_bg);
  245.         DrawScroller();
  246. }
  247.  
  248.  
  249. void draw_window() {
  250.         GetProcessInfo(#Form, SelfInfo);
  251.         DrawTopPanel();
  252.         IF (Form.status_window>=2) return;
  253.         if (window_mode == WINDOW_MODE_NORMAL)
  254.         {
  255.                 DrawPlayList();
  256.                 DrawRectangle(0, skin.h-1, skin.w-1, list.h+1, theme.color_list_border);
  257.         }
  258. }
  259.  
  260. void DrawTopPanel()
  261. {
  262.         int kfont_width;
  263.         int button_y;
  264.         //Mode depended
  265.         if (window_mode == WINDOW_MODE_NORMAL)
  266.         {
  267.                 button_y = 46;
  268.                 img_draw stdcall(skin.image, 0, 0, skin.w, skin.h, 0, 0);
  269.                 if (playback_mode != PLAYBACK_MODE_STOPED)
  270.                         img_draw stdcall(skin.image, 47, button_y, 41, 21, skin.w+1, WIN_H_SMALL+1);
  271.                 if (repeat)
  272.                         img_draw stdcall(skin.image, 217, button_y+2, 17,17,skin.w+43, WIN_H_SMALL+1);
  273.                 if (shuffle)
  274.                         img_draw stdcall(skin.image, 236, button_y+2, 17,17, skin.w+62, WIN_H_SMALL+1);
  275.  
  276.                 if (!work_folder) DrawPixieTitle("Pixie");
  277.                 else DrawPixieTitle(#work_folder + strrchr(#work_folder, '/'));
  278.                 kfont_width = kfont.WriteIntoWindow(8, 24, theme.color_top_panel_bg,
  279.                         theme.color_top_panel_song_name, list.font_type, #current_filename);
  280.                 if (kfont_width>skin.w-15) DrawBar(skin.w-1, 24, 1, list.item_h, theme.color_list_border);
  281.                 //Playing control buttons
  282.                 DefineHiddenButton(7, button_y, 38, 20, BUTTON_PLAYBACK_PREV);
  283.                 DefineHiddenButton(48, button_y, 38, 20, BUTTON_PLAYBACK_PLAY_PAUSE);
  284.                 DefineHiddenButton(87, button_y, 38, 20, BUTTON_PLAYBACK_NEXT);
  285.                 //Window control buttons
  286.                 DefineHiddenButton(Form.width - 27, 1, 26, 15, BUTTON_WINDOW_CLOSE);
  287.                 DefineHiddenButton(Form.width - 55, 1, 26, 15, BUTTON_WINDOW_MINIMIZE);
  288.                 DefineHiddenButton(Form.width - 83, 1, 26, 15, BUTTON_WINDOW_REDUCE);
  289.                 //Other buttons
  290.                 DefineHiddenButton(218, button_y+3, 17, 16, BUTTON_REPEAT);
  291.                 DefineHiddenButton(237, button_y+3, 17, 16, BUTTON_SHUFFLE);
  292.                 DefineHiddenButton(270, button_y+3, 17, 16, BUTTON_OPEN_DIALOG);
  293.                 DefineHiddenButton(289, button_y+3, 17, 16, BUTTON_SHOW_VOLUME);
  294.         }
  295.         else if (window_mode == WINDOW_MODE_SMALL)
  296.         {
  297.                 button_y = 7;
  298.                 img_draw stdcall(skin.image, 0, 0, WIN_W_SMALL, WIN_H_SMALL, skin.w-1, 0);
  299.                 if (playback_mode != PLAYBACK_MODE_STOPED)
  300.                         img_draw stdcall(skin.image, 46, button_y-1, 27, 19, skin.w+83, WIN_H_SMALL+1);
  301.                 DefineHiddenButton(0, 0, WIN_W_SMALL, WIN_H_SMALL, 99 + BT_NOFRAME);
  302.                 //Playing control buttons
  303.                 DefineHiddenButton(20, button_y, 24, 16, BUTTON_PLAYBACK_PREV);
  304.                 DefineHiddenButton(46, button_y, 24, 16, BUTTON_PLAYBACK_PLAY_PAUSE);
  305.                 DefineHiddenButton(72, button_y, 24, 16, BUTTON_PLAYBACK_NEXT);
  306.                 //Window control buttons
  307.                 DefineHiddenButton(Form.width - 20, 1, 19, 13, BUTTON_WINDOW_CLOSE);
  308.                 DefineHiddenButton(Form.width - 20, 16, 19, 13, BUTTON_WINDOW_REDUCE);
  309.         }
  310. }
  311.  
  312.  
  313. void DrawScroller()
  314. {
  315.         scroll1.max_area = list.count;
  316.         scroll1.cur_area = list.visible;
  317.         scroll1.position = list.first;
  318.         scroll1.all_redraw = 0;
  319.         scroll1.start_x = skin.w - scroll1.size_x-1;
  320.         scroll1.start_y = list.y-1;
  321.         scroll1.size_y = list.h+2;
  322.         if (list.count > list.visible) scrollbar_v_draw(#scroll1);
  323. }
  324.  
  325. void DrawPixieTitle(dword _title)
  326. {
  327.         kfont.WriteIntoWindow(8, 5, theme.color_top_panel_bg,
  328.                 theme.color_top_panel_folder_name, list.font_type, _title);
  329. }
  330.  
  331. //===================================================//
  332. //                                                   //
  333. //                     EVENTS                        //
  334. //                                                   //
  335. //===================================================//
  336.  
  337.  
  338. void EventOpenFolder(dword _open_path)
  339. {
  340.         if (!_open_path)
  341.         {
  342.                 OpenDirectory(#work_folder);
  343.         }
  344.         else
  345.         {
  346.                 strcpy(#work_folder, _open_path);
  347.                 work_folder[strrchr(#work_folder, '/')-1]='\0';
  348.                 OpenDirectory(#work_folder);
  349.                 SetOpenedFileFirst(_open_path);
  350.         }
  351.         list.SetSizes(1, skin.h, skin.w-1, 22*15, 22);
  352.         if (list.count <= list.visible)
  353.         {
  354.                 list.h = list.count * list.item_h;
  355.                 list.visible = list.count;
  356.                 list.w -= 1;
  357.         }
  358.         else
  359.         {
  360.                 list.w -= scroll1.size_x;
  361.         }
  362.         if (window_mode==WINDOW_MODE_NORMAL) MoveSize(OLD, OLD, OLD, skin.h + list.h);
  363.         list.KeyHome();
  364.         current_playing_file_n=0;
  365.         EventStopPlaying();
  366.         if (_open_path) EventStartPlaying();   
  367. }
  368.  
  369.  
  370. void EventStopPlaying()
  371. {
  372.         if (player_run_id) player_run_id = KillProcess(player_run_id);
  373.         if (notify_run_id) notify_run_id = KillProcess(notify_run_id);
  374.         playback_mode = PLAYBACK_MODE_STOPED;
  375.         DrawTopPanel();
  376.         DrawPlayList();
  377. }
  378.  
  379.  
  380. void EventStartPlaying()
  381. {
  382.         word i;
  383.         char item_path[4096];
  384.         char notify_message[512];
  385.         EventStopPlaying();
  386.         if (current_playing_file_n >= list.count) {
  387.                 current_playing_file_n = list.count-1;
  388.                 return;
  389.         }
  390.         if (current_playing_file_n < 0) {
  391.                 current_playing_file_n = 0;
  392.                 return;
  393.         }
  394.         playback_mode = PLAYBACK_MODE_PLAYING;
  395.         strlcpy(#current_filename, Getcur_yItemName(), sizeof(current_filename));
  396.         sprintf(#item_path,"-h %s/%s",#work_folder,#current_filename);
  397.         current_filename[strrchr(#current_filename, '.')-1] = '\0';
  398.         DrawPlayList();
  399.         DrawTopPanel();
  400.         player_run_id = RunProgram("/sys/media/ac97snd", #item_path);  
  401.         sprintf(#notify_message,"'Now playing:\n%s' -St",#current_filename);
  402.         if (!repeat) && (window_mode==WINDOW_MODE_SMALL)
  403.         {
  404.                 for (i=2; i<strlen(#notify_message)-6; i++)
  405.                 {
  406.                         //replace ' char to avoid @notify misunderstood
  407.                         if (notify_message[i]=='\'') notify_message[i]=96;
  408.                 }
  409.                 notify_run_id = notify(#notify_message);
  410.         }
  411. }
  412.  
  413.  
  414. void EventPlayAndPause()
  415. {
  416.         if (playback_mode == PLAYBACK_MODE_PLAYING)
  417.         {
  418.                 playback_mode = PLAYBACK_MODE_STOPED;
  419.                 EventStopPlaying();
  420.         }
  421.         else
  422.         {
  423.                 playback_mode = PLAYBACK_MODE_PLAYING;
  424.                 EventStartPlaying();
  425.         }
  426. }
  427.  
  428.  
  429. void EventChangeWindowMode()
  430. {
  431.         if (window_mode == WINDOW_MODE_NORMAL)
  432.         {
  433.                 window_mode = WINDOW_MODE_SMALL;
  434.                 win_x_normal = Form.left;
  435.                 win_y_normal = Form.top;
  436.                 MoveSize(OLD, OLD, WIN_W_SMALL-1, WIN_H_SMALL-1);
  437.                 MoveSize(OLD, win_y_small, OLD, OLD);
  438.                 MoveSize(win_x_small, OLD, OLD, OLD);
  439.         }
  440.         else
  441.         {
  442.                 window_mode = WINDOW_MODE_NORMAL;
  443.                 win_x_small = Form.left;
  444.                 win_y_small = Form.top;
  445.                 MoveSize(win_x_normal, win_y_normal, skin.w -1 ,skin.h + list.h);
  446.         }
  447. }
  448.  
  449. void EventExitApp()
  450. {
  451.         EventStopPlaying();
  452.         SaveIniConfig();
  453.         ExitProcess();
  454. }
  455.  
  456. void EventPlaybackPrevious()
  457. {
  458.         if (shuffle) current_playing_file_n = random(list.count);
  459.         else current_playing_file_n--;
  460.         EventStartPlaying();
  461. }
  462.  
  463. void EventPlaybackNext()
  464. {
  465.         if (shuffle) current_playing_file_n = random(list.count);
  466.         else current_playing_file_n++;
  467.         EventStartPlaying();
  468. }
  469.  
  470. void EventStartPlayingSelectedItem()
  471. {
  472.         current_playing_file_n=list.cur_y;
  473.         EventStartPlaying();
  474. }
  475.  
  476. void EventFileDialogOpen()
  477. {
  478.         OpenDialog_start stdcall (#o_dialog);
  479.         if (o_dialog.status==1) EventOpenFolder(#openfile_path);
  480. }
  481.  
  482. void EventCheckSongFinished()
  483. {
  484.         if (playback_mode == PLAYBACK_MODE_PLAYING)
  485.         && (!GetProcessSlot(player_run_id)) {
  486.                 if (repeat) EventStartPlaying();
  487.                 else EventPlaybackNext();
  488.         }
  489. }
  490.  
  491. void EventRepeatClick()
  492. {
  493.         repeat ^= 1;
  494.         DrawTopPanel();
  495. }
  496.  
  497. void EventShuffleClick()
  498. {
  499.         shuffle ^= 1;
  500.         DrawTopPanel();
  501. }
  502.  
  503. void EventDeleteItem()
  504. {
  505.         int i;
  506.         if (list.cur_y == current_playing_file_n) EventStopPlaying();
  507.         for (i=list.cur_y; i<list.count; i++) files_mas[i] = files_mas[i+1];
  508.         list.count--;
  509.         if (list.cur_y <= current_playing_file_n) current_playing_file_n--;
  510.         list.CheckDoesValuesOkey();
  511.         if (list.count <= list.visible)
  512.         {
  513.                 list.h = list.count * list.item_h;
  514.                 list.visible = list.count;
  515.                 if (window_mode==WINDOW_MODE_NORMAL) MoveSize(OLD, OLD, OLD, skin.h + list.h);
  516.         }
  517.         else DrawPlayList();
  518. }
  519.  
  520. void EventShowAbout()
  521. {
  522.         CreateThread(#ShowAboutThread,#menu_stak+4092);
  523. }
  524.  
  525. void ShowAboutThread()
  526. {
  527.         proc_info pop_up;
  528.         loop() switch(WaitEvent())
  529.         {
  530.                 case evButton:
  531.                         ExitProcess();
  532.                         break;
  533.                 case evKey:
  534.                         GetKeys();
  535.                         if (key_scancode == SCAN_CODE_ESC) ExitProcess();
  536.                         break;
  537.                 case evReDraw:
  538.                         DefineDragableWindow(150, 200, 400, 346);
  539.                         GetProcessInfo(#pop_up, SelfInfo);
  540.  
  541.                         DrawBar(0, 0, pop_up.width, pop_up.height, theme.color_top_panel_bg);
  542.                         DrawRectangle(0, 0, pop_up.width, pop_up.height, theme.color_list_border);
  543.  
  544.                         DefineHiddenButton(pop_up.width - 27, 1, 26, 15, BUTTON_WINDOW_CLOSE);
  545.                         img_draw stdcall(skin.image, pop_up.width-28, 0, 28, 18, skin.w - 29, 0);
  546.                         DrawCaptButton(pop_up.width-10-80, pop_up.height - 34, 80, 24, 2,
  547.                           theme.color_list_active_bg, theme.color_top_panel_song_name, "Cool");
  548.                        
  549.                         WriteTextLines(10, 10, 0x90, theme.color_top_panel_song_name, ABOUT_MESSAGE, 19);
  550.                         DrawIcon32(10, 48, theme.color_top_panel_bg, 65);
  551.  
  552.         }
  553. }
  554.  
  555.  
  556. stop:
  557.  
  558. char menu_stak[4096];