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

📄 ig_parse.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPageEffects(): Num Windows was too large: %d\n", Eff->NumWindows));
            return IG_STATUS_ERROR;
        }

        /* read in the windows */
        for (i=0; i<Eff->NumWindows; i++)
        {
            BYTE WindowID = *SegmentIndex;
            Eff->WindowList[WindowID].X = MAKE_WORD(SegmentIndex+1);
            Eff->WindowList[WindowID].Y = MAKE_WORD(SegmentIndex+3);
            Eff->WindowList[WindowID].Width = MAKE_WORD(SegmentIndex+5);
            Eff->WindowList[WindowID].Height = MAKE_WORD(SegmentIndex+7);

            SegmentIndex += SIZE_WINDOW;
        }
    }

    /* now load the number of effects */
    Eff->NumEffects = *SegmentIndex;
    SegmentIndex++;

    if (0 != Eff->NumEffects)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadICSPageEffects(): There are effects!\n"));

        /* we have space, start reading them all in */
        for (i=0; i<Eff->NumEffects; i++)
        {
#ifdef VDVD_LITTLE_ENDIAN
            Eff->EffectsList[i].EffectDuration = ((*SegmentIndex) << 16) | ((*(SegmentIndex+1)) << 8) | (*(SegmentIndex+2));
#else
            memcpy(&Eff->EffectsList[i].EffectDuration, SegmentIndex, 3);
#endif
            Eff->EffectsList[i].PaletteIDRef = *(SegmentIndex+3);
            Eff->EffectsList[i].NumCompObjs = *(SegmentIndex+4);
            SegmentIndex += 5;

            if (Eff->EffectsList[i].NumCompObjs > MAX_EFFECTS_OBJECTS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPageEffects(): Num Comp Objs was too large: %d\n", Eff->EffectsList[i].NumCompObjs));
            }

            /* load the array of composition objects */
            for (CompCur=0; CompCur<Eff->EffectsList[i].NumCompObjs; CompCur++)
            {
                Eff->EffectsList[i].CompObjs[CompCur].ObjectIDRef = MAKE_WORD(SegmentIndex);
                Eff->EffectsList[i].CompObjs[CompCur].WindowIDRef = *(SegmentIndex+2);
                Eff->EffectsList[i].CompObjs[CompCur].CroppedFlag = ((*(SegmentIndex+3)) & BIT7) >> 7;
                Eff->EffectsList[i].CompObjs[CompCur].ForcedOnFlag = ((*(SegmentIndex+3)) & BIT6) >> 6;
                Eff->EffectsList[i].CompObjs[CompCur].XPosition = MAKE_WORD(SegmentIndex+4);
                Eff->EffectsList[i].CompObjs[CompCur].YPosition = MAKE_WORD(SegmentIndex+6);

                /* if we have a cropping rectangle load it */
                if (1 == Eff->EffectsList[i].CompObjs[CompCur].CroppedFlag)
                {
                    Eff->EffectsList[i].CompObjs[CompCur].Rect.X = MAKE_WORD(SegmentIndex+8);
                    Eff->EffectsList[i].CompObjs[CompCur].Rect.Y = MAKE_WORD(SegmentIndex+10);
                    Eff->EffectsList[i].CompObjs[CompCur].Rect.Width = MAKE_WORD(SegmentIndex+12);
                    Eff->EffectsList[i].CompObjs[CompCur].Rect.Height = MAKE_WORD(SegmentIndex+14);

                    /* bump the effects index up since we have a cropping rectangle */
                    SegmentIndex += SIZE_CROPPING_RECTANGLE;
                }

                /* move to next comp object */
                SegmentIndex += SIZE_COMPOSITION_OBJECT_NO_CROP;  /* size of composition object without cropping rect */
            }
        }
    }

    /* how far did we go */
    *MovedBytes = SegmentIndex - DataStart;

    return IG_STATUS_SUCCESS;
}


/**
 * IGLoadICSPageBogs - load the button object groups for the page specified
 *
 * @param BYTE DataStart - the stream data we are processing
 * @param PAGE *Page - the page structure where the button object groups will be loaded
 * @param ULONG *MovedForward - the number of bytes we moved ahead
 *
 * @return IG_STATUS
 */
