⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcd_con.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }
    else
    {
        error = 0xff;
    }
errout:

    if (TracksFile != 0)
    {
        LoaderFileClose(tLoader, TracksFile);
    }

    return (error);
}


VCD_VER find_vcd_type(char *vcd_dir, char *vcd_ext)
{
    BYTE    bVCD   = 1;
    BYTE    bSVCD  = 1;
    BYTE    bHQVCD = 1;

    if (LoaderFileAccess(tLoader, "/mnt/cdrom/vcd", LOADER_FILE_ACCESS_EXIST, &bVCD) != LOADER_SUCCESS)
    {
        DbgPrint(("%s:%u - ERROR", __FILE__, __LINE__));
        return(VCD_VER_UNKNOWN);
    }

    if (LoaderFileAccess(tLoader, "/mnt/cdrom/hqvcd", LOADER_FILE_ACCESS_EXIST, &bHQVCD) != LOADER_SUCCESS)
    {
        DbgPrint(("%s:%u - ERROR", __FILE__, __LINE__));
        return(VCD_VER_UNKNOWN);
    }

    if (LoaderFileAccess(tLoader, "/mnt/cdrom/svcd", LOADER_FILE_ACCESS_EXIST, &bSVCD) != LOADER_SUCCESS)
    {
        DbgPrint(("%s:%u - ERROR", __FILE__, __LINE__));
        return(VCD_VER_UNKNOWN);
    }


    if (bVCD)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("IT'S A VCD\n"));
        strncpy(vcd_dir, "vcd\0", 4);
        strncpy(vcd_ext, "vcd\0", 4);
        return(VCD_VER_VCD);
    }
    else if (bHQVCD)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("IT'S AN HQVCD\n"));
        strncpy(vcd_dir, "hqvcd\0", 6);
        strncpy(vcd_ext, "vcd\0", 4);
        return(VCD_VER_HQVCD);
    }
    else if (bSVCD)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("IT'S AN SVCD\n"));
        strncpy(vcd_dir, "svcd\0", 5);
        strncpy(vcd_ext, "svd\0", 4);
        return(VCD_VER_SVCD);
    }

    return(VCD_VER_UNKNOWN);
}




/*************************************************
    Function Name:  get_vcd_info

    Purpose:    Loads and parses the INFO.VCD file.

    Theory:     Loads the INFO.VCD and ENTRIES.VCD
                files and from that information dtermines
                if it is a VCD 1.1, VCD 2.0, SVCD, or VCD
                and takes appropriate action.

    Arguments:  none

    Returns:    error

*************************************************/
CHAR get_vcd_info(void)
{
    UBYTE   load_status;
    char    vcd_dir[10];
    char    vcd_ext[4];
    VCD_VER vcd_type;


    vcd_type = find_vcd_type(&vcd_dir[0], &vcd_ext[0]);

    if (vcd_type == VCD_VER_UNKNOWN)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("VCD type is UNKNOWN\n"));
        return(-1);
    }


    load_status = load_vcd_info(vcd_dir, vcd_ext);

    if (load_status == 0xff)
    {
        return(-1);
    }

    load_status = load_vcd_entry(vcd_dir, vcd_ext);

    if (load_status == 0xff)
    {
        return(-1);
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("$$$$$$$ - g_info_vcd.ver = 0x%X\n", g_info_vcd.ver));

    VERSION_FLG = 1;

    /* load tracks.svd if it's an svcd */
    if (vcd_type == VCD_VER_SVCD)
    {
        load_status = load_tracks_svd();

        if (load_status == 0xff)
        {
            return(-1);
        }

        DBGPRINT(DBG_ON(DBG_TRACE), ("g_tracks_svd.ver = 0x%X\n", g_tracks_svd.ver));

        if ( (g_tracks_svd.ver == 0x0100) || (g_tracks_svd.ver == 0x7420) )/* 0x7420 is a CVD hack based on current info */
        {
            VERSION_FLG = 2;
        }
    }

    if (vcd_type == VCD_VER_HQVCD)
    {
        VERSION_FLG = 2;
    }


    /* if it's a simple vcd (no psd) */
    if ( ( (g_info_vcd.ver != 0x0200) && (VERSION_FLG == 1) ) || (g_info_vcd.psd_size == 0) )
    {
        if ( (g_info_vcd.ver == 0x0200) || (VERSION_FLG > 1) )
        {
            /* force it back into VCD 1.1 */
            g_info_vcd.ver = 0x01F1;
        }

        goto simple_vcd;
    }


    /*
     * it's (possibly) a vcd with menus (or an svcd or hqvcd) - parse these tables
     */
    DBGPRINT(DBG_ON(DBG_TRACE), ("LOAD_LOT\n"));

    load_status = load_vcd_lot(vcd_dir, vcd_ext);

    if (load_status == 0xff)
    {
        /* force it back into VCD 1.1 */
        g_info_vcd.ver = 0x01F1;
        goto simple_vcd;
    }


    DBGPRINT(DBG_ON(DBG_TRACE), ("LOAD_PSD\n"));

    load_status = load_vcd_psd(vcd_dir, vcd_ext);

    if (load_status == 0xff)
    {
        /* force it back into VCD 1.1 */
        g_info_vcd.ver = 0x01F1;
        goto simple_vcd;
    }


    /* tables were successfully parsed - play using playlists */

    DBGPRINT(DBG_ON(DBG_TRACE), ("$$$$$$  PSD VCD!\n"));

    return (1);


