www.pudn.com > 6027_HD65.rar > flmenu.c


/**********************************************************************/ 
/***************    MTK CONFIDENTIAL & COPYRIGHTED     ****************/ 
/***************                                       ****************/ 
/***************  $Modtime:: 04/08/09 2:01p    $       ****************/ 
/***************  $Revision:: 39               $       ****************/ 
/***************                                       ****************/ 
/***************  $Modtime:: 04/08/09 2:01p    $       ****************/ 
/***************  $Revision:: 39               $       ****************/ 
/***************                                       ****************/ 
/***************   Description : File List             ****************/ 
/***************                 File Menu Module      ****************/ 
/***************                                       ****************/ 
/***************       Company : MediaTek Inc.         ****************/ 
/***************    Programmer : Jacob Lin             ****************/ 
/**********************************************************************/ 
 
/** 
 *          $(PROJ_HOME)/8032/custom/demo/fslist/flmenu.c 
 *   
 *          Object "FILE MENU" acts like the file menu of the 
 *          file browser and MP3 player control. 
 */ 
 
#define __FLMENU_C_ 
 
 
#include "../general.h" 
#include "../osdshow.h" 
#include "flmenu.h" 
#include "flspec.h" 
#include "flcomm.h" 
#include "flipshow.h" 
#include "flconfig.h" 
 
#pragma NOAREGS 
extern void DRS232LogB(BYTE bV1, BYTE bV2, BYTE bV3, BYTE bV4); 
 
#ifdef PLAYER_FLMENU 
 
#define SPTM_SUPPORT 
 
/** 
 * Macro defnitions 
 */ 
// "FS LIST" command return handler 
static void vFlMnRetCreate(void) large; 
static void vFlMnRetSet(void) large; 
static void vFlMnRetGetItems(void) large; 
static void vFlMnRetClickItem(void) large; 
static void vFlMnRetAddToPl(void) large; 
static void vFlMnRetRmFromPl(void) large; 
static void vFlMnRetRmAllFromPl(void) large; 
static void vFlMnRetQueryItem(void) large; 
 
// UI 
static void vFlMnShowPage(void) large; 
static void vFlMnDrawItem(BYTE bItemIdx) large; 
static void vFlMnPProcName(DWRD *pdwAddr, BYTE *pbLen) large; 
static void vFlMnDrawPage(void) large; 
static void vFlMnClrPage(void) large; 
static void vFlMnDrawInfoPanel(BYTE bPanel) large; 
 
#if (defined(DATA_DISC_SUPPORT_DISC_LIST) || defined(DATA_DISC_SUPPORT_PLAY_LIST)) 
static BOOL fgFlMnChgListType(void) large; 
#endif 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
// List  
static BOOL fgFlMnPlMark(void) large; 
static BOOL fgFlMnPlRemove(void) large; 
#endif 
 
// Utilities 
static WORD wFlMnGetListBaseDir(BYTE bListId) large; 
static BOOL fgFlMnIsCurrPlayItem(BYTE bIdx) large; 
static void vFlMnHiliOn(BYTE bItemIdx, BYTE bHiliIdx, BYTE bColor1, BYTE bColor2) large; 
static void vFlMnHiliOff(BYTE bHiliIdx) large; 
static BOOL fgIsParentDir(void) large; 
 
 
static BYTE bFlMnGetIconIdx(BYTE bFType) large; 
static void vFlMnHiliItem(BYTE bItemIdx, BOOL fgOn) large; 
static BOOL fgFlMnLeavItem(BYTE bItemIdx) large; 
static BOOL fgFlMnEntItem(BYTE bItemIdx) large; 
static void vFlMnRdListInfo(BYTE bId) large; 
static BOOL fgFlMnLeavDir(void) large; 
static BOOL fgFlMnEntDir(BYTE bItemIdx, BOOL fgMoveUp) large; 
 
static void vFlMnSyncState(void) large; 
 
//  full path display manipulation 
static void vWorkAreaClear(void) large; 
#ifdef FLMN_RET_PLAY_DIR 
  static void vWorkAreaMove(BOOL fgToFront) large; 
#endif 
static void vParseFolderName(BYTE bIdx, BOOL fgMoveUp) large; 
static void vDrawFolderName(BOOL fgDraw) large; 
 
// Timer 
#ifdef FLMN_TEST_NEW_FUNC 
static void vFlMnTimerScrollWB(void) large; 
#endif 
static void vFlMnTimerJpgPv(void) large; 
#if 0 // - JACOB: unused yet 
static void vFlMnTimerScrollingStr(void) large; 
#endif //0 
static void vFlMnTimerShowBitrate(void) large; 
static void vFlMnChgMp3State(BYTE bStt) large; 
 
// IR Key Handlers 
static BOOL fgFlMnIrCmdDoneHdr(void) large; 
static BOOL fgFlMnOnIrPlay(void) large; 
static BOOL fgFlMnOnIrPause(void) large; 
//static BOOL fgFlMnIrOnIrNum(void) large; 
static BOOL fgFlMnOnIrSelDone(void) large; 
static BOOL fgFlMnIrDirsHdr(void) large; 
static BOOL fgFlMnOnIrUp(void) large; 
static BOOL fgFlMnOnIrDown(void) large; 
static BOOL fgFlMnOnIrLeft(void) large; 
static BOOL fgFlMnOnIrRight(void) large; 
static BOOL fgFlMnOnIrNext(void) large; 
static BOOL fgFlMnOnIrPrev(void) large; 
#ifdef FLMENU_FUNC_TEST 
static BOOL fgFlMnOnIrNextFile(void) large; 
static BOOL fgFlMnOnIrPrevFile(void) large; 
#endif 
static BOOL fgFlMnOnIrRepeat(void) large; 
static BOOL fgFlMnOnIrRandom(void) large; 
 
#ifdef ISO_AUTO_PLAY 
  static BOOL fgFlAutoPlayStart(void) large; 
  static BOOL fgFlAutoPlayNext(void) large; 
  static BOOL fgFlAutoPlayQuit(void) large; 
#endif 
 
static BOOL fgFlMnChgInfoPanel(void) large; 
static void vShowJpegInfo(void) large; 
 
#if 0 
static code BYTE _pbListType[] =  
{ 
  FLPARM_LIST_FOLDER 
#ifdef FLMN_SUPPORT_FILELIST 
  , FLPARM_LIST_DISC 
#endif 
#ifdef FLMN_SUPPORT_PLAYLIST 
  , FLPARM_LIST_PLAYLIST 
#endif 
}; 
#endif 
 
// Global Variables 
static xdata WORD _wFlMnLstFirst; 
static xdata WORD _wFlMnPlFirst; 
static xdata WORD _wBaseDir; 
 
static xdata BYTE _bFlMnTimer; 
static xdata BYTE _bFlMnShift; 
//xdata BYTE _bShiftPos; 
 
 
//////////////////////////////////////////////////////////////////////////////// 
// 
 
#ifdef ENABLE_ID3 
 
static code BYTE _pbId3V1Tag[3] = { 'T', 'A', 'G' }; 
static code BYTE _pbId3V1FldLen[ID3V1_MAX] =  { 3, 30, 30, 30,  4, 30 , 1 }; 
static code BYTE _pbId3V1FldPos[ID3V1_MAX] =  { 0, 3, 33, 63, 93, 97, 127 }; 
 
static void vFlGetId3Info(void) large 
{ 
  DWRD  dwAddr; 
  BYTE  pbStr[31]; 
  BYTE  bFld, bLen, i, bChar; 
    #ifndef MT1379_MANUFACTURE_TEST 
 
  vPlayerShowLogo(ISO_STOP_LOGO, ISO_LOGO_COLOR);     
 
#endif 
  bLoByte(wLoWord(dwAddr)) = bSharedInfo(SI_MP3_ID3TAG_B1); 
  bHiByte(wLoWord(dwAddr)) = bSharedInfo(SI_MP3_ID3TAG_B2); 
  bLoByte(wHiWord(dwAddr)) = bSharedInfo(SI_MP3_ID3TAG_B3); 
  bHiByte(wHiWord(dwAddr)) = bSharedInfo(SI_MP3_ID3TAG_B4); 
 
  if (dwAddr == 0xffffffff) 
    return; 
 
  for (bFld=0, bLen=0; bFld < ID3V1_MAX; bFld++) 
  { 
    pbStr[0] = _pbId3V1FldLen[bFld]; 
    for (i=0; i<_pbId3V1FldLen[bFld]; i++) 
    { 
      bChar = bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)); 
       
      if (bFld == 0) 
      { 
        if (bChar != _pbId3V1Tag[i]) 
          return; 
      } 
 
      if (bChar == 0x00) 
      { 
        pbStr[0] = i; 
        dwAddr += (_pbId3V1FldLen[bFld] - i); 
        break;         
      } 
      else 
      { 
        pbStr[i+1] = bChar; 
        dwAddr ++; 
      } 
    } 
 
    if (bFld != 0) 
    { 
      _wStartX = (WORD) FLMN_PREVIEW_X - FSMENU_BASIC_WB_LEFT; 
      _wStartY = (WORD) FLMN_PREVIEW_Y - FSMENU_BASIC_WB_TOP + 15 + 30 * bFld; 
      vOsdShowStrMax(FL_MENU_WB, pbStr, 200, 0); 
    } 
  } 
} 
#endif 
 
//////////////////////////////////////////////////////////////////////////////// 
// 
 
#ifdef ISO_LAST_MEM 
static void vFlMnGetLastMemItem(void) large 
{ 
  WORD  wSlotSa, wIdx; 
   
  _wFlCurAdoIdx = 0xFFFF; 
   
  wSlotSa = wSIItemPos(bSharedInfo(SI_DDISC_LASTMEM_GRP), 1); 
   
  wSlotSa += ((bSharedInfo(SI_DDISC_LASTMEM_NS)-1) * 
               bSharedInfo(SI_DDISC_MEM_SLOT_SZ)); 
 
  wSlotSa++; 
   
  if (bSharedInfo(wSlotSa) != SV_MEM_SLOT_DDISC) 
  { 
    return; 
  } 
   
  wSlotSa += 9; 
  bLoByte(wIdx) = bSharedInfo(wSlotSa); 
  wSlotSa ++; 
  bHiByte(wIdx) = bSharedInfo(wSlotSa); 
  _wFlCurAdoDir = wIdx; 
   
  wSlotSa ++; 
  bLoByte(wIdx) = bSharedInfo(wSlotSa); 
  wSlotSa ++; 
  bHiByte(wIdx) = bSharedInfo(wSlotSa); 
 
  _wFlCurAdoIdx = wIdx; 
  if (_wFlCurAdoDir != 0)   
    _wFlCurAdoIdx++; 
} 
#endif 
#ifdef MT1379_MANUFACTURE_TEST 
extern void vNotMp4CD() large; 
#endif 
 
//////////////////////////////////////////////////////////////////////////////// 
// Command return 
 
/** 
 * Check the return value of command "FLCMD_CREATE". 
 */ 
static void vFlMnRetCreate(void) large 
{ 
  WORD wBlkPtr; 
  BYTE bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  // - mark the command is done 
  vFlCmdDone(); 
   
  if (bRCode == FLRET_S_OK) 
  { 
    // - read in the newly created list info 
    if (fgFlClIsLock()) 
    { 
      switch(bFlClPath()) 
      { 
        case FL_CMDPATH_INIT_0: 
          _bFlMnListId = bSharedInfo(wBlkPtr ++); 
          vFlMnRdListInfo(_bFlMnListId); 
#ifdef ISO_AUTO_PLAY 
          vFlClNext(); 
          vFlCmdCreate(FLPARM_LIST_DISC, 0, 0x0,  
        #ifdef MT1379_MANUFACTURE_TEST 
                       FLPARM_FF_MPG, 
        #else  
                       FL_AUDIO_FILE,  
        #endif 
                       FLPARM_SO_GDIR); 
          break; 
 
        case FL_CMDPATH_INIT_1: 
          _bFlRefListId = bSharedInfo(wBlkPtr ++); 
        #ifdef MT1379_MANUFACTURE_TEST 
          vFlMnRdListInfo(_bFlRefListId); 
          #ifdef RS232_LOG 
            DRS232LogS("Aft FlCreate"); 
            DRS232LogB(_wFlMnListLen,0,0,0); 
          #endif 
              
          if (!_wFlMnListLen) 
            vNotMp4CD(); 
          else 
            vFlCmdClickItem(_bFlRefListId, 0); 
        #endif 
 
#endif 
          if (bSharedInfo(SI_DISC_TYPE) == SV_PCD) 
          { 
            vFlSetCmdTarget(FL_CMD_TARGET_JPEG); 
          } 
          else 
          { 
            if (_wFlCurAdoIdx == 0xFFFF) 
            { 
              fgFlCmdGetItems(_bFlMnListId, 0); 
              //vFlSetCmdTarget(FL_CMD_TARGET_MENU); 
            } 
            else 
            { 
              _bFlMnCurItemIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
              fgFlCmdGetItems(_bFlMnListId, _wFlCurAdoIdx - _bFlMnCurItemIdx); 
            } 
          } 
          break; 
      } 
    } 
  } 
  else 
  { 
    // - error occurs 
    _bFlMnListId = 0xFF; 
    _bFlRefListId = 0xFF; 
  } 
 
  return; 
} 
 
/** 
 * Check the return value of command "FLCMD_SET". 
 */ 
static void vFlMnRetSet(void) large 
{ 
  WORD wBlkPtr; 
  BYTE bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  //bRetOp = bFlCmdRetOp(); 
  // - mark the command is done 
  vFlCmdDone(); 
 
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful 
    vFlMnRdListInfo(_bFlMnListId); 
    if (fgFlClIsLock()) 
    { 
      switch(bFlClPath()) 
      { 
        case FL_CMDPATH_RETURN: 
          _bFlMnCurItemIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
          fgFlCmdGetItems(_bFlMnListId, _wFlCurAdoIdx - _bFlMnCurItemIdx); 
          break; 
        case FL_CMDPATH_CHG_DIR: 
        case FL_CMDPATH_DIR_UP_0: 
        case FL_CMDPATH_DIR_UP_1: 
          _bFlMnCurItemIdx = 0x0; 
          fgFlCmdGetItems(_bFlMnListId, 0); 
          break; 
        case FL_CMDPATH_CHG_LIST: 
          fgFlCmdGetItems(_bFlMnListId, 0x0); 
          break; 
        case FL_CMDPATH_ATPLY_1: 
          _wFlCurAdoIdx += wFlGetSubFldrNs(_bFlMnListId); 
          fgFlCmdGetItems(_bFlMnListId, _wFlCurAdoIdx - (_wFlCurAdoIdx % FLMN_ITEM_N)); 
          break; 
      } 
    } 
    else 
    { 
#if 0 
      if (bRetOp == FLCMD_RET_OP_CHG_LIST) 
        fgFlCmdGetItems(_bFlMnListId, 0x0); 
      else 
#endif 
        fgFlCmdGetItems(_bFlMnListId, 0x0); 
         
      _bFlMnCurItemIdx = 0x0; 
    } 
  } 
  else 
  { 
    // - error occurs 
  } 
 
  return; 
} 
 
/** 
 * Check the return value of command "FLCMD_GET_ITEMS". 
 */ 