IG_STATUS IGLoadICSPageBogs(BYTE *DataStart, PAGE *Page, ULONG *MovedForward)
{
    BYTE *SegmentIndex = DataStart;
    ULONG MovedBytes=0;
    int i;

    /* space is already allocated for the bogs, just fill it */
    for (i=0; i<Page->NumBogs; i++)
    {
        Page->Bogs[i].DefaultValidButtonIDRef = MAKE_WORD(SegmentIndex);
        Page->Bogs[i].NumButtons = *(SegmentIndex+2);
        SegmentIndex += 3;

        if (Page->Bogs[i].NumButtons > 0)
        {
            /* allocate space for buttons */
            Page->Bogs[i].Buttons = (BUTTON *) OS_MemAlloc(Page->Bogs[i].NumButtons * sizeof(BUTTON));
            if (NULL == Page->Bogs[i].Buttons)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPageBogs(): Failed to get space for ics->page->bogs->buttons\n"));
                goto errout;
            }

            /* load buttons here */
            IGLoadICSPageBogsButtons(SegmentIndex, Page->Bogs[i].Buttons, Page->Bogs[i].NumButtons, &MovedBytes);
            SegmentIndex += MovedBytes;
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPageBogs(): there are no buttons in the bog\n"));
        }
    }

    *MovedForward = SegmentIndex - DataStart;

    return IG_STATUS_SUCCESS;

errout:

    /* free the buttons */
    for (i=0; i<Page->NumBogs; i++)
    {
        if (Page->Bogs[i].NumButtons > 0)
        {
            if (NULL != Page->Bogs[i].Buttons)
            {
                OS_MemFree(Page->Bogs[i].Buttons);
                Page->Bogs[i].Buttons = NULL;
            }
        }
    }

    return IG_STATUS_ERROR;
}


/**
 * IGLoadICSPageBogsButtons - load the button object groups for the page specified
 *
 * @param BYTE DataStart - the stream data we are processing
 * @param BUTTON *Buttons - the buttons group we are loading
 * @param BYTE NumButtons - the number of buttons to load
 * @param ULONG *MovedForward - the number of bytes we moved ahead
 *
 * @return IG_STATUS
 */
IG_STATUS IGLoadICSPageBogsButtons(BYTE *DataStart, BUTTON *Buttons, BYTE NumButtons, ULONG *MovedForward)
{
    BYTE *SegmentIndex = DataStart;

    /* loop over the buttons */
    for (int i=0; i<NumButtons; i++)
    {
        Buttons[i].ButtonID = MAKE_WORD(SegmentIndex);
        Buttons[i].ButtonNumericSelectValue = MAKE_WORD(SegmentIndex+2);
        Buttons[i].AutoActionFlag = ((*(SegmentIndex+4)) & BIT7) >> 7;
        Buttons[i].XPosition = MAKE_WORD(SegmentIndex+5);
        Buttons[i].YPosition = MAKE_WORD(SegmentIndex+7);

        /* neighbor info */
        Buttons[i].UpperButtonIDRef = MAKE_WORD(SegmentIndex+9);
        Buttons[i].LowerButtonIDRef = MAKE_WORD(SegmentIndex+11);
        Buttons[i].LeftButtonIDRef = MAKE_WORD(SegmentIndex+13);
        Buttons[i].RightButtonIDRef = MAKE_WORD(SegmentIndex+15);

        /* normal state info (animation) */
        Buttons[i].NormalStartObjectIDRef = MAKE_WORD(SegmentIndex+17);
        Buttons[i].NormalEndObjectIDRef = MAKE_WORD(SegmentIndex+19);
        Buttons[i].NormalRepeatFlag = ((*(SegmentIndex+21)) & BIT7) >> 7;

        /* select state info (animation) */
        Buttons[i].SelectedStateSoundIDRef = *(SegmentIndex+22);
        Buttons[i].SelectedStartObjectIDRef = MAKE_WORD(SegmentIndex+23);
        Buttons[i].SelectedEndObjectIDRef = MAKE_WORD(SegmentIndex+25);
        Buttons[i].SelectedRepeatFlag = ((*(SegmentIndex+27)) & BIT7) >> 7;

        /* activation state info (animation) */
        Buttons[i].ActivatedStateSoundIDRef = *(SegmentIndex+28);
        Buttons[i].ActivatedStartObjectIDRef = MAKE_WORD(SegmentIndex+29);
        Buttons[i].ActivatedEndObjectIDRef = MAKE_WORD(SegmentIndex+31);

        /* yet another nesting, this time navigaton commands */
        Buttons[i].NumNavCommands = MAKE_WORD(SegmentIndex+33);
        SegmentIndex+=35;

        /* copy the nav commands */
        if ((Buttons[i].NumNavCommands > 0) && (Buttons[i].NumNavCommands <= MAX_NAVIGATION_COMMANDS))
        {
            memcpy(&Buttons[i].NavCommands, SegmentIndex, SIZE_NAVIGATION_COMMAND * Buttons[i].NumNavCommands);
            SegmentIndex += SIZE_NAVIGATION_COMMAND * Buttons[i].NumNavCommands;
        }

        /* load extra flags */
        Buttons[i].ButtonState = BUTTON_DISABLED;
        Buttons[i].CurrentDisplayObjectIDRef = 0xFFFF;
    }

    *MovedForward = SegmentIndex - DataStart;

    return IG_STATUS_SUCCESS;
}


/**
 * IGLoadPalette - load a palette into the palettes array
 *
 * @param BYTE *DataStart - pointer to the start of the palette
 * @param ULONG DataLength - size of DataStart in bytes
 *
 * @return IG_STATUS
 */
IG_STATUS IGLoadPalette(BYTE *DataStart, ULONG DataLength)
{
    /* use the segment length to determine the number of colors */
    BYTE *PalPtr = DataStart+2;
    PALETTE *CurPal = NULL;
    int PaletteNumber = *(DataStart);
    int NumEntries;
    BYTE fClearPalette=0;

    if (IGInfo.CurrentState != IG_STATE_RUNNING)
    {
        return IG_STATUS_SUCCESS;
    }

    /* make sure this palette number doesn't overrun memory */
    if (PaletteNumber >= IG_MAX_PALETTES)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadPalette(): Invalid palette index, palette not parsed\n"));
        return IG_STATUS_ERROR;
    }

    /* select the proper palette in the arrays */
    CurPal = &IGPalettes[PaletteNumber];

    /* load ig palette with this */
    CurPal->PaletteVersion = *(DataStart+1);

    /* calculate the number of entries, if the diviosion rounds data incorrectly the palette is
    wrong anyway and we will miss some entries at the end */
    NumEntries = (DataLength-2) / SIZE_PALETTE_ENTRY;

    /* check that the palette entries are all filled up */
    if ((DataLength-2) % SIZE_PALETTE_ENTRY != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadPalette(): Invalid Palette Entries\n"));
        return IG_STATUS_ERROR;
    }

    /* see if this is ACQ_POINT, EPOCH_START, or EPOCH_CONT, if so wipe the palette and update
       otherwise we just update the palette */
    if (IGInfo.pICSMessage)
    {
        if (IGInfo.pICSMessage->ICS)
        {
            if (IGInfo.pICSMessage->ICS->CompDesc.CompositionState == COMP_STATE_NORMAL)
            {
                /* only update the palette */
                fClearPalette = 0;
            }
            else
            {
                /* wipe the palette and update with the new colors */
                fClearPalette = 1;
            }
        }
    }

    /* set this palettes colors */
    if (IGGraphicsSetPaletteColors(PaletteNumber, PalPtr, NumEntries, fClearPalette, IGInfo.ColorSpace) != IG_STATUS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadPalette(): Failed to set palette colors\n"));
        return IG_STATUS_ERROR;
    }

    return IG_STATUS_SUCCESS;
}


/**
 * IGLoadObject - load a object into the IGObjList
 *
 * @param BYTE *DataStart - pointer to the start of the object
 * @param ULONG DataLength - size of DataStart in bytes
 *
 * @return IG_STATUS
 */
IG_STATUS IGLoadObject(BYTE *DataStart, ULONG DataLength)
{
    int ObjectID = MAKE_WORD(DataStart);
    int VersionNumber = *(DataStart + 2);
    int OutputSize;
    BYTE DoUpdate = 0;
    BYTE *ObjStart = DataStart;
    void *ImgData = NULL;
    DFBSurfaceDescription desc;
    OBJECT_DEFINITION_SEGMENT *CurObj;
#ifdef ALLOW_IG_PROFILING
    ULONG TickStart = 0;
#endif

    if (IGInfo.CurrentState != IG_STATE_RUNNING)
    {
        return IG_STATUS_SUCCESS;
    }

    /* the current object for easy access*/
    if (ObjectID >= IG_MAX_ODS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Invalid Object id %d\n", ObjectID));
        return IG_STATUS_ERROR;
    }

    CurObj = &IGObjList[ObjectID];

    /* if we get a higher version number then the one we have in this slot
       and it is marked as in use, we will do an update on it */
    if (CurObj->InUse)
    {
        if (CurObj->VersionNumber < VersionNumber)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadObject(): Do ODS update, %d > %d\n", VersionNumber, CurObj->VersionNumber));
            DoUpdate = 1;
        }
        else
        {
            //DBGPRINT(DBG_ON(DBG_TRACE), ("Don't do update, but object in use, skip it\n"));
            return IG_STATUS_SUCCESS;
        }
    }

    if (DoUpdate == 0)
    {
        /* make sure we will not overrun the size limit on the decoded object buffer */
        if (gIGDecodedObjectBuffUsed + (MAKE_WORD(ObjStart+7) * MAKE_WORD(ObjStart+9)) > MAX_SIZE_IG_DECODED_DATA)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("Discarding image %d, buffer used is %d\n", ObjectID, gIGDecodedObjectBuffUsed));
            return IG_STATUS_ERROR;
        }
    }

    /*

⌨️ 快捷键说明

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