simple_vcd:

    DBGPRINT(DBG_ON(DBG_TRACE), ("$$$$$$ NO PSD!\n"));

    return (0);
}




/*************************************************
    Function Name:  stop_on_error

    Purpose:    Stop all playback.

    Theory:     If an error happens during navigation
                data loading, this will stop all
                playback and put the system into a
                STOP state.

    Arguments:  none

    Returns:    nothing

*************************************************/
void stop_on_error(void)
{
    ULONG out_msg[4];

    DBGPRINT(DBG_ON(DBG_TRACE), ("stop_on_error: ENTER\n"));

    logo_display();
    pbc_stop_com();     /* Stop Set */

    out_msg[0] = VDVD_STATUS_STOP;
    out_msg[1] = 2;
    if (UsrEventHandler(out_msg) != USR_SUCCESS)
    {
        DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
    }
}

/*************************************************
    Function Name:  pbc_apause

    Purpose:    Send a timeout message to the VCD task.

    Theory:     When the auto pause timer expires, this sends
                a message to the VCD task to notify of a
                timeout.

    Arguments:  none

    Returns:    nothing

*************************************************/
void pbc_apause(void)
{
    ULONG msg[4];

    DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_apause: ENTER\n"));

    msg[0] = MSG_TIM_OUT;

    OS_MsgQSend(queue_vcd, (char *)&msg[0], VCD_MSG_SIZE, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
}

/*************************************************
    Function Name:  msf_modify

    Purpose:    Perform a math operation on a MSF number.

    Theory:     MSF numbers have no strict base so to do
                adds or subtracts we need to do some in
                depth checking.

    Arguments:  MSF value, number to modify with, operation to
                perform

    Returns:    new MSF value

*************************************************/
ULONG msf_modify(ULONG msf, ULONG num, UBYTE op)
{
    UBYTE msf_arr[3], num_arr[3];
    ULONG temp_num;

    DBGPRINT(DBG_ON(DBG_TRACE), ("msf_modify: Perform a math operation on a MSF number\n"));

    msf_arr[0] = com_bcdtobin( (UBYTE)((msf & 0xFF0000) >> 16) );
    msf_arr[1] = com_bcdtobin( (UBYTE)((msf & 0xFF00) >> 8) );
    msf_arr[2] = com_bcdtobin( (UBYTE)(msf & 0xFF) );

    num_arr[0] = (UBYTE)(num / 4500);

    temp_num = num - (num_arr[0] * 4500);

    num_arr[1] = (UBYTE)(temp_num / 75);

    temp_num = temp_num - (num_arr[1] * 75);

    num_arr[2] = (UBYTE)(temp_num);

    if (op == ADD_MSF)
    {
        msf_arr[2] += num_arr[2];
        msf_arr[1] += num_arr[1];
        msf_arr[0] += num_arr[0];
    }
    else
    {
        if (num_arr[2] > msf_arr[2])
        {
            if (msf_arr[1] > 0)
            {
                msf_arr[1]--;
                msf_arr[2] += 75;
            }
            else
            {
                msf_arr[0]--;
                msf_arr[1] += 59;
                msf_arr[2] += 75;
            }
        }

        msf_arr[2] -= num_arr[2];

        if (num_arr[1] > msf_arr[1])
        {
            msf_arr[0]--;
            msf_arr[1] += 60;
        }

        msf_arr[1] -= num_arr[1];
        msf_arr[0] -= num_arr[0];
    }

    num_arr[2] = msf_arr[2] / 75;
    if (num_arr[2])
    {
        msf_arr[1] += num_arr[2];
        msf_arr[2] -= (num_arr[2] * 75);
    }

    num_arr[1] = msf_arr[1] / 60;
    if (num_arr[1])
    {
        msf_arr[0] += num_arr[1];
        msf_arr[1] -= (num_arr[1] * 60);
    }

    msf_arr[0] = com_bintobcd(msf_arr[0]);
    msf_arr[1] = com_bintobcd(msf_arr[1]);
    msf_arr[2] = com_bintobcd(msf_arr[2]);

    return (combine_msf(&msf_arr[0]));
}



/*************************************************
    Function Name:  com_bcd_chk

    Purpose:    Check if valid BCD number

    Theory:     Looks at a BCD number to make sure
                each nibble is not more than 0x9.

    Arguments:  BCD number

    Returns:    valid BCD number or not

*************************************************/
UBYTE com_bcd_chk(UBYTE bcd)
{
    if ((bcd & 0x0F) > 9)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("com_bcd_chk: INVALID!!!\n"));
        return (0xff);
    }
    if (((bcd & 0x0F0) >> 4) > 9)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("com_bcd_chk: INVALID!!!\n"));
        return (0xff);
    }

    return (0);
}






