diff options
author | austriancoder <austriancoder> | 2004-08-05 23:05:21 +0000 |
---|---|---|
committer | austriancoder <austriancoder> | 2004-08-05 23:05:21 +0000 |
commit | c47666d42f7972e1b51f9de61ce0fa27c72f3127 (patch) | |
tree | e34a87e37901b7f892fb6f330ccb15bcba30039b /dxr3osd_subpicture.c | |
download | vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.gz vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.bz2 |
initial import
Diffstat (limited to 'dxr3osd_subpicture.c')
-rw-r--r-- | dxr3osd_subpicture.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/dxr3osd_subpicture.c b/dxr3osd_subpicture.c new file mode 100644 index 0000000..e6dc154 --- /dev/null +++ b/dxr3osd_subpicture.c @@ -0,0 +1,174 @@ +#include "dxr3osd_subpicture.h" + +#if VDRVERSNUM >= 10307 + +#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 + +// ================================== +cDxr3SubpictureOsd::cDxr3SubpictureOsd(int Left, int Top) : cOsd(Left, Top) +{ + shown = false; + Spu = &cSPUEncoder::Instance(); + + // must clear all windows here to avoid flashing effects - doesn't work if done + // in Flush() only for the windows that are actually used... + for (int i = 0; i < MAXNUMWINDOWS; i++) + { + Spu->Cmd(OSD_SetWindow, 0, i + 1); + Spu->Cmd(OSD_Clear); + } + +} + +// ================================== +cDxr3SubpictureOsd::~cDxr3SubpictureOsd() +{ + if (shown) + { + cBitmap *Bitmap; + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + { + Spu->Cmd(OSD_SetWindow, 0, i + 1); + Spu->Cmd(OSD_Close); + } + } +} + +// ================================== +eOsdError cDxr3SubpictureOsd::CanHandleAreas(const tArea *Areas, int NumAreas) +{ + + eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); + if (Result == oeOk) + { + if (NumAreas > MAXNUMWINDOWS) + { + return oeTooManyAreas; + } + + for (int i = 0; i < NumAreas; i++) + { + if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8) + { + return oeBppNotSupported; + } + + if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0) + { + return oeWrongAlignment; + } + } + } + return Result; +} + +// ================================== +void cDxr3SubpictureOsd::SaveRegion(int x1, int y1, int x2, int y2) +{ + // ToDo? +} + +// ================================== +void cDxr3SubpictureOsd::RestoreRegion() +{ + // ToDo? +} + +// ================================== +void cDxr3SubpictureOsd::Flush() +{ + cBitmap *Bitmap; + + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + { + Spu->Cmd(OSD_SetWindow, 0, i + 1); + + if (!shown) + { + Spu->Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden! + } + + int x1 = 0, y1 = 0, x2 = 0, y2 = 0; + if (Bitmap->Dirty(x1, y1, x2, y2)) + { + //TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple + //TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8. + //TODO Fix driver (should be able to handle any size bitmaps!) + + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) + { + if (x2 < Bitmap->Width() - 1) + { + x2++; + } + else if (x1 > 0) + { + x1--; + } + } + + //TODO "... / 2" <==> Bpp??? + while ((y1 > 0 || y2 < Bitmap->Height() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) + { + if (y2 < Bitmap->Height() - 1) + { + y2++; + } + else if (y1 > 0) + { + y1--; + } + } + + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) + { + if (x2 < Bitmap->Width() - 1) + { + x2++; + } + else if (x1 > 0) + { + x1--; + } + } + + // commit colors: + int NumColors; + const tColor *Colors = Bitmap->Colors(NumColors); + + if (Colors) + { + + // TODO this should be fixed in the driver! + tColor colors[NumColors]; + for (int i = 0; i < NumColors; i++) + { + // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): + colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); + } + + Colors = colors; + //TODO end of stuff that should be fixed in the driver + Spu->Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); + } + // commit modified data: + //Spu->Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1)); + Spu->Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1)); + } + Bitmap->Clean(); + } + + if (!shown) + { + // Showing the windows in a separate loop to avoid seeing them come up one after another + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + { + Spu->Cmd(OSD_SetWindow, 0, i + 1); + Spu->Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0()); + } + shown = true; + } +} + +#endif /*VDRVERSNUM*/ + |