📄 scr_quasarosd.c
字号:
/* * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com> * * Microwindows Screen Driver for Linux kernel framebuffers * * Portions used from Ben Pfaff's BOGL <pfaffben@debian.org> * * Note: modify select_fb_driver() to add new framebuffer subdrivers */#define _GNU_SOURCE 1#include <assert.h>#include <fcntl.h>#include <limits.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#ifndef ARCH_LINUX_POWERPPC#ifdef __GLIBC__#include <sys/io.h>#else#include <asm/io.h>#endif#endif#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include "device.h"#include "genfont.h"#include "genmem.h"#include "caribbean_plainc.h"#include "../realmagichwl_kernelland/realmagichwl.h"#include "realmagichwl_userland_api.h"// hardware library uses these types... undefine them later on. ********************************#define BYTE RMuint8#define LONG RMint32#define ULONG RMuint32#define ULONGLONG RMuint64#define BOOL RMbool#define BOOLEAN RMbool#define HANDLE void *#define UCHAR RMuint8#define USHORT RMuint16#define PULONG RMuint32 *#define PVOID void *#include "../realmagichwl_kernelland/include/rm84cmn.h"#define TRACE//#define TRACE printf("In %s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);//#define OSD_WIDTH 640//#define OSD_HEIGHT 480//#define OSD_SIZE (OSD_WIDTH*OSD_HEIGHT + 256*4 + 8)//#define OSD_BPP 8//XXX#define DRAWON while(0)#define DRAWOFF while(0)typedef unsigned char * ADDR8;typedef unsigned short * ADDR16;typedef unsigned long * ADDR32;static RUA_handle h;static PSD qosd_open(PSD psd);static void qosd_close(PSD psd);static void qosd_setpalette(PSD psd,int first, int count, MWPALENTRY *palette);static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);static void qosd_unimplemented(void);static void qosd_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c);static MWPIXELVAL qosd_readpixel(PSD psd, MWCOORD x, MWCOORD y);static void qosd_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);static void qosd_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);static void qosd_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op);static void qosd_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw, MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw, MWCOORD srch, long op);/* genmem.c*/void gen_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2, MWPIXELVAL c);SCREENDEVICE scrdev = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, qosd_open, qosd_close, gen_getscreeninfo, qosd_setpalette, qosd_drawpixel, /* DrawPixel subdriver*/ qosd_readpixel, /* ReadPixel subdriver*/ qosd_drawhorzline, /* DrawHorzLine subdriver*/ qosd_drawvertline, /* DrawVertLine subdriver*/ gen_fillrect, /* FillRect subdriver*/ gen_fonts, qosd_blit, /* Blit subdriver*/ NULL, /* PreSelect*/ NULL, /* DrawArea subdriver*/ NULL, /* SetIOPermissions*/ gen_allocatememgc, NULL, // qosd_mapmemgc, gen_freememgc, NULL, /* StretchBlit subdriver*/ NULL /* SetPortrait*/};/* ROP macro for 16 drawing modes*/#define CHECK(f,d) /* applyOp w/stored dst*/#define applyOp(op, src, pdst, type) \{ \ type d = (pdst); \ switch (op) { \ case MWMODE_XOR: \ *d ^= (src); \ CHECK("XOR", *d); \ break; \ case MWMODE_AND: \ *d &= (src); \ CHECK("AND", *d); \ break; \ case MWMODE_OR: \ *d |= (src); \ CHECK("OR", *d); \ break; \ case MWMODE_CLEAR: \ *d = 0; \ CHECK("CLEAR", *d); \ break; \ case MWMODE_SETTO1: \ *d = -1; \ CHECK("SETTO1", *d); \ break; \ case MWMODE_EQUIV: \ *d = ~(*d ^ (src)); \ CHECK("EQUIV", *d); \ break; \ case MWMODE_NOR: \ *d = ~(*d | (src)); \ CHECK("NOR", *d); \ break; \ case MWMODE_NAND: \ *d = ~(*d & (src)); \ CHECK("NAND", *d); \ break; \ case MWMODE_INVERT: \ *d = ~*d; \ CHECK("INVERT", *d); \ break; \ case MWMODE_COPYINVERTED: \ *d = ~(src); \ CHECK("COPYINVERTED", *d); \ break; \ case MWMODE_ORINVERTED: \ *d |= ~(src); \ CHECK("ORINVERTED", *d); \ break; \ case MWMODE_ANDINVERTED: \ *d &= ~(src); \ CHECK("ANDINVERTED", *d); \ break; \ case MWMODE_ORREVERSE: \ *d = ~*d | (src); \ CHECK("ORREVERSE", *d); \ break; \ case MWMODE_ANDREVERSE: \ *d = ~*d & (src); \ CHECK("ANDREVERSE", *d); \ break; \ case MWMODE_COPY: \ *d = (src); \ CHECK("COPY", *d); \ break; \ case MWMODE_NOOP: \ CHECK("NOOP", *d); \ break; \ } \}extern int gr_mode;/* static variables*/static int status; /* 0=never inited, 1=once inited, 2=inited. */static char *osd_buffer_addr;static void qosd_unimplemented(void){ printf("*** CALL TO UNIMPLEMENTED FONCTION ***\n");}/* init framebuffer*/static PSDqosd_open(PSD psd){ unsigned long flicker; OSDBuffer osdbuffer;
Wnd_type Wnd; TRACE assert(status < 2); psd->portrait = MWPORTRAIT_NONE; psd->planes = 1; psd->flags = PSF_SCREEN | PSF_HAVEBLIT; /* set pixel format*/ psd->pixtype = MWPF_PALETTE; /*DPRINTF("%dx%dx%d linelen %d type %d visual %d bpp %d\n", psd->xres, psd->yres, psd->ncolors, psd->linelen, type, visual, psd->bpp);*/// XXX If we need to we can mmap the osdbuf from the device h = RUA_OpenDevice(0); if(RUA_OSDFB_SWITCH(h,&osdbuffer) != 0) { EPRINTF("Error getting the osd buffer\n"); goto fail; } else { osd_buffer_addr = osdbuffer.framebuffer; psd->bpp = osdbuffer.bpp; psd->xres = psd->xvirtres = osdbuffer.width; psd->yres = psd->yvirtres = osdbuffer.height; /* set linelen to byte length, possibly converted later*/ psd->linelen = osdbuffer.width; /* force subdriver init of size*/ psd->size = osdbuffer.width * osdbuffer.height + 1024 + 8; psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp); printf("OSD Buffer of size %d allocated @ %p\n", psd->size, osd_buffer_addr); } psd->addr = osd_buffer_addr + 8 + 1024; /* save original palette ??? */ /* Setup the flicker filter */ // XXX - its also set in the kernel module, but it seems not to work very well // We reset it here, so that the microcode as already seen an osd frame. // 0 <= flicker <= 15 flicker = 15; RUA_DECODER_SET_PROPERTY (h, DECODER_SET, edecOsdFlicker, sizeof(flicker), &flicker);
// default osd destination
Wnd.x = 0;
Wnd.y = 0;
Wnd.w = osdbuffer.width;
Wnd.h = osdbuffer.height;
RUA_DECODER_SET_PROPERTY (h, OSD_SET, eOsdDestinationWindow, sizeof(Wnd), &Wnd); DPRINTF("End of qosd_open\n"); status = 2; return psd; /* success*/fail: return NULL;}/* close framebuffer*/static voidqosd_close(PSD psd){ /* if not opened, return*/ TRACE if(status != 2) return; status = 1; RUA_ReleaseDevice(h); /* unmap framebuffer*/// free(osd_buffer_addr);}static int fade = 100;#define START 0#define END 65536#define PRECISION 20#define MIN(a, b) (((a) <= (b)) ? (a) : (b))#define MAX(a, b) (((a) >= (b)) ? (a) : (b))// This trick transform [0..255] range into [0..65535] range (instead of about 0..255*256)#define RANGE8TO16(x) (((x)<<8)|(x))// u=0; while [ $u -lt 21 ]; do echo $u; u=$[$u+1]; done |awk '{printf("%d,\n",65536*($1/20)^2.2);}'static unsigned long powertwodottwotable[PRECISION+1]={0,89,413,1008,1899,3104,4636,6507,8729,11312,14263,17590,21301,25403,29901,34802,40112,45835,51977,58542,65536};static unsigned long invertofpowertwodottwotable[PRECISION+1]={0,16792,23010,27667,31533,34899,37914,40666,43211,45587,47824,49941,51956,53881,55727,57502,59214,60869,62471,64025,65536};// computes y/65536=f(x/65536) with 0<=x,y<65536 with f=^2.2 or ^(1/2.2) given as a unsigned long table (have to code the 65536 case)static unsigned short compute_f(unsigned long beg,unsigned long end,unsigned long prec,unsigned long *table,unsigned short x){ long a,b,fa,fb,entry; if (beg==end) { printf("memory corrupted beg=%ld end=%ld\n",beg,end); return; } entry=(x-beg)*prec/(end-beg); if ((entry<0)||(entry>=20)) { printf("memory corrupted x=%hd beg=%ld end=%ld prec=%ld\n",x,beg,end,prec); return; } a=entry*(end-beg)/prec+beg; b=(entry+1)*(end-beg)/prec+beg; fa=table[entry]; fb=table[entry+1]; return (unsigned short)(fa+(fb-fa)*(x-a)/(b-a));}// see video demystified page 43static void gammacorrectedrgbtoyuv(unsigned short R,unsigned short G,unsigned short B,unsigned short *y,unsigned short *u,unsigned short *v){ long yraw,uraw,vraw; yraw=( 257*R +504*G + 98*B)/1000 + RANGE8TO16(16); uraw=(-148*R -291*G +439*B)/1000 + RANGE8TO16(128); vraw=( 439*R -368*G - 71*B)/1000 + RANGE8TO16(128); /* Obviously the computation of yraw garantees >= RANGE8TO16(16) ;-) This is also true for uraw and vraw */ *y=MAX(MIN(yraw,RANGE8TO16(235)),RANGE8TO16(16)); *u=MAX(MIN(uraw,RANGE8TO16(240)),RANGE8TO16(16)); *v=MAX(MIN(vraw,RANGE8TO16(240)),RANGE8TO16(16));}static void yuvtorgbgammacorrected(unsigned short y,unsigned short u,unsigned short v,unsigned short *R,unsigned short *G,unsigned short *B){ long Rraw,Graw,Braw; long ym=y-RANGE8TO16(16),um=u-RANGE8TO16(128),vm=v-RANGE8TO16(128); Rraw=(1164*ym +1596*vm)/1000; Graw=(1164*ym+ 392*um- 813*vm)/1000; Braw=(1164*ym+2017*um )/1000; *R=MAX(0,MIN(Rraw,RANGE8TO16(255))); *G=MAX(0,MIN(Graw,RANGE8TO16(255))); *B=MAX(0,MIN(Braw,RANGE8TO16(255)));}void vgargbtotvyuv(unsigned short R,unsigned short G,unsigned short B,unsigned short *y,unsigned short *u,unsigned short *v){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -