summaryrefslogtreecommitdiff
path: root/dxr3osd_subpicture.c
diff options
context:
space:
mode:
authoraustriancoder <austriancoder>2004-08-05 23:05:21 +0000
committeraustriancoder <austriancoder>2004-08-05 23:05:21 +0000
commitc47666d42f7972e1b51f9de61ce0fa27c72f3127 (patch)
treee34a87e37901b7f892fb6f330ccb15bcba30039b /dxr3osd_subpicture.c
downloadvdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.gz
vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.bz2
initial import
Diffstat (limited to 'dxr3osd_subpicture.c')
-rw-r--r--dxr3osd_subpicture.c174
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*/
+