📄 pg_parse.cpp
字号:
/* if this is an update then we already malloc'd the space */
if (1 == DoUpdate)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PG Doing object update\n"));
if (NULL == PGObjList[ObjectID].SurfaceLUT8)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ERROR: PGLoadObject, there is no surface to update\n"));
goto errout;
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
TickStart = OS_GetTicks();
}
#endif
/* lock the dfb surface buffer for the object and RLE decode into it */
if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to Lock LUT8 Surface\n"));
goto errout;
}
/* RLE decode into the surface */
status = RLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
CurObj->pitch, CurObj->ObjData.Width, PGInfo.CoordsHalfWidth);
if (status != PG_STATUS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to RLE decode the image\n"));
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalRLEFailures++;
}
#endif
goto errout;
}
/* unlock the surface */
if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed Unlock LUT8 surface\n"));
goto errout;
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalRLETicks += OS_GetTicks() - TickStart;
if (PGInfo.CoordsHalfWidth)
{
PGStats.PGPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
}
else
{
PGStats.PGPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
}
}
#endif
}
else
{
DFBSurfaceDescription desc;
desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_DFBPALETTEHANDLE);
desc.pixelformat = DSPF_LUT8;
if (PGInfo.CoordsHalfWidth == 0)
{
desc.width = CurObj->ObjData.Width;
}
else
{
desc.width = (CurObj->ObjData.Width+1)/2;
}
desc.height = CurObj->ObjData.Height;
desc.caps = (DFBSurfaceCapabilities)(DSCAPS_VIDEOONLY | DSCAPS_PREMULTIPLIED);
/* Any palette will do as it will not be used */
desc.dfbpalette = PGPalettes[0].DFBPal;
/* create palettized surface */
if (PG_STATUS_SUCCESS != PGGraphicsCreateLUT8Surface(&desc, CurObj))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject: Failed to create surface for PG image\n"));
goto errout;
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
TickStart = OS_GetTicks();
}
#endif
/* lock the dfb surface buffer for the object and RLE decode into it */
if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to Lock LUT8 Surface\n"));
goto errout;
}
/* RLE decode into the surface */
status = RLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
CurObj->pitch, CurObj->ObjData.Width, PGInfo.CoordsHalfWidth);
if (status != PG_STATUS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed to RLE decode the image\n"));
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalRLEFailures++;
}
#endif
goto errout;
}
/* unlock the surface */
if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PGLoadObject(): Failed Unlock LUT8 surface\n"));
goto errout;
}
#ifdef ALLOW_PG_PROFILING
if (1 == PGStats.Profiling)
{
PGStats.PGTotalRLETicks += OS_GetTicks() - TickStart;
if (PGInfo.CoordsHalfWidth)
{
PGStats.PGPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
}
else
{
PGStats.PGPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
}
}
#endif
}
/* we are using this slot */
CurObj->InUse = 1;
return PG_STATUS_SUCCESS;
errout:
if (CurObj->SurfaceLUT8)
{
CurObj->SurfaceLUT8->Release(CurObj->SurfaceLUT8);
CurObj->SurfaceLUT8 = NULL;
}
CurObj->InUse = 0;
return PG_STATUS_ERROR;
}
/**
* PGLoadWindows - Load a window defintion segment
*
* @return VOID
*/
PG_STATUS PGLoadWindows(BYTE *DataStart, ULONG DataLength)
{
BYTE WindowID;
BYTE NumWindows;
/* quit set? */
if (PGInfo.CurrentState != PG_STATE_RUNNING)
{
return PG_STATUS_SUCCESS;
}
NumWindows = *DataStart;
DataStart++;
if (NumWindows > MAX_WINDOWS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("Num Windows too high, %d\n", NumWindows));
return PG_STATUS_ERROR;
}
/* load the windows */
for (int i=0; i<NumWindows; i++)
{
WindowID = *DataStart;
if (WindowID != i)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("Window ID not in order, invalid window\n"));
return PG_STATUS_ERROR;
}
if (WindowID > MAX_WINDOWS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("Window ID value too large, ignoring window\n"));
return PG_STATUS_ERROR;
}
PGWindows[i].X = MAKE_WORD(DataStart+1);
PGWindows[i].Y = MAKE_WORD(DataStart+3);
PGWindows[i].Width = MAKE_WORD(DataStart+5);
PGWindows[i].Height = MAKE_WORD(DataStart+7);
DataStart+=SIZE_WINDOW;
}
return PG_STATUS_SUCCESS;
}
/**
* PGFreeObjects - free all the object in PGObjList (and the memory they hold)
*
* @return VOID
*/
void PGFreeObjects()
{
for (int i=0; i<PG_MAX_ODS; i++)
{
if (PGObjList[i].InUse)
{
/* also free the DirectFBSurface */
if (PGObjList[i].SurfaceLUT8)
{
PGObjList[i].SurfaceLUT8->Release(PGObjList[i].SurfaceLUT8);
PGObjList[i].SurfaceLUT8 = NULL;
}
memset(&PGObjList[i], 0, sizeof(OBJECT_DEFINITION_SEGMENT));
}
}
}
/**
* PGClearPalettes - clear all palettes
*
* @return VOID
*/
void PGClearPalettes()
{
for (int i = 0; i < PG_MAX_PALETTES; i++)
{
/* set all palette colors to transparent */
memset(PGPalettes[i].Colors, 0, PG_MAX_PALETTE_COLORS * sizeof(DFBColor));
PGPalettes[i].PaletteVersion = 0;
}
}
/**
* PGFlushParseQ - clear all messages from the parse Queue
*
* @return VOID
*/
PG_STATUS PGFlushParseQ()
{
PG_PARSE_MSG *pMessage = NULL;
while (1)
{
/* Get a stream message */
pMessage = (PG_PARSE_MSG *)PGInfo.PGParseQ->Read(OS_NO_WAIT);
if (pMessage)
{
PGInfo.PGParseQ->ReleaseMsg(pMessage);
}
else
{
break;
}
}
return PG_STATUS_SUCCESS;
}
/**
* PGFlush - called during a PGStop(), clears all object lists and resets the parser
*
* @return VOID
*/
PG_STATUS PGFlush()
{
BYTE fClearBuffer = 0;
/* flush the parser Q */
PGFlushParseQ();
/* wait for DecodeData to finish and go back to blocking */
while (gPGParserWaiting == 0)
{
OS_SemGive(PGInfo.ParseWait.WaitSem);
OS_SemGive(PGInfo.RenderWait.WaitSem);
OS_TaskYield();
}
/* clear screen */
PGGraphicsClearBuffer(&fClearBuffer, 0);
if (0 != fClearBuffer)
{
OS_TimerSet(PGInfo.PGFlipTimer, 1);
OS_TaskYield();
}
/* delete objects and palettes */
PGFreeObjects();
PGClearPalettes();
/* we are reset, make sure any PCS's are cleared,
note the parser is already reset here so these won't be in use */
if (NULL != PGInfo.RenderPCS)
{
ReleasePCS(PGInfo.RenderPCS);
PGInfo.RenderPCS = NULL;
}
if (NULL != PGInfo.ParserPCS)
{
ReleasePCS(PGInfo.ParserPCS);
PGInfo.ParserPCS = NULL;
}
return PG_STATUS_SUCCESS;
}
/**
* PGWaitForDTS - wait for a PTS to show up
*
* @return VOID
*/
PG_STATUS PGWaitForDTS(ULONG DTS)
{
/* first check if the time has already passed that we want, if so just return */
if (PGInfo.CurPTS < DTS)
{
/* setup the ParseWait PG_WAIT_TIME_SEM to block and wait for the PTS we want */
PGInfo.ParseWait.WaitTime.WaitPTS = DTS;
PGInfo.ParseWait.WaitTime.Enabled = 1;
/* now block wait for the time to show, we awake via UpdateTimeStamp() semgive */
OS_SemTake(PGInfo.ParseWait.WaitSem, OS_WAIT_FOREVER);
/* clear flags */
PGInfo.ParseWait.WaitTime.WaitPTS = 0;
PGInfo.ParseWait.WaitTime.Enabled = 0;
}
return PG_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -