43 #error "Should define at least one of OSD_8_BIT, OSD_16_BIT, OSD_31_BIT or OSD_32_BIT!" 50 #define MAGIC_SURF 0x5e4f 52 #define DESKTOP_COLOUR 0xff000000 53 #define TOTAL_TRANSPARENCY 0x00000000 58 #define SD_BlendColour( pxl, clr, prv, swtch ) 60 #define C2L_ALPHA_CHNNL 0xf000 62 #define C4L_ALPHA_CHNNL 0xff000000 66 #define OFFSET_SEMI (PALETTE_OFFSET + 1) 67 #define OFFSET_GREY (PALETTE_OFFSET + 49) 68 #define OFFSET_BLACK (PALETTE_OFFSET + 53) 69 #define OFFSET_WHITE (PALETTE_OFFSET + 187) 70 #define DESKTOP_COLOUR_INDEX OFFSET_BLACK 72 #define NUM_SUBT_COLOURS 64 73 #define NUM_MHEG_COLOURS 188 74 #define NUM_MANU_COLOURS 4 78 typedef struct _NearCol
81 const U8BIT green[16];
90 OSDColor dbook_colour_palette[NUM_SUBT_COLOURS + NUM_MHEG_COLOURS + NUM_MANU_COLOURS] =
93 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
94 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
95 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
96 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
97 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
98 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
99 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
100 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
106 0xb3000000, 0xb30000ff, 0xb3550000, 0xb35500ff, 0xb3aa0000, 0xb3aa00ff, 0xb3ff0000, 0xb3ff00ff,
107 0xb3003300, 0xb30033ff, 0xb3553300, 0xb35533ff, 0xb3aa3300, 0xb3aa33ff, 0xb3ff3300, 0xb3ff33ff,
108 0xb3006600, 0xb30066ff, 0xb3556600, 0xb35566ff, 0xb3aa6600, 0xb3aa66ff, 0xb3ff6600, 0xb3ff66ff,
109 0xb3009900, 0xb30099ff, 0xb3559900, 0xb35599ff, 0xb3aa9900, 0xb3aa99ff, 0xb3ff9900, 0xb3ff99ff,
110 0xb300cc00, 0xb300ccff, 0xb355cc00, 0xb355ccff, 0xb3aacc00, 0xb3aaccff, 0xb3ffcc00, 0xb3ffccff,
111 0xb300ff00, 0xb300ffff, 0xb355ff00, 0xb355ffff, 0xb3aaff00, 0xb3aaffff, 0xb3ffff00, 0xb3ffffff,
114 0xff2a2a2a, 0xff555555, 0xffaaaaaa, 0xffd4d4d4,
117 0xff000000, 0xff00007f, 0xff0000ff, 0xff001f00, 0xff001f7f, 0xff001fff, 0xff003f00, 0xff003f7f,
118 0xff003fff, 0xff005f00, 0xff005f7f, 0xff005fff, 0xff007f00, 0xff007f7f, 0xff007fff, 0xff009f00,
119 0xff009f7f, 0xff009fff, 0xff00bf00, 0xff00bf7f, 0xff00bfff, 0xff00df00, 0xff00df7f, 0xff00dfff,
120 0xff00ff00, 0xff00ff7f, 0xff00ffff, 0xff3f0000, 0xff3f007f, 0xff3f00ff, 0xff3f1f00, 0xff3f1f7f,
121 0xff3f1fff, 0xff3f3f00, 0xff3f3f7f, 0xff3f3fff, 0xff3f5f00, 0xff3f5f7f, 0xff3f5fff, 0xff3f7f00,
122 0xff3f7f7f, 0xff3f7fff, 0xff3f9f00, 0xff3f9f7f, 0xff3f9fff, 0xff3fbf00, 0xff3fbf7f, 0xff3fbfff,
123 0xff3fdf00, 0xff3fdf7f, 0xff3fdfff, 0xff3fff00, 0xff3fff7f, 0xff3fffff, 0xff7f0000, 0xff7f007f,
124 0xff7f00ff, 0xff7f1f00, 0xff7f1f7f, 0xff7f1fff, 0xff7f3f00, 0xff7f3f7f, 0xff7f3fff, 0xff7f5f00,
125 0xff7f5f7f, 0xff7f5fff, 0xff7f7f00, 0xff7f7f7f, 0xff7f7fff, 0xff7f9f00, 0xff7f9f7f, 0xff7f9fff,
126 0xff7fbf00, 0xff7fbf7f, 0xff7fbfff, 0xff7fdf00, 0xff7fdf7f, 0xff7fdfff, 0xff7fff00, 0xff7fff7f,
127 0xff7fffff, 0xffbf0000, 0xffbf007f, 0xffbf00ff, 0xffbf1f00, 0xffbf1f7f, 0xffbf1fff, 0xffbf3f00,
128 0xffbf3f7f, 0xffbf3fff, 0xffbf5f00, 0xffbf5f7f, 0xffbf5fff, 0xffbf7f00, 0xffbf7f7f, 0xffbf7fff,
129 0xffbf9f00, 0xffbf9f7f, 0xffbf9fff, 0xffbfbf00, 0xffbfbf7f, 0xffbfbfff, 0xffbfdf00, 0xffbfdf7f,
130 0xffbfdfff, 0xffbfff00, 0xffbfff7f, 0xffbfffff, 0xffff0000, 0xffff007f, 0xffff00ff, 0xffff1f00,
131 0xffff1f7f, 0xffff1fff, 0xffff3f00, 0xffff3f7f, 0xffff3fff, 0xffff5f00, 0xffff5f7f, 0xffff5fff,
132 0xffff7f00, 0xffff7f7f, 0xffff7fff, 0xffff9f00, 0xffff9f7f, 0xffff9fff, 0xffffbf00, 0xffffbf7f,
133 0xffffbfff, 0xffffdf00, 0xffffdf7f, 0xffffdfff, 0xffffff00, 0xffffff7f, 0xffffffff,
136 0x00000000, 0x00000000, 0x00000000, 0x00000000
139 OSDColor *mg_palette = NULL;
157 COLOUR_FORMAT_PALETTE,
158 #if defined(OSD_31_BIT) && defined(OSD_32_BIT) 167 static U16BIT OSD_GCD( U16BIT a, U16BIT b );
171 BOOLEAN MG_IsHdSupported(
void)
173 if (mg_ctxt.colour_format >= 16 &&
174 mg_ctxt.out_osd_width >= 1280 &&
175 mg_ctxt.out_osd_height >= 720)
182 void MG_OSDInit( U16BIT inWidth, U16BIT inHeight,
183 U16BIT outWidth, U16BIT outHeight )
185 BOOLEAN out_changed, inp_changed;
189 inp_changed = (mg_ctxt.input_width != inWidth ||
190 mg_ctxt.input_height != inHeight) ? TRUE : FALSE;
191 out_changed = (mg_ctxt.out_osd_width != outWidth ||
192 mg_ctxt.out_osd_height != outHeight) ? TRUE : FALSE;
194 if (out_changed || inp_changed)
196 TRACE(TSTATE, (
"in=(%d,%d) out=(%d,%d)", inWidth, inHeight, outWidth, outHeight))
198 mg_ctxt.input_width = inWidth;
199 mg_ctxt.input_height = inHeight;
200 mg_ctxt.out_osd_width = outWidth;
201 mg_ctxt.out_osd_height = outHeight;
204 gcd = OSD_GCD( OSD_GCD(inWidth, outWidth), OSD_GCD(inHeight, outHeight));
205 mg_ctxt.osd_x.mlt = outWidth / gcd;
206 mg_ctxt.osd_x.div = inWidth / gcd;
208 mg_ctxt.osd_y.mlt = outHeight / gcd;
209 mg_ctxt.osd_y.div = inHeight / gcd;
211 gcd = OSD_GCD(inWidth, mg_ctxt.out_video_width);
212 mg_ctxt.vid_x.mlt = mg_ctxt.out_video_width / gcd;
213 mg_ctxt.vid_x.div = inWidth / gcd;
215 gcd = OSD_GCD(inHeight, mg_ctxt.out_video_height);
216 mg_ctxt.vid_y.mlt = mg_ctxt.out_video_height / gcd;
217 mg_ctxt.vid_y.div = inHeight / gcd;
222 mg_ctxt.line_w.mlt = ((mg_ctxt.osd_x.mlt * mg_ctxt.osd_y.div +
223 mg_ctxt.osd_y.mlt * mg_ctxt.osd_x.div));
224 mg_ctxt.line_w.div = (2 * mg_ctxt.osd_x.div * mg_ctxt.osd_y.div);
226 gcd = OSD_GCD(mg_ctxt.line_w.mlt, mg_ctxt.line_w.div);
227 mg_ctxt.line_w.mlt /= gcd;
228 mg_ctxt.line_w.div /= gcd;
232 TRACE(TERROR, (
"MG_FontInit Failed!\n"))
237 TRACE(TGRAPHICS, (
"About to Initialise OSD"))
238 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
241 STB_OSDSetMhegPalette( 0, NUM_MHEG_COLOURS + PALETTE_OFFSET, (U32BIT *)mg_palette );
253 #ifdef NO_SCALE_ASPECT 254 USE_UNWANTED_PARAM(sar);
258 if (!mg_ctxt.offset_left)
262 mg_ctxt.offset_left = mg_ctxt.out_osd_width >> 3;
266 if (mg_ctxt.offset_left)
270 mg_ctxt.offset_left = 0;
273 MG_OSDInit( inWidth, inHeight, mg_ctxt.out_osd_width, mg_ctxt.out_osd_height );
281 E_MhegErr
MG_Initialise( U16BIT screenWidth, U16BIT screenHeight, U8BIT colourDepth )
285 TRACE(TSTATE, (
"(screen= %d x %d, %d bit)", screenWidth, screenHeight, colourDepth))
286 if (colourDepth == 0)
289 colourDepth = mg_ctxt.colour_format;
293 mg_ctxt.colour_format = colourDepth;
295 if (screenWidth < 720 || screenHeight < 576
297 || (colourDepth == COLOUR_FORMAT_PALETTE)
300 || (colourDepth == COLOUR_FORMAT_ARGB4444)
303 || (colourDepth == COLOUR_FORMAT_ARGB7888)
306 || (colourDepth == COLOUR_FORMAT_ARGB8888)
310 DPL1((
"- Invalid Graphic Capabilities\n"));
311 result = MHERR_BAD_PARAMETER;
312 TRACE(TSTATE,(
"result=%d",result))
318 #if defined(OSD_31_BIT) && defined(OSD_32_BIT) 320 mg_ctxt.max_alpha = (mg_ctxt.colour_format == COLOUR_FORMAT_ARGB7888) ? 128 : 255;
323 mg_ctxt.out_video_width = screenWidth;
324 mg_ctxt.out_video_height = screenHeight;
326 TRACE(TSTATE,(
"result=%d",result))
329 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
331 TRACE(TSTATE,(
"result=%d",result))
332 mg_palette = &dbook_colour_palette[NUM_SUBT_COLOURS - PALETTE_OFFSET];
333 if (mg_ctxt.hw_handle == NULL)
336 if (mg_ctxt.hw_handle == NULL)
338 result = MHERR_OTHER;
341 mg_ctxt.screen_stride = screenWidth;
342 if (mg_ctxt.screen_buff == NULL)
346 TRACE(TGRAPHICS, (
"hdl=0x%x, buff=0x%x, stride=%d cft=%d", mg_ctxt.hw_handle,
347 mg_ctxt.screen_buff, mg_ctxt.screen_stride, mg_ctxt.colour_format))
351 MG_OSDInit( SD_WIDTH, SD_HEIGHT, screenWidth, screenHeight );
353 TRACE(TSTATE,(
"result=%d",result))
369 FUNCTION_START(OSDExit)
372 if (mg_ctxt.screen_buff != NULL)
376 mg_ctxt.screen_buff = NULL;
382 mg_ctxt.out_osd_width = 0;
384 FUNCTION_FINISH(OSDExit)
397 static void DrawRectangle8Bit(
S_REGION rgn, U8BIT colour_index, BOOLEAN overwrite )
402 assert( colour_index < NUM_MHEG_COLOURS );
404 w = rgn.right - rgn.left;
405 buffer = mg_ctxt.screen_buff;
406 buffer += (rgn.top * mg_ctxt.screen_stride) + rgn.left;
408 TRACE(TGRAPHICS, (
"rgn=%d,%d,%d,%d col=0x%x ow=%d", rgn.left, rgn.top, rgn.right, rgn.bottom, colour_index, overwrite))
412 for (y = rgn.top; y != rgn.bottom; y++)
414 memset(buffer, colour_index, w );
415 buffer += mg_ctxt.screen_stride;
420 w = mg_ctxt.screen_stride - w;
421 for (y = rgn.top; y != rgn.bottom; y++)
423 for (x = rgn.left; x != rgn.right; x++)
425 OSD_BlendPixels(buffer, colour_index);
432 if (rgn.left < osd_update_rgn.left)
434 osd_update_rgn.left = rgn.left;
436 if (rgn.top < osd_update_rgn.top)
438 osd_update_rgn.top = rgn.top;
440 if (rgn.right > osd_update_rgn.right)
442 osd_update_rgn.right = rgn.right;
444 if (rgn.bottom > osd_update_rgn.bottom)
446 osd_update_rgn.bottom = rgn.bottom;
459 static void DrawClippedRectangle(
S_REGION *overlap,
S_REGION rgn, OSDColor fore_col )
461 if (rgn.left < overlap->left)
463 rgn.left = overlap->left;
465 if (rgn.right > overlap->right)
467 rgn.right = overlap->right;
469 if (rgn.top < overlap->top)
471 rgn.top = overlap->top;
473 if (rgn.bottom > overlap->bottom)
475 rgn.bottom = overlap->bottom;
477 if ((rgn.bottom > rgn.top) && (rgn.right > rgn.left))
479 TRACE(TGRAPHICS, (
"region (%d,%d,%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom))
480 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
483 if (fore_col != OFFSET_TRANS)
486 DrawRectangle8Bit( rgn, (U8BIT)fore_col, (fore_col >= OFFSET_OPAQUE));
490 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
493 if ((fore_col & C2L_ALPHA_CHNNL) != 0)
496 rect.left = rgn.left;
497 rect.width = rgn.right - rgn.left;
499 rect.height = rgn.bottom - rgn.top;
500 #ifndef NO_SCALE_ASPECT 501 if (mg_ctxt.offset_left)
505 rect.left += mg_ctxt.offset_left;
512 STB_BLIT_COPY : STB_BLIT_A_BLEND );
519 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 520 if ((fore_col & C4L_ALPHA_CHNNL) != 0)
524 ConvertAlpha(fore_col, col);
525 rect.left = rgn.left;
526 rect.width = rgn.right - rgn.left;
528 rect.height = rgn.bottom - rgn.top;
529 #ifndef NO_SCALE_ASPECT 530 if (mg_ctxt.offset_left)
534 rect.left += mg_ctxt.offset_left;
541 STB_BLIT_COPY : STB_BLIT_A_BLEND );
567 int line_width, OSDColor lineColour, OSDColor fillColour )
571 TRACE(TGRAPHICS, (
"x=%d,y=%d,w=%d,h=%d", x, y, width, height));
572 if (width > 0 && height > 0)
574 S_REGION rgn, outline_region, inner_region;
577 rgn.right = x + width;
578 rgn.bottom = y + height;
579 scaled_overlap = *overlap;
580 TRACE(TGRAPHICS, (
"line_width=%d line_col=%x fill_col=%x", line_width, lineColour, fillColour));
582 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
585 tmp_col = (OSDColor)OSD_FindNearestColourIndex(lineColour);
588 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
591 tmp_col = MakeHD2Color( lineColour );
592 rgn.left = HD_X_SCALEUP(rgn.left);
593 rgn.top = HD_Y_SCALEUP(rgn.top);
594 rgn.right = HD_X_SCALEUP(rgn.right);
595 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
596 scaled_overlap.left = HD_X_SCALEUP(overlap->left);
597 scaled_overlap.top = HD_Y_SCALEUP(overlap->top);
598 scaled_overlap.right = HD_X_SCALEUP(overlap->right);
599 scaled_overlap.bottom = HD_Y_SCALEUP(overlap->bottom);
600 line_width = HD_W_SCALEUP(line_width);
606 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 607 tmp_col = lineColour;
608 rgn.left = HD_X_SCALEUP(rgn.left);
609 rgn.top = HD_Y_SCALEUP(rgn.top);
610 rgn.right = HD_X_SCALEUP(rgn.right);
611 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
612 scaled_overlap.left = HD_X_SCALEUP(overlap->left);
613 scaled_overlap.top = HD_Y_SCALEUP(overlap->top);
614 scaled_overlap.right = HD_X_SCALEUP(overlap->right);
615 scaled_overlap.bottom = HD_Y_SCALEUP(overlap->bottom);
616 line_width = HD_W_SCALEUP(line_width);
620 assert( rgn.right >= rgn.left );
621 assert( rgn.bottom >= rgn.top );
623 if (line_width > (rgn.right - rgn.left))
625 line_width = rgn.right - rgn.left;
627 if (line_width > (rgn.bottom - rgn.top))
629 line_width = rgn.bottom - rgn.top;
634 TRACE(TGRAPHICS, (
"l_col=%x", tmp_col));
637 if ((rgn.top + line_width >= rgn.bottom - line_width) ||
638 (rgn.left + line_width >= rgn.right - line_width))
641 outline_region.left = rgn.left;
642 outline_region.top = rgn.top;
643 outline_region.right = rgn.right;
644 outline_region.bottom = rgn.bottom;
646 DrawClippedRectangle( &scaled_overlap, outline_region, tmp_col );
651 outline_region.left = rgn.left;
652 outline_region.top = rgn.top;
653 outline_region.bottom = rgn.top + line_width;
654 outline_region.right = rgn.right;
656 DrawClippedRectangle( &scaled_overlap, outline_region, tmp_col );
659 outline_region.left = rgn.left;
660 outline_region.top = rgn.bottom - line_width;
661 outline_region.bottom = rgn.bottom;
662 outline_region.right = rgn.right;
664 DrawClippedRectangle( &scaled_overlap, outline_region, tmp_col );
667 outline_region.left = rgn.left;
668 outline_region.top = rgn.top + line_width;
669 outline_region.bottom = rgn.bottom - line_width;
670 outline_region.right = rgn.left + line_width;
672 DrawClippedRectangle( &scaled_overlap, outline_region, tmp_col );
675 outline_region.left = rgn.right - line_width;
676 outline_region.top = rgn.top + line_width;
677 outline_region.bottom = rgn.bottom - line_width;
678 outline_region.right = rgn.right;
680 DrawClippedRectangle( &scaled_overlap, outline_region, tmp_col );
683 if (width > line_width && height > line_width)
685 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
688 tmp_col = (OSDColor)OSD_FindNearestColourIndex(fillColour);
691 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
694 tmp_col = MakeHD2Color( fillColour );
700 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 701 tmp_col = fillColour;
704 TRACE(TGRAPHICS, (
"f_col=%x", tmp_col))
706 inner_region.left = rgn.left + line_width;
707 inner_region.top = rgn.top + line_width;
708 inner_region.right = rgn.right - line_width;
709 inner_region.bottom = rgn.bottom - line_width;
711 DrawClippedRectangle( &scaled_overlap, inner_region, tmp_col );
731 FUNCTION_START(OSDDisplayVideo)
733 TRACE(TGRAPHICS, (
"OSDdisplayVideo( %d,%d,%d,%d )\n", rgn.top, rgn.left, rgn.right, rgn.bottom))
736 if ((rgn.bottom > rgn.top) && (rgn.right > rgn.left))
738 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
741 DrawRectangle8Bit( rgn, 0, TRUE );
744 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
748 rgn.top = HD_Y_SCALEUP(rgn.top);
749 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
750 rgn.left = HD_X_SCALEUP(rgn.left);
751 rgn.right = HD_X_SCALEUP(rgn.right);
752 rect.left = rgn.left;
754 rect.width = rgn.right - rgn.left;
755 rect.height = rgn.bottom - rgn.top;
756 #ifndef NO_SCALE_ASPECT 757 if (mg_ctxt.offset_left)
761 rect.left += mg_ctxt.offset_left;
772 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 774 rgn.top = HD_Y_SCALEUP(rgn.top);
775 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
776 rgn.left = HD_X_SCALEUP(rgn.left);
777 rgn.right = HD_X_SCALEUP(rgn.right);
778 rect.left = rgn.left;
780 rect.width = rgn.right - rgn.left;
781 rect.height = rgn.bottom - rgn.top;
782 #ifndef NO_SCALE_ASPECT 783 if (mg_ctxt.offset_left)
787 rect.left += mg_ctxt.offset_left;
797 TRACE(TGRAPHICS, (
""))
798 FUNCTION_FINISH(OSDDisplayVideo)
810 FUNCTION_START(OSDerase);
812 TRACE(TGRAPHICS, (
"region (%d,%d,%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom))
814 if ((rgn.bottom > rgn.top) && (rgn.right > rgn.left))
816 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
819 DrawRectangle8Bit( rgn, OSD_FindNearestColourIndex(colour), TRUE );
822 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
826 rgn.top = HD_Y_SCALEUP(rgn.top);
827 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
828 rgn.left = HD_X_SCALEUP(rgn.left);
829 rgn.right = HD_X_SCALEUP(rgn.right);
831 rect.left = rgn.left;
833 rect.width = rgn.right - rgn.left;
834 rect.height = rgn.bottom - rgn.top;
835 #ifndef NO_SCALE_ASPECT 836 if (mg_ctxt.offset_left)
840 rect.left += mg_ctxt.offset_left;
851 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 854 ConvertAlpha(colour, col);
855 rgn.top = HD_Y_SCALEUP(rgn.top);
856 rgn.bottom = HD_Y_SCALEUP(rgn.bottom);
857 rgn.left = HD_X_SCALEUP(rgn.left);
858 rgn.right = HD_X_SCALEUP(rgn.right);
860 rect.left = rgn.left;
862 rect.width = rgn.right - rgn.left;
863 rect.height = rgn.bottom - rgn.top;
864 #ifndef NO_SCALE_ASPECT 865 if (mg_ctxt.offset_left)
869 rect.left += mg_ctxt.offset_left;
879 FUNCTION_FINISH(OSDerase)
891 TRACE(TGRAPHICS, (
""))
892 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
896 DrawRectangle8Bit( rgn, 0, TRUE );
902 #if defined(OSD_16_BIT) || defined(OSD_31_BIT) || defined(OSD_32_BIT) 912 void MG_OSDUpdate(
void )
914 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
917 rect.left = osd_update_rgn.left;
918 rect.top = osd_update_rgn.top;
919 rect.width = osd_update_rgn.right - osd_update_rgn.left;
920 rect.height = osd_update_rgn.bottom - osd_update_rgn.top;
924 data = (U8BIT *)mg_ctxt.screen_buff + (osd_update_rgn.top * mg_ctxt.screen_stride) + osd_update_rgn.left;
925 data += mg_ctxt.screen_stride * (rect.height / 2);
926 TRACE(TGRAPHICS, (
"Middle OSD Line:"))
927 TRACE_BUFF(TGRAPHICS, data, rect.width)
930 TRACE(TGRAPHICS, (
"regn (%d,%d,%d,%d)", osd_update_rgn.left, osd_update_rgn.top,
931 osd_update_rgn.right, osd_update_rgn.bottom))
932 TRACE(TGRAPHICS, (
"rect (%d,%d,%d,%d)", rect.left, rect.top, rect.width, rect.height))
934 osd_update_rgn.left, osd_update_rgn.top, STB_BLIT_COPY );
936 osd_update_rgn.left = mg_ctxt.out_osd_width;
937 osd_update_rgn.top = mg_ctxt.out_osd_height;
938 osd_update_rgn.right = 0;
939 osd_update_rgn.bottom = 0;
943 TRACE(TGRAPHICS, (
""))
944 #if defined(OSD_16_BIT) || defined(OSD_32_BIT) 960 U8BIT OSD_FindNearestColourIndex(OSDColor target)
963 static OSDColor target_cache = 0x00000000;
964 static U8BIT offset_cache = OFFSET_TRANS;
965 static const NearCol mg_nearest_colour = {
966 {0, 27, 27, 54, 54, 81, 81, 108},
967 {0, 3, 3, 6, 6, 9, 9, 12, 12, 15, 15, 18, 18, 21, 21, 24},
971 if (target != target_cache)
973 target_cache = target;
975 a = (U8BIT)(((target >> 24) & 0xff) ^ 0xff);
976 r = (U8BIT)((target >> 16) & 0xff);
977 g = (U8BIT)((target >> 8) & 0xff);
978 b = (U8BIT)(target & 0xff);
982 if (r == g && g == b && ((r > 21 && r < 106) || (r > 148 && r < 233)))
985 offset_cache = (r >> 6) + OFFSET_GREY;
990 offset_cache = mg_nearest_colour.red[r >> 5] + mg_nearest_colour.green[g >> 4] +
991 mg_nearest_colour.blue[b >> 6] + OFFSET_BLACK;
997 offset_cache = (b >> 7) + OFFSET_SEMI;
1058 offset_cache = OFFSET_TRANS;
1062 return offset_cache;
1074 void OSD_BlendPixels(U8BIT *pixel, U8BIT colour)
1076 static U8BIT back_colour_cache[2] = {0, 0};
1077 static U8BIT colour_cache[2] = {0, 0};
1078 static U8BIT offset_cache[2] = {0, 0};
1079 static U8BIT lru = 0;
1082 U8BIT front_red_index, front_green_index, front_blue_index;
1083 U8BIT back_red_index, back_green_index, back_blue_index, back_grey_index;
1084 U8BIT red_index, green_index, blue_index;
1085 U8BIT red_value, green_value, blue_value;
1088 static const U8BIT red_blend[4][8] = {
1089 { 0, 0, 0, 27, 27, 27, 27, 27},
1090 { 27, 27, 27, 54, 54, 54, 54, 54},
1091 { 54, 54, 54, 54, 54, 81, 81, 81},
1092 { 81, 81, 81, 81, 81, 108, 108, 108}
1094 static const U8BIT green_blend[6][16] = {
1095 { 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6},
1096 { 3, 3, 3, 6, 6, 6, 6, 6, 6, 9, 9, 9, 9, 9, 9, 9},
1097 { 6, 9, 9, 9, 9, 9, 9, 9, 9, 12, 12, 12, 12, 12, 12, 15},
1098 { 9, 12, 12, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 18},
1099 {12, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 21, 21, 21},
1100 {18, 18, 18, 18, 18, 18, 18, 21, 21, 21, 21, 21, 21, 24, 24, 24}
1102 static const U8BIT blue_blend[2][4] = {
1106 static const U8BIT black_red_blend[4] = {0, 59, 119, 179};
1107 static const U8BIT black_green_blend[6] = {0, 35, 71, 107, 143, 179};
1108 static const U8BIT black_blue_blend[2] = {0, 179};
1109 static const U8BIT grey_red_blend[4][4] = {
1112 {131, 144, 170, 182},
1113 {191, 204, 229, 242}
1115 static const U8BIT grey_green_blend[6][4] = {
1119 {119, 132, 158, 170},
1120 {155, 168, 193, 206},
1121 {191, 204, 229, 242}
1123 static const U8BIT grey_blue_blend[2][4] = {
1125 {191, 204, 229, 242}
1127 static const U8BIT back_red[8] = {
1128 0, 63, 63, 127, 127, 191, 191, 255
1130 static const U8BIT back_green[16] = {
1131 0, 31, 31, 63, 63, 95, 95, 127, 127, 159, 159, 191, 191, 223, 223, 255
1133 static const U8BIT back_blue[4] = {
1136 static const U8BIT front_red[4] = {
1139 static const U8BIT front_green[6] = {
1140 0, 51, 102, 153, 204, 255
1142 static const U8BIT front_blue[2] = {
1145 static const U8BIT opaque_grey_blend[2][4] = {
1146 {OFFSET_BLACK, OFFSET_GREY, OFFSET_GREY, OFFSET_GREY + 1},
1147 {OFFSET_GREY + 2, OFFSET_GREY + 3, OFFSET_GREY + 3, OFFSET_WHITE}
1149 static const U8BIT grey_grey_blend[2][4] = {
1150 {OFFSET_BLACK, OFFSET_GREY, OFFSET_GREY, OFFSET_GREY},
1151 {OFFSET_GREY + 2, OFFSET_GREY + 2, OFFSET_WHITE, OFFSET_WHITE}
1156 assert( colour != OFFSET_TRANS );
1158 back_colour = *pixel;
1161 if (back_colour_cache[0] == back_colour &&
1162 colour_cache[0] == colour)
1164 *pixel = offset_cache[0];
1166 else if (back_colour_cache[1] == back_colour &&
1167 colour_cache[1] == colour)
1169 *pixel = offset_cache[1];
1173 back_colour_cache[lru] = back_colour;
1174 colour_cache[lru] = colour;
1176 if (colour >= OFFSET_OPAQUE || back_colour < OFFSET_OPAQUE)
1179 offset_cache[lru] = colour;
1183 assert( mg_palette != NULL );
1186 colour -= OFFSET_SEMI;
1187 back = mg_palette[*pixel];
1189 front_red_index = (colour >> 1) & 0x3;
1190 front_green_index = (colour >> 3) & 0x7;
1191 front_blue_index = colour & 0x1;
1192 if (back_colour == OFFSET_BLACK)
1197 red_value = black_red_blend[front_red_index];
1198 green_value = black_green_blend[front_green_index];
1199 blue_value = black_blue_blend[front_blue_index];
1200 offset_cache[lru] = OSD_FindNearestColourIndex((0xff << 24) | (red_value << 16) | (green_value << 8) | blue_value);
1202 else if (back_colour > OFFSET_BLACK)
1205 back_red_index = (back >> 21) & 0x7;
1206 back_green_index = (back >> 12) & 0xf;
1207 back_blue_index = (back >> 6) & 0x3;
1210 if (back_red[back_red_index] == back_green[back_green_index] &&
1211 back_red[back_red_index] == back_blue[back_blue_index] &&
1212 front_red[front_red_index] == front_green[front_green_index] &&
1213 front_red[front_red_index] == front_blue[front_blue_index])
1216 offset_cache[lru] = opaque_grey_blend[back_blue_index][front_blue_index];
1221 red_index = red_blend[front_red_index][back_red_index];
1222 green_index = green_blend[front_green_index][back_green_index];
1223 blue_index = blue_blend[front_blue_index][back_blue_index];
1226 offset_cache[lru] = OFFSET_BLACK + red_index + green_index + blue_index;
1232 back_grey_index = (back >> 6) & 0x3;
1235 if (front_red[front_red_index] == front_green[front_green_index] &&
1236 front_red[front_red_index] == front_blue[front_blue_index])
1238 offset_cache[lru] = grey_grey_blend[front_blue_index][back_grey_index];
1243 red_value = grey_red_blend[front_red_index][back_grey_index];
1244 green_value = grey_green_blend[front_green_index][back_grey_index];
1245 blue_value = grey_blue_blend[front_blue_index][back_grey_index];
1246 offset_cache[lru] = OSD_FindNearestColourIndex((0xff << 24) | (red_value << 16) | (green_value << 8) | blue_value);
1250 *pixel = offset_cache[lru];
1268 S32BIT w1, y1, w2, y2;
1269 S32BIT fr, tr, fc, tc;
1274 w1 = (overlap->left * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div;
1275 w2 = (overlap->right * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div;
1277 y1 = (overlap->top * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
1278 y2 = (overlap->bottom * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
1280 TRACE(TGRAPHICS, (
"HDoverlap(l=%d,t=%d,r=%d,b=%d)", w1, y1, w2, y2))
1281 TRACE(TGRAPHICS, (
"Surf(%d,%d) type=%d posn(%d,%d)", surf->width, surf->height, surf->srf_type, x, y))
1296 if (x + tc - fc > w2)
1314 if (y + tr - fr > y2)
1319 if (fc < tc && fr < tr)
1321 TRACE(TGRAPHICS, (
"actual(l=%d,t=%d,r=%d,b=%d)", x + fc, y + fr, x + tc, y + tr))
1323 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
1327 U8BIT *pixndx, *srfndx;
1332 pixndx = mg_ctxt.screen_buff;
1333 pixndx += y * mg_ctxt.screen_stride + x;
1334 srfndx = surf->col_buff;
1335 srfndx += fr * surf->width + fc;
1339 y2 = mg_ctxt.screen_stride;
1340 for (i = fr; i != tr; ++i)
1342 memcpy(pixndx, srfndx, w1);
1349 w2 = surf->width - w1;
1350 y2 = mg_ctxt.screen_stride - w1;
1351 for (i = fr; i != tr; ++i)
1353 for (j = fc; j != tc; ++j)
1355 if (*srfndx != OFFSET_TRANS)
1357 OSD_BlendPixels(pixndx, *srfndx);
1367 if (x < osd_update_rgn.left)
1369 osd_update_rgn.left = x;
1371 if (y < osd_update_rgn.top)
1373 osd_update_rgn.top = y;
1375 if (x + w1 > osd_update_rgn.right)
1377 osd_update_rgn.right = x + w1;
1379 if (y + y1 > osd_update_rgn.bottom)
1381 osd_update_rgn.bottom = y + y1;
1385 ELSE IF_COL_DEPTH( COLOUR_FORMAT_ARGB4444 )
1391 rect.width = tc - fc;
1392 rect.height = tr - fr;
1393 #ifdef NO_SCALE_ASPECT 1395 (surf->opaque) ? STB_BLIT_COPY : STB_BLIT_A_BLEND );
1400 dstr.height= rect.height;
1401 if (mg_ctxt.offset_left)
1403 dstr.left = ((x*3)/4) + mg_ctxt.offset_left;
1404 dstr.width = (rect.width*3)/4;
1409 dstr.width = rect.width;
1412 (surf->opaque) ? STB_BLIT_COPY : STB_BLIT_A_BLEND );
1420 #if defined(OSD_31_BIT) || defined(OSD_32_BIT) 1424 rect.width = tc - fc;
1425 rect.height = tr - fr;
1426 #ifdef NO_SCALE_ASPECT 1428 (surf->opaque) ? STB_BLIT_COPY : STB_BLIT_A_BLEND );
1433 dstr.height= rect.height;
1434 if (mg_ctxt.offset_left)
1436 dstr.left = ((x*3)/4) + mg_ctxt.offset_left;
1437 dstr.width = (rect.width*3)/4;
1442 dstr.width = rect.width;
1445 (surf->opaque) ? STB_BLIT_COPY : STB_BLIT_A_BLEND );
1453 void MG_OSDdisplayImage(
void *data,
S_REGION *overlap,
int x,
int y )
1456 (x * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div,
1457 (y * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div );
1463 static U32BIT surfpixel_total = 0;
1464 static U32BIT surfpixel_tmax = 0;
1468 assert( srf != NULL );
1469 if (surflist_tail == NULL)
1472 assert( surflist_head == NULL );
1473 surflist_head = srf;
1474 surflist_tail = srf;
1479 surflist_tail->next = srf;
1480 srf->prev = surflist_tail;
1481 surflist_tail = srf;
1484 surfpixel_total += srf->width * srf->height;
1485 if (surfpixel_total > surfpixel_tmax)
1487 surfpixel_tmax = surfpixel_total;
1493 assert( srf != NULL );
1494 surfpixel_total -= srf->width * srf->height;
1495 if (surflist_head == srf)
1497 surflist_head = srf->next;
1498 if (surflist_head != NULL)
1500 surflist_head->prev = NULL;
1505 assert( srf->prev );
1506 srf->prev->next = srf->next;
1508 if (surflist_tail == srf)
1510 surflist_tail = srf->prev;
1511 if (surflist_tail != NULL)
1513 surflist_tail->next = NULL;
1518 assert( srf->next );
1519 srf->next->prev = srf->prev;
1523 void OSD_DbgListSrf(
void)
1540 IF_COL_DEPTH( COLOUR_FORMAT_PALETTE )
1543 if (srf->col_buff != NULL)
1545 OSD_MemFree( srf->col_buff );
1551 #if defined(OSD_16_BIT) || defined(OSD_31_BIT) || defined(OSD_32_BIT) 1555 OSD_DbgRemSurf( srf );
1559 OSD_MemFree( data );
1562 #ifdef SURFACE_THRESHOLD 1570 void MG_ApplySurfaceThreshold(
void **data, S32BIT threshold)
1575 if (*data != NULL && threshold > 0)
1578 total = surface->width * surface->height;
1579 if (total >= threshold)
1600 static U16BIT OSD_GCD( U16BIT a, U16BIT b )
void MG_FontExit(void)
Free all data associated with built-in font and terminate freetype library.
void MG_FreeData(void *data)
free surface buffer
void MG_OSDdisplayVideo(S_REGION rgn)
Display video window.
void STB_OSDMhegClear(void)
Clear MHEG's entire OSD.
void STB_OSDMhegFillRectangle(S_RECTANGLE *pRect, U32BIT colour, E_BLIT_OP bflg)
Draw a filled rectangle on OSD back buffer in the location given. Where pixel colour is less than fou...
void * STB_OSDMhegCreateSurface(U16BIT width, U16BIT height, BOOLEAN init, U32BIT colour)
Creates a hardware surface on which MHEG5 engine will draw an individual MHEG object. At its basic the function can just allocate the buffer to be returned by STB_OSDMhegLockBuffer(). It's size being: (width * height * bytes_per_pixel) Also, when 'init' is TRUE, function initialises surface buffer to the specified colour. For pixel colour format of less than four bytes, use least significant bits of 'colour'.
void MG_OSDdisplayRectangle(S_REGION *overlap, int x, int y, int width, int height, int line_width, OSDColor lineColour, OSDColor fillColour)
Draw rectangle.
void MG_Terminate(void)
Free all OSD resources.
void MG_OSDerase(S_REGION rgn, OSDColor colour)
Display video window.
void MG_OSDMhegInit(U16BIT inWidth, U16BIT inHeight, E_ASPECT_RATIO sar)
Initialise the on screen display Initialise the font and fill in font info.
BOOLEAN MG_FontInit(BOOLEAN isHD)
Initialise freetype library and load "built-in" font.
DVB Video functions are required by MHEG5 engine. All required functions should be non-blocking...
This file defines the profile for the MHEG engine.
void * STB_OSDMhegSetResolution(U16BIT width, U16BIT height, U8BIT bits)
Sets the size of the OSD to be used by MHEG engine. The return must be a surface handle for the entir...
void STB_OSDMhegDestroySurface(void *surface)
This function destroys surface and all data allocated by STB_OSDMhegCreateSurface() ...
void MG_OSDclear(void)
Clear entire OSD to colour.
void STB_OSDMhegUpdate(void)
Commit OSD changes to the screen - changes given by previous calls to STB_OSDMhegDrawRectangle() and ...
The functions in this file are OPTIONALLY provided by Receiver Platform *.
Font file handling with the Freetype.
void DVB_MhegSetScalingResolution(U16BIT width, U16BIT height)
Set Mheg scaling resolution for video.
void * STB_OSDMhegLockBuffer(void *surface, U32BIT *pPitch)
Converts hardware surface handle returned by STB_OSDMhegCreateSurface() to buffer address that the en...
E_ASPECT_RATIO DVB_MhegGetDisplayAspectRatio(void)
Get display aspect ratio.
void STB_OSDMhegBlitStretch(S_RECTANGLE *pSrcRect, void *src_surf, S_RECTANGLE *pDstRect, void *dst_surf, E_BLIT_OP bflg)
Stretch blit bitmap data from source surface to destination surface using source and destination rect...
void STB_OSDMhegBlitBitmap(void *surface, S_RECTANGLE *pRect, U32BIT pitch, U16BIT screen_x, U16BIT screen_y, E_BLIT_OP bflg)
Render bitmap on OSD back buffer in the given screen location, with given operation. The bitmap is referenced 'surface' - a handle returned by STB_OSDMhegCreateSurface()
Graphics functions required by the HD MHEG5 engine. All references to colour used in these functions ...
void MG_DisplayImage(S_SURFACE *surf, S_REGION *overlap, S32BIT x, S32BIT y)
Copy the image to the screen buffer.
void STB_OSDMhegUnlockBuffer(void *surface)
This function informs HW that MHEG5 is finished writing to the buffer.
E_MhegErr MG_Initialise(U16BIT screenWidth, U16BIT screenHeight, U8BIT colourDepth)
Initialise OSD, font, and font fill information. Should only be called at start up.