/*************************************************
    Function Name:  vcdReadToc

    Purpose:    Read the VCD table of contents.

    Arguments:  none

    Returns:    0 for success.  otherwise for failure

*************************************************/
static int vcdReadToc(void)
{
#define LDR_BUF_SIZE 2048

    LOADER_ERR err;
    int        entries;
    int        x;
    ULONG      tocsize;
    BYTE       first;                   /* first track no. */
    BYTE       last;                    /* last track no. */
    BYTE       last_track       = 0;    /* last track # */

    BYTE       bLdrBuffer[LDR_BUF_SIZE];


    const BYTE TRACK_MAX      = 99;     /* maximum track number */
    const BYTE SESS_MIN       = 1;      /* minimum session number */
    const BYTE SESS_MAX       = 40;     /* maximum session number */
    const BYTE FORMAT_TRK     = 0x0;    /* get track info - Mt.Fuji spec. Table 365 */
    const BYTE FORMAT_SESS    = 0x1;    /* get session info */
    const BYTE FORMAT_FULL    = 0x2;    /* get all info */
    const BYTE TRK_DESC_SIZE  = 10;     /* in FORMAT_TRK each track descriptor returned is 10 bytes in size */
    const BYTE SESS_DESC_SIZE = 10;     /* in FORMAT_SESS each track descriptor returned is 10 bytes in size */
    const BYTE FULL_DESC_SIZE = 11;     /* in FORMAT_FULL each track descriptor returned is 11 bytes in size */
    const BYTE READ_MSF       = 0x2;    /* Mt.Fuji spec. Table 364 byte 1, bit 1 */
    const BYTE READ_LBN       = 0x0;    /* Mt.Fuji spec. Table 364 byte 1, bit 1 */

    UNUSED_PARAM(SESS_MIN);
    UNUSED_PARAM(SESS_MAX);
    UNUSED_PARAM(FORMAT_TRK);
    UNUSED_PARAM(FORMAT_SESS);
    UNUSED_PARAM(FORMAT_FULL);
    UNUSED_PARAM(TRK_DESC_SIZE);
    UNUSED_PARAM(SESS_DESC_SIZE);
    UNUSED_PARAM(READ_MSF);
    UNUSED_PARAM(READ_LBN);

    /* start by clearing the buffer */
    memset(bLdrBuffer, 0, LDR_BUF_SIZE);

    /* find the toc size */
    err = LoaderGetTOC (tLoader, LOADER_TOC_CMD_FULL_TOC, 0, LOADER_TOC_MSF, bLdrBuffer, 4);
    if (LOADER_SUCCESS != err)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetTOC() - FAILURE reading TOC data\n"));
        return (-1);
    }

    /* set and check track data for session #1 */
    tocsize = MAKE_WORD(bLdrBuffer) + 2; /* data length not included so add 2 */
    first   = bLdrBuffer[2];             /* first complete session       */
    last    = bLdrBuffer[3];             /* last complete session        */

    if (1 != first) /* No first session found */
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetTOC() - First Session Not Found\n"));
        return (-1);
    }

    if (1 != last) /* multi-session disc */
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetTOC() - MULTI_SESSION DISC (%i sessions)\n", last - first + 1));
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("TOC DATA size = %i, first session = %i, last session = %i\n", tocsize, first, last));

    /* get the data for all tracks */
    err = LoaderGetTOC (tLoader, LOADER_TOC_CMD_FULL_TOC, 1, LOADER_TOC_MSF, bLdrBuffer, tocsize);
    if (LOADER_SUCCESS != err)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -