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

📄 pg_graphics.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            return PG_STATUS_ERROR;
        }
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGGraphicsDeleteAllPalettes - release the surface memory
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsDeleteAllPalettes()
{
    PALETTE *CurPal;

    /* loop and create all the dfb palettes but with clear as their colors */
    for (int i=0; i<PG_MAX_PALETTES; i++)
    {
        CurPal = &PGPalettes[i];

        /* call create palette with the entries we give here */
        if (CurPal->DFBPal->Release(CurPal->DFBPal) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsDeleteAllPalettes(): Failed to release DFB Palette\n"));
            return PG_STATUS_ERROR;
        }
        CurPal->DFBPal = NULL;
    }

    return (PG_STATUS_SUCCESS);
}

/**
 * PGGraphicsFreeSurface - release the surface memory
 *
 * @param IDirectFBSurface *Surface - The DFB Surface to release
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsFreeSurface(IDirectFBSurface *Surface)
{
    if (Surface != NULL)
    {
    Surface->Release(Surface);
    }
    return (PG_STATUS_SUCCESS);
}

/**
 * PGGraphicsCreateLUT8Surface - create a directfb surface for the LUT8 member of an ODS
 *
 * @param DFBSurfaceDescription *desc = Description pointer describing the new surface
 * @param OBJECT_DEFINITION_SEGMENT *Obj = The object that contains the LUT8 DFB Surface to create
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsCreateLUT8Surface(DFBSurfaceDescription *desc, OBJECT_DEFINITION_SEGMENT *Obj)
{
#ifdef ALLOW_PG_PROFILING
    ULONG TickStart = 0;
#endif

    /* create the palettized surface of the object passed in */
#ifdef ALLOW_PG_PROFILING
    if (1 == PGStats.Profiling)
    {
        TickStart = OS_GetTicks();
    }
#endif

    if (DFB_OK != PGInfo.DFBInfo.SurfaceManager->CreateSurface(PGInfo.DFBInfo.SurfaceManager, desc, &Obj->SurfaceLUT8))
    {
        return PG_STATUS_ERROR;
    }

#ifdef ALLOW_PG_PROFILING
    if (1 == PGStats.Profiling)
    {
        PGStats.PGTotalCreateSurfaceTicks += OS_GetTicks() - TickStart;
    }
#endif

    return PG_STATUS_SUCCESS;
}


/**
 * PGGraphicsFlip - present the backbuffer on screen
 *
 * @param void
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsFlip()
{
    OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);
#ifdef ALLOW_PG_PROFILING
    ULONG TickStart = 0;
#endif

    if ((gPGFlipRegion.x2 > gPGFlipRegion.x1) && (gPGFlipRegion.y2 > gPGFlipRegion.y1))
    {
#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            TickStart = OS_GetTicks();
        }
#endif

        /* adjust flipping region to account for rectangle vs region size, one pixel in all directions */
        gPGFlipRegion.x1 = ((gPGFlipRegion.x1-1) < 0) ? 0 : gPGFlipRegion.x1-1;
        gPGFlipRegion.y1 = ((gPGFlipRegion.y1-1) < 0) ? 0 : gPGFlipRegion.y1-1;

        if (PGInfo.CoordsHalfWidth == 1)
        {
            gPGFlipRegion.x2 = ((gPGFlipRegion.x2+1) > (PGInfo.DFBInfo.ScreenWidth/2)) ? gPGFlipRegion.x2+1 : (PGInfo.DFBInfo.ScreenWidth/2);
            gPGFlipRegion.y2 = ((gPGFlipRegion.y2+1) > PGInfo.DFBInfo.ScreenHeight) ? gPGFlipRegion.y2+1 : PGInfo.DFBInfo.ScreenHeight;
        }
        else
        {
            gPGFlipRegion.x2 = ((gPGFlipRegion.x2+1) > PGInfo.DFBInfo.ScreenWidth) ? gPGFlipRegion.x2+1 : PGInfo.DFBInfo.ScreenWidth;
            gPGFlipRegion.y2 = ((gPGFlipRegion.y2+1) > PGInfo.DFBInfo.ScreenHeight) ? gPGFlipRegion.y2+1 : PGInfo.DFBInfo.ScreenHeight;
        }

        if (PGInfo.DFBInfo.PrimarySurface->Flip(PGInfo.DFBInfo.PrimarySurface, &gPGFlipRegion, DSFLIP_NONE) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("Failed to flip surface\n"));
        }

#ifdef ALLOW_PG_PROFILING
        if (1 == PGStats.Profiling)
        {
            PGStats.PGTotalFlipTicks += OS_GetTicks() - TickStart;
        }
#endif
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("PG Not Flipping (%d %d) w=%d h=%d\n", gPGFlipRegion.x1, gPGFlipRegion.y1,
            gPGFlipRegion.x2-gPGFlipRegion.x1, gPGFlipRegion.y2-gPGFlipRegion.y1));
    }

    /* after a flip clear the region */
    if (PGInfo.CoordsHalfWidth == 0)
    {
        gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth;
        gPGFlipRegion.x2 = 0;
        gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
        gPGFlipRegion.y2 = 0;
    }
    else
    {
        gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth/2;
        gPGFlipRegion.x2 = 0;
        gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
        gPGFlipRegion.y2 = 0;
    }

    OS_SemGive(PGInfo.BlitLock);
    return PG_STATUS_SUCCESS;
}

/**
 * PGGraphicsClearBuffer - present the backbuffer on screen
 *
 * @param void
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsClearBuffer(BYTE *fUpdateScreen, OS_SEM_ID Sem)
{
    if (Sem == 0)
    {
        OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);
    }

    if (0 == gPGImageIndex)
    {
        if (fUpdateScreen)
        {
            *fUpdateScreen = 0;
        }

        if (Sem == 0)
        {
            OS_SemGive(PGInfo.BlitLock);
        }

        return PG_STATUS_SUCCESS;
    }

    /* use color 255 to clear the screen, this is the clear color */
    PGInfo.DFBInfo.PrimarySurface->SetColorIndex(PGInfo.DFBInfo.PrimarySurface, 0xFF);

    /* clean up all rectangles in the list with one call */
    PGInfo.DFBInfo.PrimarySurface->FillRectangles(PGInfo.DFBInfo.PrimarySurface, PGCleanupList, gPGImageIndex);

    if (PGInfo.CoordsHalfWidth == 0)
    {
        gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth;
        gPGFlipRegion.x2 = 0;
        gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
        gPGFlipRegion.y2 = 0;
    }
    else
    {
        gPGFlipRegion.x1 = PGInfo.DFBInfo.ScreenWidth/2;
        gPGFlipRegion.x2 = 0;
        gPGFlipRegion.y1 = PGInfo.DFBInfo.ScreenHeight;
        gPGFlipRegion.y2 = 0;
    }

    for (ULONG i=0; i<gPGImageIndex; i++)
    {
        if (PGCleanupList[i].x < gPGFlipRegion.x1)
        {
            gPGFlipRegion.x1 = PGCleanupList[i].x;
        }

        if (PGCleanupList[i].x + PGCleanupList[i].w > gPGFlipRegion.x2)
        {
            gPGFlipRegion.x2 = PGCleanupList[i].x + PGCleanupList[i].w;
        }

        if (PGCleanupList[i].y < gPGFlipRegion.y1)
        {
            gPGFlipRegion.y1 = PGCleanupList[i].y;
        }

        if (PGCleanupList[i].y + PGCleanupList[i].h > gPGFlipRegion.y2)
        {
            gPGFlipRegion.y2 = PGCleanupList[i].y + PGCleanupList[i].h;
        }

        memset(&PGCleanupList[i], 0, sizeof(DFBRectangle));
    }

    gPGImageIndex = 0;

    if (fUpdateScreen)
    {
        *fUpdateScreen = 1;
    }

    if (Sem == 0)
    {
        OS_SemGive(PGInfo.BlitLock);
    }

    return PG_STATUS_SUCCESS;
}

/**
 * PGGraphicsClearScreen - clear the buffer offscreen
 *
 * @param void
 *
 * @return PG_STATUS
 */
PG_STATUS PGGraphicsClearScreen()
{
    IDirectFBSurface *ClearSurf = NULL;
    IDirectFBPalette *ClearPal = NULL;
    DFBColor ClearColor = {0,0,0,0};

    OS_SemTake(PGInfo.BlitLock, OS_WAIT_FOREVER);

    /* get the primary surface for this diplay layer */
    if (PGInfo.DFBInfo.DispLayer->GetSurface(PGInfo.DFBInfo.DispLayer, &ClearSurf) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to get surface\n"));
        goto errout;
    }

    /* get the surfaces palette */
    if (ClearSurf->GetPalette(ClearSurf, &ClearPal) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to get palette!\n"));
        goto errout;
    }

    /* set default transparent palette entry */
    if (ClearPal->SetEntries(ClearPal, &ClearColor, 1, 0xff) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to set transparent palette entry!\n"));
        goto errout;
    }

    /* set surface color index to transparent */
    if (ClearSurf->SetColorIndex(ClearSurf, 0xff) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to set color index!\n"));
        goto errout;
    }

    /* clear the surface */
    if (PGInfo.CoordsHalfWidth == 1)
    {
        if (ClearSurf->FillRectangle(ClearSurf, 0, 0, PGInfo.DFBInfo.ScreenWidth/2, PGInfo.DFBInfo.ScreenHeight) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to clear surface!\n"));
            goto errout;
        }

        /* set to invalid region */
        gPGFlipRegion.x1 = 0;
        gPGFlipRegion.x2 = PGInfo.DFBInfo.ScreenWidth/2;
        gPGFlipRegion.y1 = 0;
        gPGFlipRegion.y2 = PGInfo.DFBInfo.ScreenHeight;
    }
    else
    {
        if (ClearSurf->FillRectangle(ClearSurf, 0, 0, PGInfo.DFBInfo.ScreenWidth, PGInfo.DFBInfo.ScreenHeight) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PGGraphicsClearScreen: Failed to clear surface!\n"));
            goto errout;
        }

        /* set to invalid region */
        gPGFlipRegion.x1 = 0;
        gPGFlipRegion.x2 = PGInfo.DFBInfo.ScreenWidth;
        gPGFlipRegion.y1 = 0;
        gPGFlipRegion.y2 = PGInfo.DFBInfo.ScreenHeight;
    }

    if (ClearPal)
    {
        ClearPal->Release(ClearPal);
    }

    if (ClearSurf)
    {
        ClearSurf->Release(ClearSurf);
    }

    OS_SemGive(PGInfo.BlitLock);

    return PG_STATUS_SUCCESS;

errout:

    if (ClearPal)
    {
        ClearPal->Release(ClearPal);
    }

    if (ClearSurf)
    {
        ClearSurf->Release(ClearSurf);
    }

    OS_SemGive(PGInfo.BlitLock);

    return PG_STATUS_ERROR;
}


/**
 * PGGraphicsBuildFlipRegion - build a flip region based on what images we have drawn
 *
 * @param void
 *
 * @return PG_STATUS
 */
void PGGraphicsBuildFlipRegion()
{
    for (ULONG i=0; i<gPGImageIndex; i++)
    {
        if (PGCleanupList[i].x < gPGFlipRegion.x1)
        {
            gPGFlipRegion.x1 = PGCleanupList[i].x;
        }

        if (PGCleanupList[i].x + PGCleanupList[i].w > gPGFlipRegion.x2)
        {
            gPGFlipRegion.x2 = PGCleanupList[i].x + PGCleanupList[i].w;
        }

        if (PGCleanupList[i].y < gPGFlipRegion.y1)
        {
            gPGFlipRegion.y1 = PGCleanupList[i].y;
        }

        if (PGCleanupList[i].y + PGCleanupList[i].h > gPGFlipRegion.y2)
        {
            gPGFlipRegion.y2 = PGCleanupList[i].y + PGCleanupList[i].h;
        }
    }
}


⌨️ 快捷键说明

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