static void vFlMnRetGetItems(void) large 
{ 
  WORD wBlkPtr; 
  WORD wNum; 
  BYTE bType; 
  BYTE bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
   
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful, update the item number, redraw the page 
    _bFlMnItemNs = bSharedInfo(wBlkPtr ++); 
    vFlCmdDone(); 
 
    switch(bFlClPath()) 
    { 
    #ifdef ISO_AUTO_PLAY 
      case FL_CMDPATH_INIT_1: 
    #else 
      case FL_CMDPATH_INIT_0: 
    #endif 
        vFlSetCmdTarget(FL_CMD_TARGET_MENU); 
        break; 
      case FL_CMDPATH_CHG_LIST: 
        vFlIpShowInfo(IP_INFO_LIST_TYPE, bSharedInfo(FL_LIST_FIELD(_bFlMnListId)), 0); 
      case FL_CMDPATH_CHG_DIR: 
      case FL_CMDPATH_REDRAW: 
      case FL_CMDPATH_DIR_UP_1: 
      case FL_CMDPATH_UP: 
      case FL_CMDPATH_DOWN: 
      case FL_CMDPATH_RETURN: 
        vFlMnSyncState(); 
        vFlMnDrawPage(); 
        fgFlMnEntItem(_bFlMnCurItemIdx); 
        vFlClRls(); 
#ifdef CDFS_AUTO_PLAY    
        if((bFlClPath() == FL_CMDPATH_REDRAW) && (bSharedInfo(SI_FS_FSTYPE) == FSTYPE_CDFS)) 
        {  
          if((!_bFlMnCurItemIdx) && (bSharedInfo(SI_PBC_STATE) == SV_STOP)) 
          {       
#ifdef RS232_LOG 
          DBGLogS(" send play \n "); 
        #endif     
            fgSetPlayPostKey(IR_PLAY); 
          } 
        } 
#endif         
        break; 
      case FL_CMDPATH_SEL_2: 
        vFlMnDrawPage(); 
        fgFlMnEntItem(_bFlMnCurItemIdx); 
        vFlClRls(); 
        break; 
      case FL_CMDPATH_DIR_DOWN: 
        fgFlMnEntDir(0x0, FALSE); 
        break; 
      case FL_CMDPATH_DIR_UP_0: 
        vFlClNext(); 
        fgFlMnEntDir(0x0, TRUE); 
        break; 
      case FL_CMDPATH_PL_RM: 
        vFlMnDrawPage(); 
        fgFlMnEntItem(_bFlMnCurItemIdx); 
        vFlClRls(); 
        break; 
      case FL_CMDPATH_SEL_0: 
        _fgFlMdChg = TRUE; 
        switch (bFlGetItemType(_bFlMnCurItemIdx)) 
        { 
          case FTYPE_FOLDER: 
            vFlClNext(); 
            if (fgIsParentDir()) 
              vParseFolderName(_bFlMnCurItemIdx, TRUE); 
            else 
              vParseFolderName(_bFlMnCurItemIdx, FALSE); 
            vFlSetCmdTarget(FL_CMD_TARGET_MENU); 
            break; 
          case FTYPE_AUDIO:  
            vFlClNext(); 
            vFlSetCmdTarget(FL_CMD_TARGET_MENU); 
            break; 
          case FTYPE_STILL: 
            vFlClNext(); 
            vFlSetCmdTarget(FL_CMD_TARGET_JPEG); 
            break; 
          case FTYPE_AV: 
            vFlClNext(); 
            vFlSetCmdTarget(FL_CMD_TARGET_MPEG); 
            break; 
        } 
        break; 
#ifdef ISO_AUTO_PLAY 
      case FL_CMDPATH_ATPLY_0: 
        vFlCmdQueryItem(_bFlRefListId, _wFlAtplyIdx); 
        break; 
      case FL_CMDPATH_ATPLY_1: 
        _bFlMnCurItemIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
     #ifdef FL_AUTO_PLAY_SYNC_MENU         
        vFlMnDrawPage(); 
        fgFlMnEntItem(_bFlMnCurItemIdx); 
     #endif         
        vFlCmdClickItem(_bFlMnListId, _wFlCurAdoIdx); 
        break; 
#endif 
    } 
  } 
  else 
  { 
    // - error occurs, mark the number of item is negative 
    vFlCmdDone();    
     
    switch(bFlClPath()) 
    { 
      case FL_CMDPATH_CHG_LIST: 
        bType = bSharedInfo(FL_LIST_FIELD(_bFlMnListId)); 
        switch (bType) 
        { 
          case FLPARM_LIST_FOLDER: 
#if defined (DATA_DISC_SUPPORT_DISC_LIST) 
            bType = FLPARM_LIST_DISC; 
            _wFlCurAdoIdx = _wFlFdIdx; 
#elif defined (DATA_DISC_SUPPORT_PLAY_LIST) 
            bType = FLPARM_LIST_PLAYLIST; 
            _wFlCurAdoIdx = _wFlFlIdx; 
#else 
            _wFlCurAdoIdx = _wFlPlIdx; 
#endif 
            break; 
 
#ifdef DATA_DISC_SUPPORT_DISC_LIST 
          case FLPARM_LIST_DISC: 
 #if defined (DATA_DISC_SUPPORT_PLAY_LIST) 
            bType = FLPARM_LIST_PLAYLIST; 
            _wFlCurAdoIdx = _wFlFlIdx; 
 #else 
            bType = FLPARM_LIST_FOLDER; 
            _wFlCurAdoIdx = _wFlPlIdx; 
 #endif 
            break; 
#endif 
 
          case FLPARM_LIST_INVALID: 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST  
          case FLPARM_LIST_PLAYLIST: 
#endif 
            bType = FLPARM_LIST_FOLDER; 
            _wFlCurAdoIdx = _wFlPlIdx; 
            break; 
        } 
         
#if 0 
        if (bType == FLPARM_LIST_PLAYLIST) 
        { 
          vSetSharedInfo(SI_DDISC_MIXED_TYPE_MODE, SV_ON); 
          vSetSharedInfo(SI_DDISC_CONC_AV_MODE, SV_OFF); 
        } 
        else 
        { 
          vSetSharedInfo(SI_DDISC_MIXED_TYPE_MODE, SV_OFF); 
          vSetSharedInfo(SI_DDISC_CONC_AV_MODE, SV_ON); 
        } 
#endif 
        if (bType == FLPARM_LIST_FOLDER) 
        { 
          vFlCmdSet(_bFlMnListId, bType, 
                    FLPARM_INC_PARENT, _wBaseDir, FLPARM_FF_DIR|FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
        } 
        else 
        { 
          vFlCmdSet(_bFlMnListId, bType, 0xFF,  
                    0xFFFF, FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
        } 
        break; 
      default: 
        //vFlCmdDone(); 
        _bFlMnCurItemIdx = 0xFF; 
        _bFlMnItemNs = 0xFF; 
        break; 
    } 
  } 
 
  return; 
} 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
/** 
 * Check the return value of command "FLCMD_RM_FROM_PL". 
 */ 
void vFlMnRetRmFromPl(void) large 
{ 
  WORD  wBlkPtr; 
  BYTE  bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  vFlCmdDone(); 
 
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful 
    _wFlMnListLen = bSharedInfo(wBlkPtr ++); 
    if (_wFlMnListLen) 
    { 
      if (_bFlMnCurItemIdx >= _wFlMnListLen) 
        _bFlMnCurItemIdx--; 
      if (fgFlClLock(FL_CMDPATH_PL_RM)) 
        fgFlCmdGetItems(_bFlMnListId, 0x0); 
    } 
    else 
    { 
      fgFlMnChgListType(); 
    } 
  } 
  else 
  { 
    // - error occurs 
    _wFlMnListLen = 0xFF; 
  } 
 
  return; 
} 
 
/** 
 * Check the return value of command "FLCMD_CLEAN". 
 */ 
static void vFlMnRetRmAllFromPl(void) large 
{ 
  WORD wBlkPtr; 
  BYTE bRCode; 
 
  vFlCmdDone(); 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful 
    fgFlMnChgListType(); 
  } 
  else 
  { 
    // - error occurs 
  } 
} 
#endif 
 
static void vFlMnRetQueryItem(void) large 
{ 
  WORD  wBlkPtr, wTmp; 
  BYTE  bRCode; 
  BYTE  bTmp1, bTmp2; 
   
   
  wBlkPtr = FL_CMD_BLK_SA + 1; 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  if ((bRCode != FLRET_S_OK) || !fgFlClIsLock()) 
    return; 
   
  vFlCmdDone(); 
 
  switch (bFlClPath()) 
  { 
    case FL_CMDPATH_ATPLY_0: 
      vFlClNext(); 
      wBlkPtr += 5; 
      bLoByte(wTmp) = bSharedInfo(wBlkPtr); 
      bHiByte(wTmp) = bSharedInfo(wBlkPtr + 1); 
      if (_wFlCurAdoDir != wTmp) 
      { 
        _wFlCurAdoDir = wTmp; 
        bLoByte(_wFlCurAdoIdx) = bSharedInfo(wBlkPtr + 2); 
        bHiByte(_wFlCurAdoIdx) = bSharedInfo(wBlkPtr + 3); 
        vFlCmdSet(_bFlMnListId, FLPARM_LIST_FOLDER, 
                  FLPARM_INC_PARENT, _wFlCurAdoDir, FLPARM_FF_DIR|FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
      } 
      else  
      { 
        bLoByte(wTmp) = bSharedInfo(wBlkPtr + 2); 
        bHiByte(wTmp) = bSharedInfo(wBlkPtr + 3); 
 
        bTmp1 = (BYTE) (wTmp % FLMN_ITEM_N); 
        bTmp2 = (BYTE) (_wFlCurAdoIdx % FLMN_ITEM_N); 
 
        if ((bTmp1 > bTmp2) && (bTmp1 < (bTmp2 + FLMN_ITEM_N))) 
        { 
          vFlCmdClickItem(_bFlMnListId, _wFlCurAdoIdx); 
        } 
        else 
        { 
          fgFlCmdGetItems(_bFlMnListId, _wFlCurAdoIdx - (_wFlCurAdoIdx % FLMN_ITEM_N)); 
        } 
     } 
 
     break; 
  } 
 
  return; 
} 
 
//////////////////////////////////////////////////////////////////////////////// 
// 
 
/** 
 * This function draw the file name of the given item by the  
 *  new OSD command "vpast_msg_addr". 
 * 
 * It also demos how to get item info from descriptor. 
 */ 
void vFlMnDrawItem(BYTE bItemIdx) large 
{ 
  DWRD dwAddr; 
  WORD wPos; 
  BYTE bFType, bStrLen; 
  WORD wIdx, wDirIdx; 
  BYTE pbStr[4]; 
  BOOL fgIsPrnt = TRUE; 
 
  wPos = FL_ITEM_FIELD(bItemIdx); 
 
  // - collect misc info 
  bFType = bSharedInfo(wPos + 5); 
  bLoByte(wIdx) = bSharedInfo(wPos + 6); 
  bHiByte(wIdx) = bSharedInfo(wPos + 7); 
  if (bFType == FTYPE_DIR) 
  { 
    bLoByte(wDirIdx) = bSharedInfo(wPos + 12); 
    bHiByte(wDirIdx) = bSharedInfo(wPos + 13); 
  } 
 
  // - collect name info 
  bLoByte(wLoWord(dwAddr)) = bSharedInfo(wPos); 
  bHiByte(wLoWord(dwAddr)) = bSharedInfo(wPos + 1); 
  bLoByte(wHiWord(dwAddr)) = bSharedInfo(wPos + 2); 
  bHiByte(wHiWord(dwAddr)) = bSharedInfo(wPos + 3); 
  bStrLen = bSharedInfo(wPos + 4); 
 
  // - preprocess the name string 
  if (!((bStrLen == 1) && (bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)) == 0x01))) 
  { 
    fgIsPrnt = FALSE; 
    vFlMnPProcName(&dwAddr, &bStrLen);     
  } 
 
  // - paste icon 
  vOsdPasteBmpXY(_prFlMnItemTbl[bItemIdx].wLeft, 
                 _prFlMnItemTbl[bItemIdx].wTop, 
                 FL_MENU_WB, bFlMnGetIconIdx(bFType)); 
 
  // - paste the message of file name 
  _wStartX = _prFlMnItemTbl[bItemIdx].wLeft + FL_ICON_W; 
  _wStartY = _prFlMnItemTbl[bItemIdx].wTop; 
 
  //if (bStrLen == 0) 
  if (fgIsPrnt) 
  { 
    // - special case " .." as the string of parent dir 
    pbStr[0] = 3; 
    pbStr[1] = ' '; 
    pbStr[2] = pbStr[3] = '.'; 
    vOsdShowStr(FL_MENU_WB, pbStr); 
  } 
  else 
  { 
    vPasteMsgAddr(FL_MENU_WB, bStrLen, dwAddr); 
  } 
   
  if (fgFlMnIsCurrPlayItem(bItemIdx)) 
  { 
    //vFlMnHiliItem(bItemIdx, TRUE); 
    vFlMnHiliOn(bItemIdx, FLMN_HILI_PLAY, FLMN_CLR_BG, FLMN_CLR_PLAY); 
  } 
   
  return; 
} 
 
/** 
 * Preprocess the given name string. The namae string is given by 
 *  pointer to it and its length. We adjust the pointer and the len to 
 *  indicate the new string. 
 * 
 * The current preprocess includes: 
 *  1. Cut out the extension name 
 *  2. Etc ... 
 */ 
void vFlMnPProcName(DWRD *pdwAddr, BYTE *pbLen) large 
{ 
  BYTE bChar, bIdx, bLen; 
  DWRD dwAddr; 
 
  if (!pdwAddr || !pbLen) 
    return; 
 
  dwAddr = (DWRD)(*pdwAddr); 
  bLen = (*pbLen); 
 
  // - move the pointer to the end of the string 
  dwAddr += (DWRD)bLen; 
 
  // - check each char 
  for (bIdx = 1; bIdx < bLen; bIdx ++) 
  { 
    dwAddr --; 
    bChar = bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)); 
    if (bChar == '.') 
      break; 
  } 
 
  // - cut out the ext 
  if (bIdx < bLen) 
    bLen -= bIdx; 
 
#ifdef FLMN_DONT_SHOW_NONPRINTABLE_CHAR 
  dwAddr = (DWRD)(*pdwAddr); 
  for (bIdx = 0; bIdx < bLen; bIdx++, dwAddr++) 
  { 
    bChar = bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)); 
    if ((bChar < 0x20) || (bChar > 0x7E)) 
    { 
      WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), '_'); 
    } 
  } 
#endif 
 
  if (bLen > FLMN_FILENANE_LEN) 
    bLen = FLMN_FILENANE_LEN; 
 
  (*pbLen) = bLen; 
} 
#if 1//def JPG_INFO 
static void vShowJpegInfo(void) large 
{ 
  BYTE  pbStr[9], i; 
  WORD  wTmp; 
 
  pbStr[0] = 8; 
  wTmp = (WORD) bSharedInfo(SI_JPG_ORG_WIDTH_HI) * 256 + (WORD) bSharedInfo(SI_JPG_ORG_WIDTH_LO); 
  wTmp = wWRDToBCD(wTmp); 
  pbStr[1] = BCD_HI(bHiByte(wTmp)) + '0'; 
  pbStr[2] = BCD_LO(bHiByte(wTmp)) + '0'; 
  pbStr[3] = BCD_HI(bLoByte(wTmp)) + '0'; 
  pbStr[4] = BCD_LO(bLoByte(wTmp)) + '0'; 
  for (i=1; i<=4; i++) 
  { 
    if (pbStr[i] == '0') 
      pbStr[i] = ' '; 
    else 
      break; 
  } 
  wTmp = (WORD) bSharedInfo(SI_JPG_ORG_HEIGHT_HI) * 256 + (WORD) bSharedInfo(SI_JPG_ORG_HEIGHT_LO); 
  wTmp = wWRDToBCD(wTmp); 
  pbStr[5] = BCD_HI(bHiByte(wTmp)) + '0'; 
  pbStr[6] = BCD_LO(bHiByte(wTmp)) + '0'; 
  pbStr[7] = BCD_HI(bLoByte(wTmp)) + '0'; 
  pbStr[8] = BCD_LO(bLoByte(wTmp)) + '0'; 
  for (i=5; i<=8; i++) 
  { 
    if (pbStr[i] == '0') 
      pbStr[i] = ' '; 
    else 
      break; 
  } 
   
  vOsdPosShowArg(OSD_POS_FS_INFO_BAR, OSD_MSG_FL_RESOLUTION, OSD_NO_DISAPPEAR, pbStr); 
} 
#endif 
/** 
 * Check the return value of command "FLCMD_CLICK_ITEM". 
 */ 
void vFlMnRetClickItem(void) large 
{ 
  WORD  wBlkPtr, wItem; 
  BYTE  bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  vFlCmdDone(); 
   
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful 
    switch (bSharedInfo(wBlkPtr ++)) 
    { 
    case FTYPE_DIR: 
      // - we clicked a dir, the list goes into it. 
      //    re-get items for redraw later 
      vFlMnRdListInfo(_bFlMnListId); 
      bLoByte(wItem) = bSharedInfo(wBlkPtr ++); 
      bHiByte(wItem) = bSharedInfo(wBlkPtr); 
      _bFlMnCurItemIdx = wItem % FLMN_ITEM_N; 
      fgFlCmdGetItems(_bFlMnListId, wItem - _bFlMnCurItemIdx); 
      break; 
    case FTYPE_JPG: 
      // - we clicked a JPEG file 
      switch (bFlClPath()) 
      { 
        case FL_CMDPATH_CHG_CMDTGT: 
        case FL_CMDPATH_RPLC_CMDTGT: 
        case FL_CMDPATH_SEL_2: 
          vFlClRls(); 
          break; 
        case FL_CMDPATH_CLICK: 
          vFlClRls(); 
#ifdef JPG_PREVIEW_SUPPORT            
          if (_bPreview == PREVIEW_STATE_FINISHED) 
          { 
            // - clicked for preview 
            _bPreview = PREVIEW_STATE_IDLE; 
          } 
          else 
#endif           
          { 
            // - clicked for selection 
            if (fgFlClLock(FL_CMDPATH_CHG_CMDTGT)) 
              vFlSetCmdTarget(FL_CMD_TARGET_JPEG); 
          } 
          break; 
      } 
      break; 
#ifdef CDDA_USE_CDFS 
    case FTYPE_CDA: 
    case FTYPE_DTS: 
#endif        
    case FTYPE_MP1: 
    case FTYPE_MP2: 
    case FTYPE_MP3: 
    case FTYPE_WMA: 
      // - we clicked a Audio file 
      switch (bFlClPath()) 
      { 
        case FL_CMDPATH_SEL_2: 
          vFlMnDrawPage();         
          vFlMnHiliItem(_bFlMnCurItemIdx, TRUE); 
          _wFlCurAdoDir = wFlMnGetListBaseDir(_bFlMnListId); 
          _wFlCurAdoIdx = wFlGetItemIdx(_bFlMnCurItemIdx); 
          vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, _wFlCurAdoIdx); 
          break; 
#ifdef ISO_AUTO_PLAY           
        case FL_CMDPATH_ATPLY_1: 
          break; 
#endif 
      } 
      vFlClRls(); 
      break; 
#ifdef DATA_DISC_CDFS_SUPPORT            
  #ifdef CDG_SUPPORT 
    case FTYPE_CDG: 
      if(bSharedInfo(SI_CDG_DISC) == SV_ON) 
      { 
        vFlClRls(); 
        vDeleteWB(FL_MENU_WB); 
        vDeleteWB(FL_INFO_WB); 
      }       
      break; 
  #endif       
#endif       
    case FTYPE_MPG: 
    case FTYPE_DAT: 
    case FTYPE_VOB: 
    case FTYPE_AVI: 
    case FTYPE_TS1: 
    case FTYPE_TS2: 
    case FTYPE_TS3: 
      vFlClRls(); 
      vFlSetCmdTarget(FL_CMD_TARGET_MPEG); 
      break; 
    default: 
      // - other case 
      break; 
    } 
  } 
  else 
  { 
    // - error occurs, do nothing 
  } 
 
  return; 
} 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
 
/** 
 * Check the return value of command "FLCMD_ADD_TO_PL". 
 */ 
void vFlMnRetAddToPl(void) large 
{ 
  WORD wBlkPtr; 
  BYTE bRCode; 
 
  wBlkPtr = FL_CMD_BLK_SA + 1; // - shift to the parameter block 
  bRCode = bSharedInfo(wBlkPtr ++); 
 
  vFlCmdDone(); 
 
  if (bRCode == FLRET_S_OK) 
  { 
    // - successful 
//    _wFlMnPlLen = bSharedInfo(wBlkPtr ++); 
    vOsdPosShow(OSD_POS_FS_INFO_BAR, OSD_MSG_FL_ADD_TO_PLAYLIST, OSD_TIMEOUT_SHORT); 
  } 
  else 
  { 
    // - error occurs 
//    _wFlMnPlLen = 0xFF; 
  } 
 
  return; 
} 
#endif 
 
 
/** 
 * Display a page with the prepared items. Mark the hovered item by hili if  
 *  necessary. 
 * 
 * DES: 
 *  1. clear the previous display 
 *  2. redraw the slider 
 *  3. draw the full path 
 *  4. draw each items 
 * 
 * NOTE: demo how to get the item info when the command "FLCMD_GET_ITEMS"  
 *  suceeds. 
 */ 
static void vFlMnDrawPage(void) large 
{ 
  BYTE  bItemIdx; 
 
  // - clear the page first 
  vFlMnClrPage(); 
 
  // - redraw the slider 
  _wStartX = FS_SLIDER_X; 
  _wEndX = FS_SLIDER_X + FS_SLIDER_W; 
  _wStartY = FS_SLIDER_Y; 
  _wEndY = FS_SLIDER_Y + FS_SLIDER_H; 
  vRectangle(FL_MENU_WB, 0, 0, 1, 0); 
#ifdef SHOW_FS_SLIDER 
  vDrawSlider(wFlGetItemIdx(_bFlMnCurItemIdx), _wFlMnListLen); 
#endif 
 
  // - draw the full path name 
  if (!_fgFlIsAutoPlay) 
  { 
    if (bSharedInfo(FL_LIST_FIELD(_bFlMnListId)) == FLPARM_LIST_FOLDER) 
      vDrawFolderName(TRUE); 
    else 
      vDrawFolderName(FALSE); 
  } 
 
  _bFlMnMemLock = FALSE; 
  //vFlClRls(); 
 
  // - draw items 
  vSetMsgCol4(FL_MENU_WB, 0, 0, 2, 3); 
  for (bItemIdx = 0;  
       (bItemIdx < _bFlMnItemNs) && (bItemIdx < FLMN_PAGE_SZ);  
       bItemIdx ++) 
  { 
    vFlMnDrawItem(bItemIdx); 
  } 
  vSetMsgCol4(FL_MENU_WB, 0, 0, 3, 2); 
   
  return; 
} 
 
/** 
 * Redraw the display of the object "file list menu". 
 */ 
#ifdef WB_ALLOC_MIN 
void vFlMnRecover(void) large 
{ 
  // - enable the white boards used by this object 
  vCreateWBEx(FL_MENU_WB); 
  vFlMnDrawInfoPanel(_bFlIpState); 
  vFlMnDrawPage(); 
  vFlMnHiliItem(_bFlMnCurItemIdx, TRUE); 
   
  vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wFlGetItemIdx(_bFlMnCurItemIdx)); 
#if 1//def JPG_INFO 
  vOsdPosClear(OSD_POS_FS_INFO_BAR); 
#endif 
#ifdef JPG_PREVIEW_SUPPORT  
  if (_bFlMnItemType == FTYPE_STILL) 
  { 
    _bPreview = PREVIEW_STATE_START; 
  } 
#endif 
 
  vFlUpdateVfd(TRUE); 
 
#ifdef CDG_SUPPORT 
  if(bSharedInfo(SI_CDG_DISC) == SV_ON) 
  { 
    if(bSharedInfo(SI_PBC_STATE) == SV_STOP) // != SV_PLAY  //windy 
    { 
      vPlayerShowLogo(ISO_STOP_LOGO, ISO_LOGO_COLOR);     
    } 
  } 
#endif   
 
  return; 
} 
#else 
void vFlMnRecover(void) large 
{ 
  // - disable all white board used outside 
  //vHideHL(FSMENU_HOVER_HILIT); 
  //vOsdShowWb(OSD_WB_FULL_SCR); 
 
  // - enable the white boards used by this object 
  vEnableWB(FL_INFO_WB);    // - for dynamic info 
  vEnableWB(FL_MENU_WB);    // - for menu 
#if 1//def JPG_INFO 
  vOsdPosClear(OSD_POS_FS_INFO_BAR); 
#endif 
#ifdef JPG_PREVIEW_SUPPORT  
  if (_bFlMnItemType == FTYPE_STILL) 
  { 
    _bPreview = PREVIEW_STATE_START; 
  } 
#endif 
 
  vFlUpdateVfd(TRUE); 
 
  return; 
} 
#endif 
 
/** 
 * Clear all item on the page. 
 */ 
void vFlMnClrPage(void) large 
{ 
  BYTE bItemIdx; 
 
  _wStartX = FS_SLIDER_X; 
  _wEndX = FS_SLIDER_X + FS_SLIDER_W; 
  _wStartY = FS_SLIDER_Y; 
  _wEndY = FS_SLIDER_Y + (WORD) FS_SLIDER_H; 
  vRectangle(FL_MENU_WB, 0, 0, 1, 0); 
 
  // - clear OSD message 
  for (bItemIdx = 0; bItemIdx < FLMN_PAGE_SZ; bItemIdx ++) 
  { 
    vOsdClearPosXY(_prFlMnItemTbl[bItemIdx].wLeft,  
                   _prFlMnItemTbl[bItemIdx].wTop, 
                   FL_MENU_WB, 
                   FLMN_ITEM_W, FLMN_ITEM_H); 
  } 
 
  return; 
} 
 
static WORD wFlMnGetListBaseDir(BYTE bListId) large 
{ 
  WORD  wPos, wBaseDir; 
  
  if (bListId > 4) 
    return 0xFFFF; 
  
  wPos = FL_LIST_FIELD(bListId); 
  bLoByte(wBaseDir) = bSharedInfo(wPos + 2); 
  bHiByte(wBaseDir) = bSharedInfo(wPos + 3); 
   
  return wBaseDir; 
} 
 
#if 0 
static BOOL fgFlMnIsCurrPlay(BYTE bItemIdx) large 
{ 
  if ((_wFlCurAdoDir == 0xFFFF) || (_wFlCurAdoIdx == 0xFFFF)) 
    return FALSE; 
 
  if ((_wFlCurAdoDir == wFlMnGetListBaseDir(_bFlMnListId)) &&  
      (_wFlCurAdoIdx == wFlGetItemIdx(bItemIdx))) 
      return TRUE; 
       
  return FALSE; 
} 
#endif 
 
/** 
 * Return the icon index of the given type. 
 */ 
BYTE bFlMnGetIconIdx(BYTE bFType) large 
{ 
  switch (bFType) 
  { 
  case FTYPE_MP3: 
  case FTYPE_MP2: 
  case FTYPE_MP1: 
    return BMP_MP3; 
//  case FTYPE_MP2: 
//    return BMP_MP2; 
//  case FTYPE_MP1: 
//    return BMP_MP1; 
  case FTYPE_JPG: 
    return BMP_PIC; 
  case FTYPE_WMA: 
//  case FTYPE_ASF: 
    return BMP_WMA; 
//  case FTYPE_MPG: 
//  case FTYPE_DAT: 
//  case FTYPE_VOB: 
    //return BMP_MPG; 
//  case FTYPE_AVI: 
//    return BMP_AVI; 
  case FTYPE_DIR: 
    return BMP_FOLDER; 
  case FTYPE_CDA: 
#ifdef CDG_SUPPORT 
  case FTYPE_CDG: 
#endif 
    return BMP_MPG; 
  case FTYPE_UNKNOWN: 
  default: 
    return BMP_INVALID; 
  } 
} 
 
static BOOL fgFlMnIsCurrPlayItem(BYTE bIdx) large 
{ 
  if ((_wFlCurAdoDir == wFlMnGetListBaseDir(_bFlMnListId)) && 
      (_wFlCurAdoIdx == wFlGetItemIdx(bIdx))) 
    return TRUE; 
   
  return FALSE; 
} 
 
static void vFlMnHiliOn(BYTE bItemIdx, BYTE bHiliIdx, BYTE bColor1, BYTE bColor2) large 
{ 
  _wStartX = _prFlMnItemTbl[bItemIdx].wLeft + FL_ICON_W; 
  _wEndX = _prFlMnItemTbl[bItemIdx].wRight; 
  _wStartY = _prFlMnItemTbl[bItemIdx].wTop; 
  _wEndY = _prFlMnItemTbl[bItemIdx].wBottom; 
 
  switch (bHiliIdx) 
  { 
    case FLMN_HILI_SEL: 
//      if (_bFlMnHiliPos1 != 0x0F) 
//        return;     
      _bFlMnHiliClrSrc1 = bColor1; 
      _bFlMnHiliClrDes1 = bColor2; 
      _bFlMnHiliPos1 = bItemIdx; 
      break; 
    case FLMN_HILI_PLAY: 
//      if (_bFlMnHiliPos2 != 0x0F) 
//        return;     
      _bFlMnHiliClrSrc2 = bColor1; 
      _bFlMnHiliClrDes2 = bColor2; 
      _bFlMnHiliPos2 = bItemIdx; 
      break; 
  } 
  vChgColRep(FL_MENU_WB, bColor1, bColor2); 
} 
   
static void vFlMnHiliOff(BYTE bHiliIdx) large 
{ 
  switch (bHiliIdx) 
  { 
    case FLMN_HILI_SEL: 
      if (_bFlMnHiliPos1 == 0x0F) 
        return; 
 
      _wStartX = _prFlMnItemTbl[_bFlMnHiliPos1].wLeft + FL_ICON_W; 
      _wEndX = _prFlMnItemTbl[_bFlMnHiliPos1].wRight; 
      _wStartY = _prFlMnItemTbl[_bFlMnHiliPos1].wTop; 
      _wEndY = _prFlMnItemTbl[_bFlMnHiliPos1].wBottom; 
      //vChgColRep(FL_MENU_WB, _bFlMnHiliClrDes1, _bFlMnHiliClrSrc1); 
      vChgColRep(FL_MENU_WB, _bFlMnHiliClrDes1, FLMN_CLR_BG); 
 
      _bFlMnHiliClrSrc1 = 0x0F; 
      _bFlMnHiliClrDes1 = 0x0F; 
      _bFlMnHiliPos1 = 0x0F; 
      break; 
    case FLMN_HILI_PLAY: 
      if (_bFlMnHiliPos2 == 0x0F) 
        return; 
 
      _wStartX = _prFlMnItemTbl[_bFlMnHiliPos2].wLeft + FL_ICON_W; 
      _wEndX = _prFlMnItemTbl[_bFlMnHiliPos2].wRight; 
      _wStartY = _prFlMnItemTbl[_bFlMnHiliPos2].wTop; 
      _wEndY = _prFlMnItemTbl[_bFlMnHiliPos2].wBottom; 
      //vChgColRep(FL_MENU_WB, _bFlMnHiliClrDes2, _bFlMnHiliClrSrc2); 
      vChgColRep(FL_MENU_WB, _bFlMnHiliClrDes2, FLMN_CLR_BG); 
 
      _bFlMnHiliClrSrc2 = 0x0F; 
      _bFlMnHiliClrDes2 = 0x0F; 
      _bFlMnHiliPos2 = 0x0F; 
      break; 
  } 
} 
 
/** 
 * The turn on/off the given item. 
 * 
 * DES: Use change color to implement this function. 
 */ 
static void vFlMnHiliItem(BYTE bItemIdx, BOOL fgOn) large 
{ 
  WORD wYOfst, wXOfst; 
  BOOL fgIsCurrPlay; 
 
  if ((bItemIdx >= _bFlMnItemNs) || (bItemIdx >= FLMN_PAGE_SZ)) 
    return; 
     
  _wStartX = _prFlMnItemTbl[bItemIdx].wLeft + FL_ICON_W; 
  _wEndX = _prFlMnItemTbl[bItemIdx].wRight; 
  _wStartY = _prFlMnItemTbl[bItemIdx].wTop; 
  _wEndY = _prFlMnItemTbl[bItemIdx].wBottom; 
 
  fgIsCurrPlay = fgFlMnIsCurrPlayItem(bItemIdx); 
 
  if (fgOn) 
  { 
    if (fgIsCurrPlay) 
    { 
      //vFlMnHiliOff(FLMN_HILI_PLAY); 
      vFlMnHiliOff(FLMN_HILI_PLAY); 
      vFlMnHiliOn(bItemIdx, FLMN_HILI_SEL, FLMN_CLR_BG, FLMN_CLR_SEL); 
      //vFlMnHiliOn(bItemIdx, FLMN_HILI_PLAY, FLMN_CLR_BG, FLMN_CLR_PLAY); 
    } 
    else 
    { 
      vFlMnHiliOn(bItemIdx, FLMN_HILI_SEL, FLMN_CLR_BG, FLMN_CLR_SEL); 
    } 
  } 
  else 
  { 
    if (fgIsCurrPlay) 
    { 
      vFlMnHiliOn(bItemIdx, FLMN_HILI_PLAY, FLMN_CLR_SEL, FLMN_CLR_PLAY); 
    } 
    else 
    { 
      vFlMnHiliOff(FLMN_HILI_SEL); 
    } 
  } 
 
  return; 
} 
 
/** 
 * Perform the operation to the given item when the hover cursor leave it. 
 */ 
static BOOL fgFlMnLeavItem(BYTE bItemIdx) large 
{ 
  if ((bItemIdx >= _bFlMnItemNs) || (bItemIdx >= FLMN_PAGE_SZ)) 
    return FALSE; 
 
  vFlMnHiliItem(bItemIdx, FALSE); 
   
#ifdef ENABLE_ID3 
  if ((_bFlMnItemType == FTYPE_AUDIO) && fgFlMnIsCurrPlayItem(bItemIdx)) 
  { 
    _wStartX = (WORD) FLMN_PREVIEW_X - FSMENU_BASIC_WB_LEFT; 
    _wStartY = (WORD) FLMN_PREVIEW_Y - FSMENU_BASIC_WB_TOP + 15; 
    vOsdClearPos(FL_MENU_WB, 200, 180); 
  } 
#endif 
 
#ifdef SHOW_FS_SLIDER 
  vMoveSlider(wFlGetItemIdx(bItemIdx), _wFlMnListLen, FALSE); 
#endif   
 
#ifdef JPG_PREVIEW_SUPPORT  
  // - terminate the JPEG preview timing 
  _bPreview = PREVIEW_STATE_IDLE; 
#endif 
 
  return TRUE; 
} 
 
/** 
 * Perform the operation to the given item when the hover cursor enter it. 
 */ 
static BOOL fgFlMnEntItem(BYTE bItemIdx) large 
{ 
  WORD  wNum; 
   
  if ((bItemIdx >= _bFlMnItemNs) || (bItemIdx >= FLMN_PAGE_SZ)) 
    return FALSE; 
 
  wNum = wFlGetItemIdx(bItemIdx); 
  vFlMnHiliItem(bItemIdx, TRUE); 
#ifdef SHOW_FS_SLIDER 
  vMoveSlider(wNum, _wFlMnListLen, TRUE); 
#endif 
   
  _bFlMnItemType = bFlGetItemType(bItemIdx); 
 
  vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wNum);   
 
#ifdef JPG_PREVIEW_SUPPORT  
  // - restart the JPEG preview timing if we enter a JPEG file   
  if (_bFlMnItemType == FTYPE_STILL) 
  { 
    _bPreview = PREVIEW_STATE_START; 
  } 
#endif 
 
  // - move current item to the given one 
  _bFlMnCurItemIdx = bItemIdx; 
   
#ifdef ENABLE_ID3 
  if ((_bFlMnItemType == FTYPE_AUDIO) && fgFlMnIsCurrPlayItem(_bFlMnCurItemIdx)) 
  { 
    vFlGetId3Info(); 
  } 
#endif 
 
  vFlUpdateVfd(FALSE); 
 
  return TRUE; 
} 
 
/** 
 * Read in the list info from proper shared info group. 
 */ 
void vFlMnRdListInfo(BYTE bId) large 
{ 
  BYTE bType, bIncItemType; 
  WORD wBsDir, wPos; 
 
  if (bId >= FL_MAX_LIST_NS) 
    return; 
 
  wPos = FL_LIST_FIELD(bId); 
  bType = bSharedInfo(wPos); 
  bIncItemType = bSharedInfo(wPos + 1); 
  bLoByte(wBsDir) = bSharedInfo(wPos + 2); 
  bHiByte(wBsDir) = bSharedInfo(wPos + 3); 
 
  bLoByte(_wFlMnListLen) = bSharedInfo(wPos + 4); 
  bHiByte(_wFlMnListLen) = bSharedInfo(wPos + 5); 
 
  return; 
} 
 
/** 
 * Leave the current dir to its parent. 
 */ 
 
// 20040809 by RC. Roll back to version 36 due to issue CR00000187 
static BOOL fgFlMnLeavDir(void) large 
{ 
  WORD wPos, wBsDir; 
 
  // - check current dir 
  wPos = FL_LIST_FIELD(_bFlMnListId); 
  bLoByte(wBsDir) = bSharedInfo(wPos + 2); 
  bHiByte(wBsDir) = bSharedInfo(wPos + 3); 
  if (!wBsDir) 
    return FALSE; 
 
  // - get in parent dir 
  fgFlMnLeavItem(_bFlMnCurItemIdx); // - leave current item 
  if ((wFlGetItemIdx(0) == 0) && (bFlGetItemType(0) == FTYPE_FOLDER)) 
  { 
 
    if (fgFlClLock(FL_CMDPATH_DIR_UP_1)) 
    { 
      fgFlMnEntDir(0, TRUE); 
    } 
  } 
  else 
  { 
 
    //_bFlMnCurItemIdx = 0;  // this should be ".." 
    //fgFlCmdGetItems(_bFlMnListId, 0x0, FLCMD_RET_OP_ENTDIR); 
    if (fgFlClLock(FL_CMDPATH_DIR_UP_0)) 
      fgFlCmdGetItems(_bFlMnListId, 0x0); 
  } 
 
  return TRUE; 
} 
 
/** 
 * Enter the dir given by item index. 
 */ 
static BOOL fgFlMnEntDir(BYTE bItemIdx, BOOL fgMoveUp) large 
{ 
  WORD wPos, wBsDir, wIdx; 
  BYTE bFType; 
 
  if (bItemIdx >= FL_MIN(_bFlMnItemNs, FLMN_PAGE_SZ)) 
  { 
    return FALSE; 
  } 
   
  // - check the type of the given item 
  wPos = FL_ITEM_FIELD(bItemIdx); 
 
  // - parse the full path 
  _bFlMnMemLock = TRUE; 
  vParseFolderName(bItemIdx, fgMoveUp); 
   
/* 
  if (bFlClPath() == FL_CMDPATH_CHG_DIR) 
  { 
    bLoByte(wIdx) = bSharedInfo(FL_ITEM_FIELD(0) + 12); 
    bHiByte(wIdx) = bSharedInfo(FL_ITEM_FIELD(0) + 13); 
    _bFlMnCurItemIdx = (BYTE) (wIdx % FLMN_ITEM_N); 
  } 
*/ 
   
  // - get the base dir index and set the list to it 
  bLoByte(wBsDir) = bSharedInfo(wPos + 12); 
  bHiByte(wBsDir) = bSharedInfo(wPos + 13); 
  wPos = FL_LIST_FIELD(_bFlMnListId); 
 
  // tmp solution 
  // if (fgFlClIsLock() || fgFlClLock(FL_CMDLOCK_SMN, FL_CMDPATH_CHG_DIR, 0)) 
  //  vFlCmdSet(_bFlMnListId, bSharedInfo(wPos),  
  //            bSharedInfo(wPos + 1), wBsDir, 0xFFFF, FLPARM_SO_GDIR); 
  vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(bItemIdx)); 
 
  return TRUE; 
} 
 
/** 
 * Handle the notification of MP3 playback status change. 
 * 
 * NOTE: In order to avoid the racing condition, check the parameters 
 *  of notification instead of shared info slot. 
 */ 
static void vFlMnChgMp3State(BYTE bStt) large 
{ 
  BYTE  bIdx; 
  WORD  wItemIdx, wIdx; 
 
  // - the current item of MP3 module 
  bLoByte(wItemIdx) = bSharedInfo(SI_MP3_ITEM_IDX_LO); 
  bHiByte(wItemIdx) = bSharedInfo(SI_MP3_ITEM_IDX_HI); 
 
  switch (bStt) 
  { 
    case MP3STT_PB_ENB: 
      // - playback enabled 
      break; 
    case MP3STT_PB_STRT: 
      // - playback starts 
      _wFlCurAdoIdx = wItemIdx; 
      vFlUpdateVfd(FALSE); 
      // - temp solution 
#ifdef SPTM_SUPPORT       
      if (_bFlIpState == IP_STATE_PANEL_1) 
        vFlIpShowInfo(IP_INFO_EQ, 0, 0); 
      else 
        vHideEqBar(); 
#endif 
        
      if (_wFlCurAdoDir == wFlMnGetListBaseDir(_bFlMnListId)) 
      { 
        vFlMnHiliOff(FLMN_HILI_PLAY); 
        _wFlCurAdoIdx = wItemIdx; 
        wIdx = wFlGetItemIdx(0); 
        if ((_wFlCurAdoIdx != wFlGetItemIdx(_bFlMnCurItemIdx)) &&  
            (wItemIdx >= wIdx) && (wItemIdx < wIdx + FLMN_ITEM_N)) 
        { 
          bIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
          vFlMnHiliOn(bIdx, FLMN_HILI_PLAY, FLMN_CLR_BG, FLMN_CLR_PLAY); 
        } 
      }       
 
      vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wItemIdx); 
      vFlIpShowInfo(IP_INFO_TOTALTIME, bSharedInfo(SI_MP3_TOTAL_TIME_MM),  
                                         bSharedInfo(SI_MP3_TOTAL_TIME_SS)); 
      vFlIpShowInfo(IP_INFO_PBC, 0, 0); 
       
#ifdef ENABLE_ID3 
      vFlGetId3Info(); 
#endif 
      break; 
    case MP3STT_PB_FSH: 
      // - playback finishes 
      // break; 
    case MP3STT_PB_ABT: 
      // - playback is aborted 
      // break; 
    case MP3STT_PB_ERR: 
      // - temp solution 
#ifdef SPTM_SUPPORT 
      vHideEqBar(); 
#endif 
     
      // - some playback erro occurs 
      vFlIpShowInfo(IP_INFO_PLAYTIME, 0, 0); 
      vFlIpShowInfo(IP_INFO_TOTALTIME, 0, 0); 
       
      if (_wFlCurAdoDir == wFlMnGetListBaseDir(_bFlMnListId)) 
      { 
        vFlMnHiliOff(FLMN_HILI_PLAY); 
        _wFlCurAdoIdx = 0xFFFF; 
      } 
      if (_bFlIpState == IP_STATE_PANEL_1) 
      { 
        _wStartX = FS_EQ_X; 
        _wStartY = 32; 
        vOsdClearPos(FL_INFO_WB, 200, 32);  
      } 
 
#ifdef ISO_AUTO_PLAY 
      fgFlAutoPlayNext(); 
/* 
      if (_fgFlIsAutoPlay) 
      { 
        _wFlAtplyIdx++; 
        if (fgFlClLock(FL_CMDPATH_ATPLY_0)) 
        { 
          bLoByte(wIdx) = bSharedInfo(FL_LIST_FIELD(_bFlRefListId) + 4); 
          bHiByte(wIdx) = bSharedInfo(FL_LIST_FIELD(_bFlRefListId) + 5); 
           
          if ((_wFlAtplyIdx >= wIdx) || (!fgFlCmdGetItems(_bFlRefListId, _wFlAtplyIdx))) 
          { 
            _fgFlIsAutoPlay = FALSE; 
            vFlClRls(); 
          } 
        } 
      } 
*/       
#endif     
      break; 
    default: 
      // - error occurs 
      break; 
  } 
 
  return;   
} 
 
/** 
 * Handle IR_CMD_DONE. 
 */ 
BOOL fgFlMnIrCmdDoneHdr(void) large 
{ 
  if (FL_ACK(_dwIrDoneParm) == FL_CMD_ASSERT) 
  { 
    // - "FS LIST" command done, get return command 
    BYTE bCmd; 
 
    bCmd = bSharedInfo(FL_CMD_BLK_SA); 
     
    switch (bCmd) 
    { 
    case FLCMD_CREATE: 
      vFlMnRetCreate(); 
      break; 
    case FLCMD_SET: 
      vFlMnRetSet(); 
      break; 
    case FLCMD_GET_ITEMS: 
      vFlMnRetGetItems(); 
      break; 
    case FLCMD_CLICK_ITEM: 
      vFlMnRetClickItem(); 
      break; 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
    case FLCMD_ADD_TO_PL: 
      vFlMnRetAddToPl(); 
      break; 
    case FLCMD_RM_FROM_PL: 
      vFlMnRetRmFromPl(); 
      break; 
    case FLCMD_CLEAN: 
      vFlMnRetRmAllFromPl(); 
      break; 
#endif 
 
    case FLCMD_QUERY_ITEM: 
      vFlMnRetQueryItem(); 
      break; 
    default: 
      // - TODO: exception handling 
      break; 
    } 
  } 
  else 
  { 
    switch(FL_ACK(_dwIrDoneParm)) 
    { 
      case SI_MP3_STT: 
        vFlMnChgMp3State(FL_PARM1(_dwIrDoneParm)); 
        break; 
      case SI_DDISC_PB_MODULE: 
        break; 
      case SI_MP3_MOD: 
        vFlIpShowInfo(IP_INFO_PBC, 0, 0); 
        break; 
      // tmp solution 
      case SI_JPG_STT: 
        switch(FL_PARM1(_dwIrDoneParm)) 
        { 
          case JPEGSTT_DEC_FSH: 
            #if 1//def JPG_INFO 
            //vShowJpegInfo(); 
            //mark this line because playing mp3 after jpg,it will display resolution 
            //JPEGSTT_DEC_FSH timing has something strange,so CL Wang will check it. 
            #endif 
            break; 
          case JPEGSTT_DEC_ABT: 
          case JPEGSTT_DEC_ERR: 
        #if 1//def JPG_INFO 
            vOsdPosClear(OSD_POS_FS_INFO_BAR); 
        #endif     
            break; 
        } 
    } 
  } 
 
  // - always grab in this case 
  return TRUE; 
} 
 
/** 
 * Clear the working area barrowed from DRAM. 
 */ 
static void vWorkAreaClear(void) large 
{ 
  BYTE bLen, i; 
  DWRD dwAddr; 
 
  bLen = bSharedInfo(SI_FS_WA_SZ); 
 
  bLoByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B1); 
  bHiByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B2); 
  bLoByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B3); 
  bHiByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B4); 
 
  WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), 0); 
  dwAddr++; 
  WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), 0); 
  dwAddr++; 
  WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), 1); 
  dwAddr++; 
  WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), '\\'); 
  dwAddr++; 
 
  for (i=4; i < bLen-4; i++) 
  { 
    WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), 0); 
  } 
 
  return; 
} 
 
#ifdef FLMN_RET_PLAY_DIR 
static void vWorkAreaMove(BOOL fgToFront) large 
{ 
  BYTE  bLen, bChar, i; 
  DWRD  dwAddr, dwSrcAddr, dwDesAddr; 
 
  bLoByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B1); 
  bHiByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B2); 
  bLoByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B3); 
  bHiByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B4); 
 
  if (fgToFront) 
  { 
    dwDesAddr = dwAddr; 
    dwSrcAddr = dwAddr + FLMN_MAX_WA_SIZE; 
  } 
  else 
  { 
    dwSrcAddr = dwAddr; 
    dwDesAddr = dwAddr + FLMN_MAX_WA_SIZE; 
  } 
 
  bChar = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
  WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bChar); 
  dwSrcAddr ++; 
  dwDesAddr ++; 
   
  bChar = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
  WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bChar); 
  dwSrcAddr ++; 
  dwDesAddr ++; 
 
  bLen = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
  WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bLen); 
  dwSrcAddr ++; 
  dwDesAddr ++; 
 
  while (bLen) 
  { 
    bChar = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
    WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bChar); 
    dwSrcAddr ++; 
    dwDesAddr ++; 
    bLen--; 
  } 
} 
#endif 
 
/** 
 * Draw the name string of the current folder. 
 */ 
static void vDrawFolderName(BOOL fgDraw) large 
{ 
  BYTE bLen, i; 
  DWRD dwAddr; 
 
 
  if (fgDraw) 
  { 
    bLoByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B1); 
    bHiByte(wLoWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B2); 
    bLoByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B3); 
    bHiByte(wHiWord(dwAddr)) = bSharedInfo(SI_FS_WA_SA_B4); 
     
    dwAddr += 2; 
    bLen = bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)); 
   
    _wStartX = FLMN_BTN_1_X + FLMN_MENU_BORDER + 20; 
    _wStartY = FLMN_BTN_1_Y + FLMN_MENU_BORDER + 2; 
    vPasteBmp(FL_MENU_WB, BMP_FOLDER); 
     
    _wStartY = FLMN_BTN_1_Y + FLMN_MENU_BORDER; 
    _wStartX += 50; 
     
    _wEndY = _wStartY + 30; 
    _wEndX = FLMN_BTN_1_X + FLMN_BTN_2_W - FLMN_MENU_BORDER * 2; 
    vRectangle(FL_MENU_WB, 0, 0, 1, 0); 
   
    //vSetFsCodePage(0); 
    vSetMsgCol4(FL_MENU_WB, 0, 0, 3, 2); 
    if (bLen > 30) 
    { 
      dwAddr += (bLen - 30); 
      bLen = 30; 
    } 
    vPasteMsgAddrXY(_wStartX, _wStartY, FL_MENU_WB, bLen, dwAddr+1); 
    //vSetFsCodePage(CODE_PAGE_MENU); 
  } 
  else 
  { 
    _wStartX = FLMN_BTN_1_X + FLMN_MENU_BORDER + 20; 
    _wStartY = FLMN_BTN_1_Y + FLMN_MENU_BORDER + 2; 
//    _wEndY = _wStartY + 30; 
//    _wEndX = FLMN_BTN_1_X + FLMN_BTN_2_W - FLMN_MENU_BORDER * 2; 
    vOsdClearPos(FL_MENU_WB, FSMENU_BASIC_WB_WIDTH, 30); 
  } 
 
  return; 
} 
 
/** 
 * Calculate the name string of the folder. 
 */ 
static void vParseFolderName(BYTE bItem, BOOL fgMoveUp) large 
{ 
  BYTE bSrcLen, bDesLen, bTmp, i; 
  WORD wPos, wBsDir; 
  DWRD dwSrcAddr, dwDesAddr, dwAddr; 
  BYTE bDepth, bDirLvl; 
 
  if (fgMoveUp == TRUE) 
  { 
    bLoByte(wLoWord(dwSrcAddr)) = bSharedInfo(SI_FS_WA_SA_B1); 
    bHiByte(wLoWord(dwSrcAddr)) = bSharedInfo(SI_FS_WA_SA_B2); 
    bLoByte(wHiWord(dwSrcAddr)) = bSharedInfo(SI_FS_WA_SA_B3); 
    bHiByte(wHiWord(dwSrcAddr)) = bSharedInfo(SI_FS_WA_SA_B4); 
 
    bDepth = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
    bDepth--; 
    WriteDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr), bDepth); 
    dwSrcAddr++; 
     
    bDirLvl = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
    if (bDirLvl == bDepth + 1) 
    { 
      bDirLvl--; 
      WriteDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr), bDirLvl); 
    } 
    dwSrcAddr++; 
 
    dwDesAddr = dwSrcAddr; 
 
    bSrcLen = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
    dwSrcAddr += bSrcLen; 
     
    dwSrcAddr--; 
    bSrcLen--; 
    while ((bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)) != '\\') && (bSrcLen > 1)) 
    { 
      bSrcLen--; 
      dwSrcAddr--; 
    } 
    WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bSrcLen); 
  } 
  else 
  { 
    wPos = FL_ITEM_FIELD(bItem); 
 
    bLoByte(wLoWord(dwDesAddr)) = bSharedInfo(SI_FS_WA_SA_B1); 
    bHiByte(wLoWord(dwDesAddr)) = bSharedInfo(SI_FS_WA_SA_B2); 
    bLoByte(wHiWord(dwDesAddr)) = bSharedInfo(SI_FS_WA_SA_B3); 
    bHiByte(wHiWord(dwDesAddr)) = bSharedInfo(SI_FS_WA_SA_B4); 
 
    bLoByte(wLoWord(dwSrcAddr)) = bSharedInfo(wPos); 
    bHiByte(wLoWord(dwSrcAddr)) = bSharedInfo(wPos + 1); 
    bLoByte(wHiWord(dwSrcAddr)) = bSharedInfo(wPos + 2); 
    bHiByte(wHiWord(dwSrcAddr)) = bSharedInfo(wPos + 3); 
     
 
    bDepth = bReadDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr)); 
    bDepth++; 
    WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bDepth); 
    dwDesAddr++; 
     
    bDirLvl = bReadDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr)); 
    dwAddr = dwDesAddr; 
    dwDesAddr++; 
 
    bSrcLen = bSharedInfo(FL_ITEM_FIELD(bItem) + 4); 
    bDesLen = bReadDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr)); 
   
    if (bSrcLen + 1 + bDesLen < FLMN_MAX_WA_SIZE - 2) 
    { 
      bDirLvl++; 
      WriteDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr), bDirLvl); 
       
      WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bSrcLen + 1 + bDesLen); 
       
      dwDesAddr += (bDesLen + 1); 
         
      i=0;  
      while (i < bSrcLen) 
      { 
        bTmp = bReadDRAMTbl(bLoByte(wHiWord(dwSrcAddr)), wLoWord(dwSrcAddr)); 
  #ifdef FLMN_DONT_SHOW_NONPRINTABLE_CHAR 
        if ((bTmp < 0x20) || (bTmp > 0x7E)) 
        { 
          bTmp = '_'; 
        } 
  #endif 
        WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), bTmp); 
        dwSrcAddr++; 
        dwDesAddr++; 
        i++; 
      } 
      WriteDRAMTbl(bLoByte(wHiWord(dwDesAddr)), wLoWord(dwDesAddr), '\\'); 
    } 
  } 
 
  return; 
} 
 
//////////////////////////////////////////////////////////////////////////////// 
// Info Panel 
 
static void vFlMnDrawInfoPanel(BYTE bPanel) large 
{ 
  switch(bPanel) 
  { 
    case IP_STATE_PANEL_1: 
      vFlIpShowInfo(IP_INFO_EQ, 0, 0); 
      vFlIpClearInfoArea(IP_INFO_PANEL_2); 
      vFlIpShowInfo(IP_INFO_VOLUME, bAdspCurrVol(),  
                    (fgIsMute() ? FLIP_VOLUME_MUTE_ON : FLIP_VOLUME_REDRAW)); 
      vFlIpShowInfo(IP_INFO_PBC, 0, 0); 
      vFlIpShowInfo(IP_INFO_USR_AUX_CTRL, bSharedInfo(SI_USR_AUX_CTRL), 0); 
      break; 
    case IP_STATE_PANEL_2: 
    #ifdef SPTM_SUPPORT 
      vHideEqBar(); 
    #endif 
 
      vFlIpClearInfoArea(IP_INFO_PANEL_1); 
      vFlIpShowInfo(IP_INFO_RPT_TYPE, _bFlPbMode, 0); 
      vFlIpShowInfo(IP_INFO_LIST_TYPE, bSharedInfo(FL_LIST_FIELD(_bFlMnListId)), 0); 
//      vFlIpShowInfo(IP_INFO_KEY_SHIFT, 0, 0); 
//      vFlIpShowInfo(IP_INFO_KEY_SHIFT, 0, 0); 
    #ifdef PLAYER_SURROUND 
      vFlIpShowInfo(IP_INFO_REVERB, bEepromReadByte(REVERB_MD_POS), 0); 
    #endif 
       
      break; 
  } 
  if (bSharedInfo(SI_MP3_STT) == MP3STT_PB_STRT) 
  { 
    // - display run-time info 
    vFlIpShowInfo(IP_INFO_PLAYTIME, bSharedInfo(SI_TIME_MM), bSharedInfo(SI_TIME_SS)); 
    vFlIpShowInfo(IP_INFO_TOTALTIME, bSharedInfo(SI_MP3_TOTAL_TIME_MM),  
                                     bSharedInfo(SI_MP3_TOTAL_TIME_SS)); 
    vFlIpShowInfo(IP_INFO_BITRATE, 0,  
                  bSharedInfo(SI_MP3_BITRATE_LO) + bSharedInfo(SI_MP3_BITRATE_HI) * 256); 
    //vFlIpShowInfo(IP_INFO_EQ, 0, 0);       
  } 
  else 
  { 
    // - clear the run-time info 
    vFlIpShowInfo(IP_INFO_PLAYTIME, 0, 0); 
    vFlIpShowInfo(IP_INFO_TOTALTIME, 0, 0); 
    vFlIpShowInfo(IP_INFO_BITRATE, 0, 0); 
    //#ifdef SPTM_SUPPORT 
    //  vHideEqBar(); 
    //#endif 
  } 
  vFlIpShowInfo(IP_INFO_DISC_TYPE, 0, 0);  
} 
 
static BOOL fgIsParentDir(void) large 
{ 
#if 1 
  BYTE  bLen, bChar; 
  WORD  wIdx; 
  DWRD  dwAddr; 
    
  bLen = bSharedInfo(FL_ITEM_FIELD(_bFlMnCurItemIdx) + 4); 
  wIdx = FL_ITEM_FIELD(_bFlMnCurItemIdx); 
  bLoByte(wLoWord(dwAddr)) = bSharedInfo(wIdx); 
  bHiByte(wLoWord(dwAddr)) = bSharedInfo(wIdx + 1); 
  bLoByte(wHiWord(dwAddr)) = bSharedInfo(wIdx + 2); 
  bHiByte(wHiWord(dwAddr)) = bSharedInfo(wIdx + 3); 
  bChar = bReadDRAMTbl(bLoByte(wHiWord(dwAddr)), wLoWord(dwAddr)); 
     
  if ((bLen == 0x1) && (bChar == 0x1)) 
    return TRUE; 
 
#else 
 
  WORD  wBsseDir, wIdx; 
   
  wBaseDir = wFlMnGetListBaseDir(_bFlMnListId); 
  wIdx = wFlGetItemIdx(_bFlMnCurItemIdx); 
  if ((wBaseDir != 0) && (wIdx == 0) && (_bFlMnItemType == FTYPE_FOLDER)) 
    return TRUE; 
#endif   
} 
 
//////////////////////////////////////////////////////////////////////////////// 
// IR Handler 
 
/** 
 * Handle IR_PLAY, IR_ENTER, IR_RIGHT_ENTER. It acts like "clicking" or  
 *  "selecting" actually. 
 */ 
static BOOL fgFlMnOnIrPlay(void) large 
{ 
  DWRD  dwAddr; 
  WORD  wBaseDir, wIdx; 
  BYTE  bLen, bChar; 
   
  // - check the type of the clicked item 
  switch(_bFlMnItemType) 
  { 
  case FTYPE_FOLDER: 
    if (_bFlMnMemLock || fgFlClIsLock()) 
      return TRUE; 
    if (!fgFlClLock(FL_CMDPATH_CHG_DIR)) 
      return TRUE; 
 
    fgFlMnLeavItem(_bFlMnCurItemIdx); 
 
    if (fgIsParentDir()) 
      fgFlMnEntDir(_bFlMnCurItemIdx, TRUE); 
    else 
      fgFlMnEntDir(_bFlMnCurItemIdx, FALSE); 
    break; 
 
  case FTYPE_AV: 
    // - click the item and change the playback module to MPEG player 
    vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx)); 
    break; 
 
  case FTYPE_STILL: 
    // - turn off the preview mode and terminate the preview timing 
#ifdef JPG_PREVIEW_SUPPORT      
    vSetSharedInfo(SI_PREVIEW_MODE, FALSE);     
    _bPreview = PREVIEW_STATE_IDLE; 
#endif 
 
#if (DRAM_SZ == DRAM_2M) 
    vDeleteWB(FL_MENU_WB); 
    vDeleteWB(FL_INFO_WB); 
#endif 
    if (fgFlClLock(FL_CMDPATH_CLICK)) 
      vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx)); 
    break; 
 
  case FTYPE_AUDIO: 
    // - for all audio files 
    wBaseDir = wFlMnGetListBaseDir(_bFlMnListId); 
    wIdx = wFlGetItemIdx(_bFlMnCurItemIdx); 
    if ((wBaseDir == _wFlCurAdoDir) && (wIdx == _wFlCurAdoIdx) && (bSharedInfo(SI_MP3_MOD) != SV_STOP)) 
    { 
      vSendUopCmd(UOP_PLAY, 0, 0, 0); 
    } 
    else 
    { 
      _wFlCurAdoDir = wBaseDir; 
      vWorkAreaMove(FALSE); 
      vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx)); 
    } 
  default: 
    break; 
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlMnOnIrPause(void) large 
{ 
  if (bSharedInfo(SI_MP3_MOD) == SV_PAUSE) 
  { 
    vSendUopCmd(UOP_PLAY, 0, 0, 0); 
  } 
  else 
  { 
    vSendUopCmd(UOP_PAUSE, 0, 0, 0); 
  } 
 
  return TRUE; 
} 
 
 
#ifdef FL_USE_LOGO 
/** 
 * Operations for showing the basic visual components of the  
 *  file browser menu. 
 */ 
static void vFlMnShowPage(void) large 
{ 
  // - display the menu logo 
   vPlayerShowLogo(ISO_STOP_LOGO, ISO_LOGO_COLOR); 
   // - enable the whiteboard 
   
#if 0//(DRAM_SZ != DRAM_2M) //cl 0512 
  #ifdef FSMENU_INFO_PANEL 
    vCreateWB(FL_INFO_WB, TRUE); 
  #endif 
    vCreateWB(FL_MENU_WB, TRUE); 
#else 
#ifdef FSMENU_INFO_PANEL 
  vEnableWB(FL_INFO_WB); 
#endif 
  vEnableWB(FL_MENU_WB); 
#endif 
  vSetSharedInfo(SI_HLI_STATE, SV_ON); // - turn on hili select mode 
 
  return; 
} 
#else 
static void vFlMnShowPage(void) large 
{ 
  _wStartX = FLMN_BTN_0_X;  
  _wEndX = FLMN_BTN_0_X + FLMN_BTN_0_W; 
  _wStartY = FLMN_BTN_0_Y; 
  _wEndY = FLMN_BTN_0_Y + FLMN_BTN_0_H; 
  vCreateButton(FL_MENU_WB, 30, 4); 
  //vSetBtnCol(FL_MENU_WB, 0, 0, 2, 3); 
  vSetBtnCol(FL_MENU_WB, 0, 0, 3, 2); 
  vUnselButton(FL_MENU_WB, 30); 
 
  _wStartX = FLMN_BTN_1_X;  
  _wEndX = FLMN_BTN_1_X + FLMN_BTN_1_W; 
  _wStartY = FLMN_BTN_1_Y; 
  _wEndY = FLMN_BTN_1_Y + FLMN_BTN_1_H; 
  vCreateButton(FL_MENU_WB, 30, 4); 
  //vSetBtnCol(FL_MENU_WB, 0, 0, 2, 3); 
  vSetBtnCol(FL_MENU_WB, 0, 0, 3, 2); 
  vSelButton(FL_MENU_WB, 30); 
 
  _wStartX = FLMN_BTN_2_X;  
  _wEndX = FLMN_BTN_2_X + FLMN_BTN_2_W; 
  _wStartY = FLMN_BTN_2_Y; 
  _wEndY = FLMN_BTN_2_Y + FLMN_BTN_2_H; 
  vCreateButton(FL_MENU_WB, 30, 4); 
  //vSetBtnCol(FL_MENU_WB, 0, 0, 2, 3); 
  vSetBtnCol(FL_MENU_WB, 0, 0, 3, 2); 
  vSelButton(FL_MENU_WB, 30); 
 
   
  _wStartX = FLMN_BTN_3_X;  
  _wEndX = FLMN_BTN_3_X + FLMN_BTN_3_W; 
  _wStartY = FLMN_BTN_3_Y; 
  _wEndY = FLMN_BTN_3_Y + FLMN_BTN_3_H; 
  vCreateButton(FL_MENU_WB, 30, 4); 
  //vSetBtnCol(FL_MENU_WB, 0, 0, 2, 3); 
  vSetBtnCol(FL_MENU_WB, 0, 0, 3, 2); 
  vSelButton(FL_MENU_WB, 30); 
 
  vDrawSpin(); 
} 
#endif 
 
 
// INTER-MODULE INTERFACE 
/** 
 * Init the object "file list menu". 
 */ 
BOOL fgFlMnInit(void) large 
{ 
  WORD  wTmp; 
   
  // - perform init operations of module "fs list menu" 
  //    1. init the command as done 
  vFlCmdDone(); 
 
  //    2. init control flags & variables 
  _bFlMnListId = 0xFF; 
  _bFlMnItemNs = 0x0; 
  _bFlMnCurItemIdx = 0x0; 
  _wFlMnListLen = 0x0; 
  _bFlMnTimeType = OSD_SHOW_SINGLE_ELAPSED; 
  _wFlMnLstFirst = 0xFFFF; 
  _wFlMnPlFirst = 0xFFFF; 
  _wFlCurAdoDir = 0xFFFF; 
  _wFlCurAdoIdx = 0xFFFF; 
  _bFlId3Field = 0x0000; 
  _bFlMnHiliClrSrc1 = 0x0F; 
  _bFlMnHiliClrDes1 = 0x0F; 
  _bFlMnHiliClrSrc2 = 0x0F; 
  _bFlMnHiliClrDes2 = 0x0F; 
  _bFlMnHiliPos1 = 0x0F; 
  _bFlMnHiliPos2 = 0x0F; 
  _wFlPlIdx = 0xFFFF; 
  _wFlFlIdx = 0xFFFF; 
  _wFlFdIdx = 0xFFFF; 
  _bFlMnItemType = FTYPE_NONE; 
  _bFlIpState = IP_STATE_PANEL_1; //IP_STATE_NORMAL; 
#ifdef JPG_PREVIEW_SUPPORT    
  _bPreview = PREVIEW_STATE_IDLE;   // - jpeg preview 
#endif   
  _bFlMnTimer = FLMN_TIMER_PERIOD;  // - timer 
  _wFlAtplyIdx = 0; 
  _fgFlIsAutoPlay = FALSE; 
 
  //    3. white board usage 
  //vDisableUnusedWB(); 
  // - create whiteboard and set up related OSD properties 
#ifdef FSMENU_INFO_PANEL 
  vCreateWB(FL_INFO_WB, TRUE); 
  vSetWBTcColor(FL_INFO_WB); 
  vSetMsgCol4(FL_INFO_WB, 0, 0, 3, 2); 
  vSetInputMsgCol4(FL_INFO_WB, 0, 4, 4, 2); 
#endif   
  vCreateWB(FL_MENU_WB, TRUE); 
  vSetWBTcColor(FL_MENU_WB); 
  vSetMsgCol4(FL_MENU_WB, 0, 0, 3, 2); 
 
  //    4. set size and range of jpeg preview mode 
#ifdef JPG_PREVIEW_SUPPORT    
  vSetSharedInfo(SI_PREVIEW_MODE, TRUE); 
  vSetSharedInfo(SI_PREVIEW_START_X, FLMN_PREVIEW_X / 4); 
  vSetSharedInfo(SI_PREVIEW_START_Y, FLMN_PREVIEW_Y / 5); 
  vSetSharedInfo(SI_PREVIEW_WIDTH, FLMN_PREVIEW_W / 4); 
  vSetSharedInfo(SI_PREVIEW_HEIGHT, FLMN_PREVIEW_H / 5); 
#endif 
 
  //    5. init run-time info display 
  vFlIpShowInfo(IP_INFO_VOLUME, bAdspCurrVol(), FLIP_VOLUME_REDRAW); 
  vFlIpShowInfo(IP_INFO_TOTALTIME, 0, 0); 
  vFlIpShowInfo(IP_INFO_TOTALTIME, 0, 0); 
  vFlIpShowInfo(IP_INFO_BITRATE, 0, 0); 
  vWorkAreaClear(); 
 
  // tmp solution 
  vSetSharedInfo(SI_MP3_TOTAL_TIME_MM, 0);  
  vSetSharedInfo(SI_MP3_TOTAL_TIME_SS, 0); 
 
#ifdef ISO_LAST_MEM 
  vFlMnGetLastMemItem(); 
#endif 
 
  //    6. create the list of the menu (the latest operation of init procedure) 
  if (!fgFlClLock(FL_CMDPATH_INIT_0)) 
  { 
    return FALSE; 
  } 
 
#ifdef ISO_LAST_MEM 
  if (_wFlCurAdoIdx != 0xFFFF) 
  { 
    vFlCmdCreate(FLPARM_LIST_FOLDER,  
             FLPARM_INC_FILE|FLPARM_INC_FOLDER|FLPARM_INC_PARENT,  
             _wFlCurAdoDir, FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
  } 
  else 
#endif 
  { 
#ifdef SUPPORT_PCD 
    if (fgIsPcdPlay()) 
    { 
      bLoByte(wTmp) = bSharedInfo(SI_FS_PCD_BASEDIR_LO); 
      bHiByte(wTmp) = bSharedInfo(SI_FS_PCD_BASEDIR_HI); 
       
      vFlCmdCreate(FLPARM_LIST_FOLDER,  
                   0x0, wTmp, FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
    } 
    else  
#endif 
    { 
      vFlCmdCreate(FLPARM_LIST_FOLDER,  
                   FLPARM_INC_PARENT, 0x0, FLPARM_FF_DIR|FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
    } 
  } 
 
  return TRUE; 
} 
 
//////////////////////////////////////////////////////////////////////////////// 
// Command Target State Transition 
 
static void vFlMnSyncState(void) large 
{ 
  bLoByte(_wFlCurAdoIdx) = bSharedInfo(SI_MP3_ITEM_IDX_LO); 
  bHiByte(_wFlCurAdoIdx) = bSharedInfo(SI_MP3_ITEM_IDX_HI); 
 
  return; 
} 
 
// 
// Enter this object (called when we try to move in the focus). 
// 
/** 
 * Operation to make the focus enter the object "file list menu". 
 * 
 * DES: 
 *  1. Show the basic visial component 
 *  2. Set shared info config for "file list menu" control 
 *  3. Display the run-time infor of MP3 (audio files) playback if necessary 
 *  4. Get item for redraw or enter the current item 
 *  5. Set the current module as the foreground module 
 */ 
void vFlMnEnter(WORD wItem) large 
{ 
  WORD  wTmp; 
  BYTE  bTmp; 
  _bFlMnMemLock = FALSE; 
   
  if (_fgFlMdChg) 
  { 
    vFlMnSyncState(); 
  } 
#if 1//(DRAM_SZ != DRAM_2M) 
   vOsdShowWb(OSD_WB_FULL_SCR); 
#endif 
 
#if 0 
  if (_wCurrItem != 0xFFFF) 
  { 
    wItem = _wCurrItem; 
  } 
  else  
#endif 
  if (wItem == 0xFFFF) 
  { 
    wItem = wFlGetItemIdx(_bFlMnCurItemIdx); 
  } 
   
  _bFlMnCurItemIdx = wItem % FLMN_ITEM_N; 
 
  // - show the basic visual components 
  vFlMnShowPage(); 
 
  if (_fgFlMdChg) 
  { 
    vFlMnDrawPage();     
    _fgFlMdChg = FALSE; 
  } 
 
  _rOsdStateCtx.bTimeType = _bFlMnTimeType; 
 
  // - set shared info to config RISC 
#ifdef JPG_PREVIEW_SUPPORT    
  _bPreview = PREVIEW_STATE_IDLE; 
#endif 
#if 1//def JPG_INFO 
  vOsdPosClear(OSD_POS_FS_INFO_BAR); 
#endif 
#ifdef JPG_PREVIEW_SUPPORT    
  vSetSharedInfo(SI_PREVIEW_MODE, TRUE); 
#endif   
  vSetSharedInfo(SI_JPG_ROTATE_AUTO_SLIDE, FL_JPEG_SLIDESHOW_INTERVAL); 
  //vSetSharedInfo(SI_JPG_DIGEST_BG, 0x2); 
 
  // - display the run-time info if necessary 
  vFlMnDrawInfoPanel(_bFlIpState); 
 
  // - set the MP3 player as the foreground module 
  vFlCtrlSetFg(FLMD_MP3_PLAYER); 
  while(bSharedInfo(SI_DDISC_PB_MODULE) != SV_DDISC_MODULE_MP3); 
   
  if (_rFlCmdLock.bPath != FL_CMDPATH_SEL_1) 
  { 
    vFlClRls(); 
  } 
 
  // - redraw page if necessary or get into the current item 
  if (!_bFlMnItemNs ||  // - list don't ready yet 
      (wItem <= wFlGetItemIdx(0x0)) ||  
      (wItem >= wFlGetItemIdx(FLMN_PAGE_SZ)) || 
      (wItem >= wFlGetItemIdx(_bFlMnItemNs - 1))) 
  { 
    // - out boundary redraw 
    _bFlMnCurItemIdx = wItem % FLMN_PAGE_SZ; 
    if (fgFlClLock(FL_CMDPATH_REDRAW)) 
      fgFlCmdGetItems(_bFlMnListId, wItem - (WORD)_bFlMnCurItemIdx); 
  } 
  else 
  { 
    // - in boundary, enter current item 
    fgFlMnEntItem((BYTE)(wItem - wFlGetItemIdx(0x0))); 
    for (bTmp = 0; (bTmp < _bFlMnItemNs) && (bTmp < FLMN_PAGE_SZ); bTmp++) 
    { 
      if (fgFlMnIsCurrPlayItem(bTmp)) 
      { 
        vFlMnHiliOn(bTmp, FLMN_HILI_PLAY, FLMN_CLR_BG, FLMN_CLR_PLAY); 
      } 
    } 
  } 
 
  vFlUpdateVfd(TRUE); 
  return; 
} 
 
// 
// Leave this object (called when we try to move away the focus). 
// 
WORD wFlMnLeave(BOOL bSuicide) large 
{ 
  // - snuff out hilight, and turn off the hili select mode 
  vFlMnHiliItem(_bFlMnCurItemIdx, FALSE); 
  vSetSharedInfo(SI_HLI_STATE, SV_OFF); 
   
  vFlMnHiliOff(FLMN_HILI_SEL); 
  vFlMnHiliOff(FLMN_HILI_PLAY); 
 
#ifdef SHOW_FS_SLIDER 
  vMoveSlider(wFlGetItemIdx(_bFlMnCurItemIdx), _wFlMnListLen, FALSE); 
#endif  
   
#ifdef SPTM_SUPPORT 
  vHideEqBar(); 
#endif 
#ifdef JPG_PREVIEW_SUPPORT  
  _bPreview = PREVIEW_STATE_IDLE; 
#endif 
 
 
#if (DRAM_SZ != DRAM_2M) 
  // - disable the whiteboard 
  vDisableWB(FL_MENU_WB); 
  vDisableWB(FL_INFO_WB); 
#else 
  vDeleteWB(FL_MENU_WB); 
  vDeleteWB(FL_INFO_WB); 
#endif 
  return (bSharedInfo(SI_MP3_ITEM_IDX_HI)*256 +  
          bSharedInfo(SI_MP3_ITEM_IDX_LO)); 
} 
 
 
//////////////////////////////////////////////////////////////////////////////// 
// IR Key Handlers 
 
/** 
 * Handle IR_DIR. 
 *  IR_DOWN, move hover item down or move to next page 
 *  IR_UP, move hover item up or move to previous page 
 *  IR_RIGHT, enter the dir if it is on a dir 
 *  IR_LEFT, move the parent dir 
 */ 
 
/** 
 * Handle IR_UP. 
 */ 
static BOOL fgFlMnOnIrUp(void) large 
{ 
  if (fgFlClIsLock()) 
    return TRUE; 
 
  if (wFlGetItemIdx(_bFlMnCurItemIdx) &&  
      (wFlGetItemIdx(_bFlMnCurItemIdx) != 0xFFFF)) 
  { 
    // - IR_UP is still available 
    vMoveSpin(TRUE); 
    fgFlMnLeavItem(_bFlMnCurItemIdx); 
    if (!fgFlMnEntItem(_bFlMnCurItemIdx - 1)) 
    { 
      // - out boundary, change to previous page 
      WORD wBIdx; 
 
      wBIdx = wFlGetItemIdx(0x0); 
      wBIdx -= (wBIdx >= FLMN_PAGE_SZ) ? (WORD)FLMN_PAGE_SZ : wBIdx; 
      if (!fgFlClLock(FL_CMDPATH_UP)) 
        return TRUE; 
      if (fgFlCmdGetItems(_bFlMnListId, wBIdx)) 
      { 
        _bFlMnCurItemIdx = FLMN_PAGE_SZ - 1; 
      } 
      else 
      { 
        // - no more previous page 
        //vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
      } 
    } 
    else 
    { 
    } 
  } 
  else 
  { 
    // - reach the first item 
    //vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
  } 
 
  return TRUE; 
} 
 
/** 
 * Handle IR_DOWN. 
 */ 
static BOOL fgFlMnOnIrDown(void) large 
{ 
  if (fgFlClIsLock()) 
    return TRUE; 
 
  if (wFlGetItemIdx(_bFlMnCurItemIdx) < (_wFlMnListLen - 1)) 
  { 
    // - IR_DOWN is available still 
    vMoveSpin(FALSE); 
    fgFlMnLeavItem(_bFlMnCurItemIdx); 
    if (!fgFlMnEntItem(_bFlMnCurItemIdx + 1)) 
    { 
      if (fgFlMnIsCurrPlayItem(_bFlMnCurItemIdx)) 
      { 
        //vFlMnHiliItem(_bFlMnCurItemIdx, FALSE); 
        //vFlMnHiliOn(_bFlMnCurItemIdx, FLMN_HILI_PLAY, FLMN_CLR_BG, FLMN_CLR_PLAY); 
      } 
         
      // - the next item is not on page, move to next page 
      if (!fgFlClLock(FL_CMDPATH_DOWN)) 
        return TRUE; 
      if (fgFlCmdGetItems(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx + 1))) 
      { 
        _bFlMnCurItemIdx = 0x0; 
      } 
      else 
      { 
        // - no more next page 
        // vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
      } 
    } 
  } 
  else 
  { 
    // - reach the lastest item 
    //vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
  } 
 
  return TRUE; 
} 
 
/** 
 * Handle IR_LEFT. Go back to upper dir. 
 */ 
BOOL fgFlMnOnIrLeft(void) large 
{ 
  if (fgFlClIsLock()) 
    return TRUE; 
   
  if (bSharedInfo(FL_LIST_FIELD(_bFlMnListId)) == FLPARM_LIST_FOLDER) 
  { 
    if (!_bFlMnMemLock) 
    { 
      if (!fgFlMnLeavDir()) 
      { 
        // - TODO: show error meessage 
      } 
    } 
  } 
 
  return TRUE; 
} 
#if 0 // - JACOB: tmp 
static BOOL fgFlMnOnIrLeft(void) large 
{ 
#if 0 // - JACOB: seems unused now 
  BYTE pbStr[10]; 
#endif //0 
  WORD wPos, wBsDir; 
 
  if (fgFlClIsLock()) 
    return TRUE; 
   
  // - check current dir 
  wPos = FL_LIST_FIELD(_bFlMnListId); 
  bLoByte(wBsDir) = bSharedInfo(wPos + 2); 
  bHiByte(wBsDir) = bSharedInfo(wPos + 3); 
  if (!wBsDir) 
    return TRUE; 
 
  // - leave the current item and reget the list at begin 
  fgFlMnLeavItem(_bFlMnCurItemIdx); // - leave current item 
  _bFlMnCurItemIdx = 0;  // this should be ".." 
  fgFlCmdGetItems(_bFlMnListId, 0, FLCMD_RET_OP_ENTDIR); 
   
  return TRUE; 
 
#if 0   
  vFlMnTimerScrollWB(); 
 
  pbStr[0] = 9; 
  pbStr[1] = 'A';    pbStr[2] = 'B';   pbStr[3] = 'C';   pbStr[4] = 'D';   pbStr[5] = 'E'; 
  pbStr[6] = 'F';    pbStr[7] = 'G';   pbStr[8] = 'H';   pbStr[9] = 'I'; 
  _wStartX = FLMN_BTN_3_X + 10; 
  _wEndX   = FLMN_BTN_3_X + FLMN_BTN_3_W - 20; 
  _wStartY = FLMN_BTN_3_Y; 
  _wEndY   = FLMN_BTN_3_Y + 32; 
   
  if (_bShiftPos) 
  { 
    _bShiftPos--; 
  } 
  vDrawScrollingStr(pbStr, (WORD)(_bShiftPos * 4)); 
  //if (!fgFlMnLeavDir()) 
  { 
    //vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
  } 
#endif 
} 
#endif //0 
 
/** 
 * Handle IR_RIGHT. Go down a dir level. 
 */ 
static BOOL fgFlMnOnIrRight(void) large 
{ 
  WORD  wPos, wBaseDir; 
 
  if (_bFlMnItemType == FTYPE_FOLDER) 
  { 
    if (_bFlMnMemLock) 
      return TRUE;     
    wPos = FL_LIST_FIELD(_bFlMnListId); 
    bLoByte(wBaseDir) = bSharedInfo(wPos + 2); 
    bHiByte(wBaseDir) = bSharedInfo(wPos + 3); 
 
//    wBaseDir = wFlMnGetListBaseDir(_bFlMnListId); 
    if ((wFlGetItemIdx(_bFlMnCurItemIdx) == 0) && (wBaseDir != 0)) 
    { 
      fgFlMnLeavItem(_bFlMnCurItemIdx); 
      fgFlMnEntDir(_bFlMnCurItemIdx, TRUE); 
    } 
    else 
    { 
      fgFlMnLeavItem(_bFlMnCurItemIdx); 
      fgFlMnEntDir(_bFlMnCurItemIdx, FALSE); 
    } 
  } 
 
#if 0 
  pbStr[0] = 9; 
  pbStr[1] = 'A';    pbStr[2] = 'B';   pbStr[3] = 'C';   pbStr[4] = 'D';   pbStr[5] = 'E'; 
  pbStr[6] = 'F';    pbStr[7] = 'G';   pbStr[8] = 'H';   pbStr[9] = 'I'; 
  _wStartX = FLMN_BTN_3_X + 10; 
  _wEndX   = FLMN_BTN_3_X + FLMN_BTN_3_W - 20; 
  _wStartY = FLMN_BTN_3_Y; 
  _wEndY   = FLMN_BTN_3_Y + 32; 
   
  if (_bShiftPos < 64) 
  { 
    _bShiftPos++; 
  } 
  vDrawScrollingStr(pbStr, (WORD)(_bShiftPos * 4)); 
  // - go into the hovered dir 
  //if (!fgFlMnEntDir(_bFlMnCurItemIdx)) 
  { 
    //vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
  } 
#endif 
 
  return TRUE; 
} 
 
/** 
 * Draw next page. 
 */ 
 
static BOOL fgFlMnOnIrNext(void) large 
{ 
  WORD  wLastItem = wFlGetItemIdx(FLMN_ITEM_N-1); 
 
#if 0 
  if (bSharedInfo(SI_MP3_STT) == MP3STT_PB_STRT) 
  { 
    vSetSharedInfo(SI_DDISC_MIXED_TYPE_MODE, SV_OFF); 
    return FALSE; 
#if 0 
    if (wFlGetItemIdx(_bFlMnCurItemIdx) < (_wFlMnListLen - 1)) 
    { 
      vMoveSpin(FALSE); 
      fgFlMnLeavItem(_bFlMnCurItemIdx); 
      if (!fgFlMnEntItem(_bFlMnCurItemIdx + 1)) 
      { 
        if (fgFlCmdGetItems(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx + 1), FLCMD_RET_OP_PLAY))  
                            //FLCMD_RET_OP_REDRAW)) 
        { 
          _bFlMnCurItemIdx = 0x0; 
        } 
        else 
        { 
          // - no more next page 
          // vOsdShowError(SV_ERR_GENERAL, FL_MSG_TIMEOUT); 
        } 
      } 
      else  
      { 
        vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx), 
                        FLCMD_RET_OP_CMDACK); 
      } 
    } 
#endif 
  } 
  else 
#endif  
  {  
    if (wLastItem < _wFlMnListLen - 1) 
    { 
      fgFlMnLeavItem(_bFlMnCurItemIdx); 
      _bFlMnCurItemIdx = 0; 
      if (fgFlClLock(FL_CMDPATH_DOWN)) 
        fgFlCmdGetItems(_bFlMnListId, wLastItem + 1); 
    } 
  } 
 
  return TRUE; 
} 
 
/** 
 * Draw previous page. 
 */ 
 
static BOOL fgFlMnOnIrPrev(void) large 
{ 
  WORD  wFirstItem = wFlGetItemIdx(0); 
 
  if (wFirstItem > FLMN_ITEM_N - 1) 
  { 
    fgFlMnLeavItem(_bFlMnCurItemIdx); 
    _bFlMnCurItemIdx = 0; 
    if (fgFlClLock(FL_CMDPATH_UP)) 
      fgFlCmdGetItems(_bFlMnListId, wFirstItem - FLMN_ITEM_N); 
  } 
  
  return TRUE; 
} 
 
#ifdef FLMENU_FUNC_TEST 
static BOOL fgFlMnOnIrNextFile(void) large 
{ 
  BYTE  bNext, bType, bIdx; 
  WORD  wNum; 
   
  bNext = _bFlMnCurItemIdx + 1; 
   
  while (bNext < FLMN_ITEM_N) 
  { 
    bType = bFlGetItemType(bNext); 
    if (bType == _bFlMnItemType) 
    { 
      break; 
    } 
    bNext++; 
  } 
 
  if (bNext < FLMN_ITEM_N) 
  { 
#ifdef SHOW_FS_SLIDER 
    vMoveSlider(wFlGetItemIdx(_bFlMnCurItemIdx), _wFlMnListLen, FALSE); 
#endif 
     
    _bFlMnCurItemIdx = bNext; 
    wNum = wFlGetItemIdx(_bFlMnCurItemIdx); 
#ifdef SHOW_FS_SLIDER 
    vMoveSlider(wNum, _wFlMnListLen, TRUE);     
#endif     
    vFlCmdClickItem(_bFlMnListId, wNum, 
                    FLCMD_RET_OP_CMDACK); 
  } 
  else 
  { 
    bIdx = (_bFlMnCurItemIdx / FLMN_ITEM_N + 1) * FLMN_ITEM_N; 
    _bFlMnCurItemIdx = 0; 
    fgFlCmdGetItems(_bFlMnListId, bIdx, FLCMD_RET_OP_PLAY); 
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlMnOnIrPrevFile(void) large 
{ 
  return TRUE; 
} 
#endif 
 
#if 0 
static BOOL fgFlMnOnIrRepeat(void) large 
{ 
  switch (_bFlPbMode) 
  { 
    case SV_REPEAT_NONE: 
    case SV_SHUFFLE: 
#ifdef DDISC_PB_SINGLE_ENABLED 
      _bFlPbMode = SV_SINGLE; 
#else 
      _bFlPbMode = SV_REPEAT_TRACK; 
#endif 
      break; 
    case SV_SINGLE: 
      _bFlPbMode = SV_REPEAT_TRACK; 
      break; 
    case SV_REPEAT_ALL: 
      _bFlPbMode = SV_REPEAT_NONE; 
      break; 
    default: 
      _bFlPbMode = SV_REPEAT_ALL; 
      break; 
  } 
   
  vSendUopCmd(UOP_REPEAT, _bFlPbMode, 0x0, 0x0); 
 
  if (_bFlIpState != IP_STATE_PANEL_2) 
    fgFlMnChgInfoPanel(); 
     
  vFlIpShowInfo(IP_INFO_RPT_TYPE, _bFlPbMode, 0); 
 
  return TRUE; 
} 
#endif 
 
static BOOL fgFlMnOnIrRandom(void) large 
{ 
   
#ifdef DDISC_PB_SHUFFLE_ENABLED 
  if (_bFlPbMode != SV_SHUFFLE) 
  { 
    _bFlPbMode = SV_SHUFFLE; 
    vSendUopCmd(UOP_SHUFFLE, SV_ON, 0x0, 0x0); 
  } 
  else 
  { 
    _bFlPbMode = SV_REPEAT_NONE; 
    vSendUopCmd(UOP_SHUFFLE, SV_OFF, 0x0, 0x0); 
  } 
#endif 
 
  return TRUE; 
} 
 
static BOOL fgFlMnOnIrSelDone(void) large 
{ 
  WORD  wIdx; 
  WORD  wTmp; 
   
  wIdx = (WORD) _rNumInStateCtx.bDig[0] * 100 +  
                _rNumInStateCtx.bDig[1] * 10 +  
                _rNumInStateCtx.bDig[2]; 
   
  if (_wFlMnListLen >= 1000) 
  { 
    wIdx = wIdx * 10 + _rNumInStateCtx.bDig[3]; 
  } 
 
  wTmp = wFlGetSubFldrNs(_bFlMnListId); 
 
  if ((wIdx != 0) &&  
#ifdef FL_CHK_FOLDER_NS 
      (wIdx <= _wFlMnListLen - wFlGetSubFldrNs(_bFlMnListId))) 
#else 
      (wIdx <= _wFlMnListLen)) 
#endif 
  { 
    if (fgFlClLock(FL_CMDPATH_SEL_0)) 
    { 
      wIdx--; 
#ifdef FL_CHK_FOLDER_NS 
      wIdx += wFlGetSubFldrNs(_bFlMnListId); 
#endif 
      fgFlMnLeavItem(_bFlMnCurItemIdx);     
      _bFlMnCurItemIdx = wIdx % FLMN_ITEM_N; 
      _wCurrItem = wIdx; 
       
      fgFlCmdGetItems(_bFlMnListId, wIdx - _bFlMnCurItemIdx); 
    } 
  } 
  else 
  { 
    vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wFlGetItemIdx(_bFlMnCurItemIdx));   
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlMnChgInfoPanel(void) large 
{ 
  WORD  wNum; 
   
  switch (_bFlIpState) 
  { 
    case IP_STATE_PANEL_1: 
      _bFlIpState = IP_STATE_PANEL_2; 
      break; 
    case IP_STATE_PANEL_2: 
      _bFlIpState = IP_STATE_PANEL_1; 
      break; 
  } 
   
  vFlMnDrawInfoPanel(_bFlIpState); 
 
  // tmp solution   
  if (_bFlIpState == IP_STATE_PANEL_1) 
  { 
    //vFlIpShowFileIndex(wFlGetItemIdx(_bFlMnCurItemIdx)+1, _wFlMnListLen, 0); 
    wNum = wFlGetItemIdx(_bFlMnCurItemIdx); 
 
    //vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wNum); 
    vFlIpShowInfo(IP_INFO_FILE_INDEX, 0, wNum);   
    vFlIpShowInfo(IP_INFO_PBC, 0, 0); 
    vFlIpShowInfo(IP_INFO_USR_AUX_CTRL, bSharedInfo(SI_USR_AUX_CTRL), 0); 
  }   
  else if (_bFlIpState == IP_STATE_PANEL_2) 
  { 
    //vFlIpShowRptType(_bFlPbMode); 
    vFlIpShowInfo(IP_INFO_RPT_TYPE, _bFlPbMode, 0); 
  } 
/* 
  switch(_bFlIpState) 
  { 
    case IP_STATE_NORMAL: 
      _bFlMnShift = 0; 
      _bFlIpState = IP_STATE_LEAVING; 
      break; 
    case IP_STATE_HIDE: 
      _bFlMnShift = (99-28+1)/4; 
      _bFlIpState = IP_STATE_ENTERING; 
      break; 
  } 
*/   
  return TRUE; 
} 
 
#ifdef FLMN_RET_PLAY_DIR 
static BOOL fgFlMnRetPlayDir(void) large 
{ 
  BYTE bTmp; 
   
  bTmp = _wFlCurAdoIdx % FLMN_ITEM_N;   //0728    
  if(bTmp == _wFlCurAdoIdx)//0728  
  { 
    return TRUE; 
  }   
  if (fgFlClIsLock()) 
    return TRUE; 
     
  if ((_wFlCurAdoDir == 0xFFFF) || (_wFlCurAdoIdx == 0xFFFF)) 
    return TRUE; 
 
  if (bSharedInfo(FL_LIST_FIELD(_bFlMnListId)) != FLPARM_LIST_FOLDER) 
    return TRUE; 
 
 
  if (!fgFlClLock(FL_CMDPATH_RETURN)) 
    return TRUE; 
  vWorkAreaMove(TRUE); 
 
//  _bFlMnCurItemIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
 
  vFlCmdSet(_bFlMnListId, FLPARM_LIST_FOLDER, FLPARM_INC_PARENT, 
            _wFlCurAdoDir, FLMN_DEF_FFAC | FLPARM_FF_DIR, FLPARM_SO_GDIR); 
 
  return TRUE; 
} 
#endif 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
/////////////////////////////////////////////////////////////////////////////// 
// Play List 
 
/** 
 * Handle IR_MARK to add the current item to playlist. 
 */ 
 
static BOOL fgFlMnPlMark(void) large 
{ 
  //if (fgFlMnIsAudioFile(_bFlMnCurItemIdx)) 
  if (_bFlMnItemType != FTYPE_FOLDER) 
  { 
    vFlCmdAddToPl(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx), 0xFFFF); 
  } 
   
  return TRUE; 
} 
 
static BOOL fgFlMnPlRemove(void) large 
{ 
  WORD  wPos; 
  WORD  wIdx = wFlGetItemIdx(_bFlMnCurItemIdx); 
     
  if ((bSharedInfo(SI_MP3_STT) == MP3STT_PB_STRT) && (FL_MP3_ITEM_IDX == wIdx)) 
  { 
//    vSendUopCmd(UOP_STOP, 0, 0, 0); 
    wPos = FL_ITEM_FIELD(_bFlMnListId); 
    if ((bSharedInfo(wPos + 4) == 0) && (bSharedInfo(wPos + 5) == 0)) 
//      vFlMnSetUopRetJob(UOP_STOP, UOP_RET_PL_RM_LAST); 
      vFlSendUopCmd(UOP_STOP, 0, UOP_RET_PL_RM_LAST); 
    else 
//      vFlMnSetUopRetJob(UOP_STOP, UOP_RET_PL_RM); 
      vFlSendUopCmd(UOP_STOP, 0, UOP_RET_PL_RM); 
  } 
  else 
  { 
    vFlCmdRmFromPl(wIdx); 
    vOsdPosShow(OSD_POS_FS_INFO_BAR, OSD_MSG_FL_REMOVE_FROM_PLAYLIST, OSD_TIMEOUT_SHORT); 
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlMnPlClear(void) large 
{ 
  vFlCmdRmAllFromPl(_bFlMnListId); 
   
  return TRUE; 
} 
 
#endif // DATA_DISC_SUPPORT_PLAY_LIST 
 
#if (defined(DATA_DISC_SUPPORT_DISC_LIST) || defined(DATA_DISC_SUPPORT_PLAY_LIST)) 
static BOOL fgFlMnChgListType(void) large 
{ 
  BYTE  bType, bIncFile; 
  WORD  wPos; 
 
  if (!fgFlClLock(FL_CMDPATH_CHG_LIST)) 
    return TRUE; 
 
  bType = bSharedInfo(FL_LIST_FIELD(_bFlMnListId)); 
 
  switch(bType) 
  { 
    case FLPARM_LIST_FOLDER: 
#if defined (DATA_DISC_SUPPORT_DISC_LIST) 
      wPos = FL_LIST_FIELD(_bFlMnListId); 
      bLoByte(_wBaseDir) = bSharedInfo(wPos + 2); 
      bHiByte(_wBaseDir) = bSharedInfo(wPos + 3); 
      bType = FLPARM_LIST_DISC; 
      bIncFile = 0x0; 
#elif defined (DATA_DISC_SUPPORT_PLAY_LIST) 
      bType = FLPARM_LIST_PLAYLIST; 
      bIncFile = 0x0; 
#else 
      bType = FLPARM_LIST_FOLDER; 
      bIncFile = FLPARM_INC_PARENT; 
#endif 
      break; 
 
#ifdef DATA_DISC_SUPPORT_DISC_LIST 
    case FLPARM_LIST_DISC: 
  #ifdef DATA_DISC_SUPPORT_PLAY_LIST 
      bType = FLPARM_LIST_PLAYLIST; 
      bIncFile = 0x0; 
  #else 
      bType = FLPARM_LIST_FOLDER; 
      bIncFile = FLPARM_INC_PARENT; 
  #endif 
      break; 
#endif 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
    case FLPARM_LIST_PLAYLIST: 
      bType = FLPARM_LIST_FOLDER; 
      bIncFile = FLPARM_INC_PARENT; 
      break; 
#endif 
  } 
  _wFlFdIdx = _wFlCurAdoIdx; 
  _wFlCurAdoIdx = _wFlFlIdx; 
 
  _bFlMnCurItemIdx = 0; 
  switch (bType) 
  { 
    case FLPARM_LIST_FOLDER: 
      vFlCmdSet(_bFlMnListId, bType, bIncFile, 
                _wBaseDir, FLMN_DEF_FFAC | FLPARM_FF_DIR, FLPARM_SO_GDIR); 
      break; 
/* 
    case FLPARM_LIST_DISC: 
      vFlCmdSet(_bFlMnListId, bType, bIncFile, 
                0x0, FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
      break; 
*/ 
    // FLPARM_LIST_FOLDER and FLPARM_LIST_PLAYLIST use tha same route 
    default: 
      vFlCmdSet(_bFlMnListId, bType, bIncFile, 
                0x0, FLMN_DEF_FFAC, FLPARM_SO_GDIR); 
  } 
   
  return TRUE; 
} 
#endif /*#if (defined(DATA_DISC_SUPPORT_DISC_LIST) || defined(DATA_DISC_SUPPORT_PLAY_LIST))*/ 
 
 
#ifdef ISO_AUTO_PLAY 
static BOOL fgFlAutoPlayStart(void) large 
{ 
  if (!fgFlClLock(FL_CMDPATH_ATPLY_0)) 
    return TRUE; 
 
  _wFlAtplyIdx = 0; 
  _fgFlIsAutoPlay = TRUE; 
#ifndef MT1379_MANUFACTURE_TEST 
//  vSetSharedInfo(SI_MP3_ITEM_ERR_ACTION, FL_ITEM_ERR_STOP); 
#endif 
  if (!fgFlCmdGetItems(_bFlRefListId, _wFlAtplyIdx)) 
  { 
    vFlClRls(); 
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlAutoPlayNext(void) large 
{ 
  WORD  wTmp; 
 
  if ((!_fgFlIsAutoPlay) || (!fgFlClLock(FL_CMDPATH_ATPLY_0))) 
    return TRUE; 
 
  _wFlAtplyIdx++; 
 
  bLoByte(wTmp) = bSharedInfo(FL_LIST_FIELD(_bFlRefListId) + 4); 
  bHiByte(wTmp) = bSharedInfo(FL_LIST_FIELD(_bFlRefListId) + 5); 
   
  if ((_wFlAtplyIdx >= wTmp) || (!fgFlCmdGetItems(_bFlRefListId, _wFlAtplyIdx))) 
  { 
    _fgFlIsAutoPlay = FALSE; 
    vFlClRls(); 
  } 
 
  return TRUE; 
} 
 
static BOOL fgFlAutoPlayQuit(void) large 
{ 
  _fgFlIsAutoPlay = FALSE; 
   
  return TRUE; 
} 
#endif 
 
/** 
 * Command handler of init state. 
 */ 
BOOL fgFlOnInit(void) 
{ 
  if (_bIRKey == IR_CMD_DONE) 
  { 
    // - perform init procedure 
    if (FL_ACK(_dwIrDoneParm) == FL_CMD_ASSERT) 
    { 
      // - what we consider 
      switch (bSharedInfo(FL_CMD_BLK_SA)) 
      { 
      case FLCMD_CREATE: 
        vFlMnRetCreate(); 
/* 
        // - there is only one list creation, change target to default 
        if (bSharedInfo(SI_DISC_TYPE) == SV_PCD) 
        { 
          vFlSetCmdTarget(FL_CMD_TARGET_JPEG); 
        } 
        else 
        { 
          if (_wFlCurAdoIdx == 0xFFFF) 
          { 
            vFlSetCmdTarget(FL_CMD_TARGET_MENU); 
          } 
          else 
          { 
            _bFlMnCurItemIdx = _wFlCurAdoIdx % FLMN_ITEM_N; 
            fgFlCmdGetItems(_bFlMnListId, _wFlCurAdoIdx - _bFlMnCurItemIdx); 
          } 
        } 
*/ 
        break; 
      default: 
        break; 
      } 
    } 
  } 
  else 
  { 
    // - should not happen, do nothing 
  } 
 
  return TRUE; 
} 
 
/** 
 * Event handler of the object "file list menu". 
 */ 
BOOL fgFlOnMn(void) large 
{ 
  BOOL fgIsGrabbed = FALSE; 
 
#ifdef ISO_AUTO_PLAY 
  switch (_bIRKey) 
  { 
  case IR_SELECT_DONE: 
  case IR_PLAY_ENTER: 
  case IR_PLAY: 
  case IR_ENTER: 
  case IR_PLAY_PAUSE: 
  case IR_PROGRAM: 
    fgFlAutoPlayQuit(); 
    break; 
  } 
#endif 
  // - IR dispatcher 
  switch (_bIRKey) 
  { 
  case IR_CMD_DONE: 
    fgIsGrabbed = fgFlMnIrCmdDoneHdr(); 
    break; 
  case IR_SELECT_DONE: 
    fgIsGrabbed = fgFlMnOnIrSelDone(); 
    break; 
  case IR_PLAY_ENTER: 
  case IR_PLAY: 
  case IR_ENTER: 
  case IR_PLAY_PAUSE: 
    fgIsGrabbed = fgFlMnOnIrPlay(); 
    break; 
#ifndef DATA_DISC_SUPPORT_DISC_LIST 
  case IR_PROGRAM:    	 
  	fgIsGrabbed = TRUE; 
  	break; 
#endif 
 
  case IR_PAUSE: 
    fgIsGrabbed = fgFlMnOnIrPause(); 
    break; 
  case IR_UP: 
    fgIsGrabbed = fgFlMnOnIrUp(); 
    break; 
  case IR_DOWN: 
    fgIsGrabbed = fgFlMnOnIrDown(); 
    break; 
  case IR_LEFT: 
    fgIsGrabbed = fgFlMnOnIrLeft(); 
    break; 
  case IR_RIGHT: 
    fgIsGrabbed = fgFlMnOnIrRight(); 
    break; 
  case IR_NEXT: 
    fgIsGrabbed = fgFlMnOnIrNext(); 
    break; 
  case IR_PREV: 
    fgIsGrabbed = fgFlMnOnIrPrev(); 
    break; 
#ifdef FLMN_MP3_NO_SLOW 
  case IR_SF: 
  case IR_SR: 
    fgIsGrabbed = TRUE; 
    break; 
#endif 
  case IR_ROOT_MENU: 
    fgIsGrabbed = TRUE; 
    break; 
#ifdef FLMN_RET_PLAY_DIR 
  case IR_RETURN: 
    fgIsGrabbed = fgFlMnRetPlayDir(); 
    break; 
#endif  
  case IR_DISPLAY: 
    fgIsGrabbed = fgFlMnChgInfoPanel(); 
    break; 
 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
#ifdef IR_PLAYLIST_ADD_DEL 
  case IR_PLAYLIST_ADD_DEL: 
    if (FL_LIST_TYPE(0x0) == FLPARM_LIST_PLAYLIST) 
      fgIsGrabbed = fgFlMnPlRemove(); 
    else 
      fgIsGrabbed = fgFlMnPlMark(); 
    break; 
#else 
  case IR_PLAYLIST_ADD: 
    fgIsGrabbed = fgFlMnPlMark(); 
    break; 
  case IR_PLAYLIST_DEL: 
      fgIsGrabbed = fgFlMnPlRemove(); 
    break; 
#endif 
  case IR_PLAYLIST_CLEAN: 
    fgIsGrabbed = fgFlMnPlClear(); 
    break; 
#endif // DATA_DISC_SUPPORT_PLAY_LIST 
 
#ifdef DATA_DISC_SUPPORT_DISC_LIST 
  case IR_CHG_LIST: 
    fgIsGrabbed = fgFlMnChgListType(); 
    break; 
#endif     
     
//  case IR_REPEAT: 
//    fgIsGrabbed = fgFlMnOnIrRepeat(); 
//    break; 
  case IR_RANDOM: 
    fgIsGrabbed = fgFlMnOnIrRandom(); 
    break; 
#ifdef FLMENU_FUNC_TEST 
  case IR_NEXT_FILE: 
    fgIsGrabbed = fgFlMnOnIrNextFile(); 
    break; 
  case IR_PREV_FILE: 
    fgIsGrabbed = fgFlMnOnIrPrevFile(); 
    break; 
#endif 
#ifdef ISO_AUTO_PLAY 
  case IR_AUTO_PLAY: 
    if (_fgFlIsAutoPlay) 
      fgIsGrabbed = fgFlAutoPlayQuit(); 
    else 
      fgIsGrabbed = fgFlAutoPlayStart(); 
    break; 
#endif 
  default: 
    // - do _NOTHING_ here 
    break; 
  } 
 
  return fgIsGrabbed; 
} 
 
//////////////////////////////////////////////////////////////////////////////// 
// Timer  
 
static code BYTE bFlMnTimerState[FLMN_TIMER_JOB_NS] =  // 2 * 20 ms 
{ 
  FLMN_TIMER_DRAW_SCROLLING_SCRIPT, 
  FLMN_TIMER_SCROLL_WB, 
  FLMN_TIMER_CHECK_PREVIEW, 
  FLMN_TIMER_SHOW_BITRATE, 
  FLMN_TIMER_NONE, 
  FLMN_TIMER_SCROLL_WB, 
 
  FLMN_TIMER_DRAW_SCROLLING_SCRIPT, 
  FLMN_TIMER_NONE, 
  FLMN_TIMER_CHECK_PREVIEW, 
  FLMN_TIMER_SCROLL_WB, 
  FLMN_TIMER_NONE, 
  FLMN_TIMER_NONE 
}; 
 
#ifdef FLMN_TEST_NEW_FUNC 
static void vFlMnTimerScrollWB(void) large 
{ 
  WORD wOffset; 
 
  switch(_bFlIpState) 
  { 
    case IP_STATE_LEAVING: 
      wOffset = (WORD)FSMENU_BASIC_WB_TOP - 5 - (_bFlMnShift++) * 2; 
      break; 
    case IP_STATE_ENTERING: 
      wOffset = (_bFlMnShift--) * 2; 
      break; 
    default: 
      return; 
  } 
 
  //_bFlMnShift++; 
  //wOffset = _bFlMnShift * 2; 
  vWaitBusy(); 
  vBeginWriteSharedGrp(SI_OSD_CMD_PRM_GRP, OSD_CMD_SCROLL_WB); 
  vWriteNextSharedItem(FL_INFO_WB); 
  vWriteNextSharedItem(bLoByte(wOffset)); 
  vWriteNextSharedItem(bHiByte(wOffset)); 
  vSendOsdCmd(); 
 
  switch(_bFlIpState) 
  { 
    case IP_STATE_LEAVING: 
      //if (_bFlMnShift == 17) 
      if (_bFlMnShift == (99-28+1)/4) 
      { 
        _bFlMnShift = 0; 
        _bFlIpState = IP_STATE_HIDE; 
//        vVoidDis(); 
      } 
      break; 
    case IP_STATE_ENTERING: 
      if (_bFlMnShift == 0) 
      { 
        _bFlIpState = IP_STATE_NORMAL; 
        vVoidDis(); 
      } 
      break; 
  } 
 
  //_wEndY = (FSMENU_BASIC_WB_TOP - 5 - 36 + 1); 
  if (_bFlIpState != IP_STATE_NORMAL) 
  { 
    if (_bFlIpState == IP_STATE_HIDE) 
    { 
      _wStartY = 28; 
    } 
    else 
    { 
      _wStartY = (WORD)FSMENU_BASIC_WB_TOP - 5 - wOffset * 2; 
    } 
    _wEndY = (WORD)FSMENU_BASIC_WB_TOP - 5; 
    _wStartX = (WORD)FSMENU_BASIC_WB_LEFT; 
    _wEndX = (WORD)FSMENU_BASIC_WB_LEFT + FSMENU_BASIC_WB_WIDTH + 1;   
    vSetVoidRng(FL_INFO_WB); 
    vVoidEn(); 
  } 
} 
#endif 
 
/** 
 * JPEG preview timer service routine. 
 * 
 * DES: 
 *  PREVIEW_STATE_START,    start to waiting 
 *  PREVIEW_STATE_TIMER0,   first stage 
 *  PREVIEW_STATE_TIMER1,   expire to launch the preview 
 *  PREVIEW_STATE_IDLE,     do nothing as you see 
 *  PREVIEW_STATE_FINISH,   do nothing state (may be removed) 
 */ 
#ifdef JPG_PREVIEW_SUPPORT  
static void vFlMnTimerJpgPv(void) large 
{ 
  switch(_bPreview) 
  { 
    case PREVIEW_STATE_START: 
      _bPreview = PREVIEW_STATE_TIEMR0; 
      break; 
    case PREVIEW_STATE_TIEMR0: 
      _bPreview = PREVIEW_STATE_TIEMR1; 
      break; 
    case PREVIEW_STATE_TIEMR1: 
      if (_bFlMnItemType == FTYPE_STILL) 
      { 
        // - cover the previous preview image 
        vFlCmdClickItem(_bFlMnListId, wFlGetItemIdx(_bFlMnCurItemIdx)); 
                        //FLCMD_RET_OP_CMDACK); 
      } 
      else 
      { 
        // - error occure 
      } 
      _bPreview = PREVIEW_STATE_FINISHED; 
      break; 
    default: 
      // - do nothing here 
      break; 
  } 
 
  return; 
} 
#endif 
 
static void vFlMnTimerShowBitrate(void) large 
{ 
  //if (bSharedInfo(SI_MP3_STT) == MP3STT_PB_STRT) 
  if (bSharedInfo(SI_MP3_MOD) != SV_STOP) 
  { 
    vFlIpShowInfo(IP_INFO_BITRATE, 0, 
                  bSharedInfo(SI_MP3_BITRATE_LO) + bSharedInfo(SI_MP3_BITRATE_HI) * 256); 
  } 
  else 
  { 
    vFlIpShowInfo(IP_INFO_BITRATE, 0, 0); 
  } 
 
  return; 
} 
 
/** 
 * Handler the timer interrupt. 
 */ 
void vFlMnOnTimer(void) large 
{ 
  if ((!fgIsIsoPlay() 
#ifdef SUPPORT_PCD 
    && !fgIsPcdPlay() 
#endif 
    ) || fgIsScrSaverOn() || fgIsInSetupMenu()) 
    return; 
 
  _bFlMnTimer--; 
 
  switch(bFlMnTimerState[_bFlMnTimer % 12]) 
  { 
    case FLMN_TIMER_CHECK_PREVIEW: 
#ifndef DDISC_ENB_CONC_AV_MODE 
      if (bSharedInfo(SI_MP3_STT) != MP3STT_PB_STRT) 
#endif 
#ifdef JPG_PREVIEW_SUPPORT  
        vFlMnTimerJpgPv(); 
#endif         
      break; 
    case FLMN_TIMER_SCROLL_WB: 
#ifdef FLMN_TEST_NEW_FUNC 
      vFlMnTimerScrollWB(); 
#endif 
      break; 
    case FLMN_TIMER_DRAW_SCROLLING_SCRIPT: 
      //vFlMnTimerScrollingStr(); 
      break; 
    case FLMN_TIMER_SHOW_BITRATE: 
      vFlMnTimerShowBitrate(); 
      break; 
  } 
 
  if (_bFlMnTimer == 0) 
    _bFlMnTimer = FLMN_TIMER_PERIOD; 
 
  return; 
} 
 
//#ifndef NEW_PLAY 
void vFlMnHandleUopRet(BYTE bUopId) large 
{ 
  switch (bUopId) 
  { 
    case UOP_STOP: 
      vFlIpShowInfo(IP_INFO_PLAYTIME, 0, 0); 
      break; 
    case UOP_REPEAT: 
    case UOP_SHUFFLE: 
      vFlIpShowInfo(IP_INFO_RPT_TYPE, _bFlPbMode, 0); 
      break; 
     
  } 
     
  if (_bFlWaitUopRet == bUopId) 
  { 
    switch(bUopId) 
    { 
      case UOP_STOP: 
        switch (_bFlUopRetJob) 
        { 
#ifdef DATA_DISC_SUPPORT_PLAY_LIST 
          case UOP_RET_PL_RM: 
          case UOP_RET_PL_RM_LAST: 
            vFlCmdRmFromPl(wFlGetItemIdx(_bFlMnCurItemIdx));//, FLCMD_RET_OP_CMDACK); 
            vOsdPosShow(OSD_POS_FS_INFO_BAR, OSD_MSG_FL_REMOVE_FROM_PLAYLIST, OSD_TIMEOUT_SHORT); 
            break; 
#endif 
        } 
        break; 
    } 
    _bFlWaitUopRet = 0xFF; 
  } 
} 
//#endif 
 
static code WORD pwOsdLang[EV_OSD_LANG_NS] = 
{ 
  OSD_MSG_OSDLANG_ENGLISH, 
//  OSD_MSG_OSDLANG_CHINESE 
}; 
 
void vFlMnChgLang(BYTE bLang) large 
{ 
  vFlIpShowInfo(IP_INFO_CHG_LANG, 0, pwOsdLang[bLang]); 
} 
 
#endif  // #ifdef PLAYER_FLMENU